Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "0.43.0"
".": "0.44.0"
}
2 changes: 1 addition & 1 deletion .stats.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
configured_endpoints: 103
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/orb%2Forb-48084a007f009b4358484f09a3a7b74a990c402669f9d15adfbb60e4f835f951.yml
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/orb%2Forb-a2c1aa029d1e72a5fc7d3c6cd431479888ebd9a379683a2c8630da48437baa4f.yml
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Changelog

## 0.44.0 (2025-03-06)

Full Changelog: [v0.43.0...v0.44.0](https://github.com/orbcorp/orb-java/compare/v0.43.0...v0.44.0)

### Features

* **api:** api update ([#313](https://github.com/orbcorp/orb-java/issues/313)) ([6121464](https://github.com/orbcorp/orb-java/commit/6121464c0d089981492bf90573d1c11590780def))
* **client:** accept `InputStream` and `Path` for file params ([#311](https://github.com/orbcorp/orb-java/issues/311)) ([11ca664](https://github.com/orbcorp/orb-java/commit/11ca66491b29b9996bbffa2b599aed9c22d32ee8))

## 0.43.0 (2025-03-05)

Full Changelog: [v0.42.0...v0.43.0](https://github.com/orbcorp/orb-java/compare/v0.42.0...v0.43.0)
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

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

[![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.43.0)
[![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.44.0)

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

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

```kotlin
implementation("com.withorb.api:orb-java:0.43.0")
implementation("com.withorb.api:orb-java:0.44.0")
```

### Maven
Expand All @@ -28,7 +28,7 @@ implementation("com.withorb.api:orb-java:0.43.0")
<dependency>
<groupId>com.withorb.api</groupId>
<artifactId>orb-java</artifactId>
<version>0.43.0</version>
<version>0.44.0</version>
</dependency>
```

Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
allprojects {
group = "com.withorb.api"
version = "0.43.0" // x-release-please-version
version = "0.44.0" // x-release-please-version
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,43 @@
package com.withorb.api.core

import com.fasterxml.jackson.annotation.JsonInclude
import com.fasterxml.jackson.core.JsonGenerator
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.SerializationFeature
import com.fasterxml.jackson.databind.SerializerProvider
import com.fasterxml.jackson.databind.cfg.CoercionAction.Fail
import com.fasterxml.jackson.databind.cfg.CoercionInputShape.Integer
import com.fasterxml.jackson.databind.json.JsonMapper
import com.fasterxml.jackson.databind.module.SimpleModule
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
import com.fasterxml.jackson.module.kotlin.jacksonMapperBuilder
import java.io.InputStream

fun jsonMapper(): JsonMapper =
jacksonMapperBuilder()
.addModule(Jdk8Module())
.addModule(JavaTimeModule())
.addModule(SimpleModule().addSerializer(InputStreamJsonSerializer))
.serializationInclusion(JsonInclude.Include.NON_ABSENT)
.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE)
.disable(SerializationFeature.FLUSH_AFTER_WRITE_VALUE)
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.disable(SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS)
.withCoercionConfig(String::class.java) { it.setCoercion(Integer, Fail) }
.build()

private object InputStreamJsonSerializer : BaseSerializer<InputStream>(InputStream::class) {

override fun serialize(
value: InputStream?,
gen: JsonGenerator?,
serializers: SerializerProvider?,
) {
if (value == null) {
gen?.writeNull()
} else {
value.use { gen?.writeBinary(it.readBytes()) }
}
}
}
6 changes: 5 additions & 1 deletion orb-java-core/src/main/kotlin/com/withorb/api/core/Values.kt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import com.fasterxml.jackson.databind.node.JsonNodeType.POJO
import com.fasterxml.jackson.databind.node.JsonNodeType.STRING
import com.fasterxml.jackson.databind.ser.std.NullSerializer
import com.withorb.api.errors.OrbInvalidDataException
import java.io.InputStream
import java.util.Objects
import java.util.Optional

Expand Down Expand Up @@ -508,7 +509,10 @@ private constructor(
return MultipartField(
value,
contentType
?: if (value is KnownValue && value.value is ByteArray)
?: if (
value is KnownValue &&
(value.value is InputStream || value.value is ByteArray)
)
"application/octet-stream"
else "text/plain; charset=utf-8",
filename,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import com.fasterxml.jackson.databind.json.JsonMapper
import com.fasterxml.jackson.databind.node.JsonNodeType
import com.withorb.api.core.MultipartField
import com.withorb.api.errors.OrbInvalidDataException
import java.io.ByteArrayInputStream
import java.io.InputStream
import java.io.OutputStream
import kotlin.jvm.optionals.getOrNull
import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder
Expand Down Expand Up @@ -41,8 +43,18 @@ internal fun multipartFormData(
MultipartEntityBuilder.create()
.apply {
fields.forEach { (name, field) ->
val node = jsonMapper.valueToTree<JsonNode>(field.value)
serializePart(name, node).forEach { (name, bytes) ->
val knownValue = field.value.asKnown().getOrNull()
val parts =
if (knownValue is InputStream) {
// Read directly from the `InputStream` instead of reading it all
// into memory due to the `jsonMapper` serialization below.
sequenceOf(name to knownValue)
} else {
val node = jsonMapper.valueToTree<JsonNode>(field.value)
serializePart(name, node)
}

parts.forEach { (name, bytes) ->
addBinaryBody(
name,
bytes,
Expand All @@ -55,16 +67,19 @@ internal fun multipartFormData(
.build()
}

private fun serializePart(name: String, node: JsonNode): Sequence<Pair<String, ByteArray>> =
private fun serializePart(
name: String,
node: JsonNode,
): Sequence<Pair<String, InputStream>> =
when (node.nodeType) {
JsonNodeType.MISSING,
JsonNodeType.NULL -> emptySequence()
JsonNodeType.BINARY -> sequenceOf(name to node.binaryValue())
JsonNodeType.STRING -> sequenceOf(name to node.textValue().toByteArray())
JsonNodeType.BINARY -> sequenceOf(name to ByteArrayInputStream(node.binaryValue()))
JsonNodeType.STRING -> sequenceOf(name to node.textValue().toInputStream())
JsonNodeType.BOOLEAN ->
sequenceOf(name to node.booleanValue().toString().toByteArray())
sequenceOf(name to node.booleanValue().toString().toInputStream())
JsonNodeType.NUMBER ->
sequenceOf(name to node.numberValue().toString().toByteArray())
sequenceOf(name to node.numberValue().toString().toInputStream())
JsonNodeType.ARRAY ->
node.elements().asSequence().flatMap { element ->
serializePart("$name[]", element)
Expand All @@ -77,6 +92,8 @@ internal fun multipartFormData(
null -> throw OrbInvalidDataException("Unexpected JsonNode type: ${node.nodeType}")
}

private fun String.toInputStream(): InputStream = ByteArrayInputStream(toByteArray())

override fun writeTo(outputStream: OutputStream) = entity.writeTo(outputStream)

override fun contentType(): String = entity.contentType
Expand Down
60 changes: 50 additions & 10 deletions orb-java-core/src/main/kotlin/com/withorb/api/models/Invoice.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4974,7 +4974,11 @@ private constructor(
*/
fun adjustedSubtotal(): String = adjustedSubtotal.getRequired("adjusted_subtotal")

/** All adjustments (ie. maximums, minimums, discounts) applied to the line item. */
/**
* All adjustments applied to the line item in the order they were applied based on invoice
* calculations (ie. usage discounts -> amount discounts -> percentage discounts -> minimums
* -> maximums).
*/
fun adjustments(): List<Adjustment> = adjustments.getRequired("adjustments")

/**
Expand Down Expand Up @@ -5076,7 +5080,11 @@ private constructor(
@ExcludeMissing
fun _adjustedSubtotal(): JsonField<String> = adjustedSubtotal

/** All adjustments (ie. maximums, minimums, discounts) applied to the line item. */
/**
* All adjustments applied to the line item in the order they were applied based on invoice
* calculations (ie. usage discounts -> amount discounts -> percentage discounts -> minimums
* -> maximums).
*/
@JsonProperty("adjustments")
@ExcludeMissing
fun _adjustments(): JsonField<List<Adjustment>> = adjustments
Expand Down Expand Up @@ -5334,40 +5342,72 @@ private constructor(
this.adjustedSubtotal = adjustedSubtotal
}

/** All adjustments (ie. maximums, minimums, discounts) applied to the line item. */
/**
* All adjustments applied to the line item in the order they were applied based on
* invoice calculations (ie. usage discounts -> amount discounts -> percentage discounts
* -> minimums -> maximums).
*/
fun adjustments(adjustments: List<Adjustment>) = adjustments(JsonField.of(adjustments))

/** All adjustments (ie. maximums, minimums, discounts) applied to the line item. */
/**
* All adjustments applied to the line item in the order they were applied based on
* invoice calculations (ie. usage discounts -> amount discounts -> percentage discounts
* -> minimums -> maximums).
*/
fun adjustments(adjustments: JsonField<List<Adjustment>>) = apply {
this.adjustments = adjustments.map { it.toMutableList() }
}

/** All adjustments (ie. maximums, minimums, discounts) applied to the line item. */
/**
* All adjustments applied to the line item in the order they were applied based on
* invoice calculations (ie. usage discounts -> amount discounts -> percentage discounts
* -> minimums -> maximums).
*/
fun addAdjustment(adjustment: Adjustment) = apply {
adjustments =
(adjustments ?: JsonField.of(mutableListOf())).also {
checkKnown("adjustments", it).add(adjustment)
}
}

/** All adjustments (ie. maximums, minimums, discounts) applied to the line item. */
/**
* All adjustments applied to the line item in the order they were applied based on
* invoice calculations (ie. usage discounts -> amount discounts -> percentage discounts
* -> minimums -> maximums).
*/
fun addAdjustment(monetaryUsageDiscount: Adjustment.MonetaryUsageDiscountAdjustment) =
addAdjustment(Adjustment.ofMonetaryUsageDiscount(monetaryUsageDiscount))

/** All adjustments (ie. maximums, minimums, discounts) applied to the line item. */
/**
* All adjustments applied to the line item in the order they were applied based on
* invoice calculations (ie. usage discounts -> amount discounts -> percentage discounts
* -> minimums -> maximums).
*/
fun addAdjustment(monetaryAmountDiscount: Adjustment.MonetaryAmountDiscountAdjustment) =
addAdjustment(Adjustment.ofMonetaryAmountDiscount(monetaryAmountDiscount))

/** All adjustments (ie. maximums, minimums, discounts) applied to the line item. */
/**
* All adjustments applied to the line item in the order they were applied based on
* invoice calculations (ie. usage discounts -> amount discounts -> percentage discounts
* -> minimums -> maximums).
*/
fun addAdjustment(
monetaryPercentageDiscount: Adjustment.MonetaryPercentageDiscountAdjustment
) = addAdjustment(Adjustment.ofMonetaryPercentageDiscount(monetaryPercentageDiscount))

/** All adjustments (ie. maximums, minimums, discounts) applied to the line item. */
/**
* All adjustments applied to the line item in the order they were applied based on
* invoice calculations (ie. usage discounts -> amount discounts -> percentage discounts
* -> minimums -> maximums).
*/
fun addAdjustment(monetaryMinimum: Adjustment.MonetaryMinimumAdjustment) =
addAdjustment(Adjustment.ofMonetaryMinimum(monetaryMinimum))

/** All adjustments (ie. maximums, minimums, discounts) applied to the line item. */
/**
* All adjustments applied to the line item in the order they were applied based on
* invoice calculations (ie. usage discounts -> amount discounts -> percentage discounts
* -> minimums -> maximums).
*/
fun addAdjustment(monetaryMaximum: Adjustment.MonetaryMaximumAdjustment) =
addAdjustment(Adjustment.ofMonetaryMaximum(monetaryMaximum))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4967,7 +4967,11 @@ private constructor(
*/
fun adjustedSubtotal(): String = adjustedSubtotal.getRequired("adjusted_subtotal")

/** All adjustments (ie. maximums, minimums, discounts) applied to the line item. */
/**
* All adjustments applied to the line item in the order they were applied based on invoice
* calculations (ie. usage discounts -> amount discounts -> percentage discounts -> minimums
* -> maximums).
*/
fun adjustments(): List<Adjustment> = adjustments.getRequired("adjustments")

/**
Expand Down Expand Up @@ -5069,7 +5073,11 @@ private constructor(
@ExcludeMissing
fun _adjustedSubtotal(): JsonField<String> = adjustedSubtotal

/** All adjustments (ie. maximums, minimums, discounts) applied to the line item. */
/**
* All adjustments applied to the line item in the order they were applied based on invoice
* calculations (ie. usage discounts -> amount discounts -> percentage discounts -> minimums
* -> maximums).
*/
@JsonProperty("adjustments")
@ExcludeMissing
fun _adjustments(): JsonField<List<Adjustment>> = adjustments
Expand Down Expand Up @@ -5327,40 +5335,72 @@ private constructor(
this.adjustedSubtotal = adjustedSubtotal
}

/** All adjustments (ie. maximums, minimums, discounts) applied to the line item. */
/**
* All adjustments applied to the line item in the order they were applied based on
* invoice calculations (ie. usage discounts -> amount discounts -> percentage discounts
* -> minimums -> maximums).
*/
fun adjustments(adjustments: List<Adjustment>) = adjustments(JsonField.of(adjustments))

/** All adjustments (ie. maximums, minimums, discounts) applied to the line item. */
/**
* All adjustments applied to the line item in the order they were applied based on
* invoice calculations (ie. usage discounts -> amount discounts -> percentage discounts
* -> minimums -> maximums).
*/
fun adjustments(adjustments: JsonField<List<Adjustment>>) = apply {
this.adjustments = adjustments.map { it.toMutableList() }
}

/** All adjustments (ie. maximums, minimums, discounts) applied to the line item. */
/**
* All adjustments applied to the line item in the order they were applied based on
* invoice calculations (ie. usage discounts -> amount discounts -> percentage discounts
* -> minimums -> maximums).
*/
fun addAdjustment(adjustment: Adjustment) = apply {
adjustments =
(adjustments ?: JsonField.of(mutableListOf())).also {
checkKnown("adjustments", it).add(adjustment)
}
}

/** All adjustments (ie. maximums, minimums, discounts) applied to the line item. */
/**
* All adjustments applied to the line item in the order they were applied based on
* invoice calculations (ie. usage discounts -> amount discounts -> percentage discounts
* -> minimums -> maximums).
*/
fun addAdjustment(monetaryUsageDiscount: Adjustment.MonetaryUsageDiscountAdjustment) =
addAdjustment(Adjustment.ofMonetaryUsageDiscount(monetaryUsageDiscount))

/** All adjustments (ie. maximums, minimums, discounts) applied to the line item. */
/**
* All adjustments applied to the line item in the order they were applied based on
* invoice calculations (ie. usage discounts -> amount discounts -> percentage discounts
* -> minimums -> maximums).
*/
fun addAdjustment(monetaryAmountDiscount: Adjustment.MonetaryAmountDiscountAdjustment) =
addAdjustment(Adjustment.ofMonetaryAmountDiscount(monetaryAmountDiscount))

/** All adjustments (ie. maximums, minimums, discounts) applied to the line item. */
/**
* All adjustments applied to the line item in the order they were applied based on
* invoice calculations (ie. usage discounts -> amount discounts -> percentage discounts
* -> minimums -> maximums).
*/
fun addAdjustment(
monetaryPercentageDiscount: Adjustment.MonetaryPercentageDiscountAdjustment
) = addAdjustment(Adjustment.ofMonetaryPercentageDiscount(monetaryPercentageDiscount))

/** All adjustments (ie. maximums, minimums, discounts) applied to the line item. */
/**
* All adjustments applied to the line item in the order they were applied based on
* invoice calculations (ie. usage discounts -> amount discounts -> percentage discounts
* -> minimums -> maximums).
*/
fun addAdjustment(monetaryMinimum: Adjustment.MonetaryMinimumAdjustment) =
addAdjustment(Adjustment.ofMonetaryMinimum(monetaryMinimum))

/** All adjustments (ie. maximums, minimums, discounts) applied to the line item. */
/**
* All adjustments applied to the line item in the order they were applied based on
* invoice calculations (ie. usage discounts -> amount discounts -> percentage discounts
* -> minimums -> maximums).
*/
fun addAdjustment(monetaryMaximum: Adjustment.MonetaryMaximumAdjustment) =
addAdjustment(Adjustment.ofMonetaryMaximum(monetaryMaximum))

Expand Down
Loading
Loading