From a8095821586036d00c3543929e6eef860fabdd3a Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 31 Jan 2026 05:10:07 +0000 Subject: [PATCH 1/4] chore(internal): allow passing args to `./scripts/test` --- scripts/build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build b/scripts/build index f4063482..16a2b00d 100755 --- a/scripts/build +++ b/scripts/build @@ -5,4 +5,4 @@ set -e cd "$(dirname "$0")/.." echo "==> Building classes" -./gradlew build testClasses -x test +./gradlew build testClasses "$@" -x test From 35df2154e48a5e158285cda871f506202d9199c6 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 5 Feb 2026 17:28:38 +0000 Subject: [PATCH 2/4] feat(api): add toOfRecipients method to send message --- .stats.yml | 4 +- .../courier/models/send/SendMessageParams.kt | 415 +++++++++++++++++- 2 files changed, 416 insertions(+), 3 deletions(-) diff --git a/.stats.yml b/.stats.yml index edd99bd4..e1e808f0 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 78 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/courier%2Fcourier-4469c7d243ac17a71d48187ede11d7f6fd178d1006f2542c973259c5c37007fb.yml -openapi_spec_hash: 2036a46b6fa7ac8eae981583bd452458 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/courier%2Fcourier-2cde866450022e180983325c70421aa17a47ae9dbf6a7dbd935f3279d61a0172.yml +openapi_spec_hash: d805377811f69d0b37c578ebf9d6bada config_hash: 93eb861d9572cea4d66edeab309e08c6 diff --git a/courier-java-core/src/main/kotlin/com/courier/models/send/SendMessageParams.kt b/courier-java-core/src/main/kotlin/com/courier/models/send/SendMessageParams.kt index 80bfc668..db5cea79 100644 --- a/courier-java-core/src/main/kotlin/com/courier/models/send/SendMessageParams.kt +++ b/courier-java-core/src/main/kotlin/com/courier/models/send/SendMessageParams.kt @@ -998,6 +998,9 @@ private constructor( /** Alias for calling [to] with `To.ofWebhookRecipient(webhookRecipient)`. */ fun to(webhookRecipient: WebhookRecipient) = to(To.ofWebhookRecipient(webhookRecipient)) + /** Alias for calling [to] with `To.ofRecipients(recipients)`. */ + fun toOfRecipients(recipients: List) = to(To.ofRecipients(recipients)) + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() putAllAdditionalProperties(additionalProperties) @@ -3743,6 +3746,7 @@ private constructor( private val msTeamsRecipient: MsTeamsRecipient? = null, private val pagerdutyRecipient: PagerdutyRecipient? = null, private val webhookRecipient: WebhookRecipient? = null, + private val recipients: List? = null, private val _json: JsonValue? = null, ) { @@ -3775,6 +3779,8 @@ private constructor( fun webhookRecipient(): Optional = Optional.ofNullable(webhookRecipient) + fun recipients(): Optional> = Optional.ofNullable(recipients) + fun isUserRecipient(): Boolean = userRecipient != null fun isAudienceRecipient(): Boolean = audienceRecipient != null @@ -3791,6 +3797,8 @@ private constructor( fun isWebhookRecipient(): Boolean = webhookRecipient != null + fun isRecipients(): Boolean = recipients != null + /** Send to a specific user by user_id, email, phone_number, or list_id */ fun asUserRecipient(): UserRecipient = userRecipient.getOrThrow("userRecipient") @@ -3820,6 +3828,8 @@ private constructor( fun asWebhookRecipient(): WebhookRecipient = webhookRecipient.getOrThrow("webhookRecipient") + fun asRecipients(): List = recipients.getOrThrow("recipients") + fun _json(): Optional = Optional.ofNullable(_json) fun accept(visitor: Visitor): T = @@ -3834,6 +3844,7 @@ private constructor( pagerdutyRecipient != null -> visitor.visitPagerdutyRecipient(pagerdutyRecipient) webhookRecipient != null -> visitor.visitWebhookRecipient(webhookRecipient) + recipients != null -> visitor.visitRecipients(recipients) else -> visitor.unknown(_json) } @@ -3881,6 +3892,10 @@ private constructor( override fun visitWebhookRecipient(webhookRecipient: WebhookRecipient) { webhookRecipient.validate() } + + override fun visitRecipients(recipients: List) { + recipients.forEach { it.validate() } + } } ) validated = true @@ -3930,6 +3945,9 @@ private constructor( override fun visitWebhookRecipient(webhookRecipient: WebhookRecipient) = webhookRecipient.validity() + override fun visitRecipients(recipients: List) = + recipients.sumOf { it.validity().toInt() } + override fun unknown(json: JsonValue?) = 0 } ) @@ -3947,7 +3965,8 @@ private constructor( slackRecipient == other.slackRecipient && msTeamsRecipient == other.msTeamsRecipient && pagerdutyRecipient == other.pagerdutyRecipient && - webhookRecipient == other.webhookRecipient + webhookRecipient == other.webhookRecipient && + recipients == other.recipients } override fun hashCode(): Int = @@ -3960,6 +3979,7 @@ private constructor( msTeamsRecipient, pagerdutyRecipient, webhookRecipient, + recipients, ) override fun toString(): String = @@ -3972,6 +3992,7 @@ private constructor( msTeamsRecipient != null -> "To{msTeamsRecipient=$msTeamsRecipient}" pagerdutyRecipient != null -> "To{pagerdutyRecipient=$pagerdutyRecipient}" webhookRecipient != null -> "To{webhookRecipient=$webhookRecipient}" + recipients != null -> "To{recipients=$recipients}" _json != null -> "To{_unknown=$_json}" else -> throw IllegalStateException("Invalid To") } @@ -4017,6 +4038,10 @@ private constructor( @JvmStatic fun ofWebhookRecipient(webhookRecipient: WebhookRecipient) = To(webhookRecipient = webhookRecipient) + + @JvmStatic + fun ofRecipients(recipients: List) = + To(recipients = recipients.toImmutable()) } /** An interface that defines how to map each variant of [To] to a value of type [T]. */ @@ -4046,6 +4071,8 @@ private constructor( /** Send via webhook */ fun visitWebhookRecipient(webhookRecipient: WebhookRecipient): T + fun visitRecipients(recipients: List): T + /** * Maps an unknown variant of [To] to a value of type [T]. * @@ -4092,6 +4119,9 @@ private constructor( tryDeserialize(node, jacksonTypeRef())?.let { To(webhookRecipient = it, _json = json) }, + tryDeserialize(node, jacksonTypeRef>())?.let { + To(recipients = it, _json = json) + }, ) .filterNotNull() .allMaxBy { it.validity() } @@ -4130,11 +4160,394 @@ private constructor( generator.writeObject(value.pagerdutyRecipient) value.webhookRecipient != null -> generator.writeObject(value.webhookRecipient) + value.recipients != null -> generator.writeObject(value.recipients) value._json != null -> generator.writeObject(value._json) else -> throw IllegalStateException("Invalid To") } } } + + /** + * A single recipient of the message. Choose one of the following types based on how you + * want to identify the recipient: - **User**: Send to a specific user by user_id, + * email, or phone number - **Audience**: Send to all users in an audience - **List**: + * Send to all users in a list - **List Pattern**: Send to users in lists matching a + * pattern - **Slack**: Send via Slack (channel, email, or user_id) - **MS Teams**: Send + * via Microsoft Teams - **PagerDuty**: Send via PagerDuty - **Webhook**: Send via + * webhook + */ + @JsonDeserialize(using = Recipient.Deserializer::class) + @JsonSerialize(using = Recipient.Serializer::class) + class Recipient + private constructor( + private val user: UserRecipient? = null, + private val audience: AudienceRecipient? = null, + private val list: ListRecipient? = null, + private val listPattern: ListPatternRecipient? = null, + private val slack: SlackRecipient? = null, + private val msTeams: MsTeamsRecipient? = null, + private val pagerduty: PagerdutyRecipient? = null, + private val webhook: WebhookRecipient? = null, + private val _json: JsonValue? = null, + ) { + + /** Send to a specific user by user_id, email, phone_number, or list_id */ + fun user(): Optional = Optional.ofNullable(user) + + /** Send to all users in an audience */ + fun audience(): Optional = Optional.ofNullable(audience) + + /** Send to all users in a specific list */ + fun list(): Optional = Optional.ofNullable(list) + + /** Send to users in lists matching a pattern */ + fun listPattern(): Optional = Optional.ofNullable(listPattern) + + /** Send via Slack (channel, email, or user_id) */ + fun slack(): Optional = Optional.ofNullable(slack) + + /** Send via Microsoft Teams */ + fun msTeams(): Optional = Optional.ofNullable(msTeams) + + /** Send via PagerDuty */ + fun pagerduty(): Optional = Optional.ofNullable(pagerduty) + + /** Send via webhook */ + fun webhook(): Optional = Optional.ofNullable(webhook) + + fun isUser(): Boolean = user != null + + fun isAudience(): Boolean = audience != null + + fun isList(): Boolean = list != null + + fun isListPattern(): Boolean = listPattern != null + + fun isSlack(): Boolean = slack != null + + fun isMsTeams(): Boolean = msTeams != null + + fun isPagerduty(): Boolean = pagerduty != null + + fun isWebhook(): Boolean = webhook != null + + /** Send to a specific user by user_id, email, phone_number, or list_id */ + fun asUser(): UserRecipient = user.getOrThrow("user") + + /** Send to all users in an audience */ + fun asAudience(): AudienceRecipient = audience.getOrThrow("audience") + + /** Send to all users in a specific list */ + fun asList(): ListRecipient = list.getOrThrow("list") + + /** Send to users in lists matching a pattern */ + fun asListPattern(): ListPatternRecipient = listPattern.getOrThrow("listPattern") + + /** Send via Slack (channel, email, or user_id) */ + fun asSlack(): SlackRecipient = slack.getOrThrow("slack") + + /** Send via Microsoft Teams */ + fun asMsTeams(): MsTeamsRecipient = msTeams.getOrThrow("msTeams") + + /** Send via PagerDuty */ + fun asPagerduty(): PagerdutyRecipient = pagerduty.getOrThrow("pagerduty") + + /** Send via webhook */ + fun asWebhook(): WebhookRecipient = webhook.getOrThrow("webhook") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T = + when { + user != null -> visitor.visitUser(user) + audience != null -> visitor.visitAudience(audience) + list != null -> visitor.visitList(list) + listPattern != null -> visitor.visitListPattern(listPattern) + slack != null -> visitor.visitSlack(slack) + msTeams != null -> visitor.visitMsTeams(msTeams) + pagerduty != null -> visitor.visitPagerduty(pagerduty) + webhook != null -> visitor.visitWebhook(webhook) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + fun validate(): Recipient = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitUser(user: UserRecipient) { + user.validate() + } + + override fun visitAudience(audience: AudienceRecipient) { + audience.validate() + } + + override fun visitList(list: ListRecipient) { + list.validate() + } + + override fun visitListPattern(listPattern: ListPatternRecipient) { + listPattern.validate() + } + + override fun visitSlack(slack: SlackRecipient) { + slack.validate() + } + + override fun visitMsTeams(msTeams: MsTeamsRecipient) { + msTeams.validate() + } + + override fun visitPagerduty(pagerduty: PagerdutyRecipient) { + pagerduty.validate() + } + + override fun visitWebhook(webhook: WebhookRecipient) { + webhook.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 = + accept( + object : Visitor { + override fun visitUser(user: UserRecipient) = user.validity() + + override fun visitAudience(audience: AudienceRecipient) = + audience.validity() + + override fun visitList(list: ListRecipient) = list.validity() + + override fun visitListPattern(listPattern: ListPatternRecipient) = + listPattern.validity() + + override fun visitSlack(slack: SlackRecipient) = slack.validity() + + override fun visitMsTeams(msTeams: MsTeamsRecipient) = + msTeams.validity() + + override fun visitPagerduty(pagerduty: PagerdutyRecipient) = + pagerduty.validity() + + override fun visitWebhook(webhook: WebhookRecipient) = + webhook.validity() + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Recipient && + user == other.user && + audience == other.audience && + list == other.list && + listPattern == other.listPattern && + slack == other.slack && + msTeams == other.msTeams && + pagerduty == other.pagerduty && + webhook == other.webhook + } + + override fun hashCode(): Int = + Objects.hash( + user, + audience, + list, + listPattern, + slack, + msTeams, + pagerduty, + webhook, + ) + + override fun toString(): String = + when { + user != null -> "Recipient{user=$user}" + audience != null -> "Recipient{audience=$audience}" + list != null -> "Recipient{list=$list}" + listPattern != null -> "Recipient{listPattern=$listPattern}" + slack != null -> "Recipient{slack=$slack}" + msTeams != null -> "Recipient{msTeams=$msTeams}" + pagerduty != null -> "Recipient{pagerduty=$pagerduty}" + webhook != null -> "Recipient{webhook=$webhook}" + _json != null -> "Recipient{_unknown=$_json}" + else -> throw IllegalStateException("Invalid Recipient") + } + + companion object { + + /** Send to a specific user by user_id, email, phone_number, or list_id */ + @JvmStatic fun ofUser(user: UserRecipient) = Recipient(user = user) + + /** Send to all users in an audience */ + @JvmStatic + fun ofAudience(audience: AudienceRecipient) = Recipient(audience = audience) + + /** Send to all users in a specific list */ + @JvmStatic fun ofList(list: ListRecipient) = Recipient(list = list) + + /** Send to users in lists matching a pattern */ + @JvmStatic + fun ofListPattern(listPattern: ListPatternRecipient) = + Recipient(listPattern = listPattern) + + /** Send via Slack (channel, email, or user_id) */ + @JvmStatic fun ofSlack(slack: SlackRecipient) = Recipient(slack = slack) + + /** Send via Microsoft Teams */ + @JvmStatic + fun ofMsTeams(msTeams: MsTeamsRecipient) = Recipient(msTeams = msTeams) + + /** Send via PagerDuty */ + @JvmStatic + fun ofPagerduty(pagerduty: PagerdutyRecipient) = + Recipient(pagerduty = pagerduty) + + /** Send via webhook */ + @JvmStatic + fun ofWebhook(webhook: WebhookRecipient) = Recipient(webhook = webhook) + } + + /** + * An interface that defines how to map each variant of [Recipient] to a value of + * type [T]. + */ + interface Visitor { + + /** Send to a specific user by user_id, email, phone_number, or list_id */ + fun visitUser(user: UserRecipient): T + + /** Send to all users in an audience */ + fun visitAudience(audience: AudienceRecipient): T + + /** Send to all users in a specific list */ + fun visitList(list: ListRecipient): T + + /** Send to users in lists matching a pattern */ + fun visitListPattern(listPattern: ListPatternRecipient): T + + /** Send via Slack (channel, email, or user_id) */ + fun visitSlack(slack: SlackRecipient): T + + /** Send via Microsoft Teams */ + fun visitMsTeams(msTeams: MsTeamsRecipient): T + + /** Send via PagerDuty */ + fun visitPagerduty(pagerduty: PagerdutyRecipient): T + + /** Send via webhook */ + fun visitWebhook(webhook: WebhookRecipient): T + + /** + * Maps an unknown variant of [Recipient] to a value of type [T]. + * + * An instance of [Recipient] 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. + */ + fun unknown(json: JsonValue?): T { + throw CourierInvalidDataException("Unknown Recipient: $json") + } + } + + internal class Deserializer : BaseDeserializer(Recipient::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): Recipient { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef())?.let { + Recipient(user = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + Recipient(audience = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + Recipient(list = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef()) + ?.let { Recipient(listPattern = it, _json = json) }, + tryDeserialize(node, jacksonTypeRef())?.let { + Recipient(slack = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + Recipient(msTeams = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef()) + ?.let { Recipient(pagerduty = it, _json = json) }, + tryDeserialize(node, jacksonTypeRef())?.let { + Recipient(webhook = 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 -> Recipient(_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(Recipient::class) { + + override fun serialize( + value: Recipient, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.user != null -> generator.writeObject(value.user) + value.audience != null -> generator.writeObject(value.audience) + value.list != null -> generator.writeObject(value.list) + value.listPattern != null -> generator.writeObject(value.listPattern) + value.slack != null -> generator.writeObject(value.slack) + value.msTeams != null -> generator.writeObject(value.msTeams) + value.pagerduty != null -> generator.writeObject(value.pagerduty) + value.webhook != null -> generator.writeObject(value.webhook) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid Recipient") + } + } + } + } } override fun equals(other: Any?): Boolean { From 41fbfe5dd327a8a142da5ac65ba72f777f9794a9 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 6 Feb 2026 18:58:33 +0000 Subject: [PATCH 3/4] feat(api): add publish/replace methods, versions resource to tenant templates --- .stats.yml | 8 +- .../PostTenantTemplatePublishRequest.kt | 166 ++++++ .../PostTenantTemplatePublishResponse.kt | 258 +++++++++ .../tenants/PutTenantTemplateRequest.kt | 222 ++++++++ .../tenants/PutTenantTemplateResponse.kt | 262 +++++++++ .../models/tenants/TenantTemplateInput.kt | 495 ++++++++++++++++++ .../templates/TemplatePublishParams.kt | 260 +++++++++ .../templates/TemplateReplaceParams.kt | 252 +++++++++ .../versions/VersionRetrieveParams.kt | 236 +++++++++ .../async/tenants/TemplateServiceAsync.kt | 133 +++++ .../async/tenants/TemplateServiceAsyncImpl.kt | 110 ++++ .../tenants/templates/VersionServiceAsync.kt | 104 ++++ .../templates/VersionServiceAsyncImpl.kt | 96 ++++ .../blocking/tenants/TemplateService.kt | 134 +++++ .../blocking/tenants/TemplateServiceImpl.kt | 104 ++++ .../tenants/templates/VersionService.kt | 100 ++++ .../tenants/templates/VersionServiceImpl.kt | 92 ++++ .../PostTenantTemplatePublishRequestTest.kt | 35 ++ .../PostTenantTemplatePublishResponseTest.kt | 45 ++ .../tenants/PutTenantTemplateRequestTest.kt | 277 ++++++++++ .../tenants/PutTenantTemplateResponseTest.kt | 44 ++ .../models/tenants/TenantTemplateInputTest.kt | 265 ++++++++++ .../templates/TemplatePublishParamsTest.kt | 58 ++ .../templates/TemplateReplaceParamsTest.kt | 355 +++++++++++++ .../versions/VersionRetrieveParamsTest.kt | 34 ++ .../async/tenants/TemplateServiceAsyncTest.kt | 140 +++++ .../templates/VersionServiceAsyncTest.kt | 37 ++ .../blocking/tenants/TemplateServiceTest.kt | 138 +++++ .../tenants/templates/VersionServiceTest.kt | 36 ++ 29 files changed, 4492 insertions(+), 4 deletions(-) create mode 100644 courier-java-core/src/main/kotlin/com/courier/models/tenants/PostTenantTemplatePublishRequest.kt create mode 100644 courier-java-core/src/main/kotlin/com/courier/models/tenants/PostTenantTemplatePublishResponse.kt create mode 100644 courier-java-core/src/main/kotlin/com/courier/models/tenants/PutTenantTemplateRequest.kt create mode 100644 courier-java-core/src/main/kotlin/com/courier/models/tenants/PutTenantTemplateResponse.kt create mode 100644 courier-java-core/src/main/kotlin/com/courier/models/tenants/TenantTemplateInput.kt create mode 100644 courier-java-core/src/main/kotlin/com/courier/models/tenants/templates/TemplatePublishParams.kt create mode 100644 courier-java-core/src/main/kotlin/com/courier/models/tenants/templates/TemplateReplaceParams.kt create mode 100644 courier-java-core/src/main/kotlin/com/courier/models/tenants/templates/versions/VersionRetrieveParams.kt create mode 100644 courier-java-core/src/main/kotlin/com/courier/services/async/tenants/templates/VersionServiceAsync.kt create mode 100644 courier-java-core/src/main/kotlin/com/courier/services/async/tenants/templates/VersionServiceAsyncImpl.kt create mode 100644 courier-java-core/src/main/kotlin/com/courier/services/blocking/tenants/templates/VersionService.kt create mode 100644 courier-java-core/src/main/kotlin/com/courier/services/blocking/tenants/templates/VersionServiceImpl.kt create mode 100644 courier-java-core/src/test/kotlin/com/courier/models/tenants/PostTenantTemplatePublishRequestTest.kt create mode 100644 courier-java-core/src/test/kotlin/com/courier/models/tenants/PostTenantTemplatePublishResponseTest.kt create mode 100644 courier-java-core/src/test/kotlin/com/courier/models/tenants/PutTenantTemplateRequestTest.kt create mode 100644 courier-java-core/src/test/kotlin/com/courier/models/tenants/PutTenantTemplateResponseTest.kt create mode 100644 courier-java-core/src/test/kotlin/com/courier/models/tenants/TenantTemplateInputTest.kt create mode 100644 courier-java-core/src/test/kotlin/com/courier/models/tenants/templates/TemplatePublishParamsTest.kt create mode 100644 courier-java-core/src/test/kotlin/com/courier/models/tenants/templates/TemplateReplaceParamsTest.kt create mode 100644 courier-java-core/src/test/kotlin/com/courier/models/tenants/templates/versions/VersionRetrieveParamsTest.kt create mode 100644 courier-java-core/src/test/kotlin/com/courier/services/async/tenants/templates/VersionServiceAsyncTest.kt create mode 100644 courier-java-core/src/test/kotlin/com/courier/services/blocking/tenants/templates/VersionServiceTest.kt diff --git a/.stats.yml b/.stats.yml index e1e808f0..17749e26 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 78 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/courier%2Fcourier-2cde866450022e180983325c70421aa17a47ae9dbf6a7dbd935f3279d61a0172.yml -openapi_spec_hash: d805377811f69d0b37c578ebf9d6bada -config_hash: 93eb861d9572cea4d66edeab309e08c6 +configured_endpoints: 81 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/courier%2Fcourier-3fc1c86b4a83a16393aaf17d1fb3ac6098d30dd057ba872973b57285a7a3f0d0.yml +openapi_spec_hash: 02a545d217b13399f311e99561f9de1d +config_hash: 0789c3cddc625bb9712b3bded274ab6c diff --git a/courier-java-core/src/main/kotlin/com/courier/models/tenants/PostTenantTemplatePublishRequest.kt b/courier-java-core/src/main/kotlin/com/courier/models/tenants/PostTenantTemplatePublishRequest.kt new file mode 100644 index 00000000..a6d1d9f3 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/models/tenants/PostTenantTemplatePublishRequest.kt @@ -0,0 +1,166 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.tenants + +import com.courier.core.ExcludeMissing +import com.courier.core.JsonField +import com.courier.core.JsonMissing +import com.courier.core.JsonValue +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 + +/** Request body for publishing a tenant template version */ +class PostTenantTemplatePublishRequest +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val version: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("version") @ExcludeMissing version: JsonField = JsonMissing.of() + ) : this(version, mutableMapOf()) + + /** + * The version of the template to publish (e.g., "v1", "v2", "latest"). If not provided, + * defaults to "latest". + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun version(): Optional = version.getOptional("version") + + /** + * Returns the raw JSON value of [version]. + * + * Unlike [version], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("version") @ExcludeMissing fun _version(): JsonField = version + + @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 + * [PostTenantTemplatePublishRequest]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [PostTenantTemplatePublishRequest]. */ + class Builder internal constructor() { + + private var version: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(postTenantTemplatePublishRequest: PostTenantTemplatePublishRequest) = + apply { + version = postTenantTemplatePublishRequest.version + additionalProperties = + postTenantTemplatePublishRequest.additionalProperties.toMutableMap() + } + + /** + * The version of the template to publish (e.g., "v1", "v2", "latest"). If not provided, + * defaults to "latest". + */ + fun version(version: String) = version(JsonField.of(version)) + + /** + * Sets [Builder.version] to an arbitrary JSON value. + * + * You should usually call [Builder.version] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun version(version: JsonField) = apply { this.version = version } + + 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 [PostTenantTemplatePublishRequest]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): PostTenantTemplatePublishRequest = + PostTenantTemplatePublishRequest(version, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): PostTenantTemplatePublishRequest = apply { + if (validated) { + return@apply + } + + version() + 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 (version.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is PostTenantTemplatePublishRequest && + version == other.version && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(version, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "PostTenantTemplatePublishRequest{version=$version, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/models/tenants/PostTenantTemplatePublishResponse.kt b/courier-java-core/src/main/kotlin/com/courier/models/tenants/PostTenantTemplatePublishResponse.kt new file mode 100644 index 00000000..b85d08cb --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/models/tenants/PostTenantTemplatePublishResponse.kt @@ -0,0 +1,258 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.tenants + +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 + +/** Response from publishing a tenant template */ +class PostTenantTemplatePublishResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val id: JsonField, + private val publishedAt: JsonField, + private val version: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("published_at") + @ExcludeMissing + publishedAt: JsonField = JsonMissing.of(), + @JsonProperty("version") @ExcludeMissing version: JsonField = JsonMissing.of(), + ) : this(id, publishedAt, version, mutableMapOf()) + + /** + * 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") + + /** + * The timestamp when the template was published + * + * @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 publishedAt(): String = publishedAt.getRequired("published_at") + + /** + * The published version of 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 version(): String = version.getRequired("version") + + /** + * 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 [publishedAt]. + * + * Unlike [publishedAt], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("published_at") + @ExcludeMissing + fun _publishedAt(): JsonField = publishedAt + + /** + * Returns the raw JSON value of [version]. + * + * Unlike [version], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("version") @ExcludeMissing fun _version(): JsonField = version + + @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 + * [PostTenantTemplatePublishResponse]. + * + * The following fields are required: + * ```java + * .id() + * .publishedAt() + * .version() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [PostTenantTemplatePublishResponse]. */ + class Builder internal constructor() { + + private var id: JsonField? = null + private var publishedAt: JsonField? = null + private var version: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(postTenantTemplatePublishResponse: PostTenantTemplatePublishResponse) = + apply { + id = postTenantTemplatePublishResponse.id + publishedAt = postTenantTemplatePublishResponse.publishedAt + version = postTenantTemplatePublishResponse.version + additionalProperties = + postTenantTemplatePublishResponse.additionalProperties.toMutableMap() + } + + /** 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 } + + /** The timestamp when the template was published */ + fun publishedAt(publishedAt: String) = publishedAt(JsonField.of(publishedAt)) + + /** + * Sets [Builder.publishedAt] to an arbitrary JSON value. + * + * You should usually call [Builder.publishedAt] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun publishedAt(publishedAt: JsonField) = apply { this.publishedAt = publishedAt } + + /** The published version of the template */ + fun version(version: String) = version(JsonField.of(version)) + + /** + * Sets [Builder.version] to an arbitrary JSON value. + * + * You should usually call [Builder.version] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun version(version: JsonField) = apply { this.version = version } + + 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 [PostTenantTemplatePublishResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .publishedAt() + * .version() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): PostTenantTemplatePublishResponse = + PostTenantTemplatePublishResponse( + checkRequired("id", id), + checkRequired("publishedAt", publishedAt), + checkRequired("version", version), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): PostTenantTemplatePublishResponse = apply { + if (validated) { + return@apply + } + + id() + publishedAt() + version() + 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 (publishedAt.asKnown().isPresent) 1 else 0) + + (if (version.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is PostTenantTemplatePublishResponse && + id == other.id && + publishedAt == other.publishedAt && + version == other.version && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(id, publishedAt, version, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "PostTenantTemplatePublishResponse{id=$id, publishedAt=$publishedAt, version=$version, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/models/tenants/PutTenantTemplateRequest.kt b/courier-java-core/src/main/kotlin/com/courier/models/tenants/PutTenantTemplateRequest.kt new file mode 100644 index 00000000..c5b21b9e --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/models/tenants/PutTenantTemplateRequest.kt @@ -0,0 +1,222 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.tenants + +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 or updating a tenant notification template */ +class PutTenantTemplateRequest +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val template: JsonField, + private val published: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("template") + @ExcludeMissing + template: JsonField = JsonMissing.of(), + @JsonProperty("published") @ExcludeMissing published: JsonField = JsonMissing.of(), + ) : this(template, published, mutableMapOf()) + + /** + * Template configuration for creating or updating a tenant notification 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 template(): TenantTemplateInput = template.getRequired("template") + + /** + * Whether to publish the template immediately after saving. When true, the template becomes the + * active/published version. When false (default), the template is saved as a draft. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun published(): Optional = published.getOptional("published") + + /** + * Returns the raw JSON value of [template]. + * + * Unlike [template], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("template") + @ExcludeMissing + fun _template(): JsonField = template + + /** + * Returns the raw JSON value of [published]. + * + * Unlike [published], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("published") @ExcludeMissing fun _published(): JsonField = published + + @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 [PutTenantTemplateRequest]. + * + * The following fields are required: + * ```java + * .template() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [PutTenantTemplateRequest]. */ + class Builder internal constructor() { + + private var template: JsonField? = null + private var published: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(putTenantTemplateRequest: PutTenantTemplateRequest) = apply { + template = putTenantTemplateRequest.template + published = putTenantTemplateRequest.published + additionalProperties = putTenantTemplateRequest.additionalProperties.toMutableMap() + } + + /** Template configuration for creating or updating a tenant notification template */ + fun template(template: TenantTemplateInput) = template(JsonField.of(template)) + + /** + * Sets [Builder.template] to an arbitrary JSON value. + * + * You should usually call [Builder.template] with a well-typed [TenantTemplateInput] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun template(template: JsonField) = apply { this.template = template } + + /** + * Whether to publish the template immediately after saving. When true, the template becomes + * the active/published version. When false (default), the template is saved as a draft. + */ + fun published(published: Boolean) = published(JsonField.of(published)) + + /** + * Sets [Builder.published] to an arbitrary JSON value. + * + * You should usually call [Builder.published] with a well-typed [Boolean] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun published(published: JsonField) = apply { this.published = published } + + 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 [PutTenantTemplateRequest]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .template() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): PutTenantTemplateRequest = + PutTenantTemplateRequest( + checkRequired("template", template), + published, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): PutTenantTemplateRequest = apply { + if (validated) { + return@apply + } + + template().validate() + published() + 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 = + (template.asKnown().getOrNull()?.validity() ?: 0) + + (if (published.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is PutTenantTemplateRequest && + template == other.template && + published == other.published && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(template, published, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "PutTenantTemplateRequest{template=$template, published=$published, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/models/tenants/PutTenantTemplateResponse.kt b/courier-java-core/src/main/kotlin/com/courier/models/tenants/PutTenantTemplateResponse.kt new file mode 100644 index 00000000..dd002065 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/models/tenants/PutTenantTemplateResponse.kt @@ -0,0 +1,262 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.tenants + +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 + +/** Response from creating or updating a tenant notification template */ +class PutTenantTemplateResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val id: JsonField, + private val version: JsonField, + private val publishedAt: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("version") @ExcludeMissing version: JsonField = JsonMissing.of(), + @JsonProperty("published_at") + @ExcludeMissing + publishedAt: JsonField = JsonMissing.of(), + ) : this(id, version, publishedAt, mutableMapOf()) + + /** + * 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") + + /** + * The version of the saved 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 version(): String = version.getRequired("version") + + /** + * The timestamp when the template was published. Only present if the template was published as + * part of this request. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun publishedAt(): Optional = publishedAt.getOptional("published_at") + + /** + * 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 [version]. + * + * Unlike [version], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("version") @ExcludeMissing fun _version(): JsonField = version + + /** + * Returns the raw JSON value of [publishedAt]. + * + * Unlike [publishedAt], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("published_at") + @ExcludeMissing + fun _publishedAt(): JsonField = publishedAt + + @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 [PutTenantTemplateResponse]. + * + * The following fields are required: + * ```java + * .id() + * .version() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [PutTenantTemplateResponse]. */ + class Builder internal constructor() { + + private var id: JsonField? = null + private var version: JsonField? = null + private var publishedAt: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(putTenantTemplateResponse: PutTenantTemplateResponse) = apply { + id = putTenantTemplateResponse.id + version = putTenantTemplateResponse.version + publishedAt = putTenantTemplateResponse.publishedAt + additionalProperties = putTenantTemplateResponse.additionalProperties.toMutableMap() + } + + /** 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 } + + /** The version of the saved template */ + fun version(version: String) = version(JsonField.of(version)) + + /** + * Sets [Builder.version] to an arbitrary JSON value. + * + * You should usually call [Builder.version] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun version(version: JsonField) = apply { this.version = version } + + /** + * The timestamp when the template was published. Only present if the template was published + * as part of this request. + */ + fun publishedAt(publishedAt: String?) = publishedAt(JsonField.ofNullable(publishedAt)) + + /** Alias for calling [Builder.publishedAt] with `publishedAt.orElse(null)`. */ + fun publishedAt(publishedAt: Optional) = publishedAt(publishedAt.getOrNull()) + + /** + * Sets [Builder.publishedAt] to an arbitrary JSON value. + * + * You should usually call [Builder.publishedAt] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun publishedAt(publishedAt: JsonField) = apply { this.publishedAt = publishedAt } + + 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 [PutTenantTemplateResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .version() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): PutTenantTemplateResponse = + PutTenantTemplateResponse( + checkRequired("id", id), + checkRequired("version", version), + publishedAt, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): PutTenantTemplateResponse = apply { + if (validated) { + return@apply + } + + id() + version() + publishedAt() + 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 (version.asKnown().isPresent) 1 else 0) + + (if (publishedAt.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is PutTenantTemplateResponse && + id == other.id && + version == other.version && + publishedAt == other.publishedAt && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(id, version, publishedAt, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "PutTenantTemplateResponse{id=$id, version=$version, publishedAt=$publishedAt, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/models/tenants/TenantTemplateInput.kt b/courier-java-core/src/main/kotlin/com/courier/models/tenants/TenantTemplateInput.kt new file mode 100644 index 00000000..4570b92f --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/models/tenants/TenantTemplateInput.kt @@ -0,0 +1,495 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.tenants + +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.core.toImmutable +import com.courier.errors.CourierInvalidDataException +import com.courier.models.ElementalContent +import com.courier.models.MessageRouting +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 + +/** Template configuration for creating or updating a tenant notification template */ +class TenantTemplateInput +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val content: JsonField, + private val channels: JsonField, + private val providers: JsonField, + private val routing: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("content") + @ExcludeMissing + content: JsonField = JsonMissing.of(), + @JsonProperty("channels") @ExcludeMissing channels: JsonField = JsonMissing.of(), + @JsonProperty("providers") + @ExcludeMissing + providers: JsonField = JsonMissing.of(), + @JsonProperty("routing") + @ExcludeMissing + routing: JsonField = JsonMissing.of(), + ) : this(content, channels, providers, routing, mutableMapOf()) + + /** + * Template content configuration including blocks, elements, and message structure + * + * @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") + + /** + * Channel-specific delivery configuration (email, SMS, push, etc.) + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun channels(): Optional = channels.getOptional("channels") + + /** + * Provider-specific delivery configuration for routing to specific email/SMS providers + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun providers(): Optional = providers.getOptional("providers") + + /** + * Message routing configuration for multi-channel delivery strategies + * + * @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") + + /** + * 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 [channels]. + * + * Unlike [channels], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("channels") @ExcludeMissing fun _channels(): JsonField = channels + + /** + * Returns the raw JSON value of [providers]. + * + * Unlike [providers], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("providers") @ExcludeMissing fun _providers(): JsonField = providers + + /** + * 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 + + @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 [TenantTemplateInput]. + * + * The following fields are required: + * ```java + * .content() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [TenantTemplateInput]. */ + class Builder internal constructor() { + + private var content: JsonField? = null + private var channels: JsonField = JsonMissing.of() + private var providers: JsonField = JsonMissing.of() + private var routing: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(tenantTemplateInput: TenantTemplateInput) = apply { + content = tenantTemplateInput.content + channels = tenantTemplateInput.channels + providers = tenantTemplateInput.providers + routing = tenantTemplateInput.routing + additionalProperties = tenantTemplateInput.additionalProperties.toMutableMap() + } + + /** Template content configuration including blocks, elements, and message structure */ + 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 } + + /** Channel-specific delivery configuration (email, SMS, push, etc.) */ + fun channels(channels: Channels) = channels(JsonField.of(channels)) + + /** + * Sets [Builder.channels] to an arbitrary JSON value. + * + * You should usually call [Builder.channels] with a well-typed [Channels] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun channels(channels: JsonField) = apply { this.channels = channels } + + /** Provider-specific delivery configuration for routing to specific email/SMS providers */ + fun providers(providers: Providers) = providers(JsonField.of(providers)) + + /** + * Sets [Builder.providers] to an arbitrary JSON value. + * + * You should usually call [Builder.providers] with a well-typed [Providers] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun providers(providers: JsonField) = apply { this.providers = providers } + + /** Message routing configuration for multi-channel delivery strategies */ + 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 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 [TenantTemplateInput]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .content() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): TenantTemplateInput = + TenantTemplateInput( + checkRequired("content", content), + channels, + providers, + routing, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): TenantTemplateInput = apply { + if (validated) { + return@apply + } + + content().validate() + channels().ifPresent { it.validate() } + providers().ifPresent { it.validate() } + routing().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 = + (content.asKnown().getOrNull()?.validity() ?: 0) + + (channels.asKnown().getOrNull()?.validity() ?: 0) + + (providers.asKnown().getOrNull()?.validity() ?: 0) + + (routing.asKnown().getOrNull()?.validity() ?: 0) + + /** Channel-specific delivery configuration (email, SMS, push, etc.) */ + class Channels + @JsonCreator + private constructor( + @com.fasterxml.jackson.annotation.JsonValue + private val additionalProperties: Map + ) { + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Channels]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Channels]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(channels: Channels) = apply { + additionalProperties = channels.additionalProperties.toMutableMap() + } + + 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 [Channels]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Channels = Channels(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): Channels = apply { + if (validated) { + return@apply + } + + 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 = + additionalProperties.count { (_, value) -> !value.isNull() && !value.isMissing() } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Channels && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Channels{additionalProperties=$additionalProperties}" + } + + /** Provider-specific delivery configuration for routing to specific email/SMS providers */ + class Providers + @JsonCreator + private constructor( + @com.fasterxml.jackson.annotation.JsonValue + private val additionalProperties: Map + ) { + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Providers]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Providers]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(providers: Providers) = apply { + additionalProperties = providers.additionalProperties.toMutableMap() + } + + 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 [Providers]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Providers = Providers(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): Providers = apply { + if (validated) { + return@apply + } + + 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 = + additionalProperties.count { (_, value) -> !value.isNull() && !value.isMissing() } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Providers && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Providers{additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is TenantTemplateInput && + content == other.content && + channels == other.channels && + providers == other.providers && + routing == other.routing && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(content, channels, providers, routing, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "TenantTemplateInput{content=$content, channels=$channels, providers=$providers, routing=$routing, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/models/tenants/templates/TemplatePublishParams.kt b/courier-java-core/src/main/kotlin/com/courier/models/tenants/templates/TemplatePublishParams.kt new file mode 100644 index 00000000..2c74d73a --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/models/tenants/templates/TemplatePublishParams.kt @@ -0,0 +1,260 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.tenants.templates + +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 com.courier.core.immutableEmptyMap +import com.courier.models.tenants.PostTenantTemplatePublishRequest +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * Publishes a specific version of a notification template for a tenant. + * + * The template must already exist in the tenant's notification map. If no version is specified, + * defaults to publishing the "latest" version. + */ +class TemplatePublishParams +private constructor( + private val tenantId: String, + private val templateId: String?, + private val postTenantTemplatePublishRequest: PostTenantTemplatePublishRequest?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun tenantId(): String = tenantId + + fun templateId(): Optional = Optional.ofNullable(templateId) + + /** Request body for publishing a tenant template version */ + fun postTenantTemplatePublishRequest(): Optional = + Optional.ofNullable(postTenantTemplatePublishRequest) + + fun _additionalBodyProperties(): Map = + postTenantTemplatePublishRequest?._additionalProperties() ?: immutableEmptyMap() + + /** 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 [TemplatePublishParams]. + * + * The following fields are required: + * ```java + * .tenantId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [TemplatePublishParams]. */ + class Builder internal constructor() { + + private var tenantId: String? = null + private var templateId: String? = null + private var postTenantTemplatePublishRequest: PostTenantTemplatePublishRequest? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(templatePublishParams: TemplatePublishParams) = apply { + tenantId = templatePublishParams.tenantId + templateId = templatePublishParams.templateId + postTenantTemplatePublishRequest = + templatePublishParams.postTenantTemplatePublishRequest + additionalHeaders = templatePublishParams.additionalHeaders.toBuilder() + additionalQueryParams = templatePublishParams.additionalQueryParams.toBuilder() + } + + fun tenantId(tenantId: String) = apply { this.tenantId = tenantId } + + fun templateId(templateId: String?) = apply { this.templateId = templateId } + + /** Alias for calling [Builder.templateId] with `templateId.orElse(null)`. */ + fun templateId(templateId: Optional) = templateId(templateId.getOrNull()) + + /** Request body for publishing a tenant template version */ + fun postTenantTemplatePublishRequest( + postTenantTemplatePublishRequest: PostTenantTemplatePublishRequest? + ) = apply { this.postTenantTemplatePublishRequest = postTenantTemplatePublishRequest } + + /** + * Alias for calling [Builder.postTenantTemplatePublishRequest] with + * `postTenantTemplatePublishRequest.orElse(null)`. + */ + fun postTenantTemplatePublishRequest( + postTenantTemplatePublishRequest: Optional + ) = postTenantTemplatePublishRequest(postTenantTemplatePublishRequest.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 [TemplatePublishParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .tenantId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): TemplatePublishParams = + TemplatePublishParams( + checkRequired("tenantId", tenantId), + templateId, + postTenantTemplatePublishRequest, + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): Optional = + Optional.ofNullable(postTenantTemplatePublishRequest) + + fun _pathParam(index: Int): String = + when (index) { + 0 -> tenantId + 1 -> templateId ?: "" + 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 TemplatePublishParams && + tenantId == other.tenantId && + templateId == other.templateId && + postTenantTemplatePublishRequest == other.postTenantTemplatePublishRequest && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash( + tenantId, + templateId, + postTenantTemplatePublishRequest, + additionalHeaders, + additionalQueryParams, + ) + + override fun toString() = + "TemplatePublishParams{tenantId=$tenantId, templateId=$templateId, postTenantTemplatePublishRequest=$postTenantTemplatePublishRequest, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/models/tenants/templates/TemplateReplaceParams.kt b/courier-java-core/src/main/kotlin/com/courier/models/tenants/templates/TemplateReplaceParams.kt new file mode 100644 index 00000000..a787cfc6 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/models/tenants/templates/TemplateReplaceParams.kt @@ -0,0 +1,252 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.tenants.templates + +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 com.courier.models.tenants.PutTenantTemplateRequest +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * Creates or updates a notification template for a tenant. + * + * If the template already exists for the tenant, it will be updated (200). Otherwise, a new + * template is created (201). + * + * Optionally publishes the template immediately if the `published` flag is set to true. + */ +class TemplateReplaceParams +private constructor( + private val tenantId: String, + private val templateId: String?, + private val putTenantTemplateRequest: PutTenantTemplateRequest, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun tenantId(): String = tenantId + + fun templateId(): Optional = Optional.ofNullable(templateId) + + /** Request body for creating or updating a tenant notification template */ + fun putTenantTemplateRequest(): PutTenantTemplateRequest = putTenantTemplateRequest + + fun _additionalBodyProperties(): Map = + putTenantTemplateRequest._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 [TemplateReplaceParams]. + * + * The following fields are required: + * ```java + * .tenantId() + * .putTenantTemplateRequest() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [TemplateReplaceParams]. */ + class Builder internal constructor() { + + private var tenantId: String? = null + private var templateId: String? = null + private var putTenantTemplateRequest: PutTenantTemplateRequest? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(templateReplaceParams: TemplateReplaceParams) = apply { + tenantId = templateReplaceParams.tenantId + templateId = templateReplaceParams.templateId + putTenantTemplateRequest = templateReplaceParams.putTenantTemplateRequest + additionalHeaders = templateReplaceParams.additionalHeaders.toBuilder() + additionalQueryParams = templateReplaceParams.additionalQueryParams.toBuilder() + } + + fun tenantId(tenantId: String) = apply { this.tenantId = tenantId } + + fun templateId(templateId: String?) = apply { this.templateId = templateId } + + /** Alias for calling [Builder.templateId] with `templateId.orElse(null)`. */ + fun templateId(templateId: Optional) = templateId(templateId.getOrNull()) + + /** Request body for creating or updating a tenant notification template */ + fun putTenantTemplateRequest(putTenantTemplateRequest: PutTenantTemplateRequest) = apply { + this.putTenantTemplateRequest = putTenantTemplateRequest + } + + 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 [TemplateReplaceParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .tenantId() + * .putTenantTemplateRequest() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): TemplateReplaceParams = + TemplateReplaceParams( + checkRequired("tenantId", tenantId), + templateId, + checkRequired("putTenantTemplateRequest", putTenantTemplateRequest), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): PutTenantTemplateRequest = putTenantTemplateRequest + + fun _pathParam(index: Int): String = + when (index) { + 0 -> tenantId + 1 -> templateId ?: "" + 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 TemplateReplaceParams && + tenantId == other.tenantId && + templateId == other.templateId && + putTenantTemplateRequest == other.putTenantTemplateRequest && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash( + tenantId, + templateId, + putTenantTemplateRequest, + additionalHeaders, + additionalQueryParams, + ) + + override fun toString() = + "TemplateReplaceParams{tenantId=$tenantId, templateId=$templateId, putTenantTemplateRequest=$putTenantTemplateRequest, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/models/tenants/templates/versions/VersionRetrieveParams.kt b/courier-java-core/src/main/kotlin/com/courier/models/tenants/templates/versions/VersionRetrieveParams.kt new file mode 100644 index 00000000..194d20d4 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/models/tenants/templates/versions/VersionRetrieveParams.kt @@ -0,0 +1,236 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.tenants.templates.versions + +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 + +/** + * Fetches a specific version of a tenant template. + * + * Supports the following version formats: + * - `latest` - The most recent version of the template + * - `published` - The currently published version + * - `v{version}` - A specific version (e.g., "v1", "v2", "v1.0.0") + */ +class VersionRetrieveParams +private constructor( + private val tenantId: String, + private val templateId: String, + private val version: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun tenantId(): String = tenantId + + fun templateId(): String = templateId + + 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 { + + /** + * Returns a mutable builder for constructing an instance of [VersionRetrieveParams]. + * + * The following fields are required: + * ```java + * .tenantId() + * .templateId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [VersionRetrieveParams]. */ + class Builder internal constructor() { + + private var tenantId: String? = null + private var templateId: 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(versionRetrieveParams: VersionRetrieveParams) = apply { + tenantId = versionRetrieveParams.tenantId + templateId = versionRetrieveParams.templateId + version = versionRetrieveParams.version + additionalHeaders = versionRetrieveParams.additionalHeaders.toBuilder() + additionalQueryParams = versionRetrieveParams.additionalQueryParams.toBuilder() + } + + fun tenantId(tenantId: String) = apply { this.tenantId = tenantId } + + fun templateId(templateId: String) = apply { this.templateId = templateId } + + 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 [VersionRetrieveParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .tenantId() + * .templateId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): VersionRetrieveParams = + VersionRetrieveParams( + checkRequired("tenantId", tenantId), + checkRequired("templateId", templateId), + version, + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _pathParam(index: Int): String = + when (index) { + 0 -> tenantId + 1 -> templateId + 2 -> version ?: "" + 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 VersionRetrieveParams && + tenantId == other.tenantId && + templateId == other.templateId && + version == other.version && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(tenantId, templateId, version, additionalHeaders, additionalQueryParams) + + override fun toString() = + "VersionRetrieveParams{tenantId=$tenantId, templateId=$templateId, version=$version, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/services/async/tenants/TemplateServiceAsync.kt b/courier-java-core/src/main/kotlin/com/courier/services/async/tenants/TemplateServiceAsync.kt index 115205e6..bb42e1ff 100644 --- a/courier-java-core/src/main/kotlin/com/courier/services/async/tenants/TemplateServiceAsync.kt +++ b/courier-java-core/src/main/kotlin/com/courier/services/async/tenants/TemplateServiceAsync.kt @@ -6,9 +6,14 @@ import com.courier.core.ClientOptions import com.courier.core.RequestOptions import com.courier.core.http.HttpResponseFor import com.courier.models.tenants.BaseTemplateTenantAssociation +import com.courier.models.tenants.PostTenantTemplatePublishResponse +import com.courier.models.tenants.PutTenantTemplateResponse import com.courier.models.tenants.templates.TemplateListParams import com.courier.models.tenants.templates.TemplateListResponse +import com.courier.models.tenants.templates.TemplatePublishParams +import com.courier.models.tenants.templates.TemplateReplaceParams import com.courier.models.tenants.templates.TemplateRetrieveParams +import com.courier.services.async.tenants.templates.VersionServiceAsync import java.util.concurrent.CompletableFuture import java.util.function.Consumer @@ -26,6 +31,8 @@ interface TemplateServiceAsync { */ fun withOptions(modifier: Consumer): TemplateServiceAsync + fun versions(): VersionServiceAsync + /** Get a Template in Tenant */ fun retrieve( templateId: String, @@ -86,6 +93,69 @@ interface TemplateServiceAsync { ): CompletableFuture = list(tenantId, TemplateListParams.none(), requestOptions) + /** + * Publishes a specific version of a notification template for a tenant. + * + * The template must already exist in the tenant's notification map. If no version is specified, + * defaults to publishing the "latest" version. + */ + fun publish( + templateId: String, + params: TemplatePublishParams, + ): CompletableFuture = + publish(templateId, params, RequestOptions.none()) + + /** @see publish */ + fun publish( + templateId: String, + params: TemplatePublishParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + publish(params.toBuilder().templateId(templateId).build(), requestOptions) + + /** @see publish */ + fun publish( + params: TemplatePublishParams + ): CompletableFuture = publish(params, RequestOptions.none()) + + /** @see publish */ + fun publish( + params: TemplatePublishParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** + * Creates or updates a notification template for a tenant. + * + * If the template already exists for the tenant, it will be updated (200). Otherwise, a new + * template is created (201). + * + * Optionally publishes the template immediately if the `published` flag is set to true. + */ + fun replace( + templateId: String, + params: TemplateReplaceParams, + ): CompletableFuture = + replace(templateId, params, RequestOptions.none()) + + /** @see replace */ + fun replace( + templateId: String, + params: TemplateReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + replace(params.toBuilder().templateId(templateId).build(), requestOptions) + + /** @see replace */ + fun replace(params: TemplateReplaceParams): CompletableFuture = + replace(params, RequestOptions.none()) + + /** @see replace */ + fun replace( + params: TemplateReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + /** * A view of [TemplateServiceAsync] that provides access to raw HTTP responses for each method. */ @@ -100,6 +170,8 @@ interface TemplateServiceAsync { modifier: Consumer ): TemplateServiceAsync.WithRawResponse + fun versions(): VersionServiceAsync.WithRawResponse + /** * Returns a raw HTTP response for `get /tenants/{tenant_id}/templates/{template_id}`, but * is otherwise the same as [TemplateServiceAsync.retrieve]. @@ -170,5 +242,66 @@ interface TemplateServiceAsync { requestOptions: RequestOptions, ): CompletableFuture> = list(tenantId, TemplateListParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `post + * /tenants/{tenant_id}/templates/{template_id}/publish`, but is otherwise the same as + * [TemplateServiceAsync.publish]. + */ + fun publish( + templateId: String, + params: TemplatePublishParams, + ): CompletableFuture> = + publish(templateId, params, RequestOptions.none()) + + /** @see publish */ + fun publish( + templateId: String, + params: TemplatePublishParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + publish(params.toBuilder().templateId(templateId).build(), requestOptions) + + /** @see publish */ + fun publish( + params: TemplatePublishParams + ): CompletableFuture> = + publish(params, RequestOptions.none()) + + /** @see publish */ + fun publish( + params: TemplatePublishParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `put /tenants/{tenant_id}/templates/{template_id}`, but + * is otherwise the same as [TemplateServiceAsync.replace]. + */ + fun replace( + templateId: String, + params: TemplateReplaceParams, + ): CompletableFuture> = + replace(templateId, params, RequestOptions.none()) + + /** @see replace */ + fun replace( + templateId: String, + params: TemplateReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + replace(params.toBuilder().templateId(templateId).build(), requestOptions) + + /** @see replace */ + fun replace( + params: TemplateReplaceParams + ): CompletableFuture> = + replace(params, RequestOptions.none()) + + /** @see replace */ + fun replace( + params: TemplateReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> } } diff --git a/courier-java-core/src/main/kotlin/com/courier/services/async/tenants/TemplateServiceAsyncImpl.kt b/courier-java-core/src/main/kotlin/com/courier/services/async/tenants/TemplateServiceAsyncImpl.kt index e16d2352..9b367d87 100644 --- a/courier-java-core/src/main/kotlin/com/courier/services/async/tenants/TemplateServiceAsyncImpl.kt +++ b/courier-java-core/src/main/kotlin/com/courier/services/async/tenants/TemplateServiceAsyncImpl.kt @@ -13,12 +13,19 @@ 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.tenants.BaseTemplateTenantAssociation +import com.courier.models.tenants.PostTenantTemplatePublishResponse +import com.courier.models.tenants.PutTenantTemplateResponse import com.courier.models.tenants.templates.TemplateListParams import com.courier.models.tenants.templates.TemplateListResponse +import com.courier.models.tenants.templates.TemplatePublishParams +import com.courier.models.tenants.templates.TemplateReplaceParams import com.courier.models.tenants.templates.TemplateRetrieveParams +import com.courier.services.async.tenants.templates.VersionServiceAsync +import com.courier.services.async.tenants.templates.VersionServiceAsyncImpl import java.util.concurrent.CompletableFuture import java.util.function.Consumer import kotlin.jvm.optionals.getOrNull @@ -30,11 +37,15 @@ class TemplateServiceAsyncImpl internal constructor(private val clientOptions: C WithRawResponseImpl(clientOptions) } + private val versions: VersionServiceAsync by lazy { VersionServiceAsyncImpl(clientOptions) } + override fun withRawResponse(): TemplateServiceAsync.WithRawResponse = withRawResponse override fun withOptions(modifier: Consumer): TemplateServiceAsync = TemplateServiceAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + override fun versions(): VersionServiceAsync = versions + override fun retrieve( params: TemplateRetrieveParams, requestOptions: RequestOptions, @@ -49,12 +60,30 @@ class TemplateServiceAsyncImpl internal constructor(private val clientOptions: C // get /tenants/{tenant_id}/templates withRawResponse().list(params, requestOptions).thenApply { it.parse() } + override fun publish( + params: TemplatePublishParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /tenants/{tenant_id}/templates/{template_id}/publish + withRawResponse().publish(params, requestOptions).thenApply { it.parse() } + + override fun replace( + params: TemplateReplaceParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // put /tenants/{tenant_id}/templates/{template_id} + withRawResponse().replace(params, requestOptions).thenApply { it.parse() } + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : TemplateServiceAsync.WithRawResponse { private val errorHandler: Handler = errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + private val versions: VersionServiceAsync.WithRawResponse by lazy { + VersionServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + override fun withOptions( modifier: Consumer ): TemplateServiceAsync.WithRawResponse = @@ -62,6 +91,8 @@ class TemplateServiceAsyncImpl internal constructor(private val clientOptions: C clientOptions.toBuilder().apply(modifier::accept).build() ) + override fun versions(): VersionServiceAsync.WithRawResponse = versions + private val retrieveHandler: Handler = jsonHandler(clientOptions.jsonMapper) @@ -132,5 +163,84 @@ class TemplateServiceAsyncImpl internal constructor(private val clientOptions: C } } } + + private val publishHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun publish( + params: TemplatePublishParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("templateId", params.templateId().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments( + "tenants", + params._pathParam(0), + "templates", + params._pathParam(1), + "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) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + + private val replaceHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun replace( + params: TemplateReplaceParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("templateId", params.templateId().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.PUT) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments( + "tenants", + params._pathParam(0), + "templates", + params._pathParam(1), + ) + .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() + } + } + } + } + } } } diff --git a/courier-java-core/src/main/kotlin/com/courier/services/async/tenants/templates/VersionServiceAsync.kt b/courier-java-core/src/main/kotlin/com/courier/services/async/tenants/templates/VersionServiceAsync.kt new file mode 100644 index 00000000..e03aed25 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/services/async/tenants/templates/VersionServiceAsync.kt @@ -0,0 +1,104 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.services.async.tenants.templates + +import com.courier.core.ClientOptions +import com.courier.core.RequestOptions +import com.courier.core.http.HttpResponseFor +import com.courier.models.tenants.BaseTemplateTenantAssociation +import com.courier.models.tenants.templates.versions.VersionRetrieveParams +import java.util.concurrent.CompletableFuture +import java.util.function.Consumer + +interface VersionServiceAsync { + + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + + /** + * Returns a view of this service with the given option modifications applied. + * + * The original service is not modified. + */ + fun withOptions(modifier: Consumer): VersionServiceAsync + + /** + * Fetches a specific version of a tenant template. + * + * Supports the following version formats: + * - `latest` - The most recent version of the template + * - `published` - The currently published version + * - `v{version}` - A specific version (e.g., "v1", "v2", "v1.0.0") + */ + fun retrieve( + version: String, + params: VersionRetrieveParams, + ): CompletableFuture = + retrieve(version, params, RequestOptions.none()) + + /** @see retrieve */ + fun retrieve( + version: String, + params: VersionRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + retrieve(params.toBuilder().version(version).build(), requestOptions) + + /** @see retrieve */ + fun retrieve(params: VersionRetrieveParams): CompletableFuture = + retrieve(params, RequestOptions.none()) + + /** @see retrieve */ + fun retrieve( + params: VersionRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** + * A view of [VersionServiceAsync] that provides access to raw HTTP responses for each method. + */ + interface WithRawResponse { + + /** + * Returns a view of this service with the given option modifications applied. + * + * The original service is not modified. + */ + fun withOptions( + modifier: Consumer + ): VersionServiceAsync.WithRawResponse + + /** + * Returns a raw HTTP response for `get + * /tenants/{tenant_id}/templates/{template_id}/versions/{version}`, but is otherwise the + * same as [VersionServiceAsync.retrieve]. + */ + fun retrieve( + version: String, + params: VersionRetrieveParams, + ): CompletableFuture> = + retrieve(version, params, RequestOptions.none()) + + /** @see retrieve */ + fun retrieve( + version: String, + params: VersionRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + retrieve(params.toBuilder().version(version).build(), requestOptions) + + /** @see retrieve */ + fun retrieve( + params: VersionRetrieveParams + ): CompletableFuture> = + retrieve(params, RequestOptions.none()) + + /** @see retrieve */ + fun retrieve( + params: VersionRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + } +} diff --git a/courier-java-core/src/main/kotlin/com/courier/services/async/tenants/templates/VersionServiceAsyncImpl.kt b/courier-java-core/src/main/kotlin/com/courier/services/async/tenants/templates/VersionServiceAsyncImpl.kt new file mode 100644 index 00000000..34666ba1 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/services/async/tenants/templates/VersionServiceAsyncImpl.kt @@ -0,0 +1,96 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.services.async.tenants.templates + +import com.courier.core.ClientOptions +import com.courier.core.RequestOptions +import com.courier.core.checkRequired +import com.courier.core.handlers.errorBodyHandler +import com.courier.core.handlers.errorHandler +import com.courier.core.handlers.jsonHandler +import com.courier.core.http.HttpMethod +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.parseable +import com.courier.core.prepareAsync +import com.courier.models.tenants.BaseTemplateTenantAssociation +import com.courier.models.tenants.templates.versions.VersionRetrieveParams +import java.util.concurrent.CompletableFuture +import java.util.function.Consumer +import kotlin.jvm.optionals.getOrNull + +class VersionServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + VersionServiceAsync { + + private val withRawResponse: VersionServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): VersionServiceAsync.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): VersionServiceAsync = + VersionServiceAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun retrieve( + params: VersionRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /tenants/{tenant_id}/templates/{template_id}/versions/{version} + withRawResponse().retrieve(params, requestOptions).thenApply { it.parse() } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + VersionServiceAsync.WithRawResponse { + + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + + override fun withOptions( + modifier: Consumer + ): VersionServiceAsync.WithRawResponse = + VersionServiceAsyncImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun retrieve( + params: VersionRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("version", params.version().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments( + "tenants", + params._pathParam(0), + "templates", + params._pathParam(1), + "versions", + params._pathParam(2), + ) + .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() + } + } + } + } + } + } +} diff --git a/courier-java-core/src/main/kotlin/com/courier/services/blocking/tenants/TemplateService.kt b/courier-java-core/src/main/kotlin/com/courier/services/blocking/tenants/TemplateService.kt index 5b21a915..77c3b221 100644 --- a/courier-java-core/src/main/kotlin/com/courier/services/blocking/tenants/TemplateService.kt +++ b/courier-java-core/src/main/kotlin/com/courier/services/blocking/tenants/TemplateService.kt @@ -6,9 +6,14 @@ import com.courier.core.ClientOptions import com.courier.core.RequestOptions import com.courier.core.http.HttpResponseFor import com.courier.models.tenants.BaseTemplateTenantAssociation +import com.courier.models.tenants.PostTenantTemplatePublishResponse +import com.courier.models.tenants.PutTenantTemplateResponse import com.courier.models.tenants.templates.TemplateListParams import com.courier.models.tenants.templates.TemplateListResponse +import com.courier.models.tenants.templates.TemplatePublishParams +import com.courier.models.tenants.templates.TemplateReplaceParams import com.courier.models.tenants.templates.TemplateRetrieveParams +import com.courier.services.blocking.tenants.templates.VersionService import com.google.errorprone.annotations.MustBeClosed import java.util.function.Consumer @@ -26,6 +31,8 @@ interface TemplateService { */ fun withOptions(modifier: Consumer): TemplateService + fun versions(): VersionService + /** Get a Template in Tenant */ fun retrieve( templateId: String, @@ -79,6 +86,64 @@ interface TemplateService { fun list(tenantId: String, requestOptions: RequestOptions): TemplateListResponse = list(tenantId, TemplateListParams.none(), requestOptions) + /** + * Publishes a specific version of a notification template for a tenant. + * + * The template must already exist in the tenant's notification map. If no version is specified, + * defaults to publishing the "latest" version. + */ + fun publish( + templateId: String, + params: TemplatePublishParams, + ): PostTenantTemplatePublishResponse = publish(templateId, params, RequestOptions.none()) + + /** @see publish */ + fun publish( + templateId: String, + params: TemplatePublishParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): PostTenantTemplatePublishResponse = + publish(params.toBuilder().templateId(templateId).build(), requestOptions) + + /** @see publish */ + fun publish(params: TemplatePublishParams): PostTenantTemplatePublishResponse = + publish(params, RequestOptions.none()) + + /** @see publish */ + fun publish( + params: TemplatePublishParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): PostTenantTemplatePublishResponse + + /** + * Creates or updates a notification template for a tenant. + * + * If the template already exists for the tenant, it will be updated (200). Otherwise, a new + * template is created (201). + * + * Optionally publishes the template immediately if the `published` flag is set to true. + */ + fun replace(templateId: String, params: TemplateReplaceParams): PutTenantTemplateResponse = + replace(templateId, params, RequestOptions.none()) + + /** @see replace */ + fun replace( + templateId: String, + params: TemplateReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): PutTenantTemplateResponse = + replace(params.toBuilder().templateId(templateId).build(), requestOptions) + + /** @see replace */ + fun replace(params: TemplateReplaceParams): PutTenantTemplateResponse = + replace(params, RequestOptions.none()) + + /** @see replace */ + fun replace( + params: TemplateReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): PutTenantTemplateResponse + /** A view of [TemplateService] that provides access to raw HTTP responses for each method. */ interface WithRawResponse { @@ -89,6 +154,8 @@ interface TemplateService { */ fun withOptions(modifier: Consumer): TemplateService.WithRawResponse + fun versions(): VersionService.WithRawResponse + /** * Returns a raw HTTP response for `get /tenants/{tenant_id}/templates/{template_id}`, but * is otherwise the same as [TemplateService.retrieve]. @@ -165,5 +232,72 @@ interface TemplateService { requestOptions: RequestOptions, ): HttpResponseFor = list(tenantId, TemplateListParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `post + * /tenants/{tenant_id}/templates/{template_id}/publish`, but is otherwise the same as + * [TemplateService.publish]. + */ + @MustBeClosed + fun publish( + templateId: String, + params: TemplatePublishParams, + ): HttpResponseFor = + publish(templateId, params, RequestOptions.none()) + + /** @see publish */ + @MustBeClosed + fun publish( + templateId: String, + params: TemplatePublishParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + publish(params.toBuilder().templateId(templateId).build(), requestOptions) + + /** @see publish */ + @MustBeClosed + fun publish( + params: TemplatePublishParams + ): HttpResponseFor = + publish(params, RequestOptions.none()) + + /** @see publish */ + @MustBeClosed + fun publish( + params: TemplatePublishParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `put /tenants/{tenant_id}/templates/{template_id}`, but + * is otherwise the same as [TemplateService.replace]. + */ + @MustBeClosed + fun replace( + templateId: String, + params: TemplateReplaceParams, + ): HttpResponseFor = + replace(templateId, params, RequestOptions.none()) + + /** @see replace */ + @MustBeClosed + fun replace( + templateId: String, + params: TemplateReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + replace(params.toBuilder().templateId(templateId).build(), requestOptions) + + /** @see replace */ + @MustBeClosed + fun replace(params: TemplateReplaceParams): HttpResponseFor = + replace(params, RequestOptions.none()) + + /** @see replace */ + @MustBeClosed + fun replace( + params: TemplateReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor } } diff --git a/courier-java-core/src/main/kotlin/com/courier/services/blocking/tenants/TemplateServiceImpl.kt b/courier-java-core/src/main/kotlin/com/courier/services/blocking/tenants/TemplateServiceImpl.kt index 5c86f3c3..739d1073 100644 --- a/courier-java-core/src/main/kotlin/com/courier/services/blocking/tenants/TemplateServiceImpl.kt +++ b/courier-java-core/src/main/kotlin/com/courier/services/blocking/tenants/TemplateServiceImpl.kt @@ -13,12 +13,19 @@ 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.tenants.BaseTemplateTenantAssociation +import com.courier.models.tenants.PostTenantTemplatePublishResponse +import com.courier.models.tenants.PutTenantTemplateResponse import com.courier.models.tenants.templates.TemplateListParams import com.courier.models.tenants.templates.TemplateListResponse +import com.courier.models.tenants.templates.TemplatePublishParams +import com.courier.models.tenants.templates.TemplateReplaceParams import com.courier.models.tenants.templates.TemplateRetrieveParams +import com.courier.services.blocking.tenants.templates.VersionService +import com.courier.services.blocking.tenants.templates.VersionServiceImpl import java.util.function.Consumer import kotlin.jvm.optionals.getOrNull @@ -29,11 +36,15 @@ class TemplateServiceImpl internal constructor(private val clientOptions: Client WithRawResponseImpl(clientOptions) } + private val versions: VersionService by lazy { VersionServiceImpl(clientOptions) } + override fun withRawResponse(): TemplateService.WithRawResponse = withRawResponse override fun withOptions(modifier: Consumer): TemplateService = TemplateServiceImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + override fun versions(): VersionService = versions + override fun retrieve( params: TemplateRetrieveParams, requestOptions: RequestOptions, @@ -48,12 +59,30 @@ class TemplateServiceImpl internal constructor(private val clientOptions: Client // get /tenants/{tenant_id}/templates withRawResponse().list(params, requestOptions).parse() + override fun publish( + params: TemplatePublishParams, + requestOptions: RequestOptions, + ): PostTenantTemplatePublishResponse = + // post /tenants/{tenant_id}/templates/{template_id}/publish + withRawResponse().publish(params, requestOptions).parse() + + override fun replace( + params: TemplateReplaceParams, + requestOptions: RequestOptions, + ): PutTenantTemplateResponse = + // put /tenants/{tenant_id}/templates/{template_id} + withRawResponse().replace(params, requestOptions).parse() + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : TemplateService.WithRawResponse { private val errorHandler: Handler = errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + private val versions: VersionService.WithRawResponse by lazy { + VersionServiceImpl.WithRawResponseImpl(clientOptions) + } + override fun withOptions( modifier: Consumer ): TemplateService.WithRawResponse = @@ -61,6 +90,8 @@ class TemplateServiceImpl internal constructor(private val clientOptions: Client clientOptions.toBuilder().apply(modifier::accept).build() ) + override fun versions(): VersionService.WithRawResponse = versions + private val retrieveHandler: Handler = jsonHandler(clientOptions.jsonMapper) @@ -125,5 +156,78 @@ class TemplateServiceImpl internal constructor(private val clientOptions: Client } } } + + private val publishHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun publish( + params: TemplatePublishParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("templateId", params.templateId().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments( + "tenants", + params._pathParam(0), + "templates", + params._pathParam(1), + "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) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + + private val replaceHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun replace( + params: TemplateReplaceParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("templateId", params.templateId().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.PUT) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments( + "tenants", + params._pathParam(0), + "templates", + params._pathParam(1), + ) + .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() + } + } + } + } } } diff --git a/courier-java-core/src/main/kotlin/com/courier/services/blocking/tenants/templates/VersionService.kt b/courier-java-core/src/main/kotlin/com/courier/services/blocking/tenants/templates/VersionService.kt new file mode 100644 index 00000000..bd8e9493 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/services/blocking/tenants/templates/VersionService.kt @@ -0,0 +1,100 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.services.blocking.tenants.templates + +import com.courier.core.ClientOptions +import com.courier.core.RequestOptions +import com.courier.core.http.HttpResponseFor +import com.courier.models.tenants.BaseTemplateTenantAssociation +import com.courier.models.tenants.templates.versions.VersionRetrieveParams +import com.google.errorprone.annotations.MustBeClosed +import java.util.function.Consumer + +interface VersionService { + + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + + /** + * Returns a view of this service with the given option modifications applied. + * + * The original service is not modified. + */ + fun withOptions(modifier: Consumer): VersionService + + /** + * Fetches a specific version of a tenant template. + * + * Supports the following version formats: + * - `latest` - The most recent version of the template + * - `published` - The currently published version + * - `v{version}` - A specific version (e.g., "v1", "v2", "v1.0.0") + */ + fun retrieve(version: String, params: VersionRetrieveParams): BaseTemplateTenantAssociation = + retrieve(version, params, RequestOptions.none()) + + /** @see retrieve */ + fun retrieve( + version: String, + params: VersionRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): BaseTemplateTenantAssociation = + retrieve(params.toBuilder().version(version).build(), requestOptions) + + /** @see retrieve */ + fun retrieve(params: VersionRetrieveParams): BaseTemplateTenantAssociation = + retrieve(params, RequestOptions.none()) + + /** @see retrieve */ + fun retrieve( + params: VersionRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): BaseTemplateTenantAssociation + + /** A view of [VersionService] that provides access to raw HTTP responses for each method. */ + interface WithRawResponse { + + /** + * Returns a view of this service with the given option modifications applied. + * + * The original service is not modified. + */ + fun withOptions(modifier: Consumer): VersionService.WithRawResponse + + /** + * Returns a raw HTTP response for `get + * /tenants/{tenant_id}/templates/{template_id}/versions/{version}`, but is otherwise the + * same as [VersionService.retrieve]. + */ + @MustBeClosed + fun retrieve( + version: String, + params: VersionRetrieveParams, + ): HttpResponseFor = + retrieve(version, params, RequestOptions.none()) + + /** @see retrieve */ + @MustBeClosed + fun retrieve( + version: String, + params: VersionRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + retrieve(params.toBuilder().version(version).build(), requestOptions) + + /** @see retrieve */ + @MustBeClosed + fun retrieve( + params: VersionRetrieveParams + ): HttpResponseFor = retrieve(params, RequestOptions.none()) + + /** @see retrieve */ + @MustBeClosed + fun retrieve( + params: VersionRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + } +} diff --git a/courier-java-core/src/main/kotlin/com/courier/services/blocking/tenants/templates/VersionServiceImpl.kt b/courier-java-core/src/main/kotlin/com/courier/services/blocking/tenants/templates/VersionServiceImpl.kt new file mode 100644 index 00000000..e972beab --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/services/blocking/tenants/templates/VersionServiceImpl.kt @@ -0,0 +1,92 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.services.blocking.tenants.templates + +import com.courier.core.ClientOptions +import com.courier.core.RequestOptions +import com.courier.core.checkRequired +import com.courier.core.handlers.errorBodyHandler +import com.courier.core.handlers.errorHandler +import com.courier.core.handlers.jsonHandler +import com.courier.core.http.HttpMethod +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.parseable +import com.courier.core.prepare +import com.courier.models.tenants.BaseTemplateTenantAssociation +import com.courier.models.tenants.templates.versions.VersionRetrieveParams +import java.util.function.Consumer +import kotlin.jvm.optionals.getOrNull + +class VersionServiceImpl internal constructor(private val clientOptions: ClientOptions) : + VersionService { + + private val withRawResponse: VersionService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): VersionService.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): VersionService = + VersionServiceImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun retrieve( + params: VersionRetrieveParams, + requestOptions: RequestOptions, + ): BaseTemplateTenantAssociation = + // get /tenants/{tenant_id}/templates/{template_id}/versions/{version} + withRawResponse().retrieve(params, requestOptions).parse() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + VersionService.WithRawResponse { + + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + + override fun withOptions( + modifier: Consumer + ): VersionService.WithRawResponse = + VersionServiceImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun retrieve( + params: VersionRetrieveParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("version", params.version().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments( + "tenants", + params._pathParam(0), + "templates", + params._pathParam(1), + "versions", + params._pathParam(2), + ) + .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() + } + } + } + } + } +} diff --git a/courier-java-core/src/test/kotlin/com/courier/models/tenants/PostTenantTemplatePublishRequestTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/tenants/PostTenantTemplatePublishRequestTest.kt new file mode 100644 index 00000000..5fdfb090 --- /dev/null +++ b/courier-java-core/src/test/kotlin/com/courier/models/tenants/PostTenantTemplatePublishRequestTest.kt @@ -0,0 +1,35 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.tenants + +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 PostTenantTemplatePublishRequestTest { + + @Test + fun create() { + val postTenantTemplatePublishRequest = + PostTenantTemplatePublishRequest.builder().version("version").build() + + assertThat(postTenantTemplatePublishRequest.version()).contains("version") + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val postTenantTemplatePublishRequest = + PostTenantTemplatePublishRequest.builder().version("version").build() + + val roundtrippedPostTenantTemplatePublishRequest = + jsonMapper.readValue( + jsonMapper.writeValueAsString(postTenantTemplatePublishRequest), + jacksonTypeRef(), + ) + + assertThat(roundtrippedPostTenantTemplatePublishRequest) + .isEqualTo(postTenantTemplatePublishRequest) + } +} diff --git a/courier-java-core/src/test/kotlin/com/courier/models/tenants/PostTenantTemplatePublishResponseTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/tenants/PostTenantTemplatePublishResponseTest.kt new file mode 100644 index 00000000..fdc140e0 --- /dev/null +++ b/courier-java-core/src/test/kotlin/com/courier/models/tenants/PostTenantTemplatePublishResponseTest.kt @@ -0,0 +1,45 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.tenants + +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 PostTenantTemplatePublishResponseTest { + + @Test + fun create() { + val postTenantTemplatePublishResponse = + PostTenantTemplatePublishResponse.builder() + .id("id") + .publishedAt("published_at") + .version("version") + .build() + + assertThat(postTenantTemplatePublishResponse.id()).isEqualTo("id") + assertThat(postTenantTemplatePublishResponse.publishedAt()).isEqualTo("published_at") + assertThat(postTenantTemplatePublishResponse.version()).isEqualTo("version") + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val postTenantTemplatePublishResponse = + PostTenantTemplatePublishResponse.builder() + .id("id") + .publishedAt("published_at") + .version("version") + .build() + + val roundtrippedPostTenantTemplatePublishResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(postTenantTemplatePublishResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedPostTenantTemplatePublishResponse) + .isEqualTo(postTenantTemplatePublishResponse) + } +} diff --git a/courier-java-core/src/test/kotlin/com/courier/models/tenants/PutTenantTemplateRequestTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/tenants/PutTenantTemplateRequestTest.kt new file mode 100644 index 00000000..622c096b --- /dev/null +++ b/courier-java-core/src/test/kotlin/com/courier/models/tenants/PutTenantTemplateRequestTest.kt @@ -0,0 +1,277 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.tenants + +import com.courier.core.JsonValue +import com.courier.core.jsonMapper +import com.courier.models.ElementalContent +import com.courier.models.ElementalTextNodeWithType +import com.courier.models.MessageRouting +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class PutTenantTemplateRequestTest { + + @Test + fun create() { + val putTenantTemplateRequest = + PutTenantTemplateRequest.builder() + .template( + TenantTemplateInput.builder() + .content( + ElementalContent.builder() + .addElement( + ElementalTextNodeWithType.builder() + .addChannel("string") + .if_("if") + .loop("loop") + .ref("ref") + .type(ElementalTextNodeWithType.Type.TEXT) + .build() + ) + .version("version") + .brand("brand") + .build() + ) + .channels( + TenantTemplateInput.Channels.builder() + .putAdditionalProperty( + "foo", + JsonValue.from( + mapOf( + "brand_id" to "brand_id", + "if" to "if", + "metadata" to + mapOf( + "utm" to + mapOf( + "campaign" to "campaign", + "content" to "content", + "medium" to "medium", + "source" to "source", + "term" to "term", + ) + ), + "override" to mapOf("foo" to "bar"), + "providers" to listOf("string"), + "routing_method" to "all", + "timeouts" to mapOf("channel" to 0, "provider" to 0), + ) + ), + ) + .build() + ) + .providers( + TenantTemplateInput.Providers.builder() + .putAdditionalProperty( + "foo", + JsonValue.from( + mapOf( + "if" to "if", + "metadata" to + mapOf( + "utm" to + mapOf( + "campaign" to "campaign", + "content" to "content", + "medium" to "medium", + "source" to "source", + "term" to "term", + ) + ), + "override" to mapOf("foo" to "bar"), + "timeouts" to 0, + ) + ), + ) + .build() + ) + .routing( + MessageRouting.builder() + .addChannel("string") + .method(MessageRouting.Method.ALL) + .build() + ) + .build() + ) + .published(true) + .build() + + assertThat(putTenantTemplateRequest.template()) + .isEqualTo( + TenantTemplateInput.builder() + .content( + ElementalContent.builder() + .addElement( + ElementalTextNodeWithType.builder() + .addChannel("string") + .if_("if") + .loop("loop") + .ref("ref") + .type(ElementalTextNodeWithType.Type.TEXT) + .build() + ) + .version("version") + .brand("brand") + .build() + ) + .channels( + TenantTemplateInput.Channels.builder() + .putAdditionalProperty( + "foo", + JsonValue.from( + mapOf( + "brand_id" to "brand_id", + "if" to "if", + "metadata" to + mapOf( + "utm" to + mapOf( + "campaign" to "campaign", + "content" to "content", + "medium" to "medium", + "source" to "source", + "term" to "term", + ) + ), + "override" to mapOf("foo" to "bar"), + "providers" to listOf("string"), + "routing_method" to "all", + "timeouts" to mapOf("channel" to 0, "provider" to 0), + ) + ), + ) + .build() + ) + .providers( + TenantTemplateInput.Providers.builder() + .putAdditionalProperty( + "foo", + JsonValue.from( + mapOf( + "if" to "if", + "metadata" to + mapOf( + "utm" to + mapOf( + "campaign" to "campaign", + "content" to "content", + "medium" to "medium", + "source" to "source", + "term" to "term", + ) + ), + "override" to mapOf("foo" to "bar"), + "timeouts" to 0, + ) + ), + ) + .build() + ) + .routing( + MessageRouting.builder() + .addChannel("string") + .method(MessageRouting.Method.ALL) + .build() + ) + .build() + ) + assertThat(putTenantTemplateRequest.published()).contains(true) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val putTenantTemplateRequest = + PutTenantTemplateRequest.builder() + .template( + TenantTemplateInput.builder() + .content( + ElementalContent.builder() + .addElement( + ElementalTextNodeWithType.builder() + .addChannel("string") + .if_("if") + .loop("loop") + .ref("ref") + .type(ElementalTextNodeWithType.Type.TEXT) + .build() + ) + .version("version") + .brand("brand") + .build() + ) + .channels( + TenantTemplateInput.Channels.builder() + .putAdditionalProperty( + "foo", + JsonValue.from( + mapOf( + "brand_id" to "brand_id", + "if" to "if", + "metadata" to + mapOf( + "utm" to + mapOf( + "campaign" to "campaign", + "content" to "content", + "medium" to "medium", + "source" to "source", + "term" to "term", + ) + ), + "override" to mapOf("foo" to "bar"), + "providers" to listOf("string"), + "routing_method" to "all", + "timeouts" to mapOf("channel" to 0, "provider" to 0), + ) + ), + ) + .build() + ) + .providers( + TenantTemplateInput.Providers.builder() + .putAdditionalProperty( + "foo", + JsonValue.from( + mapOf( + "if" to "if", + "metadata" to + mapOf( + "utm" to + mapOf( + "campaign" to "campaign", + "content" to "content", + "medium" to "medium", + "source" to "source", + "term" to "term", + ) + ), + "override" to mapOf("foo" to "bar"), + "timeouts" to 0, + ) + ), + ) + .build() + ) + .routing( + MessageRouting.builder() + .addChannel("string") + .method(MessageRouting.Method.ALL) + .build() + ) + .build() + ) + .published(true) + .build() + + val roundtrippedPutTenantTemplateRequest = + jsonMapper.readValue( + jsonMapper.writeValueAsString(putTenantTemplateRequest), + jacksonTypeRef(), + ) + + assertThat(roundtrippedPutTenantTemplateRequest).isEqualTo(putTenantTemplateRequest) + } +} diff --git a/courier-java-core/src/test/kotlin/com/courier/models/tenants/PutTenantTemplateResponseTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/tenants/PutTenantTemplateResponseTest.kt new file mode 100644 index 00000000..92e0ded5 --- /dev/null +++ b/courier-java-core/src/test/kotlin/com/courier/models/tenants/PutTenantTemplateResponseTest.kt @@ -0,0 +1,44 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.tenants + +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 PutTenantTemplateResponseTest { + + @Test + fun create() { + val putTenantTemplateResponse = + PutTenantTemplateResponse.builder() + .id("id") + .version("version") + .publishedAt("published_at") + .build() + + assertThat(putTenantTemplateResponse.id()).isEqualTo("id") + assertThat(putTenantTemplateResponse.version()).isEqualTo("version") + assertThat(putTenantTemplateResponse.publishedAt()).contains("published_at") + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val putTenantTemplateResponse = + PutTenantTemplateResponse.builder() + .id("id") + .version("version") + .publishedAt("published_at") + .build() + + val roundtrippedPutTenantTemplateResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(putTenantTemplateResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedPutTenantTemplateResponse).isEqualTo(putTenantTemplateResponse) + } +} diff --git a/courier-java-core/src/test/kotlin/com/courier/models/tenants/TenantTemplateInputTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/tenants/TenantTemplateInputTest.kt new file mode 100644 index 00000000..2d4ec449 --- /dev/null +++ b/courier-java-core/src/test/kotlin/com/courier/models/tenants/TenantTemplateInputTest.kt @@ -0,0 +1,265 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.tenants + +import com.courier.core.JsonValue +import com.courier.core.jsonMapper +import com.courier.models.ElementalContent +import com.courier.models.ElementalTextNodeWithType +import com.courier.models.MessageRouting +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class TenantTemplateInputTest { + + @Test + fun create() { + val tenantTemplateInput = + TenantTemplateInput.builder() + .content( + ElementalContent.builder() + .addElement( + ElementalTextNodeWithType.builder() + .addChannel("string") + .if_("if") + .loop("loop") + .ref("ref") + .type(ElementalTextNodeWithType.Type.TEXT) + .build() + ) + .version("version") + .brand("brand") + .build() + ) + .channels( + TenantTemplateInput.Channels.builder() + .putAdditionalProperty( + "foo", + JsonValue.from( + mapOf( + "brand_id" to "brand_id", + "if" to "if", + "metadata" to + mapOf( + "utm" to + mapOf( + "campaign" to "campaign", + "content" to "content", + "medium" to "medium", + "source" to "source", + "term" to "term", + ) + ), + "override" to mapOf("foo" to "bar"), + "providers" to listOf("string"), + "routing_method" to "all", + "timeouts" to mapOf("channel" to 0, "provider" to 0), + ) + ), + ) + .build() + ) + .providers( + TenantTemplateInput.Providers.builder() + .putAdditionalProperty( + "foo", + JsonValue.from( + mapOf( + "if" to "if", + "metadata" to + mapOf( + "utm" to + mapOf( + "campaign" to "campaign", + "content" to "content", + "medium" to "medium", + "source" to "source", + "term" to "term", + ) + ), + "override" to mapOf("foo" to "bar"), + "timeouts" to 0, + ) + ), + ) + .build() + ) + .routing( + MessageRouting.builder() + .addChannel("string") + .method(MessageRouting.Method.ALL) + .build() + ) + .build() + + assertThat(tenantTemplateInput.content()) + .isEqualTo( + ElementalContent.builder() + .addElement( + ElementalTextNodeWithType.builder() + .addChannel("string") + .if_("if") + .loop("loop") + .ref("ref") + .type(ElementalTextNodeWithType.Type.TEXT) + .build() + ) + .version("version") + .brand("brand") + .build() + ) + assertThat(tenantTemplateInput.channels()) + .contains( + TenantTemplateInput.Channels.builder() + .putAdditionalProperty( + "foo", + JsonValue.from( + mapOf( + "brand_id" to "brand_id", + "if" to "if", + "metadata" to + mapOf( + "utm" to + mapOf( + "campaign" to "campaign", + "content" to "content", + "medium" to "medium", + "source" to "source", + "term" to "term", + ) + ), + "override" to mapOf("foo" to "bar"), + "providers" to listOf("string"), + "routing_method" to "all", + "timeouts" to mapOf("channel" to 0, "provider" to 0), + ) + ), + ) + .build() + ) + assertThat(tenantTemplateInput.providers()) + .contains( + TenantTemplateInput.Providers.builder() + .putAdditionalProperty( + "foo", + JsonValue.from( + mapOf( + "if" to "if", + "metadata" to + mapOf( + "utm" to + mapOf( + "campaign" to "campaign", + "content" to "content", + "medium" to "medium", + "source" to "source", + "term" to "term", + ) + ), + "override" to mapOf("foo" to "bar"), + "timeouts" to 0, + ) + ), + ) + .build() + ) + assertThat(tenantTemplateInput.routing()) + .contains( + MessageRouting.builder() + .addChannel("string") + .method(MessageRouting.Method.ALL) + .build() + ) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val tenantTemplateInput = + TenantTemplateInput.builder() + .content( + ElementalContent.builder() + .addElement( + ElementalTextNodeWithType.builder() + .addChannel("string") + .if_("if") + .loop("loop") + .ref("ref") + .type(ElementalTextNodeWithType.Type.TEXT) + .build() + ) + .version("version") + .brand("brand") + .build() + ) + .channels( + TenantTemplateInput.Channels.builder() + .putAdditionalProperty( + "foo", + JsonValue.from( + mapOf( + "brand_id" to "brand_id", + "if" to "if", + "metadata" to + mapOf( + "utm" to + mapOf( + "campaign" to "campaign", + "content" to "content", + "medium" to "medium", + "source" to "source", + "term" to "term", + ) + ), + "override" to mapOf("foo" to "bar"), + "providers" to listOf("string"), + "routing_method" to "all", + "timeouts" to mapOf("channel" to 0, "provider" to 0), + ) + ), + ) + .build() + ) + .providers( + TenantTemplateInput.Providers.builder() + .putAdditionalProperty( + "foo", + JsonValue.from( + mapOf( + "if" to "if", + "metadata" to + mapOf( + "utm" to + mapOf( + "campaign" to "campaign", + "content" to "content", + "medium" to "medium", + "source" to "source", + "term" to "term", + ) + ), + "override" to mapOf("foo" to "bar"), + "timeouts" to 0, + ) + ), + ) + .build() + ) + .routing( + MessageRouting.builder() + .addChannel("string") + .method(MessageRouting.Method.ALL) + .build() + ) + .build() + + val roundtrippedTenantTemplateInput = + jsonMapper.readValue( + jsonMapper.writeValueAsString(tenantTemplateInput), + jacksonTypeRef(), + ) + + assertThat(roundtrippedTenantTemplateInput).isEqualTo(tenantTemplateInput) + } +} diff --git a/courier-java-core/src/test/kotlin/com/courier/models/tenants/templates/TemplatePublishParamsTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/tenants/templates/TemplatePublishParamsTest.kt new file mode 100644 index 00000000..cdc9ba22 --- /dev/null +++ b/courier-java-core/src/test/kotlin/com/courier/models/tenants/templates/TemplatePublishParamsTest.kt @@ -0,0 +1,58 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.tenants.templates + +import com.courier.models.tenants.PostTenantTemplatePublishRequest +import kotlin.jvm.optionals.getOrNull +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class TemplatePublishParamsTest { + + @Test + fun create() { + TemplatePublishParams.builder() + .tenantId("tenant_id") + .templateId("template_id") + .postTenantTemplatePublishRequest( + PostTenantTemplatePublishRequest.builder().version("version").build() + ) + .build() + } + + @Test + fun pathParams() { + val params = + TemplatePublishParams.builder().tenantId("tenant_id").templateId("template_id").build() + + assertThat(params._pathParam(0)).isEqualTo("tenant_id") + assertThat(params._pathParam(1)).isEqualTo("template_id") + // out-of-bound path param + assertThat(params._pathParam(2)).isEqualTo("") + } + + @Test + fun body() { + val params = + TemplatePublishParams.builder() + .tenantId("tenant_id") + .templateId("template_id") + .postTenantTemplatePublishRequest( + PostTenantTemplatePublishRequest.builder().version("version").build() + ) + .build() + + val body = params._body().getOrNull() + + assertThat(body) + .isEqualTo(PostTenantTemplatePublishRequest.builder().version("version").build()) + } + + @Test + fun bodyWithoutOptionalFields() { + val params = + TemplatePublishParams.builder().tenantId("tenant_id").templateId("template_id").build() + + val body = params._body().getOrNull() + } +} diff --git a/courier-java-core/src/test/kotlin/com/courier/models/tenants/templates/TemplateReplaceParamsTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/tenants/templates/TemplateReplaceParamsTest.kt new file mode 100644 index 00000000..63c580af --- /dev/null +++ b/courier-java-core/src/test/kotlin/com/courier/models/tenants/templates/TemplateReplaceParamsTest.kt @@ -0,0 +1,355 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.tenants.templates + +import com.courier.core.JsonValue +import com.courier.models.ElementalContent +import com.courier.models.ElementalTextNodeWithType +import com.courier.models.MessageRouting +import com.courier.models.tenants.PutTenantTemplateRequest +import com.courier.models.tenants.TenantTemplateInput +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class TemplateReplaceParamsTest { + + @Test + fun create() { + TemplateReplaceParams.builder() + .tenantId("tenant_id") + .templateId("template_id") + .putTenantTemplateRequest( + PutTenantTemplateRequest.builder() + .template( + TenantTemplateInput.builder() + .content( + ElementalContent.builder() + .addElement( + ElementalTextNodeWithType.builder() + .addChannel("string") + .if_("if") + .loop("loop") + .ref("ref") + .type(ElementalTextNodeWithType.Type.TEXT) + .build() + ) + .version("version") + .brand("brand") + .build() + ) + .channels( + TenantTemplateInput.Channels.builder() + .putAdditionalProperty( + "foo", + JsonValue.from( + mapOf( + "brand_id" to "brand_id", + "if" to "if", + "metadata" to + mapOf( + "utm" to + mapOf( + "campaign" to "campaign", + "content" to "content", + "medium" to "medium", + "source" to "source", + "term" to "term", + ) + ), + "override" to mapOf("foo" to "bar"), + "providers" to listOf("string"), + "routing_method" to "all", + "timeouts" to mapOf("channel" to 0, "provider" to 0), + ) + ), + ) + .build() + ) + .providers( + TenantTemplateInput.Providers.builder() + .putAdditionalProperty( + "foo", + JsonValue.from( + mapOf( + "if" to "if", + "metadata" to + mapOf( + "utm" to + mapOf( + "campaign" to "campaign", + "content" to "content", + "medium" to "medium", + "source" to "source", + "term" to "term", + ) + ), + "override" to mapOf("foo" to "bar"), + "timeouts" to 0, + ) + ), + ) + .build() + ) + .routing( + MessageRouting.builder() + .addChannel("string") + .method(MessageRouting.Method.ALL) + .build() + ) + .build() + ) + .published(true) + .build() + ) + .build() + } + + @Test + fun pathParams() { + val params = + TemplateReplaceParams.builder() + .tenantId("tenant_id") + .templateId("template_id") + .putTenantTemplateRequest( + PutTenantTemplateRequest.builder() + .template( + TenantTemplateInput.builder() + .content( + ElementalContent.builder() + .addElement(ElementalTextNodeWithType.builder().build()) + .version("version") + .build() + ) + .build() + ) + .build() + ) + .build() + + assertThat(params._pathParam(0)).isEqualTo("tenant_id") + assertThat(params._pathParam(1)).isEqualTo("template_id") + // out-of-bound path param + assertThat(params._pathParam(2)).isEqualTo("") + } + + @Test + fun body() { + val params = + TemplateReplaceParams.builder() + .tenantId("tenant_id") + .templateId("template_id") + .putTenantTemplateRequest( + PutTenantTemplateRequest.builder() + .template( + TenantTemplateInput.builder() + .content( + ElementalContent.builder() + .addElement( + ElementalTextNodeWithType.builder() + .addChannel("string") + .if_("if") + .loop("loop") + .ref("ref") + .type(ElementalTextNodeWithType.Type.TEXT) + .build() + ) + .version("version") + .brand("brand") + .build() + ) + .channels( + TenantTemplateInput.Channels.builder() + .putAdditionalProperty( + "foo", + JsonValue.from( + mapOf( + "brand_id" to "brand_id", + "if" to "if", + "metadata" to + mapOf( + "utm" to + mapOf( + "campaign" to "campaign", + "content" to "content", + "medium" to "medium", + "source" to "source", + "term" to "term", + ) + ), + "override" to mapOf("foo" to "bar"), + "providers" to listOf("string"), + "routing_method" to "all", + "timeouts" to + mapOf("channel" to 0, "provider" to 0), + ) + ), + ) + .build() + ) + .providers( + TenantTemplateInput.Providers.builder() + .putAdditionalProperty( + "foo", + JsonValue.from( + mapOf( + "if" to "if", + "metadata" to + mapOf( + "utm" to + mapOf( + "campaign" to "campaign", + "content" to "content", + "medium" to "medium", + "source" to "source", + "term" to "term", + ) + ), + "override" to mapOf("foo" to "bar"), + "timeouts" to 0, + ) + ), + ) + .build() + ) + .routing( + MessageRouting.builder() + .addChannel("string") + .method(MessageRouting.Method.ALL) + .build() + ) + .build() + ) + .published(true) + .build() + ) + .build() + + val body = params._body() + + assertThat(body) + .isEqualTo( + PutTenantTemplateRequest.builder() + .template( + TenantTemplateInput.builder() + .content( + ElementalContent.builder() + .addElement( + ElementalTextNodeWithType.builder() + .addChannel("string") + .if_("if") + .loop("loop") + .ref("ref") + .type(ElementalTextNodeWithType.Type.TEXT) + .build() + ) + .version("version") + .brand("brand") + .build() + ) + .channels( + TenantTemplateInput.Channels.builder() + .putAdditionalProperty( + "foo", + JsonValue.from( + mapOf( + "brand_id" to "brand_id", + "if" to "if", + "metadata" to + mapOf( + "utm" to + mapOf( + "campaign" to "campaign", + "content" to "content", + "medium" to "medium", + "source" to "source", + "term" to "term", + ) + ), + "override" to mapOf("foo" to "bar"), + "providers" to listOf("string"), + "routing_method" to "all", + "timeouts" to mapOf("channel" to 0, "provider" to 0), + ) + ), + ) + .build() + ) + .providers( + TenantTemplateInput.Providers.builder() + .putAdditionalProperty( + "foo", + JsonValue.from( + mapOf( + "if" to "if", + "metadata" to + mapOf( + "utm" to + mapOf( + "campaign" to "campaign", + "content" to "content", + "medium" to "medium", + "source" to "source", + "term" to "term", + ) + ), + "override" to mapOf("foo" to "bar"), + "timeouts" to 0, + ) + ), + ) + .build() + ) + .routing( + MessageRouting.builder() + .addChannel("string") + .method(MessageRouting.Method.ALL) + .build() + ) + .build() + ) + .published(true) + .build() + ) + } + + @Test + fun bodyWithoutOptionalFields() { + val params = + TemplateReplaceParams.builder() + .tenantId("tenant_id") + .templateId("template_id") + .putTenantTemplateRequest( + PutTenantTemplateRequest.builder() + .template( + TenantTemplateInput.builder() + .content( + ElementalContent.builder() + .addElement(ElementalTextNodeWithType.builder().build()) + .version("version") + .build() + ) + .build() + ) + .build() + ) + .build() + + val body = params._body() + + assertThat(body) + .isEqualTo( + PutTenantTemplateRequest.builder() + .template( + TenantTemplateInput.builder() + .content( + ElementalContent.builder() + .addElement(ElementalTextNodeWithType.builder().build()) + .version("version") + .build() + ) + .build() + ) + .build() + ) + } +} diff --git a/courier-java-core/src/test/kotlin/com/courier/models/tenants/templates/versions/VersionRetrieveParamsTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/tenants/templates/versions/VersionRetrieveParamsTest.kt new file mode 100644 index 00000000..d98f9582 --- /dev/null +++ b/courier-java-core/src/test/kotlin/com/courier/models/tenants/templates/versions/VersionRetrieveParamsTest.kt @@ -0,0 +1,34 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.tenants.templates.versions + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class VersionRetrieveParamsTest { + + @Test + fun create() { + VersionRetrieveParams.builder() + .tenantId("tenant_id") + .templateId("template_id") + .version("version") + .build() + } + + @Test + fun pathParams() { + val params = + VersionRetrieveParams.builder() + .tenantId("tenant_id") + .templateId("template_id") + .version("version") + .build() + + assertThat(params._pathParam(0)).isEqualTo("tenant_id") + assertThat(params._pathParam(1)).isEqualTo("template_id") + assertThat(params._pathParam(2)).isEqualTo("version") + // out-of-bound path param + assertThat(params._pathParam(3)).isEqualTo("") + } +} diff --git a/courier-java-core/src/test/kotlin/com/courier/services/async/tenants/TemplateServiceAsyncTest.kt b/courier-java-core/src/test/kotlin/com/courier/services/async/tenants/TemplateServiceAsyncTest.kt index e4b8a8ae..624ac794 100644 --- a/courier-java-core/src/test/kotlin/com/courier/services/async/tenants/TemplateServiceAsyncTest.kt +++ b/courier-java-core/src/test/kotlin/com/courier/services/async/tenants/TemplateServiceAsyncTest.kt @@ -4,7 +4,16 @@ package com.courier.services.async.tenants import com.courier.TestServerExtension import com.courier.client.okhttp.CourierOkHttpClientAsync +import com.courier.core.JsonValue +import com.courier.models.ElementalContent +import com.courier.models.ElementalTextNodeWithType +import com.courier.models.MessageRouting +import com.courier.models.tenants.PostTenantTemplatePublishRequest +import com.courier.models.tenants.PutTenantTemplateRequest +import com.courier.models.tenants.TenantTemplateInput import com.courier.models.tenants.templates.TemplateListParams +import com.courier.models.tenants.templates.TemplatePublishParams +import com.courier.models.tenants.templates.TemplateReplaceParams import com.courier.models.tenants.templates.TemplateRetrieveParams import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test @@ -57,4 +66,135 @@ internal class TemplateServiceAsyncTest { val templates = templatesFuture.get() templates.validate() } + + @Disabled("Prism tests are disabled") + @Test + fun publish() { + val client = + CourierOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val templateServiceAsync = client.tenants().templates() + + val postTenantTemplatePublishResponseFuture = + templateServiceAsync.publish( + TemplatePublishParams.builder() + .tenantId("tenant_id") + .templateId("template_id") + .postTenantTemplatePublishRequest( + PostTenantTemplatePublishRequest.builder().version("version").build() + ) + .build() + ) + + val postTenantTemplatePublishResponse = postTenantTemplatePublishResponseFuture.get() + postTenantTemplatePublishResponse.validate() + } + + @Disabled("Prism tests are disabled") + @Test + fun replace() { + val client = + CourierOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val templateServiceAsync = client.tenants().templates() + + val putTenantTemplateResponseFuture = + templateServiceAsync.replace( + TemplateReplaceParams.builder() + .tenantId("tenant_id") + .templateId("template_id") + .putTenantTemplateRequest( + PutTenantTemplateRequest.builder() + .template( + TenantTemplateInput.builder() + .content( + ElementalContent.builder() + .addElement( + ElementalTextNodeWithType.builder() + .addChannel("string") + .if_("if") + .loop("loop") + .ref("ref") + .type(ElementalTextNodeWithType.Type.TEXT) + .build() + ) + .version("version") + .brand("brand") + .build() + ) + .channels( + TenantTemplateInput.Channels.builder() + .putAdditionalProperty( + "foo", + JsonValue.from( + mapOf( + "brand_id" to "brand_id", + "if" to "if", + "metadata" to + mapOf( + "utm" to + mapOf( + "campaign" to "campaign", + "content" to "content", + "medium" to "medium", + "source" to "source", + "term" to "term", + ) + ), + "override" to mapOf("foo" to "bar"), + "providers" to listOf("string"), + "routing_method" to "all", + "timeouts" to + mapOf("channel" to 0, "provider" to 0), + ) + ), + ) + .build() + ) + .providers( + TenantTemplateInput.Providers.builder() + .putAdditionalProperty( + "foo", + JsonValue.from( + mapOf( + "if" to "if", + "metadata" to + mapOf( + "utm" to + mapOf( + "campaign" to "campaign", + "content" to "content", + "medium" to "medium", + "source" to "source", + "term" to "term", + ) + ), + "override" to mapOf("foo" to "bar"), + "timeouts" to 0, + ) + ), + ) + .build() + ) + .routing( + MessageRouting.builder() + .addChannel("string") + .method(MessageRouting.Method.ALL) + .build() + ) + .build() + ) + .published(true) + .build() + ) + .build() + ) + + val putTenantTemplateResponse = putTenantTemplateResponseFuture.get() + putTenantTemplateResponse.validate() + } } diff --git a/courier-java-core/src/test/kotlin/com/courier/services/async/tenants/templates/VersionServiceAsyncTest.kt b/courier-java-core/src/test/kotlin/com/courier/services/async/tenants/templates/VersionServiceAsyncTest.kt new file mode 100644 index 00000000..b0b24a8a --- /dev/null +++ b/courier-java-core/src/test/kotlin/com/courier/services/async/tenants/templates/VersionServiceAsyncTest.kt @@ -0,0 +1,37 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.services.async.tenants.templates + +import com.courier.TestServerExtension +import com.courier.client.okhttp.CourierOkHttpClientAsync +import com.courier.models.tenants.templates.versions.VersionRetrieveParams +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class VersionServiceAsyncTest { + + @Disabled("Prism tests are disabled") + @Test + fun retrieve() { + val client = + CourierOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val versionServiceAsync = client.tenants().templates().versions() + + val baseTemplateTenantAssociationFuture = + versionServiceAsync.retrieve( + VersionRetrieveParams.builder() + .tenantId("tenant_id") + .templateId("template_id") + .version("version") + .build() + ) + + val baseTemplateTenantAssociation = baseTemplateTenantAssociationFuture.get() + baseTemplateTenantAssociation.validate() + } +} diff --git a/courier-java-core/src/test/kotlin/com/courier/services/blocking/tenants/TemplateServiceTest.kt b/courier-java-core/src/test/kotlin/com/courier/services/blocking/tenants/TemplateServiceTest.kt index 44e218a6..1c9f6df7 100644 --- a/courier-java-core/src/test/kotlin/com/courier/services/blocking/tenants/TemplateServiceTest.kt +++ b/courier-java-core/src/test/kotlin/com/courier/services/blocking/tenants/TemplateServiceTest.kt @@ -4,7 +4,16 @@ package com.courier.services.blocking.tenants import com.courier.TestServerExtension import com.courier.client.okhttp.CourierOkHttpClient +import com.courier.core.JsonValue +import com.courier.models.ElementalContent +import com.courier.models.ElementalTextNodeWithType +import com.courier.models.MessageRouting +import com.courier.models.tenants.PostTenantTemplatePublishRequest +import com.courier.models.tenants.PutTenantTemplateRequest +import com.courier.models.tenants.TenantTemplateInput import com.courier.models.tenants.templates.TemplateListParams +import com.courier.models.tenants.templates.TemplatePublishParams +import com.courier.models.tenants.templates.TemplateReplaceParams import com.courier.models.tenants.templates.TemplateRetrieveParams import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test @@ -55,4 +64,133 @@ internal class TemplateServiceTest { templates.validate() } + + @Disabled("Prism tests are disabled") + @Test + fun publish() { + val client = + CourierOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val templateService = client.tenants().templates() + + val postTenantTemplatePublishResponse = + templateService.publish( + TemplatePublishParams.builder() + .tenantId("tenant_id") + .templateId("template_id") + .postTenantTemplatePublishRequest( + PostTenantTemplatePublishRequest.builder().version("version").build() + ) + .build() + ) + + postTenantTemplatePublishResponse.validate() + } + + @Disabled("Prism tests are disabled") + @Test + fun replace() { + val client = + CourierOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val templateService = client.tenants().templates() + + val putTenantTemplateResponse = + templateService.replace( + TemplateReplaceParams.builder() + .tenantId("tenant_id") + .templateId("template_id") + .putTenantTemplateRequest( + PutTenantTemplateRequest.builder() + .template( + TenantTemplateInput.builder() + .content( + ElementalContent.builder() + .addElement( + ElementalTextNodeWithType.builder() + .addChannel("string") + .if_("if") + .loop("loop") + .ref("ref") + .type(ElementalTextNodeWithType.Type.TEXT) + .build() + ) + .version("version") + .brand("brand") + .build() + ) + .channels( + TenantTemplateInput.Channels.builder() + .putAdditionalProperty( + "foo", + JsonValue.from( + mapOf( + "brand_id" to "brand_id", + "if" to "if", + "metadata" to + mapOf( + "utm" to + mapOf( + "campaign" to "campaign", + "content" to "content", + "medium" to "medium", + "source" to "source", + "term" to "term", + ) + ), + "override" to mapOf("foo" to "bar"), + "providers" to listOf("string"), + "routing_method" to "all", + "timeouts" to + mapOf("channel" to 0, "provider" to 0), + ) + ), + ) + .build() + ) + .providers( + TenantTemplateInput.Providers.builder() + .putAdditionalProperty( + "foo", + JsonValue.from( + mapOf( + "if" to "if", + "metadata" to + mapOf( + "utm" to + mapOf( + "campaign" to "campaign", + "content" to "content", + "medium" to "medium", + "source" to "source", + "term" to "term", + ) + ), + "override" to mapOf("foo" to "bar"), + "timeouts" to 0, + ) + ), + ) + .build() + ) + .routing( + MessageRouting.builder() + .addChannel("string") + .method(MessageRouting.Method.ALL) + .build() + ) + .build() + ) + .published(true) + .build() + ) + .build() + ) + + putTenantTemplateResponse.validate() + } } diff --git a/courier-java-core/src/test/kotlin/com/courier/services/blocking/tenants/templates/VersionServiceTest.kt b/courier-java-core/src/test/kotlin/com/courier/services/blocking/tenants/templates/VersionServiceTest.kt new file mode 100644 index 00000000..a231cee9 --- /dev/null +++ b/courier-java-core/src/test/kotlin/com/courier/services/blocking/tenants/templates/VersionServiceTest.kt @@ -0,0 +1,36 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.services.blocking.tenants.templates + +import com.courier.TestServerExtension +import com.courier.client.okhttp.CourierOkHttpClient +import com.courier.models.tenants.templates.versions.VersionRetrieveParams +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class VersionServiceTest { + + @Disabled("Prism tests are disabled") + @Test + fun retrieve() { + val client = + CourierOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val versionService = client.tenants().templates().versions() + + val baseTemplateTenantAssociation = + versionService.retrieve( + VersionRetrieveParams.builder() + .tenantId("tenant_id") + .templateId("template_id") + .version("version") + .build() + ) + + baseTemplateTenantAssociation.validate() + } +} From 2024cc2803cdb17e1cf6e76653e7de8db1148b77 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 6 Feb 2026 18:58:52 +0000 Subject: [PATCH 4/4] release: 4.9.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 14 ++++++++++++++ README.md | 10 +++++----- build.gradle.kts | 2 +- 4 files changed, 21 insertions(+), 7 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 90eeef65..6b467676 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "4.8.0" + ".": "4.9.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 429953fe..5618fa3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # Changelog +## 4.9.0 (2026-02-06) + +Full Changelog: [v4.8.0...v4.9.0](https://github.com/trycourier/courier-java/compare/v4.8.0...v4.9.0) + +### Features + +* **api:** add publish/replace methods, versions resource to tenant templates ([41fbfe5](https://github.com/trycourier/courier-java/commit/41fbfe5dd327a8a142da5ac65ba72f777f9794a9)) +* **api:** add toOfRecipients method to send message ([35df215](https://github.com/trycourier/courier-java/commit/35df2154e48a5e158285cda871f506202d9199c6)) + + +### Chores + +* **internal:** allow passing args to `./scripts/test` ([a809582](https://github.com/trycourier/courier-java/commit/a8095821586036d00c3543929e6eef860fabdd3a)) + ## 4.8.0 (2026-01-27) Full Changelog: [v4.7.1...v4.8.0](https://github.com/trycourier/courier-java/compare/v4.7.1...v4.8.0) diff --git a/README.md b/README.md index a85bd3fe..689f7a57 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ -[![Maven Central](https://img.shields.io/maven-central/v/com.courier/courier-java)](https://central.sonatype.com/artifact/com.courier/courier-java/4.8.0) -[![javadoc](https://javadoc.io/badge2/com.courier/courier-java/4.8.0/javadoc.svg)](https://javadoc.io/doc/com.courier/courier-java/4.8.0) +[![Maven Central](https://img.shields.io/maven-central/v/com.courier/courier-java)](https://central.sonatype.com/artifact/com.courier/courier-java/4.9.0) +[![javadoc](https://javadoc.io/badge2/com.courier/courier-java/4.9.0/javadoc.svg)](https://javadoc.io/doc/com.courier/courier-java/4.9.0) @@ -13,7 +13,7 @@ It is generated with [Stainless](https://www.stainless.com/). -The REST API documentation can be found on [www.courier.com](https://www.courier.com/docs). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.courier/courier-java/4.8.0). +The REST API documentation can be found on [www.courier.com](https://www.courier.com/docs). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.courier/courier-java/4.9.0). @@ -24,7 +24,7 @@ The REST API documentation can be found on [www.courier.com](https://www.courier ### Gradle ```kotlin -implementation("com.courier:courier-java:4.8.0") +implementation("com.courier:courier-java:4.9.0") ``` ### Maven @@ -33,7 +33,7 @@ implementation("com.courier:courier-java:4.8.0") com.courier courier-java - 4.8.0 + 4.9.0 ``` diff --git a/build.gradle.kts b/build.gradle.kts index 3e741ebc..ca061824 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,7 +8,7 @@ repositories { allprojects { group = "com.courier" - version = "4.8.0" // x-release-please-version + version = "4.9.0" // x-release-please-version } subprojects {