diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 37458fa12..fd30b1d67 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.262.0" + ".": "0.263.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index b26d90908..d843fc927 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 202 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/increase%2Fincrease-7f26440e2137fb4f39521c361e76d56bad7c56d81cd06d0677d7735e73f7c160.yml -openapi_spec_hash: aa475d425f493e41eb8485ae17a3d0f9 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/increase%2Fincrease-2965cbcf43d274ee029249246f9e3760a82372b9120a033bd651cad24765a4fb.yml +openapi_spec_hash: ae42e357b1bedbf992105c2a37f1b544 config_hash: a185e9a72778cc4658ea73fb3a7f1354 diff --git a/CHANGELOG.md b/CHANGELOG.md index 0cf6e97eb..c0533e392 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ # Changelog +## 0.263.0 (2025-07-21) + +Full Changelog: [v0.262.0...v0.263.0](https://github.com/Increase/increase-java/compare/v0.262.0...v0.263.0) + +### Features + +* **api:** api update ([146db20](https://github.com/Increase/increase-java/commit/146db20ddc3179d3fb7193c446f6584a8776d5a1)) +* **client:** add https config options ([f22db91](https://github.com/Increase/increase-java/commit/f22db91567decbc8fd08b957e4ec01052675a570)) +* **client:** allow configuring env via system properties ([13c25db](https://github.com/Increase/increase-java/commit/13c25dba41aaaacdc7a1c166fe3e3e827fd43089)) +* **client:** allow setting additional multipart body props ([15bb03f](https://github.com/Increase/increase-java/commit/15bb03f8234293bd936c2ae617ade816a005e9c7)) + + +### Chores + +* **internal:** refactor delegating from client to options ([3dec230](https://github.com/Increase/increase-java/commit/3dec2305506bb528f5ab6b8258b0f23431a72765)) + ## 0.262.0 (2025-07-18) Full Changelog: [v0.261.1...v0.262.0](https://github.com/Increase/increase-java/compare/v0.261.1...v0.262.0) diff --git a/README.md b/README.md index d33e33ee9..392684ede 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ -[![Maven Central](https://img.shields.io/maven-central/v/com.increase.api/increase-java)](https://central.sonatype.com/artifact/com.increase.api/increase-java/0.262.0) -[![javadoc](https://javadoc.io/badge2/com.increase.api/increase-java/0.262.0/javadoc.svg)](https://javadoc.io/doc/com.increase.api/increase-java/0.262.0) +[![Maven Central](https://img.shields.io/maven-central/v/com.increase.api/increase-java)](https://central.sonatype.com/artifact/com.increase.api/increase-java/0.263.0) +[![javadoc](https://javadoc.io/badge2/com.increase.api/increase-java/0.263.0/javadoc.svg)](https://javadoc.io/doc/com.increase.api/increase-java/0.263.0) @@ -13,7 +13,7 @@ The Increase Java SDK is similar to the Increase Kotlin SDK but with minor diffe -The REST API documentation can be found on [increase.com](https://increase.com/documentation). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.increase.api/increase-java/0.262.0). +The REST API documentation can be found on [increase.com](https://increase.com/documentation). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.increase.api/increase-java/0.263.0). @@ -24,7 +24,7 @@ The REST API documentation can be found on [increase.com](https://increase.com/d ### Gradle ```kotlin -implementation("com.increase.api:increase-java:0.262.0") +implementation("com.increase.api:increase-java:0.263.0") ``` ### Maven @@ -33,7 +33,7 @@ implementation("com.increase.api:increase-java:0.262.0") com.increase.api increase-java - 0.262.0 + 0.263.0 ``` @@ -51,7 +51,8 @@ import com.increase.api.client.okhttp.IncreaseOkHttpClient; import com.increase.api.models.accounts.Account; import com.increase.api.models.accounts.AccountCreateParams; -// Configures using the `INCREASE_API_KEY`, `INCREASE_WEBHOOK_SECRET` and `INCREASE_BASE_URL` environment variables +// Configures using the `increase.apiKey`, `increase.webhookSecret` and `increase.baseUrl` system properties +// Or configures using the `INCREASE_API_KEY`, `INCREASE_WEBHOOK_SECRET` and `INCREASE_BASE_URL` environment variables IncreaseClient client = IncreaseOkHttpClient.fromEnv(); AccountCreateParams params = AccountCreateParams.builder() @@ -64,13 +65,14 @@ Account account = client.accounts().create(params); ## Client configuration -Configure the client using environment variables: +Configure the client using system properties or environment variables: ```java import com.increase.api.client.IncreaseClient; import com.increase.api.client.okhttp.IncreaseOkHttpClient; -// Configures using the `INCREASE_API_KEY`, `INCREASE_WEBHOOK_SECRET` and `INCREASE_BASE_URL` environment variables +// Configures using the `increase.apiKey`, `increase.webhookSecret` and `increase.baseUrl` system properties +// Or configures using the `INCREASE_API_KEY`, `INCREASE_WEBHOOK_SECRET` and `INCREASE_BASE_URL` environment variables IncreaseClient client = IncreaseOkHttpClient.fromEnv(); ``` @@ -92,7 +94,8 @@ import com.increase.api.client.IncreaseClient; import com.increase.api.client.okhttp.IncreaseOkHttpClient; IncreaseClient client = IncreaseOkHttpClient.builder() - // Configures using the `INCREASE_API_KEY`, `INCREASE_WEBHOOK_SECRET` and `INCREASE_BASE_URL` environment variables + // Configures using the `increase.apiKey`, `increase.webhookSecret` and `increase.baseUrl` system properties + Or configures using the `INCREASE_API_KEY`, `INCREASE_WEBHOOK_SECRET` and `INCREASE_BASE_URL` environment variables .fromEnv() .apiKey("My API Key") .build(); @@ -100,11 +103,13 @@ IncreaseClient client = IncreaseOkHttpClient.builder() See this table for the available options: -| Setter | Environment variable | Required | Default value | -| --------------- | ------------------------- | -------- | ---------------------------- | -| `apiKey` | `INCREASE_API_KEY` | true | - | -| `webhookSecret` | `INCREASE_WEBHOOK_SECRET` | false | - | -| `baseUrl` | `INCREASE_BASE_URL` | true | `"https://api.increase.com"` | +| Setter | System property | Environment variable | Required | Default value | +| --------------- | ------------------------ | ------------------------- | -------- | ---------------------------- | +| `apiKey` | `increase.apiKey` | `INCREASE_API_KEY` | true | - | +| `webhookSecret` | `increase.webhookSecret` | `INCREASE_WEBHOOK_SECRET` | false | - | +| `baseUrl` | `increase.baseUrl` | `INCREASE_BASE_URL` | true | `"https://api.increase.com"` | + +System properties take precedence over environment variables. > [!TIP] > Don't create more than one client in the same application. Each client has a connection pool and @@ -150,7 +155,8 @@ import com.increase.api.models.accounts.Account; import com.increase.api.models.accounts.AccountCreateParams; import java.util.concurrent.CompletableFuture; -// Configures using the `INCREASE_API_KEY`, `INCREASE_WEBHOOK_SECRET` and `INCREASE_BASE_URL` environment variables +// Configures using the `increase.apiKey`, `increase.webhookSecret` and `increase.baseUrl` system properties +// Or configures using the `INCREASE_API_KEY`, `INCREASE_WEBHOOK_SECRET` and `INCREASE_BASE_URL` environment variables IncreaseClient client = IncreaseOkHttpClient.fromEnv(); AccountCreateParams params = AccountCreateParams.builder() @@ -170,7 +176,8 @@ import com.increase.api.models.accounts.Account; import com.increase.api.models.accounts.AccountCreateParams; import java.util.concurrent.CompletableFuture; -// Configures using the `INCREASE_API_KEY`, `INCREASE_WEBHOOK_SECRET` and `INCREASE_BASE_URL` environment variables +// Configures using the `increase.apiKey`, `increase.webhookSecret` and `increase.baseUrl` system properties +// Or configures using the `INCREASE_API_KEY`, `INCREASE_WEBHOOK_SECRET` and `INCREASE_BASE_URL` environment variables IncreaseClientAsync client = IncreaseOkHttpClientAsync.fromEnv(); AccountCreateParams params = AccountCreateParams.builder() @@ -513,6 +520,27 @@ IncreaseClient client = IncreaseOkHttpClient.builder() .build(); ``` +### HTTPS + +> [!NOTE] +> Most applications should not call these methods, and instead use the system defaults. The defaults include +> special optimizations that can be lost if the implementations are modified. + +To configure how HTTPS connections are secured, configure the client using the `sslSocketFactory`, `trustManager`, and `hostnameVerifier` methods: + +```java +import com.increase.api.client.IncreaseClient; +import com.increase.api.client.okhttp.IncreaseOkHttpClient; + +IncreaseClient client = IncreaseOkHttpClient.builder() + .fromEnv() + // If `sslSocketFactory` is set, then `trustManager` must be set, and vice versa. + .sslSocketFactory(yourSSLSocketFactory) + .trustManager(yourTrustManager) + .hostnameVerifier(yourHostnameVerifier) + .build(); +``` + ### Environments The SDK sends requests to the production by default. To send requests to a different environment, configure the client like so: diff --git a/build.gradle.kts b/build.gradle.kts index 0a341c72e..779e859b9 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,7 +8,7 @@ repositories { allprojects { group = "com.increase.api" - version = "0.262.0" // x-release-please-version + version = "0.263.0" // x-release-please-version } subprojects { diff --git a/increase-java-client-okhttp/src/main/kotlin/com/increase/api/client/okhttp/IncreaseOkHttpClient.kt b/increase-java-client-okhttp/src/main/kotlin/com/increase/api/client/okhttp/IncreaseOkHttpClient.kt index 2609b9e53..aa5ca7054 100644 --- a/increase-java-client-okhttp/src/main/kotlin/com/increase/api/client/okhttp/IncreaseOkHttpClient.kt +++ b/increase-java-client-okhttp/src/main/kotlin/com/increase/api/client/okhttp/IncreaseOkHttpClient.kt @@ -9,11 +9,15 @@ import com.increase.api.core.ClientOptions import com.increase.api.core.Timeout import com.increase.api.core.http.Headers import com.increase.api.core.http.QueryParams +import com.increase.api.core.jsonMapper import java.net.Proxy import java.time.Clock import java.time.Duration import java.util.Optional import java.util.concurrent.Executor +import javax.net.ssl.HostnameVerifier +import javax.net.ssl.SSLSocketFactory +import javax.net.ssl.X509TrustManager import kotlin.jvm.optionals.getOrNull class IncreaseOkHttpClient private constructor() { @@ -30,12 +34,63 @@ class IncreaseOkHttpClient private constructor() { class Builder internal constructor() { private var clientOptions: ClientOptions.Builder = ClientOptions.builder() - private var timeout: Timeout = Timeout.default() private var proxy: Proxy? = null + private var sslSocketFactory: SSLSocketFactory? = null + private var trustManager: X509TrustManager? = null + private var hostnameVerifier: HostnameVerifier? = null - fun sandbox() = apply { baseUrl(ClientOptions.SANDBOX_URL) } + fun proxy(proxy: Proxy?) = apply { this.proxy = proxy } - fun baseUrl(baseUrl: String) = apply { clientOptions.baseUrl(baseUrl) } + /** Alias for calling [Builder.proxy] with `proxy.orElse(null)`. */ + fun proxy(proxy: Optional) = proxy(proxy.getOrNull()) + + /** + * The socket factory used to secure HTTPS connections. + * + * If this is set, then [trustManager] must also be set. + * + * If unset, then the system default is used. Most applications should not call this method, + * and instead use the system default. The default include special optimizations that can be + * lost if the implementation is modified. + */ + fun sslSocketFactory(sslSocketFactory: SSLSocketFactory?) = apply { + this.sslSocketFactory = sslSocketFactory + } + + /** Alias for calling [Builder.sslSocketFactory] with `sslSocketFactory.orElse(null)`. */ + fun sslSocketFactory(sslSocketFactory: Optional) = + sslSocketFactory(sslSocketFactory.getOrNull()) + + /** + * The trust manager used to secure HTTPS connections. + * + * If this is set, then [sslSocketFactory] must also be set. + * + * If unset, then the system default is used. Most applications should not call this method, + * and instead use the system default. The default include special optimizations that can be + * lost if the implementation is modified. + */ + fun trustManager(trustManager: X509TrustManager?) = apply { + this.trustManager = trustManager + } + + /** Alias for calling [Builder.trustManager] with `trustManager.orElse(null)`. */ + fun trustManager(trustManager: Optional) = + trustManager(trustManager.getOrNull()) + + /** + * The verifier used to confirm that response certificates apply to requested hostnames for + * HTTPS connections. + * + * If unset, then a default hostname verifier is used. + */ + fun hostnameVerifier(hostnameVerifier: HostnameVerifier?) = apply { + this.hostnameVerifier = hostnameVerifier + } + + /** Alias for calling [Builder.hostnameVerifier] with `hostnameVerifier.orElse(null)`. */ + fun hostnameVerifier(hostnameVerifier: Optional) = + hostnameVerifier(hostnameVerifier.getOrNull()) /** * Whether to throw an exception if any of the Jackson versions detected at runtime are @@ -56,6 +111,40 @@ class IncreaseOkHttpClient private constructor() { fun clock(clock: Clock) = apply { clientOptions.clock(clock) } + fun baseUrl(baseUrl: String?) = apply { clientOptions.baseUrl(baseUrl) } + + /** Alias for calling [Builder.baseUrl] with `baseUrl.orElse(null)`. */ + fun baseUrl(baseUrl: Optional) = baseUrl(baseUrl.getOrNull()) + + fun sandbox() = apply { clientOptions.sandbox() } + + fun responseValidation(responseValidation: Boolean) = apply { + clientOptions.responseValidation(responseValidation) + } + + fun timeout(timeout: Timeout) = apply { clientOptions.timeout(timeout) } + + /** + * Sets the maximum time allowed for a complete HTTP call, not including retries. + * + * See [Timeout.request] for more details. + * + * For fine-grained control, pass a [Timeout] object. + */ + fun timeout(timeout: Duration) = apply { clientOptions.timeout(timeout) } + + fun maxRetries(maxRetries: Int) = apply { clientOptions.maxRetries(maxRetries) } + + fun apiKey(apiKey: String) = apply { clientOptions.apiKey(apiKey) } + + fun webhookSecret(webhookSecret: String?) = apply { + clientOptions.webhookSecret(webhookSecret) + } + + /** Alias for calling [Builder.webhookSecret] with `webhookSecret.orElse(null)`. */ + fun webhookSecret(webhookSecret: Optional) = + webhookSecret(webhookSecret.getOrNull()) + fun headers(headers: Headers) = apply { clientOptions.headers(headers) } fun headers(headers: Map>) = apply { @@ -136,38 +225,6 @@ class IncreaseOkHttpClient private constructor() { clientOptions.removeAllQueryParams(keys) } - fun timeout(timeout: Timeout) = apply { - clientOptions.timeout(timeout) - this.timeout = timeout - } - - /** - * Sets the maximum time allowed for a complete HTTP call, not including retries. - * - * See [Timeout.request] for more details. - * - * For fine-grained control, pass a [Timeout] object. - */ - fun timeout(timeout: Duration) = timeout(Timeout.builder().request(timeout).build()) - - fun maxRetries(maxRetries: Int) = apply { clientOptions.maxRetries(maxRetries) } - - fun proxy(proxy: Proxy) = apply { this.proxy = proxy } - - fun responseValidation(responseValidation: Boolean) = apply { - clientOptions.responseValidation(responseValidation) - } - - fun apiKey(apiKey: String) = apply { clientOptions.apiKey(apiKey) } - - fun webhookSecret(webhookSecret: String?) = apply { - clientOptions.webhookSecret(webhookSecret) - } - - /** Alias for calling [Builder.webhookSecret] with `webhookSecret.orElse(null)`. */ - fun webhookSecret(webhookSecret: Optional) = - webhookSecret(webhookSecret.getOrNull()) - fun fromEnv() = apply { clientOptions.fromEnv() } /** @@ -178,7 +235,15 @@ class IncreaseOkHttpClient private constructor() { fun build(): IncreaseClient = IncreaseClientImpl( clientOptions - .httpClient(OkHttpClient.builder().timeout(timeout).proxy(proxy).build()) + .httpClient( + OkHttpClient.builder() + .timeout(clientOptions.timeout()) + .proxy(proxy) + .sslSocketFactory(sslSocketFactory) + .trustManager(trustManager) + .hostnameVerifier(hostnameVerifier) + .build() + ) .build() ) } diff --git a/increase-java-client-okhttp/src/main/kotlin/com/increase/api/client/okhttp/IncreaseOkHttpClientAsync.kt b/increase-java-client-okhttp/src/main/kotlin/com/increase/api/client/okhttp/IncreaseOkHttpClientAsync.kt index 9625d1ac2..c78d5b162 100644 --- a/increase-java-client-okhttp/src/main/kotlin/com/increase/api/client/okhttp/IncreaseOkHttpClientAsync.kt +++ b/increase-java-client-okhttp/src/main/kotlin/com/increase/api/client/okhttp/IncreaseOkHttpClientAsync.kt @@ -9,11 +9,15 @@ import com.increase.api.core.ClientOptions import com.increase.api.core.Timeout import com.increase.api.core.http.Headers import com.increase.api.core.http.QueryParams +import com.increase.api.core.jsonMapper import java.net.Proxy import java.time.Clock import java.time.Duration import java.util.Optional import java.util.concurrent.Executor +import javax.net.ssl.HostnameVerifier +import javax.net.ssl.SSLSocketFactory +import javax.net.ssl.X509TrustManager import kotlin.jvm.optionals.getOrNull class IncreaseOkHttpClientAsync private constructor() { @@ -32,12 +36,63 @@ class IncreaseOkHttpClientAsync private constructor() { class Builder internal constructor() { private var clientOptions: ClientOptions.Builder = ClientOptions.builder() - private var timeout: Timeout = Timeout.default() private var proxy: Proxy? = null + private var sslSocketFactory: SSLSocketFactory? = null + private var trustManager: X509TrustManager? = null + private var hostnameVerifier: HostnameVerifier? = null - fun sandbox() = apply { baseUrl(ClientOptions.SANDBOX_URL) } + fun proxy(proxy: Proxy?) = apply { this.proxy = proxy } - fun baseUrl(baseUrl: String) = apply { clientOptions.baseUrl(baseUrl) } + /** Alias for calling [Builder.proxy] with `proxy.orElse(null)`. */ + fun proxy(proxy: Optional) = proxy(proxy.getOrNull()) + + /** + * The socket factory used to secure HTTPS connections. + * + * If this is set, then [trustManager] must also be set. + * + * If unset, then the system default is used. Most applications should not call this method, + * and instead use the system default. The default include special optimizations that can be + * lost if the implementation is modified. + */ + fun sslSocketFactory(sslSocketFactory: SSLSocketFactory?) = apply { + this.sslSocketFactory = sslSocketFactory + } + + /** Alias for calling [Builder.sslSocketFactory] with `sslSocketFactory.orElse(null)`. */ + fun sslSocketFactory(sslSocketFactory: Optional) = + sslSocketFactory(sslSocketFactory.getOrNull()) + + /** + * The trust manager used to secure HTTPS connections. + * + * If this is set, then [sslSocketFactory] must also be set. + * + * If unset, then the system default is used. Most applications should not call this method, + * and instead use the system default. The default include special optimizations that can be + * lost if the implementation is modified. + */ + fun trustManager(trustManager: X509TrustManager?) = apply { + this.trustManager = trustManager + } + + /** Alias for calling [Builder.trustManager] with `trustManager.orElse(null)`. */ + fun trustManager(trustManager: Optional) = + trustManager(trustManager.getOrNull()) + + /** + * The verifier used to confirm that response certificates apply to requested hostnames for + * HTTPS connections. + * + * If unset, then a default hostname verifier is used. + */ + fun hostnameVerifier(hostnameVerifier: HostnameVerifier?) = apply { + this.hostnameVerifier = hostnameVerifier + } + + /** Alias for calling [Builder.hostnameVerifier] with `hostnameVerifier.orElse(null)`. */ + fun hostnameVerifier(hostnameVerifier: Optional) = + hostnameVerifier(hostnameVerifier.getOrNull()) /** * Whether to throw an exception if any of the Jackson versions detected at runtime are @@ -58,6 +113,40 @@ class IncreaseOkHttpClientAsync private constructor() { fun clock(clock: Clock) = apply { clientOptions.clock(clock) } + fun baseUrl(baseUrl: String?) = apply { clientOptions.baseUrl(baseUrl) } + + /** Alias for calling [Builder.baseUrl] with `baseUrl.orElse(null)`. */ + fun baseUrl(baseUrl: Optional) = baseUrl(baseUrl.getOrNull()) + + fun sandbox() = apply { clientOptions.sandbox() } + + fun responseValidation(responseValidation: Boolean) = apply { + clientOptions.responseValidation(responseValidation) + } + + fun timeout(timeout: Timeout) = apply { clientOptions.timeout(timeout) } + + /** + * Sets the maximum time allowed for a complete HTTP call, not including retries. + * + * See [Timeout.request] for more details. + * + * For fine-grained control, pass a [Timeout] object. + */ + fun timeout(timeout: Duration) = apply { clientOptions.timeout(timeout) } + + fun maxRetries(maxRetries: Int) = apply { clientOptions.maxRetries(maxRetries) } + + fun apiKey(apiKey: String) = apply { clientOptions.apiKey(apiKey) } + + fun webhookSecret(webhookSecret: String?) = apply { + clientOptions.webhookSecret(webhookSecret) + } + + /** Alias for calling [Builder.webhookSecret] with `webhookSecret.orElse(null)`. */ + fun webhookSecret(webhookSecret: Optional) = + webhookSecret(webhookSecret.getOrNull()) + fun headers(headers: Headers) = apply { clientOptions.headers(headers) } fun headers(headers: Map>) = apply { @@ -138,38 +227,6 @@ class IncreaseOkHttpClientAsync private constructor() { clientOptions.removeAllQueryParams(keys) } - fun timeout(timeout: Timeout) = apply { - clientOptions.timeout(timeout) - this.timeout = timeout - } - - /** - * Sets the maximum time allowed for a complete HTTP call, not including retries. - * - * See [Timeout.request] for more details. - * - * For fine-grained control, pass a [Timeout] object. - */ - fun timeout(timeout: Duration) = timeout(Timeout.builder().request(timeout).build()) - - fun maxRetries(maxRetries: Int) = apply { clientOptions.maxRetries(maxRetries) } - - fun proxy(proxy: Proxy) = apply { this.proxy = proxy } - - fun responseValidation(responseValidation: Boolean) = apply { - clientOptions.responseValidation(responseValidation) - } - - fun apiKey(apiKey: String) = apply { clientOptions.apiKey(apiKey) } - - fun webhookSecret(webhookSecret: String?) = apply { - clientOptions.webhookSecret(webhookSecret) - } - - /** Alias for calling [Builder.webhookSecret] with `webhookSecret.orElse(null)`. */ - fun webhookSecret(webhookSecret: Optional) = - webhookSecret(webhookSecret.getOrNull()) - fun fromEnv() = apply { clientOptions.fromEnv() } /** @@ -180,7 +237,15 @@ class IncreaseOkHttpClientAsync private constructor() { fun build(): IncreaseClientAsync = IncreaseClientAsyncImpl( clientOptions - .httpClient(OkHttpClient.builder().timeout(timeout).proxy(proxy).build()) + .httpClient( + OkHttpClient.builder() + .timeout(clientOptions.timeout()) + .proxy(proxy) + .sslSocketFactory(sslSocketFactory) + .trustManager(trustManager) + .hostnameVerifier(hostnameVerifier) + .build() + ) .build() ) } diff --git a/increase-java-client-okhttp/src/main/kotlin/com/increase/api/client/okhttp/OkHttpClient.kt b/increase-java-client-okhttp/src/main/kotlin/com/increase/api/client/okhttp/OkHttpClient.kt index bee252bf1..a94bf6a54 100644 --- a/increase-java-client-okhttp/src/main/kotlin/com/increase/api/client/okhttp/OkHttpClient.kt +++ b/increase-java-client-okhttp/src/main/kotlin/com/increase/api/client/okhttp/OkHttpClient.kt @@ -14,6 +14,9 @@ import java.io.InputStream import java.net.Proxy import java.time.Duration import java.util.concurrent.CompletableFuture +import javax.net.ssl.HostnameVerifier +import javax.net.ssl.SSLSocketFactory +import javax.net.ssl.X509TrustManager import okhttp3.Call import okhttp3.Callback import okhttp3.HttpUrl.Companion.toHttpUrl @@ -189,6 +192,9 @@ class OkHttpClient private constructor(private val okHttpClient: okhttp3.OkHttpC private var timeout: Timeout = Timeout.default() private var proxy: Proxy? = null + private var sslSocketFactory: SSLSocketFactory? = null + private var trustManager: X509TrustManager? = null + private var hostnameVerifier: HostnameVerifier? = null fun timeout(timeout: Timeout) = apply { this.timeout = timeout } @@ -196,6 +202,18 @@ class OkHttpClient private constructor(private val okHttpClient: okhttp3.OkHttpC fun proxy(proxy: Proxy?) = apply { this.proxy = proxy } + fun sslSocketFactory(sslSocketFactory: SSLSocketFactory?) = apply { + this.sslSocketFactory = sslSocketFactory + } + + fun trustManager(trustManager: X509TrustManager?) = apply { + this.trustManager = trustManager + } + + fun hostnameVerifier(hostnameVerifier: HostnameVerifier?) = apply { + this.hostnameVerifier = hostnameVerifier + } + fun build(): OkHttpClient = OkHttpClient( okhttp3.OkHttpClient.Builder() @@ -204,6 +222,19 @@ class OkHttpClient private constructor(private val okHttpClient: okhttp3.OkHttpC .writeTimeout(timeout.write()) .callTimeout(timeout.request()) .proxy(proxy) + .apply { + val sslSocketFactory = sslSocketFactory + val trustManager = trustManager + if (sslSocketFactory != null && trustManager != null) { + sslSocketFactory(sslSocketFactory, trustManager) + } else { + check((sslSocketFactory != null) == (trustManager != null)) { + "Both or none of `sslSocketFactory` and `trustManager` must be set, but only one was set" + } + } + + hostnameVerifier?.let(::hostnameVerifier) + } .build() .apply { // We usually make all our requests to the same host so it makes sense to diff --git a/increase-java-core/src/main/kotlin/com/increase/api/core/ClientOptions.kt b/increase-java-core/src/main/kotlin/com/increase/api/core/ClientOptions.kt index b359750c6..bb3bdf789 100644 --- a/increase-java-core/src/main/kotlin/com/increase/api/core/ClientOptions.kt +++ b/increase-java-core/src/main/kotlin/com/increase/api/core/ClientOptions.kt @@ -9,6 +9,7 @@ import com.increase.api.core.http.PhantomReachableClosingHttpClient import com.increase.api.core.http.QueryParams import com.increase.api.core.http.RetryingHttpClient import java.time.Clock +import java.time.Duration import java.util.Optional import java.util.concurrent.Executor import java.util.concurrent.Executors @@ -20,6 +21,13 @@ class ClientOptions private constructor( private val originalHttpClient: HttpClient, @get:JvmName("httpClient") val httpClient: HttpClient, + /** + * Whether to throw an exception if any of the Jackson versions detected at runtime are + * incompatible with the SDK's minimum supported Jackson version (2.13.4). + * + * Defaults to true. Use extreme caution when disabling this option. There is no guarantee that + * the SDK will work correctly when using an incompatible Jackson version. + */ @get:JvmName("checkJacksonVersionCompatibility") val checkJacksonVersionCompatibility: Boolean, @get:JvmName("jsonMapper") val jsonMapper: JsonMapper, @get:JvmName("streamHandlerExecutor") val streamHandlerExecutor: Executor, @@ -104,6 +112,13 @@ private constructor( this.httpClient = PhantomReachableClosingHttpClient(httpClient) } + /** + * Whether to throw an exception if any of the Jackson versions detected at runtime are + * incompatible with the SDK's minimum supported Jackson version (2.13.4). + * + * Defaults to true. Use extreme caution when disabling this option. There is no guarantee + * that the SDK will work correctly when using an incompatible Jackson version. + */ fun checkJacksonVersionCompatibility(checkJacksonVersionCompatibility: Boolean) = apply { this.checkJacksonVersionCompatibility = checkJacksonVersionCompatibility } @@ -121,12 +136,23 @@ private constructor( /** Alias for calling [Builder.baseUrl] with `baseUrl.orElse(null)`. */ fun baseUrl(baseUrl: Optional) = baseUrl(baseUrl.getOrNull()) + fun sandbox() = baseUrl(SANDBOX_URL) + fun responseValidation(responseValidation: Boolean) = apply { this.responseValidation = responseValidation } fun timeout(timeout: Timeout) = apply { this.timeout = timeout } + /** + * Sets the maximum time allowed for a complete HTTP call, not including retries. + * + * See [Timeout.request] for more details. + * + * For fine-grained control, pass a [Timeout] object. + */ + fun timeout(timeout: Duration) = timeout(Timeout.builder().request(timeout).build()) + fun maxRetries(maxRetries: Int) = apply { this.maxRetries = maxRetries } fun apiKey(apiKey: String) = apply { this.apiKey = apiKey } @@ -217,10 +243,18 @@ private constructor( fun removeAllQueryParams(keys: Set) = apply { queryParams.removeAll(keys) } + fun timeout(): Timeout = timeout + fun fromEnv() = apply { - System.getenv("INCREASE_BASE_URL")?.let { baseUrl(it) } - System.getenv("INCREASE_API_KEY")?.let { apiKey(it) } - System.getenv("INCREASE_WEBHOOK_SECRET")?.let { webhookSecret(it) } + (System.getProperty("increase.baseUrl") ?: System.getenv("INCREASE_BASE_URL"))?.let { + baseUrl(it) + } + (System.getProperty("increase.apiKey") ?: System.getenv("INCREASE_API_KEY"))?.let { + apiKey(it) + } + (System.getProperty("increase.webhookSecret") + ?: System.getenv("INCREASE_WEBHOOK_SECRET")) + ?.let { webhookSecret(it) } } /** diff --git a/increase-java-core/src/main/kotlin/com/increase/api/models/events/Event.kt b/increase-java-core/src/main/kotlin/com/increase/api/models/events/Event.kt index 25b9ed24b..132fdc48a 100644 --- a/increase-java-core/src/main/kotlin/com/increase/api/models/events/Event.kt +++ b/increase-java-core/src/main/kotlin/com/increase/api/models/events/Event.kt @@ -642,6 +642,12 @@ private constructor( /** Occurs whenever a Physical Card Profile is updated. */ @JvmField val PHYSICAL_CARD_PROFILE_UPDATED = of("physical_card_profile.updated") + /** Occurs whenever a Program is created. */ + @JvmField val PROGRAM_CREATED = of("program.created") + + /** Occurs whenever a Program is updated. */ + @JvmField val PROGRAM_UPDATED = of("program.updated") + /** Occurs whenever a Proof of Authorization Request is created. */ @JvmField val PROOF_OF_AUTHORIZATION_REQUEST_CREATED = @@ -893,6 +899,10 @@ private constructor( PHYSICAL_CARD_PROFILE_CREATED, /** Occurs whenever a Physical Card Profile is updated. */ PHYSICAL_CARD_PROFILE_UPDATED, + /** Occurs whenever a Program is created. */ + PROGRAM_CREATED, + /** Occurs whenever a Program is updated. */ + PROGRAM_UPDATED, /** Occurs whenever a Proof of Authorization Request is created. */ PROOF_OF_AUTHORIZATION_REQUEST_CREATED, /** Occurs whenever a Proof of Authorization Request is updated. */ @@ -1113,6 +1123,10 @@ private constructor( PHYSICAL_CARD_PROFILE_CREATED, /** Occurs whenever a Physical Card Profile is updated. */ PHYSICAL_CARD_PROFILE_UPDATED, + /** Occurs whenever a Program is created. */ + PROGRAM_CREATED, + /** Occurs whenever a Program is updated. */ + PROGRAM_UPDATED, /** Occurs whenever a Proof of Authorization Request is created. */ PROOF_OF_AUTHORIZATION_REQUEST_CREATED, /** Occurs whenever a Proof of Authorization Request is updated. */ @@ -1255,6 +1269,8 @@ private constructor( PHYSICAL_CARD_UPDATED -> Value.PHYSICAL_CARD_UPDATED PHYSICAL_CARD_PROFILE_CREATED -> Value.PHYSICAL_CARD_PROFILE_CREATED PHYSICAL_CARD_PROFILE_UPDATED -> Value.PHYSICAL_CARD_PROFILE_UPDATED + PROGRAM_CREATED -> Value.PROGRAM_CREATED + PROGRAM_UPDATED -> Value.PROGRAM_UPDATED PROOF_OF_AUTHORIZATION_REQUEST_CREATED -> Value.PROOF_OF_AUTHORIZATION_REQUEST_CREATED PROOF_OF_AUTHORIZATION_REQUEST_UPDATED -> @@ -1376,6 +1392,8 @@ private constructor( PHYSICAL_CARD_UPDATED -> Known.PHYSICAL_CARD_UPDATED PHYSICAL_CARD_PROFILE_CREATED -> Known.PHYSICAL_CARD_PROFILE_CREATED PHYSICAL_CARD_PROFILE_UPDATED -> Known.PHYSICAL_CARD_PROFILE_UPDATED + PROGRAM_CREATED -> Known.PROGRAM_CREATED + PROGRAM_UPDATED -> Known.PROGRAM_UPDATED PROOF_OF_AUTHORIZATION_REQUEST_CREATED -> Known.PROOF_OF_AUTHORIZATION_REQUEST_CREATED PROOF_OF_AUTHORIZATION_REQUEST_UPDATED -> diff --git a/increase-java-core/src/main/kotlin/com/increase/api/models/events/EventListParams.kt b/increase-java-core/src/main/kotlin/com/increase/api/models/events/EventListParams.kt index fc0896ea1..0487ae794 100644 --- a/increase-java-core/src/main/kotlin/com/increase/api/models/events/EventListParams.kt +++ b/increase-java-core/src/main/kotlin/com/increase/api/models/events/EventListParams.kt @@ -652,6 +652,12 @@ private constructor( /** Occurs whenever a Physical Card Profile is updated. */ @JvmField val PHYSICAL_CARD_PROFILE_UPDATED = of("physical_card_profile.updated") + /** Occurs whenever a Program is created. */ + @JvmField val PROGRAM_CREATED = of("program.created") + + /** Occurs whenever a Program is updated. */ + @JvmField val PROGRAM_UPDATED = of("program.updated") + /** Occurs whenever a Proof of Authorization Request is created. */ @JvmField val PROOF_OF_AUTHORIZATION_REQUEST_CREATED = @@ -905,6 +911,10 @@ private constructor( PHYSICAL_CARD_PROFILE_CREATED, /** Occurs whenever a Physical Card Profile is updated. */ PHYSICAL_CARD_PROFILE_UPDATED, + /** Occurs whenever a Program is created. */ + PROGRAM_CREATED, + /** Occurs whenever a Program is updated. */ + PROGRAM_UPDATED, /** Occurs whenever a Proof of Authorization Request is created. */ PROOF_OF_AUTHORIZATION_REQUEST_CREATED, /** Occurs whenever a Proof of Authorization Request is updated. */ @@ -1127,6 +1137,10 @@ private constructor( PHYSICAL_CARD_PROFILE_CREATED, /** Occurs whenever a Physical Card Profile is updated. */ PHYSICAL_CARD_PROFILE_UPDATED, + /** Occurs whenever a Program is created. */ + PROGRAM_CREATED, + /** Occurs whenever a Program is updated. */ + PROGRAM_UPDATED, /** Occurs whenever a Proof of Authorization Request is created. */ PROOF_OF_AUTHORIZATION_REQUEST_CREATED, /** Occurs whenever a Proof of Authorization Request is updated. */ @@ -1272,6 +1286,8 @@ private constructor( PHYSICAL_CARD_UPDATED -> Value.PHYSICAL_CARD_UPDATED PHYSICAL_CARD_PROFILE_CREATED -> Value.PHYSICAL_CARD_PROFILE_CREATED PHYSICAL_CARD_PROFILE_UPDATED -> Value.PHYSICAL_CARD_PROFILE_UPDATED + PROGRAM_CREATED -> Value.PROGRAM_CREATED + PROGRAM_UPDATED -> Value.PROGRAM_UPDATED PROOF_OF_AUTHORIZATION_REQUEST_CREATED -> Value.PROOF_OF_AUTHORIZATION_REQUEST_CREATED PROOF_OF_AUTHORIZATION_REQUEST_UPDATED -> @@ -1394,6 +1410,8 @@ private constructor( PHYSICAL_CARD_UPDATED -> Known.PHYSICAL_CARD_UPDATED PHYSICAL_CARD_PROFILE_CREATED -> Known.PHYSICAL_CARD_PROFILE_CREATED PHYSICAL_CARD_PROFILE_UPDATED -> Known.PHYSICAL_CARD_PROFILE_UPDATED + PROGRAM_CREATED -> Known.PROGRAM_CREATED + PROGRAM_UPDATED -> Known.PROGRAM_UPDATED PROOF_OF_AUTHORIZATION_REQUEST_CREATED -> Known.PROOF_OF_AUTHORIZATION_REQUEST_CREATED PROOF_OF_AUTHORIZATION_REQUEST_UPDATED -> diff --git a/increase-java-core/src/main/kotlin/com/increase/api/models/eventsubscriptions/EventSubscription.kt b/increase-java-core/src/main/kotlin/com/increase/api/models/eventsubscriptions/EventSubscription.kt index 92f8df847..fbbf2e331 100644 --- a/increase-java-core/src/main/kotlin/com/increase/api/models/eventsubscriptions/EventSubscription.kt +++ b/increase-java-core/src/main/kotlin/com/increase/api/models/eventsubscriptions/EventSubscription.kt @@ -753,6 +753,12 @@ private constructor( /** Occurs whenever a Physical Card Profile is updated. */ @JvmField val PHYSICAL_CARD_PROFILE_UPDATED = of("physical_card_profile.updated") + /** Occurs whenever a Program is created. */ + @JvmField val PROGRAM_CREATED = of("program.created") + + /** Occurs whenever a Program is updated. */ + @JvmField val PROGRAM_UPDATED = of("program.updated") + /** Occurs whenever a Proof of Authorization Request is created. */ @JvmField val PROOF_OF_AUTHORIZATION_REQUEST_CREATED = @@ -1004,6 +1010,10 @@ private constructor( PHYSICAL_CARD_PROFILE_CREATED, /** Occurs whenever a Physical Card Profile is updated. */ PHYSICAL_CARD_PROFILE_UPDATED, + /** Occurs whenever a Program is created. */ + PROGRAM_CREATED, + /** Occurs whenever a Program is updated. */ + PROGRAM_UPDATED, /** Occurs whenever a Proof of Authorization Request is created. */ PROOF_OF_AUTHORIZATION_REQUEST_CREATED, /** Occurs whenever a Proof of Authorization Request is updated. */ @@ -1225,6 +1235,10 @@ private constructor( PHYSICAL_CARD_PROFILE_CREATED, /** Occurs whenever a Physical Card Profile is updated. */ PHYSICAL_CARD_PROFILE_UPDATED, + /** Occurs whenever a Program is created. */ + PROGRAM_CREATED, + /** Occurs whenever a Program is updated. */ + PROGRAM_UPDATED, /** Occurs whenever a Proof of Authorization Request is created. */ PROOF_OF_AUTHORIZATION_REQUEST_CREATED, /** Occurs whenever a Proof of Authorization Request is updated. */ @@ -1370,6 +1384,8 @@ private constructor( PHYSICAL_CARD_UPDATED -> Value.PHYSICAL_CARD_UPDATED PHYSICAL_CARD_PROFILE_CREATED -> Value.PHYSICAL_CARD_PROFILE_CREATED PHYSICAL_CARD_PROFILE_UPDATED -> Value.PHYSICAL_CARD_PROFILE_UPDATED + PROGRAM_CREATED -> Value.PROGRAM_CREATED + PROGRAM_UPDATED -> Value.PROGRAM_UPDATED PROOF_OF_AUTHORIZATION_REQUEST_CREATED -> Value.PROOF_OF_AUTHORIZATION_REQUEST_CREATED PROOF_OF_AUTHORIZATION_REQUEST_UPDATED -> @@ -1491,6 +1507,8 @@ private constructor( PHYSICAL_CARD_UPDATED -> Known.PHYSICAL_CARD_UPDATED PHYSICAL_CARD_PROFILE_CREATED -> Known.PHYSICAL_CARD_PROFILE_CREATED PHYSICAL_CARD_PROFILE_UPDATED -> Known.PHYSICAL_CARD_PROFILE_UPDATED + PROGRAM_CREATED -> Known.PROGRAM_CREATED + PROGRAM_UPDATED -> Known.PROGRAM_UPDATED PROOF_OF_AUTHORIZATION_REQUEST_CREATED -> Known.PROOF_OF_AUTHORIZATION_REQUEST_CREATED PROOF_OF_AUTHORIZATION_REQUEST_UPDATED -> diff --git a/increase-java-core/src/main/kotlin/com/increase/api/models/eventsubscriptions/EventSubscriptionCreateParams.kt b/increase-java-core/src/main/kotlin/com/increase/api/models/eventsubscriptions/EventSubscriptionCreateParams.kt index 2661e3269..996e90a92 100644 --- a/increase-java-core/src/main/kotlin/com/increase/api/models/eventsubscriptions/EventSubscriptionCreateParams.kt +++ b/increase-java-core/src/main/kotlin/com/increase/api/models/eventsubscriptions/EventSubscriptionCreateParams.kt @@ -919,6 +919,12 @@ private constructor( /** Occurs whenever a Physical Card Profile is updated. */ @JvmField val PHYSICAL_CARD_PROFILE_UPDATED = of("physical_card_profile.updated") + /** Occurs whenever a Program is created. */ + @JvmField val PROGRAM_CREATED = of("program.created") + + /** Occurs whenever a Program is updated. */ + @JvmField val PROGRAM_UPDATED = of("program.updated") + /** Occurs whenever a Proof of Authorization Request is created. */ @JvmField val PROOF_OF_AUTHORIZATION_REQUEST_CREATED = @@ -1170,6 +1176,10 @@ private constructor( PHYSICAL_CARD_PROFILE_CREATED, /** Occurs whenever a Physical Card Profile is updated. */ PHYSICAL_CARD_PROFILE_UPDATED, + /** Occurs whenever a Program is created. */ + PROGRAM_CREATED, + /** Occurs whenever a Program is updated. */ + PROGRAM_UPDATED, /** Occurs whenever a Proof of Authorization Request is created. */ PROOF_OF_AUTHORIZATION_REQUEST_CREATED, /** Occurs whenever a Proof of Authorization Request is updated. */ @@ -1391,6 +1401,10 @@ private constructor( PHYSICAL_CARD_PROFILE_CREATED, /** Occurs whenever a Physical Card Profile is updated. */ PHYSICAL_CARD_PROFILE_UPDATED, + /** Occurs whenever a Program is created. */ + PROGRAM_CREATED, + /** Occurs whenever a Program is updated. */ + PROGRAM_UPDATED, /** Occurs whenever a Proof of Authorization Request is created. */ PROOF_OF_AUTHORIZATION_REQUEST_CREATED, /** Occurs whenever a Proof of Authorization Request is updated. */ @@ -1536,6 +1550,8 @@ private constructor( PHYSICAL_CARD_UPDATED -> Value.PHYSICAL_CARD_UPDATED PHYSICAL_CARD_PROFILE_CREATED -> Value.PHYSICAL_CARD_PROFILE_CREATED PHYSICAL_CARD_PROFILE_UPDATED -> Value.PHYSICAL_CARD_PROFILE_UPDATED + PROGRAM_CREATED -> Value.PROGRAM_CREATED + PROGRAM_UPDATED -> Value.PROGRAM_UPDATED PROOF_OF_AUTHORIZATION_REQUEST_CREATED -> Value.PROOF_OF_AUTHORIZATION_REQUEST_CREATED PROOF_OF_AUTHORIZATION_REQUEST_UPDATED -> @@ -1657,6 +1673,8 @@ private constructor( PHYSICAL_CARD_UPDATED -> Known.PHYSICAL_CARD_UPDATED PHYSICAL_CARD_PROFILE_CREATED -> Known.PHYSICAL_CARD_PROFILE_CREATED PHYSICAL_CARD_PROFILE_UPDATED -> Known.PHYSICAL_CARD_PROFILE_UPDATED + PROGRAM_CREATED -> Known.PROGRAM_CREATED + PROGRAM_UPDATED -> Known.PROGRAM_UPDATED PROOF_OF_AUTHORIZATION_REQUEST_CREATED -> Known.PROOF_OF_AUTHORIZATION_REQUEST_CREATED PROOF_OF_AUTHORIZATION_REQUEST_UPDATED -> diff --git a/increase-java-core/src/main/kotlin/com/increase/api/models/files/FileCreateParams.kt b/increase-java-core/src/main/kotlin/com/increase/api/models/files/FileCreateParams.kt index ae285291b..962f137c5 100644 --- a/increase-java-core/src/main/kotlin/com/increase/api/models/files/FileCreateParams.kt +++ b/increase-java-core/src/main/kotlin/com/increase/api/models/files/FileCreateParams.kt @@ -2,11 +2,14 @@ package com.increase.api.models.files +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.increase.api.core.Enum import com.increase.api.core.ExcludeMissing import com.increase.api.core.JsonField +import com.increase.api.core.JsonValue import com.increase.api.core.MultipartField import com.increase.api.core.Params import com.increase.api.core.checkRequired @@ -16,6 +19,7 @@ import com.increase.api.core.toImmutable import com.increase.api.errors.IncreaseInvalidDataException import java.io.InputStream import java.nio.file.Path +import java.util.Collections import java.util.Objects import java.util.Optional import kotlin.io.path.inputStream @@ -81,6 +85,8 @@ private constructor( */ fun _description(): MultipartField = body._description() + fun _additionalBodyProperties(): Map = body._additionalProperties() + fun _additionalHeaders(): Headers = additionalHeaders fun _additionalQueryParams(): QueryParams = additionalQueryParams @@ -181,6 +187,25 @@ private constructor( body.description(description) } + 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) @@ -297,7 +322,8 @@ private constructor( } fun _body(): Map> = - mapOf("file" to _file(), "purpose" to _purpose(), "description" to _description()) + (mapOf("file" to _file(), "purpose" to _purpose(), "description" to _description()) + + _additionalBodyProperties().mapValues { MultipartField.of(it) }) .toImmutable() override fun _headers(): Headers = additionalHeaders @@ -309,6 +335,7 @@ private constructor( private val file: MultipartField, private val purpose: MultipartField, private val description: MultipartField, + private val additionalProperties: MutableMap, ) { /** @@ -362,6 +389,16 @@ private constructor( @ExcludeMissing fun _description(): MultipartField = description + @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 { @@ -384,12 +421,14 @@ private constructor( private var file: MultipartField? = null private var purpose: MultipartField? = null private var description: MultipartField = MultipartField.of(null) + private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(body: Body) = apply { file = body.file purpose = body.purpose description = body.description + additionalProperties = body.additionalProperties.toMutableMap() } /** @@ -454,6 +493,25 @@ private constructor( this.description = description } + 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) = apply { + keys.forEach(::removeAdditionalProperty) + } + /** * Returns an immutable instance of [Body]. * @@ -468,7 +526,12 @@ private constructor( * @throws IllegalStateException if any required field is unset. */ fun build(): Body = - Body(checkRequired("file", file), checkRequired("purpose", purpose), description) + Body( + checkRequired("file", file), + checkRequired("purpose", purpose), + description, + additionalProperties.toMutableMap(), + ) } private var validated: Boolean = false @@ -497,16 +560,17 @@ private constructor( return true } - return /* spotless:off */ other is Body && file == other.file && purpose == other.purpose && description == other.description /* spotless:on */ + return /* spotless:off */ other is Body && file == other.file && purpose == other.purpose && description == other.description && additionalProperties == other.additionalProperties /* spotless:on */ } /* spotless:off */ - private val hashCode: Int by lazy { Objects.hash(file, purpose, description) } + private val hashCode: Int by lazy { Objects.hash(file, purpose, description, additionalProperties) } /* spotless:on */ override fun hashCode(): Int = hashCode - override fun toString() = "Body{file=$file, purpose=$purpose, description=$description}" + override fun toString() = + "Body{file=$file, purpose=$purpose, description=$description, additionalProperties=$additionalProperties}" } /** What the File will be used for in Increase's systems. */