Skip to content

Commit 99123b3

Browse files
authored
Merge pull request #380 from orbcorp/release-please--branches--main--changes--next
release: 0.53.0
2 parents 03623dd + 5965a39 commit 99123b3

File tree

229 files changed

+97049
-4944
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

229 files changed

+97049
-4944
lines changed

.release-please-manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
".": "0.52.2"
2+
".": "0.53.0"
33
}

.stats.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
configured_endpoints: 103
22
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/orb%2Forb-95a3d7780935a38e0cf076d4ad2d68bd1a5641bced8398d972db2e92751d364a.yml
33
openapi_spec_hash: 9ebe818c4ad4f2d9c4e473b5192d7544
4-
config_hash: ec4f1e02d3528e3a93a73e33bca17c2a
4+
config_hash: 3dc5bc1df028fc7301fb2ada9846f038

CHANGELOG.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,22 @@
11
# Changelog
22

3+
## 0.53.0 (2025-04-02)
4+
5+
Full Changelog: [v0.52.2...v0.53.0](https://github.com/orbcorp/orb-java/compare/v0.52.2...v0.53.0)
6+
7+
### Features
8+
9+
* **client:** add enum validation method ([d6fdaa3](https://github.com/orbcorp/orb-java/commit/d6fdaa34309a8c1bcc4f2bd84beaae587f3a3e9d))
10+
* **client:** make union deserialization more robust ([#379](https://github.com/orbcorp/orb-java/issues/379)) ([d6fdaa3](https://github.com/orbcorp/orb-java/commit/d6fdaa34309a8c1bcc4f2bd84beaae587f3a3e9d))
11+
12+
13+
### Chores
14+
15+
* **client:** remove unnecessary json state from some query param classes ([d6fdaa3](https://github.com/orbcorp/orb-java/commit/d6fdaa34309a8c1bcc4f2bd84beaae587f3a3e9d))
16+
* **internal:** add invalid json deserialization tests ([d6fdaa3](https://github.com/orbcorp/orb-java/commit/d6fdaa34309a8c1bcc4f2bd84beaae587f3a3e9d))
17+
* **internal:** add json roundtripping tests ([d6fdaa3](https://github.com/orbcorp/orb-java/commit/d6fdaa34309a8c1bcc4f2bd84beaae587f3a3e9d))
18+
* **internal:** codegen related update ([#381](https://github.com/orbcorp/orb-java/issues/381)) ([1373dc9](https://github.com/orbcorp/orb-java/commit/1373dc9c246351e40eb442e4af9af81c1b8cb881))
19+
320
## 0.52.2 (2025-04-01)
421

522
Full Changelog: [v0.52.1...v0.52.2](https://github.com/orbcorp/orb-java/compare/v0.52.1...v0.52.2)

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<!-- x-release-please-start-version -->
44

5-
[![Maven Central](https://img.shields.io/maven-central/v/com.withorb.api/orb-java)](https://central.sonatype.com/artifact/com.withorb.api/orb-java/0.52.2)
5+
[![Maven Central](https://img.shields.io/maven-central/v/com.withorb.api/orb-java)](https://central.sonatype.com/artifact/com.withorb.api/orb-java/0.53.0)
66

77
<!-- x-release-please-end -->
88

@@ -19,7 +19,7 @@ The REST API documentation can be found on [docs.withorb.com](https://docs.witho
1919
### Gradle
2020

2121
```kotlin
22-
implementation("com.withorb.api:orb-java:0.52.2")
22+
implementation("com.withorb.api:orb-java:0.53.0")
2323
```
2424

2525
### Maven
@@ -28,7 +28,7 @@ implementation("com.withorb.api:orb-java:0.52.2")
2828
<dependency>
2929
<groupId>com.withorb.api</groupId>
3030
<artifactId>orb-java</artifactId>
31-
<version>0.52.2</version>
31+
<version>0.53.0</version>
3232
</dependency>
3333
```
3434

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
allprojects {
22
group = "com.withorb.api"
3-
version = "0.52.2" // x-release-please-version
3+
version = "0.53.0" // x-release-please-version
44
}

orb-java-core/src/main/kotlin/com/withorb/api/core/BaseDeserializer.kt

Lines changed: 5 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,9 @@ import com.fasterxml.jackson.databind.BeanProperty
77
import com.fasterxml.jackson.databind.DeserializationContext
88
import com.fasterxml.jackson.databind.JavaType
99
import com.fasterxml.jackson.databind.JsonDeserializer
10-
import com.fasterxml.jackson.databind.JsonMappingException
1110
import com.fasterxml.jackson.databind.JsonNode
1211
import com.fasterxml.jackson.databind.deser.ContextualDeserializer
1312
import com.fasterxml.jackson.databind.deser.std.StdDeserializer
14-
import com.withorb.api.errors.OrbInvalidDataException
1513
import kotlin.reflect.KClass
1614

1715
abstract class BaseDeserializer<T : Any>(type: KClass<T>) :
@@ -30,38 +28,17 @@ abstract class BaseDeserializer<T : Any>(type: KClass<T>) :
3028

3129
protected abstract fun ObjectCodec.deserialize(node: JsonNode): T
3230

33-
protected fun <T> ObjectCodec.deserialize(node: JsonNode, type: TypeReference<T>): T =
31+
protected fun <T> ObjectCodec.tryDeserialize(node: JsonNode, type: TypeReference<T>): T? =
3432
try {
3533
readValue(treeAsTokens(node), type)
3634
} catch (e: Exception) {
37-
throw OrbInvalidDataException("Error deserializing", e)
38-
}
39-
40-
protected fun <T> ObjectCodec.tryDeserialize(
41-
node: JsonNode,
42-
type: TypeReference<T>,
43-
validate: (T) -> Unit = {},
44-
): T? {
45-
return try {
46-
readValue(treeAsTokens(node), type).apply(validate)
47-
} catch (e: JsonMappingException) {
48-
null
49-
} catch (e: RuntimeException) {
5035
null
5136
}
52-
}
5337

54-
protected fun <T> ObjectCodec.tryDeserialize(
55-
node: JsonNode,
56-
type: JavaType,
57-
validate: (T) -> Unit = {},
58-
): T? {
59-
return try {
60-
readValue<T>(treeAsTokens(node), type).apply(validate)
61-
} catch (e: JsonMappingException) {
62-
null
63-
} catch (e: RuntimeException) {
38+
protected fun <T> ObjectCodec.tryDeserialize(node: JsonNode, type: JavaType): T? =
39+
try {
40+
readValue(treeAsTokens(node), type)
41+
} catch (e: Exception) {
6442
null
6543
}
66-
}
6744
}

orb-java-core/src/main/kotlin/com/withorb/api/core/ObjectMappers.kt

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,40 @@ package com.withorb.api.core
44

55
import com.fasterxml.jackson.annotation.JsonInclude
66
import com.fasterxml.jackson.core.JsonGenerator
7+
import com.fasterxml.jackson.core.JsonParseException
8+
import com.fasterxml.jackson.core.JsonParser
9+
import com.fasterxml.jackson.databind.DeserializationContext
710
import com.fasterxml.jackson.databind.DeserializationFeature
811
import com.fasterxml.jackson.databind.MapperFeature
912
import com.fasterxml.jackson.databind.SerializationFeature
1013
import com.fasterxml.jackson.databind.SerializerProvider
1114
import com.fasterxml.jackson.databind.cfg.CoercionAction
1215
import com.fasterxml.jackson.databind.cfg.CoercionInputShape
16+
import com.fasterxml.jackson.databind.deser.std.StdDeserializer
1317
import com.fasterxml.jackson.databind.json.JsonMapper
1418
import com.fasterxml.jackson.databind.module.SimpleModule
1519
import com.fasterxml.jackson.databind.type.LogicalType
1620
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module
1721
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
1822
import com.fasterxml.jackson.module.kotlin.kotlinModule
1923
import java.io.InputStream
24+
import java.time.DateTimeException
25+
import java.time.LocalDate
26+
import java.time.LocalDateTime
27+
import java.time.ZonedDateTime
28+
import java.time.format.DateTimeFormatter
29+
import java.time.temporal.ChronoField
2030

2131
fun jsonMapper(): JsonMapper =
2232
JsonMapper.builder()
2333
.addModule(kotlinModule())
2434
.addModule(Jdk8Module())
2535
.addModule(JavaTimeModule())
26-
.addModule(SimpleModule().addSerializer(InputStreamJsonSerializer))
36+
.addModule(
37+
SimpleModule()
38+
.addSerializer(InputStreamSerializer)
39+
.addDeserializer(LocalDateTime::class.java, LenientLocalDateTimeDeserializer())
40+
)
2741
.withCoercionConfig(LogicalType.Boolean) {
2842
it.setCoercion(CoercionInputShape.Integer, CoercionAction.Fail)
2943
.setCoercion(CoercionInputShape.Float, CoercionAction.Fail)
@@ -91,7 +105,10 @@ fun jsonMapper(): JsonMapper =
91105
.disable(MapperFeature.AUTO_DETECT_SETTERS)
92106
.build()
93107

94-
private object InputStreamJsonSerializer : BaseSerializer<InputStream>(InputStream::class) {
108+
/** A serializer that serializes [InputStream] to bytes. */
109+
private object InputStreamSerializer : BaseSerializer<InputStream>(InputStream::class) {
110+
111+
private fun readResolve(): Any = InputStreamSerializer
95112

96113
override fun serialize(
97114
value: InputStream?,
@@ -105,3 +122,46 @@ private object InputStreamJsonSerializer : BaseSerializer<InputStream>(InputStre
105122
}
106123
}
107124
}
125+
126+
/**
127+
* A deserializer that can deserialize [LocalDateTime] from datetimes, dates, and zoned datetimes.
128+
*/
129+
private class LenientLocalDateTimeDeserializer :
130+
StdDeserializer<LocalDateTime>(LocalDateTime::class.java) {
131+
132+
companion object {
133+
134+
private val DATE_TIME_FORMATTERS =
135+
listOf(
136+
DateTimeFormatter.ISO_LOCAL_DATE_TIME,
137+
DateTimeFormatter.ISO_LOCAL_DATE,
138+
DateTimeFormatter.ISO_ZONED_DATE_TIME,
139+
)
140+
}
141+
142+
override fun logicalType(): LogicalType = LogicalType.DateTime
143+
144+
override fun deserialize(p: JsonParser, context: DeserializationContext?): LocalDateTime {
145+
val exceptions = mutableListOf<Exception>()
146+
147+
for (formatter in DATE_TIME_FORMATTERS) {
148+
try {
149+
val temporal = formatter.parse(p.text)
150+
151+
return when {
152+
!temporal.isSupported(ChronoField.HOUR_OF_DAY) ->
153+
LocalDate.from(temporal).atStartOfDay()
154+
!temporal.isSupported(ChronoField.OFFSET_SECONDS) ->
155+
LocalDateTime.from(temporal)
156+
else -> ZonedDateTime.from(temporal).toLocalDateTime()
157+
}
158+
} catch (e: DateTimeException) {
159+
exceptions.add(e)
160+
}
161+
}
162+
163+
throw JsonParseException(p, "Cannot parse `LocalDateTime` from value: ${p.text}").apply {
164+
exceptions.forEach { addSuppressed(it) }
165+
}
166+
}
167+
}

orb-java-core/src/main/kotlin/com/withorb/api/core/Utils.kt

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,34 @@ internal fun <K : Comparable<K>, V> SortedMap<K, V>.toImmutable(): SortedMap<K,
2626
if (isEmpty()) Collections.emptySortedMap()
2727
else Collections.unmodifiableSortedMap(toSortedMap(comparator()))
2828

29+
/**
30+
* Returns all elements that yield the largest value for the given function, or an empty list if
31+
* there are zero elements.
32+
*
33+
* This is similar to [Sequence.maxByOrNull] except it returns _all_ elements that yield the largest
34+
* value; not just the first one.
35+
*/
36+
@JvmSynthetic
37+
internal fun <T, R : Comparable<R>> Sequence<T>.allMaxBy(selector: (T) -> R): List<T> {
38+
var maxValue: R? = null
39+
val maxElements = mutableListOf<T>()
40+
41+
val iterator = iterator()
42+
while (iterator.hasNext()) {
43+
val element = iterator.next()
44+
val value = selector(element)
45+
if (maxValue == null || value > maxValue) {
46+
maxValue = value
47+
maxElements.clear()
48+
maxElements.add(element)
49+
} else if (value == maxValue) {
50+
maxElements.add(element)
51+
}
52+
}
53+
54+
return maxElements
55+
}
56+
2957
/**
3058
* Returns whether [this] is equal to [other].
3159
*

0 commit comments

Comments
 (0)