diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b7046597..c9acbd5b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,12 +1,14 @@ name: CI on: push: - branches-ignore: - - 'generated' - - 'codegen/**' - - 'integrated/**' - - 'stl-preview-head/**' - - 'stl-preview-base/**' + branches: + - '**' + - '!integrated/**' + - '!stl-preview-head/**' + - '!stl-preview-base/**' + - '!generated' + - '!codegen/**' + - 'codegen/stl/**' pull_request: branches-ignore: - 'stl-preview-head/**' @@ -17,7 +19,7 @@ jobs: timeout-minutes: 15 name: lint runs-on: ${{ github.repository == 'stainless-sdks/courier-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 @@ -44,7 +46,7 @@ jobs: contents: read id-token: write runs-on: ${{ github.repository == 'stainless-sdks/courier-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/.gitignore b/.gitignore index b1346e6d..90b85e94 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .prism.log +.stdy.log .gradle .idea .kotlin diff --git a/.release-please-manifest.json b/.release-please-manifest.json index ad56a78c..a43b15a4 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "4.10.0" + ".": "4.11.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 75c12180..51d97c36 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 83 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/courier%2Fcourier-19330fca8fa9bbae835ec9d9f83b37b3df364d9b462090b9623bfc9b6eae99c2.yml -openapi_spec_hash: 0bc6889464c9ac2542b4837f569c1837 -config_hash: 1ae49ed522c8423378d9463cdd0fb880 +configured_endpoints: 88 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/courier%2Fcourier-288ef53fff4d0cc92b3ac14bc1e03dc41c112b55634713adb75158b1c97c4576.yml +openapi_spec_hash: 5c4fed9a1639a6cdfcb5adaf666c9ed6 +config_hash: a0ecf9dfbd637db38508b3de2b81aeeb diff --git a/CHANGELOG.md b/CHANGELOG.md index 712ef68f..887e51e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,32 @@ # Changelog +## 4.11.0 (2026-03-25) + +Full Changelog: [v4.10.0...v4.11.0](https://github.com/trycourier/courier-java/compare/v4.10.0...v4.11.0) + +### Features + +* **api:** add create/retrieve/archive/publish/replace methods, event_id param to notifications ([d0341ec](https://github.com/trycourier/courier-java/commit/d0341ecd91cd175c1fbd252f3f5caa4961a38a11)) + + +### Bug Fixes + +* **client:** allow updating header/query affecting fields in `toBuilder()` ([ed456e5](https://github.com/trycourier/courier-java/commit/ed456e5be6b63dd0c16ddf1e5c90dde476d4d7e5)) + + +### Chores + +* **ci:** skip lint on metadata-only changes ([2b3cd27](https://github.com/trycourier/courier-java/commit/2b3cd2798e31d09d6e0d329e3bb46f45a73c9aac)) +* **internal:** bump ktfmt ([affb7da](https://github.com/trycourier/courier-java/commit/affb7dae80ab5957a15a0b497dcf1afd3146eec7)) +* **internal:** tweak CI branches ([1bd9068](https://github.com/trycourier/courier-java/commit/1bd906869c298547c59c2ffbc0f0ef0e37958206)) +* **internal:** update gitignore ([d801bca](https://github.com/trycourier/courier-java/commit/d801bca833d04aa2adb2f9bb4df7b6777cfb022a)) +* **internal:** update retry delay tests ([e3ecdf0](https://github.com/trycourier/courier-java/commit/e3ecdf0b1b898a83eb234cb289db18e51cfd8982)) + + +### Documentation + +* sync README from mintlify-docs (2026-03-23 19:31 UTC) ([#95](https://github.com/trycourier/courier-java/issues/95)) ([8efc854](https://github.com/trycourier/courier-java/commit/8efc8542cbe37b8ba7673d53a37995625e574785)) + ## 4.10.0 (2026-03-12) Full Changelog: [v4.9.1...v4.10.0](https://github.com/trycourier/courier-java/compare/v4.9.1...v4.10.0) diff --git a/build.gradle.kts b/build.gradle.kts index 653fe829..16f27348 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,7 +8,7 @@ repositories { allprojects { group = "com.courier" - version = "4.10.0" // x-release-please-version + version = "4.11.0" // x-release-please-version } subprojects { diff --git a/buildSrc/src/main/kotlin/courier.kotlin.gradle.kts b/buildSrc/src/main/kotlin/courier.kotlin.gradle.kts index 9de64f25..28ed4760 100644 --- a/buildSrc/src/main/kotlin/courier.kotlin.gradle.kts +++ b/buildSrc/src/main/kotlin/courier.kotlin.gradle.kts @@ -40,7 +40,7 @@ tasks.withType().configureEach { val ktfmt by configurations.creating dependencies { - ktfmt("com.facebook:ktfmt:0.56") + ktfmt("com.facebook:ktfmt:0.61") } fun registerKtfmt( diff --git a/courier-java-core/src/main/kotlin/com/courier/core/ClientOptions.kt b/courier-java-core/src/main/kotlin/com/courier/core/ClientOptions.kt index 122fde64..bee20967 100644 --- a/courier-java-core/src/main/kotlin/com/courier/core/ClientOptions.kt +++ b/courier-java-core/src/main/kotlin/com/courier/core/ClientOptions.kt @@ -403,13 +403,14 @@ private constructor( headers.put("X-Stainless-Runtime", "JRE") headers.put("X-Stainless-Runtime-Version", getJavaVersion()) headers.put("X-Stainless-Kotlin-Version", KotlinVersion.CURRENT.toString()) + // We replace after all the default headers to allow end-users to overwrite them. + headers.replaceAll(this.headers.build()) + queryParams.replaceAll(this.queryParams.build()) apiKey.let { if (!it.isEmpty()) { - headers.put("Authorization", "Bearer $it") + headers.replace("Authorization", "Bearer $it") } } - headers.replaceAll(this.headers.build()) - queryParams.replaceAll(this.queryParams.build()) return ClientOptions( httpClient, diff --git a/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationArchiveParams.kt b/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationArchiveParams.kt new file mode 100644 index 00000000..d27b7f60 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationArchiveParams.kt @@ -0,0 +1,232 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.notifications + +import com.courier.core.JsonValue +import com.courier.core.Params +import com.courier.core.http.Headers +import com.courier.core.http.QueryParams +import com.courier.core.toImmutable +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Archive a notification template. */ +class NotificationArchiveParams +private constructor( + private val id: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, + private val additionalBodyProperties: Map, +) : Params { + + fun id(): Optional = Optional.ofNullable(id) + + /** Additional body properties to send with the request. */ + fun _additionalBodyProperties(): Map = additionalBodyProperties + + /** 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(): NotificationArchiveParams = builder().build() + + /** + * Returns a mutable builder for constructing an instance of [NotificationArchiveParams]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [NotificationArchiveParams]. */ + class Builder internal constructor() { + + private var id: String? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + private var additionalBodyProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(notificationArchiveParams: NotificationArchiveParams) = apply { + id = notificationArchiveParams.id + additionalHeaders = notificationArchiveParams.additionalHeaders.toBuilder() + additionalQueryParams = notificationArchiveParams.additionalQueryParams.toBuilder() + additionalBodyProperties = + notificationArchiveParams.additionalBodyProperties.toMutableMap() + } + + fun id(id: String?) = apply { this.id = id } + + /** Alias for calling [Builder.id] with `id.orElse(null)`. */ + fun id(id: Optional) = id(id.getOrNull()) + + 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) + } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + this.additionalBodyProperties.clear() + putAllAdditionalBodyProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + additionalBodyProperties.put(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + this.additionalBodyProperties.putAll(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { + additionalBodyProperties.remove(key) + } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalBodyProperty) + } + + /** + * Returns an immutable instance of [NotificationArchiveParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): NotificationArchiveParams = + NotificationArchiveParams( + id, + additionalHeaders.build(), + additionalQueryParams.build(), + additionalBodyProperties.toImmutable(), + ) + } + + fun _body(): Optional> = + Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) + + fun _pathParam(index: Int): String = + when (index) { + 0 -> id ?: "" + else -> "" + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is NotificationArchiveParams && + id == other.id && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams && + additionalBodyProperties == other.additionalBodyProperties + } + + override fun hashCode(): Int = + Objects.hash(id, additionalHeaders, additionalQueryParams, additionalBodyProperties) + + override fun toString() = + "NotificationArchiveParams{id=$id, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationCreateParams.kt b/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationCreateParams.kt new file mode 100644 index 00000000..8c1ebbd1 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationCreateParams.kt @@ -0,0 +1,214 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.notifications + +import com.courier.core.JsonValue +import com.courier.core.Params +import com.courier.core.checkRequired +import com.courier.core.http.Headers +import com.courier.core.http.QueryParams +import java.util.Objects + +/** + * Create a notification template. Requires all fields in the notification object. Templates are + * created in draft state by default. + */ +class NotificationCreateParams +private constructor( + private val notificationTemplateCreateRequest: NotificationTemplateCreateRequest, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** Request body for creating a notification template. */ + fun notificationTemplateCreateRequest(): NotificationTemplateCreateRequest = + notificationTemplateCreateRequest + + fun _additionalBodyProperties(): Map = + notificationTemplateCreateRequest._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 { + + /** + * Returns a mutable builder for constructing an instance of [NotificationCreateParams]. + * + * The following fields are required: + * ```java + * .notificationTemplateCreateRequest() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [NotificationCreateParams]. */ + class Builder internal constructor() { + + private var notificationTemplateCreateRequest: NotificationTemplateCreateRequest? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(notificationCreateParams: NotificationCreateParams) = apply { + notificationTemplateCreateRequest = + notificationCreateParams.notificationTemplateCreateRequest + additionalHeaders = notificationCreateParams.additionalHeaders.toBuilder() + additionalQueryParams = notificationCreateParams.additionalQueryParams.toBuilder() + } + + /** Request body for creating a notification template. */ + fun notificationTemplateCreateRequest( + notificationTemplateCreateRequest: NotificationTemplateCreateRequest + ) = apply { this.notificationTemplateCreateRequest = notificationTemplateCreateRequest } + + 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 [NotificationCreateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .notificationTemplateCreateRequest() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): NotificationCreateParams = + NotificationCreateParams( + checkRequired( + "notificationTemplateCreateRequest", + notificationTemplateCreateRequest, + ), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): NotificationTemplateCreateRequest = notificationTemplateCreateRequest + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is NotificationCreateParams && + notificationTemplateCreateRequest == other.notificationTemplateCreateRequest && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(notificationTemplateCreateRequest, additionalHeaders, additionalQueryParams) + + override fun toString() = + "NotificationCreateParams{notificationTemplateCreateRequest=$notificationTemplateCreateRequest, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationListParams.kt b/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationListParams.kt index 96d1ad00..6e86a5b2 100644 --- a/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationListParams.kt +++ b/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationListParams.kt @@ -9,17 +9,23 @@ import java.util.Objects import java.util.Optional import kotlin.jvm.optionals.getOrNull +/** List notification templates in your workspace. */ class NotificationListParams private constructor( private val cursor: String?, + private val eventId: String?, private val notes: Boolean?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, ) : Params { + /** Opaque pagination cursor from a previous response. Omit for the first page. */ fun cursor(): Optional = Optional.ofNullable(cursor) - /** Retrieve the notes from the Notification template settings. */ + /** Filter to templates linked to this event map ID. */ + fun eventId(): Optional = Optional.ofNullable(eventId) + + /** Include template notes in the response. Only applies to legacy templates. */ fun notes(): Optional = Optional.ofNullable(notes) /** Additional headers to send with the request. */ @@ -42,6 +48,7 @@ private constructor( class Builder internal constructor() { private var cursor: String? = null + private var eventId: String? = null private var notes: Boolean? = null private var additionalHeaders: Headers.Builder = Headers.builder() private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @@ -49,17 +56,25 @@ private constructor( @JvmSynthetic internal fun from(notificationListParams: NotificationListParams) = apply { cursor = notificationListParams.cursor + eventId = notificationListParams.eventId notes = notificationListParams.notes additionalHeaders = notificationListParams.additionalHeaders.toBuilder() additionalQueryParams = notificationListParams.additionalQueryParams.toBuilder() } + /** Opaque pagination cursor from a previous response. Omit for the first page. */ fun cursor(cursor: String?) = apply { this.cursor = cursor } /** Alias for calling [Builder.cursor] with `cursor.orElse(null)`. */ fun cursor(cursor: Optional) = cursor(cursor.getOrNull()) - /** Retrieve the notes from the Notification template settings. */ + /** Filter to templates linked to this event map ID. */ + fun eventId(eventId: String?) = apply { this.eventId = eventId } + + /** Alias for calling [Builder.eventId] with `eventId.orElse(null)`. */ + fun eventId(eventId: Optional) = eventId(eventId.getOrNull()) + + /** Include template notes in the response. Only applies to legacy templates. */ fun notes(notes: Boolean?) = apply { this.notes = notes } /** @@ -178,6 +193,7 @@ private constructor( fun build(): NotificationListParams = NotificationListParams( cursor, + eventId, notes, additionalHeaders.build(), additionalQueryParams.build(), @@ -190,6 +206,7 @@ private constructor( QueryParams.builder() .apply { cursor?.let { put("cursor", it) } + eventId?.let { put("event_id", it) } notes?.let { put("notes", it.toString()) } putAll(additionalQueryParams) } @@ -202,14 +219,15 @@ private constructor( return other is NotificationListParams && cursor == other.cursor && + eventId == other.eventId && notes == other.notes && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams } override fun hashCode(): Int = - Objects.hash(cursor, notes, additionalHeaders, additionalQueryParams) + Objects.hash(cursor, eventId, notes, additionalHeaders, additionalQueryParams) override fun toString() = - "NotificationListParams{cursor=$cursor, notes=$notes, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" + "NotificationListParams{cursor=$cursor, eventId=$eventId, notes=$notes, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationListResponse.kt b/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationListResponse.kt index 6746aadd..65dd898b 100644 --- a/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationListResponse.kt +++ b/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationListResponse.kt @@ -2,12 +2,16 @@ package com.courier.models.notifications +import com.courier.core.BaseDeserializer +import com.courier.core.BaseSerializer import com.courier.core.ExcludeMissing import com.courier.core.JsonField import com.courier.core.JsonMissing import com.courier.core.JsonValue +import com.courier.core.allMaxBy import com.courier.core.checkKnown import com.courier.core.checkRequired +import com.courier.core.getOrThrow import com.courier.core.toImmutable import com.courier.errors.CourierInvalidDataException import com.courier.models.MessageRouting @@ -16,6 +20,13 @@ 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.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.ObjectCodec +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.SerializerProvider +import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import com.fasterxml.jackson.databind.annotation.JsonSerialize +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import java.util.Collections import java.util.Objects import java.util.Optional @@ -42,6 +53,8 @@ private constructor( fun paging(): Paging = paging.getRequired("paging") /** + * Notification templates in this workspace. + * * @throws CourierInvalidDataException if the JSON field has an unexpected type or is * unexpectedly missing or null (e.g. if the server responded with an unexpected value). */ @@ -111,6 +124,7 @@ private constructor( */ fun paging(paging: JsonField) = apply { this.paging = paging } + /** Notification templates in this workspace. */ fun results(results: List) = results(JsonField.of(results)) /** @@ -136,6 +150,17 @@ private constructor( } } + /** Alias for calling [addResult] with `Result.ofNotification(notification)`. */ + fun addResult(notification: Result.Notification) = + addResult(Result.ofNotification(notification)) + + /** + * Alias for calling [addResult] with + * `Result.ofNotificationTemplateSummary(notificationTemplateSummary)`. + */ + fun addResult(notificationTemplateSummary: NotificationTemplateSummary) = + addResult(Result.ofNotificationTemplateSummary(notificationTemplateSummary)) + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() putAllAdditionalProperties(additionalProperties) @@ -206,475 +231,383 @@ private constructor( (paging.asKnown().getOrNull()?.validity() ?: 0) + (results.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + /** V2 (CDS) template summary returned in list responses. */ + @JsonDeserialize(using = Result.Deserializer::class) + @JsonSerialize(using = Result.Serializer::class) class Result - @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( - private val id: JsonField, - private val createdAt: JsonField, - private val eventIds: JsonField>, - private val note: JsonField, - private val routing: JsonField, - private val topicId: JsonField, - private val updatedAt: JsonField, - private val tags: JsonField, - private val title: JsonField, - private val additionalProperties: MutableMap, + private val notification: Notification? = null, + private val notificationTemplateSummary: NotificationTemplateSummary? = null, + private val _json: JsonValue? = null, ) { - @JsonCreator - private constructor( - @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), - @JsonProperty("created_at") - @ExcludeMissing - createdAt: JsonField = JsonMissing.of(), - @JsonProperty("event_ids") - @ExcludeMissing - eventIds: JsonField> = JsonMissing.of(), - @JsonProperty("note") @ExcludeMissing note: JsonField = JsonMissing.of(), - @JsonProperty("routing") - @ExcludeMissing - routing: JsonField = JsonMissing.of(), - @JsonProperty("topic_id") @ExcludeMissing topicId: JsonField = JsonMissing.of(), - @JsonProperty("updated_at") - @ExcludeMissing - updatedAt: JsonField = JsonMissing.of(), - @JsonProperty("tags") @ExcludeMissing tags: JsonField = JsonMissing.of(), - @JsonProperty("title") @ExcludeMissing title: JsonField = JsonMissing.of(), - ) : this( - id, - createdAt, - eventIds, - note, - routing, - topicId, - updatedAt, - tags, - title, - mutableMapOf(), - ) + fun notification(): Optional = Optional.ofNullable(notification) - /** - * @throws CourierInvalidDataException 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 id(): String = id.getRequired("id") + /** V2 (CDS) template summary returned in list responses. */ + fun notificationTemplateSummary(): Optional = + Optional.ofNullable(notificationTemplateSummary) - /** - * @throws CourierInvalidDataException 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 createdAt(): Long = createdAt.getRequired("created_at") + fun isNotification(): Boolean = notification != null - /** - * Array of event IDs associated with this notification - * - * @throws CourierInvalidDataException 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 eventIds(): List = eventIds.getRequired("event_ids") + fun isNotificationTemplateSummary(): Boolean = notificationTemplateSummary != null - /** - * @throws CourierInvalidDataException 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 note(): String = note.getRequired("note") + fun asNotification(): Notification = notification.getOrThrow("notification") - /** - * @throws CourierInvalidDataException 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 routing(): MessageRouting = routing.getRequired("routing") + /** V2 (CDS) template summary returned in list responses. */ + fun asNotificationTemplateSummary(): NotificationTemplateSummary = + notificationTemplateSummary.getOrThrow("notificationTemplateSummary") - /** - * @throws CourierInvalidDataException 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 topicId(): String = topicId.getRequired("topic_id") + fun _json(): Optional = Optional.ofNullable(_json) - /** - * @throws CourierInvalidDataException 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 updatedAt(): Long = updatedAt.getRequired("updated_at") + fun accept(visitor: Visitor): T = + when { + notification != null -> visitor.visitNotification(notification) + notificationTemplateSummary != null -> + visitor.visitNotificationTemplateSummary(notificationTemplateSummary) + else -> visitor.unknown(_json) + } - /** - * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun tags(): Optional = tags.getOptional("tags") + private var validated: Boolean = false - /** - * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun title(): Optional = title.getOptional("title") + fun validate(): Result = apply { + if (validated) { + return@apply + } - /** - * Returns the raw JSON value of [id]. - * - * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + accept( + object : Visitor { + override fun visitNotification(notification: Notification) { + notification.validate() + } - /** - * Returns the raw JSON value of [createdAt]. - * - * Unlike [createdAt], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("created_at") @ExcludeMissing fun _createdAt(): JsonField = createdAt + override fun visitNotificationTemplateSummary( + notificationTemplateSummary: NotificationTemplateSummary + ) { + notificationTemplateSummary.validate() + } + } + ) + validated = true + } - /** - * Returns the raw JSON value of [eventIds]. - * - * Unlike [eventIds], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("event_ids") - @ExcludeMissing - fun _eventIds(): JsonField> = eventIds + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + false + } /** - * Returns the raw JSON value of [note]. + * Returns a score indicating how many valid values are contained in this object + * recursively. * - * Unlike [note], this method doesn't throw if the JSON field has an unexpected type. + * Used for best match union deserialization. */ - @JsonProperty("note") @ExcludeMissing fun _note(): JsonField = note + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitNotification(notification: Notification) = + notification.validity() - /** - * Returns the raw JSON value of [routing]. - * - * Unlike [routing], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("routing") @ExcludeMissing fun _routing(): JsonField = routing + override fun visitNotificationTemplateSummary( + notificationTemplateSummary: NotificationTemplateSummary + ) = notificationTemplateSummary.validity() - /** - * Returns the raw JSON value of [topicId]. - * - * Unlike [topicId], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("topic_id") @ExcludeMissing fun _topicId(): JsonField = topicId + override fun unknown(json: JsonValue?) = 0 + } + ) - /** - * Returns the raw JSON value of [updatedAt]. - * - * Unlike [updatedAt], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("updated_at") @ExcludeMissing fun _updatedAt(): JsonField = updatedAt + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - /** - * Returns the raw JSON value of [tags]. - * - * Unlike [tags], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("tags") @ExcludeMissing fun _tags(): JsonField = tags + return other is Result && + notification == other.notification && + notificationTemplateSummary == other.notificationTemplateSummary + } - /** - * Returns the raw JSON value of [title]. - * - * Unlike [title], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("title") @ExcludeMissing fun _title(): JsonField = title + override fun hashCode(): Int = Objects.hash(notification, notificationTemplateSummary) - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) + override fun toString(): String = + when { + notification != null -> "Result{notification=$notification}" + notificationTemplateSummary != null -> + "Result{notificationTemplateSummary=$notificationTemplateSummary}" + _json != null -> "Result{_unknown=$_json}" + else -> throw IllegalStateException("Invalid Result") + } + + companion object { + + @JvmStatic + fun ofNotification(notification: Notification) = Result(notification = notification) + + /** V2 (CDS) template summary returned in list responses. */ + @JvmStatic + fun ofNotificationTemplateSummary( + notificationTemplateSummary: NotificationTemplateSummary + ) = Result(notificationTemplateSummary = notificationTemplateSummary) } - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) + /** An interface that defines how to map each variant of [Result] to a value of type [T]. */ + interface Visitor { - fun toBuilder() = Builder().from(this) + fun visitNotification(notification: Notification): T - companion object { + /** V2 (CDS) template summary returned in list responses. */ + fun visitNotificationTemplateSummary( + notificationTemplateSummary: NotificationTemplateSummary + ): T /** - * Returns a mutable builder for constructing an instance of [Result]. + * Maps an unknown variant of [Result] to a value of type [T]. * - * The following fields are required: - * ```java - * .id() - * .createdAt() - * .eventIds() - * .note() - * .routing() - * .topicId() - * .updatedAt() - * ``` + * An instance of [Result] can contain an unknown variant if it was deserialized from + * data that doesn't match any known variant. For example, if the SDK is on an older + * version than the API, then the API may respond with new variants that the SDK is + * unaware of. + * + * @throws CourierInvalidDataException in the default implementation. */ - @JvmStatic fun builder() = Builder() + fun unknown(json: JsonValue?): T { + throw CourierInvalidDataException("Unknown Result: $json") + } } - /** A builder for [Result]. */ - class Builder internal constructor() { + internal class Deserializer : BaseDeserializer(Result::class) { - private var id: JsonField? = null - private var createdAt: JsonField? = null - private var eventIds: JsonField>? = null - private var note: JsonField? = null - private var routing: JsonField? = null - private var topicId: JsonField? = null - private var updatedAt: JsonField? = null - private var tags: JsonField = JsonMissing.of() - private var title: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() + override fun ObjectCodec.deserialize(node: JsonNode): Result { + val json = JsonValue.fromJsonNode(node) - @JvmSynthetic - internal fun from(result: Result) = apply { - id = result.id - createdAt = result.createdAt - eventIds = result.eventIds.map { it.toMutableList() } - note = result.note - routing = result.routing - topicId = result.topicId - updatedAt = result.updatedAt - tags = result.tags - title = result.title - additionalProperties = result.additionalProperties.toMutableMap() + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef())?.let { + Result(notification = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef()) + ?.let { Result(notificationTemplateSummary = it, _json = json) }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible with + // all the possible variants (e.g. deserializing from boolean). + 0 -> Result(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the first + // completely valid match, or simply the first match if none are completely + // valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : BaseSerializer(Result::class) { + + override fun serialize( + value: Result, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.notification != null -> generator.writeObject(value.notification) + value.notificationTemplateSummary != null -> + generator.writeObject(value.notificationTemplateSummary) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid Result") + } } + } - fun id(id: String) = id(JsonField.of(id)) + class Notification + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val id: JsonField, + private val createdAt: JsonField, + private val eventIds: JsonField>, + private val note: JsonField, + private val routing: JsonField, + private val topicId: JsonField, + private val updatedAt: JsonField, + private val tags: JsonField, + private val title: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("created_at") + @ExcludeMissing + createdAt: JsonField = JsonMissing.of(), + @JsonProperty("event_ids") + @ExcludeMissing + eventIds: JsonField> = JsonMissing.of(), + @JsonProperty("note") @ExcludeMissing note: JsonField = JsonMissing.of(), + @JsonProperty("routing") + @ExcludeMissing + routing: JsonField = JsonMissing.of(), + @JsonProperty("topic_id") + @ExcludeMissing + topicId: JsonField = JsonMissing.of(), + @JsonProperty("updated_at") + @ExcludeMissing + updatedAt: JsonField = JsonMissing.of(), + @JsonProperty("tags") @ExcludeMissing tags: JsonField = JsonMissing.of(), + @JsonProperty("title") @ExcludeMissing title: JsonField = JsonMissing.of(), + ) : this( + id, + createdAt, + eventIds, + note, + routing, + topicId, + updatedAt, + tags, + title, + mutableMapOf(), + ) /** - * Sets [Builder.id] to an arbitrary JSON value. - * - * You should usually call [Builder.id] with a well-typed [String] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported - * value. + * @throws CourierInvalidDataException 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 id(id: JsonField) = apply { this.id = id } + fun id(): String = id.getRequired("id") - fun createdAt(createdAt: Long) = createdAt(JsonField.of(createdAt)) + /** + * @throws CourierInvalidDataException 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 createdAt(): Long = createdAt.getRequired("created_at") /** - * Sets [Builder.createdAt] to an arbitrary JSON value. + * Array of event IDs associated with this notification * - * You should usually call [Builder.createdAt] with a well-typed [Long] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. + * @throws CourierInvalidDataException 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 createdAt(createdAt: JsonField) = apply { this.createdAt = createdAt } + fun eventIds(): List = eventIds.getRequired("event_ids") - /** Array of event IDs associated with this notification */ - fun eventIds(eventIds: List) = eventIds(JsonField.of(eventIds)) + /** + * @throws CourierInvalidDataException 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 note(): String = note.getRequired("note") /** - * Sets [Builder.eventIds] to an arbitrary JSON value. - * - * You should usually call [Builder.eventIds] with a well-typed `List` value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. + * @throws CourierInvalidDataException 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 eventIds(eventIds: JsonField>) = apply { - this.eventIds = eventIds.map { it.toMutableList() } - } + fun routing(): MessageRouting = routing.getRequired("routing") /** - * Adds a single [String] to [eventIds]. - * - * @throws IllegalStateException if the field was previously set to a non-list. + * @throws CourierInvalidDataException 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 addEventId(eventId: String) = apply { - eventIds = - (eventIds ?: JsonField.of(mutableListOf())).also { - checkKnown("eventIds", it).add(eventId) - } - } + fun topicId(): String = topicId.getRequired("topic_id") - fun note(note: String) = note(JsonField.of(note)) + /** + * @throws CourierInvalidDataException 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 updatedAt(): Long = updatedAt.getRequired("updated_at") /** - * Sets [Builder.note] to an arbitrary JSON value. - * - * You should usually call [Builder.note] with a well-typed [String] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported - * value. + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - fun note(note: JsonField) = apply { this.note = note } + fun tags(): Optional = tags.getOptional("tags") - fun routing(routing: MessageRouting) = routing(JsonField.of(routing)) + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun title(): Optional = title.getOptional("title") /** - * Sets [Builder.routing] to an arbitrary JSON value. + * Returns the raw JSON value of [id]. * - * You should usually call [Builder.routing] with a well-typed [MessageRouting] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. */ - fun routing(routing: JsonField) = apply { this.routing = routing } - - fun topicId(topicId: String) = topicId(JsonField.of(topicId)) + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id /** - * Sets [Builder.topicId] to an arbitrary JSON value. + * Returns the raw JSON value of [createdAt]. * - * You should usually call [Builder.topicId] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. + * Unlike [createdAt], this method doesn't throw if the JSON field has an unexpected + * type. */ - fun topicId(topicId: JsonField) = apply { this.topicId = topicId } - - fun updatedAt(updatedAt: Long) = updatedAt(JsonField.of(updatedAt)) + @JsonProperty("created_at") + @ExcludeMissing + fun _createdAt(): JsonField = createdAt /** - * Sets [Builder.updatedAt] to an arbitrary JSON value. + * Returns the raw JSON value of [eventIds]. * - * You should usually call [Builder.updatedAt] with a well-typed [Long] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. + * Unlike [eventIds], this method doesn't throw if the JSON field has an unexpected + * type. */ - fun updatedAt(updatedAt: JsonField) = apply { this.updatedAt = updatedAt } - - fun tags(tags: Tags?) = tags(JsonField.ofNullable(tags)) - - /** Alias for calling [Builder.tags] with `tags.orElse(null)`. */ - fun tags(tags: Optional) = tags(tags.getOrNull()) + @JsonProperty("event_ids") + @ExcludeMissing + fun _eventIds(): JsonField> = eventIds /** - * Sets [Builder.tags] to an arbitrary JSON value. + * Returns the raw JSON value of [note]. * - * You should usually call [Builder.tags] with a well-typed [Tags] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported - * value. + * Unlike [note], this method doesn't throw if the JSON field has an unexpected type. */ - fun tags(tags: JsonField) = apply { this.tags = tags } - - fun title(title: String?) = title(JsonField.ofNullable(title)) - - /** Alias for calling [Builder.title] with `title.orElse(null)`. */ - fun title(title: Optional) = title(title.getOrNull()) + @JsonProperty("note") @ExcludeMissing fun _note(): JsonField = note /** - * Sets [Builder.title] to an arbitrary JSON value. + * Returns the raw JSON value of [routing]. * - * You should usually call [Builder.title] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. + * Unlike [routing], this method doesn't throw if the JSON field has an unexpected type. */ - fun title(title: JsonField) = apply { this.title = title } - - 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) - } + @JsonProperty("routing") + @ExcludeMissing + fun _routing(): JsonField = routing /** - * Returns an immutable instance of [Result]. - * - * Further updates to this [Builder] will not mutate the returned instance. + * Returns the raw JSON value of [topicId]. * - * The following fields are required: - * ```java - * .id() - * .createdAt() - * .eventIds() - * .note() - * .routing() - * .topicId() - * .updatedAt() - * ``` - * - * @throws IllegalStateException if any required field is unset. + * Unlike [topicId], this method doesn't throw if the JSON field has an unexpected type. */ - fun build(): Result = - Result( - checkRequired("id", id), - checkRequired("createdAt", createdAt), - checkRequired("eventIds", eventIds).map { it.toImmutable() }, - checkRequired("note", note), - checkRequired("routing", routing), - checkRequired("topicId", topicId), - checkRequired("updatedAt", updatedAt), - tags, - title, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): Result = apply { - if (validated) { - return@apply - } - - id() - createdAt() - eventIds() - note() - routing().validate() - topicId() - updatedAt() - tags().ifPresent { it.validate() } - title() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CourierInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - (if (id.asKnown().isPresent) 1 else 0) + - (if (createdAt.asKnown().isPresent) 1 else 0) + - (eventIds.asKnown().getOrNull()?.size ?: 0) + - (if (note.asKnown().isPresent) 1 else 0) + - (routing.asKnown().getOrNull()?.validity() ?: 0) + - (if (topicId.asKnown().isPresent) 1 else 0) + - (if (updatedAt.asKnown().isPresent) 1 else 0) + - (tags.asKnown().getOrNull()?.validity() ?: 0) + - (if (title.asKnown().isPresent) 1 else 0) - - class Tags - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val data: JsonField>, - private val additionalProperties: MutableMap, - ) { + @JsonProperty("topic_id") @ExcludeMissing fun _topicId(): JsonField = topicId - @JsonCreator - private constructor( - @JsonProperty("data") @ExcludeMissing data: JsonField> = JsonMissing.of() - ) : this(data, mutableMapOf()) + /** + * Returns the raw JSON value of [updatedAt]. + * + * Unlike [updatedAt], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("updated_at") + @ExcludeMissing + fun _updatedAt(): JsonField = updatedAt /** - * @throws CourierInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected - * value). + * Returns the raw JSON value of [tags]. + * + * Unlike [tags], this method doesn't throw if the JSON field has an unexpected type. */ - fun data(): List = data.getRequired("data") + @JsonProperty("tags") @ExcludeMissing fun _tags(): JsonField = tags /** - * Returns the raw JSON value of [data]. + * Returns the raw JSON value of [title]. * - * Unlike [data], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [title], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("data") @ExcludeMissing fun _data(): JsonField> = data + @JsonProperty("title") @ExcludeMissing fun _title(): JsonField = title @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { @@ -691,53 +624,170 @@ private constructor( companion object { /** - * Returns a mutable builder for constructing an instance of [Tags]. + * Returns a mutable builder for constructing an instance of [Notification]. * * The following fields are required: * ```java - * .data() + * .id() + * .createdAt() + * .eventIds() + * .note() + * .routing() + * .topicId() + * .updatedAt() * ``` */ @JvmStatic fun builder() = Builder() } - /** A builder for [Tags]. */ + /** A builder for [Notification]. */ class Builder internal constructor() { - private var data: JsonField>? = null + private var id: JsonField? = null + private var createdAt: JsonField? = null + private var eventIds: JsonField>? = null + private var note: JsonField? = null + private var routing: JsonField? = null + private var topicId: JsonField? = null + private var updatedAt: JsonField? = null + private var tags: JsonField = JsonMissing.of() + private var title: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(tags: Tags) = apply { - data = tags.data.map { it.toMutableList() } - additionalProperties = tags.additionalProperties.toMutableMap() + internal fun from(notification: Notification) = apply { + id = notification.id + createdAt = notification.createdAt + eventIds = notification.eventIds.map { it.toMutableList() } + note = notification.note + routing = notification.routing + topicId = notification.topicId + updatedAt = notification.updatedAt + tags = notification.tags + title = notification.title + additionalProperties = notification.additionalProperties.toMutableMap() } - fun data(data: List) = data(JsonField.of(data)) + fun id(id: String) = id(JsonField.of(id)) /** - * Sets [Builder.data] to an arbitrary JSON value. + * Sets [Builder.id] to an arbitrary JSON value. * - * You should usually call [Builder.data] with a well-typed `List` value + * You should usually call [Builder.id] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun id(id: JsonField) = apply { this.id = id } + + fun createdAt(createdAt: Long) = createdAt(JsonField.of(createdAt)) + + /** + * Sets [Builder.createdAt] to an arbitrary JSON value. + * + * You should usually call [Builder.createdAt] with a well-typed [Long] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun createdAt(createdAt: JsonField) = apply { this.createdAt = createdAt } + + /** Array of event IDs associated with this notification */ + fun eventIds(eventIds: List) = eventIds(JsonField.of(eventIds)) + + /** + * Sets [Builder.eventIds] to an arbitrary JSON value. + * + * You should usually call [Builder.eventIds] with a well-typed `List` value * instead. This method is primarily for setting the field to an undocumented or not * yet supported value. */ - fun data(data: JsonField>) = apply { - this.data = data.map { it.toMutableList() } + fun eventIds(eventIds: JsonField>) = apply { + this.eventIds = eventIds.map { it.toMutableList() } } /** - * Adds a single [Data] to [Builder.data]. + * Adds a single [String] to [eventIds]. * * @throws IllegalStateException if the field was previously set to a non-list. */ - fun addData(data: Data) = apply { - this.data = - (this.data ?: JsonField.of(mutableListOf())).also { - checkKnown("data", it).add(data) + fun addEventId(eventId: String) = apply { + eventIds = + (eventIds ?: JsonField.of(mutableListOf())).also { + checkKnown("eventIds", it).add(eventId) } } + fun note(note: String) = note(JsonField.of(note)) + + /** + * Sets [Builder.note] to an arbitrary JSON value. + * + * You should usually call [Builder.note] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun note(note: JsonField) = apply { this.note = note } + + fun routing(routing: MessageRouting) = routing(JsonField.of(routing)) + + /** + * Sets [Builder.routing] to an arbitrary JSON value. + * + * You should usually call [Builder.routing] with a well-typed [MessageRouting] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun routing(routing: JsonField) = apply { this.routing = routing } + + fun topicId(topicId: String) = topicId(JsonField.of(topicId)) + + /** + * Sets [Builder.topicId] to an arbitrary JSON value. + * + * You should usually call [Builder.topicId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun topicId(topicId: JsonField) = apply { this.topicId = topicId } + + fun updatedAt(updatedAt: Long) = updatedAt(JsonField.of(updatedAt)) + + /** + * Sets [Builder.updatedAt] to an arbitrary JSON value. + * + * You should usually call [Builder.updatedAt] with a well-typed [Long] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun updatedAt(updatedAt: JsonField) = apply { this.updatedAt = updatedAt } + + fun tags(tags: Tags?) = tags(JsonField.ofNullable(tags)) + + /** Alias for calling [Builder.tags] with `tags.orElse(null)`. */ + fun tags(tags: Optional) = tags(tags.getOrNull()) + + /** + * Sets [Builder.tags] to an arbitrary JSON value. + * + * You should usually call [Builder.tags] with a well-typed [Tags] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun tags(tags: JsonField) = apply { this.tags = tags } + + fun title(title: String?) = title(JsonField.ofNullable(title)) + + /** Alias for calling [Builder.title] with `title.orElse(null)`. */ + fun title(title: Optional) = title(title.getOrNull()) + + /** + * Sets [Builder.title] to an arbitrary JSON value. + * + * You should usually call [Builder.title] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun title(title: JsonField) = apply { this.title = title } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() putAllAdditionalProperties(additionalProperties) @@ -761,32 +811,54 @@ private constructor( } /** - * Returns an immutable instance of [Tags]. + * Returns an immutable instance of [Notification]. * * Further updates to this [Builder] will not mutate the returned instance. * * The following fields are required: * ```java - * .data() + * .id() + * .createdAt() + * .eventIds() + * .note() + * .routing() + * .topicId() + * .updatedAt() * ``` * * @throws IllegalStateException if any required field is unset. */ - fun build(): Tags = - Tags( - checkRequired("data", data).map { it.toImmutable() }, + fun build(): Notification = + Notification( + checkRequired("id", id), + checkRequired("createdAt", createdAt), + checkRequired("eventIds", eventIds).map { it.toImmutable() }, + checkRequired("note", note), + checkRequired("routing", routing), + checkRequired("topicId", topicId), + checkRequired("updatedAt", updatedAt), + tags, + title, additionalProperties.toMutableMap(), ) } private var validated: Boolean = false - fun validate(): Tags = apply { + fun validate(): Notification = apply { if (validated) { return@apply } - data().forEach { it.validate() } + id() + createdAt() + eventIds() + note() + routing().validate() + topicId() + updatedAt() + tags().ifPresent { it.validate() } + title() validated = true } @@ -806,50 +878,44 @@ private constructor( */ @JvmSynthetic internal fun validity(): Int = - (data.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) - - class Data + (if (id.asKnown().isPresent) 1 else 0) + + (if (createdAt.asKnown().isPresent) 1 else 0) + + (eventIds.asKnown().getOrNull()?.size ?: 0) + + (if (note.asKnown().isPresent) 1 else 0) + + (routing.asKnown().getOrNull()?.validity() ?: 0) + + (if (topicId.asKnown().isPresent) 1 else 0) + + (if (updatedAt.asKnown().isPresent) 1 else 0) + + (tags.asKnown().getOrNull()?.validity() ?: 0) + + (if (title.asKnown().isPresent) 1 else 0) + + class Tags @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( - private val id: JsonField, - private val name: JsonField, + private val data: JsonField>, private val additionalProperties: MutableMap, ) { @JsonCreator private constructor( - @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), - @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), - ) : this(id, name, mutableMapOf()) - - /** - * @throws CourierInvalidDataException 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 id(): String = id.getRequired("id") + @JsonProperty("data") + @ExcludeMissing + data: JsonField> = JsonMissing.of() + ) : this(data, mutableMapOf()) /** * @throws CourierInvalidDataException 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 name(): String = name.getRequired("name") - - /** - * Returns the raw JSON value of [id]. - * - * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + fun data(): List = data.getRequired("data") /** - * Returns the raw JSON value of [name]. + * Returns the raw JSON value of [data]. * - * Unlike [name], this method doesn't throw if the JSON field has an unexpected + * Unlike [data], this method doesn't throw if the JSON field has an unexpected * type. */ - @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + @JsonProperty("data") @ExcludeMissing fun _data(): JsonField> = data @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { @@ -866,52 +932,52 @@ private constructor( companion object { /** - * Returns a mutable builder for constructing an instance of [Data]. + * Returns a mutable builder for constructing an instance of [Tags]. * * The following fields are required: * ```java - * .id() - * .name() + * .data() * ``` */ @JvmStatic fun builder() = Builder() } - /** A builder for [Data]. */ + /** A builder for [Tags]. */ class Builder internal constructor() { - private var id: JsonField? = null - private var name: JsonField? = null + private var data: JsonField>? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(data: Data) = apply { - id = data.id - name = data.name - additionalProperties = data.additionalProperties.toMutableMap() + internal fun from(tags: Tags) = apply { + data = tags.data.map { it.toMutableList() } + additionalProperties = tags.additionalProperties.toMutableMap() } - fun id(id: String) = id(JsonField.of(id)) + fun data(data: List) = data(JsonField.of(data)) /** - * Sets [Builder.id] to an arbitrary JSON value. + * Sets [Builder.data] to an arbitrary JSON value. * - * You should usually call [Builder.id] with a well-typed [String] value + * You should usually call [Builder.data] with a well-typed `List` value * instead. This method is primarily for setting the field to an undocumented or * not yet supported value. */ - fun id(id: JsonField) = apply { this.id = id } - - fun name(name: String) = name(JsonField.of(name)) + fun data(data: JsonField>) = apply { + this.data = data.map { it.toMutableList() } + } /** - * Sets [Builder.name] to an arbitrary JSON value. + * Adds a single [Data] to [Builder.data]. * - * You should usually call [Builder.name] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. + * @throws IllegalStateException if the field was previously set to a non-list. */ - fun name(name: JsonField) = apply { this.name = name } + fun addData(data: Data) = apply { + this.data = + (this.data ?: JsonField.of(mutableListOf())).also { + checkKnown("data", it).add(data) + } + } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() @@ -936,35 +1002,32 @@ private constructor( } /** - * Returns an immutable instance of [Data]. + * Returns an immutable instance of [Tags]. * * Further updates to this [Builder] will not mutate the returned instance. * * The following fields are required: * ```java - * .id() - * .name() + * .data() * ``` * * @throws IllegalStateException if any required field is unset. */ - fun build(): Data = - Data( - checkRequired("id", id), - checkRequired("name", name), + fun build(): Tags = + Tags( + checkRequired("data", data).map { it.toImmutable() }, additionalProperties.toMutableMap(), ) } private var validated: Boolean = false - fun validate(): Data = apply { + fun validate(): Tags = apply { if (validated) { return@apply } - id() - name() + data().forEach { it.validate() } validated = true } @@ -984,26 +1047,230 @@ private constructor( */ @JvmSynthetic internal fun validity(): Int = - (if (id.asKnown().isPresent) 1 else 0) + - (if (name.asKnown().isPresent) 1 else 0) + (data.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + class Data + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val id: JsonField, + private val name: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("id") + @ExcludeMissing + id: JsonField = JsonMissing.of(), + @JsonProperty("name") + @ExcludeMissing + name: JsonField = JsonMissing.of(), + ) : this(id, name, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 id(): String = id.getRequired("id") + + /** + * @throws CourierInvalidDataException 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 name(): String = name.getRequired("name") + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + + @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 [Data]. + * + * The following fields are required: + * ```java + * .id() + * .name() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Data]. */ + class Builder internal constructor() { + + private var id: JsonField? = null + private var name: JsonField? = null + private var additionalProperties: MutableMap = + mutableMapOf() + + @JvmSynthetic + internal fun from(data: Data) = apply { + id = data.id + name = data.name + additionalProperties = data.additionalProperties.toMutableMap() + } + + fun id(id: String) = id(JsonField.of(id)) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun id(id: JsonField) = apply { this.id = id } + + fun name(name: String) = name(JsonField.of(name)) + + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun name(name: JsonField) = apply { this.name = name } + + 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 [Data]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .name() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Data = + Data( + checkRequired("id", id), + checkRequired("name", name), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Data = apply { + if (validated) { + return@apply + } + + id() + name() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (id.asKnown().isPresent) 1 else 0) + + (if (name.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Data && + id == other.id && + name == other.name && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(id, name, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Data{id=$id, name=$name, additionalProperties=$additionalProperties}" + } override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is Data && - id == other.id && - name == other.name && + return other is Tags && + data == other.data && additionalProperties == other.additionalProperties } - private val hashCode: Int by lazy { Objects.hash(id, name, additionalProperties) } + private val hashCode: Int by lazy { Objects.hash(data, additionalProperties) } override fun hashCode(): Int = hashCode override fun toString() = - "Data{id=$id, name=$name, additionalProperties=$additionalProperties}" + "Tags{data=$data, additionalProperties=$additionalProperties}" } override fun equals(other: Any?): Boolean { @@ -1011,55 +1278,39 @@ private constructor( return true } - return other is Tags && - data == other.data && + return other is Notification && + id == other.id && + createdAt == other.createdAt && + eventIds == other.eventIds && + note == other.note && + routing == other.routing && + topicId == other.topicId && + updatedAt == other.updatedAt && + tags == other.tags && + title == other.title && additionalProperties == other.additionalProperties } - private val hashCode: Int by lazy { Objects.hash(data, additionalProperties) } - - override fun hashCode(): Int = hashCode - - override fun toString() = "Tags{data=$data, additionalProperties=$additionalProperties}" - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + private val hashCode: Int by lazy { + Objects.hash( + id, + createdAt, + eventIds, + note, + routing, + topicId, + updatedAt, + tags, + title, + additionalProperties, + ) } - return other is Result && - id == other.id && - createdAt == other.createdAt && - eventIds == other.eventIds && - note == other.note && - routing == other.routing && - topicId == other.topicId && - updatedAt == other.updatedAt && - tags == other.tags && - title == other.title && - additionalProperties == other.additionalProperties - } + override fun hashCode(): Int = hashCode - private val hashCode: Int by lazy { - Objects.hash( - id, - createdAt, - eventIds, - note, - routing, - topicId, - updatedAt, - tags, - title, - additionalProperties, - ) + override fun toString() = + "Notification{id=$id, createdAt=$createdAt, eventIds=$eventIds, note=$note, routing=$routing, topicId=$topicId, updatedAt=$updatedAt, tags=$tags, title=$title, additionalProperties=$additionalProperties}" } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Result{id=$id, createdAt=$createdAt, eventIds=$eventIds, note=$note, routing=$routing, topicId=$topicId, updatedAt=$updatedAt, tags=$tags, title=$title, additionalProperties=$additionalProperties}" } override fun equals(other: Any?): Boolean { diff --git a/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationPublishParams.kt b/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationPublishParams.kt new file mode 100644 index 00000000..a47b2214 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationPublishParams.kt @@ -0,0 +1,232 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.notifications + +import com.courier.core.JsonValue +import com.courier.core.Params +import com.courier.core.http.Headers +import com.courier.core.http.QueryParams +import com.courier.core.toImmutable +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Publish the current draft of a notification template. */ +class NotificationPublishParams +private constructor( + private val id: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, + private val additionalBodyProperties: Map, +) : Params { + + fun id(): Optional = Optional.ofNullable(id) + + /** Additional body properties to send with the request. */ + fun _additionalBodyProperties(): Map = additionalBodyProperties + + /** 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(): NotificationPublishParams = builder().build() + + /** + * Returns a mutable builder for constructing an instance of [NotificationPublishParams]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [NotificationPublishParams]. */ + class Builder internal constructor() { + + private var id: String? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + private var additionalBodyProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(notificationPublishParams: NotificationPublishParams) = apply { + id = notificationPublishParams.id + additionalHeaders = notificationPublishParams.additionalHeaders.toBuilder() + additionalQueryParams = notificationPublishParams.additionalQueryParams.toBuilder() + additionalBodyProperties = + notificationPublishParams.additionalBodyProperties.toMutableMap() + } + + fun id(id: String?) = apply { this.id = id } + + /** Alias for calling [Builder.id] with `id.orElse(null)`. */ + fun id(id: Optional) = id(id.getOrNull()) + + 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) + } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + this.additionalBodyProperties.clear() + putAllAdditionalBodyProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + additionalBodyProperties.put(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + this.additionalBodyProperties.putAll(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { + additionalBodyProperties.remove(key) + } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalBodyProperty) + } + + /** + * Returns an immutable instance of [NotificationPublishParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): NotificationPublishParams = + NotificationPublishParams( + id, + additionalHeaders.build(), + additionalQueryParams.build(), + additionalBodyProperties.toImmutable(), + ) + } + + fun _body(): Optional> = + Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) + + fun _pathParam(index: Int): String = + when (index) { + 0 -> id ?: "" + else -> "" + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is NotificationPublishParams && + id == other.id && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams && + additionalBodyProperties == other.additionalBodyProperties + } + + override fun hashCode(): Int = + Objects.hash(id, additionalHeaders, additionalQueryParams, additionalBodyProperties) + + override fun toString() = + "NotificationPublishParams{id=$id, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationReplaceParams.kt b/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationReplaceParams.kt new file mode 100644 index 00000000..3a935803 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationReplaceParams.kt @@ -0,0 +1,242 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.notifications + +import com.courier.core.JsonValue +import com.courier.core.Params +import com.courier.core.checkRequired +import com.courier.core.http.Headers +import com.courier.core.http.QueryParams +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Replace a notification template. All fields are required. */ +class NotificationReplaceParams +private constructor( + private val id: String?, + private val notificationTemplateUpdateRequest: NotificationTemplateUpdateRequest, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun id(): Optional = Optional.ofNullable(id) + + /** + * Request body for replacing a notification template. Same shape as create. All fields required + * (PUT = full replacement). + */ + fun notificationTemplateUpdateRequest(): NotificationTemplateUpdateRequest = + notificationTemplateUpdateRequest + + fun _additionalBodyProperties(): Map = + notificationTemplateUpdateRequest._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 { + + /** + * Returns a mutable builder for constructing an instance of [NotificationReplaceParams]. + * + * The following fields are required: + * ```java + * .notificationTemplateUpdateRequest() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [NotificationReplaceParams]. */ + class Builder internal constructor() { + + private var id: String? = null + private var notificationTemplateUpdateRequest: NotificationTemplateUpdateRequest? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(notificationReplaceParams: NotificationReplaceParams) = apply { + id = notificationReplaceParams.id + notificationTemplateUpdateRequest = + notificationReplaceParams.notificationTemplateUpdateRequest + additionalHeaders = notificationReplaceParams.additionalHeaders.toBuilder() + additionalQueryParams = notificationReplaceParams.additionalQueryParams.toBuilder() + } + + fun id(id: String?) = apply { this.id = id } + + /** Alias for calling [Builder.id] with `id.orElse(null)`. */ + fun id(id: Optional) = id(id.getOrNull()) + + /** + * Request body for replacing a notification template. Same shape as create. All fields + * required (PUT = full replacement). + */ + fun notificationTemplateUpdateRequest( + notificationTemplateUpdateRequest: NotificationTemplateUpdateRequest + ) = apply { this.notificationTemplateUpdateRequest = notificationTemplateUpdateRequest } + + 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 [NotificationReplaceParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .notificationTemplateUpdateRequest() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): NotificationReplaceParams = + NotificationReplaceParams( + id, + checkRequired( + "notificationTemplateUpdateRequest", + notificationTemplateUpdateRequest, + ), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): NotificationTemplateUpdateRequest = notificationTemplateUpdateRequest + + fun _pathParam(index: Int): String = + when (index) { + 0 -> id ?: "" + else -> "" + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is NotificationReplaceParams && + id == other.id && + notificationTemplateUpdateRequest == other.notificationTemplateUpdateRequest && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash( + id, + notificationTemplateUpdateRequest, + additionalHeaders, + additionalQueryParams, + ) + + override fun toString() = + "NotificationReplaceParams{id=$id, notificationTemplateUpdateRequest=$notificationTemplateUpdateRequest, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationRetrieveParams.kt b/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationRetrieveParams.kt new file mode 100644 index 00000000..448f14d4 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationRetrieveParams.kt @@ -0,0 +1,225 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.notifications + +import com.courier.core.Params +import com.courier.core.http.Headers +import com.courier.core.http.QueryParams +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * Retrieve a notification template by ID. Returns the published version by default. Pass + * version=draft to retrieve an unpublished template. + */ +class NotificationRetrieveParams +private constructor( + private val id: String?, + private val version: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun id(): Optional = Optional.ofNullable(id) + + /** + * Version to retrieve. One of "draft", "published", or a version string like "v001". Defaults + * to "published". + */ + fun version(): Optional = Optional.ofNullable(version) + + /** 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(): NotificationRetrieveParams = builder().build() + + /** + * Returns a mutable builder for constructing an instance of [NotificationRetrieveParams]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [NotificationRetrieveParams]. */ + class Builder internal constructor() { + + private var id: String? = null + private var version: String? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(notificationRetrieveParams: NotificationRetrieveParams) = apply { + id = notificationRetrieveParams.id + version = notificationRetrieveParams.version + additionalHeaders = notificationRetrieveParams.additionalHeaders.toBuilder() + additionalQueryParams = notificationRetrieveParams.additionalQueryParams.toBuilder() + } + + fun id(id: String?) = apply { this.id = id } + + /** Alias for calling [Builder.id] with `id.orElse(null)`. */ + fun id(id: Optional) = id(id.getOrNull()) + + /** + * Version to retrieve. One of "draft", "published", or a version string like "v001". + * Defaults to "published". + */ + fun version(version: String?) = apply { this.version = version } + + /** Alias for calling [Builder.version] with `version.orElse(null)`. */ + fun version(version: Optional) = version(version.getOrNull()) + + 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 [NotificationRetrieveParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): NotificationRetrieveParams = + NotificationRetrieveParams( + id, + version, + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _pathParam(index: Int): String = + when (index) { + 0 -> id ?: "" + else -> "" + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + version?.let { put("version", it) } + putAll(additionalQueryParams) + } + .build() + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is NotificationRetrieveParams && + id == other.id && + version == other.version && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(id, version, additionalHeaders, additionalQueryParams) + + override fun toString() = + "NotificationRetrieveParams{id=$id, version=$version, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationTemplateCreateRequest.kt b/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationTemplateCreateRequest.kt new file mode 100644 index 00000000..37991db3 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationTemplateCreateRequest.kt @@ -0,0 +1,361 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.notifications + +import com.courier.core.Enum +import com.courier.core.ExcludeMissing +import com.courier.core.JsonField +import com.courier.core.JsonMissing +import com.courier.core.JsonValue +import com.courier.core.checkRequired +import com.courier.errors.CourierInvalidDataException +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 java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Request body for creating a notification template. */ +class NotificationTemplateCreateRequest +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val notification: JsonField, + private val state: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("notification") + @ExcludeMissing + notification: JsonField = JsonMissing.of(), + @JsonProperty("state") @ExcludeMissing state: JsonField = JsonMissing.of(), + ) : this(notification, state, mutableMapOf()) + + /** + * Full document shape used in POST and PUT request bodies, and returned inside the GET response + * envelope. + * + * @throws CourierInvalidDataException 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 notification(): NotificationTemplatePayload = notification.getRequired("notification") + + /** + * Template state after creation. Case-insensitive input, normalized to uppercase in the + * response. Defaults to "DRAFT". + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun state(): Optional = state.getOptional("state") + + /** + * Returns the raw JSON value of [notification]. + * + * Unlike [notification], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("notification") + @ExcludeMissing + fun _notification(): JsonField = notification + + /** + * Returns the raw JSON value of [state]. + * + * Unlike [state], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("state") @ExcludeMissing fun _state(): JsonField = state + + @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 + * [NotificationTemplateCreateRequest]. + * + * The following fields are required: + * ```java + * .notification() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [NotificationTemplateCreateRequest]. */ + class Builder internal constructor() { + + private var notification: JsonField? = null + private var state: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(notificationTemplateCreateRequest: NotificationTemplateCreateRequest) = + apply { + notification = notificationTemplateCreateRequest.notification + state = notificationTemplateCreateRequest.state + additionalProperties = + notificationTemplateCreateRequest.additionalProperties.toMutableMap() + } + + /** + * Full document shape used in POST and PUT request bodies, and returned inside the GET + * response envelope. + */ + fun notification(notification: NotificationTemplatePayload) = + notification(JsonField.of(notification)) + + /** + * Sets [Builder.notification] to an arbitrary JSON value. + * + * You should usually call [Builder.notification] with a well-typed + * [NotificationTemplatePayload] value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun notification(notification: JsonField) = apply { + this.notification = notification + } + + /** + * Template state after creation. Case-insensitive input, normalized to uppercase in the + * response. Defaults to "DRAFT". + */ + fun state(state: State) = state(JsonField.of(state)) + + /** + * Sets [Builder.state] to an arbitrary JSON value. + * + * You should usually call [Builder.state] with a well-typed [State] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun state(state: JsonField) = apply { this.state = state } + + 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 [NotificationTemplateCreateRequest]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .notification() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): NotificationTemplateCreateRequest = + NotificationTemplateCreateRequest( + checkRequired("notification", notification), + state, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): NotificationTemplateCreateRequest = apply { + if (validated) { + return@apply + } + + notification().validate() + state().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (notification.asKnown().getOrNull()?.validity() ?: 0) + + (state.asKnown().getOrNull()?.validity() ?: 0) + + /** + * Template state after creation. Case-insensitive input, normalized to uppercase in the + * response. Defaults to "DRAFT". + */ + class State @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val DRAFT = of("DRAFT") + + @JvmField val PUBLISHED = of("PUBLISHED") + + @JvmStatic fun of(value: String) = State(JsonField.of(value)) + } + + /** An enum containing [State]'s known values. */ + enum class Known { + DRAFT, + PUBLISHED, + } + + /** + * An enum containing [State]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [State] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + DRAFT, + PUBLISHED, + /** An enum member indicating that [State] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + DRAFT -> Value.DRAFT + PUBLISHED -> Value.PUBLISHED + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws CourierInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + DRAFT -> Known.DRAFT + PUBLISHED -> Known.PUBLISHED + else -> throw CourierInvalidDataException("Unknown State: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws CourierInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { CourierInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + fun validate(): State = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is State && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is NotificationTemplateCreateRequest && + notification == other.notification && + state == other.state && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(notification, state, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "NotificationTemplateCreateRequest{notification=$notification, state=$state, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationTemplateGetResponse.kt b/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationTemplateGetResponse.kt new file mode 100644 index 00000000..5fecbc80 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationTemplateGetResponse.kt @@ -0,0 +1,963 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.notifications + +import com.courier.core.Enum +import com.courier.core.ExcludeMissing +import com.courier.core.JsonField +import com.courier.core.JsonMissing +import com.courier.core.JsonValue +import com.courier.core.checkKnown +import com.courier.core.checkRequired +import com.courier.core.toImmutable +import com.courier.errors.CourierInvalidDataException +import com.courier.models.ElementalContent +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 java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * Envelope response for GET /notifications/{id}. The notification object mirrors the POST/PUT input + * shape. Nullable fields return null when unset. + */ +class NotificationTemplateGetResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val created: JsonField, + private val creator: JsonField, + private val notification: JsonField, + private val state: JsonField, + private val updated: JsonField, + private val updater: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("created") @ExcludeMissing created: JsonField = JsonMissing.of(), + @JsonProperty("creator") @ExcludeMissing creator: JsonField = JsonMissing.of(), + @JsonProperty("notification") + @ExcludeMissing + notification: JsonField = JsonMissing.of(), + @JsonProperty("state") @ExcludeMissing state: JsonField = JsonMissing.of(), + @JsonProperty("updated") @ExcludeMissing updated: JsonField = JsonMissing.of(), + @JsonProperty("updater") @ExcludeMissing updater: JsonField = JsonMissing.of(), + ) : this(created, creator, notification, state, updated, updater, mutableMapOf()) + + /** + * Epoch milliseconds when the template was created. + * + * @throws CourierInvalidDataException 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 created(): Long = created.getRequired("created") + + /** + * User ID of the creator. + * + * @throws CourierInvalidDataException 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 creator(): String = creator.getRequired("creator") + + /** + * Full document shape used in POST and PUT request bodies, and returned inside the GET response + * envelope. + * + * @throws CourierInvalidDataException 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 notification(): Notification = notification.getRequired("notification") + + /** + * The template state. Always uppercase. + * + * @throws CourierInvalidDataException 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 state(): State = state.getRequired("state") + + /** + * Epoch milliseconds of last update. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun updated(): Optional = updated.getOptional("updated") + + /** + * User ID of the last updater. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun updater(): Optional = updater.getOptional("updater") + + /** + * Returns the raw JSON value of [created]. + * + * Unlike [created], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created") @ExcludeMissing fun _created(): JsonField = created + + /** + * Returns the raw JSON value of [creator]. + * + * Unlike [creator], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("creator") @ExcludeMissing fun _creator(): JsonField = creator + + /** + * Returns the raw JSON value of [notification]. + * + * Unlike [notification], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("notification") + @ExcludeMissing + fun _notification(): JsonField = notification + + /** + * Returns the raw JSON value of [state]. + * + * Unlike [state], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("state") @ExcludeMissing fun _state(): JsonField = state + + /** + * Returns the raw JSON value of [updated]. + * + * Unlike [updated], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("updated") @ExcludeMissing fun _updated(): JsonField = updated + + /** + * Returns the raw JSON value of [updater]. + * + * Unlike [updater], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("updater") @ExcludeMissing fun _updater(): JsonField = updater + + @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 + * [NotificationTemplateGetResponse]. + * + * The following fields are required: + * ```java + * .created() + * .creator() + * .notification() + * .state() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [NotificationTemplateGetResponse]. */ + class Builder internal constructor() { + + private var created: JsonField? = null + private var creator: JsonField? = null + private var notification: JsonField? = null + private var state: JsonField? = null + private var updated: JsonField = JsonMissing.of() + private var updater: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(notificationTemplateGetResponse: NotificationTemplateGetResponse) = + apply { + created = notificationTemplateGetResponse.created + creator = notificationTemplateGetResponse.creator + notification = notificationTemplateGetResponse.notification + state = notificationTemplateGetResponse.state + updated = notificationTemplateGetResponse.updated + updater = notificationTemplateGetResponse.updater + additionalProperties = + notificationTemplateGetResponse.additionalProperties.toMutableMap() + } + + /** Epoch milliseconds when the template was created. */ + fun created(created: Long) = created(JsonField.of(created)) + + /** + * Sets [Builder.created] to an arbitrary JSON value. + * + * You should usually call [Builder.created] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun created(created: JsonField) = apply { this.created = created } + + /** User ID of the creator. */ + fun creator(creator: String) = creator(JsonField.of(creator)) + + /** + * Sets [Builder.creator] to an arbitrary JSON value. + * + * You should usually call [Builder.creator] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun creator(creator: JsonField) = apply { this.creator = creator } + + /** + * Full document shape used in POST and PUT request bodies, and returned inside the GET + * response envelope. + */ + fun notification(notification: Notification) = notification(JsonField.of(notification)) + + /** + * Sets [Builder.notification] to an arbitrary JSON value. + * + * You should usually call [Builder.notification] with a well-typed [Notification] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun notification(notification: JsonField) = apply { + this.notification = notification + } + + /** The template state. Always uppercase. */ + fun state(state: State) = state(JsonField.of(state)) + + /** + * Sets [Builder.state] to an arbitrary JSON value. + * + * You should usually call [Builder.state] with a well-typed [State] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun state(state: JsonField) = apply { this.state = state } + + /** Epoch milliseconds of last update. */ + fun updated(updated: Long) = updated(JsonField.of(updated)) + + /** + * Sets [Builder.updated] to an arbitrary JSON value. + * + * You should usually call [Builder.updated] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun updated(updated: JsonField) = apply { this.updated = updated } + + /** User ID of the last updater. */ + fun updater(updater: String) = updater(JsonField.of(updater)) + + /** + * Sets [Builder.updater] to an arbitrary JSON value. + * + * You should usually call [Builder.updater] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun updater(updater: JsonField) = apply { this.updater = updater } + + 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 [NotificationTemplateGetResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .created() + * .creator() + * .notification() + * .state() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): NotificationTemplateGetResponse = + NotificationTemplateGetResponse( + checkRequired("created", created), + checkRequired("creator", creator), + checkRequired("notification", notification), + checkRequired("state", state), + updated, + updater, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): NotificationTemplateGetResponse = apply { + if (validated) { + return@apply + } + + created() + creator() + notification().validate() + state().validate() + updated() + updater() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (created.asKnown().isPresent) 1 else 0) + + (if (creator.asKnown().isPresent) 1 else 0) + + (notification.asKnown().getOrNull()?.validity() ?: 0) + + (state.asKnown().getOrNull()?.validity() ?: 0) + + (if (updated.asKnown().isPresent) 1 else 0) + + (if (updater.asKnown().isPresent) 1 else 0) + + /** + * Full document shape used in POST and PUT request bodies, and returned inside the GET response + * envelope. + */ + class Notification + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val brand: JsonField, + private val content: JsonField, + private val name: JsonField, + private val routing: JsonField, + private val subscription: JsonField, + private val tags: JsonField>, + private val id: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("brand") + @ExcludeMissing + brand: JsonField = JsonMissing.of(), + @JsonProperty("content") + @ExcludeMissing + content: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("routing") + @ExcludeMissing + routing: JsonField = JsonMissing.of(), + @JsonProperty("subscription") + @ExcludeMissing + subscription: JsonField = JsonMissing.of(), + @JsonProperty("tags") @ExcludeMissing tags: JsonField> = JsonMissing.of(), + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + ) : this(brand, content, name, routing, subscription, tags, id, mutableMapOf()) + + fun toNotificationTemplatePayload(): NotificationTemplatePayload = + NotificationTemplatePayload.builder() + .brand(brand) + .content(content) + .name(name) + .routing(routing) + .subscription(subscription) + .tags(tags) + .build() + + /** + * Brand reference, or null for no brand. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun brand(): Optional = brand.getOptional("brand") + + /** + * Elemental content definition. + * + * @throws CourierInvalidDataException 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 content(): ElementalContent = content.getRequired("content") + + /** + * Display name for the template. + * + * @throws CourierInvalidDataException 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 name(): String = name.getRequired("name") + + /** + * Routing strategy reference, or null for none. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun routing(): Optional = + routing.getOptional("routing") + + /** + * Subscription topic reference, or null for none. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun subscription(): Optional = + subscription.getOptional("subscription") + + /** + * Tags for categorization. Send empty array for none. + * + * @throws CourierInvalidDataException 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 tags(): List = tags.getRequired("tags") + + /** + * The template ID. + * + * @throws CourierInvalidDataException 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 id(): String = id.getRequired("id") + + /** + * Returns the raw JSON value of [brand]. + * + * Unlike [brand], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("brand") + @ExcludeMissing + fun _brand(): JsonField = brand + + /** + * Returns the raw JSON value of [content]. + * + * Unlike [content], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("content") + @ExcludeMissing + fun _content(): JsonField = content + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + + /** + * Returns the raw JSON value of [routing]. + * + * Unlike [routing], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("routing") + @ExcludeMissing + fun _routing(): JsonField = routing + + /** + * Returns the raw JSON value of [subscription]. + * + * Unlike [subscription], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("subscription") + @ExcludeMissing + fun _subscription(): JsonField = subscription + + /** + * Returns the raw JSON value of [tags]. + * + * Unlike [tags], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("tags") @ExcludeMissing fun _tags(): JsonField> = tags + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + @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 [Notification]. + * + * The following fields are required: + * ```java + * .brand() + * .content() + * .name() + * .routing() + * .subscription() + * .tags() + * .id() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Notification]. */ + class Builder internal constructor() { + + private var brand: JsonField? = null + private var content: JsonField? = null + private var name: JsonField? = null + private var routing: JsonField? = null + private var subscription: JsonField? = null + private var tags: JsonField>? = null + private var id: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(notification: Notification) = apply { + brand = notification.brand + content = notification.content + name = notification.name + routing = notification.routing + subscription = notification.subscription + tags = notification.tags.map { it.toMutableList() } + id = notification.id + additionalProperties = notification.additionalProperties.toMutableMap() + } + + /** Brand reference, or null for no brand. */ + fun brand(brand: NotificationTemplatePayload.Brand?) = + brand(JsonField.ofNullable(brand)) + + /** Alias for calling [Builder.brand] with `brand.orElse(null)`. */ + fun brand(brand: Optional) = brand(brand.getOrNull()) + + /** + * Sets [Builder.brand] to an arbitrary JSON value. + * + * You should usually call [Builder.brand] with a well-typed + * [NotificationTemplatePayload.Brand] value instead. This method is primarily for + * setting the field to an undocumented or not yet supported value. + */ + fun brand(brand: JsonField) = apply { + this.brand = brand + } + + /** Elemental content definition. */ + fun content(content: ElementalContent) = content(JsonField.of(content)) + + /** + * Sets [Builder.content] to an arbitrary JSON value. + * + * You should usually call [Builder.content] with a well-typed [ElementalContent] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun content(content: JsonField) = apply { this.content = content } + + /** Display name for the template. */ + fun name(name: String) = name(JsonField.of(name)) + + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun name(name: JsonField) = apply { this.name = name } + + /** Routing strategy reference, or null for none. */ + fun routing(routing: NotificationTemplatePayload.Routing?) = + routing(JsonField.ofNullable(routing)) + + /** Alias for calling [Builder.routing] with `routing.orElse(null)`. */ + fun routing(routing: Optional) = + routing(routing.getOrNull()) + + /** + * Sets [Builder.routing] to an arbitrary JSON value. + * + * You should usually call [Builder.routing] with a well-typed + * [NotificationTemplatePayload.Routing] value instead. This method is primarily for + * setting the field to an undocumented or not yet supported value. + */ + fun routing(routing: JsonField) = apply { + this.routing = routing + } + + /** Subscription topic reference, or null for none. */ + fun subscription(subscription: NotificationTemplatePayload.Subscription?) = + subscription(JsonField.ofNullable(subscription)) + + /** Alias for calling [Builder.subscription] with `subscription.orElse(null)`. */ + fun subscription(subscription: Optional) = + subscription(subscription.getOrNull()) + + /** + * Sets [Builder.subscription] to an arbitrary JSON value. + * + * You should usually call [Builder.subscription] with a well-typed + * [NotificationTemplatePayload.Subscription] value instead. This method is primarily + * for setting the field to an undocumented or not yet supported value. + */ + fun subscription(subscription: JsonField) = + apply { + this.subscription = subscription + } + + /** Tags for categorization. Send empty array for none. */ + fun tags(tags: List) = tags(JsonField.of(tags)) + + /** + * Sets [Builder.tags] to an arbitrary JSON value. + * + * You should usually call [Builder.tags] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun tags(tags: JsonField>) = apply { + this.tags = tags.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [tags]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addTag(tag: String) = apply { + tags = + (tags ?: JsonField.of(mutableListOf())).also { checkKnown("tags", it).add(tag) } + } + + /** The template ID. */ + fun id(id: String) = id(JsonField.of(id)) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun id(id: JsonField) = apply { this.id = id } + + 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 [Notification]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .brand() + * .content() + * .name() + * .routing() + * .subscription() + * .tags() + * .id() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Notification = + Notification( + checkRequired("brand", brand), + checkRequired("content", content), + checkRequired("name", name), + checkRequired("routing", routing), + checkRequired("subscription", subscription), + checkRequired("tags", tags).map { it.toImmutable() }, + checkRequired("id", id), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Notification = apply { + if (validated) { + return@apply + } + + brand().ifPresent { it.validate() } + content().validate() + name() + routing().ifPresent { it.validate() } + subscription().ifPresent { it.validate() } + tags() + id() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (brand.asKnown().getOrNull()?.validity() ?: 0) + + (content.asKnown().getOrNull()?.validity() ?: 0) + + (if (name.asKnown().isPresent) 1 else 0) + + (routing.asKnown().getOrNull()?.validity() ?: 0) + + (subscription.asKnown().getOrNull()?.validity() ?: 0) + + (tags.asKnown().getOrNull()?.size ?: 0) + + (if (id.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Notification && + brand == other.brand && + content == other.content && + name == other.name && + routing == other.routing && + subscription == other.subscription && + tags == other.tags && + id == other.id && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + brand, + content, + name, + routing, + subscription, + tags, + id, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Notification{brand=$brand, content=$content, name=$name, routing=$routing, subscription=$subscription, tags=$tags, id=$id, additionalProperties=$additionalProperties}" + } + + /** The template state. Always uppercase. */ + class State @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val DRAFT = of("DRAFT") + + @JvmField val PUBLISHED = of("PUBLISHED") + + @JvmStatic fun of(value: String) = State(JsonField.of(value)) + } + + /** An enum containing [State]'s known values. */ + enum class Known { + DRAFT, + PUBLISHED, + } + + /** + * An enum containing [State]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [State] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + DRAFT, + PUBLISHED, + /** An enum member indicating that [State] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + DRAFT -> Value.DRAFT + PUBLISHED -> Value.PUBLISHED + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws CourierInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + DRAFT -> Known.DRAFT + PUBLISHED -> Known.PUBLISHED + else -> throw CourierInvalidDataException("Unknown State: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws CourierInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { CourierInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + fun validate(): State = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is State && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is NotificationTemplateGetResponse && + created == other.created && + creator == other.creator && + notification == other.notification && + state == other.state && + updated == other.updated && + updater == other.updater && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(created, creator, notification, state, updated, updater, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "NotificationTemplateGetResponse{created=$created, creator=$creator, notification=$notification, state=$state, updated=$updated, updater=$updater, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationTemplateMutationResponse.kt b/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationTemplateMutationResponse.kt new file mode 100644 index 00000000..89c0a043 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationTemplateMutationResponse.kt @@ -0,0 +1,503 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.notifications + +import com.courier.core.Enum +import com.courier.core.ExcludeMissing +import com.courier.core.JsonField +import com.courier.core.JsonMissing +import com.courier.core.JsonValue +import com.courier.core.checkRequired +import com.courier.errors.CourierInvalidDataException +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 java.util.Collections +import java.util.Objects +import kotlin.jvm.optionals.getOrNull + +/** Response returned by POST and PUT operations. */ +class NotificationTemplateMutationResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val notification: JsonField, + private val state: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("notification") + @ExcludeMissing + notification: JsonField = JsonMissing.of(), + @JsonProperty("state") @ExcludeMissing state: JsonField = JsonMissing.of(), + ) : this(notification, state, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 notification(): Notification = notification.getRequired("notification") + + /** + * The template state after the operation. Always uppercase. + * + * @throws CourierInvalidDataException 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 state(): State = state.getRequired("state") + + /** + * Returns the raw JSON value of [notification]. + * + * Unlike [notification], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("notification") + @ExcludeMissing + fun _notification(): JsonField = notification + + /** + * Returns the raw JSON value of [state]. + * + * Unlike [state], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("state") @ExcludeMissing fun _state(): JsonField = state + + @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 + * [NotificationTemplateMutationResponse]. + * + * The following fields are required: + * ```java + * .notification() + * .state() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [NotificationTemplateMutationResponse]. */ + class Builder internal constructor() { + + private var notification: JsonField? = null + private var state: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from( + notificationTemplateMutationResponse: NotificationTemplateMutationResponse + ) = apply { + notification = notificationTemplateMutationResponse.notification + state = notificationTemplateMutationResponse.state + additionalProperties = + notificationTemplateMutationResponse.additionalProperties.toMutableMap() + } + + fun notification(notification: Notification) = notification(JsonField.of(notification)) + + /** + * Sets [Builder.notification] to an arbitrary JSON value. + * + * You should usually call [Builder.notification] with a well-typed [Notification] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun notification(notification: JsonField) = apply { + this.notification = notification + } + + /** The template state after the operation. Always uppercase. */ + fun state(state: State) = state(JsonField.of(state)) + + /** + * Sets [Builder.state] to an arbitrary JSON value. + * + * You should usually call [Builder.state] with a well-typed [State] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun state(state: JsonField) = apply { this.state = state } + + 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 [NotificationTemplateMutationResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .notification() + * .state() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): NotificationTemplateMutationResponse = + NotificationTemplateMutationResponse( + checkRequired("notification", notification), + checkRequired("state", state), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): NotificationTemplateMutationResponse = apply { + if (validated) { + return@apply + } + + notification().validate() + state().validate() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (notification.asKnown().getOrNull()?.validity() ?: 0) + + (state.asKnown().getOrNull()?.validity() ?: 0) + + class Notification + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val id: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of() + ) : this(id, mutableMapOf()) + + /** + * The ID of the created or updated template. + * + * @throws CourierInvalidDataException 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 id(): String = id.getRequired("id") + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + @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 [Notification]. + * + * The following fields are required: + * ```java + * .id() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Notification]. */ + class Builder internal constructor() { + + private var id: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(notification: Notification) = apply { + id = notification.id + additionalProperties = notification.additionalProperties.toMutableMap() + } + + /** The ID of the created or updated template. */ + fun id(id: String) = id(JsonField.of(id)) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun id(id: JsonField) = apply { this.id = id } + + 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 [Notification]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Notification = + Notification(checkRequired("id", id), additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Notification = apply { + if (validated) { + return@apply + } + + id() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = (if (id.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Notification && + id == other.id && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(id, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Notification{id=$id, additionalProperties=$additionalProperties}" + } + + /** The template state after the operation. Always uppercase. */ + class State @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val DRAFT = of("DRAFT") + + @JvmField val PUBLISHED = of("PUBLISHED") + + @JvmStatic fun of(value: String) = State(JsonField.of(value)) + } + + /** An enum containing [State]'s known values. */ + enum class Known { + DRAFT, + PUBLISHED, + } + + /** + * An enum containing [State]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [State] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + DRAFT, + PUBLISHED, + /** An enum member indicating that [State] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + DRAFT -> Value.DRAFT + PUBLISHED -> Value.PUBLISHED + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws CourierInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + DRAFT -> Known.DRAFT + PUBLISHED -> Known.PUBLISHED + else -> throw CourierInvalidDataException("Unknown State: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws CourierInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { CourierInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + fun validate(): State = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is State && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is NotificationTemplateMutationResponse && + notification == other.notification && + state == other.state && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(notification, state, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "NotificationTemplateMutationResponse{notification=$notification, state=$state, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationTemplatePayload.kt b/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationTemplatePayload.kt new file mode 100644 index 00000000..95c08055 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationTemplatePayload.kt @@ -0,0 +1,866 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.notifications + +import com.courier.core.ExcludeMissing +import com.courier.core.JsonField +import com.courier.core.JsonMissing +import com.courier.core.JsonValue +import com.courier.core.checkKnown +import com.courier.core.checkRequired +import com.courier.core.toImmutable +import com.courier.errors.CourierInvalidDataException +import com.courier.models.ElementalContent +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 java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * Full document shape used in POST and PUT request bodies, and returned inside the GET response + * envelope. + */ +class NotificationTemplatePayload +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val brand: JsonField, + private val content: JsonField, + private val name: JsonField, + private val routing: JsonField, + private val subscription: JsonField, + private val tags: JsonField>, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("brand") @ExcludeMissing brand: JsonField = JsonMissing.of(), + @JsonProperty("content") + @ExcludeMissing + content: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("routing") @ExcludeMissing routing: JsonField = JsonMissing.of(), + @JsonProperty("subscription") + @ExcludeMissing + subscription: JsonField = JsonMissing.of(), + @JsonProperty("tags") @ExcludeMissing tags: JsonField> = JsonMissing.of(), + ) : this(brand, content, name, routing, subscription, tags, mutableMapOf()) + + /** + * Brand reference, or null for no brand. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun brand(): Optional = brand.getOptional("brand") + + /** + * Elemental content definition. + * + * @throws CourierInvalidDataException 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 content(): ElementalContent = content.getRequired("content") + + /** + * Display name for the template. + * + * @throws CourierInvalidDataException 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 name(): String = name.getRequired("name") + + /** + * Routing strategy reference, or null for none. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun routing(): Optional = routing.getOptional("routing") + + /** + * Subscription topic reference, or null for none. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun subscription(): Optional = subscription.getOptional("subscription") + + /** + * Tags for categorization. Send empty array for none. + * + * @throws CourierInvalidDataException 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 tags(): List = tags.getRequired("tags") + + /** + * Returns the raw JSON value of [brand]. + * + * Unlike [brand], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("brand") @ExcludeMissing fun _brand(): JsonField = brand + + /** + * Returns the raw JSON value of [content]. + * + * Unlike [content], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("content") @ExcludeMissing fun _content(): JsonField = content + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + + /** + * Returns the raw JSON value of [routing]. + * + * Unlike [routing], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("routing") @ExcludeMissing fun _routing(): JsonField = routing + + /** + * Returns the raw JSON value of [subscription]. + * + * Unlike [subscription], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("subscription") + @ExcludeMissing + fun _subscription(): JsonField = subscription + + /** + * Returns the raw JSON value of [tags]. + * + * Unlike [tags], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("tags") @ExcludeMissing fun _tags(): JsonField> = tags + + @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 [NotificationTemplatePayload]. + * + * The following fields are required: + * ```java + * .brand() + * .content() + * .name() + * .routing() + * .subscription() + * .tags() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [NotificationTemplatePayload]. */ + class Builder internal constructor() { + + private var brand: JsonField? = null + private var content: JsonField? = null + private var name: JsonField? = null + private var routing: JsonField? = null + private var subscription: JsonField? = null + private var tags: JsonField>? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(notificationTemplatePayload: NotificationTemplatePayload) = apply { + brand = notificationTemplatePayload.brand + content = notificationTemplatePayload.content + name = notificationTemplatePayload.name + routing = notificationTemplatePayload.routing + subscription = notificationTemplatePayload.subscription + tags = notificationTemplatePayload.tags.map { it.toMutableList() } + additionalProperties = notificationTemplatePayload.additionalProperties.toMutableMap() + } + + /** Brand reference, or null for no brand. */ + fun brand(brand: Brand?) = brand(JsonField.ofNullable(brand)) + + /** Alias for calling [Builder.brand] with `brand.orElse(null)`. */ + fun brand(brand: Optional) = brand(brand.getOrNull()) + + /** + * Sets [Builder.brand] to an arbitrary JSON value. + * + * You should usually call [Builder.brand] with a well-typed [Brand] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun brand(brand: JsonField) = apply { this.brand = brand } + + /** Elemental content definition. */ + fun content(content: ElementalContent) = content(JsonField.of(content)) + + /** + * Sets [Builder.content] to an arbitrary JSON value. + * + * You should usually call [Builder.content] with a well-typed [ElementalContent] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun content(content: JsonField) = apply { this.content = content } + + /** Display name for the template. */ + fun name(name: String) = name(JsonField.of(name)) + + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun name(name: JsonField) = apply { this.name = name } + + /** Routing strategy reference, or null for none. */ + fun routing(routing: Routing?) = routing(JsonField.ofNullable(routing)) + + /** Alias for calling [Builder.routing] with `routing.orElse(null)`. */ + fun routing(routing: Optional) = routing(routing.getOrNull()) + + /** + * Sets [Builder.routing] to an arbitrary JSON value. + * + * You should usually call [Builder.routing] with a well-typed [Routing] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun routing(routing: JsonField) = apply { this.routing = routing } + + /** Subscription topic reference, or null for none. */ + fun subscription(subscription: Subscription?) = + subscription(JsonField.ofNullable(subscription)) + + /** Alias for calling [Builder.subscription] with `subscription.orElse(null)`. */ + fun subscription(subscription: Optional) = + subscription(subscription.getOrNull()) + + /** + * Sets [Builder.subscription] to an arbitrary JSON value. + * + * You should usually call [Builder.subscription] with a well-typed [Subscription] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun subscription(subscription: JsonField) = apply { + this.subscription = subscription + } + + /** Tags for categorization. Send empty array for none. */ + fun tags(tags: List) = tags(JsonField.of(tags)) + + /** + * Sets [Builder.tags] to an arbitrary JSON value. + * + * You should usually call [Builder.tags] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun tags(tags: JsonField>) = apply { + this.tags = tags.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [tags]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addTag(tag: String) = apply { + tags = (tags ?: JsonField.of(mutableListOf())).also { checkKnown("tags", it).add(tag) } + } + + 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 [NotificationTemplatePayload]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .brand() + * .content() + * .name() + * .routing() + * .subscription() + * .tags() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): NotificationTemplatePayload = + NotificationTemplatePayload( + checkRequired("brand", brand), + checkRequired("content", content), + checkRequired("name", name), + checkRequired("routing", routing), + checkRequired("subscription", subscription), + checkRequired("tags", tags).map { it.toImmutable() }, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): NotificationTemplatePayload = apply { + if (validated) { + return@apply + } + + brand().ifPresent { it.validate() } + content().validate() + name() + routing().ifPresent { it.validate() } + subscription().ifPresent { it.validate() } + tags() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (brand.asKnown().getOrNull()?.validity() ?: 0) + + (content.asKnown().getOrNull()?.validity() ?: 0) + + (if (name.asKnown().isPresent) 1 else 0) + + (routing.asKnown().getOrNull()?.validity() ?: 0) + + (subscription.asKnown().getOrNull()?.validity() ?: 0) + + (tags.asKnown().getOrNull()?.size ?: 0) + + /** Brand reference, or null for no brand. */ + class Brand + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val id: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of() + ) : this(id, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 id(): String = id.getRequired("id") + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + @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 [Brand]. + * + * The following fields are required: + * ```java + * .id() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Brand]. */ + class Builder internal constructor() { + + private var id: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(brand: Brand) = apply { + id = brand.id + additionalProperties = brand.additionalProperties.toMutableMap() + } + + fun id(id: String) = id(JsonField.of(id)) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun id(id: JsonField) = apply { this.id = id } + + 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 [Brand]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Brand = Brand(checkRequired("id", id), additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Brand = apply { + if (validated) { + return@apply + } + + id() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = (if (id.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Brand && + id == other.id && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(id, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Brand{id=$id, additionalProperties=$additionalProperties}" + } + + /** Routing strategy reference, or null for none. */ + class Routing + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val strategyId: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("strategy_id") + @ExcludeMissing + strategyId: JsonField = JsonMissing.of() + ) : this(strategyId, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 strategyId(): String = strategyId.getRequired("strategy_id") + + /** + * Returns the raw JSON value of [strategyId]. + * + * Unlike [strategyId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("strategy_id") + @ExcludeMissing + fun _strategyId(): JsonField = strategyId + + @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 [Routing]. + * + * The following fields are required: + * ```java + * .strategyId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Routing]. */ + class Builder internal constructor() { + + private var strategyId: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(routing: Routing) = apply { + strategyId = routing.strategyId + additionalProperties = routing.additionalProperties.toMutableMap() + } + + fun strategyId(strategyId: String) = strategyId(JsonField.of(strategyId)) + + /** + * Sets [Builder.strategyId] to an arbitrary JSON value. + * + * You should usually call [Builder.strategyId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun strategyId(strategyId: JsonField) = apply { this.strategyId = strategyId } + + 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 [Routing]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .strategyId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Routing = + Routing( + checkRequired("strategyId", strategyId), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Routing = apply { + if (validated) { + return@apply + } + + strategyId() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = (if (strategyId.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Routing && + strategyId == other.strategyId && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(strategyId, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Routing{strategyId=$strategyId, additionalProperties=$additionalProperties}" + } + + /** Subscription topic reference, or null for none. */ + class Subscription + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val topicId: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("topic_id") @ExcludeMissing topicId: JsonField = JsonMissing.of() + ) : this(topicId, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 topicId(): String = topicId.getRequired("topic_id") + + /** + * Returns the raw JSON value of [topicId]. + * + * Unlike [topicId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("topic_id") @ExcludeMissing fun _topicId(): JsonField = topicId + + @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 [Subscription]. + * + * The following fields are required: + * ```java + * .topicId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Subscription]. */ + class Builder internal constructor() { + + private var topicId: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(subscription: Subscription) = apply { + topicId = subscription.topicId + additionalProperties = subscription.additionalProperties.toMutableMap() + } + + fun topicId(topicId: String) = topicId(JsonField.of(topicId)) + + /** + * Sets [Builder.topicId] to an arbitrary JSON value. + * + * You should usually call [Builder.topicId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun topicId(topicId: JsonField) = apply { this.topicId = topicId } + + 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 [Subscription]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .topicId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Subscription = + Subscription(checkRequired("topicId", topicId), additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Subscription = apply { + if (validated) { + return@apply + } + + topicId() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = (if (topicId.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Subscription && + topicId == other.topicId && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(topicId, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Subscription{topicId=$topicId, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is NotificationTemplatePayload && + brand == other.brand && + content == other.content && + name == other.name && + routing == other.routing && + subscription == other.subscription && + tags == other.tags && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(brand, content, name, routing, subscription, tags, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "NotificationTemplatePayload{brand=$brand, content=$content, name=$name, routing=$routing, subscription=$subscription, tags=$tags, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationTemplateSummary.kt b/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationTemplateSummary.kt new file mode 100644 index 00000000..554b46f7 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationTemplateSummary.kt @@ -0,0 +1,566 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.notifications + +import com.courier.core.Enum +import com.courier.core.ExcludeMissing +import com.courier.core.JsonField +import com.courier.core.JsonMissing +import com.courier.core.JsonValue +import com.courier.core.checkKnown +import com.courier.core.checkRequired +import com.courier.core.toImmutable +import com.courier.errors.CourierInvalidDataException +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 java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** V2 (CDS) template summary returned in list responses. */ +class NotificationTemplateSummary +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val id: JsonField, + private val created: JsonField, + private val creator: JsonField, + private val name: JsonField, + private val state: JsonField, + private val tags: JsonField>, + private val updated: JsonField, + private val updater: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("created") @ExcludeMissing created: JsonField = JsonMissing.of(), + @JsonProperty("creator") @ExcludeMissing creator: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("state") @ExcludeMissing state: JsonField = JsonMissing.of(), + @JsonProperty("tags") @ExcludeMissing tags: JsonField> = JsonMissing.of(), + @JsonProperty("updated") @ExcludeMissing updated: JsonField = JsonMissing.of(), + @JsonProperty("updater") @ExcludeMissing updater: JsonField = JsonMissing.of(), + ) : this(id, created, creator, name, state, tags, updated, updater, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 id(): String = id.getRequired("id") + + /** + * Epoch milliseconds when the template was created. + * + * @throws CourierInvalidDataException 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 created(): Long = created.getRequired("created") + + /** + * User ID of the creator. + * + * @throws CourierInvalidDataException 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 creator(): String = creator.getRequired("creator") + + /** + * @throws CourierInvalidDataException 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 name(): String = name.getRequired("name") + + /** + * @throws CourierInvalidDataException 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 state(): State = state.getRequired("state") + + /** + * @throws CourierInvalidDataException 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 tags(): List = tags.getRequired("tags") + + /** + * Epoch milliseconds of last update. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun updated(): Optional = updated.getOptional("updated") + + /** + * User ID of the last updater. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun updater(): Optional = updater.getOptional("updater") + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + /** + * Returns the raw JSON value of [created]. + * + * Unlike [created], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created") @ExcludeMissing fun _created(): JsonField = created + + /** + * Returns the raw JSON value of [creator]. + * + * Unlike [creator], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("creator") @ExcludeMissing fun _creator(): JsonField = creator + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + + /** + * Returns the raw JSON value of [state]. + * + * Unlike [state], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("state") @ExcludeMissing fun _state(): JsonField = state + + /** + * Returns the raw JSON value of [tags]. + * + * Unlike [tags], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("tags") @ExcludeMissing fun _tags(): JsonField> = tags + + /** + * Returns the raw JSON value of [updated]. + * + * Unlike [updated], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("updated") @ExcludeMissing fun _updated(): JsonField = updated + + /** + * Returns the raw JSON value of [updater]. + * + * Unlike [updater], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("updater") @ExcludeMissing fun _updater(): JsonField = updater + + @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 [NotificationTemplateSummary]. + * + * The following fields are required: + * ```java + * .id() + * .created() + * .creator() + * .name() + * .state() + * .tags() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [NotificationTemplateSummary]. */ + class Builder internal constructor() { + + private var id: JsonField? = null + private var created: JsonField? = null + private var creator: JsonField? = null + private var name: JsonField? = null + private var state: JsonField? = null + private var tags: JsonField>? = null + private var updated: JsonField = JsonMissing.of() + private var updater: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(notificationTemplateSummary: NotificationTemplateSummary) = apply { + id = notificationTemplateSummary.id + created = notificationTemplateSummary.created + creator = notificationTemplateSummary.creator + name = notificationTemplateSummary.name + state = notificationTemplateSummary.state + tags = notificationTemplateSummary.tags.map { it.toMutableList() } + updated = notificationTemplateSummary.updated + updater = notificationTemplateSummary.updater + additionalProperties = notificationTemplateSummary.additionalProperties.toMutableMap() + } + + fun id(id: String) = id(JsonField.of(id)) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun id(id: JsonField) = apply { this.id = id } + + /** Epoch milliseconds when the template was created. */ + fun created(created: Long) = created(JsonField.of(created)) + + /** + * Sets [Builder.created] to an arbitrary JSON value. + * + * You should usually call [Builder.created] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun created(created: JsonField) = apply { this.created = created } + + /** User ID of the creator. */ + fun creator(creator: String) = creator(JsonField.of(creator)) + + /** + * Sets [Builder.creator] to an arbitrary JSON value. + * + * You should usually call [Builder.creator] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun creator(creator: JsonField) = apply { this.creator = creator } + + fun name(name: String) = name(JsonField.of(name)) + + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun name(name: JsonField) = apply { this.name = name } + + fun state(state: State) = state(JsonField.of(state)) + + /** + * Sets [Builder.state] to an arbitrary JSON value. + * + * You should usually call [Builder.state] with a well-typed [State] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun state(state: JsonField) = apply { this.state = state } + + fun tags(tags: List) = tags(JsonField.of(tags)) + + /** + * Sets [Builder.tags] to an arbitrary JSON value. + * + * You should usually call [Builder.tags] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun tags(tags: JsonField>) = apply { + this.tags = tags.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [tags]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addTag(tag: String) = apply { + tags = (tags ?: JsonField.of(mutableListOf())).also { checkKnown("tags", it).add(tag) } + } + + /** Epoch milliseconds of last update. */ + fun updated(updated: Long) = updated(JsonField.of(updated)) + + /** + * Sets [Builder.updated] to an arbitrary JSON value. + * + * You should usually call [Builder.updated] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun updated(updated: JsonField) = apply { this.updated = updated } + + /** User ID of the last updater. */ + fun updater(updater: String) = updater(JsonField.of(updater)) + + /** + * Sets [Builder.updater] to an arbitrary JSON value. + * + * You should usually call [Builder.updater] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun updater(updater: JsonField) = apply { this.updater = updater } + + 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 [NotificationTemplateSummary]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .created() + * .creator() + * .name() + * .state() + * .tags() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): NotificationTemplateSummary = + NotificationTemplateSummary( + checkRequired("id", id), + checkRequired("created", created), + checkRequired("creator", creator), + checkRequired("name", name), + checkRequired("state", state), + checkRequired("tags", tags).map { it.toImmutable() }, + updated, + updater, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): NotificationTemplateSummary = apply { + if (validated) { + return@apply + } + + id() + created() + creator() + name() + state().validate() + tags() + updated() + updater() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (id.asKnown().isPresent) 1 else 0) + + (if (created.asKnown().isPresent) 1 else 0) + + (if (creator.asKnown().isPresent) 1 else 0) + + (if (name.asKnown().isPresent) 1 else 0) + + (state.asKnown().getOrNull()?.validity() ?: 0) + + (tags.asKnown().getOrNull()?.size ?: 0) + + (if (updated.asKnown().isPresent) 1 else 0) + + (if (updater.asKnown().isPresent) 1 else 0) + + class State @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val DRAFT = of("DRAFT") + + @JvmField val PUBLISHED = of("PUBLISHED") + + @JvmStatic fun of(value: String) = State(JsonField.of(value)) + } + + /** An enum containing [State]'s known values. */ + enum class Known { + DRAFT, + PUBLISHED, + } + + /** + * An enum containing [State]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [State] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + DRAFT, + PUBLISHED, + /** An enum member indicating that [State] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + DRAFT -> Value.DRAFT + PUBLISHED -> Value.PUBLISHED + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws CourierInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + DRAFT -> Known.DRAFT + PUBLISHED -> Known.PUBLISHED + else -> throw CourierInvalidDataException("Unknown State: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws CourierInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { CourierInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + fun validate(): State = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is State && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is NotificationTemplateSummary && + id == other.id && + created == other.created && + creator == other.creator && + name == other.name && + state == other.state && + tags == other.tags && + updated == other.updated && + updater == other.updater && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + id, + created, + creator, + name, + state, + tags, + updated, + updater, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "NotificationTemplateSummary{id=$id, created=$created, creator=$creator, name=$name, state=$state, tags=$tags, updated=$updated, updater=$updater, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationTemplateUpdateRequest.kt b/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationTemplateUpdateRequest.kt new file mode 100644 index 00000000..7e87677f --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationTemplateUpdateRequest.kt @@ -0,0 +1,364 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.notifications + +import com.courier.core.Enum +import com.courier.core.ExcludeMissing +import com.courier.core.JsonField +import com.courier.core.JsonMissing +import com.courier.core.JsonValue +import com.courier.core.checkRequired +import com.courier.errors.CourierInvalidDataException +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 java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * Request body for replacing a notification template. Same shape as create. All fields required + * (PUT = full replacement). + */ +class NotificationTemplateUpdateRequest +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val notification: JsonField, + private val state: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("notification") + @ExcludeMissing + notification: JsonField = JsonMissing.of(), + @JsonProperty("state") @ExcludeMissing state: JsonField = JsonMissing.of(), + ) : this(notification, state, mutableMapOf()) + + /** + * Full document shape used in POST and PUT request bodies, and returned inside the GET response + * envelope. + * + * @throws CourierInvalidDataException 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 notification(): NotificationTemplatePayload = notification.getRequired("notification") + + /** + * Template state after update. Case-insensitive input, normalized to uppercase in the response. + * Defaults to "DRAFT". + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun state(): Optional = state.getOptional("state") + + /** + * Returns the raw JSON value of [notification]. + * + * Unlike [notification], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("notification") + @ExcludeMissing + fun _notification(): JsonField = notification + + /** + * Returns the raw JSON value of [state]. + * + * Unlike [state], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("state") @ExcludeMissing fun _state(): JsonField = state + + @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 + * [NotificationTemplateUpdateRequest]. + * + * The following fields are required: + * ```java + * .notification() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [NotificationTemplateUpdateRequest]. */ + class Builder internal constructor() { + + private var notification: JsonField? = null + private var state: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(notificationTemplateUpdateRequest: NotificationTemplateUpdateRequest) = + apply { + notification = notificationTemplateUpdateRequest.notification + state = notificationTemplateUpdateRequest.state + additionalProperties = + notificationTemplateUpdateRequest.additionalProperties.toMutableMap() + } + + /** + * Full document shape used in POST and PUT request bodies, and returned inside the GET + * response envelope. + */ + fun notification(notification: NotificationTemplatePayload) = + notification(JsonField.of(notification)) + + /** + * Sets [Builder.notification] to an arbitrary JSON value. + * + * You should usually call [Builder.notification] with a well-typed + * [NotificationTemplatePayload] value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun notification(notification: JsonField) = apply { + this.notification = notification + } + + /** + * Template state after update. Case-insensitive input, normalized to uppercase in the + * response. Defaults to "DRAFT". + */ + fun state(state: State) = state(JsonField.of(state)) + + /** + * Sets [Builder.state] to an arbitrary JSON value. + * + * You should usually call [Builder.state] with a well-typed [State] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun state(state: JsonField) = apply { this.state = state } + + 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 [NotificationTemplateUpdateRequest]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .notification() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): NotificationTemplateUpdateRequest = + NotificationTemplateUpdateRequest( + checkRequired("notification", notification), + state, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): NotificationTemplateUpdateRequest = apply { + if (validated) { + return@apply + } + + notification().validate() + state().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (notification.asKnown().getOrNull()?.validity() ?: 0) + + (state.asKnown().getOrNull()?.validity() ?: 0) + + /** + * Template state after update. Case-insensitive input, normalized to uppercase in the response. + * Defaults to "DRAFT". + */ + class State @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val DRAFT = of("DRAFT") + + @JvmField val PUBLISHED = of("PUBLISHED") + + @JvmStatic fun of(value: String) = State(JsonField.of(value)) + } + + /** An enum containing [State]'s known values. */ + enum class Known { + DRAFT, + PUBLISHED, + } + + /** + * An enum containing [State]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [State] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + DRAFT, + PUBLISHED, + /** An enum member indicating that [State] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + DRAFT -> Value.DRAFT + PUBLISHED -> Value.PUBLISHED + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws CourierInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + DRAFT -> Known.DRAFT + PUBLISHED -> Known.PUBLISHED + else -> throw CourierInvalidDataException("Unknown State: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws CourierInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { CourierInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + fun validate(): State = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is State && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is NotificationTemplateUpdateRequest && + notification == other.notification && + state == other.state && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(notification, state, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "NotificationTemplateUpdateRequest{notification=$notification, state=$state, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/services/async/NotificationServiceAsync.kt b/courier-java-core/src/main/kotlin/com/courier/services/async/NotificationServiceAsync.kt index 7cb2c3ed..5d687834 100644 --- a/courier-java-core/src/main/kotlin/com/courier/services/async/NotificationServiceAsync.kt +++ b/courier-java-core/src/main/kotlin/com/courier/services/async/NotificationServiceAsync.kt @@ -4,11 +4,20 @@ package com.courier.services.async import com.courier.core.ClientOptions import com.courier.core.RequestOptions +import com.courier.core.http.HttpResponse import com.courier.core.http.HttpResponseFor +import com.courier.models.notifications.NotificationArchiveParams +import com.courier.models.notifications.NotificationCreateParams import com.courier.models.notifications.NotificationGetContent import com.courier.models.notifications.NotificationListParams import com.courier.models.notifications.NotificationListResponse +import com.courier.models.notifications.NotificationPublishParams +import com.courier.models.notifications.NotificationReplaceParams import com.courier.models.notifications.NotificationRetrieveContentParams +import com.courier.models.notifications.NotificationRetrieveParams +import com.courier.models.notifications.NotificationTemplateCreateRequest +import com.courier.models.notifications.NotificationTemplateGetResponse +import com.courier.models.notifications.NotificationTemplateMutationResponse import com.courier.services.async.notifications.CheckServiceAsync import com.courier.services.async.notifications.DraftServiceAsync import java.util.concurrent.CompletableFuture @@ -32,6 +41,80 @@ interface NotificationServiceAsync { fun checks(): CheckServiceAsync + /** + * Create a notification template. Requires all fields in the notification object. Templates are + * created in draft state by default. + */ + fun create( + params: NotificationCreateParams + ): CompletableFuture = + create(params, RequestOptions.none()) + + /** @see create */ + fun create( + params: NotificationCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see create */ + fun create( + notificationTemplateCreateRequest: NotificationTemplateCreateRequest, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + create( + NotificationCreateParams.builder() + .notificationTemplateCreateRequest(notificationTemplateCreateRequest) + .build(), + requestOptions, + ) + + /** @see create */ + fun create( + notificationTemplateCreateRequest: NotificationTemplateCreateRequest + ): CompletableFuture = + create(notificationTemplateCreateRequest, RequestOptions.none()) + + /** + * Retrieve a notification template by ID. Returns the published version by default. Pass + * version=draft to retrieve an unpublished template. + */ + fun retrieve(id: String): CompletableFuture = + retrieve(id, NotificationRetrieveParams.none()) + + /** @see retrieve */ + fun retrieve( + id: String, + params: NotificationRetrieveParams = NotificationRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + retrieve(params.toBuilder().id(id).build(), requestOptions) + + /** @see retrieve */ + fun retrieve( + id: String, + params: NotificationRetrieveParams = NotificationRetrieveParams.none(), + ): CompletableFuture = + retrieve(id, params, RequestOptions.none()) + + /** @see retrieve */ + fun retrieve( + params: NotificationRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see retrieve */ + fun retrieve( + params: NotificationRetrieveParams + ): CompletableFuture = retrieve(params, RequestOptions.none()) + + /** @see retrieve */ + fun retrieve( + id: String, + requestOptions: RequestOptions, + ): CompletableFuture = + retrieve(id, NotificationRetrieveParams.none(), requestOptions) + + /** List notification templates in your workspace. */ fun list(): CompletableFuture = list(NotificationListParams.none()) /** @see list */ @@ -49,6 +132,95 @@ interface NotificationServiceAsync { fun list(requestOptions: RequestOptions): CompletableFuture = list(NotificationListParams.none(), requestOptions) + /** Archive a notification template. */ + fun archive(id: String): CompletableFuture = + archive(id, NotificationArchiveParams.none()) + + /** @see archive */ + fun archive( + id: String, + params: NotificationArchiveParams = NotificationArchiveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = archive(params.toBuilder().id(id).build(), requestOptions) + + /** @see archive */ + fun archive( + id: String, + params: NotificationArchiveParams = NotificationArchiveParams.none(), + ): CompletableFuture = archive(id, params, RequestOptions.none()) + + /** @see archive */ + fun archive( + params: NotificationArchiveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see archive */ + fun archive(params: NotificationArchiveParams): CompletableFuture = + archive(params, RequestOptions.none()) + + /** @see archive */ + fun archive(id: String, requestOptions: RequestOptions): CompletableFuture = + archive(id, NotificationArchiveParams.none(), requestOptions) + + /** Publish the current draft of a notification template. */ + fun publish(id: String): CompletableFuture = + publish(id, NotificationPublishParams.none()) + + /** @see publish */ + fun publish( + id: String, + params: NotificationPublishParams = NotificationPublishParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = publish(params.toBuilder().id(id).build(), requestOptions) + + /** @see publish */ + fun publish( + id: String, + params: NotificationPublishParams = NotificationPublishParams.none(), + ): CompletableFuture = publish(id, params, RequestOptions.none()) + + /** @see publish */ + fun publish( + params: NotificationPublishParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see publish */ + fun publish(params: NotificationPublishParams): CompletableFuture = + publish(params, RequestOptions.none()) + + /** @see publish */ + fun publish(id: String, requestOptions: RequestOptions): CompletableFuture = + publish(id, NotificationPublishParams.none(), requestOptions) + + /** Replace a notification template. All fields are required. */ + fun replace( + id: String, + params: NotificationReplaceParams, + ): CompletableFuture = + replace(id, params, RequestOptions.none()) + + /** @see replace */ + fun replace( + id: String, + params: NotificationReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + replace(params.toBuilder().id(id).build(), requestOptions) + + /** @see replace */ + fun replace( + params: NotificationReplaceParams + ): CompletableFuture = + replace(params, RequestOptions.none()) + + /** @see replace */ + fun replace( + params: NotificationReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + fun retrieveContent(id: String): CompletableFuture = retrieveContent(id, NotificationRetrieveContentParams.none()) @@ -104,6 +276,82 @@ interface NotificationServiceAsync { fun checks(): CheckServiceAsync.WithRawResponse + /** + * Returns a raw HTTP response for `post /notifications`, but is otherwise the same as + * [NotificationServiceAsync.create]. + */ + fun create( + params: NotificationCreateParams + ): CompletableFuture> = + create(params, RequestOptions.none()) + + /** @see create */ + fun create( + params: NotificationCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see create */ + fun create( + notificationTemplateCreateRequest: NotificationTemplateCreateRequest, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + create( + NotificationCreateParams.builder() + .notificationTemplateCreateRequest(notificationTemplateCreateRequest) + .build(), + requestOptions, + ) + + /** @see create */ + fun create( + notificationTemplateCreateRequest: NotificationTemplateCreateRequest + ): CompletableFuture> = + create(notificationTemplateCreateRequest, RequestOptions.none()) + + /** + * Returns a raw HTTP response for `get /notifications/{id}`, but is otherwise the same as + * [NotificationServiceAsync.retrieve]. + */ + fun retrieve( + id: String + ): CompletableFuture> = + retrieve(id, NotificationRetrieveParams.none()) + + /** @see retrieve */ + fun retrieve( + id: String, + params: NotificationRetrieveParams = NotificationRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + retrieve(params.toBuilder().id(id).build(), requestOptions) + + /** @see retrieve */ + fun retrieve( + id: String, + params: NotificationRetrieveParams = NotificationRetrieveParams.none(), + ): CompletableFuture> = + retrieve(id, params, RequestOptions.none()) + + /** @see retrieve */ + fun retrieve( + params: NotificationRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see retrieve */ + fun retrieve( + params: NotificationRetrieveParams + ): CompletableFuture> = + retrieve(params, RequestOptions.none()) + + /** @see retrieve */ + fun retrieve( + id: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + retrieve(id, NotificationRetrieveParams.none(), requestOptions) + /** * Returns a raw HTTP response for `get /notifications`, but is otherwise the same as * [NotificationServiceAsync.list]. @@ -129,6 +377,106 @@ interface NotificationServiceAsync { ): CompletableFuture> = list(NotificationListParams.none(), requestOptions) + /** + * Returns a raw HTTP response for `delete /notifications/{id}`, but is otherwise the same + * as [NotificationServiceAsync.archive]. + */ + fun archive(id: String): CompletableFuture = + archive(id, NotificationArchiveParams.none()) + + /** @see archive */ + fun archive( + id: String, + params: NotificationArchiveParams = NotificationArchiveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + archive(params.toBuilder().id(id).build(), requestOptions) + + /** @see archive */ + fun archive( + id: String, + params: NotificationArchiveParams = NotificationArchiveParams.none(), + ): CompletableFuture = archive(id, params, RequestOptions.none()) + + /** @see archive */ + fun archive( + params: NotificationArchiveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see archive */ + fun archive(params: NotificationArchiveParams): CompletableFuture = + archive(params, RequestOptions.none()) + + /** @see archive */ + fun archive(id: String, requestOptions: RequestOptions): CompletableFuture = + archive(id, NotificationArchiveParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `post /notifications/{id}/publish`, but is otherwise the + * same as [NotificationServiceAsync.publish]. + */ + fun publish(id: String): CompletableFuture = + publish(id, NotificationPublishParams.none()) + + /** @see publish */ + fun publish( + id: String, + params: NotificationPublishParams = NotificationPublishParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + publish(params.toBuilder().id(id).build(), requestOptions) + + /** @see publish */ + fun publish( + id: String, + params: NotificationPublishParams = NotificationPublishParams.none(), + ): CompletableFuture = publish(id, params, RequestOptions.none()) + + /** @see publish */ + fun publish( + params: NotificationPublishParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see publish */ + fun publish(params: NotificationPublishParams): CompletableFuture = + publish(params, RequestOptions.none()) + + /** @see publish */ + fun publish(id: String, requestOptions: RequestOptions): CompletableFuture = + publish(id, NotificationPublishParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `put /notifications/{id}`, but is otherwise the same as + * [NotificationServiceAsync.replace]. + */ + fun replace( + id: String, + params: NotificationReplaceParams, + ): CompletableFuture> = + replace(id, params, RequestOptions.none()) + + /** @see replace */ + fun replace( + id: String, + params: NotificationReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + replace(params.toBuilder().id(id).build(), requestOptions) + + /** @see replace */ + fun replace( + params: NotificationReplaceParams + ): CompletableFuture> = + replace(params, RequestOptions.none()) + + /** @see replace */ + fun replace( + params: NotificationReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + /** * Returns a raw HTTP response for `get /notifications/{id}/content`, but is otherwise the * same as [NotificationServiceAsync.retrieveContent]. diff --git a/courier-java-core/src/main/kotlin/com/courier/services/async/NotificationServiceAsyncImpl.kt b/courier-java-core/src/main/kotlin/com/courier/services/async/NotificationServiceAsyncImpl.kt index 4a21e0c3..be690f47 100644 --- a/courier-java-core/src/main/kotlin/com/courier/services/async/NotificationServiceAsyncImpl.kt +++ b/courier-java-core/src/main/kotlin/com/courier/services/async/NotificationServiceAsyncImpl.kt @@ -5,6 +5,7 @@ package com.courier.services.async import com.courier.core.ClientOptions import com.courier.core.RequestOptions import com.courier.core.checkRequired +import com.courier.core.handlers.emptyHandler import com.courier.core.handlers.errorBodyHandler import com.courier.core.handlers.errorHandler import com.courier.core.handlers.jsonHandler @@ -13,12 +14,20 @@ import com.courier.core.http.HttpRequest import com.courier.core.http.HttpResponse import com.courier.core.http.HttpResponse.Handler import com.courier.core.http.HttpResponseFor +import com.courier.core.http.json import com.courier.core.http.parseable import com.courier.core.prepareAsync +import com.courier.models.notifications.NotificationArchiveParams +import com.courier.models.notifications.NotificationCreateParams import com.courier.models.notifications.NotificationGetContent import com.courier.models.notifications.NotificationListParams import com.courier.models.notifications.NotificationListResponse +import com.courier.models.notifications.NotificationPublishParams +import com.courier.models.notifications.NotificationReplaceParams import com.courier.models.notifications.NotificationRetrieveContentParams +import com.courier.models.notifications.NotificationRetrieveParams +import com.courier.models.notifications.NotificationTemplateGetResponse +import com.courier.models.notifications.NotificationTemplateMutationResponse import com.courier.services.async.notifications.CheckServiceAsync import com.courier.services.async.notifications.CheckServiceAsyncImpl import com.courier.services.async.notifications.DraftServiceAsync @@ -47,6 +56,20 @@ class NotificationServiceAsyncImpl internal constructor(private val clientOption override fun checks(): CheckServiceAsync = checks + override fun create( + params: NotificationCreateParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /notifications + withRawResponse().create(params, requestOptions).thenApply { it.parse() } + + override fun retrieve( + params: NotificationRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /notifications/{id} + withRawResponse().retrieve(params, requestOptions).thenApply { it.parse() } + override fun list( params: NotificationListParams, requestOptions: RequestOptions, @@ -54,6 +77,27 @@ class NotificationServiceAsyncImpl internal constructor(private val clientOption // get /notifications withRawResponse().list(params, requestOptions).thenApply { it.parse() } + override fun archive( + params: NotificationArchiveParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // delete /notifications/{id} + withRawResponse().archive(params, requestOptions).thenAccept {} + + override fun publish( + params: NotificationPublishParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /notifications/{id}/publish + withRawResponse().publish(params, requestOptions).thenAccept {} + + override fun replace( + params: NotificationReplaceParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // put /notifications/{id} + withRawResponse().replace(params, requestOptions).thenApply { it.parse() } + override fun retrieveContent( params: NotificationRetrieveContentParams, requestOptions: RequestOptions, @@ -86,6 +130,70 @@ class NotificationServiceAsyncImpl internal constructor(private val clientOption override fun checks(): CheckServiceAsync.WithRawResponse = checks + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun create( + params: NotificationCreateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("notifications") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + errorHandler.handle(response).parseable { + response + .use { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun retrieve( + params: NotificationRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("id", params.id().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("notifications", params._pathParam(0)) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + errorHandler.handle(response).parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + private val listHandler: Handler = jsonHandler(clientOptions.jsonMapper) @@ -116,6 +224,94 @@ class NotificationServiceAsyncImpl internal constructor(private val clientOption } } + private val archiveHandler: Handler = emptyHandler() + + override fun archive( + params: NotificationArchiveParams, + requestOptions: RequestOptions, + ): CompletableFuture { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("id", params.id().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("notifications", params._pathParam(0)) + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + errorHandler.handle(response).parseable { + response.use { archiveHandler.handle(it) } + } + } + } + + private val publishHandler: Handler = emptyHandler() + + override fun publish( + params: NotificationPublishParams, + requestOptions: RequestOptions, + ): CompletableFuture { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("id", params.id().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("notifications", params._pathParam(0), "publish") + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + errorHandler.handle(response).parseable { + response.use { publishHandler.handle(it) } + } + } + } + + private val replaceHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun replace( + params: NotificationReplaceParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("id", params.id().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.PUT) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("notifications", params._pathParam(0)) + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + errorHandler.handle(response).parseable { + response + .use { replaceHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + private val retrieveContentHandler: Handler = jsonHandler(clientOptions.jsonMapper) diff --git a/courier-java-core/src/main/kotlin/com/courier/services/blocking/NotificationService.kt b/courier-java-core/src/main/kotlin/com/courier/services/blocking/NotificationService.kt index b316e37a..711e3b90 100644 --- a/courier-java-core/src/main/kotlin/com/courier/services/blocking/NotificationService.kt +++ b/courier-java-core/src/main/kotlin/com/courier/services/blocking/NotificationService.kt @@ -4,11 +4,20 @@ package com.courier.services.blocking import com.courier.core.ClientOptions import com.courier.core.RequestOptions +import com.courier.core.http.HttpResponse import com.courier.core.http.HttpResponseFor +import com.courier.models.notifications.NotificationArchiveParams +import com.courier.models.notifications.NotificationCreateParams import com.courier.models.notifications.NotificationGetContent import com.courier.models.notifications.NotificationListParams import com.courier.models.notifications.NotificationListResponse +import com.courier.models.notifications.NotificationPublishParams +import com.courier.models.notifications.NotificationReplaceParams import com.courier.models.notifications.NotificationRetrieveContentParams +import com.courier.models.notifications.NotificationRetrieveParams +import com.courier.models.notifications.NotificationTemplateCreateRequest +import com.courier.models.notifications.NotificationTemplateGetResponse +import com.courier.models.notifications.NotificationTemplateMutationResponse import com.courier.services.blocking.notifications.CheckService import com.courier.services.blocking.notifications.DraftService import com.google.errorprone.annotations.MustBeClosed @@ -32,6 +41,72 @@ interface NotificationService { fun checks(): CheckService + /** + * Create a notification template. Requires all fields in the notification object. Templates are + * created in draft state by default. + */ + fun create(params: NotificationCreateParams): NotificationTemplateMutationResponse = + create(params, RequestOptions.none()) + + /** @see create */ + fun create( + params: NotificationCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): NotificationTemplateMutationResponse + + /** @see create */ + fun create( + notificationTemplateCreateRequest: NotificationTemplateCreateRequest, + requestOptions: RequestOptions = RequestOptions.none(), + ): NotificationTemplateMutationResponse = + create( + NotificationCreateParams.builder() + .notificationTemplateCreateRequest(notificationTemplateCreateRequest) + .build(), + requestOptions, + ) + + /** @see create */ + fun create( + notificationTemplateCreateRequest: NotificationTemplateCreateRequest + ): NotificationTemplateMutationResponse = + create(notificationTemplateCreateRequest, RequestOptions.none()) + + /** + * Retrieve a notification template by ID. Returns the published version by default. Pass + * version=draft to retrieve an unpublished template. + */ + fun retrieve(id: String): NotificationTemplateGetResponse = + retrieve(id, NotificationRetrieveParams.none()) + + /** @see retrieve */ + fun retrieve( + id: String, + params: NotificationRetrieveParams = NotificationRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): NotificationTemplateGetResponse = retrieve(params.toBuilder().id(id).build(), requestOptions) + + /** @see retrieve */ + fun retrieve( + id: String, + params: NotificationRetrieveParams = NotificationRetrieveParams.none(), + ): NotificationTemplateGetResponse = retrieve(id, params, RequestOptions.none()) + + /** @see retrieve */ + fun retrieve( + params: NotificationRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): NotificationTemplateGetResponse + + /** @see retrieve */ + fun retrieve(params: NotificationRetrieveParams): NotificationTemplateGetResponse = + retrieve(params, RequestOptions.none()) + + /** @see retrieve */ + fun retrieve(id: String, requestOptions: RequestOptions): NotificationTemplateGetResponse = + retrieve(id, NotificationRetrieveParams.none(), requestOptions) + + /** List notification templates in your workspace. */ fun list(): NotificationListResponse = list(NotificationListParams.none()) /** @see list */ @@ -49,6 +124,84 @@ interface NotificationService { fun list(requestOptions: RequestOptions): NotificationListResponse = list(NotificationListParams.none(), requestOptions) + /** Archive a notification template. */ + fun archive(id: String) = archive(id, NotificationArchiveParams.none()) + + /** @see archive */ + fun archive( + id: String, + params: NotificationArchiveParams = NotificationArchiveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ) = archive(params.toBuilder().id(id).build(), requestOptions) + + /** @see archive */ + fun archive(id: String, params: NotificationArchiveParams = NotificationArchiveParams.none()) = + archive(id, params, RequestOptions.none()) + + /** @see archive */ + fun archive( + params: NotificationArchiveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ) + + /** @see archive */ + fun archive(params: NotificationArchiveParams) = archive(params, RequestOptions.none()) + + /** @see archive */ + fun archive(id: String, requestOptions: RequestOptions) = + archive(id, NotificationArchiveParams.none(), requestOptions) + + /** Publish the current draft of a notification template. */ + fun publish(id: String) = publish(id, NotificationPublishParams.none()) + + /** @see publish */ + fun publish( + id: String, + params: NotificationPublishParams = NotificationPublishParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ) = publish(params.toBuilder().id(id).build(), requestOptions) + + /** @see publish */ + fun publish(id: String, params: NotificationPublishParams = NotificationPublishParams.none()) = + publish(id, params, RequestOptions.none()) + + /** @see publish */ + fun publish( + params: NotificationPublishParams, + requestOptions: RequestOptions = RequestOptions.none(), + ) + + /** @see publish */ + fun publish(params: NotificationPublishParams) = publish(params, RequestOptions.none()) + + /** @see publish */ + fun publish(id: String, requestOptions: RequestOptions) = + publish(id, NotificationPublishParams.none(), requestOptions) + + /** Replace a notification template. All fields are required. */ + fun replace( + id: String, + params: NotificationReplaceParams, + ): NotificationTemplateMutationResponse = replace(id, params, RequestOptions.none()) + + /** @see replace */ + fun replace( + id: String, + params: NotificationReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): NotificationTemplateMutationResponse = + replace(params.toBuilder().id(id).build(), requestOptions) + + /** @see replace */ + fun replace(params: NotificationReplaceParams): NotificationTemplateMutationResponse = + replace(params, RequestOptions.none()) + + /** @see replace */ + fun replace( + params: NotificationReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): NotificationTemplateMutationResponse + fun retrieveContent(id: String): NotificationGetContent = retrieveContent(id, NotificationRetrieveContentParams.none()) @@ -97,6 +250,90 @@ interface NotificationService { fun checks(): CheckService.WithRawResponse + /** + * Returns a raw HTTP response for `post /notifications`, but is otherwise the same as + * [NotificationService.create]. + */ + @MustBeClosed + fun create( + params: NotificationCreateParams + ): HttpResponseFor = + create(params, RequestOptions.none()) + + /** @see create */ + @MustBeClosed + fun create( + params: NotificationCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see create */ + @MustBeClosed + fun create( + notificationTemplateCreateRequest: NotificationTemplateCreateRequest, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + create( + NotificationCreateParams.builder() + .notificationTemplateCreateRequest(notificationTemplateCreateRequest) + .build(), + requestOptions, + ) + + /** @see create */ + @MustBeClosed + fun create( + notificationTemplateCreateRequest: NotificationTemplateCreateRequest + ): HttpResponseFor = + create(notificationTemplateCreateRequest, RequestOptions.none()) + + /** + * Returns a raw HTTP response for `get /notifications/{id}`, but is otherwise the same as + * [NotificationService.retrieve]. + */ + @MustBeClosed + fun retrieve(id: String): HttpResponseFor = + retrieve(id, NotificationRetrieveParams.none()) + + /** @see retrieve */ + @MustBeClosed + fun retrieve( + id: String, + params: NotificationRetrieveParams = NotificationRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + retrieve(params.toBuilder().id(id).build(), requestOptions) + + /** @see retrieve */ + @MustBeClosed + fun retrieve( + id: String, + params: NotificationRetrieveParams = NotificationRetrieveParams.none(), + ): HttpResponseFor = + retrieve(id, params, RequestOptions.none()) + + /** @see retrieve */ + @MustBeClosed + fun retrieve( + params: NotificationRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see retrieve */ + @MustBeClosed + fun retrieve( + params: NotificationRetrieveParams + ): HttpResponseFor = + retrieve(params, RequestOptions.none()) + + /** @see retrieve */ + @MustBeClosed + fun retrieve( + id: String, + requestOptions: RequestOptions, + ): HttpResponseFor = + retrieve(id, NotificationRetrieveParams.none(), requestOptions) + /** * Returns a raw HTTP response for `get /notifications`, but is otherwise the same as * [NotificationService.list]. @@ -122,6 +359,118 @@ interface NotificationService { fun list(requestOptions: RequestOptions): HttpResponseFor = list(NotificationListParams.none(), requestOptions) + /** + * Returns a raw HTTP response for `delete /notifications/{id}`, but is otherwise the same + * as [NotificationService.archive]. + */ + @MustBeClosed + fun archive(id: String): HttpResponse = archive(id, NotificationArchiveParams.none()) + + /** @see archive */ + @MustBeClosed + fun archive( + id: String, + params: NotificationArchiveParams = NotificationArchiveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponse = archive(params.toBuilder().id(id).build(), requestOptions) + + /** @see archive */ + @MustBeClosed + fun archive( + id: String, + params: NotificationArchiveParams = NotificationArchiveParams.none(), + ): HttpResponse = archive(id, params, RequestOptions.none()) + + /** @see archive */ + @MustBeClosed + fun archive( + params: NotificationArchiveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponse + + /** @see archive */ + @MustBeClosed + fun archive(params: NotificationArchiveParams): HttpResponse = + archive(params, RequestOptions.none()) + + /** @see archive */ + @MustBeClosed + fun archive(id: String, requestOptions: RequestOptions): HttpResponse = + archive(id, NotificationArchiveParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `post /notifications/{id}/publish`, but is otherwise the + * same as [NotificationService.publish]. + */ + @MustBeClosed + fun publish(id: String): HttpResponse = publish(id, NotificationPublishParams.none()) + + /** @see publish */ + @MustBeClosed + fun publish( + id: String, + params: NotificationPublishParams = NotificationPublishParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponse = publish(params.toBuilder().id(id).build(), requestOptions) + + /** @see publish */ + @MustBeClosed + fun publish( + id: String, + params: NotificationPublishParams = NotificationPublishParams.none(), + ): HttpResponse = publish(id, params, RequestOptions.none()) + + /** @see publish */ + @MustBeClosed + fun publish( + params: NotificationPublishParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponse + + /** @see publish */ + @MustBeClosed + fun publish(params: NotificationPublishParams): HttpResponse = + publish(params, RequestOptions.none()) + + /** @see publish */ + @MustBeClosed + fun publish(id: String, requestOptions: RequestOptions): HttpResponse = + publish(id, NotificationPublishParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `put /notifications/{id}`, but is otherwise the same as + * [NotificationService.replace]. + */ + @MustBeClosed + fun replace( + id: String, + params: NotificationReplaceParams, + ): HttpResponseFor = + replace(id, params, RequestOptions.none()) + + /** @see replace */ + @MustBeClosed + fun replace( + id: String, + params: NotificationReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + replace(params.toBuilder().id(id).build(), requestOptions) + + /** @see replace */ + @MustBeClosed + fun replace( + params: NotificationReplaceParams + ): HttpResponseFor = + replace(params, RequestOptions.none()) + + /** @see replace */ + @MustBeClosed + fun replace( + params: NotificationReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + /** * Returns a raw HTTP response for `get /notifications/{id}/content`, but is otherwise the * same as [NotificationService.retrieveContent]. diff --git a/courier-java-core/src/main/kotlin/com/courier/services/blocking/NotificationServiceImpl.kt b/courier-java-core/src/main/kotlin/com/courier/services/blocking/NotificationServiceImpl.kt index dc6f4de3..5df1e644 100644 --- a/courier-java-core/src/main/kotlin/com/courier/services/blocking/NotificationServiceImpl.kt +++ b/courier-java-core/src/main/kotlin/com/courier/services/blocking/NotificationServiceImpl.kt @@ -5,6 +5,7 @@ package com.courier.services.blocking import com.courier.core.ClientOptions import com.courier.core.RequestOptions import com.courier.core.checkRequired +import com.courier.core.handlers.emptyHandler import com.courier.core.handlers.errorBodyHandler import com.courier.core.handlers.errorHandler import com.courier.core.handlers.jsonHandler @@ -13,12 +14,20 @@ import com.courier.core.http.HttpRequest import com.courier.core.http.HttpResponse import com.courier.core.http.HttpResponse.Handler import com.courier.core.http.HttpResponseFor +import com.courier.core.http.json import com.courier.core.http.parseable import com.courier.core.prepare +import com.courier.models.notifications.NotificationArchiveParams +import com.courier.models.notifications.NotificationCreateParams import com.courier.models.notifications.NotificationGetContent import com.courier.models.notifications.NotificationListParams import com.courier.models.notifications.NotificationListResponse +import com.courier.models.notifications.NotificationPublishParams +import com.courier.models.notifications.NotificationReplaceParams import com.courier.models.notifications.NotificationRetrieveContentParams +import com.courier.models.notifications.NotificationRetrieveParams +import com.courier.models.notifications.NotificationTemplateGetResponse +import com.courier.models.notifications.NotificationTemplateMutationResponse import com.courier.services.blocking.notifications.CheckService import com.courier.services.blocking.notifications.CheckServiceImpl import com.courier.services.blocking.notifications.DraftService @@ -46,6 +55,20 @@ class NotificationServiceImpl internal constructor(private val clientOptions: Cl override fun checks(): CheckService = checks + override fun create( + params: NotificationCreateParams, + requestOptions: RequestOptions, + ): NotificationTemplateMutationResponse = + // post /notifications + withRawResponse().create(params, requestOptions).parse() + + override fun retrieve( + params: NotificationRetrieveParams, + requestOptions: RequestOptions, + ): NotificationTemplateGetResponse = + // get /notifications/{id} + withRawResponse().retrieve(params, requestOptions).parse() + override fun list( params: NotificationListParams, requestOptions: RequestOptions, @@ -53,6 +76,23 @@ class NotificationServiceImpl internal constructor(private val clientOptions: Cl // get /notifications withRawResponse().list(params, requestOptions).parse() + override fun archive(params: NotificationArchiveParams, requestOptions: RequestOptions) { + // delete /notifications/{id} + withRawResponse().archive(params, requestOptions) + } + + override fun publish(params: NotificationPublishParams, requestOptions: RequestOptions) { + // post /notifications/{id}/publish + withRawResponse().publish(params, requestOptions) + } + + override fun replace( + params: NotificationReplaceParams, + requestOptions: RequestOptions, + ): NotificationTemplateMutationResponse = + // put /notifications/{id} + withRawResponse().replace(params, requestOptions).parse() + override fun retrieveContent( params: NotificationRetrieveContentParams, requestOptions: RequestOptions, @@ -85,6 +125,64 @@ class NotificationServiceImpl internal constructor(private val clientOptions: Cl override fun checks(): CheckService.WithRawResponse = checks + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun create( + params: NotificationCreateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("notifications") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return errorHandler.handle(response).parseable { + response + .use { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun retrieve( + params: NotificationRetrieveParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("id", params.id().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("notifications", params._pathParam(0)) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return errorHandler.handle(response).parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + private val listHandler: Handler = jsonHandler(clientOptions.jsonMapper) @@ -112,6 +210,85 @@ class NotificationServiceImpl internal constructor(private val clientOptions: Cl } } + private val archiveHandler: Handler = emptyHandler() + + override fun archive( + params: NotificationArchiveParams, + requestOptions: RequestOptions, + ): HttpResponse { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("id", params.id().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("notifications", params._pathParam(0)) + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return errorHandler.handle(response).parseable { + response.use { archiveHandler.handle(it) } + } + } + + private val publishHandler: Handler = emptyHandler() + + override fun publish( + params: NotificationPublishParams, + requestOptions: RequestOptions, + ): HttpResponse { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("id", params.id().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("notifications", params._pathParam(0), "publish") + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return errorHandler.handle(response).parseable { + response.use { publishHandler.handle(it) } + } + } + + private val replaceHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun replace( + params: NotificationReplaceParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("id", params.id().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.PUT) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("notifications", params._pathParam(0)) + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return errorHandler.handle(response).parseable { + response + .use { replaceHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + private val retrieveContentHandler: Handler = jsonHandler(clientOptions.jsonMapper) diff --git a/courier-java-core/src/test/kotlin/com/courier/core/ClientOptionsTest.kt b/courier-java-core/src/test/kotlin/com/courier/core/ClientOptionsTest.kt index bb4ebcb2..fd9aa5ca 100644 --- a/courier-java-core/src/test/kotlin/com/courier/core/ClientOptionsTest.kt +++ b/courier-java-core/src/test/kotlin/com/courier/core/ClientOptionsTest.kt @@ -16,6 +16,29 @@ internal class ClientOptionsTest { private val httpClient = mock() + @Test + fun putHeader_canOverwriteDefaultHeader() { + val clientOptions = + ClientOptions.builder() + .httpClient(httpClient) + .putHeader("User-Agent", "My User Agent") + .apiKey("My API Key") + .build() + + assertThat(clientOptions.headers.values("User-Agent")).containsExactly("My User Agent") + } + + @Test + fun toBuilder_bearerAuthCanBeUpdated() { + var clientOptions = + ClientOptions.builder().httpClient(httpClient).apiKey("My API Key").build() + + clientOptions = clientOptions.toBuilder().apiKey("another My API Key").build() + + assertThat(clientOptions.headers.values("Authorization")) + .containsExactly("Bearer another My API Key") + } + @Test fun toBuilder_whenOriginalClientOptionsGarbageCollected_doesNotCloseOriginalClient() { var clientOptions = diff --git a/courier-java-core/src/test/kotlin/com/courier/core/http/RetryingHttpClientTest.kt b/courier-java-core/src/test/kotlin/com/courier/core/http/RetryingHttpClientTest.kt index e5636ac7..c4654980 100644 --- a/courier-java-core/src/test/kotlin/com/courier/core/http/RetryingHttpClientTest.kt +++ b/courier-java-core/src/test/kotlin/com/courier/core/http/RetryingHttpClientTest.kt @@ -400,9 +400,9 @@ internal class RetryingHttpClientTest { assertThat(sleeper.durations).hasSize(3) // retries=1: 0.5s * [0.75, 1.0] assertThat(sleeper.durations[0]).isBetween(Duration.ofMillis(375), Duration.ofMillis(500)) - // retries=2: 1.0s * [0.75, 1.0] + // retries=2: 1s * [0.75, 1.0] assertThat(sleeper.durations[1]).isBetween(Duration.ofMillis(750), Duration.ofMillis(1000)) - // retries=3: 2.0s * [0.75, 1.0] + // retries=3: 2s * [0.75, 1.0] assertThat(sleeper.durations[2]).isBetween(Duration.ofMillis(1500), Duration.ofMillis(2000)) assertNoResponseLeaks() } @@ -427,9 +427,9 @@ internal class RetryingHttpClientTest { assertThat(response.statusCode()).isEqualTo(503) verify(7, postRequestedFor(urlPathEqualTo("/something"))) assertThat(sleeper.durations).hasSize(6) - // retries=5: min(0.5 * 2^4, 8) = 8.0s * [0.75, 1.0] + // retries=5: backoff hits the 8s cap * [0.75, 1.0] assertThat(sleeper.durations[4]).isBetween(Duration.ofMillis(6000), Duration.ofMillis(8000)) - // retries=6: min(0.5 * 2^5, 8) = min(16, 8) = 8.0s * [0.75, 1.0] (capped) + // retries=6: still capped at 8s * [0.75, 1.0] assertThat(sleeper.durations[5]).isBetween(Duration.ofMillis(6000), Duration.ofMillis(8000)) assertNoResponseLeaks() } diff --git a/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationArchiveParamsTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationArchiveParamsTest.kt new file mode 100644 index 00000000..57900731 --- /dev/null +++ b/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationArchiveParamsTest.kt @@ -0,0 +1,23 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.notifications + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class NotificationArchiveParamsTest { + + @Test + fun create() { + NotificationArchiveParams.builder().id("id").build() + } + + @Test + fun pathParams() { + val params = NotificationArchiveParams.builder().id("id").build() + + assertThat(params._pathParam(0)).isEqualTo("id") + // out-of-bound path param + assertThat(params._pathParam(1)).isEqualTo("") + } +} diff --git a/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationCreateParamsTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationCreateParamsTest.kt new file mode 100644 index 00000000..eb8b89cd --- /dev/null +++ b/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationCreateParamsTest.kt @@ -0,0 +1,209 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.notifications + +import com.courier.models.ElementalChannelNodeWithType +import com.courier.models.ElementalContent +import com.courier.models.ElementalTextNodeWithType +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class NotificationCreateParamsTest { + + @Test + fun create() { + NotificationCreateParams.builder() + .notificationTemplateCreateRequest( + NotificationTemplateCreateRequest.builder() + .notification( + NotificationTemplatePayload.builder() + .brand( + NotificationTemplatePayload.Brand.builder().id("brand_abc").build() + ) + .content( + ElementalContent.builder() + .addElement( + ElementalChannelNodeWithType.builder() + .type(ElementalChannelNodeWithType.Type.CHANNEL) + .build() + ) + .version("2022-01-01") + .build() + ) + .name("Welcome Email") + .routing( + NotificationTemplatePayload.Routing.builder() + .strategyId("rs_123") + .build() + ) + .subscription( + NotificationTemplatePayload.Subscription.builder() + .topicId("marketing") + .build() + ) + .addTag("onboarding") + .addTag("welcome") + .build() + ) + .state(NotificationTemplateCreateRequest.State.DRAFT) + .build() + ) + .build() + } + + @Test + fun body() { + val params = + NotificationCreateParams.builder() + .notificationTemplateCreateRequest( + NotificationTemplateCreateRequest.builder() + .notification( + NotificationTemplatePayload.builder() + .brand( + NotificationTemplatePayload.Brand.builder() + .id("brand_abc") + .build() + ) + .content( + ElementalContent.builder() + .addElement( + ElementalChannelNodeWithType.builder() + .type(ElementalChannelNodeWithType.Type.CHANNEL) + .build() + ) + .version("2022-01-01") + .build() + ) + .name("Welcome Email") + .routing( + NotificationTemplatePayload.Routing.builder() + .strategyId("rs_123") + .build() + ) + .subscription( + NotificationTemplatePayload.Subscription.builder() + .topicId("marketing") + .build() + ) + .addTag("onboarding") + .addTag("welcome") + .build() + ) + .state(NotificationTemplateCreateRequest.State.DRAFT) + .build() + ) + .build() + + val body = params._body() + + assertThat(body) + .isEqualTo( + NotificationTemplateCreateRequest.builder() + .notification( + NotificationTemplatePayload.builder() + .brand( + NotificationTemplatePayload.Brand.builder().id("brand_abc").build() + ) + .content( + ElementalContent.builder() + .addElement( + ElementalChannelNodeWithType.builder() + .type(ElementalChannelNodeWithType.Type.CHANNEL) + .build() + ) + .version("2022-01-01") + .build() + ) + .name("Welcome Email") + .routing( + NotificationTemplatePayload.Routing.builder() + .strategyId("rs_123") + .build() + ) + .subscription( + NotificationTemplatePayload.Subscription.builder() + .topicId("marketing") + .build() + ) + .addTag("onboarding") + .addTag("welcome") + .build() + ) + .state(NotificationTemplateCreateRequest.State.DRAFT) + .build() + ) + } + + @Test + fun bodyWithoutOptionalFields() { + val params = + NotificationCreateParams.builder() + .notificationTemplateCreateRequest( + NotificationTemplateCreateRequest.builder() + .notification( + NotificationTemplatePayload.builder() + .brand( + NotificationTemplatePayload.Brand.builder() + .id("brand_abc") + .build() + ) + .content( + ElementalContent.builder() + .addElement(ElementalTextNodeWithType.builder().build()) + .version("2022-01-01") + .build() + ) + .name("Welcome Email") + .routing( + NotificationTemplatePayload.Routing.builder() + .strategyId("rs_123") + .build() + ) + .subscription( + NotificationTemplatePayload.Subscription.builder() + .topicId("marketing") + .build() + ) + .addTag("onboarding") + .addTag("welcome") + .build() + ) + .build() + ) + .build() + + val body = params._body() + + assertThat(body) + .isEqualTo( + NotificationTemplateCreateRequest.builder() + .notification( + NotificationTemplatePayload.builder() + .brand( + NotificationTemplatePayload.Brand.builder().id("brand_abc").build() + ) + .content( + ElementalContent.builder() + .addElement(ElementalTextNodeWithType.builder().build()) + .version("2022-01-01") + .build() + ) + .name("Welcome Email") + .routing( + NotificationTemplatePayload.Routing.builder() + .strategyId("rs_123") + .build() + ) + .subscription( + NotificationTemplatePayload.Subscription.builder() + .topicId("marketing") + .build() + ) + .addTag("onboarding") + .addTag("welcome") + .build() + ) + .build() + ) + } +} diff --git a/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationListParamsTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationListParamsTest.kt index ad2797a3..02de59ee 100644 --- a/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationListParamsTest.kt +++ b/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationListParamsTest.kt @@ -10,17 +10,28 @@ internal class NotificationListParamsTest { @Test fun create() { - NotificationListParams.builder().cursor("cursor").notes(true).build() + NotificationListParams.builder().cursor("cursor").eventId("event_id").notes(true).build() } @Test fun queryParams() { - val params = NotificationListParams.builder().cursor("cursor").notes(true).build() + val params = + NotificationListParams.builder() + .cursor("cursor") + .eventId("event_id") + .notes(true) + .build() val queryParams = params._queryParams() assertThat(queryParams) - .isEqualTo(QueryParams.builder().put("cursor", "cursor").put("notes", "true").build()) + .isEqualTo( + QueryParams.builder() + .put("cursor", "cursor") + .put("event_id", "event_id") + .put("notes", "true") + .build() + ) } @Test diff --git a/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationListResponseTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationListResponseTest.kt index c223f94d..fcd413e5 100644 --- a/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationListResponseTest.kt +++ b/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationListResponseTest.kt @@ -17,7 +17,7 @@ internal class NotificationListResponseTest { NotificationListResponse.builder() .paging(Paging.builder().more(true).cursor("cursor").build()) .addResult( - NotificationListResponse.Result.builder() + NotificationListResponse.Result.Notification.builder() .id("id") .createdAt(0L) .addEventId("string") @@ -31,9 +31,9 @@ internal class NotificationListResponseTest { .topicId("topic_id") .updatedAt(0L) .tags( - NotificationListResponse.Result.Tags.builder() + NotificationListResponse.Result.Notification.Tags.builder() .addData( - NotificationListResponse.Result.Tags.Data.builder() + NotificationListResponse.Result.Notification.Tags.Data.builder() .id("id") .name("name") .build() @@ -49,31 +49,33 @@ internal class NotificationListResponseTest { .isEqualTo(Paging.builder().more(true).cursor("cursor").build()) assertThat(notificationListResponse.results()) .containsExactly( - NotificationListResponse.Result.builder() - .id("id") - .createdAt(0L) - .addEventId("string") - .note("note") - .routing( - MessageRouting.builder() - .addChannel("string") - .method(MessageRouting.Method.ALL) - .build() - ) - .topicId("topic_id") - .updatedAt(0L) - .tags( - NotificationListResponse.Result.Tags.builder() - .addData( - NotificationListResponse.Result.Tags.Data.builder() - .id("id") - .name("name") - .build() - ) - .build() - ) - .title("title") - .build() + NotificationListResponse.Result.ofNotification( + NotificationListResponse.Result.Notification.builder() + .id("id") + .createdAt(0L) + .addEventId("string") + .note("note") + .routing( + MessageRouting.builder() + .addChannel("string") + .method(MessageRouting.Method.ALL) + .build() + ) + .topicId("topic_id") + .updatedAt(0L) + .tags( + NotificationListResponse.Result.Notification.Tags.builder() + .addData( + NotificationListResponse.Result.Notification.Tags.Data.builder() + .id("id") + .name("name") + .build() + ) + .build() + ) + .title("title") + .build() + ) ) } @@ -84,7 +86,7 @@ internal class NotificationListResponseTest { NotificationListResponse.builder() .paging(Paging.builder().more(true).cursor("cursor").build()) .addResult( - NotificationListResponse.Result.builder() + NotificationListResponse.Result.Notification.builder() .id("id") .createdAt(0L) .addEventId("string") @@ -98,9 +100,9 @@ internal class NotificationListResponseTest { .topicId("topic_id") .updatedAt(0L) .tags( - NotificationListResponse.Result.Tags.builder() + NotificationListResponse.Result.Notification.Tags.builder() .addData( - NotificationListResponse.Result.Tags.Data.builder() + NotificationListResponse.Result.Notification.Tags.Data.builder() .id("id") .name("name") .build() diff --git a/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationPublishParamsTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationPublishParamsTest.kt new file mode 100644 index 00000000..bb5d939f --- /dev/null +++ b/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationPublishParamsTest.kt @@ -0,0 +1,23 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.notifications + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class NotificationPublishParamsTest { + + @Test + fun create() { + NotificationPublishParams.builder().id("id").build() + } + + @Test + fun pathParams() { + val params = NotificationPublishParams.builder().id("id").build() + + assertThat(params._pathParam(0)).isEqualTo("id") + // out-of-bound path param + assertThat(params._pathParam(1)).isEqualTo("") + } +} diff --git a/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationReplaceParamsTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationReplaceParamsTest.kt new file mode 100644 index 00000000..39e34a6f --- /dev/null +++ b/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationReplaceParamsTest.kt @@ -0,0 +1,232 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.notifications + +import com.courier.models.ElementalChannelNodeWithType +import com.courier.models.ElementalContent +import com.courier.models.ElementalTextNodeWithType +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class NotificationReplaceParamsTest { + + @Test + fun create() { + NotificationReplaceParams.builder() + .id("id") + .notificationTemplateUpdateRequest( + NotificationTemplateUpdateRequest.builder() + .notification( + NotificationTemplatePayload.builder() + .brand(NotificationTemplatePayload.Brand.builder().id("id").build()) + .content( + ElementalContent.builder() + .addElement( + ElementalChannelNodeWithType.builder() + .type(ElementalChannelNodeWithType.Type.CHANNEL) + .build() + ) + .version("2022-01-01") + .build() + ) + .name("Updated Name") + .routing( + NotificationTemplatePayload.Routing.builder() + .strategyId("strategy_id") + .build() + ) + .subscription( + NotificationTemplatePayload.Subscription.builder() + .topicId("topic_id") + .build() + ) + .addTag("updated") + .build() + ) + .state(NotificationTemplateUpdateRequest.State.PUBLISHED) + .build() + ) + .build() + } + + @Test + fun pathParams() { + val params = + NotificationReplaceParams.builder() + .id("id") + .notificationTemplateUpdateRequest( + NotificationTemplateUpdateRequest.builder() + .notification( + NotificationTemplatePayload.builder() + .brand(NotificationTemplatePayload.Brand.builder().id("id").build()) + .content( + ElementalContent.builder() + .addElement(ElementalTextNodeWithType.builder().build()) + .version("2022-01-01") + .build() + ) + .name("Updated Name") + .routing( + NotificationTemplatePayload.Routing.builder() + .strategyId("strategy_id") + .build() + ) + .subscription( + NotificationTemplatePayload.Subscription.builder() + .topicId("topic_id") + .build() + ) + .addTag("updated") + .build() + ) + .build() + ) + .build() + + assertThat(params._pathParam(0)).isEqualTo("id") + // out-of-bound path param + assertThat(params._pathParam(1)).isEqualTo("") + } + + @Test + fun body() { + val params = + NotificationReplaceParams.builder() + .id("id") + .notificationTemplateUpdateRequest( + NotificationTemplateUpdateRequest.builder() + .notification( + NotificationTemplatePayload.builder() + .brand(NotificationTemplatePayload.Brand.builder().id("id").build()) + .content( + ElementalContent.builder() + .addElement( + ElementalChannelNodeWithType.builder() + .type(ElementalChannelNodeWithType.Type.CHANNEL) + .build() + ) + .version("2022-01-01") + .build() + ) + .name("Updated Name") + .routing( + NotificationTemplatePayload.Routing.builder() + .strategyId("strategy_id") + .build() + ) + .subscription( + NotificationTemplatePayload.Subscription.builder() + .topicId("topic_id") + .build() + ) + .addTag("updated") + .build() + ) + .state(NotificationTemplateUpdateRequest.State.PUBLISHED) + .build() + ) + .build() + + val body = params._body() + + assertThat(body) + .isEqualTo( + NotificationTemplateUpdateRequest.builder() + .notification( + NotificationTemplatePayload.builder() + .brand(NotificationTemplatePayload.Brand.builder().id("id").build()) + .content( + ElementalContent.builder() + .addElement( + ElementalChannelNodeWithType.builder() + .type(ElementalChannelNodeWithType.Type.CHANNEL) + .build() + ) + .version("2022-01-01") + .build() + ) + .name("Updated Name") + .routing( + NotificationTemplatePayload.Routing.builder() + .strategyId("strategy_id") + .build() + ) + .subscription( + NotificationTemplatePayload.Subscription.builder() + .topicId("topic_id") + .build() + ) + .addTag("updated") + .build() + ) + .state(NotificationTemplateUpdateRequest.State.PUBLISHED) + .build() + ) + } + + @Test + fun bodyWithoutOptionalFields() { + val params = + NotificationReplaceParams.builder() + .id("id") + .notificationTemplateUpdateRequest( + NotificationTemplateUpdateRequest.builder() + .notification( + NotificationTemplatePayload.builder() + .brand(NotificationTemplatePayload.Brand.builder().id("id").build()) + .content( + ElementalContent.builder() + .addElement(ElementalTextNodeWithType.builder().build()) + .version("2022-01-01") + .build() + ) + .name("Updated Name") + .routing( + NotificationTemplatePayload.Routing.builder() + .strategyId("strategy_id") + .build() + ) + .subscription( + NotificationTemplatePayload.Subscription.builder() + .topicId("topic_id") + .build() + ) + .addTag("updated") + .build() + ) + .build() + ) + .build() + + val body = params._body() + + assertThat(body) + .isEqualTo( + NotificationTemplateUpdateRequest.builder() + .notification( + NotificationTemplatePayload.builder() + .brand(NotificationTemplatePayload.Brand.builder().id("id").build()) + .content( + ElementalContent.builder() + .addElement(ElementalTextNodeWithType.builder().build()) + .version("2022-01-01") + .build() + ) + .name("Updated Name") + .routing( + NotificationTemplatePayload.Routing.builder() + .strategyId("strategy_id") + .build() + ) + .subscription( + NotificationTemplatePayload.Subscription.builder() + .topicId("topic_id") + .build() + ) + .addTag("updated") + .build() + ) + .build() + ) + } +} diff --git a/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationRetrieveParamsTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationRetrieveParamsTest.kt new file mode 100644 index 00000000..2a71aefd --- /dev/null +++ b/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationRetrieveParamsTest.kt @@ -0,0 +1,42 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.notifications + +import com.courier.core.http.QueryParams +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class NotificationRetrieveParamsTest { + + @Test + fun create() { + NotificationRetrieveParams.builder().id("id").version("version").build() + } + + @Test + fun pathParams() { + val params = NotificationRetrieveParams.builder().id("id").build() + + assertThat(params._pathParam(0)).isEqualTo("id") + // out-of-bound path param + assertThat(params._pathParam(1)).isEqualTo("") + } + + @Test + fun queryParams() { + val params = NotificationRetrieveParams.builder().id("id").version("version").build() + + val queryParams = params._queryParams() + + assertThat(queryParams).isEqualTo(QueryParams.builder().put("version", "version").build()) + } + + @Test + fun queryParamsWithoutOptionalFields() { + val params = NotificationRetrieveParams.builder().id("id").build() + + val queryParams = params._queryParams() + + assertThat(queryParams).isEqualTo(QueryParams.builder().build()) + } +} diff --git a/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationTemplateCreateRequestTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationTemplateCreateRequestTest.kt new file mode 100644 index 00000000..974768fa --- /dev/null +++ b/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationTemplateCreateRequestTest.kt @@ -0,0 +1,136 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.notifications + +import com.courier.core.jsonMapper +import com.courier.models.ElementalContent +import com.courier.models.ElementalTextNodeWithType +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class NotificationTemplateCreateRequestTest { + + @Test + fun create() { + val notificationTemplateCreateRequest = + NotificationTemplateCreateRequest.builder() + .notification( + NotificationTemplatePayload.builder() + .brand(NotificationTemplatePayload.Brand.builder().id("id").build()) + .content( + ElementalContent.builder() + .addElement( + ElementalTextNodeWithType.builder() + .addChannel("string") + .if_("if") + .loop("loop") + .ref("ref") + .type(ElementalTextNodeWithType.Type.TEXT) + .build() + ) + .version("version") + .build() + ) + .name("name") + .routing( + NotificationTemplatePayload.Routing.builder() + .strategyId("strategy_id") + .build() + ) + .subscription( + NotificationTemplatePayload.Subscription.builder() + .topicId("topic_id") + .build() + ) + .addTag("string") + .build() + ) + .state(NotificationTemplateCreateRequest.State.DRAFT) + .build() + + assertThat(notificationTemplateCreateRequest.notification()) + .isEqualTo( + NotificationTemplatePayload.builder() + .brand(NotificationTemplatePayload.Brand.builder().id("id").build()) + .content( + ElementalContent.builder() + .addElement( + ElementalTextNodeWithType.builder() + .addChannel("string") + .if_("if") + .loop("loop") + .ref("ref") + .type(ElementalTextNodeWithType.Type.TEXT) + .build() + ) + .version("version") + .build() + ) + .name("name") + .routing( + NotificationTemplatePayload.Routing.builder() + .strategyId("strategy_id") + .build() + ) + .subscription( + NotificationTemplatePayload.Subscription.builder() + .topicId("topic_id") + .build() + ) + .addTag("string") + .build() + ) + assertThat(notificationTemplateCreateRequest.state()) + .contains(NotificationTemplateCreateRequest.State.DRAFT) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val notificationTemplateCreateRequest = + NotificationTemplateCreateRequest.builder() + .notification( + NotificationTemplatePayload.builder() + .brand(NotificationTemplatePayload.Brand.builder().id("id").build()) + .content( + ElementalContent.builder() + .addElement( + ElementalTextNodeWithType.builder() + .addChannel("string") + .if_("if") + .loop("loop") + .ref("ref") + .type(ElementalTextNodeWithType.Type.TEXT) + .build() + ) + .version("version") + .build() + ) + .name("name") + .routing( + NotificationTemplatePayload.Routing.builder() + .strategyId("strategy_id") + .build() + ) + .subscription( + NotificationTemplatePayload.Subscription.builder() + .topicId("topic_id") + .build() + ) + .addTag("string") + .build() + ) + .state(NotificationTemplateCreateRequest.State.DRAFT) + .build() + + val roundtrippedNotificationTemplateCreateRequest = + jsonMapper.readValue( + jsonMapper.writeValueAsString(notificationTemplateCreateRequest), + jacksonTypeRef(), + ) + + assertThat(roundtrippedNotificationTemplateCreateRequest) + .isEqualTo(notificationTemplateCreateRequest) + } +} diff --git a/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationTemplateGetResponseTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationTemplateGetResponseTest.kt new file mode 100644 index 00000000..720ed454 --- /dev/null +++ b/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationTemplateGetResponseTest.kt @@ -0,0 +1,151 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.notifications + +import com.courier.core.jsonMapper +import com.courier.models.ElementalContent +import com.courier.models.ElementalTextNodeWithType +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class NotificationTemplateGetResponseTest { + + @Test + fun create() { + val notificationTemplateGetResponse = + NotificationTemplateGetResponse.builder() + .created(0L) + .creator("creator") + .notification( + NotificationTemplateGetResponse.Notification.builder() + .brand(NotificationTemplatePayload.Brand.builder().id("id").build()) + .content( + ElementalContent.builder() + .addElement( + ElementalTextNodeWithType.builder() + .addChannel("string") + .if_("if") + .loop("loop") + .ref("ref") + .type(ElementalTextNodeWithType.Type.TEXT) + .build() + ) + .version("version") + .build() + ) + .name("name") + .routing( + NotificationTemplatePayload.Routing.builder() + .strategyId("strategy_id") + .build() + ) + .subscription( + NotificationTemplatePayload.Subscription.builder() + .topicId("topic_id") + .build() + ) + .addTag("string") + .id("id") + .build() + ) + .state(NotificationTemplateGetResponse.State.DRAFT) + .updated(0L) + .updater("updater") + .build() + + assertThat(notificationTemplateGetResponse.created()).isEqualTo(0L) + assertThat(notificationTemplateGetResponse.creator()).isEqualTo("creator") + assertThat(notificationTemplateGetResponse.notification()) + .isEqualTo( + NotificationTemplateGetResponse.Notification.builder() + .brand(NotificationTemplatePayload.Brand.builder().id("id").build()) + .content( + ElementalContent.builder() + .addElement( + ElementalTextNodeWithType.builder() + .addChannel("string") + .if_("if") + .loop("loop") + .ref("ref") + .type(ElementalTextNodeWithType.Type.TEXT) + .build() + ) + .version("version") + .build() + ) + .name("name") + .routing( + NotificationTemplatePayload.Routing.builder() + .strategyId("strategy_id") + .build() + ) + .subscription( + NotificationTemplatePayload.Subscription.builder() + .topicId("topic_id") + .build() + ) + .addTag("string") + .id("id") + .build() + ) + assertThat(notificationTemplateGetResponse.state()) + .isEqualTo(NotificationTemplateGetResponse.State.DRAFT) + assertThat(notificationTemplateGetResponse.updated()).contains(0L) + assertThat(notificationTemplateGetResponse.updater()).contains("updater") + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val notificationTemplateGetResponse = + NotificationTemplateGetResponse.builder() + .created(0L) + .creator("creator") + .notification( + NotificationTemplateGetResponse.Notification.builder() + .brand(NotificationTemplatePayload.Brand.builder().id("id").build()) + .content( + ElementalContent.builder() + .addElement( + ElementalTextNodeWithType.builder() + .addChannel("string") + .if_("if") + .loop("loop") + .ref("ref") + .type(ElementalTextNodeWithType.Type.TEXT) + .build() + ) + .version("version") + .build() + ) + .name("name") + .routing( + NotificationTemplatePayload.Routing.builder() + .strategyId("strategy_id") + .build() + ) + .subscription( + NotificationTemplatePayload.Subscription.builder() + .topicId("topic_id") + .build() + ) + .addTag("string") + .id("id") + .build() + ) + .state(NotificationTemplateGetResponse.State.DRAFT) + .updated(0L) + .updater("updater") + .build() + + val roundtrippedNotificationTemplateGetResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(notificationTemplateGetResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedNotificationTemplateGetResponse) + .isEqualTo(notificationTemplateGetResponse) + } +} diff --git a/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationTemplateMutationResponseTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationTemplateMutationResponseTest.kt new file mode 100644 index 00000000..69470bce --- /dev/null +++ b/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationTemplateMutationResponseTest.kt @@ -0,0 +1,48 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.notifications + +import com.courier.core.jsonMapper +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class NotificationTemplateMutationResponseTest { + + @Test + fun create() { + val notificationTemplateMutationResponse = + NotificationTemplateMutationResponse.builder() + .notification( + NotificationTemplateMutationResponse.Notification.builder().id("id").build() + ) + .state(NotificationTemplateMutationResponse.State.DRAFT) + .build() + + assertThat(notificationTemplateMutationResponse.notification()) + .isEqualTo(NotificationTemplateMutationResponse.Notification.builder().id("id").build()) + assertThat(notificationTemplateMutationResponse.state()) + .isEqualTo(NotificationTemplateMutationResponse.State.DRAFT) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val notificationTemplateMutationResponse = + NotificationTemplateMutationResponse.builder() + .notification( + NotificationTemplateMutationResponse.Notification.builder().id("id").build() + ) + .state(NotificationTemplateMutationResponse.State.DRAFT) + .build() + + val roundtrippedNotificationTemplateMutationResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(notificationTemplateMutationResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedNotificationTemplateMutationResponse) + .isEqualTo(notificationTemplateMutationResponse) + } +} diff --git a/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationTemplatePayloadTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationTemplatePayloadTest.kt new file mode 100644 index 00000000..12b423d1 --- /dev/null +++ b/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationTemplatePayloadTest.kt @@ -0,0 +1,110 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.notifications + +import com.courier.core.jsonMapper +import com.courier.models.ElementalContent +import com.courier.models.ElementalTextNodeWithType +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class NotificationTemplatePayloadTest { + + @Test + fun create() { + val notificationTemplatePayload = + NotificationTemplatePayload.builder() + .brand(NotificationTemplatePayload.Brand.builder().id("id").build()) + .content( + ElementalContent.builder() + .addElement( + ElementalTextNodeWithType.builder() + .addChannel("string") + .if_("if") + .loop("loop") + .ref("ref") + .type(ElementalTextNodeWithType.Type.TEXT) + .build() + ) + .version("version") + .build() + ) + .name("name") + .routing( + NotificationTemplatePayload.Routing.builder().strategyId("strategy_id").build() + ) + .subscription( + NotificationTemplatePayload.Subscription.builder().topicId("topic_id").build() + ) + .addTag("string") + .build() + + assertThat(notificationTemplatePayload.brand()) + .contains(NotificationTemplatePayload.Brand.builder().id("id").build()) + assertThat(notificationTemplatePayload.content()) + .isEqualTo( + ElementalContent.builder() + .addElement( + ElementalTextNodeWithType.builder() + .addChannel("string") + .if_("if") + .loop("loop") + .ref("ref") + .type(ElementalTextNodeWithType.Type.TEXT) + .build() + ) + .version("version") + .build() + ) + assertThat(notificationTemplatePayload.name()).isEqualTo("name") + assertThat(notificationTemplatePayload.routing()) + .contains( + NotificationTemplatePayload.Routing.builder().strategyId("strategy_id").build() + ) + assertThat(notificationTemplatePayload.subscription()) + .contains( + NotificationTemplatePayload.Subscription.builder().topicId("topic_id").build() + ) + assertThat(notificationTemplatePayload.tags()).containsExactly("string") + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val notificationTemplatePayload = + NotificationTemplatePayload.builder() + .brand(NotificationTemplatePayload.Brand.builder().id("id").build()) + .content( + ElementalContent.builder() + .addElement( + ElementalTextNodeWithType.builder() + .addChannel("string") + .if_("if") + .loop("loop") + .ref("ref") + .type(ElementalTextNodeWithType.Type.TEXT) + .build() + ) + .version("version") + .build() + ) + .name("name") + .routing( + NotificationTemplatePayload.Routing.builder().strategyId("strategy_id").build() + ) + .subscription( + NotificationTemplatePayload.Subscription.builder().topicId("topic_id").build() + ) + .addTag("string") + .build() + + val roundtrippedNotificationTemplatePayload = + jsonMapper.readValue( + jsonMapper.writeValueAsString(notificationTemplatePayload), + jacksonTypeRef(), + ) + + assertThat(roundtrippedNotificationTemplatePayload).isEqualTo(notificationTemplatePayload) + } +} diff --git a/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationTemplateSummaryTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationTemplateSummaryTest.kt new file mode 100644 index 00000000..b03e82bf --- /dev/null +++ b/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationTemplateSummaryTest.kt @@ -0,0 +1,60 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.notifications + +import com.courier.core.jsonMapper +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class NotificationTemplateSummaryTest { + + @Test + fun create() { + val notificationTemplateSummary = + NotificationTemplateSummary.builder() + .id("id") + .created(0L) + .creator("creator") + .name("name") + .state(NotificationTemplateSummary.State.DRAFT) + .addTag("string") + .updated(0L) + .updater("updater") + .build() + + assertThat(notificationTemplateSummary.id()).isEqualTo("id") + assertThat(notificationTemplateSummary.created()).isEqualTo(0L) + assertThat(notificationTemplateSummary.creator()).isEqualTo("creator") + assertThat(notificationTemplateSummary.name()).isEqualTo("name") + assertThat(notificationTemplateSummary.state()) + .isEqualTo(NotificationTemplateSummary.State.DRAFT) + assertThat(notificationTemplateSummary.tags()).containsExactly("string") + assertThat(notificationTemplateSummary.updated()).contains(0L) + assertThat(notificationTemplateSummary.updater()).contains("updater") + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val notificationTemplateSummary = + NotificationTemplateSummary.builder() + .id("id") + .created(0L) + .creator("creator") + .name("name") + .state(NotificationTemplateSummary.State.DRAFT) + .addTag("string") + .updated(0L) + .updater("updater") + .build() + + val roundtrippedNotificationTemplateSummary = + jsonMapper.readValue( + jsonMapper.writeValueAsString(notificationTemplateSummary), + jacksonTypeRef(), + ) + + assertThat(roundtrippedNotificationTemplateSummary).isEqualTo(notificationTemplateSummary) + } +} diff --git a/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationTemplateUpdateRequestTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationTemplateUpdateRequestTest.kt new file mode 100644 index 00000000..b220db66 --- /dev/null +++ b/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationTemplateUpdateRequestTest.kt @@ -0,0 +1,136 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.notifications + +import com.courier.core.jsonMapper +import com.courier.models.ElementalContent +import com.courier.models.ElementalTextNodeWithType +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class NotificationTemplateUpdateRequestTest { + + @Test + fun create() { + val notificationTemplateUpdateRequest = + NotificationTemplateUpdateRequest.builder() + .notification( + NotificationTemplatePayload.builder() + .brand(NotificationTemplatePayload.Brand.builder().id("id").build()) + .content( + ElementalContent.builder() + .addElement( + ElementalTextNodeWithType.builder() + .addChannel("string") + .if_("if") + .loop("loop") + .ref("ref") + .type(ElementalTextNodeWithType.Type.TEXT) + .build() + ) + .version("version") + .build() + ) + .name("name") + .routing( + NotificationTemplatePayload.Routing.builder() + .strategyId("strategy_id") + .build() + ) + .subscription( + NotificationTemplatePayload.Subscription.builder() + .topicId("topic_id") + .build() + ) + .addTag("string") + .build() + ) + .state(NotificationTemplateUpdateRequest.State.DRAFT) + .build() + + assertThat(notificationTemplateUpdateRequest.notification()) + .isEqualTo( + NotificationTemplatePayload.builder() + .brand(NotificationTemplatePayload.Brand.builder().id("id").build()) + .content( + ElementalContent.builder() + .addElement( + ElementalTextNodeWithType.builder() + .addChannel("string") + .if_("if") + .loop("loop") + .ref("ref") + .type(ElementalTextNodeWithType.Type.TEXT) + .build() + ) + .version("version") + .build() + ) + .name("name") + .routing( + NotificationTemplatePayload.Routing.builder() + .strategyId("strategy_id") + .build() + ) + .subscription( + NotificationTemplatePayload.Subscription.builder() + .topicId("topic_id") + .build() + ) + .addTag("string") + .build() + ) + assertThat(notificationTemplateUpdateRequest.state()) + .contains(NotificationTemplateUpdateRequest.State.DRAFT) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val notificationTemplateUpdateRequest = + NotificationTemplateUpdateRequest.builder() + .notification( + NotificationTemplatePayload.builder() + .brand(NotificationTemplatePayload.Brand.builder().id("id").build()) + .content( + ElementalContent.builder() + .addElement( + ElementalTextNodeWithType.builder() + .addChannel("string") + .if_("if") + .loop("loop") + .ref("ref") + .type(ElementalTextNodeWithType.Type.TEXT) + .build() + ) + .version("version") + .build() + ) + .name("name") + .routing( + NotificationTemplatePayload.Routing.builder() + .strategyId("strategy_id") + .build() + ) + .subscription( + NotificationTemplatePayload.Subscription.builder() + .topicId("topic_id") + .build() + ) + .addTag("string") + .build() + ) + .state(NotificationTemplateUpdateRequest.State.DRAFT) + .build() + + val roundtrippedNotificationTemplateUpdateRequest = + jsonMapper.readValue( + jsonMapper.writeValueAsString(notificationTemplateUpdateRequest), + jacksonTypeRef(), + ) + + assertThat(roundtrippedNotificationTemplateUpdateRequest) + .isEqualTo(notificationTemplateUpdateRequest) + } +} diff --git a/courier-java-core/src/test/kotlin/com/courier/services/async/NotificationServiceAsyncTest.kt b/courier-java-core/src/test/kotlin/com/courier/services/async/NotificationServiceAsyncTest.kt index e26c7a58..1dfc3560 100644 --- a/courier-java-core/src/test/kotlin/com/courier/services/async/NotificationServiceAsyncTest.kt +++ b/courier-java-core/src/test/kotlin/com/courier/services/async/NotificationServiceAsyncTest.kt @@ -3,12 +3,81 @@ package com.courier.services.async import com.courier.client.okhttp.CourierOkHttpClientAsync +import com.courier.models.ElementalChannelNodeWithType +import com.courier.models.ElementalContent import com.courier.models.notifications.NotificationListParams +import com.courier.models.notifications.NotificationReplaceParams +import com.courier.models.notifications.NotificationRetrieveParams +import com.courier.models.notifications.NotificationTemplateCreateRequest +import com.courier.models.notifications.NotificationTemplatePayload +import com.courier.models.notifications.NotificationTemplateUpdateRequest import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test internal class NotificationServiceAsyncTest { + @Disabled("Mock server tests are disabled") + @Test + fun create() { + val client = CourierOkHttpClientAsync.builder().apiKey("My API Key").build() + val notificationServiceAsync = client.notifications() + + val notificationTemplateMutationResponseFuture = + notificationServiceAsync.create( + NotificationTemplateCreateRequest.builder() + .notification( + NotificationTemplatePayload.builder() + .brand( + NotificationTemplatePayload.Brand.builder().id("brand_abc").build() + ) + .content( + ElementalContent.builder() + .addElement( + ElementalChannelNodeWithType.builder() + .type(ElementalChannelNodeWithType.Type.CHANNEL) + .build() + ) + .version("2022-01-01") + .build() + ) + .name("Welcome Email") + .routing( + NotificationTemplatePayload.Routing.builder() + .strategyId("rs_123") + .build() + ) + .subscription( + NotificationTemplatePayload.Subscription.builder() + .topicId("marketing") + .build() + ) + .addTag("onboarding") + .addTag("welcome") + .build() + ) + .state(NotificationTemplateCreateRequest.State.DRAFT) + .build() + ) + + val notificationTemplateMutationResponse = notificationTemplateMutationResponseFuture.get() + notificationTemplateMutationResponse.validate() + } + + @Disabled("Mock server tests are disabled") + @Test + fun retrieve() { + val client = CourierOkHttpClientAsync.builder().apiKey("My API Key").build() + val notificationServiceAsync = client.notifications() + + val notificationTemplateGetResponseFuture = + notificationServiceAsync.retrieve( + NotificationRetrieveParams.builder().id("id").version("version").build() + ) + + val notificationTemplateGetResponse = notificationTemplateGetResponseFuture.get() + notificationTemplateGetResponse.validate() + } + @Disabled("Mock server tests are disabled") @Test fun list() { @@ -17,13 +86,90 @@ internal class NotificationServiceAsyncTest { val notificationsFuture = notificationServiceAsync.list( - NotificationListParams.builder().cursor("cursor").notes(true).build() + NotificationListParams.builder() + .cursor("cursor") + .eventId("event_id") + .notes(true) + .build() ) val notifications = notificationsFuture.get() notifications.validate() } + @Disabled("Mock server tests are disabled") + @Test + fun archive() { + val client = CourierOkHttpClientAsync.builder().apiKey("My API Key").build() + val notificationServiceAsync = client.notifications() + + val future = notificationServiceAsync.archive("id") + + val response = future.get() + } + + @Disabled("Mock server tests are disabled") + @Test + fun publish() { + val client = CourierOkHttpClientAsync.builder().apiKey("My API Key").build() + val notificationServiceAsync = client.notifications() + + val future = notificationServiceAsync.publish("id") + + val response = future.get() + } + + @Disabled("Mock server tests are disabled") + @Test + fun replace() { + val client = CourierOkHttpClientAsync.builder().apiKey("My API Key").build() + val notificationServiceAsync = client.notifications() + + val notificationTemplateMutationResponseFuture = + notificationServiceAsync.replace( + NotificationReplaceParams.builder() + .id("id") + .notificationTemplateUpdateRequest( + NotificationTemplateUpdateRequest.builder() + .notification( + NotificationTemplatePayload.builder() + .brand( + NotificationTemplatePayload.Brand.builder().id("id").build() + ) + .content( + ElementalContent.builder() + .addElement( + ElementalChannelNodeWithType.builder() + .type(ElementalChannelNodeWithType.Type.CHANNEL) + .build() + ) + .version("2022-01-01") + .build() + ) + .name("Updated Name") + .routing( + NotificationTemplatePayload.Routing.builder() + .strategyId("strategy_id") + .build() + ) + .subscription( + NotificationTemplatePayload.Subscription.builder() + .topicId("topic_id") + .build() + ) + .addTag("updated") + .build() + ) + .state(NotificationTemplateUpdateRequest.State.PUBLISHED) + .build() + ) + .build() + ) + + val notificationTemplateMutationResponse = notificationTemplateMutationResponseFuture.get() + notificationTemplateMutationResponse.validate() + } + @Disabled("Mock server tests are disabled") @Test fun retrieveContent() { diff --git a/courier-java-core/src/test/kotlin/com/courier/services/blocking/NotificationServiceTest.kt b/courier-java-core/src/test/kotlin/com/courier/services/blocking/NotificationServiceTest.kt index 6be0d0ea..1001d20a 100644 --- a/courier-java-core/src/test/kotlin/com/courier/services/blocking/NotificationServiceTest.kt +++ b/courier-java-core/src/test/kotlin/com/courier/services/blocking/NotificationServiceTest.kt @@ -3,12 +3,79 @@ package com.courier.services.blocking import com.courier.client.okhttp.CourierOkHttpClient +import com.courier.models.ElementalChannelNodeWithType +import com.courier.models.ElementalContent import com.courier.models.notifications.NotificationListParams +import com.courier.models.notifications.NotificationReplaceParams +import com.courier.models.notifications.NotificationRetrieveParams +import com.courier.models.notifications.NotificationTemplateCreateRequest +import com.courier.models.notifications.NotificationTemplatePayload +import com.courier.models.notifications.NotificationTemplateUpdateRequest import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test internal class NotificationServiceTest { + @Disabled("Mock server tests are disabled") + @Test + fun create() { + val client = CourierOkHttpClient.builder().apiKey("My API Key").build() + val notificationService = client.notifications() + + val notificationTemplateMutationResponse = + notificationService.create( + NotificationTemplateCreateRequest.builder() + .notification( + NotificationTemplatePayload.builder() + .brand( + NotificationTemplatePayload.Brand.builder().id("brand_abc").build() + ) + .content( + ElementalContent.builder() + .addElement( + ElementalChannelNodeWithType.builder() + .type(ElementalChannelNodeWithType.Type.CHANNEL) + .build() + ) + .version("2022-01-01") + .build() + ) + .name("Welcome Email") + .routing( + NotificationTemplatePayload.Routing.builder() + .strategyId("rs_123") + .build() + ) + .subscription( + NotificationTemplatePayload.Subscription.builder() + .topicId("marketing") + .build() + ) + .addTag("onboarding") + .addTag("welcome") + .build() + ) + .state(NotificationTemplateCreateRequest.State.DRAFT) + .build() + ) + + notificationTemplateMutationResponse.validate() + } + + @Disabled("Mock server tests are disabled") + @Test + fun retrieve() { + val client = CourierOkHttpClient.builder().apiKey("My API Key").build() + val notificationService = client.notifications() + + val notificationTemplateGetResponse = + notificationService.retrieve( + NotificationRetrieveParams.builder().id("id").version("version").build() + ) + + notificationTemplateGetResponse.validate() + } + @Disabled("Mock server tests are disabled") @Test fun list() { @@ -17,12 +84,84 @@ internal class NotificationServiceTest { val notifications = notificationService.list( - NotificationListParams.builder().cursor("cursor").notes(true).build() + NotificationListParams.builder() + .cursor("cursor") + .eventId("event_id") + .notes(true) + .build() ) notifications.validate() } + @Disabled("Mock server tests are disabled") + @Test + fun archive() { + val client = CourierOkHttpClient.builder().apiKey("My API Key").build() + val notificationService = client.notifications() + + notificationService.archive("id") + } + + @Disabled("Mock server tests are disabled") + @Test + fun publish() { + val client = CourierOkHttpClient.builder().apiKey("My API Key").build() + val notificationService = client.notifications() + + notificationService.publish("id") + } + + @Disabled("Mock server tests are disabled") + @Test + fun replace() { + val client = CourierOkHttpClient.builder().apiKey("My API Key").build() + val notificationService = client.notifications() + + val notificationTemplateMutationResponse = + notificationService.replace( + NotificationReplaceParams.builder() + .id("id") + .notificationTemplateUpdateRequest( + NotificationTemplateUpdateRequest.builder() + .notification( + NotificationTemplatePayload.builder() + .brand( + NotificationTemplatePayload.Brand.builder().id("id").build() + ) + .content( + ElementalContent.builder() + .addElement( + ElementalChannelNodeWithType.builder() + .type(ElementalChannelNodeWithType.Type.CHANNEL) + .build() + ) + .version("2022-01-01") + .build() + ) + .name("Updated Name") + .routing( + NotificationTemplatePayload.Routing.builder() + .strategyId("strategy_id") + .build() + ) + .subscription( + NotificationTemplatePayload.Subscription.builder() + .topicId("topic_id") + .build() + ) + .addTag("updated") + .build() + ) + .state(NotificationTemplateUpdateRequest.State.PUBLISHED) + .build() + ) + .build() + ) + + notificationTemplateMutationResponse.validate() + } + @Disabled("Mock server tests are disabled") @Test fun retrieveContent() { diff --git a/scripts/fast-format b/scripts/fast-format index 1b3bc473..35a1dee2 100755 --- a/scripts/fast-format +++ b/scripts/fast-format @@ -24,8 +24,8 @@ if [ ! -f "$FILE_LIST" ]; then exit 1 fi -if ! command -v ktfmt-fast-format &> /dev/null; then - echo "Error: ktfmt-fast-format not found" +if ! command -v ktfmt &> /dev/null; then + echo "Error: ktfmt not found" exit 1 fi @@ -36,7 +36,7 @@ echo "==> Done looking for Kotlin files" if [[ -n "$kt_files" ]]; then echo "==> will format Kotlin files" - echo "$kt_files" | tr '\n' '\0' | xargs -0 ktfmt-fast-format --kotlinlang-style "$@" + echo "$kt_files" | tr '\n' '\0' | xargs -0 ktfmt --kotlinlang-style "$@" else echo "No Kotlin files to format -- expected outcome during incremental formatting" fi