diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 141929c0..f3ab3a80 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "4.25.0" + ".": "4.26.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 2b725395..6f303f16 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 145 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/courier/courier-9074e771bd8042233d1c6d73d11ea3c41ee63f3639119deae5dc3b7a5655e568.yml -openapi_spec_hash: f09e821d35afa0ad0117a1d8eb9d4d16 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/courier/courier-31abe25287f6885a9e18e84b9317abcb36a9fff5f694feb7a4353c5622d93730.yml +openapi_spec_hash: 65d48382e29817ef7b89e70b20bf8d4d config_hash: 3eb0070d128aef7a6da16173f7050177 diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b498870..dc09f8c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## 4.26.0 (2026-08-04) + +Full Changelog: [v4.25.0...v4.26.0](https://github.com/trycourier/courier-java/compare/v4.25.0...v4.26.0) + +### Features + +* Merge pull request [#178](https://github.com/trycourier/courier-java/issues/178) from trycourier/geraldosilva/c-19484-elemental-formatting-controls ([b101502](https://github.com/trycourier/courier-java/commit/b101502c679ded2342612293da4c8fec8574e1c2)) + + +### Chores + +* **internal:** codegen related update ([703b085](https://github.com/trycourier/courier-java/commit/703b085eb7aeb0ba0948849bb023a8fe7b9622da)) + ## 4.25.0 (2026-08-03) Full Changelog: [v4.24.0...v4.25.0](https://github.com/trycourier/courier-java/compare/v4.24.0...v4.25.0) diff --git a/build.gradle.kts b/build.gradle.kts index 0e254586..d0475401 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,7 +8,7 @@ repositories { allprojects { group = "com.courier" - version = "4.25.0" // x-release-please-version + version = "4.26.0" // x-release-please-version } subprojects { diff --git a/courier-java-core/src/main/kotlin/com/courier/models/ElementalChannelNode.kt b/courier-java-core/src/main/kotlin/com/courier/models/ElementalChannelNode.kt index b2c59726..7b156bde 100644 --- a/courier-java-core/src/main/kotlin/com/courier/models/ElementalChannelNode.kt +++ b/courier-java-core/src/main/kotlin/com/courier/models/ElementalChannelNode.kt @@ -37,6 +37,9 @@ private constructor( private val loop: JsonField, private val ref: JsonField, private val channel: JsonField, + private val fontSize: JsonField, + private val lineHeight: JsonField, + private val padding: JsonField, private val raw: JsonField, private val additionalProperties: MutableMap, ) { @@ -50,8 +53,13 @@ private constructor( @JsonProperty("loop") @ExcludeMissing loop: JsonField = JsonMissing.of(), @JsonProperty("ref") @ExcludeMissing ref: JsonField = JsonMissing.of(), @JsonProperty("channel") @ExcludeMissing channel: JsonField = JsonMissing.of(), + @JsonProperty("font_size") @ExcludeMissing fontSize: JsonField = JsonMissing.of(), + @JsonProperty("line_height") + @ExcludeMissing + lineHeight: JsonField = JsonMissing.of(), + @JsonProperty("padding") @ExcludeMissing padding: JsonField = JsonMissing.of(), @JsonProperty("raw") @ExcludeMissing raw: JsonField = JsonMissing.of(), - ) : this(channels, if_, loop, ref, channel, raw, mutableMapOf()) + ) : this(channels, if_, loop, ref, channel, fontSize, lineHeight, padding, raw, mutableMapOf()) fun toElementalBaseNode(): ElementalBaseNode = ElementalBaseNode.builder().channels(channels).if_(if_).loop(loop).ref(ref).build() @@ -89,6 +97,34 @@ private constructor( */ fun channel(): Optional = channel.getOptional("channel") + /** + * Email only. Document-level base font size (CSS px, e.g. `16px`) for body content — text, + * quote, list and action button labels. Heading styles (`h1`/`h2`/`h3`) and `subtext` keep + * their preset sizes. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun fontSize(): Optional = fontSize.getOptional("font_size") + + /** + * Email only. Document-level line height (CSS px or unitless multiplier, e.g. `24px` or `1.5`) + * applied to all body content unless overridden per block. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun lineHeight(): Optional = lineHeight.getOptional("line_height") + + /** + * Email only. Document-level body padding applied once around the email body, as a CSS px + * shorthand (1–4 values), e.g. `48px 64px`. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun padding(): Optional = padding.getOptional("padding") + /** * Raw data to apply to the channel. If `elements` has not been specified, `raw` is required. * @@ -132,6 +168,27 @@ private constructor( */ @JsonProperty("channel") @ExcludeMissing fun _channel(): JsonField = channel + /** + * Returns the raw JSON value of [fontSize]. + * + * Unlike [fontSize], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("font_size") @ExcludeMissing fun _fontSize(): JsonField = fontSize + + /** + * Returns the raw JSON value of [lineHeight]. + * + * Unlike [lineHeight], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("line_height") @ExcludeMissing fun _lineHeight(): JsonField = lineHeight + + /** + * Returns the raw JSON value of [padding]. + * + * Unlike [padding], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("padding") @ExcludeMissing fun _padding(): JsonField = padding + /** * Returns the raw JSON value of [raw]. * @@ -165,6 +222,9 @@ private constructor( private var loop: JsonField = JsonMissing.of() private var ref: JsonField = JsonMissing.of() private var channel: JsonField = JsonMissing.of() + private var fontSize: JsonField = JsonMissing.of() + private var lineHeight: JsonField = JsonMissing.of() + private var padding: JsonField = JsonMissing.of() private var raw: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @@ -175,6 +235,9 @@ private constructor( loop = elementalChannelNode.loop ref = elementalChannelNode.ref channel = elementalChannelNode.channel + fontSize = elementalChannelNode.fontSize + lineHeight = elementalChannelNode.lineHeight + padding = elementalChannelNode.padding raw = elementalChannelNode.raw additionalProperties = elementalChannelNode.additionalProperties.toMutableMap() } @@ -260,6 +323,59 @@ private constructor( */ fun channel(channel: JsonField) = apply { this.channel = channel } + /** + * Email only. Document-level base font size (CSS px, e.g. `16px`) for body content — text, + * quote, list and action button labels. Heading styles (`h1`/`h2`/`h3`) and `subtext` keep + * their preset sizes. + */ + fun fontSize(fontSize: String?) = fontSize(JsonField.ofNullable(fontSize)) + + /** Alias for calling [Builder.fontSize] with `fontSize.orElse(null)`. */ + fun fontSize(fontSize: Optional) = fontSize(fontSize.getOrNull()) + + /** + * Sets [Builder.fontSize] to an arbitrary JSON value. + * + * You should usually call [Builder.fontSize] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun fontSize(fontSize: JsonField) = apply { this.fontSize = fontSize } + + /** + * Email only. Document-level line height (CSS px or unitless multiplier, e.g. `24px` or + * `1.5`) applied to all body content unless overridden per block. + */ + fun lineHeight(lineHeight: String?) = lineHeight(JsonField.ofNullable(lineHeight)) + + /** Alias for calling [Builder.lineHeight] with `lineHeight.orElse(null)`. */ + fun lineHeight(lineHeight: Optional) = lineHeight(lineHeight.getOrNull()) + + /** + * Sets [Builder.lineHeight] to an arbitrary JSON value. + * + * You should usually call [Builder.lineHeight] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun lineHeight(lineHeight: JsonField) = apply { this.lineHeight = lineHeight } + + /** + * Email only. Document-level body padding applied once around the email body, as a CSS px + * shorthand (1–4 values), e.g. `48px 64px`. + */ + fun padding(padding: String?) = padding(JsonField.ofNullable(padding)) + + /** Alias for calling [Builder.padding] with `padding.orElse(null)`. */ + fun padding(padding: Optional) = padding(padding.getOrNull()) + + /** + * Sets [Builder.padding] to an arbitrary JSON value. + * + * You should usually call [Builder.padding] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun padding(padding: JsonField) = apply { this.padding = padding } + /** * Raw data to apply to the channel. If `elements` has not been specified, `raw` is * required. @@ -308,6 +424,9 @@ private constructor( loop, ref, channel, + fontSize, + lineHeight, + padding, raw, additionalProperties.toMutableMap(), ) @@ -333,6 +452,9 @@ private constructor( loop() ref() channel() + fontSize() + lineHeight() + padding() raw().ifPresent { it.validate() } validated = true } @@ -357,6 +479,9 @@ private constructor( (if (loop.asKnown().isPresent) 1 else 0) + (if (ref.asKnown().isPresent) 1 else 0) + (if (channel.asKnown().isPresent) 1 else 0) + + (if (fontSize.asKnown().isPresent) 1 else 0) + + (if (lineHeight.asKnown().isPresent) 1 else 0) + + (if (padding.asKnown().isPresent) 1 else 0) + (raw.asKnown().getOrNull()?.validity() ?: 0) /** @@ -481,16 +606,30 @@ private constructor( loop == other.loop && ref == other.ref && channel == other.channel && + fontSize == other.fontSize && + lineHeight == other.lineHeight && + padding == other.padding && raw == other.raw && additionalProperties == other.additionalProperties } private val hashCode: Int by lazy { - Objects.hash(channels, if_, loop, ref, channel, raw, additionalProperties) + Objects.hash( + channels, + if_, + loop, + ref, + channel, + fontSize, + lineHeight, + padding, + raw, + additionalProperties, + ) } override fun hashCode(): Int = hashCode override fun toString() = - "ElementalChannelNode{channels=$channels, if_=$if_, loop=$loop, ref=$ref, channel=$channel, raw=$raw, additionalProperties=$additionalProperties}" + "ElementalChannelNode{channels=$channels, if_=$if_, loop=$loop, ref=$ref, channel=$channel, fontSize=$fontSize, lineHeight=$lineHeight, padding=$padding, raw=$raw, additionalProperties=$additionalProperties}" } diff --git a/courier-java-core/src/main/kotlin/com/courier/models/ElementalChannelNodeWithType.kt b/courier-java-core/src/main/kotlin/com/courier/models/ElementalChannelNodeWithType.kt index 159bb5c7..93cb776a 100644 --- a/courier-java-core/src/main/kotlin/com/courier/models/ElementalChannelNodeWithType.kt +++ b/courier-java-core/src/main/kotlin/com/courier/models/ElementalChannelNodeWithType.kt @@ -38,6 +38,9 @@ private constructor( private val loop: JsonField, private val ref: JsonField, private val channel: JsonField, + private val fontSize: JsonField, + private val lineHeight: JsonField, + private val padding: JsonField, private val raw: JsonField, private val type: JsonField, private val additionalProperties: MutableMap, @@ -52,11 +55,28 @@ private constructor( @JsonProperty("loop") @ExcludeMissing loop: JsonField = JsonMissing.of(), @JsonProperty("ref") @ExcludeMissing ref: JsonField = JsonMissing.of(), @JsonProperty("channel") @ExcludeMissing channel: JsonField = JsonMissing.of(), + @JsonProperty("font_size") @ExcludeMissing fontSize: JsonField = JsonMissing.of(), + @JsonProperty("line_height") + @ExcludeMissing + lineHeight: JsonField = JsonMissing.of(), + @JsonProperty("padding") @ExcludeMissing padding: JsonField = JsonMissing.of(), @JsonProperty("raw") @ExcludeMissing raw: JsonField = JsonMissing.of(), @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), - ) : this(channels, if_, loop, ref, channel, raw, type, mutableMapOf()) + ) : this( + channels, + if_, + loop, + ref, + channel, + fontSize, + lineHeight, + padding, + raw, + type, + mutableMapOf(), + ) fun toElementalChannelNode(): ElementalChannelNode = ElementalChannelNode.builder() @@ -65,6 +85,9 @@ private constructor( .loop(loop) .ref(ref) .channel(channel) + .fontSize(fontSize) + .lineHeight(lineHeight) + .padding(padding) .raw(raw) .build() @@ -101,6 +124,34 @@ private constructor( */ fun channel(): Optional = channel.getOptional("channel") + /** + * Email only. Document-level base font size (CSS px, e.g. `16px`) for body content — text, + * quote, list and action button labels. Heading styles (`h1`/`h2`/`h3`) and `subtext` keep + * their preset sizes. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun fontSize(): Optional = fontSize.getOptional("font_size") + + /** + * Email only. Document-level line height (CSS px or unitless multiplier, e.g. `24px` or `1.5`) + * applied to all body content unless overridden per block. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun lineHeight(): Optional = lineHeight.getOptional("line_height") + + /** + * Email only. Document-level body padding applied once around the email body, as a CSS px + * shorthand (1–4 values), e.g. `48px 64px`. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun padding(): Optional = padding.getOptional("padding") + /** * Raw data to apply to the channel. If `elements` has not been specified, `raw` is required. * @@ -150,6 +201,27 @@ private constructor( */ @JsonProperty("channel") @ExcludeMissing fun _channel(): JsonField = channel + /** + * Returns the raw JSON value of [fontSize]. + * + * Unlike [fontSize], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("font_size") @ExcludeMissing fun _fontSize(): JsonField = fontSize + + /** + * Returns the raw JSON value of [lineHeight]. + * + * Unlike [lineHeight], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("line_height") @ExcludeMissing fun _lineHeight(): JsonField = lineHeight + + /** + * Returns the raw JSON value of [padding]. + * + * Unlike [padding], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("padding") @ExcludeMissing fun _padding(): JsonField = padding + /** * Returns the raw JSON value of [raw]. * @@ -192,6 +264,9 @@ private constructor( private var loop: JsonField = JsonMissing.of() private var ref: JsonField = JsonMissing.of() private var channel: JsonField = JsonMissing.of() + private var fontSize: JsonField = JsonMissing.of() + private var lineHeight: JsonField = JsonMissing.of() + private var padding: JsonField = JsonMissing.of() private var raw: JsonField = JsonMissing.of() private var type: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @@ -203,6 +278,9 @@ private constructor( loop = elementalChannelNodeWithType.loop ref = elementalChannelNodeWithType.ref channel = elementalChannelNodeWithType.channel + fontSize = elementalChannelNodeWithType.fontSize + lineHeight = elementalChannelNodeWithType.lineHeight + padding = elementalChannelNodeWithType.padding raw = elementalChannelNodeWithType.raw type = elementalChannelNodeWithType.type additionalProperties = elementalChannelNodeWithType.additionalProperties.toMutableMap() @@ -289,6 +367,59 @@ private constructor( */ fun channel(channel: JsonField) = apply { this.channel = channel } + /** + * Email only. Document-level base font size (CSS px, e.g. `16px`) for body content — text, + * quote, list and action button labels. Heading styles (`h1`/`h2`/`h3`) and `subtext` keep + * their preset sizes. + */ + fun fontSize(fontSize: String?) = fontSize(JsonField.ofNullable(fontSize)) + + /** Alias for calling [Builder.fontSize] with `fontSize.orElse(null)`. */ + fun fontSize(fontSize: Optional) = fontSize(fontSize.getOrNull()) + + /** + * Sets [Builder.fontSize] to an arbitrary JSON value. + * + * You should usually call [Builder.fontSize] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun fontSize(fontSize: JsonField) = apply { this.fontSize = fontSize } + + /** + * Email only. Document-level line height (CSS px or unitless multiplier, e.g. `24px` or + * `1.5`) applied to all body content unless overridden per block. + */ + fun lineHeight(lineHeight: String?) = lineHeight(JsonField.ofNullable(lineHeight)) + + /** Alias for calling [Builder.lineHeight] with `lineHeight.orElse(null)`. */ + fun lineHeight(lineHeight: Optional) = lineHeight(lineHeight.getOrNull()) + + /** + * Sets [Builder.lineHeight] to an arbitrary JSON value. + * + * You should usually call [Builder.lineHeight] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun lineHeight(lineHeight: JsonField) = apply { this.lineHeight = lineHeight } + + /** + * Email only. Document-level body padding applied once around the email body, as a CSS px + * shorthand (1–4 values), e.g. `48px 64px`. + */ + fun padding(padding: String?) = padding(JsonField.ofNullable(padding)) + + /** Alias for calling [Builder.padding] with `padding.orElse(null)`. */ + fun padding(padding: Optional) = padding(padding.getOrNull()) + + /** + * Sets [Builder.padding] to an arbitrary JSON value. + * + * You should usually call [Builder.padding] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun padding(padding: JsonField) = apply { this.padding = padding } + /** * Raw data to apply to the channel. If `elements` has not been specified, `raw` is * required. @@ -348,6 +479,9 @@ private constructor( loop, ref, channel, + fontSize, + lineHeight, + padding, raw, type, additionalProperties.toMutableMap(), @@ -374,6 +508,9 @@ private constructor( loop() ref() channel() + fontSize() + lineHeight() + padding() raw().ifPresent { it.validate() } type().ifPresent { it.validate() } validated = true @@ -399,6 +536,9 @@ private constructor( (if (loop.asKnown().isPresent) 1 else 0) + (if (ref.asKnown().isPresent) 1 else 0) + (if (channel.asKnown().isPresent) 1 else 0) + + (if (fontSize.asKnown().isPresent) 1 else 0) + + (if (lineHeight.asKnown().isPresent) 1 else 0) + + (if (padding.asKnown().isPresent) 1 else 0) + (raw.asKnown().getOrNull()?.validity() ?: 0) + (type.asKnown().getOrNull()?.validity() ?: 0) @@ -541,17 +681,32 @@ private constructor( loop == other.loop && ref == other.ref && channel == other.channel && + fontSize == other.fontSize && + lineHeight == other.lineHeight && + padding == other.padding && raw == other.raw && type == other.type && additionalProperties == other.additionalProperties } private val hashCode: Int by lazy { - Objects.hash(channels, if_, loop, ref, channel, raw, type, additionalProperties) + Objects.hash( + channels, + if_, + loop, + ref, + channel, + fontSize, + lineHeight, + padding, + raw, + type, + additionalProperties, + ) } override fun hashCode(): Int = hashCode override fun toString() = - "ElementalChannelNodeWithType{channels=$channels, if_=$if_, loop=$loop, ref=$ref, channel=$channel, raw=$raw, type=$type, additionalProperties=$additionalProperties}" + "ElementalChannelNodeWithType{channels=$channels, if_=$if_, loop=$loop, ref=$ref, channel=$channel, fontSize=$fontSize, lineHeight=$lineHeight, padding=$padding, raw=$raw, type=$type, additionalProperties=$additionalProperties}" } diff --git a/courier-java-core/src/test/kotlin/com/courier/models/ElementalChannelNodeTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/ElementalChannelNodeTest.kt index 39d5c45b..dec76649 100644 --- a/courier-java-core/src/test/kotlin/com/courier/models/ElementalChannelNodeTest.kt +++ b/courier-java-core/src/test/kotlin/com/courier/models/ElementalChannelNodeTest.kt @@ -20,6 +20,9 @@ internal class ElementalChannelNodeTest { .loop("loop") .ref("ref") .channel("email") + .fontSize("font_size") + .lineHeight("line_height") + .padding("padding") .raw( ElementalChannelNode.Raw.builder() .putAdditionalProperty("foo", JsonValue.from("bar")) @@ -32,6 +35,9 @@ internal class ElementalChannelNodeTest { assertThat(elementalChannelNode.loop()).contains("loop") assertThat(elementalChannelNode.ref()).contains("ref") assertThat(elementalChannelNode.channel()).contains("email") + assertThat(elementalChannelNode.fontSize()).contains("font_size") + assertThat(elementalChannelNode.lineHeight()).contains("line_height") + assertThat(elementalChannelNode.padding()).contains("padding") assertThat(elementalChannelNode.raw()) .contains( ElementalChannelNode.Raw.builder() @@ -50,6 +56,9 @@ internal class ElementalChannelNodeTest { .loop("loop") .ref("ref") .channel("email") + .fontSize("font_size") + .lineHeight("line_height") + .padding("padding") .raw( ElementalChannelNode.Raw.builder() .putAdditionalProperty("foo", JsonValue.from("bar")) diff --git a/scripts/upload-artifacts b/scripts/upload-artifacts index 10f3c705..5c1fbefc 100755 --- a/scripts/upload-artifacts +++ b/scripts/upload-artifacts @@ -91,6 +91,7 @@ generate_instructions() { Maven Repo +

Stainless SDK Maven Repository