diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index d47822c9..936028a3 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,12 +1,14 @@
name: CI
on:
push:
- branches-ignore:
- - 'generated'
- - 'codegen/**'
- - 'integrated/**'
- - 'stl-preview-head/**'
- - 'stl-preview-base/**'
+ branches:
+ - '**'
+ - '!integrated/**'
+ - '!stl-preview-head/**'
+ - '!stl-preview-base/**'
+ - '!generated'
+ - '!codegen/**'
+ - 'codegen/stl/**'
pull_request:
branches-ignore:
- 'stl-preview-head/**'
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index ac031714..e3778b2c 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.6.1"
+ ".": "0.6.2"
}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ec6c35a8..13286b10 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,25 @@
# Changelog
+## 0.6.2 (2026-03-20)
+
+Full Changelog: [v0.6.1...v0.6.2](https://github.com/openlayer-ai/openlayer-java/compare/v0.6.1...v0.6.2)
+
+### Bug Fixes
+
+* **client:** allow updating header/query affecting fields in `toBuilder()` ([d8d7183](https://github.com/openlayer-ai/openlayer-java/commit/d8d71833a6e9c2558290671cc7eb09929a7052cc))
+
+
+### Chores
+
+* **internal:** bump ktfmt ([b5baeb0](https://github.com/openlayer-ai/openlayer-java/commit/b5baeb0a9a47e2b1bd713141c8ec1b0f89a42317))
+* **internal:** tweak CI branches ([213ce88](https://github.com/openlayer-ai/openlayer-java/commit/213ce883034978b2e18bae11630c5d32a627058a))
+* **internal:** update retry delay tests ([29c1ab3](https://github.com/openlayer-ai/openlayer-java/commit/29c1ab379fc3a5f5a2c90e6a46c93e9060309f1e))
+
+
+### Refactors
+
+* **tests:** switch from prism to steady ([0c240d8](https://github.com/openlayer-ai/openlayer-java/commit/0c240d8156ac2385a97f39e8017efef69293edfe))
+
## 0.6.1 (2026-03-11)
Full Changelog: [v0.6.0...v0.6.1](https://github.com/openlayer-ai/openlayer-java/compare/v0.6.0...v0.6.1)
diff --git a/README.md b/README.md
index a2cf1d0d..69a88f43 100644
--- a/README.md
+++ b/README.md
@@ -2,8 +2,8 @@
-[](https://central.sonatype.com/artifact/com.openlayer.api/openlayer-java/0.6.1)
-[](https://javadoc.io/doc/com.openlayer.api/openlayer-java/0.6.1)
+[](https://central.sonatype.com/artifact/com.openlayer.api/openlayer-java/0.6.2)
+[](https://javadoc.io/doc/com.openlayer.api/openlayer-java/0.6.2)
@@ -13,7 +13,7 @@ It is generated with [Stainless](https://www.stainless.com/).
-The REST API documentation can be found on [openlayer.com](https://openlayer.com/docs/api-reference/rest/overview). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.openlayer.api/openlayer-java/0.6.1).
+The REST API documentation can be found on [openlayer.com](https://openlayer.com/docs/api-reference/rest/overview). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.openlayer.api/openlayer-java/0.6.2).
@@ -24,7 +24,7 @@ The REST API documentation can be found on [openlayer.com](https://openlayer.com
### Gradle
```kotlin
-implementation("com.openlayer.api:openlayer-java:0.6.1")
+implementation("com.openlayer.api:openlayer-java:0.6.2")
```
### Maven
@@ -33,7 +33,7 @@ implementation("com.openlayer.api:openlayer-java:0.6.1")
com.openlayer.api
openlayer-java
- 0.6.1
+ 0.6.2
```
diff --git a/build.gradle.kts b/build.gradle.kts
index fe534953..d2596138 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -8,7 +8,7 @@ repositories {
allprojects {
group = "com.openlayer.api"
- version = "0.6.1" // x-release-please-version
+ version = "0.6.2" // x-release-please-version
}
subprojects {
diff --git a/buildSrc/src/main/kotlin/openlayer.kotlin.gradle.kts b/buildSrc/src/main/kotlin/openlayer.kotlin.gradle.kts
index e8c2b61e..01815b34 100644
--- a/buildSrc/src/main/kotlin/openlayer.kotlin.gradle.kts
+++ b/buildSrc/src/main/kotlin/openlayer.kotlin.gradle.kts
@@ -40,7 +40,7 @@ tasks.withType().configureEach {
val ktfmt by configurations.creating
dependencies {
- ktfmt("com.facebook:ktfmt:0.56")
+ ktfmt("com.facebook:ktfmt:0.61")
}
fun registerKtfmt(
diff --git a/openlayer-java-core/src/main/kotlin/com/openlayer/api/core/ClientOptions.kt b/openlayer-java-core/src/main/kotlin/com/openlayer/api/core/ClientOptions.kt
index 526c782a..166a2acf 100644
--- a/openlayer-java-core/src/main/kotlin/com/openlayer/api/core/ClientOptions.kt
+++ b/openlayer-java-core/src/main/kotlin/com/openlayer/api/core/ClientOptions.kt
@@ -405,13 +405,14 @@ private constructor(
headers.put("X-Stainless-Runtime", "JRE")
headers.put("X-Stainless-Runtime-Version", getJavaVersion())
headers.put("X-Stainless-Kotlin-Version", KotlinVersion.CURRENT.toString())
+ // We replace after all the default headers to allow end-users to overwrite them.
+ headers.replaceAll(this.headers.build())
+ queryParams.replaceAll(this.queryParams.build())
apiKey?.let {
if (!it.isEmpty()) {
- headers.put("Authorization", "Bearer $it")
+ headers.replace("Authorization", "Bearer $it")
}
}
- headers.replaceAll(this.headers.build())
- queryParams.replaceAll(this.queryParams.build())
return ClientOptions(
httpClient,
diff --git a/openlayer-java-core/src/test/kotlin/com/openlayer/api/core/ClientOptionsTest.kt b/openlayer-java-core/src/test/kotlin/com/openlayer/api/core/ClientOptionsTest.kt
index b25c9917..36f1e9f6 100644
--- a/openlayer-java-core/src/test/kotlin/com/openlayer/api/core/ClientOptionsTest.kt
+++ b/openlayer-java-core/src/test/kotlin/com/openlayer/api/core/ClientOptionsTest.kt
@@ -16,6 +16,29 @@ internal class ClientOptionsTest {
private val httpClient = mock()
+ @Test
+ fun putHeader_canOverwriteDefaultHeader() {
+ val clientOptions =
+ ClientOptions.builder()
+ .httpClient(httpClient)
+ .putHeader("User-Agent", "My User Agent")
+ .apiKey("My API Key")
+ .build()
+
+ assertThat(clientOptions.headers.values("User-Agent")).containsExactly("My User Agent")
+ }
+
+ @Test
+ fun toBuilder_bearerAuthCanBeUpdated() {
+ var clientOptions =
+ ClientOptions.builder().httpClient(httpClient).apiKey("My API Key").build()
+
+ clientOptions = clientOptions.toBuilder().apiKey("another My API Key").build()
+
+ assertThat(clientOptions.headers.values("Authorization"))
+ .containsExactly("Bearer another My API Key")
+ }
+
@Test
fun toBuilder_whenOriginalClientOptionsGarbageCollected_doesNotCloseOriginalClient() {
var clientOptions =
diff --git a/openlayer-java-core/src/test/kotlin/com/openlayer/api/core/http/RetryingHttpClientTest.kt b/openlayer-java-core/src/test/kotlin/com/openlayer/api/core/http/RetryingHttpClientTest.kt
index 045c7c1e..b65010c5 100644
--- a/openlayer-java-core/src/test/kotlin/com/openlayer/api/core/http/RetryingHttpClientTest.kt
+++ b/openlayer-java-core/src/test/kotlin/com/openlayer/api/core/http/RetryingHttpClientTest.kt
@@ -400,9 +400,9 @@ internal class RetryingHttpClientTest {
assertThat(sleeper.durations).hasSize(3)
// retries=1: 0.5s * [0.75, 1.0]
assertThat(sleeper.durations[0]).isBetween(Duration.ofMillis(375), Duration.ofMillis(500))
- // retries=2: 1.0s * [0.75, 1.0]
+ // retries=2: 1s * [0.75, 1.0]
assertThat(sleeper.durations[1]).isBetween(Duration.ofMillis(750), Duration.ofMillis(1000))
- // retries=3: 2.0s * [0.75, 1.0]
+ // retries=3: 2s * [0.75, 1.0]
assertThat(sleeper.durations[2]).isBetween(Duration.ofMillis(1500), Duration.ofMillis(2000))
assertNoResponseLeaks()
}
@@ -427,9 +427,9 @@ internal class RetryingHttpClientTest {
assertThat(response.statusCode()).isEqualTo(503)
verify(7, postRequestedFor(urlPathEqualTo("/something")))
assertThat(sleeper.durations).hasSize(6)
- // retries=5: min(0.5 * 2^4, 8) = 8.0s * [0.75, 1.0]
+ // retries=5: backoff hits the 8s cap * [0.75, 1.0]
assertThat(sleeper.durations[4]).isBetween(Duration.ofMillis(6000), Duration.ofMillis(8000))
- // retries=6: min(0.5 * 2^5, 8) = min(16, 8) = 8.0s * [0.75, 1.0] (capped)
+ // retries=6: still capped at 8s * [0.75, 1.0]
assertThat(sleeper.durations[5]).isBetween(Duration.ofMillis(6000), Duration.ofMillis(8000))
assertNoResponseLeaks()
}
diff --git a/scripts/fast-format b/scripts/fast-format
index 1b3bc473..35a1dee2 100755
--- a/scripts/fast-format
+++ b/scripts/fast-format
@@ -24,8 +24,8 @@ if [ ! -f "$FILE_LIST" ]; then
exit 1
fi
-if ! command -v ktfmt-fast-format &> /dev/null; then
- echo "Error: ktfmt-fast-format not found"
+if ! command -v ktfmt &> /dev/null; then
+ echo "Error: ktfmt not found"
exit 1
fi
@@ -36,7 +36,7 @@ echo "==> Done looking for Kotlin files"
if [[ -n "$kt_files" ]]; then
echo "==> will format Kotlin files"
- echo "$kt_files" | tr '\n' '\0' | xargs -0 ktfmt-fast-format --kotlinlang-style "$@"
+ echo "$kt_files" | tr '\n' '\0' | xargs -0 ktfmt --kotlinlang-style "$@"
else
echo "No Kotlin files to format -- expected outcome during incremental formatting"
fi
diff --git a/scripts/mock b/scripts/mock
index bcf3b392..38201de8 100755
--- a/scripts/mock
+++ b/scripts/mock
@@ -19,34 +19,34 @@ fi
echo "==> Starting mock server with URL ${URL}"
-# Run prism mock on the given spec
+# Run steady mock on the given spec
if [ "$1" == "--daemon" ]; then
# Pre-install the package so the download doesn't eat into the startup timeout
- npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism --version
+ npm exec --package=@stdy/cli@0.19.3 -- steady --version
- npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock "$URL" &> .prism.log &
+ npm exec --package=@stdy/cli@0.19.3 -- steady --host 127.0.0.1 -p 4010 --validator-query-array-format=comma --validator-query-object-format=brackets "$URL" &> .stdy.log &
- # Wait for server to come online (max 30s)
+ # Wait for server to come online via health endpoint (max 30s)
echo -n "Waiting for server"
attempts=0
- while ! grep -q "✖ fatal\|Prism is listening" ".prism.log" ; do
+ while ! curl --silent --fail "http://127.0.0.1:4010/_x-steady/health" >/dev/null 2>&1; do
+ if ! kill -0 $! 2>/dev/null; then
+ echo
+ cat .stdy.log
+ exit 1
+ fi
attempts=$((attempts + 1))
if [ "$attempts" -ge 300 ]; then
echo
- echo "Timed out waiting for Prism server to start"
- cat .prism.log
+ echo "Timed out waiting for Steady server to start"
+ cat .stdy.log
exit 1
fi
echo -n "."
sleep 0.1
done
- if grep -q "✖ fatal" ".prism.log"; then
- cat .prism.log
- exit 1
- fi
-
echo
else
- npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock "$URL"
+ npm exec --package=@stdy/cli@0.19.3 -- steady --host 127.0.0.1 -p 4010 --validator-query-array-format=comma --validator-query-object-format=brackets "$URL"
fi
diff --git a/scripts/test b/scripts/test
index 047bc1db..0d08465c 100755
--- a/scripts/test
+++ b/scripts/test
@@ -9,8 +9,8 @@ GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color
-function prism_is_running() {
- curl --silent "http://localhost:4010" >/dev/null 2>&1
+function steady_is_running() {
+ curl --silent "http://127.0.0.1:4010/_x-steady/health" >/dev/null 2>&1
}
kill_server_on_port() {
@@ -25,7 +25,7 @@ function is_overriding_api_base_url() {
[ -n "$TEST_API_BASE_URL" ]
}
-if ! is_overriding_api_base_url && ! prism_is_running ; then
+if ! is_overriding_api_base_url && ! steady_is_running ; then
# When we exit this script, make sure to kill the background mock server process
trap 'kill_server_on_port 4010' EXIT
@@ -36,19 +36,19 @@ fi
if is_overriding_api_base_url ; then
echo -e "${GREEN}✔ Running tests against ${TEST_API_BASE_URL}${NC}"
echo
-elif ! prism_is_running ; then
- echo -e "${RED}ERROR:${NC} The test suite will not run without a mock Prism server"
+elif ! steady_is_running ; then
+ echo -e "${RED}ERROR:${NC} The test suite will not run without a mock Steady server"
echo -e "running against your OpenAPI spec."
echo
echo -e "To run the server, pass in the path or url of your OpenAPI"
- echo -e "spec to the prism command:"
+ echo -e "spec to the steady command:"
echo
- echo -e " \$ ${YELLOW}npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock path/to/your.openapi.yml${NC}"
+ echo -e " \$ ${YELLOW}npm exec --package=@stdy/cli@0.19.3 -- steady path/to/your.openapi.yml --host 127.0.0.1 -p 4010 --validator-query-array-format=comma --validator-query-object-format=brackets${NC}"
echo
exit 1
else
- echo -e "${GREEN}✔ Mock prism server is running with your OpenAPI spec${NC}"
+ echo -e "${GREEN}✔ Mock steady server is running with your OpenAPI spec${NC}"
echo
fi