From c70ccb90a1b14364b4b2f0a064386da5c1888e06 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 18 Aug 2025 08:08:51 +0000 Subject: [PATCH 01/99] chore: configure new SDK language --- .devcontainer/Dockerfile | 23 + .devcontainer/devcontainer.json | 20 + .gitattributes | 5 + .github/workflows/ci.yml | 85 + .gitignore | 7 + .stats.yml | 4 + LICENSE | 201 + README.md | 611 +- SECURITY.md | 27 + build.gradle.kts | 49 + buildSrc/build.gradle.kts | 12 + .../main/kotlin/cas-parser.java.gradle.kts | 136 + .../main/kotlin/cas-parser.kotlin.gradle.kts | 106 + .../main/kotlin/cas-parser.publish.gradle.kts | 61 + .../build.gradle.kts | 14 + .../client/okhttp/CasParserOkHttpClient.kt | 296 + .../okhttp/CasParserOkHttpClientAsync.kt | 296 + .../api/client/okhttp/OkHttpClient.kt | 246 + cas-parser-java-core/build.gradle.kts | 41 + .../cas_parser/api/client/CasParserClient.kt | 77 + .../api/client/CasParserClientAsync.kt | 81 + .../api/client/CasParserClientAsyncImpl.kt | 73 + .../api/client/CasParserClientImpl.kt | 73 + .../cas_parser/api/core/BaseDeserializer.kt | 44 + .../com/cas_parser/api/core/BaseSerializer.kt | 6 + .../kotlin/com/cas_parser/api/core/Check.kt | 96 + .../com/cas_parser/api/core/ClientOptions.kt | 407 + .../com/cas_parser/api/core/ObjectMappers.kt | 167 + .../kotlin/com/cas_parser/api/core/Params.kt | 16 + .../cas_parser/api/core/PhantomReachable.kt | 56 + .../com/cas_parser/api/core/PrepareRequest.kt | 24 + .../com/cas_parser/api/core/Properties.kt | 42 + .../com/cas_parser/api/core/RequestOptions.kt | 46 + .../kotlin/com/cas_parser/api/core/Timeout.kt | 171 + .../kotlin/com/cas_parser/api/core/Utils.kt | 115 + .../kotlin/com/cas_parser/api/core/Values.kt | 723 ++ .../api/core/handlers/ErrorHandler.kt | 84 + .../api/core/handlers/JsonHandler.kt | 20 + .../api/core/handlers/StringHandler.kt | 13 + .../api/core/http/AsyncStreamResponse.kt | 157 + .../com/cas_parser/api/core/http/Headers.kt | 115 + .../cas_parser/api/core/http/HttpClient.kt | 26 + .../cas_parser/api/core/http/HttpMethod.kt | 13 + .../cas_parser/api/core/http/HttpRequest.kt | 146 + .../api/core/http/HttpRequestBodies.kt | 130 + .../api/core/http/HttpRequestBody.kt | 25 + .../cas_parser/api/core/http/HttpResponse.kt | 22 + .../api/core/http/HttpResponseFor.kt | 25 + ...ntomReachableClosingAsyncStreamResponse.kt | 56 + .../http/PhantomReachableClosingHttpClient.kt | 26 + .../PhantomReachableClosingStreamResponse.kt | 21 + .../cas_parser/api/core/http/QueryParams.kt | 129 + .../api/core/http/RetryingHttpClient.kt | 288 + .../api/core/http/StreamResponse.kt | 19 + .../api/errors/BadRequestException.kt | 80 + .../api/errors/CasParserException.kt | 5 + .../errors/CasParserInvalidDataException.kt | 5 + .../api/errors/CasParserIoException.kt | 5 + .../api/errors/CasParserRetryableException.kt | 14 + .../api/errors/CasParserServiceException.kt | 17 + .../api/errors/InternalServerException.kt | 91 + .../api/errors/NotFoundException.kt | 76 + .../api/errors/PermissionDeniedException.kt | 80 + .../api/errors/RateLimitException.kt | 80 + .../api/errors/UnauthorizedException.kt | 80 + .../errors/UnexpectedStatusCodeException.kt | 92 + .../errors/UnprocessableEntityException.kt | 80 + .../CasGeneratorGenerateCasParams.kt | 918 ++ .../CasGeneratorGenerateCasResponse.kt | 188 + .../casparser/CasParserCamsKfintechParams.kt | 504 ++ .../models/casparser/CasParserCdslParams.kt | 501 ++ .../models/casparser/CasParserNsdlParams.kt | 501 ++ .../casparser/CasParserSmartParseParams.kt | 504 ++ .../api/models/casparser/UnifiedResponse.kt | 8005 +++++++++++++++++ .../async/CasGeneratorServiceAsync.kt | 73 + .../async/CasGeneratorServiceAsyncImpl.kt | 86 + .../services/async/CasParserServiceAsync.kt | 230 + .../async/CasParserServiceAsyncImpl.kt | 203 + .../services/blocking/CasGeneratorService.kt | 72 + .../blocking/CasGeneratorServiceImpl.kt | 82 + .../api/services/blocking/CasParserService.kt | 226 + .../services/blocking/CasParserServiceImpl.kt | 190 + .../proguard/cas-parser-java-core.pro | 32 + .../com/cas_parser/api/TestServerExtension.kt | 62 + .../cas_parser/api/core/ClientOptionsTest.kt | 34 + .../cas_parser/api/core/ObjectMappersTest.kt | 102 + .../api/core/PhantomReachableTest.kt | 27 + .../com/cas_parser/api/core/UtilsTest.kt | 33 + .../com/cas_parser/api/core/ValuesTest.kt | 144 + .../api/core/http/AsyncStreamResponseTest.kt | 268 + .../cas_parser/api/core/http/HeadersTest.kt | 242 + .../api/core/http/QueryParamsTest.kt | 180 + .../api/core/http/RetryingHttpClientTest.kt | 351 + .../CasGeneratorGenerateCasParamsTest.kt | 62 + .../CasGeneratorGenerateCasResponseTest.kt | 49 + .../CasParserCamsKfintechParamsTest.kt | 72 + .../casparser/CasParserCdslParamsTest.kt | 72 + .../casparser/CasParserNsdlParamsTest.kt | 72 + .../CasParserSmartParseParamsTest.kt | 72 + .../models/casparser/UnifiedResponseTest.kt | 623 ++ .../api/services/ErrorHandlingTest.kt | 503 ++ .../api/services/ServiceParamsTest.kt | 63 + .../async/CasGeneratorServiceAsyncTest.kt | 40 + .../async/CasParserServiceAsyncTest.kt | 109 + .../blocking/CasGeneratorServiceTest.kt | 39 + .../services/blocking/CasParserServiceTest.kt | 105 + cas-parser-java-example/build.gradle.kts | 28 + cas-parser-java-lib/.keep | 4 + .../build.gradle.kts | 103 + .../api/proguard/ProGuardCompatibilityTest.kt | 265 + cas-parser-java-proguard-test/test.pro | 8 + cas-parser-java/build.gradle.kts | 29 + gradle.properties | 18 + gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 43583 bytes gradle/wrapper/gradle-wrapper.properties | 7 + gradlew | 251 + gradlew.bat | 94 + scripts/build | 8 + scripts/format | 8 + scripts/lint | 8 + scripts/mock | 41 + scripts/test | 56 + settings.gradle.kts | 14 + 123 files changed, 23057 insertions(+), 1 deletion(-) create mode 100644 .devcontainer/Dockerfile create mode 100644 .devcontainer/devcontainer.json create mode 100644 .gitattributes create mode 100644 .github/workflows/ci.yml create mode 100644 .gitignore create mode 100644 .stats.yml create mode 100644 LICENSE create mode 100644 SECURITY.md create mode 100644 build.gradle.kts create mode 100644 buildSrc/build.gradle.kts create mode 100644 buildSrc/src/main/kotlin/cas-parser.java.gradle.kts create mode 100644 buildSrc/src/main/kotlin/cas-parser.kotlin.gradle.kts create mode 100644 buildSrc/src/main/kotlin/cas-parser.publish.gradle.kts create mode 100644 cas-parser-java-client-okhttp/build.gradle.kts create mode 100644 cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClient.kt create mode 100644 cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClientAsync.kt create mode 100644 cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/OkHttpClient.kt create mode 100644 cas-parser-java-core/build.gradle.kts create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClient.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientAsync.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientAsyncImpl.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientImpl.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/BaseDeserializer.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/BaseSerializer.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Check.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ClientOptions.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ObjectMappers.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Params.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/PhantomReachable.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/PrepareRequest.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Properties.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/RequestOptions.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Timeout.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Utils.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Values.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/handlers/ErrorHandler.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/handlers/JsonHandler.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/handlers/StringHandler.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/AsyncStreamResponse.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/Headers.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/HttpClient.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/HttpMethod.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/HttpRequest.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/HttpRequestBodies.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/HttpRequestBody.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/HttpResponse.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/HttpResponseFor.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/PhantomReachableClosingAsyncStreamResponse.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/PhantomReachableClosingHttpClient.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/PhantomReachableClosingStreamResponse.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/QueryParams.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/RetryingHttpClient.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/StreamResponse.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/BadRequestException.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/CasParserException.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/CasParserInvalidDataException.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/CasParserIoException.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/CasParserRetryableException.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/CasParserServiceException.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/InternalServerException.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/NotFoundException.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/PermissionDeniedException.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/RateLimitException.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/UnauthorizedException.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/UnexpectedStatusCodeException.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/UnprocessableEntityException.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casgenerator/CasGeneratorGenerateCasParams.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casgenerator/CasGeneratorGenerateCasResponse.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserCamsKfintechParams.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserCdslParams.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserNsdlParams.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserSmartParseParams.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/UnifiedResponse.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CasGeneratorServiceAsync.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CasGeneratorServiceAsyncImpl.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CasParserServiceAsync.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CasParserServiceAsyncImpl.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CasGeneratorService.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CasGeneratorServiceImpl.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CasParserService.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CasParserServiceImpl.kt create mode 100644 cas-parser-java-core/src/main/resources/META-INF/proguard/cas-parser-java-core.pro create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/TestServerExtension.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/ClientOptionsTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/ObjectMappersTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/PhantomReachableTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/UtilsTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/ValuesTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/AsyncStreamResponseTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/HeadersTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/QueryParamsTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/RetryingHttpClientTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casgenerator/CasGeneratorGenerateCasParamsTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casgenerator/CasGeneratorGenerateCasResponseTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserCamsKfintechParamsTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserCdslParamsTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserNsdlParamsTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserSmartParseParamsTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/UnifiedResponseTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/ErrorHandlingTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/ServiceParamsTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CasGeneratorServiceAsyncTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CasParserServiceAsyncTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CasGeneratorServiceTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CasParserServiceTest.kt create mode 100644 cas-parser-java-example/build.gradle.kts create mode 100644 cas-parser-java-lib/.keep create mode 100644 cas-parser-java-proguard-test/build.gradle.kts create mode 100644 cas-parser-java-proguard-test/src/test/kotlin/com/cas_parser/api/proguard/ProGuardCompatibilityTest.kt create mode 100644 cas-parser-java-proguard-test/test.pro create mode 100644 cas-parser-java/build.gradle.kts create mode 100644 gradle.properties create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100755 gradlew create mode 100644 gradlew.bat create mode 100755 scripts/build create mode 100755 scripts/format create mode 100755 scripts/lint create mode 100755 scripts/mock create mode 100755 scripts/test create mode 100644 settings.gradle.kts diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000..bd8e261 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,23 @@ +# syntax=docker/dockerfile:1 +FROM debian:bookworm-slim + +RUN apt-get update && apt-get install -y --no-install-recommends \ + libxkbcommon0 \ + ca-certificates \ + ca-certificates-java \ + make \ + curl \ + git \ + openjdk-17-jdk-headless \ + unzip \ + libc++1 \ + vim \ + && apt-get clean autoclean + +# Ensure UTF-8 encoding +ENV LANG=C.UTF-8 +ENV LC_ALL=C.UTF-8 + +WORKDIR /workspace + +COPY . /workspace diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..d55fc4d --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,20 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/debian +{ + "name": "Debian", + "build": { + "dockerfile": "Dockerfile" + } + + // Features to add to the dev container. More info: https://containers.dev/features. + // "features": {}, + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + + // Configure tool-specific properties. + // "customizations": {}, + + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. + // "remoteUser": "root" +} diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..022b841 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,5 @@ +# +# https://help.github.com/articles/dealing-with-line-endings/ +# +# These are explicitly windows files and should use crlf +*.bat text eol=crlf diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..eedd0cf --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,85 @@ +name: CI +on: + push: + branches-ignore: + - 'generated' + - 'codegen/**' + - 'integrated/**' + - 'stl-preview-head/**' + - 'stl-preview-base/**' + pull_request: + branches-ignore: + - 'stl-preview-head/**' + - 'stl-preview-base/**' + +jobs: + lint: + timeout-minutes: 15 + name: lint + runs-on: ${{ github.repository == 'stainless-sdks/cas-parser-java' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} + if: github.event_name == 'push' || github.event.pull_request.head.repo.fork + + steps: + - uses: actions/checkout@v4 + + - name: Set up Java + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: | + 8 + 21 + cache: gradle + + - name: Set up Gradle + uses: gradle/actions/setup-gradle@v4 + + - name: Run lints + run: ./scripts/lint + + build: + timeout-minutes: 15 + name: build + runs-on: ${{ github.repository == 'stainless-sdks/cas-parser-java' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} + if: github.event_name == 'push' || github.event.pull_request.head.repo.fork + + steps: + - uses: actions/checkout@v4 + + - name: Set up Java + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: | + 8 + 21 + cache: gradle + + - name: Set up Gradle + uses: gradle/actions/setup-gradle@v4 + + - name: Build SDK + run: ./scripts/build + + test: + timeout-minutes: 15 + name: test + runs-on: ${{ github.repository == 'stainless-sdks/cas-parser-java' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} + if: github.event_name == 'push' || github.event.pull_request.head.repo.fork + steps: + - uses: actions/checkout@v4 + + - name: Set up Java + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: | + 8 + 21 + cache: gradle + + - name: Set up Gradle + uses: gradle/gradle-build-action@v2 + + - name: Run tests + run: ./scripts/test diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b1346e6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.prism.log +.gradle +.idea +.kotlin +build/ +codegen.log +kls_database.db diff --git a/.stats.yml b/.stats.yml new file mode 100644 index 0000000..aa8116c --- /dev/null +++ b/.stats.yml @@ -0,0 +1,4 @@ +configured_endpoints: 5 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-b7fdba3d3f97c7debc22c7ca30b828bce81bcd64648df8c94029b27a3321ebb9.yml +openapi_spec_hash: 03f1315f1d32ada42445ca920f047dff +config_hash: 05034d55bf9f8573b1160f7825bcd9b9 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f1756ce --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2025 Cas Parser + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md index ac89b43..2709980 100644 --- a/README.md +++ b/README.md @@ -1 +1,610 @@ -# cas-parser-java \ No newline at end of file +# Cas Parser Java API Library + +[![Maven Central](https://img.shields.io/maven-central/v/com.cas_parser.api/cas-parser-java)](https://central.sonatype.com/artifact/com.cas_parser.api/cas-parser-java/0.0.1) +[![javadoc](https://javadoc.io/badge2/com.cas_parser.api/cas-parser-java/0.0.1/javadoc.svg)](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.0.1) + +The Cas Parser Java SDK provides convenient access to the [Cas Parser REST API](https://docs.casparser.in/reference) from applications written in Java. + +It is generated with [Stainless](https://www.stainless.com/). + +The REST API documentation can be found on [docs.casparser.in](https://docs.casparser.in/reference). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.0.1). + +## Installation + +### Gradle + +```kotlin +implementation("com.cas_parser.api:cas-parser-java:0.0.1") +``` + +### Maven + +```xml + + com.cas_parser.api + cas-parser-java + 0.0.1 + +``` + +## Requirements + +This library requires Java 8 or later. + +## Usage + +```java +import com.cas_parser.api.client.CasParserClient; +import com.cas_parser.api.client.okhttp.CasParserOkHttpClient; +import com.cas_parser.api.models.casparser.CasParserSmartParseParams; +import com.cas_parser.api.models.casparser.UnifiedResponse; + +// Configures using the `casparser.apiKey` and `casparser.baseUrl` system properties +// Or configures using the `CAS_PARSER_API_KEY` and `CAS_PARSER_BASE_URL` environment variables +CasParserClient client = CasParserOkHttpClient.fromEnv(); + +CasParserSmartParseParams params = CasParserSmartParseParams.builder() + .password("ABCDF") + .pdfUrl("https://your-cas-pdf-url-here.com") + .build(); +UnifiedResponse unifiedResponse = client.casParser().smartParse(params); +``` + +## Client configuration + +Configure the client using system properties or environment variables: + +```java +import com.cas_parser.api.client.CasParserClient; +import com.cas_parser.api.client.okhttp.CasParserOkHttpClient; + +// Configures using the `casparser.apiKey` and `casparser.baseUrl` system properties +// Or configures using the `CAS_PARSER_API_KEY` and `CAS_PARSER_BASE_URL` environment variables +CasParserClient client = CasParserOkHttpClient.fromEnv(); +``` + +Or manually: + +```java +import com.cas_parser.api.client.CasParserClient; +import com.cas_parser.api.client.okhttp.CasParserOkHttpClient; + +CasParserClient client = CasParserOkHttpClient.builder() + .apiKey("My API Key") + .build(); +``` + +Or using a combination of the two approaches: + +```java +import com.cas_parser.api.client.CasParserClient; +import com.cas_parser.api.client.okhttp.CasParserOkHttpClient; + +CasParserClient client = CasParserOkHttpClient.builder() + // Configures using the `casparser.apiKey` and `casparser.baseUrl` system properties + // Or configures using the `CAS_PARSER_API_KEY` and `CAS_PARSER_BASE_URL` environment variables + .fromEnv() + .apiKey("My API Key") + .build(); +``` + +See this table for the available options: + +| Setter | System property | Environment variable | Required | Default value | +| --------- | ------------------- | --------------------- | -------- | --------------------------------------------- | +| `apiKey` | `casparser.apiKey` | `CAS_PARSER_API_KEY` | true | - | +| `baseUrl` | `casparser.baseUrl` | `CAS_PARSER_BASE_URL` | true | `"https://portfolio-parser.api.casparser.in"` | + +System properties take precedence over environment variables. + +> [!TIP] +> Don't create more than one client in the same application. Each client has a connection pool and +> thread pools, which are more efficient to share between requests. + +### Modifying configuration + +To temporarily use a modified client configuration, while reusing the same connection and thread pools, call `withOptions()` on any client or service: + +```java +import com.cas_parser.api.client.CasParserClient; + +CasParserClient clientWithOptions = client.withOptions(optionsBuilder -> { + optionsBuilder.baseUrl("https://example.com"); + optionsBuilder.maxRetries(42); +}); +``` + +The `withOptions()` method does not affect the original client or service. + +## Requests and responses + +To send a request to the Cas Parser API, build an instance of some `Params` class and pass it to the corresponding client method. When the response is received, it will be deserialized into an instance of a Java class. + +For example, `client.casParser().smartParse(...)` should be called with an instance of `CasParserSmartParseParams`, and it will return an instance of `UnifiedResponse`. + +## Immutability + +Each class in the SDK has an associated [builder](https://blogs.oracle.com/javamagazine/post/exploring-joshua-blochs-builder-design-pattern-in-java) or factory method for constructing it. + +Each class is [immutable](https://docs.oracle.com/javase/tutorial/essential/concurrency/immutable.html) once constructed. If the class has an associated builder, then it has a `toBuilder()` method, which can be used to convert it back to a builder for making a modified copy. + +Because each class is immutable, builder modification will _never_ affect already built class instances. + +## Asynchronous execution + +The default client is synchronous. To switch to asynchronous execution, call the `async()` method: + +```java +import com.cas_parser.api.client.CasParserClient; +import com.cas_parser.api.client.okhttp.CasParserOkHttpClient; +import com.cas_parser.api.models.casparser.CasParserSmartParseParams; +import com.cas_parser.api.models.casparser.UnifiedResponse; +import java.util.concurrent.CompletableFuture; + +// Configures using the `casparser.apiKey` and `casparser.baseUrl` system properties +// Or configures using the `CAS_PARSER_API_KEY` and `CAS_PARSER_BASE_URL` environment variables +CasParserClient client = CasParserOkHttpClient.fromEnv(); + +CasParserSmartParseParams params = CasParserSmartParseParams.builder() + .password("ABCDF") + .pdfUrl("https://your-cas-pdf-url-here.com") + .build(); +CompletableFuture unifiedResponse = client.async().casParser().smartParse(params); +``` + +Or create an asynchronous client from the beginning: + +```java +import com.cas_parser.api.client.CasParserClientAsync; +import com.cas_parser.api.client.okhttp.CasParserOkHttpClientAsync; +import com.cas_parser.api.models.casparser.CasParserSmartParseParams; +import com.cas_parser.api.models.casparser.UnifiedResponse; +import java.util.concurrent.CompletableFuture; + +// Configures using the `casparser.apiKey` and `casparser.baseUrl` system properties +// Or configures using the `CAS_PARSER_API_KEY` and `CAS_PARSER_BASE_URL` environment variables +CasParserClientAsync client = CasParserOkHttpClientAsync.fromEnv(); + +CasParserSmartParseParams params = CasParserSmartParseParams.builder() + .password("ABCDF") + .pdfUrl("https://your-cas-pdf-url-here.com") + .build(); +CompletableFuture unifiedResponse = client.casParser().smartParse(params); +``` + +The asynchronous client supports the same options as the synchronous one, except most methods return `CompletableFuture`s. + +## Raw responses + +The SDK defines methods that deserialize responses into instances of Java classes. However, these methods don't provide access to the response headers, status code, or the raw response body. + +To access this data, prefix any HTTP method call on a client or service with `withRawResponse()`: + +```java +import com.cas_parser.api.core.http.Headers; +import com.cas_parser.api.core.http.HttpResponseFor; +import com.cas_parser.api.models.casparser.CasParserSmartParseParams; +import com.cas_parser.api.models.casparser.UnifiedResponse; + +CasParserSmartParseParams params = CasParserSmartParseParams.builder() + .password("ABCDF") + .pdfUrl("https://you-cas-pdf-url-here.com") + .build(); +HttpResponseFor unifiedResponse = client.casParser().withRawResponse().smartParse(params); + +int statusCode = unifiedResponse.statusCode(); +Headers headers = unifiedResponse.headers(); +``` + +You can still deserialize the response into an instance of a Java class if needed: + +```java +import com.cas_parser.api.models.casparser.UnifiedResponse; + +UnifiedResponse parsedUnifiedResponse = unifiedResponse.parse(); +``` + +## Error handling + +The SDK throws custom unchecked exception types: + +- [`CasParserServiceException`](cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/CasParserServiceException.kt): Base class for HTTP errors. See this table for which exception subclass is thrown for each HTTP status code: + + | Status | Exception | + | ------ | ---------------------------------------------------------------------------------------------------------------------------------- | + | 400 | [`BadRequestException`](cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/BadRequestException.kt) | + | 401 | [`UnauthorizedException`](cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/UnauthorizedException.kt) | + | 403 | [`PermissionDeniedException`](cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/PermissionDeniedException.kt) | + | 404 | [`NotFoundException`](cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/NotFoundException.kt) | + | 422 | [`UnprocessableEntityException`](cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/UnprocessableEntityException.kt) | + | 429 | [`RateLimitException`](cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/RateLimitException.kt) | + | 5xx | [`InternalServerException`](cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/InternalServerException.kt) | + | others | [`UnexpectedStatusCodeException`](cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/UnexpectedStatusCodeException.kt) | + +- [`CasParserIoException`](cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/CasParserIoException.kt): I/O networking errors. + +- [`CasParserRetryableException`](cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/CasParserRetryableException.kt): Generic error indicating a failure that could be retried by the client. + +- [`CasParserInvalidDataException`](cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/CasParserInvalidDataException.kt): Failure to interpret successfully parsed data. For example, when accessing a property that's supposed to be required, but the API unexpectedly omitted it from the response. + +- [`CasParserException`](cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/CasParserException.kt): Base class for all exceptions. Most errors will result in one of the previously mentioned ones, but completely generic errors may be thrown using the base class. + +## Logging + +The SDK uses the standard [OkHttp logging interceptor](https://github.com/square/okhttp/tree/master/okhttp-logging-interceptor). + +Enable logging by setting the `CAS_PARSER_LOG` environment variable to `info`: + +```sh +$ export CAS_PARSER_LOG=info +``` + +Or to `debug` for more verbose logging: + +```sh +$ export CAS_PARSER_LOG=debug +``` + +## ProGuard and R8 + +Although the SDK uses reflection, it is still usable with [ProGuard](https://github.com/Guardsquare/proguard) and [R8](https://developer.android.com/topic/performance/app-optimization/enable-app-optimization) because `cas-parser-java-core` is published with a [configuration file](cas-parser-java-core/src/main/resources/META-INF/proguard/cas-parser-java-core.pro) containing [keep rules](https://www.guardsquare.com/manual/configuration/usage). + +ProGuard and R8 should automatically detect and use the published rules, but you can also manually copy the keep rules if necessary. + +## Jackson + +The SDK depends on [Jackson](https://github.com/FasterXML/jackson) for JSON serialization/deserialization. It is compatible with version 2.13.4 or higher, but depends on version 2.18.2 by default. + +The SDK throws an exception if it detects an incompatible Jackson version at runtime (e.g. if the default version was overridden in your Maven or Gradle config). + +If the SDK threw an exception, but you're _certain_ the version is compatible, then disable the version check using the `checkJacksonVersionCompatibility` on [`CasParserOkHttpClient`](cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClient.kt) or [`CasParserOkHttpClientAsync`](cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClientAsync.kt). + +> [!CAUTION] +> We make no guarantee that the SDK works correctly when the Jackson version check is disabled. + +## Network options + +### Retries + +The SDK automatically retries 2 times by default, with a short exponential backoff between requests. + +Only the following error types are retried: + +- Connection errors (for example, due to a network connectivity problem) +- 408 Request Timeout +- 409 Conflict +- 429 Rate Limit +- 5xx Internal + +The API may also explicitly instruct the SDK to retry or not retry a request. + +To set a custom number of retries, configure the client using the `maxRetries` method: + +```java +import com.cas_parser.api.client.CasParserClient; +import com.cas_parser.api.client.okhttp.CasParserOkHttpClient; + +CasParserClient client = CasParserOkHttpClient.builder() + .fromEnv() + .maxRetries(4) + .build(); +``` + +### Timeouts + +Requests time out after 1 minute by default. + +To set a custom timeout, configure the method call using the `timeout` method: + +```java +import com.cas_parser.api.models.casparser.UnifiedResponse; + +UnifiedResponse unifiedResponse = client.casParser().smartParse(RequestOptions.builder().timeout(Duration.ofSeconds(30)).build()); +``` + +Or configure the default for all method calls at the client level: + +```java +import com.cas_parser.api.client.CasParserClient; +import com.cas_parser.api.client.okhttp.CasParserOkHttpClient; +import java.time.Duration; + +CasParserClient client = CasParserOkHttpClient.builder() + .fromEnv() + .timeout(Duration.ofSeconds(30)) + .build(); +``` + +### Proxies + +To route requests through a proxy, configure the client using the `proxy` method: + +```java +import com.cas_parser.api.client.CasParserClient; +import com.cas_parser.api.client.okhttp.CasParserOkHttpClient; +import java.net.InetSocketAddress; +import java.net.Proxy; + +CasParserClient client = CasParserOkHttpClient.builder() + .fromEnv() + .proxy(new Proxy( + Proxy.Type.HTTP, new InetSocketAddress( + "https://example.com", 8080 + ) + )) + .build(); +``` + +### HTTPS + +> [!NOTE] +> Most applications should not call these methods, and instead use the system defaults. The defaults include +> special optimizations that can be lost if the implementations are modified. + +To configure how HTTPS connections are secured, configure the client using the `sslSocketFactory`, `trustManager`, and `hostnameVerifier` methods: + +```java +import com.cas_parser.api.client.CasParserClient; +import com.cas_parser.api.client.okhttp.CasParserOkHttpClient; + +CasParserClient client = CasParserOkHttpClient.builder() + .fromEnv() + // If `sslSocketFactory` is set, then `trustManager` must be set, and vice versa. + .sslSocketFactory(yourSSLSocketFactory) + .trustManager(yourTrustManager) + .hostnameVerifier(yourHostnameVerifier) + .build(); +``` + +### Custom HTTP client + +The SDK consists of three artifacts: + +- `cas-parser-java-core` + - Contains core SDK logic + - Does not depend on [OkHttp](https://square.github.io/okhttp) + - Exposes [`CasParserClient`](cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClient.kt), [`CasParserClientAsync`](cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientAsync.kt), [`CasParserClientImpl`](cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientImpl.kt), and [`CasParserClientAsyncImpl`](cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientAsyncImpl.kt), all of which can work with any HTTP client +- `cas-parser-java-client-okhttp` + - Depends on [OkHttp](https://square.github.io/okhttp) + - Exposes [`CasParserOkHttpClient`](cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClient.kt) and [`CasParserOkHttpClientAsync`](cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClientAsync.kt), which provide a way to construct [`CasParserClientImpl`](cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientImpl.kt) and [`CasParserClientAsyncImpl`](cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientAsyncImpl.kt), respectively, using OkHttp +- `cas-parser-java` + - Depends on and exposes the APIs of both `cas-parser-java-core` and `cas-parser-java-client-okhttp` + - Does not have its own logic + +This structure allows replacing the SDK's default HTTP client without pulling in unnecessary dependencies. + +#### Customized [`OkHttpClient`](https://square.github.io/okhttp/3.x/okhttp/okhttp3/OkHttpClient.html) + +> [!TIP] +> Try the available [network options](#network-options) before replacing the default client. + +To use a customized `OkHttpClient`: + +1. Replace your [`cas-parser-java` dependency](#installation) with `cas-parser-java-core` +2. Copy `cas-parser-java-client-okhttp`'s [`OkHttpClient`](cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/OkHttpClient.kt) class into your code and customize it +3. Construct [`CasParserClientImpl`](cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientImpl.kt) or [`CasParserClientAsyncImpl`](cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientAsyncImpl.kt), similarly to [`CasParserOkHttpClient`](cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClient.kt) or [`CasParserOkHttpClientAsync`](cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClientAsync.kt), using your customized client + +### Completely custom HTTP client + +To use a completely custom HTTP client: + +1. Replace your [`cas-parser-java` dependency](#installation) with `cas-parser-java-core` +2. Write a class that implements the [`HttpClient`](cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/HttpClient.kt) interface +3. Construct [`CasParserClientImpl`](cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientImpl.kt) or [`CasParserClientAsyncImpl`](cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientAsyncImpl.kt), similarly to [`CasParserOkHttpClient`](cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClient.kt) or [`CasParserOkHttpClientAsync`](cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClientAsync.kt), using your new client class + +## Undocumented API functionality + +The SDK is typed for convenient usage of the documented API. However, it also supports working with undocumented or not yet supported parts of the API. + +### Parameters + +To set undocumented parameters, call the `putAdditionalHeader`, `putAdditionalQueryParam`, or `putAdditionalBodyProperty` methods on any `Params` class: + +```java +import com.cas_parser.api.core.JsonValue; +import com.cas_parser.api.models.casparser.CasParserSmartParseParams; + +CasParserSmartParseParams params = CasParserSmartParseParams.builder() + .putAdditionalHeader("Secret-Header", "42") + .putAdditionalQueryParam("secret_query_param", "42") + .putAdditionalBodyProperty("secretProperty", JsonValue.from("42")) + .build(); +``` + +These can be accessed on the built object later using the `_additionalHeaders()`, `_additionalQueryParams()`, and `_additionalBodyProperties()` methods. + +To set a documented parameter or property to an undocumented or not yet supported _value_, pass a [`JsonValue`](cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Values.kt) object to its setter: + +```java +import com.cas_parser.api.core.JsonValue; +import com.cas_parser.api.models.casparser.CasParserSmartParseParams; + +CasParserSmartParseParams params = CasParserSmartParseParams.builder() + .password(JsonValue.from(42)) + .pdfUrl("https://your-cas-pdf-url-here.com") + .build(); +``` + +The most straightforward way to create a [`JsonValue`](cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Values.kt) is using its `from(...)` method: + +```java +import com.cas_parser.api.core.JsonValue; +import java.util.List; +import java.util.Map; + +// Create primitive JSON values +JsonValue nullValue = JsonValue.from(null); +JsonValue booleanValue = JsonValue.from(true); +JsonValue numberValue = JsonValue.from(42); +JsonValue stringValue = JsonValue.from("Hello World!"); + +// Create a JSON array value equivalent to `["Hello", "World"]` +JsonValue arrayValue = JsonValue.from(List.of( + "Hello", "World" +)); + +// Create a JSON object value equivalent to `{ "a": 1, "b": 2 }` +JsonValue objectValue = JsonValue.from(Map.of( + "a", 1, + "b", 2 +)); + +// Create an arbitrarily nested JSON equivalent to: +// { +// "a": [1, 2], +// "b": [3, 4] +// } +JsonValue complexValue = JsonValue.from(Map.of( + "a", List.of( + 1, 2 + ), + "b", List.of( + 3, 4 + ) +)); +``` + +Normally a `Builder` class's `build` method will throw [`IllegalStateException`](https://docs.oracle.com/javase/8/docs/api/java/lang/IllegalStateException.html) if any required parameter or property is unset. + +To forcibly omit a required parameter or property, pass [`JsonMissing`](cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Values.kt): + +```java +import com.cas_parser.api.core.JsonMissing; +import com.cas_parser.api.models.casgenerator.CasGeneratorGenerateCasParams; +import com.cas_parser.api.models.casparser.CasParserSmartParseParams; + +CasParserSmartParseParams params = CasGeneratorGenerateCasParams.builder() + .fromDate("2023-01-01") + .password("Abcdefghi12$") + .toDate("2023-12-31") + .email(JsonMissing.of()) + .build(); +``` + +### Response properties + +To access undocumented response properties, call the `_additionalProperties()` method: + +```java +import com.cas_parser.api.core.JsonValue; +import java.util.Map; + +Map additionalProperties = client.casParser().smartParse(params)._additionalProperties(); +JsonValue secretPropertyValue = additionalProperties.get("secretProperty"); + +String result = secretPropertyValue.accept(new JsonValue.Visitor<>() { + @Override + public String visitNull() { + return "It's null!"; + } + + @Override + public String visitBoolean(boolean value) { + return "It's a boolean!"; + } + + @Override + public String visitNumber(Number value) { + return "It's a number!"; + } + + // Other methods include `visitMissing`, `visitString`, `visitArray`, and `visitObject` + // The default implementation of each unimplemented method delegates to `visitDefault`, which throws by default, but can also be overridden +}); +``` + +To access a property's raw JSON value, which may be undocumented, call its `_` prefixed method: + +```java +import com.cas_parser.api.core.JsonField; +import java.util.Optional; + +JsonField password = client.casParser().smartParse(params)._password(); + +if (password.isMissing()) { + // The property is absent from the JSON response +} else if (password.isNull()) { + // The property was set to literal null +} else { + // Check if value was provided as a string + // Other methods include `asNumber()`, `asBoolean()`, etc. + Optional jsonString = password.asString(); + + // Try to deserialize into a custom type + MyClass myObject = password.asUnknown().orElseThrow().convert(MyClass.class); +} +``` + +### Response validation + +In rare cases, the API may return a response that doesn't match the expected type. For example, the SDK may expect a property to contain a `String`, but the API could return something else. + +By default, the SDK will not throw an exception in this case. It will throw [`CasParserInvalidDataException`](cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/CasParserInvalidDataException.kt) only if you directly access the property. + +If you would prefer to check that the response is completely well-typed upfront, then either call `validate()`: + +```java +import com.cas_parser.api.models.casparser.UnifiedResponse; + +UnifiedResponse unifiedResponse = client.casParser().smartParse(params).validate(); +``` + +Or configure the method call to validate the response using the `responseValidation` method: + +```java +import com.cas_parser.api.models.casparser.UnifiedResponse; + +UnifiedResponse unifiedResponse = client.casParser().smartParse(RequestOptions.builder().responseValidation(true).build()); +``` + +Or configure the default for all method calls at the client level: + +```java +import com.cas_parser.api.client.CasParserClient; +import com.cas_parser.api.client.okhttp.CasParserOkHttpClient; + +CasParserClient client = CasParserOkHttpClient.builder() + .fromEnv() + .responseValidation(true) + .build(); +``` + +## FAQ + +### Why don't you use plain `enum` classes? + +Java `enum` classes are not trivially [forwards compatible](https://www.stainless.com/blog/making-java-enums-forwards-compatible). Using them in the SDK could cause runtime exceptions if the API is updated to respond with a new enum value. + +### Why do you represent fields using `JsonField` instead of just plain `T`? + +Using `JsonField` enables a few features: + +- Allowing usage of [undocumented API functionality](#undocumented-api-functionality) +- Lazily [validating the API response against the expected shape](#response-validation) +- Representing absent vs explicitly null values + +### Why don't you use [`data` classes](https://kotlinlang.org/docs/data-classes.html)? + +It is not [backwards compatible to add new fields to a data class](https://kotlinlang.org/docs/api-guidelines-backward-compatibility.html#avoid-using-data-classes-in-your-api) and we don't want to introduce a breaking change every time we add a field to a class. + +### Why don't you use checked exceptions? + +Checked exceptions are widely considered a mistake in the Java programming language. In fact, they were omitted from Kotlin for this reason. + +Checked exceptions: + +- Are verbose to handle +- Encourage error handling at the wrong level of abstraction, where nothing can be done about the error +- Are tedious to propagate due to the [function coloring problem](https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function) +- Don't play well with lambdas (also due to the function coloring problem) + +## Semantic versioning + +This package generally follows [SemVer](https://semver.org/spec/v2.0.0.html) conventions, though certain backwards-incompatible changes may be released as minor versions: + +1. Changes to library internals which are technically public but not intended or documented for external use. _(Please open a GitHub issue to let us know if you are relying on such internals.)_ +2. Changes that we do not expect to impact the vast majority of users in practice. + +We take backwards-compatibility seriously and work hard to ensure you can rely on a smooth upgrade experience. + +We are keen for your feedback; please open an [issue](https://www.github.com/stainless-sdks/cas-parser-java/issues) with questions, bugs, or suggestions. diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..62f7dbe --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,27 @@ +# Security Policy + +## Reporting Security Issues + +This SDK is generated by [Stainless Software Inc](http://stainless.com). Stainless takes security seriously, and encourages you to report any security vulnerability promptly so that appropriate action can be taken. + +To report a security issue, please contact the Stainless team at security@stainless.com. + +## Responsible Disclosure + +We appreciate the efforts of security researchers and individuals who help us maintain the security of +SDKs we generate. If you believe you have found a security vulnerability, please adhere to responsible +disclosure practices by allowing us a reasonable amount of time to investigate and address the issue +before making any information public. + +## Reporting Non-SDK Related Security Issues + +If you encounter security issues that are not directly related to SDKs but pertain to the services +or products provided by Cas Parser, please follow the respective company's security reporting guidelines. + +### Cas Parser Terms and Policies + +Please contact sameer@casparser.in for any questions or concerns regarding the security of our services. + +--- + +Thank you for helping us keep the SDKs and systems they interact with secure. diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000..734b874 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,49 @@ +plugins { + id("io.github.gradle-nexus.publish-plugin") version "1.1.0" + id("org.jetbrains.dokka") version "2.0.0" +} + +repositories { + mavenCentral() +} + +allprojects { + group = "com.cas_parser.api" + version = "0.0.1" +} + +subprojects { + // These are populated with dependencies by `buildSrc` scripts. + tasks.register("format") { + group = "Verification" + description = "Formats all source files." + } + tasks.register("lint") { + group = "Verification" + description = "Verifies all source files are formatted." + } + apply(plugin = "org.jetbrains.dokka") +} + +subprojects { + apply(plugin = "org.jetbrains.dokka") +} + +// Avoid race conditions between `dokkaJavadocCollector` and `dokkaJavadocJar` tasks +tasks.named("dokkaJavadocCollector").configure { + subprojects.flatMap { it.tasks } + .filter { it.project.name != "cas-parser-java" && it.name == "dokkaJavadocJar" } + .forEach { mustRunAfter(it) } +} + +nexusPublishing { + repositories { + sonatype { + nexusUrl.set(uri("https://s01.oss.sonatype.org/service/local/")) + snapshotRepositoryUrl.set(uri("https://s01.oss.sonatype.org/content/repositories/snapshots/")) + + username.set(System.getenv("SONATYPE_USERNAME")) + password.set(System.getenv("SONATYPE_PASSWORD")) + } + } +} diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts new file mode 100644 index 0000000..0b14135 --- /dev/null +++ b/buildSrc/build.gradle.kts @@ -0,0 +1,12 @@ +plugins { + `kotlin-dsl` + kotlin("jvm") version "1.9.20" +} + +repositories { + gradlePluginPortal() +} + +dependencies { + implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.20") +} diff --git a/buildSrc/src/main/kotlin/cas-parser.java.gradle.kts b/buildSrc/src/main/kotlin/cas-parser.java.gradle.kts new file mode 100644 index 0000000..81d5d32 --- /dev/null +++ b/buildSrc/src/main/kotlin/cas-parser.java.gradle.kts @@ -0,0 +1,136 @@ +import org.gradle.api.tasks.testing.logging.TestExceptionFormat + +plugins { + `java-library` +} + +repositories { + mavenCentral() +} + +configure { + withJavadocJar() + withSourcesJar() +} + +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(21)) + } + + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 +} + +tasks.withType().configureEach { + options.compilerArgs.add("-Werror") + options.release.set(8) +} + +tasks.named("javadocJar") { + setZip64(true) +} + +tasks.named("jar") { + manifest { + attributes(mapOf( + "Implementation-Title" to project.name, + "Implementation-Version" to project.version + )) + } +} + +tasks.withType().configureEach { + useJUnitPlatform() + + // Run tests in parallel to some degree. + maxParallelForks = (Runtime.getRuntime().availableProcessors() / 2).coerceAtLeast(1) + forkEvery = 100 + + testLogging { + exceptionFormat = TestExceptionFormat.FULL + } +} + +val palantir by configurations.creating +dependencies { + palantir("com.palantir.javaformat:palantir-java-format:2.73.0") +} + +fun registerPalantir( + name: String, + description: String, +) { + val javaName = "${name}Java" + tasks.register(javaName) { + group = "Verification" + this.description = description + + classpath = palantir + mainClass = "com.palantir.javaformat.java.Main" + + // Avoid an `IllegalAccessError` on Java 9+. + jvmArgs( + "--add-exports", "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED", + "--add-exports", "jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED", + "--add-exports", "jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED", + "--add-exports", "jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED", + "--add-exports", "jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED", + ) + + // Use paths relative to the current module. + val argumentFile = + project.layout.buildDirectory.file("palantir-$name-args.txt").get().asFile + val lastRunTimeFile = + project.layout.buildDirectory.file("palantir-$name-last-run.txt").get().asFile + + // Read the time when this task was last executed for this module (if ever). + val lastRunTime = lastRunTimeFile.takeIf { it.exists() }?.readText()?.toLongOrNull() ?: 0L + + // Use a `fileTree` relative to the module's source directory. + val javaFiles = project.fileTree("src") { include("**/*.java") } + + // Determine if any files need to be formatted or linted and continue only if there is at least + // one file. + onlyIf { javaFiles.any { it.lastModified() > lastRunTime } } + + inputs.files(javaFiles) + + doFirst { + // Create the argument file and set the preferred formatting style. + argumentFile.parentFile.mkdirs() + argumentFile.writeText("--palantir\n") + + if (name == "lint") { + // For lint, do a dry run, so no files are modified. Set the exit code to 1 (instead of + // the default 0) if any files need to be formatted, indicating that linting has failed. + argumentFile.appendText("--dry-run\n") + argumentFile.appendText("--set-exit-if-changed\n") + } else { + // `--dry-run` and `--replace` (for in-place formatting) are mutually exclusive. + argumentFile.appendText("--replace\n") + } + + // Write the modified files to the argument file. + javaFiles.filter { it.lastModified() > lastRunTime } + .forEach { argumentFile.appendText("${it.absolutePath}\n") } + } + + doLast { + // Record the last execution time for later up-to-date checking. + lastRunTimeFile.writeText(System.currentTimeMillis().toString()) + } + + // Pass the argument file using the @ symbol + args = listOf("@${argumentFile.absolutePath}") + + outputs.upToDateWhen { javaFiles.none { it.lastModified() > lastRunTime } } + } + + tasks.named(name) { + dependsOn(tasks.named(javaName)) + } +} + +registerPalantir(name = "format", description = "Formats all Java source files.") +registerPalantir(name = "lint", description = "Verifies all Java source files are formatted.") diff --git a/buildSrc/src/main/kotlin/cas-parser.kotlin.gradle.kts b/buildSrc/src/main/kotlin/cas-parser.kotlin.gradle.kts new file mode 100644 index 0000000..89a07ea --- /dev/null +++ b/buildSrc/src/main/kotlin/cas-parser.kotlin.gradle.kts @@ -0,0 +1,106 @@ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget +import org.jetbrains.kotlin.gradle.dsl.KotlinVersion + +plugins { + id("cas-parser.java") + kotlin("jvm") +} + +repositories { + mavenCentral() +} + +kotlin { + jvmToolchain { + languageVersion.set(JavaLanguageVersion.of(21)) + } + + compilerOptions { + freeCompilerArgs = listOf( + "-Xjvm-default=all", + "-Xjdk-release=1.8", + // Suppress deprecation warnings because we may still reference and test deprecated members. + // TODO: Replace with `-Xsuppress-warning=DEPRECATION` once we use Kotlin compiler 2.1.0+. + "-nowarn", + ) + jvmTarget.set(JvmTarget.JVM_1_8) + languageVersion.set(KotlinVersion.KOTLIN_1_8) + apiVersion.set(KotlinVersion.KOTLIN_1_8) + coreLibrariesVersion = "1.8.0" + } +} + +tasks.withType().configureEach { + systemProperty("junit.jupiter.execution.parallel.enabled", true) + systemProperty("junit.jupiter.execution.parallel.mode.default", "concurrent") +} + +val ktfmt by configurations.creating +dependencies { + ktfmt("com.facebook:ktfmt:0.56") +} + +fun registerKtfmt( + name: String, + description: String, +) { + val kotlinName = "${name}Kotlin" + tasks.register(kotlinName) { + group = "Verification" + this.description = description + + classpath = ktfmt + mainClass = "com.facebook.ktfmt.cli.Main" + + // Use paths relative to the current module. + val argumentFile = project.layout.buildDirectory.file("ktfmt-$name-args.txt").get().asFile + val lastRunTimeFile = + project.layout.buildDirectory.file("ktfmt-$name-last-run.txt").get().asFile + + // Read the time when this task was last executed for this module (if ever). + val lastRunTime = lastRunTimeFile.takeIf { it.exists() }?.readText()?.toLongOrNull() ?: 0L + + // Use a `fileTree` relative to the module's source directory. + val kotlinFiles = project.fileTree("src") { include("**/*.kt") } + + // Determine if any files need to be formatted or linted and continue only if there is at least + // one file (otherwise Ktfmt will fail). + onlyIf { kotlinFiles.any { it.lastModified() > lastRunTime } } + + inputs.files(kotlinFiles) + + doFirst { + // Create the argument file and set the preferred formatting style. + argumentFile.parentFile.mkdirs() + argumentFile.writeText("--kotlinlang-style\n") + + if (name == "lint") { + // For lint, do a dry run, so no files are modified. Set the exit code to 1 (instead of + // the default 0) if any files need to be formatted, indicating that linting has failed. + argumentFile.appendText("--dry-run\n") + argumentFile.appendText("--set-exit-if-changed\n") + } + + // Write the modified files to the argument file. + kotlinFiles.filter { it.lastModified() > lastRunTime } + .forEach { argumentFile.appendText("${it.absolutePath}\n") } + } + + doLast { + // Record the last execution time for later up-to-date checking. + lastRunTimeFile.writeText(System.currentTimeMillis().toString()) + } + + // Pass the argument file using the @ symbol + args = listOf("@${argumentFile.absolutePath}") + + outputs.upToDateWhen { kotlinFiles.none { it.lastModified() > lastRunTime } } + } + + tasks.named(name) { + dependsOn(tasks.named(kotlinName)) + } +} + +registerKtfmt(name = "format", description = "Formats all Kotlin source files.") +registerKtfmt(name = "lint", description = "Verifies all Kotlin source files are formatted.") diff --git a/buildSrc/src/main/kotlin/cas-parser.publish.gradle.kts b/buildSrc/src/main/kotlin/cas-parser.publish.gradle.kts new file mode 100644 index 0000000..12e6487 --- /dev/null +++ b/buildSrc/src/main/kotlin/cas-parser.publish.gradle.kts @@ -0,0 +1,61 @@ +plugins { + `maven-publish` + signing +} + +configure { + publications { + register("maven") { + from(components["java"]) + + pom { + name.set("CAS Parser - Track Portfolios from CDSL, NSDL, CAMS, KFintech") + description.set("API for parsing and analyzing CAS (Consolidated Account Statement) PDF files\nfrom NSDL, CDSL, and CAMS/KFintech, with a unified response format") + url.set("https://docs.casparser.in/reference") + + licenses { + license { + name.set("Apache-2.0") + } + } + + developers { + developer { + name.set("Cas Parser") + email.set("sameer@casparser.in") + } + } + + scm { + connection.set("scm:git:git://github.com/stainless-sdks/cas-parser-java.git") + developerConnection.set("scm:git:git://github.com/stainless-sdks/cas-parser-java.git") + url.set("https://github.com/stainless-sdks/cas-parser-java") + } + + versionMapping { + allVariants { + fromResolutionResult() + } + } + } + } + } +} + +signing { + val signingKeyId = System.getenv("GPG_SIGNING_KEY_ID")?.ifBlank { null } + val signingKey = System.getenv("GPG_SIGNING_KEY")?.ifBlank { null } + val signingPassword = System.getenv("GPG_SIGNING_PASSWORD")?.ifBlank { null } + if (signingKey != null && signingPassword != null) { + useInMemoryPgpKeys( + signingKeyId, + signingKey, + signingPassword, + ) + sign(publishing.publications["maven"]) + } +} + +tasks.named("publish") { + dependsOn(":closeAndReleaseSonatypeStagingRepository") +} diff --git a/cas-parser-java-client-okhttp/build.gradle.kts b/cas-parser-java-client-okhttp/build.gradle.kts new file mode 100644 index 0000000..115d28c --- /dev/null +++ b/cas-parser-java-client-okhttp/build.gradle.kts @@ -0,0 +1,14 @@ +plugins { + id("cas-parser.kotlin") + id("cas-parser.publish") +} + +dependencies { + api(project(":cas-parser-java-core")) + + implementation("com.squareup.okhttp3:okhttp:4.12.0") + implementation("com.squareup.okhttp3:logging-interceptor:4.12.0") + + testImplementation(kotlin("test")) + testImplementation("org.assertj:assertj-core:3.25.3") +} diff --git a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClient.kt b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClient.kt new file mode 100644 index 0000000..687527a --- /dev/null +++ b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClient.kt @@ -0,0 +1,296 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.client.okhttp + +import com.cas_parser.api.client.CasParserClient +import com.cas_parser.api.client.CasParserClientImpl +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.Timeout +import com.cas_parser.api.core.http.Headers +import com.cas_parser.api.core.http.HttpClient +import com.cas_parser.api.core.http.QueryParams +import com.cas_parser.api.core.jsonMapper +import com.fasterxml.jackson.databind.json.JsonMapper +import java.net.Proxy +import java.time.Clock +import java.time.Duration +import java.util.Optional +import javax.net.ssl.HostnameVerifier +import javax.net.ssl.SSLSocketFactory +import javax.net.ssl.X509TrustManager +import kotlin.jvm.optionals.getOrNull + +/** + * A class that allows building an instance of [CasParserClient] with [OkHttpClient] as the + * underlying [HttpClient]. + */ +class CasParserOkHttpClient private constructor() { + + companion object { + + /** Returns a mutable builder for constructing an instance of [CasParserClient]. */ + @JvmStatic fun builder() = Builder() + + /** + * Returns a client configured using system properties and environment variables. + * + * @see ClientOptions.Builder.fromEnv + */ + @JvmStatic fun fromEnv(): CasParserClient = builder().fromEnv().build() + } + + /** A builder for [CasParserOkHttpClient]. */ + class Builder internal constructor() { + + private var clientOptions: ClientOptions.Builder = ClientOptions.builder() + private var proxy: Proxy? = null + private var sslSocketFactory: SSLSocketFactory? = null + private var trustManager: X509TrustManager? = null + private var hostnameVerifier: HostnameVerifier? = null + + fun proxy(proxy: Proxy?) = apply { this.proxy = proxy } + + /** Alias for calling [Builder.proxy] with `proxy.orElse(null)`. */ + fun proxy(proxy: Optional) = proxy(proxy.getOrNull()) + + /** + * The socket factory used to secure HTTPS connections. + * + * If this is set, then [trustManager] must also be set. + * + * If unset, then the system default is used. Most applications should not call this method, + * and instead use the system default. The default include special optimizations that can be + * lost if the implementation is modified. + */ + fun sslSocketFactory(sslSocketFactory: SSLSocketFactory?) = apply { + this.sslSocketFactory = sslSocketFactory + } + + /** Alias for calling [Builder.sslSocketFactory] with `sslSocketFactory.orElse(null)`. */ + fun sslSocketFactory(sslSocketFactory: Optional) = + sslSocketFactory(sslSocketFactory.getOrNull()) + + /** + * The trust manager used to secure HTTPS connections. + * + * If this is set, then [sslSocketFactory] must also be set. + * + * If unset, then the system default is used. Most applications should not call this method, + * and instead use the system default. The default include special optimizations that can be + * lost if the implementation is modified. + */ + fun trustManager(trustManager: X509TrustManager?) = apply { + this.trustManager = trustManager + } + + /** Alias for calling [Builder.trustManager] with `trustManager.orElse(null)`. */ + fun trustManager(trustManager: Optional) = + trustManager(trustManager.getOrNull()) + + /** + * The verifier used to confirm that response certificates apply to requested hostnames for + * HTTPS connections. + * + * If unset, then a default hostname verifier is used. + */ + fun hostnameVerifier(hostnameVerifier: HostnameVerifier?) = apply { + this.hostnameVerifier = hostnameVerifier + } + + /** Alias for calling [Builder.hostnameVerifier] with `hostnameVerifier.orElse(null)`. */ + fun hostnameVerifier(hostnameVerifier: Optional) = + hostnameVerifier(hostnameVerifier.getOrNull()) + + /** + * Whether to throw an exception if any of the Jackson versions detected at runtime are + * incompatible with the SDK's minimum supported Jackson version (2.13.4). + * + * Defaults to true. Use extreme caution when disabling this option. There is no guarantee + * that the SDK will work correctly when using an incompatible Jackson version. + */ + fun checkJacksonVersionCompatibility(checkJacksonVersionCompatibility: Boolean) = apply { + clientOptions.checkJacksonVersionCompatibility(checkJacksonVersionCompatibility) + } + + /** + * The Jackson JSON mapper to use for serializing and deserializing JSON. + * + * Defaults to [com.cas_parser.api.core.jsonMapper]. The default is usually sufficient and + * rarely needs to be overridden. + */ + fun jsonMapper(jsonMapper: JsonMapper) = apply { clientOptions.jsonMapper(jsonMapper) } + + /** + * The clock to use for operations that require timing, like retries. + * + * This is primarily useful for using a fake clock in tests. + * + * Defaults to [Clock.systemUTC]. + */ + fun clock(clock: Clock) = apply { clientOptions.clock(clock) } + + /** + * The base URL to use for every request. + * + * Defaults to the production environment: `https://portfolio-parser.api.casparser.in`. + */ + fun baseUrl(baseUrl: String?) = apply { clientOptions.baseUrl(baseUrl) } + + /** Alias for calling [Builder.baseUrl] with `baseUrl.orElse(null)`. */ + fun baseUrl(baseUrl: Optional) = baseUrl(baseUrl.getOrNull()) + + /** + * Whether to call `validate` on every response before returning it. + * + * Defaults to false, which means the shape of the response will not be validated upfront. + * Instead, validation will only occur for the parts of the response that are accessed. + */ + fun responseValidation(responseValidation: Boolean) = apply { + clientOptions.responseValidation(responseValidation) + } + + /** + * Sets the maximum time allowed for various parts of an HTTP call's lifecycle, excluding + * retries. + * + * Defaults to [Timeout.default]. + */ + fun timeout(timeout: Timeout) = apply { clientOptions.timeout(timeout) } + + /** + * Sets the maximum time allowed for a complete HTTP call, not including retries. + * + * See [Timeout.request] for more details. + * + * For fine-grained control, pass a [Timeout] object. + */ + fun timeout(timeout: Duration) = apply { clientOptions.timeout(timeout) } + + /** + * The maximum number of times to retry failed requests, with a short exponential backoff + * between requests. + * + * Only the following error types are retried: + * - Connection errors (for example, due to a network connectivity problem) + * - 408 Request Timeout + * - 409 Conflict + * - 429 Rate Limit + * - 5xx Internal + * + * The API may also explicitly instruct the SDK to retry or not retry a request. + * + * Defaults to 2. + */ + fun maxRetries(maxRetries: Int) = apply { clientOptions.maxRetries(maxRetries) } + + /** Your API key for authentication. Use `sandbox-with-json-responses` as Sandbox key. */ + fun apiKey(apiKey: String) = apply { clientOptions.apiKey(apiKey) } + + fun headers(headers: Headers) = apply { clientOptions.headers(headers) } + + fun headers(headers: Map>) = apply { + clientOptions.headers(headers) + } + + fun putHeader(name: String, value: String) = apply { clientOptions.putHeader(name, value) } + + fun putHeaders(name: String, values: Iterable) = apply { + clientOptions.putHeaders(name, values) + } + + fun putAllHeaders(headers: Headers) = apply { clientOptions.putAllHeaders(headers) } + + fun putAllHeaders(headers: Map>) = apply { + clientOptions.putAllHeaders(headers) + } + + fun replaceHeaders(name: String, value: String) = apply { + clientOptions.replaceHeaders(name, value) + } + + fun replaceHeaders(name: String, values: Iterable) = apply { + clientOptions.replaceHeaders(name, values) + } + + fun replaceAllHeaders(headers: Headers) = apply { clientOptions.replaceAllHeaders(headers) } + + fun replaceAllHeaders(headers: Map>) = apply { + clientOptions.replaceAllHeaders(headers) + } + + fun removeHeaders(name: String) = apply { clientOptions.removeHeaders(name) } + + fun removeAllHeaders(names: Set) = apply { clientOptions.removeAllHeaders(names) } + + fun queryParams(queryParams: QueryParams) = apply { clientOptions.queryParams(queryParams) } + + fun queryParams(queryParams: Map>) = apply { + clientOptions.queryParams(queryParams) + } + + fun putQueryParam(key: String, value: String) = apply { + clientOptions.putQueryParam(key, value) + } + + fun putQueryParams(key: String, values: Iterable) = apply { + clientOptions.putQueryParams(key, values) + } + + fun putAllQueryParams(queryParams: QueryParams) = apply { + clientOptions.putAllQueryParams(queryParams) + } + + fun putAllQueryParams(queryParams: Map>) = apply { + clientOptions.putAllQueryParams(queryParams) + } + + fun replaceQueryParams(key: String, value: String) = apply { + clientOptions.replaceQueryParams(key, value) + } + + fun replaceQueryParams(key: String, values: Iterable) = apply { + clientOptions.replaceQueryParams(key, values) + } + + fun replaceAllQueryParams(queryParams: QueryParams) = apply { + clientOptions.replaceAllQueryParams(queryParams) + } + + fun replaceAllQueryParams(queryParams: Map>) = apply { + clientOptions.replaceAllQueryParams(queryParams) + } + + fun removeQueryParams(key: String) = apply { clientOptions.removeQueryParams(key) } + + fun removeAllQueryParams(keys: Set) = apply { + clientOptions.removeAllQueryParams(keys) + } + + /** + * Updates configuration using system properties and environment variables. + * + * @see ClientOptions.Builder.fromEnv + */ + fun fromEnv() = apply { clientOptions.fromEnv() } + + /** + * Returns an immutable instance of [CasParserClient]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): CasParserClient = + CasParserClientImpl( + clientOptions + .httpClient( + OkHttpClient.builder() + .timeout(clientOptions.timeout()) + .proxy(proxy) + .sslSocketFactory(sslSocketFactory) + .trustManager(trustManager) + .hostnameVerifier(hostnameVerifier) + .build() + ) + .build() + ) + } +} diff --git a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClientAsync.kt b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClientAsync.kt new file mode 100644 index 0000000..186bbe4 --- /dev/null +++ b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClientAsync.kt @@ -0,0 +1,296 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.client.okhttp + +import com.cas_parser.api.client.CasParserClientAsync +import com.cas_parser.api.client.CasParserClientAsyncImpl +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.Timeout +import com.cas_parser.api.core.http.Headers +import com.cas_parser.api.core.http.HttpClient +import com.cas_parser.api.core.http.QueryParams +import com.cas_parser.api.core.jsonMapper +import com.fasterxml.jackson.databind.json.JsonMapper +import java.net.Proxy +import java.time.Clock +import java.time.Duration +import java.util.Optional +import javax.net.ssl.HostnameVerifier +import javax.net.ssl.SSLSocketFactory +import javax.net.ssl.X509TrustManager +import kotlin.jvm.optionals.getOrNull + +/** + * A class that allows building an instance of [CasParserClientAsync] with [OkHttpClient] as the + * underlying [HttpClient]. + */ +class CasParserOkHttpClientAsync private constructor() { + + companion object { + + /** Returns a mutable builder for constructing an instance of [CasParserClientAsync]. */ + @JvmStatic fun builder() = Builder() + + /** + * Returns a client configured using system properties and environment variables. + * + * @see ClientOptions.Builder.fromEnv + */ + @JvmStatic fun fromEnv(): CasParserClientAsync = builder().fromEnv().build() + } + + /** A builder for [CasParserOkHttpClientAsync]. */ + class Builder internal constructor() { + + private var clientOptions: ClientOptions.Builder = ClientOptions.builder() + private var proxy: Proxy? = null + private var sslSocketFactory: SSLSocketFactory? = null + private var trustManager: X509TrustManager? = null + private var hostnameVerifier: HostnameVerifier? = null + + fun proxy(proxy: Proxy?) = apply { this.proxy = proxy } + + /** Alias for calling [Builder.proxy] with `proxy.orElse(null)`. */ + fun proxy(proxy: Optional) = proxy(proxy.getOrNull()) + + /** + * The socket factory used to secure HTTPS connections. + * + * If this is set, then [trustManager] must also be set. + * + * If unset, then the system default is used. Most applications should not call this method, + * and instead use the system default. The default include special optimizations that can be + * lost if the implementation is modified. + */ + fun sslSocketFactory(sslSocketFactory: SSLSocketFactory?) = apply { + this.sslSocketFactory = sslSocketFactory + } + + /** Alias for calling [Builder.sslSocketFactory] with `sslSocketFactory.orElse(null)`. */ + fun sslSocketFactory(sslSocketFactory: Optional) = + sslSocketFactory(sslSocketFactory.getOrNull()) + + /** + * The trust manager used to secure HTTPS connections. + * + * If this is set, then [sslSocketFactory] must also be set. + * + * If unset, then the system default is used. Most applications should not call this method, + * and instead use the system default. The default include special optimizations that can be + * lost if the implementation is modified. + */ + fun trustManager(trustManager: X509TrustManager?) = apply { + this.trustManager = trustManager + } + + /** Alias for calling [Builder.trustManager] with `trustManager.orElse(null)`. */ + fun trustManager(trustManager: Optional) = + trustManager(trustManager.getOrNull()) + + /** + * The verifier used to confirm that response certificates apply to requested hostnames for + * HTTPS connections. + * + * If unset, then a default hostname verifier is used. + */ + fun hostnameVerifier(hostnameVerifier: HostnameVerifier?) = apply { + this.hostnameVerifier = hostnameVerifier + } + + /** Alias for calling [Builder.hostnameVerifier] with `hostnameVerifier.orElse(null)`. */ + fun hostnameVerifier(hostnameVerifier: Optional) = + hostnameVerifier(hostnameVerifier.getOrNull()) + + /** + * Whether to throw an exception if any of the Jackson versions detected at runtime are + * incompatible with the SDK's minimum supported Jackson version (2.13.4). + * + * Defaults to true. Use extreme caution when disabling this option. There is no guarantee + * that the SDK will work correctly when using an incompatible Jackson version. + */ + fun checkJacksonVersionCompatibility(checkJacksonVersionCompatibility: Boolean) = apply { + clientOptions.checkJacksonVersionCompatibility(checkJacksonVersionCompatibility) + } + + /** + * The Jackson JSON mapper to use for serializing and deserializing JSON. + * + * Defaults to [com.cas_parser.api.core.jsonMapper]. The default is usually sufficient and + * rarely needs to be overridden. + */ + fun jsonMapper(jsonMapper: JsonMapper) = apply { clientOptions.jsonMapper(jsonMapper) } + + /** + * The clock to use for operations that require timing, like retries. + * + * This is primarily useful for using a fake clock in tests. + * + * Defaults to [Clock.systemUTC]. + */ + fun clock(clock: Clock) = apply { clientOptions.clock(clock) } + + /** + * The base URL to use for every request. + * + * Defaults to the production environment: `https://portfolio-parser.api.casparser.in`. + */ + fun baseUrl(baseUrl: String?) = apply { clientOptions.baseUrl(baseUrl) } + + /** Alias for calling [Builder.baseUrl] with `baseUrl.orElse(null)`. */ + fun baseUrl(baseUrl: Optional) = baseUrl(baseUrl.getOrNull()) + + /** + * Whether to call `validate` on every response before returning it. + * + * Defaults to false, which means the shape of the response will not be validated upfront. + * Instead, validation will only occur for the parts of the response that are accessed. + */ + fun responseValidation(responseValidation: Boolean) = apply { + clientOptions.responseValidation(responseValidation) + } + + /** + * Sets the maximum time allowed for various parts of an HTTP call's lifecycle, excluding + * retries. + * + * Defaults to [Timeout.default]. + */ + fun timeout(timeout: Timeout) = apply { clientOptions.timeout(timeout) } + + /** + * Sets the maximum time allowed for a complete HTTP call, not including retries. + * + * See [Timeout.request] for more details. + * + * For fine-grained control, pass a [Timeout] object. + */ + fun timeout(timeout: Duration) = apply { clientOptions.timeout(timeout) } + + /** + * The maximum number of times to retry failed requests, with a short exponential backoff + * between requests. + * + * Only the following error types are retried: + * - Connection errors (for example, due to a network connectivity problem) + * - 408 Request Timeout + * - 409 Conflict + * - 429 Rate Limit + * - 5xx Internal + * + * The API may also explicitly instruct the SDK to retry or not retry a request. + * + * Defaults to 2. + */ + fun maxRetries(maxRetries: Int) = apply { clientOptions.maxRetries(maxRetries) } + + /** Your API key for authentication. Use `sandbox-with-json-responses` as Sandbox key. */ + fun apiKey(apiKey: String) = apply { clientOptions.apiKey(apiKey) } + + fun headers(headers: Headers) = apply { clientOptions.headers(headers) } + + fun headers(headers: Map>) = apply { + clientOptions.headers(headers) + } + + fun putHeader(name: String, value: String) = apply { clientOptions.putHeader(name, value) } + + fun putHeaders(name: String, values: Iterable) = apply { + clientOptions.putHeaders(name, values) + } + + fun putAllHeaders(headers: Headers) = apply { clientOptions.putAllHeaders(headers) } + + fun putAllHeaders(headers: Map>) = apply { + clientOptions.putAllHeaders(headers) + } + + fun replaceHeaders(name: String, value: String) = apply { + clientOptions.replaceHeaders(name, value) + } + + fun replaceHeaders(name: String, values: Iterable) = apply { + clientOptions.replaceHeaders(name, values) + } + + fun replaceAllHeaders(headers: Headers) = apply { clientOptions.replaceAllHeaders(headers) } + + fun replaceAllHeaders(headers: Map>) = apply { + clientOptions.replaceAllHeaders(headers) + } + + fun removeHeaders(name: String) = apply { clientOptions.removeHeaders(name) } + + fun removeAllHeaders(names: Set) = apply { clientOptions.removeAllHeaders(names) } + + fun queryParams(queryParams: QueryParams) = apply { clientOptions.queryParams(queryParams) } + + fun queryParams(queryParams: Map>) = apply { + clientOptions.queryParams(queryParams) + } + + fun putQueryParam(key: String, value: String) = apply { + clientOptions.putQueryParam(key, value) + } + + fun putQueryParams(key: String, values: Iterable) = apply { + clientOptions.putQueryParams(key, values) + } + + fun putAllQueryParams(queryParams: QueryParams) = apply { + clientOptions.putAllQueryParams(queryParams) + } + + fun putAllQueryParams(queryParams: Map>) = apply { + clientOptions.putAllQueryParams(queryParams) + } + + fun replaceQueryParams(key: String, value: String) = apply { + clientOptions.replaceQueryParams(key, value) + } + + fun replaceQueryParams(key: String, values: Iterable) = apply { + clientOptions.replaceQueryParams(key, values) + } + + fun replaceAllQueryParams(queryParams: QueryParams) = apply { + clientOptions.replaceAllQueryParams(queryParams) + } + + fun replaceAllQueryParams(queryParams: Map>) = apply { + clientOptions.replaceAllQueryParams(queryParams) + } + + fun removeQueryParams(key: String) = apply { clientOptions.removeQueryParams(key) } + + fun removeAllQueryParams(keys: Set) = apply { + clientOptions.removeAllQueryParams(keys) + } + + /** + * Updates configuration using system properties and environment variables. + * + * @see ClientOptions.Builder.fromEnv + */ + fun fromEnv() = apply { clientOptions.fromEnv() } + + /** + * Returns an immutable instance of [CasParserClientAsync]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): CasParserClientAsync = + CasParserClientAsyncImpl( + clientOptions + .httpClient( + OkHttpClient.builder() + .timeout(clientOptions.timeout()) + .proxy(proxy) + .sslSocketFactory(sslSocketFactory) + .trustManager(trustManager) + .hostnameVerifier(hostnameVerifier) + .build() + ) + .build() + ) + } +} diff --git a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/OkHttpClient.kt b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/OkHttpClient.kt new file mode 100644 index 0000000..281e1c4 --- /dev/null +++ b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/OkHttpClient.kt @@ -0,0 +1,246 @@ +package com.cas_parser.api.client.okhttp + +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.Timeout +import com.cas_parser.api.core.http.Headers +import com.cas_parser.api.core.http.HttpClient +import com.cas_parser.api.core.http.HttpMethod +import com.cas_parser.api.core.http.HttpRequest +import com.cas_parser.api.core.http.HttpRequestBody +import com.cas_parser.api.core.http.HttpResponse +import com.cas_parser.api.errors.CasParserIoException +import java.io.IOException +import java.io.InputStream +import java.net.Proxy +import java.time.Duration +import java.util.concurrent.CompletableFuture +import javax.net.ssl.HostnameVerifier +import javax.net.ssl.SSLSocketFactory +import javax.net.ssl.X509TrustManager +import okhttp3.Call +import okhttp3.Callback +import okhttp3.HttpUrl.Companion.toHttpUrl +import okhttp3.MediaType +import okhttp3.MediaType.Companion.toMediaType +import okhttp3.Request +import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.toRequestBody +import okhttp3.Response +import okhttp3.logging.HttpLoggingInterceptor +import okio.BufferedSink + +class OkHttpClient private constructor(private val okHttpClient: okhttp3.OkHttpClient) : + HttpClient { + + override fun execute(request: HttpRequest, requestOptions: RequestOptions): HttpResponse { + val call = newCall(request, requestOptions) + + return try { + call.execute().toResponse() + } catch (e: IOException) { + throw CasParserIoException("Request failed", e) + } finally { + request.body?.close() + } + } + + override fun executeAsync( + request: HttpRequest, + requestOptions: RequestOptions, + ): CompletableFuture { + val future = CompletableFuture() + + request.body?.run { future.whenComplete { _, _ -> close() } } + + newCall(request, requestOptions) + .enqueue( + object : Callback { + override fun onResponse(call: Call, response: Response) { + future.complete(response.toResponse()) + } + + override fun onFailure(call: Call, e: IOException) { + future.completeExceptionally(CasParserIoException("Request failed", e)) + } + } + ) + + return future + } + + override fun close() { + okHttpClient.dispatcher.executorService.shutdown() + okHttpClient.connectionPool.evictAll() + okHttpClient.cache?.close() + } + + private fun newCall(request: HttpRequest, requestOptions: RequestOptions): Call { + val clientBuilder = okHttpClient.newBuilder() + + val logLevel = + when (System.getenv("CAS_PARSER_LOG")?.lowercase()) { + "info" -> HttpLoggingInterceptor.Level.BASIC + "debug" -> HttpLoggingInterceptor.Level.BODY + else -> null + } + if (logLevel != null) { + clientBuilder.addNetworkInterceptor( + HttpLoggingInterceptor().setLevel(logLevel).apply { redactHeader("x-api-key") } + ) + } + + requestOptions.timeout?.let { + clientBuilder + .connectTimeout(it.connect()) + .readTimeout(it.read()) + .writeTimeout(it.write()) + .callTimeout(it.request()) + } + + val client = clientBuilder.build() + return client.newCall(request.toRequest(client)) + } + + private fun HttpRequest.toRequest(client: okhttp3.OkHttpClient): Request { + var body: RequestBody? = body?.toRequestBody() + if (body == null && requiresBody(method)) { + body = "".toRequestBody() + } + + val builder = Request.Builder().url(toUrl()).method(method.name, body) + headers.names().forEach { name -> + headers.values(name).forEach { builder.header(name, it) } + } + + if ( + !headers.names().contains("X-Stainless-Read-Timeout") && client.readTimeoutMillis != 0 + ) { + builder.header( + "X-Stainless-Read-Timeout", + Duration.ofMillis(client.readTimeoutMillis.toLong()).seconds.toString(), + ) + } + if (!headers.names().contains("X-Stainless-Timeout") && client.callTimeoutMillis != 0) { + builder.header( + "X-Stainless-Timeout", + Duration.ofMillis(client.callTimeoutMillis.toLong()).seconds.toString(), + ) + } + + return builder.build() + } + + /** `OkHttpClient` always requires a request body for some methods. */ + private fun requiresBody(method: HttpMethod): Boolean = + when (method) { + HttpMethod.POST, + HttpMethod.PUT, + HttpMethod.PATCH -> true + else -> false + } + + private fun HttpRequest.toUrl(): String { + val builder = baseUrl.toHttpUrl().newBuilder() + pathSegments.forEach(builder::addPathSegment) + queryParams.keys().forEach { key -> + queryParams.values(key).forEach { builder.addQueryParameter(key, it) } + } + + return builder.toString() + } + + private fun HttpRequestBody.toRequestBody(): RequestBody { + val mediaType = contentType()?.toMediaType() + val length = contentLength() + + return object : RequestBody() { + override fun contentType(): MediaType? = mediaType + + override fun contentLength(): Long = length + + override fun isOneShot(): Boolean = !repeatable() + + override fun writeTo(sink: BufferedSink) = writeTo(sink.outputStream()) + } + } + + private fun Response.toResponse(): HttpResponse { + val headers = headers.toHeaders() + + return object : HttpResponse { + override fun statusCode(): Int = code + + override fun headers(): Headers = headers + + override fun body(): InputStream = body!!.byteStream() + + override fun close() = body!!.close() + } + } + + private fun okhttp3.Headers.toHeaders(): Headers { + val headersBuilder = Headers.builder() + forEach { (name, value) -> headersBuilder.put(name, value) } + return headersBuilder.build() + } + + companion object { + @JvmStatic fun builder() = Builder() + } + + class Builder internal constructor() { + + private var timeout: Timeout = Timeout.default() + private var proxy: Proxy? = null + private var sslSocketFactory: SSLSocketFactory? = null + private var trustManager: X509TrustManager? = null + private var hostnameVerifier: HostnameVerifier? = null + + fun timeout(timeout: Timeout) = apply { this.timeout = timeout } + + fun timeout(timeout: Duration) = timeout(Timeout.builder().request(timeout).build()) + + fun proxy(proxy: Proxy?) = apply { this.proxy = proxy } + + fun sslSocketFactory(sslSocketFactory: SSLSocketFactory?) = apply { + this.sslSocketFactory = sslSocketFactory + } + + fun trustManager(trustManager: X509TrustManager?) = apply { + this.trustManager = trustManager + } + + fun hostnameVerifier(hostnameVerifier: HostnameVerifier?) = apply { + this.hostnameVerifier = hostnameVerifier + } + + fun build(): OkHttpClient = + OkHttpClient( + okhttp3.OkHttpClient.Builder() + .connectTimeout(timeout.connect()) + .readTimeout(timeout.read()) + .writeTimeout(timeout.write()) + .callTimeout(timeout.request()) + .proxy(proxy) + .apply { + val sslSocketFactory = sslSocketFactory + val trustManager = trustManager + if (sslSocketFactory != null && trustManager != null) { + sslSocketFactory(sslSocketFactory, trustManager) + } else { + check((sslSocketFactory != null) == (trustManager != null)) { + "Both or none of `sslSocketFactory` and `trustManager` must be set, but only one was set" + } + } + + hostnameVerifier?.let(::hostnameVerifier) + } + .build() + .apply { + // We usually make all our requests to the same host so it makes sense to + // raise the per-host limit to the overall limit. + dispatcher.maxRequestsPerHost = dispatcher.maxRequests + } + ) + } +} diff --git a/cas-parser-java-core/build.gradle.kts b/cas-parser-java-core/build.gradle.kts new file mode 100644 index 0000000..9861d5b --- /dev/null +++ b/cas-parser-java-core/build.gradle.kts @@ -0,0 +1,41 @@ +plugins { + id("cas-parser.kotlin") + id("cas-parser.publish") +} + +configurations.all { + resolutionStrategy { + // Compile and test against a lower Jackson version to ensure we're compatible with it. + // We publish with a higher version (see below) to ensure users depend on a secure version by default. + force("com.fasterxml.jackson.core:jackson-core:2.13.4") + force("com.fasterxml.jackson.core:jackson-databind:2.13.4") + force("com.fasterxml.jackson.core:jackson-annotations:2.13.4") + force("com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.13.4") + force("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.4") + force("com.fasterxml.jackson.module:jackson-module-kotlin:2.13.4") + } +} + +dependencies { + api("com.fasterxml.jackson.core:jackson-core:2.18.2") + api("com.fasterxml.jackson.core:jackson-databind:2.18.2") + api("com.google.errorprone:error_prone_annotations:2.33.0") + + implementation("com.fasterxml.jackson.core:jackson-annotations:2.18.2") + implementation("com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.18.2") + implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.18.2") + implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.18.2") + implementation("org.apache.httpcomponents.core5:httpcore5:5.2.4") + implementation("org.apache.httpcomponents.client5:httpclient5:5.3.1") + + testImplementation(kotlin("test")) + testImplementation(project(":cas-parser-java-client-okhttp")) + testImplementation("com.github.tomakehurst:wiremock-jre8:2.35.2") + testImplementation("org.assertj:assertj-core:3.25.3") + testImplementation("org.junit.jupiter:junit-jupiter-api:5.9.3") + testImplementation("org.junit.jupiter:junit-jupiter-params:5.9.3") + testImplementation("org.junit-pioneer:junit-pioneer:1.9.1") + testImplementation("org.mockito:mockito-core:5.14.2") + testImplementation("org.mockito:mockito-junit-jupiter:5.14.2") + testImplementation("org.mockito.kotlin:mockito-kotlin:4.1.0") +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClient.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClient.kt new file mode 100644 index 0000000..6a2e9fb --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClient.kt @@ -0,0 +1,77 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.client + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.services.blocking.CasGeneratorService +import com.cas_parser.api.services.blocking.CasParserService +import java.util.function.Consumer + +/** + * A client for interacting with the Cas Parser REST API synchronously. You can also switch to + * asynchronous execution via the [async] method. + * + * This client performs best when you create a single instance and reuse it for all interactions + * with the REST API. This is because each client holds its own connection pool and thread pools. + * Reusing connections and threads reduces latency and saves memory. The client also handles rate + * limiting per client. This means that creating and using multiple instances at the same time will + * not respect rate limits. + * + * The threads and connections that are held will be released automatically if they remain idle. But + * if you are writing an application that needs to aggressively release unused resources, then you + * may call [close]. + */ +interface CasParserClient { + + /** + * Returns a version of this client that uses asynchronous execution. + * + * The returned client shares its resources, like its connection pool and thread pools, with + * this client. + */ + fun async(): CasParserClientAsync + + /** + * 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): CasParserClient + + fun casParser(): CasParserService + + fun casGenerator(): CasGeneratorService + + /** + * Closes this client, relinquishing any underlying resources. + * + * This is purposefully not inherited from [AutoCloseable] because the client is long-lived and + * usually should not be synchronously closed via try-with-resources. + * + * It's also usually not necessary to call this method at all. the default HTTP client + * automatically releases threads and connections if they remain idle, but if you are writing an + * application that needs to aggressively release unused resources, then you may call this + * method. + */ + fun close() + + /** A view of [CasParserClient] 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): CasParserClient.WithRawResponse + + fun casParser(): CasParserService.WithRawResponse + + fun casGenerator(): CasGeneratorService.WithRawResponse + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientAsync.kt new file mode 100644 index 0000000..24e7f4e --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientAsync.kt @@ -0,0 +1,81 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.client + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.services.async.CasGeneratorServiceAsync +import com.cas_parser.api.services.async.CasParserServiceAsync +import java.util.function.Consumer + +/** + * A client for interacting with the Cas Parser REST API asynchronously. You can also switch to + * synchronous execution via the [sync] method. + * + * This client performs best when you create a single instance and reuse it for all interactions + * with the REST API. This is because each client holds its own connection pool and thread pools. + * Reusing connections and threads reduces latency and saves memory. The client also handles rate + * limiting per client. This means that creating and using multiple instances at the same time will + * not respect rate limits. + * + * The threads and connections that are held will be released automatically if they remain idle. But + * if you are writing an application that needs to aggressively release unused resources, then you + * may call [close]. + */ +interface CasParserClientAsync { + + /** + * Returns a version of this client that uses synchronous execution. + * + * The returned client shares its resources, like its connection pool and thread pools, with + * this client. + */ + fun sync(): CasParserClient + + /** + * 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): CasParserClientAsync + + fun casParser(): CasParserServiceAsync + + fun casGenerator(): CasGeneratorServiceAsync + + /** + * Closes this client, relinquishing any underlying resources. + * + * This is purposefully not inherited from [AutoCloseable] because the client is long-lived and + * usually should not be synchronously closed via try-with-resources. + * + * It's also usually not necessary to call this method at all. the default HTTP client + * automatically releases threads and connections if they remain idle, but if you are writing an + * application that needs to aggressively release unused resources, then you may call this + * method. + */ + fun close() + + /** + * A view of [CasParserClientAsync] 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 + ): CasParserClientAsync.WithRawResponse + + fun casParser(): CasParserServiceAsync.WithRawResponse + + fun casGenerator(): CasGeneratorServiceAsync.WithRawResponse + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientAsyncImpl.kt new file mode 100644 index 0000000..2301ccd --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientAsyncImpl.kt @@ -0,0 +1,73 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.client + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.getPackageVersion +import com.cas_parser.api.services.async.CasGeneratorServiceAsync +import com.cas_parser.api.services.async.CasGeneratorServiceAsyncImpl +import com.cas_parser.api.services.async.CasParserServiceAsync +import com.cas_parser.api.services.async.CasParserServiceAsyncImpl +import java.util.function.Consumer + +class CasParserClientAsyncImpl(private val clientOptions: ClientOptions) : CasParserClientAsync { + + private val clientOptionsWithUserAgent = + if (clientOptions.headers.names().contains("User-Agent")) clientOptions + else + clientOptions + .toBuilder() + .putHeader("User-Agent", "${javaClass.simpleName}/Java ${getPackageVersion()}") + .build() + + // Pass the original clientOptions so that this client sets its own User-Agent. + private val sync: CasParserClient by lazy { CasParserClientImpl(clientOptions) } + + private val withRawResponse: CasParserClientAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + private val casParser: CasParserServiceAsync by lazy { + CasParserServiceAsyncImpl(clientOptionsWithUserAgent) + } + + private val casGenerator: CasGeneratorServiceAsync by lazy { + CasGeneratorServiceAsyncImpl(clientOptionsWithUserAgent) + } + + override fun sync(): CasParserClient = sync + + override fun withRawResponse(): CasParserClientAsync.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): CasParserClientAsync = + CasParserClientAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun casParser(): CasParserServiceAsync = casParser + + override fun casGenerator(): CasGeneratorServiceAsync = casGenerator + + override fun close() = clientOptions.httpClient.close() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + CasParserClientAsync.WithRawResponse { + + private val casParser: CasParserServiceAsync.WithRawResponse by lazy { + CasParserServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val casGenerator: CasGeneratorServiceAsync.WithRawResponse by lazy { + CasGeneratorServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + override fun withOptions( + modifier: Consumer + ): CasParserClientAsync.WithRawResponse = + CasParserClientAsyncImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + override fun casParser(): CasParserServiceAsync.WithRawResponse = casParser + + override fun casGenerator(): CasGeneratorServiceAsync.WithRawResponse = casGenerator + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientImpl.kt new file mode 100644 index 0000000..0104e8f --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientImpl.kt @@ -0,0 +1,73 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.client + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.getPackageVersion +import com.cas_parser.api.services.blocking.CasGeneratorService +import com.cas_parser.api.services.blocking.CasGeneratorServiceImpl +import com.cas_parser.api.services.blocking.CasParserService +import com.cas_parser.api.services.blocking.CasParserServiceImpl +import java.util.function.Consumer + +class CasParserClientImpl(private val clientOptions: ClientOptions) : CasParserClient { + + private val clientOptionsWithUserAgent = + if (clientOptions.headers.names().contains("User-Agent")) clientOptions + else + clientOptions + .toBuilder() + .putHeader("User-Agent", "${javaClass.simpleName}/Java ${getPackageVersion()}") + .build() + + // Pass the original clientOptions so that this client sets its own User-Agent. + private val async: CasParserClientAsync by lazy { CasParserClientAsyncImpl(clientOptions) } + + private val withRawResponse: CasParserClient.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + private val casParser: CasParserService by lazy { + CasParserServiceImpl(clientOptionsWithUserAgent) + } + + private val casGenerator: CasGeneratorService by lazy { + CasGeneratorServiceImpl(clientOptionsWithUserAgent) + } + + override fun async(): CasParserClientAsync = async + + override fun withRawResponse(): CasParserClient.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): CasParserClient = + CasParserClientImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun casParser(): CasParserService = casParser + + override fun casGenerator(): CasGeneratorService = casGenerator + + override fun close() = clientOptions.httpClient.close() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + CasParserClient.WithRawResponse { + + private val casParser: CasParserService.WithRawResponse by lazy { + CasParserServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val casGenerator: CasGeneratorService.WithRawResponse by lazy { + CasGeneratorServiceImpl.WithRawResponseImpl(clientOptions) + } + + override fun withOptions( + modifier: Consumer + ): CasParserClient.WithRawResponse = + CasParserClientImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + override fun casParser(): CasParserService.WithRawResponse = casParser + + override fun casGenerator(): CasGeneratorService.WithRawResponse = casGenerator + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/BaseDeserializer.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/BaseDeserializer.kt new file mode 100644 index 0000000..a6dcabc --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/BaseDeserializer.kt @@ -0,0 +1,44 @@ +package com.cas_parser.api.core + +import com.fasterxml.jackson.core.JsonParser +import com.fasterxml.jackson.core.ObjectCodec +import com.fasterxml.jackson.core.type.TypeReference +import com.fasterxml.jackson.databind.BeanProperty +import com.fasterxml.jackson.databind.DeserializationContext +import com.fasterxml.jackson.databind.JavaType +import com.fasterxml.jackson.databind.JsonDeserializer +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.deser.ContextualDeserializer +import com.fasterxml.jackson.databind.deser.std.StdDeserializer +import kotlin.reflect.KClass + +abstract class BaseDeserializer(type: KClass) : + StdDeserializer(type.java), ContextualDeserializer { + + override fun createContextual( + context: DeserializationContext, + property: BeanProperty?, + ): JsonDeserializer { + return this + } + + override fun deserialize(parser: JsonParser, context: DeserializationContext): T { + return parser.codec.deserialize(parser.readValueAsTree()) + } + + protected abstract fun ObjectCodec.deserialize(node: JsonNode): T + + protected fun ObjectCodec.tryDeserialize(node: JsonNode, type: TypeReference): T? = + try { + readValue(treeAsTokens(node), type) + } catch (e: Exception) { + null + } + + protected fun ObjectCodec.tryDeserialize(node: JsonNode, type: JavaType): T? = + try { + readValue(treeAsTokens(node), type) + } catch (e: Exception) { + null + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/BaseSerializer.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/BaseSerializer.kt new file mode 100644 index 0000000..5ea87e0 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/BaseSerializer.kt @@ -0,0 +1,6 @@ +package com.cas_parser.api.core + +import com.fasterxml.jackson.databind.ser.std.StdSerializer +import kotlin.reflect.KClass + +abstract class BaseSerializer(type: KClass) : StdSerializer(type.java) diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Check.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Check.kt new file mode 100644 index 0000000..2e4c6e8 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Check.kt @@ -0,0 +1,96 @@ +@file:JvmName("Check") + +package com.cas_parser.api.core + +import com.fasterxml.jackson.core.Version +import com.fasterxml.jackson.core.util.VersionUtil + +fun checkRequired(name: String, condition: Boolean) = + check(condition) { "`$name` is required, but was not set" } + +fun checkRequired(name: String, value: T?): T = + checkNotNull(value) { "`$name` is required, but was not set" } + +@JvmSynthetic +internal fun checkKnown(name: String, value: JsonField): T = + value.asKnown().orElseThrow { + IllegalStateException("`$name` is not a known type: ${value.javaClass.simpleName}") + } + +@JvmSynthetic +internal fun checkKnown(name: String, value: MultipartField): T = + value.value.asKnown().orElseThrow { + IllegalStateException("`$name` is not a known type: ${value.javaClass.simpleName}") + } + +@JvmSynthetic +internal fun checkLength(name: String, value: String, length: Int): String = + value.also { + check(it.length == length) { "`$name` must have length $length, but was ${it.length}" } + } + +@JvmSynthetic +internal fun checkMinLength(name: String, value: String, minLength: Int): String = + value.also { + check(it.length >= minLength) { + if (minLength == 1) "`$name` must be non-empty, but was empty" + else "`$name` must have at least length $minLength, but was ${it.length}" + } + } + +@JvmSynthetic +internal fun checkMaxLength(name: String, value: String, maxLength: Int): String = + value.also { + check(it.length <= maxLength) { + "`$name` must have at most length $maxLength, but was ${it.length}" + } + } + +@JvmSynthetic +internal fun checkJacksonVersionCompatibility() { + val incompatibleJacksonVersions = + RUNTIME_JACKSON_VERSIONS.mapNotNull { + val badVersionReason = BAD_JACKSON_VERSIONS[it.toString()] + when { + it.majorVersion != MINIMUM_JACKSON_VERSION.majorVersion -> + it to "incompatible major version" + it.minorVersion < MINIMUM_JACKSON_VERSION.minorVersion -> + it to "minor version too low" + it.minorVersion == MINIMUM_JACKSON_VERSION.minorVersion && + it.patchLevel < MINIMUM_JACKSON_VERSION.patchLevel -> + it to "patch version too low" + badVersionReason != null -> it to badVersionReason + else -> null + } + } + check(incompatibleJacksonVersions.isEmpty()) { + """ +This SDK requires a minimum Jackson version of $MINIMUM_JACKSON_VERSION, but the following incompatible Jackson versions were detected at runtime: + +${incompatibleJacksonVersions.asSequence().map { (version, incompatibilityReason) -> + "- `${version.toFullString().replace("/", ":")}` ($incompatibilityReason)" +}.joinToString("\n")} + +This can happen if you are either: +1. Directly depending on different Jackson versions +2. Depending on some library that depends on different Jackson versions, potentially transitively + +Double-check that you are depending on compatible Jackson versions. + +See https://www.github.com/stainless-sdks/cas-parser-java#jackson for more information. + """ + .trimIndent() + } +} + +private val MINIMUM_JACKSON_VERSION: Version = VersionUtil.parseVersion("2.13.4", null, null) +private val BAD_JACKSON_VERSIONS: Map = + mapOf("2.18.1" to "due to https://github.com/FasterXML/jackson-databind/issues/4639") +private val RUNTIME_JACKSON_VERSIONS: List = + listOf( + com.fasterxml.jackson.core.json.PackageVersion.VERSION, + com.fasterxml.jackson.databind.cfg.PackageVersion.VERSION, + com.fasterxml.jackson.datatype.jdk8.PackageVersion.VERSION, + com.fasterxml.jackson.datatype.jsr310.PackageVersion.VERSION, + com.fasterxml.jackson.module.kotlin.PackageVersion.VERSION, + ) diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ClientOptions.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ClientOptions.kt new file mode 100644 index 0000000..516a36d --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ClientOptions.kt @@ -0,0 +1,407 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.core + +import com.cas_parser.api.core.http.Headers +import com.cas_parser.api.core.http.HttpClient +import com.cas_parser.api.core.http.PhantomReachableClosingHttpClient +import com.cas_parser.api.core.http.QueryParams +import com.cas_parser.api.core.http.RetryingHttpClient +import com.fasterxml.jackson.databind.json.JsonMapper +import java.time.Clock +import java.time.Duration +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** A class representing the SDK client configuration. */ +class ClientOptions +private constructor( + private val originalHttpClient: HttpClient, + /** + * The HTTP client to use in the SDK. + * + * Use the one published in `cas-parser-java-client-okhttp` or implement your own. + */ + @get:JvmName("httpClient") val httpClient: HttpClient, + /** + * Whether to throw an exception if any of the Jackson versions detected at runtime are + * incompatible with the SDK's minimum supported Jackson version (2.13.4). + * + * Defaults to true. Use extreme caution when disabling this option. There is no guarantee that + * the SDK will work correctly when using an incompatible Jackson version. + */ + @get:JvmName("checkJacksonVersionCompatibility") val checkJacksonVersionCompatibility: Boolean, + /** + * The Jackson JSON mapper to use for serializing and deserializing JSON. + * + * Defaults to [com.cas_parser.api.core.jsonMapper]. The default is usually sufficient and + * rarely needs to be overridden. + */ + @get:JvmName("jsonMapper") val jsonMapper: JsonMapper, + /** + * The clock to use for operations that require timing, like retries. + * + * This is primarily useful for using a fake clock in tests. + * + * Defaults to [Clock.systemUTC]. + */ + @get:JvmName("clock") val clock: Clock, + private val baseUrl: String?, + /** Headers to send with the request. */ + @get:JvmName("headers") val headers: Headers, + /** Query params to send with the request. */ + @get:JvmName("queryParams") val queryParams: QueryParams, + /** + * Whether to call `validate` on every response before returning it. + * + * Defaults to false, which means the shape of the response will not be validated upfront. + * Instead, validation will only occur for the parts of the response that are accessed. + */ + @get:JvmName("responseValidation") val responseValidation: Boolean, + /** + * Sets the maximum time allowed for various parts of an HTTP call's lifecycle, excluding + * retries. + * + * Defaults to [Timeout.default]. + */ + @get:JvmName("timeout") val timeout: Timeout, + /** + * The maximum number of times to retry failed requests, with a short exponential backoff + * between requests. + * + * Only the following error types are retried: + * - Connection errors (for example, due to a network connectivity problem) + * - 408 Request Timeout + * - 409 Conflict + * - 429 Rate Limit + * - 5xx Internal + * + * The API may also explicitly instruct the SDK to retry or not retry a request. + * + * Defaults to 2. + */ + @get:JvmName("maxRetries") val maxRetries: Int, + /** Your API key for authentication. Use `sandbox-with-json-responses` as Sandbox key. */ + @get:JvmName("apiKey") val apiKey: String, +) { + + init { + if (checkJacksonVersionCompatibility) { + checkJacksonVersionCompatibility() + } + } + + /** + * The base URL to use for every request. + * + * Defaults to the production environment: `https://portfolio-parser.api.casparser.in`. + */ + fun baseUrl(): String = baseUrl ?: PRODUCTION_URL + + fun toBuilder() = Builder().from(this) + + companion object { + + const val PRODUCTION_URL = "https://portfolio-parser.api.casparser.in" + + /** + * Returns a mutable builder for constructing an instance of [ClientOptions]. + * + * The following fields are required: + * ```java + * .httpClient() + * .apiKey() + * ``` + */ + @JvmStatic fun builder() = Builder() + + /** + * Returns options configured using system properties and environment variables. + * + * @see Builder.fromEnv + */ + @JvmStatic fun fromEnv(): ClientOptions = builder().fromEnv().build() + } + + /** A builder for [ClientOptions]. */ + class Builder internal constructor() { + + private var httpClient: HttpClient? = null + private var checkJacksonVersionCompatibility: Boolean = true + private var jsonMapper: JsonMapper = jsonMapper() + private var clock: Clock = Clock.systemUTC() + private var baseUrl: String? = null + private var headers: Headers.Builder = Headers.builder() + private var queryParams: QueryParams.Builder = QueryParams.builder() + private var responseValidation: Boolean = false + private var timeout: Timeout = Timeout.default() + private var maxRetries: Int = 2 + private var apiKey: String? = null + + @JvmSynthetic + internal fun from(clientOptions: ClientOptions) = apply { + httpClient = clientOptions.originalHttpClient + checkJacksonVersionCompatibility = clientOptions.checkJacksonVersionCompatibility + jsonMapper = clientOptions.jsonMapper + clock = clientOptions.clock + baseUrl = clientOptions.baseUrl + headers = clientOptions.headers.toBuilder() + queryParams = clientOptions.queryParams.toBuilder() + responseValidation = clientOptions.responseValidation + timeout = clientOptions.timeout + maxRetries = clientOptions.maxRetries + apiKey = clientOptions.apiKey + } + + /** + * The HTTP client to use in the SDK. + * + * Use the one published in `cas-parser-java-client-okhttp` or implement your own. + */ + fun httpClient(httpClient: HttpClient) = apply { + this.httpClient = PhantomReachableClosingHttpClient(httpClient) + } + + /** + * Whether to throw an exception if any of the Jackson versions detected at runtime are + * incompatible with the SDK's minimum supported Jackson version (2.13.4). + * + * Defaults to true. Use extreme caution when disabling this option. There is no guarantee + * that the SDK will work correctly when using an incompatible Jackson version. + */ + fun checkJacksonVersionCompatibility(checkJacksonVersionCompatibility: Boolean) = apply { + this.checkJacksonVersionCompatibility = checkJacksonVersionCompatibility + } + + /** + * The Jackson JSON mapper to use for serializing and deserializing JSON. + * + * Defaults to [com.cas_parser.api.core.jsonMapper]. The default is usually sufficient and + * rarely needs to be overridden. + */ + fun jsonMapper(jsonMapper: JsonMapper) = apply { this.jsonMapper = jsonMapper } + + /** + * The clock to use for operations that require timing, like retries. + * + * This is primarily useful for using a fake clock in tests. + * + * Defaults to [Clock.systemUTC]. + */ + fun clock(clock: Clock) = apply { this.clock = clock } + + /** + * The base URL to use for every request. + * + * Defaults to the production environment: `https://portfolio-parser.api.casparser.in`. + */ + fun baseUrl(baseUrl: String?) = apply { this.baseUrl = baseUrl } + + /** Alias for calling [Builder.baseUrl] with `baseUrl.orElse(null)`. */ + fun baseUrl(baseUrl: Optional) = baseUrl(baseUrl.getOrNull()) + + /** + * Whether to call `validate` on every response before returning it. + * + * Defaults to false, which means the shape of the response will not be validated upfront. + * Instead, validation will only occur for the parts of the response that are accessed. + */ + fun responseValidation(responseValidation: Boolean) = apply { + this.responseValidation = responseValidation + } + + /** + * Sets the maximum time allowed for various parts of an HTTP call's lifecycle, excluding + * retries. + * + * Defaults to [Timeout.default]. + */ + fun timeout(timeout: Timeout) = apply { this.timeout = timeout } + + /** + * Sets the maximum time allowed for a complete HTTP call, not including retries. + * + * See [Timeout.request] for more details. + * + * For fine-grained control, pass a [Timeout] object. + */ + fun timeout(timeout: Duration) = timeout(Timeout.builder().request(timeout).build()) + + /** + * The maximum number of times to retry failed requests, with a short exponential backoff + * between requests. + * + * Only the following error types are retried: + * - Connection errors (for example, due to a network connectivity problem) + * - 408 Request Timeout + * - 409 Conflict + * - 429 Rate Limit + * - 5xx Internal + * + * The API may also explicitly instruct the SDK to retry or not retry a request. + * + * Defaults to 2. + */ + fun maxRetries(maxRetries: Int) = apply { this.maxRetries = maxRetries } + + /** Your API key for authentication. Use `sandbox-with-json-responses` as Sandbox key. */ + fun apiKey(apiKey: String) = apply { this.apiKey = apiKey } + + fun headers(headers: Headers) = apply { + this.headers.clear() + putAllHeaders(headers) + } + + fun headers(headers: Map>) = apply { + this.headers.clear() + putAllHeaders(headers) + } + + fun putHeader(name: String, value: String) = apply { headers.put(name, value) } + + fun putHeaders(name: String, values: Iterable) = apply { headers.put(name, values) } + + fun putAllHeaders(headers: Headers) = apply { this.headers.putAll(headers) } + + fun putAllHeaders(headers: Map>) = apply { + this.headers.putAll(headers) + } + + fun replaceHeaders(name: String, value: String) = apply { headers.replace(name, value) } + + fun replaceHeaders(name: String, values: Iterable) = apply { + headers.replace(name, values) + } + + fun replaceAllHeaders(headers: Headers) = apply { this.headers.replaceAll(headers) } + + fun replaceAllHeaders(headers: Map>) = apply { + this.headers.replaceAll(headers) + } + + fun removeHeaders(name: String) = apply { headers.remove(name) } + + fun removeAllHeaders(names: Set) = apply { headers.removeAll(names) } + + fun queryParams(queryParams: QueryParams) = apply { + this.queryParams.clear() + putAllQueryParams(queryParams) + } + + fun queryParams(queryParams: Map>) = apply { + this.queryParams.clear() + putAllQueryParams(queryParams) + } + + fun putQueryParam(key: String, value: String) = apply { queryParams.put(key, value) } + + fun putQueryParams(key: String, values: Iterable) = apply { + queryParams.put(key, values) + } + + fun putAllQueryParams(queryParams: QueryParams) = apply { + this.queryParams.putAll(queryParams) + } + + fun putAllQueryParams(queryParams: Map>) = apply { + this.queryParams.putAll(queryParams) + } + + fun replaceQueryParams(key: String, value: String) = apply { + queryParams.replace(key, value) + } + + fun replaceQueryParams(key: String, values: Iterable) = apply { + queryParams.replace(key, values) + } + + fun replaceAllQueryParams(queryParams: QueryParams) = apply { + this.queryParams.replaceAll(queryParams) + } + + fun replaceAllQueryParams(queryParams: Map>) = apply { + this.queryParams.replaceAll(queryParams) + } + + fun removeQueryParams(key: String) = apply { queryParams.remove(key) } + + fun removeAllQueryParams(keys: Set) = apply { queryParams.removeAll(keys) } + + fun timeout(): Timeout = timeout + + /** + * Updates configuration using system properties and environment variables. + * + * See this table for the available options: + * + * |Setter |System property |Environment variable |Required|Default value | + * |---------|-------------------|---------------------|--------|---------------------------------------------| + * |`apiKey` |`casparser.apiKey` |`CAS_PARSER_API_KEY` |true |- | + * |`baseUrl`|`casparser.baseUrl`|`CAS_PARSER_BASE_URL`|true |`"https://portfolio-parser.api.casparser.in"`| + * + * System properties take precedence over environment variables. + */ + fun fromEnv() = apply { + (System.getProperty("casparser.baseUrl") ?: System.getenv("CAS_PARSER_BASE_URL"))?.let { + baseUrl(it) + } + (System.getProperty("casparser.apiKey") ?: System.getenv("CAS_PARSER_API_KEY"))?.let { + apiKey(it) + } + } + + /** + * Returns an immutable instance of [ClientOptions]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .httpClient() + * .apiKey() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ClientOptions { + val httpClient = checkRequired("httpClient", httpClient) + val apiKey = checkRequired("apiKey", apiKey) + + val headers = Headers.builder() + val queryParams = QueryParams.builder() + headers.put("X-Stainless-Lang", "java") + headers.put("X-Stainless-Arch", getOsArch()) + headers.put("X-Stainless-OS", getOsName()) + headers.put("X-Stainless-OS-Version", getOsVersion()) + headers.put("X-Stainless-Package-Version", getPackageVersion()) + headers.put("X-Stainless-Runtime", "JRE") + headers.put("X-Stainless-Runtime-Version", getJavaVersion()) + apiKey.let { + if (!it.isEmpty()) { + headers.put("x-api-key", it) + } + } + headers.replaceAll(this.headers.build()) + queryParams.replaceAll(this.queryParams.build()) + + return ClientOptions( + httpClient, + RetryingHttpClient.builder() + .httpClient(httpClient) + .clock(clock) + .maxRetries(maxRetries) + .build(), + checkJacksonVersionCompatibility, + jsonMapper, + clock, + baseUrl, + headers.build(), + queryParams.build(), + responseValidation, + timeout, + maxRetries, + apiKey, + ) + } + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ObjectMappers.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ObjectMappers.kt new file mode 100644 index 0000000..85d0b7e --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ObjectMappers.kt @@ -0,0 +1,167 @@ +@file:JvmName("ObjectMappers") + +package com.cas_parser.api.core + +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.JsonParseException +import com.fasterxml.jackson.core.JsonParser +import com.fasterxml.jackson.databind.DeserializationContext +import com.fasterxml.jackson.databind.DeserializationFeature +import com.fasterxml.jackson.databind.MapperFeature +import com.fasterxml.jackson.databind.SerializationFeature +import com.fasterxml.jackson.databind.SerializerProvider +import com.fasterxml.jackson.databind.cfg.CoercionAction +import com.fasterxml.jackson.databind.cfg.CoercionInputShape +import com.fasterxml.jackson.databind.deser.std.StdDeserializer +import com.fasterxml.jackson.databind.json.JsonMapper +import com.fasterxml.jackson.databind.module.SimpleModule +import com.fasterxml.jackson.databind.type.LogicalType +import com.fasterxml.jackson.datatype.jdk8.Jdk8Module +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule +import com.fasterxml.jackson.module.kotlin.kotlinModule +import java.io.InputStream +import java.time.DateTimeException +import java.time.LocalDate +import java.time.LocalDateTime +import java.time.ZonedDateTime +import java.time.format.DateTimeFormatter +import java.time.temporal.ChronoField + +fun jsonMapper(): JsonMapper = + JsonMapper.builder() + .addModule(kotlinModule()) + .addModule(Jdk8Module()) + .addModule(JavaTimeModule()) + .addModule( + SimpleModule() + .addSerializer(InputStreamSerializer) + .addDeserializer(LocalDateTime::class.java, LenientLocalDateTimeDeserializer()) + ) + .withCoercionConfig(LogicalType.Boolean) { + it.setCoercion(CoercionInputShape.Integer, CoercionAction.Fail) + .setCoercion(CoercionInputShape.Float, CoercionAction.Fail) + .setCoercion(CoercionInputShape.String, CoercionAction.Fail) + .setCoercion(CoercionInputShape.Array, CoercionAction.Fail) + .setCoercion(CoercionInputShape.Object, CoercionAction.Fail) + } + .withCoercionConfig(LogicalType.Integer) { + it.setCoercion(CoercionInputShape.Boolean, CoercionAction.Fail) + .setCoercion(CoercionInputShape.String, CoercionAction.Fail) + .setCoercion(CoercionInputShape.Array, CoercionAction.Fail) + .setCoercion(CoercionInputShape.Object, CoercionAction.Fail) + } + .withCoercionConfig(LogicalType.Float) { + it.setCoercion(CoercionInputShape.Boolean, CoercionAction.Fail) + .setCoercion(CoercionInputShape.String, CoercionAction.Fail) + .setCoercion(CoercionInputShape.Array, CoercionAction.Fail) + .setCoercion(CoercionInputShape.Object, CoercionAction.Fail) + } + .withCoercionConfig(LogicalType.Textual) { + it.setCoercion(CoercionInputShape.Boolean, CoercionAction.Fail) + .setCoercion(CoercionInputShape.Integer, CoercionAction.Fail) + .setCoercion(CoercionInputShape.Float, CoercionAction.Fail) + .setCoercion(CoercionInputShape.Array, CoercionAction.Fail) + .setCoercion(CoercionInputShape.Object, CoercionAction.Fail) + } + .withCoercionConfig(LogicalType.Array) { + it.setCoercion(CoercionInputShape.Boolean, CoercionAction.Fail) + .setCoercion(CoercionInputShape.Integer, CoercionAction.Fail) + .setCoercion(CoercionInputShape.Float, CoercionAction.Fail) + .setCoercion(CoercionInputShape.String, CoercionAction.Fail) + .setCoercion(CoercionInputShape.Object, CoercionAction.Fail) + } + .withCoercionConfig(LogicalType.Collection) { + it.setCoercion(CoercionInputShape.Boolean, CoercionAction.Fail) + .setCoercion(CoercionInputShape.Integer, CoercionAction.Fail) + .setCoercion(CoercionInputShape.Float, CoercionAction.Fail) + .setCoercion(CoercionInputShape.String, CoercionAction.Fail) + .setCoercion(CoercionInputShape.Object, CoercionAction.Fail) + } + .withCoercionConfig(LogicalType.Map) { + it.setCoercion(CoercionInputShape.Boolean, CoercionAction.Fail) + .setCoercion(CoercionInputShape.Integer, CoercionAction.Fail) + .setCoercion(CoercionInputShape.Float, CoercionAction.Fail) + .setCoercion(CoercionInputShape.String, CoercionAction.Fail) + .setCoercion(CoercionInputShape.Object, CoercionAction.Fail) + } + .withCoercionConfig(LogicalType.POJO) { + it.setCoercion(CoercionInputShape.Boolean, CoercionAction.Fail) + .setCoercion(CoercionInputShape.Integer, CoercionAction.Fail) + .setCoercion(CoercionInputShape.Float, CoercionAction.Fail) + .setCoercion(CoercionInputShape.String, CoercionAction.Fail) + .setCoercion(CoercionInputShape.Array, CoercionAction.Fail) + } + .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) + .disable(MapperFeature.ALLOW_COERCION_OF_SCALARS) + .disable(MapperFeature.AUTO_DETECT_CREATORS) + .disable(MapperFeature.AUTO_DETECT_FIELDS) + .disable(MapperFeature.AUTO_DETECT_GETTERS) + .disable(MapperFeature.AUTO_DETECT_IS_GETTERS) + .disable(MapperFeature.AUTO_DETECT_SETTERS) + .build() + +/** A serializer that serializes [InputStream] to bytes. */ +private object InputStreamSerializer : BaseSerializer(InputStream::class) { + + private fun readResolve(): Any = InputStreamSerializer + + override fun serialize( + value: InputStream?, + gen: JsonGenerator?, + serializers: SerializerProvider?, + ) { + if (value == null) { + gen?.writeNull() + } else { + value.use { gen?.writeBinary(it.readBytes()) } + } + } +} + +/** + * A deserializer that can deserialize [LocalDateTime] from datetimes, dates, and zoned datetimes. + */ +private class LenientLocalDateTimeDeserializer : + StdDeserializer(LocalDateTime::class.java) { + + companion object { + + private val DATE_TIME_FORMATTERS = + listOf( + DateTimeFormatter.ISO_LOCAL_DATE_TIME, + DateTimeFormatter.ISO_LOCAL_DATE, + DateTimeFormatter.ISO_ZONED_DATE_TIME, + ) + } + + override fun logicalType(): LogicalType = LogicalType.DateTime + + override fun deserialize(p: JsonParser, context: DeserializationContext?): LocalDateTime { + val exceptions = mutableListOf() + + for (formatter in DATE_TIME_FORMATTERS) { + try { + val temporal = formatter.parse(p.text) + + return when { + !temporal.isSupported(ChronoField.HOUR_OF_DAY) -> + LocalDate.from(temporal).atStartOfDay() + !temporal.isSupported(ChronoField.OFFSET_SECONDS) -> + LocalDateTime.from(temporal) + else -> ZonedDateTime.from(temporal).toLocalDateTime() + } + } catch (e: DateTimeException) { + exceptions.add(e) + } + } + + throw JsonParseException(p, "Cannot parse `LocalDateTime` from value: ${p.text}").apply { + exceptions.forEach { addSuppressed(it) } + } + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Params.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Params.kt new file mode 100644 index 0000000..5e3891e --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Params.kt @@ -0,0 +1,16 @@ +package com.cas_parser.api.core + +import com.cas_parser.api.core.http.Headers +import com.cas_parser.api.core.http.QueryParams + +/** An interface representing parameters passed to a service method. */ +interface Params { + /** The full set of headers in the parameters, including both fixed and additional headers. */ + fun _headers(): Headers + + /** + * The full set of query params in the parameters, including both fixed and additional query + * params. + */ + fun _queryParams(): QueryParams +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/PhantomReachable.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/PhantomReachable.kt new file mode 100644 index 0000000..a08ef9b --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/PhantomReachable.kt @@ -0,0 +1,56 @@ +@file:JvmName("PhantomReachable") + +package com.cas_parser.api.core + +import com.cas_parser.api.errors.CasParserException +import java.lang.reflect.InvocationTargetException + +/** + * Closes [closeable] when [observed] becomes only phantom reachable. + * + * This is a wrapper around a Java 9+ [java.lang.ref.Cleaner], or a no-op in older Java versions. + */ +@JvmSynthetic +internal fun closeWhenPhantomReachable(observed: Any, closeable: AutoCloseable) { + check(observed !== closeable) { + "`observed` cannot be the same object as `closeable` because it would never become phantom reachable" + } + closeWhenPhantomReachable(observed, closeable::close) +} + +/** + * Calls [close] when [observed] becomes only phantom reachable. + * + * This is a wrapper around a Java 9+ [java.lang.ref.Cleaner], or a no-op in older Java versions. + */ +@JvmSynthetic +internal fun closeWhenPhantomReachable(observed: Any, close: () -> Unit) { + closeWhenPhantomReachable?.let { it(observed, close) } +} + +private val closeWhenPhantomReachable: ((Any, () -> Unit) -> Unit)? by lazy { + try { + val cleanerClass = Class.forName("java.lang.ref.Cleaner") + val cleanerCreate = cleanerClass.getMethod("create") + val cleanerRegister = + cleanerClass.getMethod("register", Any::class.java, Runnable::class.java) + val cleanerObject = cleanerCreate.invoke(null); + + { observed, close -> + try { + cleanerRegister.invoke(cleanerObject, observed, Runnable { close() }) + } catch (e: ReflectiveOperationException) { + if (e is InvocationTargetException) { + when (val cause = e.cause) { + is RuntimeException, + is Error -> throw cause + } + } + throw CasParserException("Unexpected reflective invocation failure", e) + } + } + } catch (e: ReflectiveOperationException) { + // We're running Java 8, which has no Cleaner. + null + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/PrepareRequest.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/PrepareRequest.kt new file mode 100644 index 0000000..7d0287b --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/PrepareRequest.kt @@ -0,0 +1,24 @@ +@file:JvmName("PrepareRequest") + +package com.cas_parser.api.core + +import com.cas_parser.api.core.http.HttpRequest +import java.util.concurrent.CompletableFuture + +@JvmSynthetic +internal fun HttpRequest.prepare(clientOptions: ClientOptions, params: Params): HttpRequest = + toBuilder() + .putAllQueryParams(clientOptions.queryParams) + .replaceAllQueryParams(params._queryParams()) + .putAllHeaders(clientOptions.headers) + .replaceAllHeaders(params._headers()) + .build() + +@JvmSynthetic +internal fun HttpRequest.prepareAsync( + clientOptions: ClientOptions, + params: Params, +): CompletableFuture = + // This async version exists to make it easier to add async specific preparation logic in the + // future. + CompletableFuture.completedFuture(prepare(clientOptions, params)) diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Properties.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Properties.kt new file mode 100644 index 0000000..c715f1a --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Properties.kt @@ -0,0 +1,42 @@ +@file:JvmName("Properties") + +package com.cas_parser.api.core + +import java.util.Properties + +fun getOsArch(): String { + val osArch = System.getProperty("os.arch") + + return when (osArch) { + null -> "unknown" + "i386", + "x32", + "x86" -> "x32" + "amd64", + "x86_64" -> "x64" + "arm" -> "arm" + "aarch64" -> "arm64" + else -> "other:${osArch}" + } +} + +fun getOsName(): String { + val osName = System.getProperty("os.name") + val vendorUrl = System.getProperty("java.vendor.url") + + return when { + osName == null -> "Unknown" + osName.startsWith("Linux") && vendorUrl == "http://www.android.com/" -> "Android" + osName.startsWith("Linux") -> "Linux" + osName.startsWith("Mac OS") -> "MacOS" + osName.startsWith("Windows") -> "Windows" + else -> "Other:${osName}" + } +} + +fun getOsVersion(): String = System.getProperty("os.version", "unknown") + +fun getPackageVersion(): String = + Properties::class.java.`package`.implementationVersion ?: "unknown" + +fun getJavaVersion(): String = System.getProperty("java.version", "unknown") diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/RequestOptions.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/RequestOptions.kt new file mode 100644 index 0000000..0232e87 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/RequestOptions.kt @@ -0,0 +1,46 @@ +package com.cas_parser.api.core + +import java.time.Duration + +class RequestOptions private constructor(val responseValidation: Boolean?, val timeout: Timeout?) { + + companion object { + + private val NONE = builder().build() + + @JvmStatic fun none() = NONE + + @JvmSynthetic + internal fun from(clientOptions: ClientOptions): RequestOptions = + builder() + .responseValidation(clientOptions.responseValidation) + .timeout(clientOptions.timeout) + .build() + + @JvmStatic fun builder() = Builder() + } + + fun applyDefaults(options: RequestOptions): RequestOptions = + RequestOptions( + responseValidation = responseValidation ?: options.responseValidation, + timeout = + if (options.timeout != null && timeout != null) timeout.assign(options.timeout) + else timeout ?: options.timeout, + ) + + class Builder internal constructor() { + + private var responseValidation: Boolean? = null + private var timeout: Timeout? = null + + fun responseValidation(responseValidation: Boolean) = apply { + this.responseValidation = responseValidation + } + + fun timeout(timeout: Timeout) = apply { this.timeout = timeout } + + fun timeout(timeout: Duration) = timeout(Timeout.builder().request(timeout).build()) + + fun build(): RequestOptions = RequestOptions(responseValidation, timeout) + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Timeout.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Timeout.kt new file mode 100644 index 0000000..8aaa968 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Timeout.kt @@ -0,0 +1,171 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.core + +import java.time.Duration +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** A class containing timeouts for various processing phases of a request. */ +class Timeout +private constructor( + private val connect: Duration?, + private val read: Duration?, + private val write: Duration?, + private val request: Duration?, +) { + + /** + * The maximum time allowed to establish a connection with a host. + * + * A value of [Duration.ZERO] means there's no timeout. + * + * Defaults to `Duration.ofMinutes(1)`. + */ + fun connect(): Duration = connect ?: Duration.ofMinutes(1) + + /** + * The maximum time allowed between two data packets when waiting for the server’s response. + * + * A value of [Duration.ZERO] means there's no timeout. + * + * Defaults to `request()`. + */ + fun read(): Duration = read ?: request() + + /** + * The maximum time allowed between two data packets when sending the request to the server. + * + * A value of [Duration.ZERO] means there's no timeout. + * + * Defaults to `request()`. + */ + fun write(): Duration = write ?: request() + + /** + * The maximum time allowed for a complete HTTP call, not including retries. + * + * This includes resolving DNS, connecting, writing the request body, server processing, as well + * as reading the response body. + * + * A value of [Duration.ZERO] means there's no timeout. + * + * Defaults to `Duration.ofMinutes(1)`. + */ + fun request(): Duration = request ?: Duration.ofMinutes(1) + + fun toBuilder() = Builder().from(this) + + companion object { + + @JvmStatic fun default() = builder().build() + + /** Returns a mutable builder for constructing an instance of [Timeout]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Timeout]. */ + class Builder internal constructor() { + + private var connect: Duration? = null + private var read: Duration? = null + private var write: Duration? = null + private var request: Duration? = null + + @JvmSynthetic + internal fun from(timeout: Timeout) = apply { + connect = timeout.connect + read = timeout.read + write = timeout.write + request = timeout.request + } + + /** + * The maximum time allowed to establish a connection with a host. + * + * A value of [Duration.ZERO] means there's no timeout. + * + * Defaults to `Duration.ofMinutes(1)`. + */ + fun connect(connect: Duration?) = apply { this.connect = connect } + + /** Alias for calling [Builder.connect] with `connect.orElse(null)`. */ + fun connect(connect: Optional) = connect(connect.getOrNull()) + + /** + * The maximum time allowed between two data packets when waiting for the server’s response. + * + * A value of [Duration.ZERO] means there's no timeout. + * + * Defaults to `request()`. + */ + fun read(read: Duration?) = apply { this.read = read } + + /** Alias for calling [Builder.read] with `read.orElse(null)`. */ + fun read(read: Optional) = read(read.getOrNull()) + + /** + * The maximum time allowed between two data packets when sending the request to the server. + * + * A value of [Duration.ZERO] means there's no timeout. + * + * Defaults to `request()`. + */ + fun write(write: Duration?) = apply { this.write = write } + + /** Alias for calling [Builder.write] with `write.orElse(null)`. */ + fun write(write: Optional) = write(write.getOrNull()) + + /** + * The maximum time allowed for a complete HTTP call, not including retries. + * + * This includes resolving DNS, connecting, writing the request body, server processing, as + * well as reading the response body. + * + * A value of [Duration.ZERO] means there's no timeout. + * + * Defaults to `Duration.ofMinutes(1)`. + */ + fun request(request: Duration?) = apply { this.request = request } + + /** Alias for calling [Builder.request] with `request.orElse(null)`. */ + fun request(request: Optional) = request(request.getOrNull()) + + /** + * Returns an immutable instance of [Timeout]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Timeout = Timeout(connect, read, write, request) + } + + @JvmSynthetic + internal fun assign(target: Timeout): Timeout = + target + .toBuilder() + .apply { + connect?.let(this::connect) + read?.let(this::read) + write?.let(this::write) + request?.let(this::request) + } + .build() + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Timeout && + connect == other.connect && + read == other.read && + write == other.write && + request == other.request + } + + override fun hashCode(): Int = Objects.hash(connect, read, write, request) + + override fun toString() = + "Timeout{connect=$connect, read=$read, write=$write, request=$request}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Utils.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Utils.kt new file mode 100644 index 0000000..9cdb07b --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Utils.kt @@ -0,0 +1,115 @@ +@file:JvmName("Utils") + +package com.cas_parser.api.core + +import com.cas_parser.api.errors.CasParserInvalidDataException +import java.util.Collections +import java.util.SortedMap +import java.util.concurrent.CompletableFuture +import java.util.concurrent.locks.Lock + +@JvmSynthetic +internal fun T?.getOrThrow(name: String): T = + this ?: throw CasParserInvalidDataException("`${name}` is not present") + +@JvmSynthetic +internal fun List.toImmutable(): List = + if (isEmpty()) Collections.emptyList() else Collections.unmodifiableList(toList()) + +@JvmSynthetic +internal fun Map.toImmutable(): Map = + if (isEmpty()) immutableEmptyMap() else Collections.unmodifiableMap(toMap()) + +@JvmSynthetic internal fun immutableEmptyMap(): Map = Collections.emptyMap() + +@JvmSynthetic +internal fun , V> SortedMap.toImmutable(): SortedMap = + if (isEmpty()) Collections.emptySortedMap() + else Collections.unmodifiableSortedMap(toSortedMap(comparator())) + +/** + * Returns all elements that yield the largest value for the given function, or an empty list if + * there are zero elements. + * + * This is similar to [Sequence.maxByOrNull] except it returns _all_ elements that yield the largest + * value; not just the first one. + */ +@JvmSynthetic +internal fun > Sequence.allMaxBy(selector: (T) -> R): List { + var maxValue: R? = null + val maxElements = mutableListOf() + + val iterator = iterator() + while (iterator.hasNext()) { + val element = iterator.next() + val value = selector(element) + if (maxValue == null || value > maxValue) { + maxValue = value + maxElements.clear() + maxElements.add(element) + } else if (value == maxValue) { + maxElements.add(element) + } + } + + return maxElements +} + +/** + * Returns whether [this] is equal to [other]. + * + * This differs from [Object.equals] because it also deeply equates arrays based on their contents, + * even when there are arrays directly nested within other arrays. + */ +@JvmSynthetic +internal infix fun Any?.contentEquals(other: Any?): Boolean = + arrayOf(this).contentDeepEquals(arrayOf(other)) + +/** + * Returns a hash of the given sequence of [values]. + * + * This differs from [java.util.Objects.hash] because it also deeply hashes arrays based on their + * contents, even when there are arrays directly nested within other arrays. + */ +@JvmSynthetic internal fun contentHash(vararg values: Any?): Int = values.contentDeepHashCode() + +/** + * Returns a [String] representation of [this]. + * + * This differs from [Object.toString] because it also deeply stringifies arrays based on their + * contents, even when there are arrays directly nested within other arrays. + */ +@JvmSynthetic +internal fun Any?.contentToString(): String { + var string = arrayOf(this).contentDeepToString() + if (string.startsWith('[')) { + string = string.substring(1) + } + if (string.endsWith(']')) { + string = string.substring(0, string.length - 1) + } + return string +} + +internal interface Enum + +/** + * Executes the given [action] while holding the lock, returning a [CompletableFuture] with the + * result. + * + * @param action The asynchronous action to execute while holding the lock + * @return A [CompletableFuture] that completes with the result of the action + */ +@JvmSynthetic +internal fun Lock.withLockAsync(action: () -> CompletableFuture): CompletableFuture { + lock() + val future = + try { + action() + } catch (e: Throwable) { + unlock() + throw e + } + future.whenComplete { _, _ -> unlock() } + return future +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Values.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Values.kt new file mode 100644 index 0000000..08c2a3f --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Values.kt @@ -0,0 +1,723 @@ +package com.cas_parser.api.core + +import com.cas_parser.api.errors.CasParserInvalidDataException +import com.fasterxml.jackson.annotation.JacksonAnnotationsInside +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.ObjectCodec +import com.fasterxml.jackson.core.type.TypeReference +import com.fasterxml.jackson.databind.BeanProperty +import com.fasterxml.jackson.databind.DeserializationContext +import com.fasterxml.jackson.databind.JavaType +import com.fasterxml.jackson.databind.JsonDeserializer +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.SerializerProvider +import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import com.fasterxml.jackson.databind.annotation.JsonSerialize +import com.fasterxml.jackson.databind.node.JsonNodeType.ARRAY +import com.fasterxml.jackson.databind.node.JsonNodeType.BINARY +import com.fasterxml.jackson.databind.node.JsonNodeType.BOOLEAN +import com.fasterxml.jackson.databind.node.JsonNodeType.MISSING +import com.fasterxml.jackson.databind.node.JsonNodeType.NULL +import com.fasterxml.jackson.databind.node.JsonNodeType.NUMBER +import com.fasterxml.jackson.databind.node.JsonNodeType.OBJECT +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 java.io.InputStream +import java.util.Objects +import java.util.Optional + +/** + * A class representing a serializable JSON field. + * + * It can either be a [KnownValue] value of type [T], matching the type the SDK expects, or an + * arbitrary JSON value that bypasses the type system (via [JsonValue]). + */ +@JsonDeserialize(using = JsonField.Deserializer::class) +sealed class JsonField { + + /** + * Returns whether this field is missing, which means it will be omitted from the serialized + * JSON entirely. + */ + fun isMissing(): Boolean = this is JsonMissing + + /** Whether this field is explicitly set to `null`. */ + fun isNull(): Boolean = this is JsonNull + + /** + * Returns an [Optional] containing this field's "known" value, meaning it matches the type the + * SDK expects, or an empty [Optional] if this field contains an arbitrary [JsonValue]. + * + * This is the opposite of [asUnknown]. + */ + fun asKnown(): + Optional< + // Safe because `Optional` is effectively covariant, but Kotlin doesn't know that. + @UnsafeVariance + T + > = Optional.ofNullable((this as? KnownValue)?.value) + + /** + * Returns an [Optional] containing this field's arbitrary [JsonValue], meaning it mismatches + * the type the SDK expects, or an empty [Optional] if this field contains a "known" value. + * + * This is the opposite of [asKnown]. + */ + fun asUnknown(): Optional = Optional.ofNullable(this as? JsonValue) + + /** + * Returns an [Optional] containing this field's boolean value, or an empty [Optional] if it + * doesn't contain a boolean. + * + * This method checks for both a [KnownValue] containing a boolean and for [JsonBoolean]. + */ + fun asBoolean(): Optional = + when (this) { + is JsonBoolean -> Optional.of(value) + is KnownValue -> Optional.ofNullable(value as? Boolean) + else -> Optional.empty() + } + + /** + * Returns an [Optional] containing this field's numerical value, or an empty [Optional] if it + * doesn't contain a number. + * + * This method checks for both a [KnownValue] containing a number and for [JsonNumber]. + */ + fun asNumber(): Optional = + when (this) { + is JsonNumber -> Optional.of(value) + is KnownValue -> Optional.ofNullable(value as? Number) + else -> Optional.empty() + } + + /** + * Returns an [Optional] containing this field's string value, or an empty [Optional] if it + * doesn't contain a string. + * + * This method checks for both a [KnownValue] containing a string and for [JsonString]. + */ + fun asString(): Optional = + when (this) { + is JsonString -> Optional.of(value) + is KnownValue -> Optional.ofNullable(value as? String) + else -> Optional.empty() + } + + fun asStringOrThrow(): String = + asString().orElseThrow { CasParserInvalidDataException("Value is not a string") } + + /** + * Returns an [Optional] containing this field's list value, or an empty [Optional] if it + * doesn't contain a list. + * + * This method checks for both a [KnownValue] containing a list and for [JsonArray]. + */ + fun asArray(): Optional> = + when (this) { + is JsonArray -> Optional.of(values) + is KnownValue -> + Optional.ofNullable( + (value as? List<*>)?.map { + try { + JsonValue.from(it) + } catch (e: IllegalArgumentException) { + // The known value is a list, but not all values are convertible to + // `JsonValue`. + return Optional.empty() + } + } + ) + else -> Optional.empty() + } + + /** + * Returns an [Optional] containing this field's map value, or an empty [Optional] if it doesn't + * contain a map. + * + * This method checks for both a [KnownValue] containing a map and for [JsonObject]. + */ + fun asObject(): Optional> = + when (this) { + is JsonObject -> Optional.of(values) + is KnownValue -> + Optional.ofNullable( + (value as? Map<*, *>) + ?.map { (key, value) -> + if (key !is String) { + return Optional.empty() + } + + val jsonValue = + try { + JsonValue.from(value) + } catch (e: IllegalArgumentException) { + // The known value is a map, but not all items are convertible + // to `JsonValue`. + return Optional.empty() + } + + key to jsonValue + } + ?.toMap() + ) + else -> Optional.empty() + } + + @JvmSynthetic + internal fun getRequired(name: String): T = + when (this) { + is KnownValue -> value + is JsonMissing -> throw CasParserInvalidDataException("`$name` is not set") + is JsonNull -> throw CasParserInvalidDataException("`$name` is null") + else -> throw CasParserInvalidDataException("`$name` is invalid, received $this") + } + + @JvmSynthetic + internal fun getOptional( + name: String + ): Optional< + // Safe because `Optional` is effectively covariant, but Kotlin doesn't know that. + @UnsafeVariance + T + > = + when (this) { + is KnownValue -> Optional.of(value) + is JsonMissing, + is JsonNull -> Optional.empty() + else -> throw CasParserInvalidDataException("`$name` is invalid, received $this") + } + + @JvmSynthetic + internal fun map(transform: (T) -> R): JsonField = + when (this) { + is KnownValue -> KnownValue.of(transform(value)) + is JsonValue -> this + } + + @JvmSynthetic internal fun accept(consume: (T) -> Unit) = asKnown().ifPresent(consume) + + /** Returns the result of calling the [visitor] method corresponding to this field's state. */ + fun accept(visitor: Visitor): R = + when (this) { + is KnownValue -> visitor.visitKnown(value) + is JsonValue -> accept(visitor as JsonValue.Visitor) + } + + /** + * An interface that defines how to map each possible state of a `JsonField` to a value of + * type [R]. + */ + interface Visitor : JsonValue.Visitor { + + fun visitKnown(value: T): R = visitDefault() + } + + companion object { + + /** Returns a [JsonField] containing the given "known" [value]. */ + @JvmStatic fun of(value: T): JsonField = KnownValue.of(value) + + /** + * Returns a [JsonField] containing the given "known" [value], or [JsonNull] if [value] is + * null. + */ + @JvmStatic + fun ofNullable(value: T?): JsonField = + when (value) { + null -> JsonNull.of() + else -> KnownValue.of(value) + } + } + + /** + * This class is a Jackson filter that can be used to exclude missing properties from objects. + * This filter should not be used directly and should instead use the @ExcludeMissing + * annotation. + */ + class IsMissing { + + override fun equals(other: Any?): Boolean = other is JsonMissing + + override fun hashCode(): Int = Objects.hash() + } + + class Deserializer(private val type: JavaType? = null) : + BaseDeserializer>(JsonField::class) { + + override fun createContextual( + context: DeserializationContext, + property: BeanProperty?, + ): JsonDeserializer> = Deserializer(context.contextualType?.containedType(0)) + + override fun ObjectCodec.deserialize(node: JsonNode): JsonField<*> = + type?.let { tryDeserialize(node, type) }?.let { of(it) } + ?: JsonValue.fromJsonNode(node) + + override fun getNullValue(context: DeserializationContext): JsonField<*> = JsonNull.of() + } +} + +/** + * A class representing an arbitrary JSON value. + * + * It is immutable and assignable to any [JsonField], regardless of its expected type (i.e. its + * generic type argument). + */ +@JsonDeserialize(using = JsonValue.Deserializer::class) +sealed class JsonValue : JsonField() { + + fun convert(type: TypeReference): R? = JSON_MAPPER.convertValue(this, type) + + fun convert(type: Class): R? = JSON_MAPPER.convertValue(this, type) + + /** Returns the result of calling the [visitor] method corresponding to this value's variant. */ + fun accept(visitor: Visitor): R = + when (this) { + is JsonMissing -> visitor.visitMissing() + is JsonNull -> visitor.visitNull() + is JsonBoolean -> visitor.visitBoolean(value) + is JsonNumber -> visitor.visitNumber(value) + is JsonString -> visitor.visitString(value) + is JsonArray -> visitor.visitArray(values) + is JsonObject -> visitor.visitObject(values) + } + + /** + * An interface that defines how to map each variant state of a [JsonValue] to a value of type + * [R]. + */ + interface Visitor { + + fun visitNull(): R = visitDefault() + + fun visitMissing(): R = visitDefault() + + fun visitBoolean(value: Boolean): R = visitDefault() + + fun visitNumber(value: Number): R = visitDefault() + + fun visitString(value: String): R = visitDefault() + + fun visitArray(values: List): R = visitDefault() + + fun visitObject(values: Map): R = visitDefault() + + /** + * The default implementation for unimplemented visitor methods. + * + * @throws IllegalArgumentException in the default implementation. + */ + fun visitDefault(): R = throw IllegalArgumentException("Unexpected value") + } + + companion object { + + private val JSON_MAPPER = jsonMapper() + + /** + * Converts the given [value] to a [JsonValue]. + * + * This method works best on primitive types, [List] values, [Map] values, and nested + * combinations of these. For example: + * ```java + * // Create primitive JSON values + * JsonValue nullValue = JsonValue.from(null); + * JsonValue booleanValue = JsonValue.from(true); + * JsonValue numberValue = JsonValue.from(42); + * JsonValue stringValue = JsonValue.from("Hello World!"); + * + * // Create a JSON array value equivalent to `["Hello", "World"]` + * JsonValue arrayValue = JsonValue.from(List.of("Hello", "World")); + * + * // Create a JSON object value equivalent to `{ "a": 1, "b": 2 }` + * JsonValue objectValue = JsonValue.from(Map.of( + * "a", 1, + * "b", 2 + * )); + * + * // Create an arbitrarily nested JSON equivalent to: + * // { + * // "a": [1, 2], + * // "b": [3, 4] + * // } + * JsonValue complexValue = JsonValue.from(Map.of( + * "a", List.of(1, 2), + * "b", List.of(3, 4) + * )); + * ``` + * + * @throws IllegalArgumentException if [value] is not JSON serializable. + */ + @JvmStatic + fun from(value: Any?): JsonValue = + when (value) { + null -> JsonNull.of() + is JsonValue -> value + else -> JSON_MAPPER.convertValue(value, JsonValue::class.java) + } + + /** + * Returns a [JsonValue] converted from the given Jackson [JsonNode]. + * + * @throws IllegalStateException for unsupported node types. + */ + @JvmStatic + fun fromJsonNode(node: JsonNode): JsonValue = + when (node.nodeType) { + MISSING -> JsonMissing.of() + NULL -> JsonNull.of() + BOOLEAN -> JsonBoolean.of(node.booleanValue()) + NUMBER -> JsonNumber.of(node.numberValue()) + STRING -> JsonString.of(node.textValue()) + ARRAY -> + JsonArray.of(node.elements().asSequence().map { fromJsonNode(it) }.toList()) + OBJECT -> + JsonObject.of( + node.fields().asSequence().map { it.key to fromJsonNode(it.value) }.toMap() + ) + BINARY, + POJO, + null -> throw IllegalStateException("Unexpected JsonNode type: ${node.nodeType}") + } + } + + class Deserializer : BaseDeserializer(JsonValue::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): JsonValue = fromJsonNode(node) + + override fun getNullValue(context: DeserializationContext?): JsonValue = JsonNull.of() + } +} + +/** + * A class representing a "known" JSON serializable value of type [T], matching the type the SDK + * expects. + * + * It is assignable to `JsonField`. + */ +class KnownValue +private constructor( + @com.fasterxml.jackson.annotation.JsonValue @get:JvmName("value") val value: T +) : JsonField() { + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is KnownValue<*> && value contentEquals other.value + } + + override fun hashCode() = contentHash(value) + + override fun toString() = value.contentToString() + + companion object { + + /** Returns a [KnownValue] containing the given [value]. */ + @JsonCreator @JvmStatic fun of(value: T) = KnownValue(value) + } +} + +/** + * A [JsonValue] representing an omitted JSON field. + * + * An instance of this class will cause a JSON field to be omitted from the serialized JSON + * entirely. + */ +@JsonSerialize(using = JsonMissing.Serializer::class) +class JsonMissing : JsonValue() { + + override fun toString() = "" + + companion object { + + private val INSTANCE: JsonMissing = JsonMissing() + + /** Returns the singleton instance of [JsonMissing]. */ + @JvmStatic fun of() = INSTANCE + } + + class Serializer : BaseSerializer(JsonMissing::class) { + + override fun serialize( + value: JsonMissing, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + throw IllegalStateException("JsonMissing cannot be serialized") + } + } +} + +/** A [JsonValue] representing a JSON `null` value. */ +@JsonSerialize(using = NullSerializer::class) +class JsonNull : JsonValue() { + + override fun toString() = "null" + + companion object { + + private val INSTANCE: JsonNull = JsonNull() + + /** Returns the singleton instance of [JsonMissing]. */ + @JsonCreator @JvmStatic fun of() = INSTANCE + } +} + +/** A [JsonValue] representing a JSON boolean value. */ +class JsonBoolean +private constructor( + @get:com.fasterxml.jackson.annotation.JsonValue @get:JvmName("value") val value: Boolean +) : JsonValue() { + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is JsonBoolean && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + + companion object { + + /** Returns a [JsonBoolean] containing the given [value]. */ + @JsonCreator @JvmStatic fun of(value: Boolean) = JsonBoolean(value) + } +} + +/** A [JsonValue] representing a JSON number value. */ +class JsonNumber +private constructor( + @get:com.fasterxml.jackson.annotation.JsonValue @get:JvmName("value") val value: Number +) : JsonValue() { + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is JsonNumber && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + + companion object { + + /** Returns a [JsonNumber] containing the given [value]. */ + @JsonCreator @JvmStatic fun of(value: Number) = JsonNumber(value) + } +} + +/** A [JsonValue] representing a JSON string value. */ +class JsonString +private constructor( + @get:com.fasterxml.jackson.annotation.JsonValue @get:JvmName("value") val value: String +) : JsonValue() { + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is JsonString && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value + + companion object { + + /** Returns a [JsonString] containing the given [value]. */ + @JsonCreator @JvmStatic fun of(value: String) = JsonString(value) + } +} + +/** A [JsonValue] representing a JSON array value. */ +class JsonArray +private constructor( + @get:com.fasterxml.jackson.annotation.JsonValue + @get:JvmName("values") + val values: List +) : JsonValue() { + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is JsonArray && values == other.values + } + + override fun hashCode() = values.hashCode() + + override fun toString() = values.toString() + + companion object { + + /** Returns a [JsonArray] containing the given [values]. */ + @JsonCreator @JvmStatic fun of(values: List) = JsonArray(values.toImmutable()) + } +} + +/** A [JsonValue] representing a JSON object value. */ +class JsonObject +private constructor( + @get:com.fasterxml.jackson.annotation.JsonValue + @get:JvmName("values") + val values: Map +) : JsonValue() { + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is JsonObject && values == other.values + } + + override fun hashCode() = values.hashCode() + + override fun toString() = values.toString() + + companion object { + + /** Returns a [JsonObject] containing the given [values]. */ + @JsonCreator + @JvmStatic + fun of(values: Map) = JsonObject(values.toImmutable()) + } +} + +/** A Jackson annotation for excluding fields set to [JsonMissing] from the serialized JSON. */ +@JacksonAnnotationsInside +@JsonInclude(JsonInclude.Include.CUSTOM, valueFilter = JsonField.IsMissing::class) +annotation class ExcludeMissing + +/** A class representing a field in a `multipart/form-data` request. */ +class MultipartField +private constructor( + /** A [JsonField] value, which will be serialized to zero or more parts. */ + @get:com.fasterxml.jackson.annotation.JsonValue @get:JvmName("value") val value: JsonField, + /** A content type for the serialized parts. */ + @get:JvmName("contentType") val contentType: String, + private val filename: String?, +) { + + companion object { + + /** + * Returns a [MultipartField] containing the given [value] as a [KnownValue]. + * + * [contentType] will be set to `application/octet-stream` if [value] is binary data, or + * `text/plain; charset=utf-8` otherwise. + */ + @JvmStatic fun of(value: T?) = builder().value(value).build() + + /** + * Returns a [MultipartField] containing the given [value]. + * + * [contentType] will be set to `application/octet-stream` if [value] is binary data, or + * `text/plain; charset=utf-8` otherwise. + */ + @JvmStatic fun of(value: JsonField) = builder().value(value).build() + + /** + * Returns a mutable builder for constructing an instance of [MultipartField]. + * + * The following fields are required: + * ```java + * .value() + * ``` + * + * If [contentType] is unset, then it will be set to `application/octet-stream` if [value] + * is binary data, or `text/plain; charset=utf-8` otherwise. + */ + @JvmStatic fun builder() = Builder() + } + + /** Returns the filename directive that will be included in the serialized field. */ + fun filename(): Optional = Optional.ofNullable(filename) + + @JvmSynthetic + internal fun map(transform: (T) -> R): MultipartField = + builder().value(value.map(transform)).contentType(contentType).filename(filename).build() + + /** A builder for [MultipartField]. */ + class Builder internal constructor() { + + private var value: JsonField? = null + private var contentType: String? = null + private var filename: String? = null + + fun value(value: JsonField) = apply { this.value = value } + + fun value(value: T?) = value(JsonField.ofNullable(value)) + + fun contentType(contentType: String) = apply { this.contentType = contentType } + + fun filename(filename: String?) = apply { this.filename = filename } + + /** Alias for calling [Builder.filename] with `filename.orElse(null)`. */ + fun filename(filename: Optional) = filename(filename.orElse(null)) + + /** + * Returns an immutable instance of [MultipartField]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .value() + * ``` + * + * If [contentType] is unset, then it will be set to `application/octet-stream` if [value] + * is binary data, or `text/plain; charset=utf-8` otherwise. + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): MultipartField { + val value = checkRequired("value", value) + return MultipartField( + value, + contentType + ?: if ( + value is KnownValue && + (value.value is InputStream || value.value is ByteArray) + ) + "application/octet-stream" + else "text/plain; charset=utf-8", + filename, + ) + } + } + + private val hashCode: Int by lazy { contentHash(value, contentType, filename) } + + override fun hashCode(): Int = hashCode + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is MultipartField<*> && + value == other.value && + contentType == other.contentType && + filename == other.filename + } + + override fun toString(): String = + "MultipartField{value=$value, contentType=$contentType, filename=$filename}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/handlers/ErrorHandler.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/handlers/ErrorHandler.kt new file mode 100644 index 0000000..1209491 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/handlers/ErrorHandler.kt @@ -0,0 +1,84 @@ +// File generated from our OpenAPI spec by Stainless. + +@file:JvmName("ErrorHandler") + +package com.cas_parser.api.core.handlers + +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.http.HttpResponse +import com.cas_parser.api.core.http.HttpResponse.Handler +import com.cas_parser.api.errors.BadRequestException +import com.cas_parser.api.errors.InternalServerException +import com.cas_parser.api.errors.NotFoundException +import com.cas_parser.api.errors.PermissionDeniedException +import com.cas_parser.api.errors.RateLimitException +import com.cas_parser.api.errors.UnauthorizedException +import com.cas_parser.api.errors.UnexpectedStatusCodeException +import com.cas_parser.api.errors.UnprocessableEntityException +import com.fasterxml.jackson.databind.json.JsonMapper + +@JvmSynthetic +internal fun errorBodyHandler(jsonMapper: JsonMapper): Handler { + val handler = jsonHandler(jsonMapper) + + return object : Handler { + override fun handle(response: HttpResponse): JsonValue = + try { + handler.handle(response) + } catch (e: Exception) { + JsonMissing.of() + } + } +} + +@JvmSynthetic +internal fun errorHandler(errorBodyHandler: Handler): Handler = + object : Handler { + override fun handle(response: HttpResponse): HttpResponse = + when (val statusCode = response.statusCode()) { + in 200..299 -> response + 400 -> + throw BadRequestException.builder() + .headers(response.headers()) + .body(errorBodyHandler.handle(response)) + .build() + 401 -> + throw UnauthorizedException.builder() + .headers(response.headers()) + .body(errorBodyHandler.handle(response)) + .build() + 403 -> + throw PermissionDeniedException.builder() + .headers(response.headers()) + .body(errorBodyHandler.handle(response)) + .build() + 404 -> + throw NotFoundException.builder() + .headers(response.headers()) + .body(errorBodyHandler.handle(response)) + .build() + 422 -> + throw UnprocessableEntityException.builder() + .headers(response.headers()) + .body(errorBodyHandler.handle(response)) + .build() + 429 -> + throw RateLimitException.builder() + .headers(response.headers()) + .body(errorBodyHandler.handle(response)) + .build() + in 500..599 -> + throw InternalServerException.builder() + .statusCode(statusCode) + .headers(response.headers()) + .body(errorBodyHandler.handle(response)) + .build() + else -> + throw UnexpectedStatusCodeException.builder() + .statusCode(statusCode) + .headers(response.headers()) + .body(errorBodyHandler.handle(response)) + .build() + } + } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/handlers/JsonHandler.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/handlers/JsonHandler.kt new file mode 100644 index 0000000..94121e6 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/handlers/JsonHandler.kt @@ -0,0 +1,20 @@ +@file:JvmName("JsonHandler") + +package com.cas_parser.api.core.handlers + +import com.cas_parser.api.core.http.HttpResponse +import com.cas_parser.api.core.http.HttpResponse.Handler +import com.cas_parser.api.errors.CasParserInvalidDataException +import com.fasterxml.jackson.databind.json.JsonMapper +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef + +@JvmSynthetic +internal inline fun jsonHandler(jsonMapper: JsonMapper): Handler = + object : Handler { + override fun handle(response: HttpResponse): T = + try { + jsonMapper.readValue(response.body(), jacksonTypeRef()) + } catch (e: Exception) { + throw CasParserInvalidDataException("Error reading response", e) + } + } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/handlers/StringHandler.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/handlers/StringHandler.kt new file mode 100644 index 0000000..908418d --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/handlers/StringHandler.kt @@ -0,0 +1,13 @@ +@file:JvmName("StringHandler") + +package com.cas_parser.api.core.handlers + +import com.cas_parser.api.core.http.HttpResponse +import com.cas_parser.api.core.http.HttpResponse.Handler + +@JvmSynthetic internal fun stringHandler(): Handler = StringHandlerInternal + +private object StringHandlerInternal : Handler { + override fun handle(response: HttpResponse): String = + response.body().readBytes().toString(Charsets.UTF_8) +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/AsyncStreamResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/AsyncStreamResponse.kt new file mode 100644 index 0000000..561090a --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/AsyncStreamResponse.kt @@ -0,0 +1,157 @@ +package com.cas_parser.api.core.http + +import com.cas_parser.api.core.http.AsyncStreamResponse.Handler +import java.util.Optional +import java.util.concurrent.CompletableFuture +import java.util.concurrent.Executor +import java.util.concurrent.atomic.AtomicReference + +/** + * A class providing access to an API response as an asynchronous stream of chunks of type [T], + * where each chunk can be individually processed as soon as it arrives instead of waiting on the + * full response. + */ +interface AsyncStreamResponse { + + /** + * Registers [handler] to be called for events of this stream. + * + * [handler]'s methods will be called in the client's configured or default thread pool. + * + * @throws IllegalStateException if [subscribe] has already been called. + */ + fun subscribe(handler: Handler): AsyncStreamResponse + + /** + * Registers [handler] to be called for events of this stream. + * + * [handler]'s methods will be called in the given [executor]. + * + * @throws IllegalStateException if [subscribe] has already been called. + */ + fun subscribe(handler: Handler, executor: Executor): AsyncStreamResponse + + /** + * Returns a future that completes when a stream is fully consumed, errors, or gets closed + * early. + */ + fun onCompleteFuture(): CompletableFuture + + /** + * Closes this resource, relinquishing any underlying resources. + * + * This is purposefully not inherited from [AutoCloseable] because this response should not be + * synchronously closed via try-with-resources. + */ + fun close() + + /** A class for handling streaming events. */ + fun interface Handler { + + /** Called whenever a chunk is received. */ + fun onNext(value: T) + + /** + * Called when a stream is fully consumed, errors, or gets closed early. + * + * [onNext] will not be called once this method is called. + * + * @param error Non-empty if the stream completed due to an error. + */ + fun onComplete(error: Optional) {} + } +} + +@JvmSynthetic +internal fun CompletableFuture>.toAsync(streamHandlerExecutor: Executor) = + PhantomReachableClosingAsyncStreamResponse( + object : AsyncStreamResponse { + + private val onCompleteFuture = CompletableFuture() + private val state = AtomicReference(State.NEW) + + init { + this@toAsync.whenComplete { _, error -> + // If an error occurs from the original future, then we should resolve the + // `onCompleteFuture` even if `subscribe` has not been called. + error?.let(onCompleteFuture::completeExceptionally) + } + } + + override fun subscribe(handler: Handler): AsyncStreamResponse = + subscribe(handler, streamHandlerExecutor) + + override fun subscribe( + handler: Handler, + executor: Executor, + ): AsyncStreamResponse = apply { + // TODO(JDK): Use `compareAndExchange` once targeting JDK 9. + check(state.compareAndSet(State.NEW, State.SUBSCRIBED)) { + if (state.get() == State.SUBSCRIBED) "Cannot subscribe more than once" + else "Cannot subscribe after the response is closed" + } + + this@toAsync.whenCompleteAsync( + { streamResponse, futureError -> + if (state.get() == State.CLOSED) { + // Avoid doing any work if `close` was called before the future + // completed. + return@whenCompleteAsync + } + + if (futureError != null) { + // An error occurred before we started passing chunks to the handler. + handler.onComplete(Optional.of(futureError)) + return@whenCompleteAsync + } + + var streamError: Throwable? = null + try { + streamResponse.stream().forEach(handler::onNext) + } catch (e: Throwable) { + streamError = e + } + + try { + handler.onComplete(Optional.ofNullable(streamError)) + } finally { + try { + // Notify completion via the `onCompleteFuture` as well. This is in + // a separate `try-finally` block so that we still complete the + // future if `handler.onComplete` throws. + if (streamError == null) { + onCompleteFuture.complete(null) + } else { + onCompleteFuture.completeExceptionally(streamError) + } + } finally { + close() + } + } + }, + executor, + ) + } + + override fun onCompleteFuture(): CompletableFuture = onCompleteFuture + + override fun close() { + val previousState = state.getAndSet(State.CLOSED) + if (previousState == State.CLOSED) { + return + } + + this@toAsync.whenComplete { streamResponse, error -> streamResponse?.close() } + // When the stream is closed, we should always consider it closed. If it closed due + // to an error, then we will have already completed the future earlier, and this + // will be a no-op. + onCompleteFuture.complete(null) + } + } + ) + +private enum class State { + NEW, + SUBSCRIBED, + CLOSED, +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/Headers.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/Headers.kt new file mode 100644 index 0000000..52ab0bd --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/Headers.kt @@ -0,0 +1,115 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.core.http + +import com.cas_parser.api.core.JsonArray +import com.cas_parser.api.core.JsonBoolean +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonNull +import com.cas_parser.api.core.JsonNumber +import com.cas_parser.api.core.JsonObject +import com.cas_parser.api.core.JsonString +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.toImmutable +import java.util.TreeMap + +class Headers +private constructor( + private val map: Map>, + @get:JvmName("size") val size: Int, +) { + + fun isEmpty(): Boolean = map.isEmpty() + + fun names(): Set = map.keys + + fun values(name: String): List = map[name].orEmpty() + + fun toBuilder(): Builder = Builder().putAll(map) + + companion object { + + @JvmStatic fun builder() = Builder() + } + + class Builder internal constructor() { + + private val map: MutableMap> = + TreeMap(String.CASE_INSENSITIVE_ORDER) + private var size: Int = 0 + + fun put(name: String, value: JsonValue): Builder = apply { + when (value) { + is JsonMissing, + is JsonNull -> {} + is JsonBoolean -> put(name, value.value.toString()) + is JsonNumber -> put(name, value.value.toString()) + is JsonString -> put(name, value.value) + is JsonArray -> value.values.forEach { put(name, it) } + is JsonObject -> + value.values.forEach { (nestedName, value) -> put("$name.$nestedName", value) } + } + } + + fun put(name: String, value: String) = apply { + map.getOrPut(name) { mutableListOf() }.add(value) + size++ + } + + fun put(name: String, values: Iterable) = apply { values.forEach { put(name, it) } } + + fun putAll(headers: Map>) = apply { headers.forEach(::put) } + + fun putAll(headers: Headers) = apply { + headers.names().forEach { put(it, headers.values(it)) } + } + + fun replace(name: String, value: String) = apply { + remove(name) + put(name, value) + } + + fun replace(name: String, values: Iterable) = apply { + remove(name) + put(name, values) + } + + fun replaceAll(headers: Map>) = apply { + headers.forEach(::replace) + } + + fun replaceAll(headers: Headers) = apply { + headers.names().forEach { replace(it, headers.values(it)) } + } + + fun remove(name: String) = apply { size -= map.remove(name).orEmpty().size } + + fun removeAll(names: Set) = apply { names.forEach(::remove) } + + fun clear() = apply { + map.clear() + size = 0 + } + + fun build() = + Headers( + map.mapValuesTo(TreeMap(String.CASE_INSENSITIVE_ORDER)) { (_, values) -> + values.toImmutable() + } + .toImmutable(), + size, + ) + } + + override fun hashCode(): Int = map.hashCode() + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Headers && map == other.map + } + + override fun toString(): String = "Headers{map=$map}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/HttpClient.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/HttpClient.kt new file mode 100644 index 0000000..0801f90 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/HttpClient.kt @@ -0,0 +1,26 @@ +package com.cas_parser.api.core.http + +import com.cas_parser.api.core.RequestOptions +import java.lang.AutoCloseable +import java.util.concurrent.CompletableFuture + +interface HttpClient : AutoCloseable { + + fun execute( + request: HttpRequest, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponse + + fun execute(request: HttpRequest): HttpResponse = execute(request, RequestOptions.none()) + + fun executeAsync( + request: HttpRequest, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + fun executeAsync(request: HttpRequest): CompletableFuture = + executeAsync(request, RequestOptions.none()) + + /** Overridden from [AutoCloseable] to not have a checked exception in its signature. */ + override fun close() +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/HttpMethod.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/HttpMethod.kt new file mode 100644 index 0000000..039990b --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/HttpMethod.kt @@ -0,0 +1,13 @@ +package com.cas_parser.api.core.http + +enum class HttpMethod { + GET, + HEAD, + POST, + PUT, + DELETE, + CONNECT, + OPTIONS, + TRACE, + PATCH, +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/HttpRequest.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/HttpRequest.kt new file mode 100644 index 0000000..7301769 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/HttpRequest.kt @@ -0,0 +1,146 @@ +package com.cas_parser.api.core.http + +import com.cas_parser.api.core.checkRequired +import com.cas_parser.api.core.toImmutable + +class HttpRequest +private constructor( + @get:JvmName("method") val method: HttpMethod, + @get:JvmName("baseUrl") val baseUrl: String, + @get:JvmName("pathSegments") val pathSegments: List, + @get:JvmName("headers") val headers: Headers, + @get:JvmName("queryParams") val queryParams: QueryParams, + @get:JvmName("body") val body: HttpRequestBody?, +) { + + fun toBuilder(): Builder = Builder().from(this) + + override fun toString(): String = + "HttpRequest{method=$method, baseUrl=$baseUrl, pathSegments=$pathSegments, headers=$headers, queryParams=$queryParams, body=$body}" + + companion object { + @JvmStatic fun builder() = Builder() + } + + class Builder internal constructor() { + + private var method: HttpMethod? = null + private var baseUrl: String? = null + private var pathSegments: MutableList = mutableListOf() + private var headers: Headers.Builder = Headers.builder() + private var queryParams: QueryParams.Builder = QueryParams.builder() + private var body: HttpRequestBody? = null + + @JvmSynthetic + internal fun from(request: HttpRequest) = apply { + method = request.method + baseUrl = request.baseUrl + pathSegments = request.pathSegments.toMutableList() + headers = request.headers.toBuilder() + queryParams = request.queryParams.toBuilder() + body = request.body + } + + fun method(method: HttpMethod) = apply { this.method = method } + + fun baseUrl(baseUrl: String) = apply { this.baseUrl = baseUrl } + + fun addPathSegment(pathSegment: String) = apply { pathSegments.add(pathSegment) } + + fun addPathSegments(vararg pathSegments: String) = apply { + this.pathSegments.addAll(pathSegments) + } + + fun headers(headers: Headers) = apply { + this.headers.clear() + putAllHeaders(headers) + } + + fun headers(headers: Map>) = apply { + this.headers.clear() + putAllHeaders(headers) + } + + fun putHeader(name: String, value: String) = apply { headers.put(name, value) } + + fun putHeaders(name: String, values: Iterable) = apply { headers.put(name, values) } + + fun putAllHeaders(headers: Headers) = apply { this.headers.putAll(headers) } + + fun putAllHeaders(headers: Map>) = apply { + this.headers.putAll(headers) + } + + fun replaceHeaders(name: String, value: String) = apply { headers.replace(name, value) } + + fun replaceHeaders(name: String, values: Iterable) = apply { + headers.replace(name, values) + } + + fun replaceAllHeaders(headers: Headers) = apply { this.headers.replaceAll(headers) } + + fun replaceAllHeaders(headers: Map>) = apply { + this.headers.replaceAll(headers) + } + + fun removeHeaders(name: String) = apply { headers.remove(name) } + + fun removeAllHeaders(names: Set) = apply { headers.removeAll(names) } + + fun queryParams(queryParams: QueryParams) = apply { + this.queryParams.clear() + putAllQueryParams(queryParams) + } + + fun queryParams(queryParams: Map>) = apply { + this.queryParams.clear() + putAllQueryParams(queryParams) + } + + fun putQueryParam(key: String, value: String) = apply { queryParams.put(key, value) } + + fun putQueryParams(key: String, values: Iterable) = apply { + queryParams.put(key, values) + } + + fun putAllQueryParams(queryParams: QueryParams) = apply { + this.queryParams.putAll(queryParams) + } + + fun putAllQueryParams(queryParams: Map>) = apply { + this.queryParams.putAll(queryParams) + } + + fun replaceQueryParams(key: String, value: String) = apply { + queryParams.replace(key, value) + } + + fun replaceQueryParams(key: String, values: Iterable) = apply { + queryParams.replace(key, values) + } + + fun replaceAllQueryParams(queryParams: QueryParams) = apply { + this.queryParams.replaceAll(queryParams) + } + + fun replaceAllQueryParams(queryParams: Map>) = apply { + this.queryParams.replaceAll(queryParams) + } + + fun removeQueryParams(key: String) = apply { queryParams.remove(key) } + + fun removeAllQueryParams(keys: Set) = apply { queryParams.removeAll(keys) } + + fun body(body: HttpRequestBody) = apply { this.body = body } + + fun build(): HttpRequest = + HttpRequest( + checkRequired("method", method), + checkRequired("baseUrl", baseUrl), + pathSegments.toImmutable(), + headers.build(), + queryParams.build(), + body, + ) + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/HttpRequestBodies.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/HttpRequestBodies.kt new file mode 100644 index 0000000..34ce9d6 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/HttpRequestBodies.kt @@ -0,0 +1,130 @@ +// File generated from our OpenAPI spec by Stainless. + +@file:JvmName("HttpRequestBodies") + +package com.cas_parser.api.core.http + +import com.cas_parser.api.core.MultipartField +import com.cas_parser.api.errors.CasParserInvalidDataException +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.json.JsonMapper +import com.fasterxml.jackson.databind.node.JsonNodeType +import java.io.InputStream +import java.io.OutputStream +import kotlin.jvm.optionals.getOrNull +import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder +import org.apache.hc.core5.http.ContentType +import org.apache.hc.core5.http.HttpEntity + +@JvmSynthetic +internal inline fun json(jsonMapper: JsonMapper, value: T): HttpRequestBody = + object : HttpRequestBody { + private val bytes: ByteArray by lazy { jsonMapper.writeValueAsBytes(value) } + + override fun writeTo(outputStream: OutputStream) = outputStream.write(bytes) + + override fun contentType(): String = "application/json" + + override fun contentLength(): Long = bytes.size.toLong() + + override fun repeatable(): Boolean = true + + override fun close() {} + } + +@JvmSynthetic +internal fun multipartFormData( + jsonMapper: JsonMapper, + fields: Map>, +): HttpRequestBody = + object : HttpRequestBody { + private val entity: HttpEntity by lazy { + MultipartEntityBuilder.create() + .apply { + fields.forEach { (name, field) -> + 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(field.value) + serializePart(name, node) + } + + parts.forEach { (name, bytes) -> + addBinaryBody( + name, + bytes, + ContentType.parseLenient(field.contentType), + field.filename().getOrNull(), + ) + } + } + } + .build() + } + + private fun serializePart( + name: String, + node: JsonNode, + ): Sequence> = + when (node.nodeType) { + JsonNodeType.MISSING, + JsonNodeType.NULL -> emptySequence() + JsonNodeType.BINARY -> sequenceOf(name to node.binaryValue().inputStream()) + JsonNodeType.STRING -> sequenceOf(name to node.textValue().inputStream()) + JsonNodeType.BOOLEAN -> + sequenceOf(name to node.booleanValue().toString().inputStream()) + JsonNodeType.NUMBER -> + sequenceOf(name to node.numberValue().toString().inputStream()) + JsonNodeType.ARRAY -> + sequenceOf( + name to + node + .elements() + .asSequence() + .mapNotNull { element -> + when (element.nodeType) { + JsonNodeType.MISSING, + JsonNodeType.NULL -> null + JsonNodeType.STRING -> node.textValue() + JsonNodeType.BOOLEAN -> node.booleanValue().toString() + JsonNodeType.NUMBER -> node.numberValue().toString() + null, + JsonNodeType.BINARY, + JsonNodeType.ARRAY, + JsonNodeType.OBJECT, + JsonNodeType.POJO -> + throw CasParserInvalidDataException( + "Unexpected JsonNode type in array: ${node.nodeType}" + ) + } + } + .joinToString(",") + .inputStream() + ) + JsonNodeType.OBJECT -> + node.fields().asSequence().flatMap { (key, value) -> + serializePart("$name[$key]", value) + } + JsonNodeType.POJO, + null -> + throw CasParserInvalidDataException( + "Unexpected JsonNode type: ${node.nodeType}" + ) + } + + private fun String.inputStream(): InputStream = toByteArray().inputStream() + + override fun writeTo(outputStream: OutputStream) = entity.writeTo(outputStream) + + override fun contentType(): String = entity.contentType + + override fun contentLength(): Long = entity.contentLength + + override fun repeatable(): Boolean = entity.isRepeatable + + override fun close() = entity.close() + } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/HttpRequestBody.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/HttpRequestBody.kt new file mode 100644 index 0000000..28c90f7 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/HttpRequestBody.kt @@ -0,0 +1,25 @@ +package com.cas_parser.api.core.http + +import java.io.OutputStream +import java.lang.AutoCloseable + +interface HttpRequestBody : AutoCloseable { + + fun writeTo(outputStream: OutputStream) + + fun contentType(): String? + + fun contentLength(): Long + + /** + * Determines if a request can be repeated in a meaningful way, for example before doing a + * retry. + * + * The most typical case when a request can't be retried is if the request body is being + * streamed. In this case the body data isn't available on subsequent attempts. + */ + fun repeatable(): Boolean + + /** Overridden from [AutoCloseable] to not have a checked exception in its signature. */ + override fun close() +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/HttpResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/HttpResponse.kt new file mode 100644 index 0000000..f19a687 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/HttpResponse.kt @@ -0,0 +1,22 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.core.http + +import java.io.InputStream + +interface HttpResponse : AutoCloseable { + + fun statusCode(): Int + + fun headers(): Headers + + fun body(): InputStream + + /** Overridden from [AutoCloseable] to not have a checked exception in its signature. */ + override fun close() + + interface Handler { + + fun handle(response: HttpResponse): T + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/HttpResponseFor.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/HttpResponseFor.kt new file mode 100644 index 0000000..2ad845f --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/HttpResponseFor.kt @@ -0,0 +1,25 @@ +package com.cas_parser.api.core.http + +import java.io.InputStream + +interface HttpResponseFor : HttpResponse { + + fun parse(): T +} + +@JvmSynthetic +internal fun HttpResponse.parseable(parse: () -> T): HttpResponseFor = + object : HttpResponseFor { + + private val parsed: T by lazy { parse() } + + override fun parse(): T = parsed + + override fun statusCode(): Int = this@parseable.statusCode() + + override fun headers(): Headers = this@parseable.headers() + + override fun body(): InputStream = this@parseable.body() + + override fun close() = this@parseable.close() + } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/PhantomReachableClosingAsyncStreamResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/PhantomReachableClosingAsyncStreamResponse.kt new file mode 100644 index 0000000..493c17a --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/PhantomReachableClosingAsyncStreamResponse.kt @@ -0,0 +1,56 @@ +package com.cas_parser.api.core.http + +import com.cas_parser.api.core.closeWhenPhantomReachable +import com.cas_parser.api.core.http.AsyncStreamResponse.Handler +import java.util.Optional +import java.util.concurrent.CompletableFuture +import java.util.concurrent.Executor + +/** + * A delegating wrapper around an `AsyncStreamResponse` that closes it once it's only phantom + * reachable. + * + * This class ensures the `AsyncStreamResponse` is closed even if the user forgets to close it. + */ +internal class PhantomReachableClosingAsyncStreamResponse( + private val asyncStreamResponse: AsyncStreamResponse +) : AsyncStreamResponse { + + /** + * An object used for keeping `asyncStreamResponse` open while the object is still reachable. + */ + private val reachabilityTracker = Object() + + init { + closeWhenPhantomReachable(reachabilityTracker, asyncStreamResponse::close) + } + + override fun subscribe(handler: Handler): AsyncStreamResponse = apply { + asyncStreamResponse.subscribe(TrackedHandler(handler, reachabilityTracker)) + } + + override fun subscribe(handler: Handler, executor: Executor): AsyncStreamResponse = + apply { + asyncStreamResponse.subscribe(TrackedHandler(handler, reachabilityTracker), executor) + } + + override fun onCompleteFuture(): CompletableFuture = + asyncStreamResponse.onCompleteFuture() + + override fun close() = asyncStreamResponse.close() +} + +/** + * A wrapper around a `Handler` that also references a `reachabilityTracker` object. + * + * Referencing the `reachabilityTracker` object prevents it from getting reclaimed while the handler + * is still reachable. + */ +private class TrackedHandler( + private val handler: Handler, + private val reachabilityTracker: Any, +) : Handler { + override fun onNext(value: T) = handler.onNext(value) + + override fun onComplete(error: Optional) = handler.onComplete(error) +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/PhantomReachableClosingHttpClient.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/PhantomReachableClosingHttpClient.kt new file mode 100644 index 0000000..cb87081 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/PhantomReachableClosingHttpClient.kt @@ -0,0 +1,26 @@ +package com.cas_parser.api.core.http + +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.closeWhenPhantomReachable +import java.util.concurrent.CompletableFuture + +/** + * A delegating wrapper around an `HttpClient` that closes it once it's only phantom reachable. + * + * This class ensures the `HttpClient` is closed even if the user forgets to close it. + */ +internal class PhantomReachableClosingHttpClient(private val httpClient: HttpClient) : HttpClient { + init { + closeWhenPhantomReachable(this, httpClient) + } + + override fun execute(request: HttpRequest, requestOptions: RequestOptions): HttpResponse = + httpClient.execute(request, requestOptions) + + override fun executeAsync( + request: HttpRequest, + requestOptions: RequestOptions, + ): CompletableFuture = httpClient.executeAsync(request, requestOptions) + + override fun close() = httpClient.close() +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/PhantomReachableClosingStreamResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/PhantomReachableClosingStreamResponse.kt new file mode 100644 index 0000000..1972f32 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/PhantomReachableClosingStreamResponse.kt @@ -0,0 +1,21 @@ +package com.cas_parser.api.core.http + +import com.cas_parser.api.core.closeWhenPhantomReachable +import java.util.stream.Stream + +/** + * A delegating wrapper around a `StreamResponse` that closes it once it's only phantom reachable. + * + * This class ensures the `StreamResponse` is closed even if the user forgets to close it. + */ +internal class PhantomReachableClosingStreamResponse( + private val streamResponse: StreamResponse +) : StreamResponse { + init { + closeWhenPhantomReachable(this, streamResponse) + } + + override fun stream(): Stream = streamResponse.stream() + + override fun close() = streamResponse.close() +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/QueryParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/QueryParams.kt new file mode 100644 index 0000000..8ae0e4b --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/QueryParams.kt @@ -0,0 +1,129 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.core.http + +import com.cas_parser.api.core.JsonArray +import com.cas_parser.api.core.JsonBoolean +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonNull +import com.cas_parser.api.core.JsonNumber +import com.cas_parser.api.core.JsonObject +import com.cas_parser.api.core.JsonString +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.toImmutable + +class QueryParams +private constructor( + private val map: Map>, + @get:JvmName("size") val size: Int, +) { + + fun isEmpty(): Boolean = map.isEmpty() + + fun keys(): Set = map.keys + + fun values(key: String): List = map[key].orEmpty() + + fun toBuilder(): Builder = Builder().putAll(map) + + companion object { + + @JvmStatic fun builder() = Builder() + } + + class Builder internal constructor() { + + private val map: MutableMap> = mutableMapOf() + private var size: Int = 0 + + fun put(key: String, value: JsonValue): Builder = apply { + when (value) { + is JsonMissing, + is JsonNull -> {} + is JsonBoolean -> put(key, value.value.toString()) + is JsonNumber -> put(key, value.value.toString()) + is JsonString -> put(key, value.value) + is JsonArray -> + put( + key, + value.values + .asSequence() + .mapNotNull { + when (it) { + is JsonMissing, + is JsonNull -> null + is JsonBoolean -> it.value.toString() + is JsonNumber -> it.value.toString() + is JsonString -> it.value + is JsonArray, + is JsonObject -> + throw IllegalArgumentException( + "Cannot comma separate non-primitives in query params" + ) + } + } + .joinToString(","), + ) + is JsonObject -> + value.values.forEach { (nestedKey, value) -> put("$key[$nestedKey]", value) } + } + } + + fun put(key: String, value: String) = apply { + map.getOrPut(key) { mutableListOf() }.add(value) + size++ + } + + fun put(key: String, values: Iterable) = apply { values.forEach { put(key, it) } } + + fun putAll(queryParams: Map>) = apply { + queryParams.forEach(::put) + } + + fun putAll(queryParams: QueryParams) = apply { + queryParams.keys().forEach { put(it, queryParams.values(it)) } + } + + fun replace(key: String, value: String) = apply { + remove(key) + put(key, value) + } + + fun replace(key: String, values: Iterable) = apply { + remove(key) + put(key, values) + } + + fun replaceAll(queryParams: Map>) = apply { + queryParams.forEach(::replace) + } + + fun replaceAll(queryParams: QueryParams) = apply { + queryParams.keys().forEach { replace(it, queryParams.values(it)) } + } + + fun remove(key: String) = apply { size -= map.remove(key).orEmpty().size } + + fun removeAll(keys: Set) = apply { keys.forEach(::remove) } + + fun clear() = apply { + map.clear() + size = 0 + } + + fun build() = + QueryParams(map.mapValues { (_, values) -> values.toImmutable() }.toImmutable(), size) + } + + override fun hashCode(): Int = map.hashCode() + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is QueryParams && map == other.map + } + + override fun toString(): String = "QueryParams{map=$map}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/RetryingHttpClient.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/RetryingHttpClient.kt new file mode 100644 index 0000000..569b1aa --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/RetryingHttpClient.kt @@ -0,0 +1,288 @@ +package com.cas_parser.api.core.http + +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.checkRequired +import com.cas_parser.api.errors.CasParserIoException +import com.cas_parser.api.errors.CasParserRetryableException +import java.io.IOException +import java.time.Clock +import java.time.Duration +import java.time.OffsetDateTime +import java.time.format.DateTimeFormatter +import java.time.format.DateTimeParseException +import java.time.temporal.ChronoUnit +import java.util.Timer +import java.util.TimerTask +import java.util.UUID +import java.util.concurrent.CompletableFuture +import java.util.concurrent.ThreadLocalRandom +import java.util.concurrent.TimeUnit +import java.util.function.Function +import kotlin.math.min +import kotlin.math.pow + +class RetryingHttpClient +private constructor( + private val httpClient: HttpClient, + private val sleeper: Sleeper, + private val clock: Clock, + private val maxRetries: Int, + private val idempotencyHeader: String?, +) : HttpClient { + + override fun execute(request: HttpRequest, requestOptions: RequestOptions): HttpResponse { + if (!isRetryable(request) || maxRetries <= 0) { + return httpClient.execute(request, requestOptions) + } + + var modifiedRequest = maybeAddIdempotencyHeader(request) + + // Don't send the current retry count in the headers if the caller set their own value. + val shouldSendRetryCount = + !modifiedRequest.headers.names().contains("X-Stainless-Retry-Count") + + var retries = 0 + + while (true) { + if (shouldSendRetryCount) { + modifiedRequest = setRetryCountHeader(modifiedRequest, retries) + } + + val response = + try { + val response = httpClient.execute(modifiedRequest, requestOptions) + if (++retries > maxRetries || !shouldRetry(response)) { + return response + } + + response + } catch (throwable: Throwable) { + if (++retries > maxRetries || !shouldRetry(throwable)) { + throw throwable + } + + null + } + + val backoffDuration = getRetryBackoffDuration(retries, response) + // All responses must be closed, so close the failed one before retrying. + response?.close() + sleeper.sleep(backoffDuration) + } + } + + override fun executeAsync( + request: HttpRequest, + requestOptions: RequestOptions, + ): CompletableFuture { + if (!isRetryable(request) || maxRetries <= 0) { + return httpClient.executeAsync(request, requestOptions) + } + + val modifiedRequest = maybeAddIdempotencyHeader(request) + + // Don't send the current retry count in the headers if the caller set their own value. + val shouldSendRetryCount = + !modifiedRequest.headers.names().contains("X-Stainless-Retry-Count") + + var retries = 0 + + fun executeWithRetries( + request: HttpRequest, + requestOptions: RequestOptions, + ): CompletableFuture { + val requestWithRetryCount = + if (shouldSendRetryCount) setRetryCountHeader(request, retries) else request + + return httpClient + .executeAsync(requestWithRetryCount, requestOptions) + .handleAsync( + fun( + response: HttpResponse?, + throwable: Throwable?, + ): CompletableFuture { + if (response != null) { + if (++retries > maxRetries || !shouldRetry(response)) { + return CompletableFuture.completedFuture(response) + } + } else { + if (++retries > maxRetries || !shouldRetry(throwable!!)) { + val failedFuture = CompletableFuture() + failedFuture.completeExceptionally(throwable) + return failedFuture + } + } + + val backoffDuration = getRetryBackoffDuration(retries, response) + // All responses must be closed, so close the failed one before retrying. + response?.close() + return sleeper.sleepAsync(backoffDuration).thenCompose { + executeWithRetries(requestWithRetryCount, requestOptions) + } + } + ) { + // Run in the same thread. + it.run() + } + .thenCompose(Function.identity()) + } + + return executeWithRetries(modifiedRequest, requestOptions) + } + + override fun close() = httpClient.close() + + private fun isRetryable(request: HttpRequest): Boolean = + // Some requests, such as when a request body is being streamed, cannot be retried because + // the body data aren't available on subsequent attempts. + request.body?.repeatable() ?: true + + private fun setRetryCountHeader(request: HttpRequest, retries: Int): HttpRequest = + request.toBuilder().replaceHeaders("X-Stainless-Retry-Count", retries.toString()).build() + + private fun idempotencyKey(): String = "stainless-java-retry-${UUID.randomUUID()}" + + private fun maybeAddIdempotencyHeader(request: HttpRequest): HttpRequest { + if (idempotencyHeader == null || request.headers.names().contains(idempotencyHeader)) { + return request + } + + return request + .toBuilder() + // Set a header to uniquely identify the request when retried. + .putHeader(idempotencyHeader, idempotencyKey()) + .build() + } + + private fun shouldRetry(response: HttpResponse): Boolean { + // Note: this is not a standard header + val shouldRetryHeader = response.headers().values("X-Should-Retry").getOrNull(0) + val statusCode = response.statusCode() + + return when { + // If the server explicitly says whether to retry, obey + shouldRetryHeader == "true" -> true + shouldRetryHeader == "false" -> false + + // Retry on request timeouts + statusCode == 408 -> true + // Retry on lock timeouts + statusCode == 409 -> true + // Retry on rate limits + statusCode == 429 -> true + // Retry internal errors + statusCode >= 500 -> true + else -> false + } + } + + private fun shouldRetry(throwable: Throwable): Boolean = + // Only retry known retryable exceptions, other exceptions are not intended to be retried. + throwable is IOException || + throwable is CasParserIoException || + throwable is CasParserRetryableException + + private fun getRetryBackoffDuration(retries: Int, response: HttpResponse?): Duration { + // About the Retry-After header: + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After + response + ?.headers() + ?.let { headers -> + headers + .values("Retry-After-Ms") + .getOrNull(0) + ?.toFloatOrNull() + ?.times(TimeUnit.MILLISECONDS.toNanos(1)) + ?: headers.values("Retry-After").getOrNull(0)?.let { retryAfter -> + retryAfter.toFloatOrNull()?.times(TimeUnit.SECONDS.toNanos(1)) + ?: try { + ChronoUnit.MILLIS.between( + OffsetDateTime.now(clock), + OffsetDateTime.parse( + retryAfter, + DateTimeFormatter.RFC_1123_DATE_TIME, + ), + ) + } catch (e: DateTimeParseException) { + null + } + } + } + ?.let { retryAfterNanos -> + // If the API asks us to wait a certain amount of time (and it's a reasonable + // amount), just + // do what it says. + val retryAfter = Duration.ofNanos(retryAfterNanos.toLong()) + if (retryAfter in Duration.ofNanos(0)..Duration.ofMinutes(1)) { + return retryAfter + } + } + + // Apply exponential backoff, but not more than the max. + val backoffSeconds = min(0.5 * 2.0.pow(retries - 1), 8.0) + + // Apply some jitter + val jitter = 1.0 - 0.25 * ThreadLocalRandom.current().nextDouble() + + return Duration.ofNanos((TimeUnit.SECONDS.toNanos(1) * backoffSeconds * jitter).toLong()) + } + + companion object { + + @JvmStatic fun builder() = Builder() + } + + class Builder internal constructor() { + + private var httpClient: HttpClient? = null + private var sleeper: Sleeper = + object : Sleeper { + + private val timer = Timer("RetryingHttpClient", true) + + override fun sleep(duration: Duration) = Thread.sleep(duration.toMillis()) + + override fun sleepAsync(duration: Duration): CompletableFuture { + val future = CompletableFuture() + timer.schedule( + object : TimerTask() { + override fun run() { + future.complete(null) + } + }, + duration.toMillis(), + ) + return future + } + } + private var clock: Clock = Clock.systemUTC() + private var maxRetries: Int = 2 + private var idempotencyHeader: String? = null + + fun httpClient(httpClient: HttpClient) = apply { this.httpClient = httpClient } + + @JvmSynthetic internal fun sleeper(sleeper: Sleeper) = apply { this.sleeper = sleeper } + + fun clock(clock: Clock) = apply { this.clock = clock } + + fun maxRetries(maxRetries: Int) = apply { this.maxRetries = maxRetries } + + fun idempotencyHeader(header: String) = apply { this.idempotencyHeader = header } + + fun build(): HttpClient = + RetryingHttpClient( + checkRequired("httpClient", httpClient), + sleeper, + clock, + maxRetries, + idempotencyHeader, + ) + } + + internal interface Sleeper { + + fun sleep(duration: Duration) + + fun sleepAsync(duration: Duration): CompletableFuture + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/StreamResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/StreamResponse.kt new file mode 100644 index 0000000..6e4c1f2 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/StreamResponse.kt @@ -0,0 +1,19 @@ +package com.cas_parser.api.core.http + +import java.util.stream.Stream + +interface StreamResponse : AutoCloseable { + + fun stream(): Stream + + /** Overridden from [AutoCloseable] to not have a checked exception in its signature. */ + override fun close() +} + +@JvmSynthetic +internal fun StreamResponse.map(transform: (T) -> R): StreamResponse = + object : StreamResponse { + override fun stream(): Stream = this@map.stream().map(transform) + + override fun close() = this@map.close() + } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/BadRequestException.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/BadRequestException.kt new file mode 100644 index 0000000..a0737dc --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/BadRequestException.kt @@ -0,0 +1,80 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.errors + +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.checkRequired +import com.cas_parser.api.core.http.Headers +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +class BadRequestException +private constructor(private val headers: Headers, private val body: JsonValue, cause: Throwable?) : + CasParserServiceException("400: $body", cause) { + + override fun statusCode(): Int = 400 + + override fun headers(): Headers = headers + + override fun body(): JsonValue = body + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [BadRequestException]. + * + * The following fields are required: + * ```java + * .headers() + * .body() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [BadRequestException]. */ + class Builder internal constructor() { + + private var headers: Headers? = null + private var body: JsonValue? = null + private var cause: Throwable? = null + + @JvmSynthetic + internal fun from(badRequestException: BadRequestException) = apply { + headers = badRequestException.headers + body = badRequestException.body + cause = badRequestException.cause + } + + fun headers(headers: Headers) = apply { this.headers = headers } + + fun body(body: JsonValue) = apply { this.body = body } + + fun cause(cause: Throwable?) = apply { this.cause = cause } + + /** Alias for calling [Builder.cause] with `cause.orElse(null)`. */ + fun cause(cause: Optional) = cause(cause.getOrNull()) + + /** + * Returns an immutable instance of [BadRequestException]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .headers() + * .body() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): BadRequestException = + BadRequestException( + checkRequired("headers", headers), + checkRequired("body", body), + cause, + ) + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/CasParserException.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/CasParserException.kt new file mode 100644 index 0000000..c1edd1c --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/CasParserException.kt @@ -0,0 +1,5 @@ +package com.cas_parser.api.errors + +open class CasParserException +@JvmOverloads +constructor(message: String? = null, cause: Throwable? = null) : RuntimeException(message, cause) diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/CasParserInvalidDataException.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/CasParserInvalidDataException.kt new file mode 100644 index 0000000..bee598d --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/CasParserInvalidDataException.kt @@ -0,0 +1,5 @@ +package com.cas_parser.api.errors + +class CasParserInvalidDataException +@JvmOverloads +constructor(message: String? = null, cause: Throwable? = null) : CasParserException(message, cause) diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/CasParserIoException.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/CasParserIoException.kt new file mode 100644 index 0000000..1a1b36b --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/CasParserIoException.kt @@ -0,0 +1,5 @@ +package com.cas_parser.api.errors + +class CasParserIoException +@JvmOverloads +constructor(message: String? = null, cause: Throwable? = null) : CasParserException(message, cause) diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/CasParserRetryableException.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/CasParserRetryableException.kt new file mode 100644 index 0000000..dc5ccb2 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/CasParserRetryableException.kt @@ -0,0 +1,14 @@ +package com.cas_parser.api.errors + +/** + * Exception that indicates a transient error that can be retried. + * + * When this exception is thrown during an HTTP request, the SDK will automatically retry the + * request up to the maximum number of retries. + * + * @param message A descriptive error message + * @param cause The underlying cause of this exception, if any + */ +class CasParserRetryableException +@JvmOverloads +constructor(message: String? = null, cause: Throwable? = null) : CasParserException(message, cause) diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/CasParserServiceException.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/CasParserServiceException.kt new file mode 100644 index 0000000..6f5136e --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/CasParserServiceException.kt @@ -0,0 +1,17 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.errors + +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.http.Headers + +abstract class CasParserServiceException +protected constructor(message: String, cause: Throwable? = null) : + CasParserException(message, cause) { + + abstract fun statusCode(): Int + + abstract fun headers(): Headers + + abstract fun body(): JsonValue +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/InternalServerException.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/InternalServerException.kt new file mode 100644 index 0000000..ec2af8e --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/InternalServerException.kt @@ -0,0 +1,91 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.errors + +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.checkRequired +import com.cas_parser.api.core.http.Headers +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +class InternalServerException +private constructor( + private val statusCode: Int, + private val headers: Headers, + private val body: JsonValue, + cause: Throwable?, +) : CasParserServiceException("$statusCode: $body", cause) { + + override fun statusCode(): Int = statusCode + + override fun headers(): Headers = headers + + override fun body(): JsonValue = body + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [InternalServerException]. + * + * The following fields are required: + * ```java + * .statusCode() + * .headers() + * .body() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [InternalServerException]. */ + class Builder internal constructor() { + + private var statusCode: Int? = null + private var headers: Headers? = null + private var body: JsonValue? = null + private var cause: Throwable? = null + + @JvmSynthetic + internal fun from(internalServerException: InternalServerException) = apply { + statusCode = internalServerException.statusCode + headers = internalServerException.headers + body = internalServerException.body + cause = internalServerException.cause + } + + fun statusCode(statusCode: Int) = apply { this.statusCode = statusCode } + + fun headers(headers: Headers) = apply { this.headers = headers } + + fun body(body: JsonValue) = apply { this.body = body } + + fun cause(cause: Throwable?) = apply { this.cause = cause } + + /** Alias for calling [Builder.cause] with `cause.orElse(null)`. */ + fun cause(cause: Optional) = cause(cause.getOrNull()) + + /** + * Returns an immutable instance of [InternalServerException]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .statusCode() + * .headers() + * .body() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): InternalServerException = + InternalServerException( + checkRequired("statusCode", statusCode), + checkRequired("headers", headers), + checkRequired("body", body), + cause, + ) + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/NotFoundException.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/NotFoundException.kt new file mode 100644 index 0000000..c01b9dd --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/NotFoundException.kt @@ -0,0 +1,76 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.errors + +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.checkRequired +import com.cas_parser.api.core.http.Headers +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +class NotFoundException +private constructor(private val headers: Headers, private val body: JsonValue, cause: Throwable?) : + CasParserServiceException("404: $body", cause) { + + override fun statusCode(): Int = 404 + + override fun headers(): Headers = headers + + override fun body(): JsonValue = body + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [NotFoundException]. + * + * The following fields are required: + * ```java + * .headers() + * .body() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [NotFoundException]. */ + class Builder internal constructor() { + + private var headers: Headers? = null + private var body: JsonValue? = null + private var cause: Throwable? = null + + @JvmSynthetic + internal fun from(notFoundException: NotFoundException) = apply { + headers = notFoundException.headers + body = notFoundException.body + cause = notFoundException.cause + } + + fun headers(headers: Headers) = apply { this.headers = headers } + + fun body(body: JsonValue) = apply { this.body = body } + + fun cause(cause: Throwable?) = apply { this.cause = cause } + + /** Alias for calling [Builder.cause] with `cause.orElse(null)`. */ + fun cause(cause: Optional) = cause(cause.getOrNull()) + + /** + * Returns an immutable instance of [NotFoundException]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .headers() + * .body() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): NotFoundException = + NotFoundException(checkRequired("headers", headers), checkRequired("body", body), cause) + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/PermissionDeniedException.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/PermissionDeniedException.kt new file mode 100644 index 0000000..520a46f --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/PermissionDeniedException.kt @@ -0,0 +1,80 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.errors + +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.checkRequired +import com.cas_parser.api.core.http.Headers +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +class PermissionDeniedException +private constructor(private val headers: Headers, private val body: JsonValue, cause: Throwable?) : + CasParserServiceException("403: $body", cause) { + + override fun statusCode(): Int = 403 + + override fun headers(): Headers = headers + + override fun body(): JsonValue = body + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [PermissionDeniedException]. + * + * The following fields are required: + * ```java + * .headers() + * .body() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [PermissionDeniedException]. */ + class Builder internal constructor() { + + private var headers: Headers? = null + private var body: JsonValue? = null + private var cause: Throwable? = null + + @JvmSynthetic + internal fun from(permissionDeniedException: PermissionDeniedException) = apply { + headers = permissionDeniedException.headers + body = permissionDeniedException.body + cause = permissionDeniedException.cause + } + + fun headers(headers: Headers) = apply { this.headers = headers } + + fun body(body: JsonValue) = apply { this.body = body } + + fun cause(cause: Throwable?) = apply { this.cause = cause } + + /** Alias for calling [Builder.cause] with `cause.orElse(null)`. */ + fun cause(cause: Optional) = cause(cause.getOrNull()) + + /** + * Returns an immutable instance of [PermissionDeniedException]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .headers() + * .body() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): PermissionDeniedException = + PermissionDeniedException( + checkRequired("headers", headers), + checkRequired("body", body), + cause, + ) + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/RateLimitException.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/RateLimitException.kt new file mode 100644 index 0000000..10c79f3 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/RateLimitException.kt @@ -0,0 +1,80 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.errors + +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.checkRequired +import com.cas_parser.api.core.http.Headers +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +class RateLimitException +private constructor(private val headers: Headers, private val body: JsonValue, cause: Throwable?) : + CasParserServiceException("429: $body", cause) { + + override fun statusCode(): Int = 429 + + override fun headers(): Headers = headers + + override fun body(): JsonValue = body + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [RateLimitException]. + * + * The following fields are required: + * ```java + * .headers() + * .body() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [RateLimitException]. */ + class Builder internal constructor() { + + private var headers: Headers? = null + private var body: JsonValue? = null + private var cause: Throwable? = null + + @JvmSynthetic + internal fun from(rateLimitException: RateLimitException) = apply { + headers = rateLimitException.headers + body = rateLimitException.body + cause = rateLimitException.cause + } + + fun headers(headers: Headers) = apply { this.headers = headers } + + fun body(body: JsonValue) = apply { this.body = body } + + fun cause(cause: Throwable?) = apply { this.cause = cause } + + /** Alias for calling [Builder.cause] with `cause.orElse(null)`. */ + fun cause(cause: Optional) = cause(cause.getOrNull()) + + /** + * Returns an immutable instance of [RateLimitException]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .headers() + * .body() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): RateLimitException = + RateLimitException( + checkRequired("headers", headers), + checkRequired("body", body), + cause, + ) + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/UnauthorizedException.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/UnauthorizedException.kt new file mode 100644 index 0000000..290a3e7 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/UnauthorizedException.kt @@ -0,0 +1,80 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.errors + +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.checkRequired +import com.cas_parser.api.core.http.Headers +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +class UnauthorizedException +private constructor(private val headers: Headers, private val body: JsonValue, cause: Throwable?) : + CasParserServiceException("401: $body", cause) { + + override fun statusCode(): Int = 401 + + override fun headers(): Headers = headers + + override fun body(): JsonValue = body + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [UnauthorizedException]. + * + * The following fields are required: + * ```java + * .headers() + * .body() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [UnauthorizedException]. */ + class Builder internal constructor() { + + private var headers: Headers? = null + private var body: JsonValue? = null + private var cause: Throwable? = null + + @JvmSynthetic + internal fun from(unauthorizedException: UnauthorizedException) = apply { + headers = unauthorizedException.headers + body = unauthorizedException.body + cause = unauthorizedException.cause + } + + fun headers(headers: Headers) = apply { this.headers = headers } + + fun body(body: JsonValue) = apply { this.body = body } + + fun cause(cause: Throwable?) = apply { this.cause = cause } + + /** Alias for calling [Builder.cause] with `cause.orElse(null)`. */ + fun cause(cause: Optional) = cause(cause.getOrNull()) + + /** + * Returns an immutable instance of [UnauthorizedException]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .headers() + * .body() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): UnauthorizedException = + UnauthorizedException( + checkRequired("headers", headers), + checkRequired("body", body), + cause, + ) + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/UnexpectedStatusCodeException.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/UnexpectedStatusCodeException.kt new file mode 100644 index 0000000..55a37fe --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/UnexpectedStatusCodeException.kt @@ -0,0 +1,92 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.errors + +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.checkRequired +import com.cas_parser.api.core.http.Headers +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +class UnexpectedStatusCodeException +private constructor( + private val statusCode: Int, + private val headers: Headers, + private val body: JsonValue, + cause: Throwable?, +) : CasParserServiceException("$statusCode: $body", cause) { + + override fun statusCode(): Int = statusCode + + override fun headers(): Headers = headers + + override fun body(): JsonValue = body + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of + * [UnexpectedStatusCodeException]. + * + * The following fields are required: + * ```java + * .statusCode() + * .headers() + * .body() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [UnexpectedStatusCodeException]. */ + class Builder internal constructor() { + + private var statusCode: Int? = null + private var headers: Headers? = null + private var body: JsonValue? = null + private var cause: Throwable? = null + + @JvmSynthetic + internal fun from(unexpectedStatusCodeException: UnexpectedStatusCodeException) = apply { + statusCode = unexpectedStatusCodeException.statusCode + headers = unexpectedStatusCodeException.headers + body = unexpectedStatusCodeException.body + cause = unexpectedStatusCodeException.cause + } + + fun statusCode(statusCode: Int) = apply { this.statusCode = statusCode } + + fun headers(headers: Headers) = apply { this.headers = headers } + + fun body(body: JsonValue) = apply { this.body = body } + + fun cause(cause: Throwable?) = apply { this.cause = cause } + + /** Alias for calling [Builder.cause] with `cause.orElse(null)`. */ + fun cause(cause: Optional) = cause(cause.getOrNull()) + + /** + * Returns an immutable instance of [UnexpectedStatusCodeException]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .statusCode() + * .headers() + * .body() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): UnexpectedStatusCodeException = + UnexpectedStatusCodeException( + checkRequired("statusCode", statusCode), + checkRequired("headers", headers), + checkRequired("body", body), + cause, + ) + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/UnprocessableEntityException.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/UnprocessableEntityException.kt new file mode 100644 index 0000000..678980c --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/UnprocessableEntityException.kt @@ -0,0 +1,80 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.errors + +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.checkRequired +import com.cas_parser.api.core.http.Headers +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +class UnprocessableEntityException +private constructor(private val headers: Headers, private val body: JsonValue, cause: Throwable?) : + CasParserServiceException("422: $body", cause) { + + override fun statusCode(): Int = 422 + + override fun headers(): Headers = headers + + override fun body(): JsonValue = body + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [UnprocessableEntityException]. + * + * The following fields are required: + * ```java + * .headers() + * .body() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [UnprocessableEntityException]. */ + class Builder internal constructor() { + + private var headers: Headers? = null + private var body: JsonValue? = null + private var cause: Throwable? = null + + @JvmSynthetic + internal fun from(unprocessableEntityException: UnprocessableEntityException) = apply { + headers = unprocessableEntityException.headers + body = unprocessableEntityException.body + cause = unprocessableEntityException.cause + } + + fun headers(headers: Headers) = apply { this.headers = headers } + + fun body(body: JsonValue) = apply { this.body = body } + + fun cause(cause: Throwable?) = apply { this.cause = cause } + + /** Alias for calling [Builder.cause] with `cause.orElse(null)`. */ + fun cause(cause: Optional) = cause(cause.getOrNull()) + + /** + * Returns an immutable instance of [UnprocessableEntityException]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .headers() + * .body() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): UnprocessableEntityException = + UnprocessableEntityException( + checkRequired("headers", headers), + checkRequired("body", body), + cause, + ) + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casgenerator/CasGeneratorGenerateCasParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casgenerator/CasGeneratorGenerateCasParams.kt new file mode 100644 index 0000000..eb7213c --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casgenerator/CasGeneratorGenerateCasParams.kt @@ -0,0 +1,918 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.casgenerator + +import com.cas_parser.api.core.Enum +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonField +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.Params +import com.cas_parser.api.core.checkRequired +import com.cas_parser.api.core.http.Headers +import com.cas_parser.api.core.http.QueryParams +import com.cas_parser.api.errors.CasParserInvalidDataException +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 + +/** + * This endpoint generates CAS (Consolidated Account Statement) documents by submitting a mailback + * request to the specified CAS authority. Currently only supports KFintech, with plans to support + * CAMS, CDSL, and NSDL in the future. + */ +class CasGeneratorGenerateCasParams +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Email address to receive the CAS document + * + * @throws CasParserInvalidDataException 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 email(): String = body.email() + + /** + * Start date for the CAS period (format YYYY-MM-DD) + * + * @throws CasParserInvalidDataException 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 fromDate(): String = body.fromDate() + + /** + * Password to protect the generated CAS PDF + * + * @throws CasParserInvalidDataException 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 password(): String = body.password() + + /** + * End date for the CAS period (format YYYY-MM-DD) + * + * @throws CasParserInvalidDataException 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 toDate(): String = body.toDate() + + /** + * CAS authority to generate the document from (currently only kfintech is supported) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun casAuthority(): Optional = body.casAuthority() + + /** + * PAN number (optional for some CAS authorities) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun panNo(): Optional = body.panNo() + + /** + * Returns the raw JSON value of [email]. + * + * Unlike [email], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _email(): JsonField = body._email() + + /** + * Returns the raw JSON value of [fromDate]. + * + * Unlike [fromDate], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _fromDate(): JsonField = body._fromDate() + + /** + * Returns the raw JSON value of [password]. + * + * Unlike [password], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _password(): JsonField = body._password() + + /** + * Returns the raw JSON value of [toDate]. + * + * Unlike [toDate], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _toDate(): JsonField = body._toDate() + + /** + * Returns the raw JSON value of [casAuthority]. + * + * Unlike [casAuthority], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _casAuthority(): JsonField = body._casAuthority() + + /** + * Returns the raw JSON value of [panNo]. + * + * Unlike [panNo], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _panNo(): JsonField = body._panNo() + + fun _additionalBodyProperties(): Map = body._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 + * [CasGeneratorGenerateCasParams]. + * + * The following fields are required: + * ```java + * .email() + * .fromDate() + * .password() + * .toDate() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [CasGeneratorGenerateCasParams]. */ + class Builder internal constructor() { + + private var body: Body.Builder = Body.builder() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(casGeneratorGenerateCasParams: CasGeneratorGenerateCasParams) = apply { + body = casGeneratorGenerateCasParams.body.toBuilder() + additionalHeaders = casGeneratorGenerateCasParams.additionalHeaders.toBuilder() + additionalQueryParams = casGeneratorGenerateCasParams.additionalQueryParams.toBuilder() + } + + /** + * Sets the entire request body. + * + * This is generally only useful if you are already constructing the body separately. + * Otherwise, it's more convenient to use the top-level setters instead: + * - [email] + * - [fromDate] + * - [password] + * - [toDate] + * - [casAuthority] + * - etc. + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + /** Email address to receive the CAS document */ + fun email(email: String) = apply { body.email(email) } + + /** + * Sets [Builder.email] to an arbitrary JSON value. + * + * You should usually call [Builder.email] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun email(email: JsonField) = apply { body.email(email) } + + /** Start date for the CAS period (format YYYY-MM-DD) */ + fun fromDate(fromDate: String) = apply { body.fromDate(fromDate) } + + /** + * Sets [Builder.fromDate] to an arbitrary JSON value. + * + * You should usually call [Builder.fromDate] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun fromDate(fromDate: JsonField) = apply { body.fromDate(fromDate) } + + /** Password to protect the generated CAS PDF */ + fun password(password: String) = apply { body.password(password) } + + /** + * Sets [Builder.password] to an arbitrary JSON value. + * + * You should usually call [Builder.password] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun password(password: JsonField) = apply { body.password(password) } + + /** End date for the CAS period (format YYYY-MM-DD) */ + fun toDate(toDate: String) = apply { body.toDate(toDate) } + + /** + * Sets [Builder.toDate] to an arbitrary JSON value. + * + * You should usually call [Builder.toDate] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun toDate(toDate: JsonField) = apply { body.toDate(toDate) } + + /** CAS authority to generate the document from (currently only kfintech is supported) */ + fun casAuthority(casAuthority: CasAuthority) = apply { body.casAuthority(casAuthority) } + + /** + * Sets [Builder.casAuthority] to an arbitrary JSON value. + * + * You should usually call [Builder.casAuthority] with a well-typed [CasAuthority] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun casAuthority(casAuthority: JsonField) = apply { + body.casAuthority(casAuthority) + } + + /** PAN number (optional for some CAS authorities) */ + fun panNo(panNo: String) = apply { body.panNo(panNo) } + + /** + * Sets [Builder.panNo] to an arbitrary JSON value. + * + * You should usually call [Builder.panNo] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun panNo(panNo: JsonField) = apply { body.panNo(panNo) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) + } + + 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 [CasGeneratorGenerateCasParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .email() + * .fromDate() + * .password() + * .toDate() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): CasGeneratorGenerateCasParams = + CasGeneratorGenerateCasParams( + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + class Body + private constructor( + private val email: JsonField, + private val fromDate: JsonField, + private val password: JsonField, + private val toDate: JsonField, + private val casAuthority: JsonField, + private val panNo: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("email") @ExcludeMissing email: JsonField = JsonMissing.of(), + @JsonProperty("from_date") + @ExcludeMissing + fromDate: JsonField = JsonMissing.of(), + @JsonProperty("password") + @ExcludeMissing + password: JsonField = JsonMissing.of(), + @JsonProperty("to_date") @ExcludeMissing toDate: JsonField = JsonMissing.of(), + @JsonProperty("cas_authority") + @ExcludeMissing + casAuthority: JsonField = JsonMissing.of(), + @JsonProperty("pan_no") @ExcludeMissing panNo: JsonField = JsonMissing.of(), + ) : this(email, fromDate, password, toDate, casAuthority, panNo, mutableMapOf()) + + /** + * Email address to receive the CAS document + * + * @throws CasParserInvalidDataException 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 email(): String = email.getRequired("email") + + /** + * Start date for the CAS period (format YYYY-MM-DD) + * + * @throws CasParserInvalidDataException 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 fromDate(): String = fromDate.getRequired("from_date") + + /** + * Password to protect the generated CAS PDF + * + * @throws CasParserInvalidDataException 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 password(): String = password.getRequired("password") + + /** + * End date for the CAS period (format YYYY-MM-DD) + * + * @throws CasParserInvalidDataException 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 toDate(): String = toDate.getRequired("to_date") + + /** + * CAS authority to generate the document from (currently only kfintech is supported) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun casAuthority(): Optional = casAuthority.getOptional("cas_authority") + + /** + * PAN number (optional for some CAS authorities) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun panNo(): Optional = panNo.getOptional("pan_no") + + /** + * Returns the raw JSON value of [email]. + * + * Unlike [email], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("email") @ExcludeMissing fun _email(): JsonField = email + + /** + * Returns the raw JSON value of [fromDate]. + * + * Unlike [fromDate], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("from_date") @ExcludeMissing fun _fromDate(): JsonField = fromDate + + /** + * Returns the raw JSON value of [password]. + * + * Unlike [password], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("password") @ExcludeMissing fun _password(): JsonField = password + + /** + * Returns the raw JSON value of [toDate]. + * + * Unlike [toDate], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("to_date") @ExcludeMissing fun _toDate(): JsonField = toDate + + /** + * Returns the raw JSON value of [casAuthority]. + * + * Unlike [casAuthority], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("cas_authority") + @ExcludeMissing + fun _casAuthority(): JsonField = casAuthority + + /** + * Returns the raw JSON value of [panNo]. + * + * Unlike [panNo], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("pan_no") @ExcludeMissing fun _panNo(): JsonField = panNo + + @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 [Body]. + * + * The following fields are required: + * ```java + * .email() + * .fromDate() + * .password() + * .toDate() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var email: JsonField? = null + private var fromDate: JsonField? = null + private var password: JsonField? = null + private var toDate: JsonField? = null + private var casAuthority: JsonField = JsonMissing.of() + private var panNo: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + email = body.email + fromDate = body.fromDate + password = body.password + toDate = body.toDate + casAuthority = body.casAuthority + panNo = body.panNo + additionalProperties = body.additionalProperties.toMutableMap() + } + + /** Email address to receive the CAS document */ + fun email(email: String) = email(JsonField.of(email)) + + /** + * Sets [Builder.email] to an arbitrary JSON value. + * + * You should usually call [Builder.email] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun email(email: JsonField) = apply { this.email = email } + + /** Start date for the CAS period (format YYYY-MM-DD) */ + fun fromDate(fromDate: String) = fromDate(JsonField.of(fromDate)) + + /** + * Sets [Builder.fromDate] to an arbitrary JSON value. + * + * You should usually call [Builder.fromDate] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun fromDate(fromDate: JsonField) = apply { this.fromDate = fromDate } + + /** Password to protect the generated CAS PDF */ + fun password(password: String) = password(JsonField.of(password)) + + /** + * Sets [Builder.password] to an arbitrary JSON value. + * + * You should usually call [Builder.password] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun password(password: JsonField) = apply { this.password = password } + + /** End date for the CAS period (format YYYY-MM-DD) */ + fun toDate(toDate: String) = toDate(JsonField.of(toDate)) + + /** + * Sets [Builder.toDate] to an arbitrary JSON value. + * + * You should usually call [Builder.toDate] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun toDate(toDate: JsonField) = apply { this.toDate = toDate } + + /** + * CAS authority to generate the document from (currently only kfintech is supported) + */ + fun casAuthority(casAuthority: CasAuthority) = casAuthority(JsonField.of(casAuthority)) + + /** + * Sets [Builder.casAuthority] to an arbitrary JSON value. + * + * You should usually call [Builder.casAuthority] with a well-typed [CasAuthority] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun casAuthority(casAuthority: JsonField) = apply { + this.casAuthority = casAuthority + } + + /** PAN number (optional for some CAS authorities) */ + fun panNo(panNo: String) = panNo(JsonField.of(panNo)) + + /** + * Sets [Builder.panNo] to an arbitrary JSON value. + * + * You should usually call [Builder.panNo] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun panNo(panNo: JsonField) = apply { this.panNo = panNo } + + 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 [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .email() + * .fromDate() + * .password() + * .toDate() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("email", email), + checkRequired("fromDate", fromDate), + checkRequired("password", password), + checkRequired("toDate", toDate), + casAuthority, + panNo, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + email() + fromDate() + password() + toDate() + casAuthority().ifPresent { it.validate() } + panNo() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (email.asKnown().isPresent) 1 else 0) + + (if (fromDate.asKnown().isPresent) 1 else 0) + + (if (password.asKnown().isPresent) 1 else 0) + + (if (toDate.asKnown().isPresent) 1 else 0) + + (casAuthority.asKnown().getOrNull()?.validity() ?: 0) + + (if (panNo.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + email == other.email && + fromDate == other.fromDate && + password == other.password && + toDate == other.toDate && + casAuthority == other.casAuthority && + panNo == other.panNo && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + email, + fromDate, + password, + toDate, + casAuthority, + panNo, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{email=$email, fromDate=$fromDate, password=$password, toDate=$toDate, casAuthority=$casAuthority, panNo=$panNo, additionalProperties=$additionalProperties}" + } + + /** CAS authority to generate the document from (currently only kfintech is supported) */ + class CasAuthority @JsonCreator private constructor(private val value: JsonField) : + Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val KFINTECH = of("kfintech") + + @JvmField val CAMS = of("cams") + + @JvmField val CDSL = of("cdsl") + + @JvmField val NSDL = of("nsdl") + + @JvmStatic fun of(value: String) = CasAuthority(JsonField.of(value)) + } + + /** An enum containing [CasAuthority]'s known values. */ + enum class Known { + KFINTECH, + CAMS, + CDSL, + NSDL, + } + + /** + * An enum containing [CasAuthority]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [CasAuthority] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + KFINTECH, + CAMS, + CDSL, + NSDL, + /** + * An enum member indicating that [CasAuthority] was instantiated with an unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + KFINTECH -> Value.KFINTECH + CAMS -> Value.CAMS + CDSL -> Value.CDSL + NSDL -> Value.NSDL + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws CasParserInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + KFINTECH -> Known.KFINTECH + CAMS -> Known.CAMS + CDSL -> Known.CDSL + NSDL -> Known.NSDL + else -> throw CasParserInvalidDataException("Unknown CasAuthority: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws CasParserInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CasParserInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): CasAuthority = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is CasAuthority && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is CasGeneratorGenerateCasParams && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = Objects.hash(body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "CasGeneratorGenerateCasParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casgenerator/CasGeneratorGenerateCasResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casgenerator/CasGeneratorGenerateCasResponse.kt new file mode 100644 index 0000000..09df4cd --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casgenerator/CasGeneratorGenerateCasResponse.kt @@ -0,0 +1,188 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.casgenerator + +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonField +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.errors.CasParserInvalidDataException +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 + +class CasGeneratorGenerateCasResponse +private constructor( + private val msg: JsonField, + private val status: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("msg") @ExcludeMissing msg: JsonField = JsonMissing.of(), + @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(), + ) : this(msg, status, mutableMapOf()) + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun msg(): Optional = msg.getOptional("msg") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun status(): Optional = status.getOptional("status") + + /** + * Returns the raw JSON value of [msg]. + * + * Unlike [msg], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("msg") @ExcludeMissing fun _msg(): JsonField = msg + + /** + * Returns the raw JSON value of [status]. + * + * Unlike [status], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("status") @ExcludeMissing fun _status(): JsonField = status + + @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 + * [CasGeneratorGenerateCasResponse]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [CasGeneratorGenerateCasResponse]. */ + class Builder internal constructor() { + + private var msg: JsonField = JsonMissing.of() + private var status: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(casGeneratorGenerateCasResponse: CasGeneratorGenerateCasResponse) = + apply { + msg = casGeneratorGenerateCasResponse.msg + status = casGeneratorGenerateCasResponse.status + additionalProperties = + casGeneratorGenerateCasResponse.additionalProperties.toMutableMap() + } + + fun msg(msg: String) = msg(JsonField.of(msg)) + + /** + * Sets [Builder.msg] to an arbitrary JSON value. + * + * You should usually call [Builder.msg] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun msg(msg: JsonField) = apply { this.msg = msg } + + fun status(status: String) = status(JsonField.of(status)) + + /** + * Sets [Builder.status] to an arbitrary JSON value. + * + * You should usually call [Builder.status] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun status(status: JsonField) = apply { this.status = status } + + 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 [CasGeneratorGenerateCasResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): CasGeneratorGenerateCasResponse = + CasGeneratorGenerateCasResponse(msg, status, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): CasGeneratorGenerateCasResponse = apply { + if (validated) { + return@apply + } + + msg() + status() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (msg.asKnown().isPresent) 1 else 0) + (if (status.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is CasGeneratorGenerateCasResponse && + msg == other.msg && + status == other.status && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(msg, status, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "CasGeneratorGenerateCasResponse{msg=$msg, status=$status, additionalProperties=$additionalProperties}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserCamsKfintechParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserCamsKfintechParams.kt new file mode 100644 index 0000000..6c18be5 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserCamsKfintechParams.kt @@ -0,0 +1,504 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.casparser + +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.MultipartField +import com.cas_parser.api.core.Params +import com.cas_parser.api.core.http.Headers +import com.cas_parser.api.core.http.QueryParams +import com.cas_parser.api.core.toImmutable +import com.cas_parser.api.errors.CasParserInvalidDataException +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonProperty +import java.util.Collections +import java.util.Objects +import java.util.Optional + +/** + * This endpoint specifically parses CAMS/KFintech CAS (Consolidated Account Statement) PDF files + * and returns data in a unified format. Use this endpoint when you know the PDF is from CAMS or + * KFintech. + */ +class CasParserCamsKfintechParams +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Password for the PDF file (if required) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun password(): Optional = body.password() + + /** + * Base64 encoded CAS PDF file + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun pdfFile(): Optional = body.pdfFile() + + /** + * URL to the CAS PDF file + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun pdfUrl(): Optional = body.pdfUrl() + + /** + * Returns the raw multipart value of [password]. + * + * Unlike [password], this method doesn't throw if the multipart field has an unexpected type. + */ + fun _password(): MultipartField = body._password() + + /** + * Returns the raw multipart value of [pdfFile]. + * + * Unlike [pdfFile], this method doesn't throw if the multipart field has an unexpected type. + */ + fun _pdfFile(): MultipartField = body._pdfFile() + + /** + * Returns the raw multipart value of [pdfUrl]. + * + * Unlike [pdfUrl], this method doesn't throw if the multipart field has an unexpected type. + */ + fun _pdfUrl(): MultipartField = body._pdfUrl() + + fun _additionalBodyProperties(): Map = body._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 { + + @JvmStatic fun none(): CasParserCamsKfintechParams = builder().build() + + /** + * Returns a mutable builder for constructing an instance of [CasParserCamsKfintechParams]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [CasParserCamsKfintechParams]. */ + class Builder internal constructor() { + + private var body: Body.Builder = Body.builder() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(casParserCamsKfintechParams: CasParserCamsKfintechParams) = apply { + body = casParserCamsKfintechParams.body.toBuilder() + additionalHeaders = casParserCamsKfintechParams.additionalHeaders.toBuilder() + additionalQueryParams = casParserCamsKfintechParams.additionalQueryParams.toBuilder() + } + + /** + * Sets the entire request body. + * + * This is generally only useful if you are already constructing the body separately. + * Otherwise, it's more convenient to use the top-level setters instead: + * - [password] + * - [pdfFile] + * - [pdfUrl] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + /** Password for the PDF file (if required) */ + fun password(password: String) = apply { body.password(password) } + + /** + * Sets [Builder.password] to an arbitrary multipart value. + * + * You should usually call [Builder.password] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun password(password: MultipartField) = apply { body.password(password) } + + /** Base64 encoded CAS PDF file */ + fun pdfFile(pdfFile: String) = apply { body.pdfFile(pdfFile) } + + /** + * Sets [Builder.pdfFile] to an arbitrary multipart value. + * + * You should usually call [Builder.pdfFile] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun pdfFile(pdfFile: MultipartField) = apply { body.pdfFile(pdfFile) } + + /** URL to the CAS PDF file */ + fun pdfUrl(pdfUrl: String) = apply { body.pdfUrl(pdfUrl) } + + /** + * Sets [Builder.pdfUrl] to an arbitrary multipart value. + * + * You should usually call [Builder.pdfUrl] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun pdfUrl(pdfUrl: MultipartField) = apply { body.pdfUrl(pdfUrl) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) + } + + 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 [CasParserCamsKfintechParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): CasParserCamsKfintechParams = + CasParserCamsKfintechParams( + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): Map> = + (mapOf("password" to _password(), "pdf_file" to _pdfFile(), "pdf_url" to _pdfUrl()) + + _additionalBodyProperties().mapValues { (_, value) -> MultipartField.of(value) }) + .toImmutable() + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + class Body + private constructor( + private val password: MultipartField, + private val pdfFile: MultipartField, + private val pdfUrl: MultipartField, + private val additionalProperties: MutableMap, + ) { + + /** + * Password for the PDF file (if required) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun password(): Optional = password.value.getOptional("password") + + /** + * Base64 encoded CAS PDF file + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun pdfFile(): Optional = pdfFile.value.getOptional("pdf_file") + + /** + * URL to the CAS PDF file + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun pdfUrl(): Optional = pdfUrl.value.getOptional("pdf_url") + + /** + * Returns the raw multipart value of [password]. + * + * Unlike [password], this method doesn't throw if the multipart field has an unexpected + * type. + */ + @JsonProperty("password") @ExcludeMissing fun _password(): MultipartField = password + + /** + * Returns the raw multipart value of [pdfFile]. + * + * Unlike [pdfFile], this method doesn't throw if the multipart field has an unexpected + * type. + */ + @JsonProperty("pdf_file") @ExcludeMissing fun _pdfFile(): MultipartField = pdfFile + + /** + * Returns the raw multipart value of [pdfUrl]. + * + * Unlike [pdfUrl], this method doesn't throw if the multipart field has an unexpected type. + */ + @JsonProperty("pdf_url") @ExcludeMissing fun _pdfUrl(): MultipartField = pdfUrl + + @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 [Body]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var password: MultipartField = MultipartField.of(null) + private var pdfFile: MultipartField = MultipartField.of(null) + private var pdfUrl: MultipartField = MultipartField.of(null) + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + password = body.password + pdfFile = body.pdfFile + pdfUrl = body.pdfUrl + additionalProperties = body.additionalProperties.toMutableMap() + } + + /** Password for the PDF file (if required) */ + fun password(password: String) = password(MultipartField.of(password)) + + /** + * Sets [Builder.password] to an arbitrary multipart value. + * + * You should usually call [Builder.password] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun password(password: MultipartField) = apply { this.password = password } + + /** Base64 encoded CAS PDF file */ + fun pdfFile(pdfFile: String) = pdfFile(MultipartField.of(pdfFile)) + + /** + * Sets [Builder.pdfFile] to an arbitrary multipart value. + * + * You should usually call [Builder.pdfFile] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun pdfFile(pdfFile: MultipartField) = apply { this.pdfFile = pdfFile } + + /** URL to the CAS PDF file */ + fun pdfUrl(pdfUrl: String) = pdfUrl(MultipartField.of(pdfUrl)) + + /** + * Sets [Builder.pdfUrl] to an arbitrary multipart value. + * + * You should usually call [Builder.pdfUrl] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun pdfUrl(pdfUrl: MultipartField) = apply { this.pdfUrl = pdfUrl } + + 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 [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Body = Body(password, pdfFile, pdfUrl, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + password() + pdfFile() + pdfUrl() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + false + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + password == other.password && + pdfFile == other.pdfFile && + pdfUrl == other.pdfUrl && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(password, pdfFile, pdfUrl, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{password=$password, pdfFile=$pdfFile, pdfUrl=$pdfUrl, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is CasParserCamsKfintechParams && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = Objects.hash(body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "CasParserCamsKfintechParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserCdslParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserCdslParams.kt new file mode 100644 index 0000000..dac6268 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserCdslParams.kt @@ -0,0 +1,501 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.casparser + +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.MultipartField +import com.cas_parser.api.core.Params +import com.cas_parser.api.core.http.Headers +import com.cas_parser.api.core.http.QueryParams +import com.cas_parser.api.core.toImmutable +import com.cas_parser.api.errors.CasParserInvalidDataException +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonProperty +import java.util.Collections +import java.util.Objects +import java.util.Optional + +/** + * This endpoint specifically parses CDSL CAS (Consolidated Account Statement) PDF files and returns + * data in a unified format. Use this endpoint when you know the PDF is from CDSL. + */ +class CasParserCdslParams +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Password for the PDF file (if required) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun password(): Optional = body.password() + + /** + * Base64 encoded CAS PDF file + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun pdfFile(): Optional = body.pdfFile() + + /** + * URL to the CAS PDF file + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun pdfUrl(): Optional = body.pdfUrl() + + /** + * Returns the raw multipart value of [password]. + * + * Unlike [password], this method doesn't throw if the multipart field has an unexpected type. + */ + fun _password(): MultipartField = body._password() + + /** + * Returns the raw multipart value of [pdfFile]. + * + * Unlike [pdfFile], this method doesn't throw if the multipart field has an unexpected type. + */ + fun _pdfFile(): MultipartField = body._pdfFile() + + /** + * Returns the raw multipart value of [pdfUrl]. + * + * Unlike [pdfUrl], this method doesn't throw if the multipart field has an unexpected type. + */ + fun _pdfUrl(): MultipartField = body._pdfUrl() + + fun _additionalBodyProperties(): Map = body._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 { + + @JvmStatic fun none(): CasParserCdslParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [CasParserCdslParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [CasParserCdslParams]. */ + class Builder internal constructor() { + + private var body: Body.Builder = Body.builder() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(casParserCdslParams: CasParserCdslParams) = apply { + body = casParserCdslParams.body.toBuilder() + additionalHeaders = casParserCdslParams.additionalHeaders.toBuilder() + additionalQueryParams = casParserCdslParams.additionalQueryParams.toBuilder() + } + + /** + * Sets the entire request body. + * + * This is generally only useful if you are already constructing the body separately. + * Otherwise, it's more convenient to use the top-level setters instead: + * - [password] + * - [pdfFile] + * - [pdfUrl] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + /** Password for the PDF file (if required) */ + fun password(password: String) = apply { body.password(password) } + + /** + * Sets [Builder.password] to an arbitrary multipart value. + * + * You should usually call [Builder.password] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun password(password: MultipartField) = apply { body.password(password) } + + /** Base64 encoded CAS PDF file */ + fun pdfFile(pdfFile: String) = apply { body.pdfFile(pdfFile) } + + /** + * Sets [Builder.pdfFile] to an arbitrary multipart value. + * + * You should usually call [Builder.pdfFile] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun pdfFile(pdfFile: MultipartField) = apply { body.pdfFile(pdfFile) } + + /** URL to the CAS PDF file */ + fun pdfUrl(pdfUrl: String) = apply { body.pdfUrl(pdfUrl) } + + /** + * Sets [Builder.pdfUrl] to an arbitrary multipart value. + * + * You should usually call [Builder.pdfUrl] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun pdfUrl(pdfUrl: MultipartField) = apply { body.pdfUrl(pdfUrl) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) + } + + 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 [CasParserCdslParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): CasParserCdslParams = + CasParserCdslParams( + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): Map> = + (mapOf("password" to _password(), "pdf_file" to _pdfFile(), "pdf_url" to _pdfUrl()) + + _additionalBodyProperties().mapValues { (_, value) -> MultipartField.of(value) }) + .toImmutable() + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + class Body + private constructor( + private val password: MultipartField, + private val pdfFile: MultipartField, + private val pdfUrl: MultipartField, + private val additionalProperties: MutableMap, + ) { + + /** + * Password for the PDF file (if required) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun password(): Optional = password.value.getOptional("password") + + /** + * Base64 encoded CAS PDF file + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun pdfFile(): Optional = pdfFile.value.getOptional("pdf_file") + + /** + * URL to the CAS PDF file + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun pdfUrl(): Optional = pdfUrl.value.getOptional("pdf_url") + + /** + * Returns the raw multipart value of [password]. + * + * Unlike [password], this method doesn't throw if the multipart field has an unexpected + * type. + */ + @JsonProperty("password") @ExcludeMissing fun _password(): MultipartField = password + + /** + * Returns the raw multipart value of [pdfFile]. + * + * Unlike [pdfFile], this method doesn't throw if the multipart field has an unexpected + * type. + */ + @JsonProperty("pdf_file") @ExcludeMissing fun _pdfFile(): MultipartField = pdfFile + + /** + * Returns the raw multipart value of [pdfUrl]. + * + * Unlike [pdfUrl], this method doesn't throw if the multipart field has an unexpected type. + */ + @JsonProperty("pdf_url") @ExcludeMissing fun _pdfUrl(): MultipartField = pdfUrl + + @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 [Body]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var password: MultipartField = MultipartField.of(null) + private var pdfFile: MultipartField = MultipartField.of(null) + private var pdfUrl: MultipartField = MultipartField.of(null) + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + password = body.password + pdfFile = body.pdfFile + pdfUrl = body.pdfUrl + additionalProperties = body.additionalProperties.toMutableMap() + } + + /** Password for the PDF file (if required) */ + fun password(password: String) = password(MultipartField.of(password)) + + /** + * Sets [Builder.password] to an arbitrary multipart value. + * + * You should usually call [Builder.password] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun password(password: MultipartField) = apply { this.password = password } + + /** Base64 encoded CAS PDF file */ + fun pdfFile(pdfFile: String) = pdfFile(MultipartField.of(pdfFile)) + + /** + * Sets [Builder.pdfFile] to an arbitrary multipart value. + * + * You should usually call [Builder.pdfFile] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun pdfFile(pdfFile: MultipartField) = apply { this.pdfFile = pdfFile } + + /** URL to the CAS PDF file */ + fun pdfUrl(pdfUrl: String) = pdfUrl(MultipartField.of(pdfUrl)) + + /** + * Sets [Builder.pdfUrl] to an arbitrary multipart value. + * + * You should usually call [Builder.pdfUrl] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun pdfUrl(pdfUrl: MultipartField) = apply { this.pdfUrl = pdfUrl } + + 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 [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Body = Body(password, pdfFile, pdfUrl, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + password() + pdfFile() + pdfUrl() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + false + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + password == other.password && + pdfFile == other.pdfFile && + pdfUrl == other.pdfUrl && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(password, pdfFile, pdfUrl, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{password=$password, pdfFile=$pdfFile, pdfUrl=$pdfUrl, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is CasParserCdslParams && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = Objects.hash(body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "CasParserCdslParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserNsdlParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserNsdlParams.kt new file mode 100644 index 0000000..4692e36 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserNsdlParams.kt @@ -0,0 +1,501 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.casparser + +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.MultipartField +import com.cas_parser.api.core.Params +import com.cas_parser.api.core.http.Headers +import com.cas_parser.api.core.http.QueryParams +import com.cas_parser.api.core.toImmutable +import com.cas_parser.api.errors.CasParserInvalidDataException +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonProperty +import java.util.Collections +import java.util.Objects +import java.util.Optional + +/** + * This endpoint specifically parses NSDL CAS (Consolidated Account Statement) PDF files and returns + * data in a unified format. Use this endpoint when you know the PDF is from NSDL. + */ +class CasParserNsdlParams +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Password for the PDF file (if required) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun password(): Optional = body.password() + + /** + * Base64 encoded CAS PDF file + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun pdfFile(): Optional = body.pdfFile() + + /** + * URL to the CAS PDF file + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun pdfUrl(): Optional = body.pdfUrl() + + /** + * Returns the raw multipart value of [password]. + * + * Unlike [password], this method doesn't throw if the multipart field has an unexpected type. + */ + fun _password(): MultipartField = body._password() + + /** + * Returns the raw multipart value of [pdfFile]. + * + * Unlike [pdfFile], this method doesn't throw if the multipart field has an unexpected type. + */ + fun _pdfFile(): MultipartField = body._pdfFile() + + /** + * Returns the raw multipart value of [pdfUrl]. + * + * Unlike [pdfUrl], this method doesn't throw if the multipart field has an unexpected type. + */ + fun _pdfUrl(): MultipartField = body._pdfUrl() + + fun _additionalBodyProperties(): Map = body._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 { + + @JvmStatic fun none(): CasParserNsdlParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [CasParserNsdlParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [CasParserNsdlParams]. */ + class Builder internal constructor() { + + private var body: Body.Builder = Body.builder() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(casParserNsdlParams: CasParserNsdlParams) = apply { + body = casParserNsdlParams.body.toBuilder() + additionalHeaders = casParserNsdlParams.additionalHeaders.toBuilder() + additionalQueryParams = casParserNsdlParams.additionalQueryParams.toBuilder() + } + + /** + * Sets the entire request body. + * + * This is generally only useful if you are already constructing the body separately. + * Otherwise, it's more convenient to use the top-level setters instead: + * - [password] + * - [pdfFile] + * - [pdfUrl] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + /** Password for the PDF file (if required) */ + fun password(password: String) = apply { body.password(password) } + + /** + * Sets [Builder.password] to an arbitrary multipart value. + * + * You should usually call [Builder.password] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun password(password: MultipartField) = apply { body.password(password) } + + /** Base64 encoded CAS PDF file */ + fun pdfFile(pdfFile: String) = apply { body.pdfFile(pdfFile) } + + /** + * Sets [Builder.pdfFile] to an arbitrary multipart value. + * + * You should usually call [Builder.pdfFile] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun pdfFile(pdfFile: MultipartField) = apply { body.pdfFile(pdfFile) } + + /** URL to the CAS PDF file */ + fun pdfUrl(pdfUrl: String) = apply { body.pdfUrl(pdfUrl) } + + /** + * Sets [Builder.pdfUrl] to an arbitrary multipart value. + * + * You should usually call [Builder.pdfUrl] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun pdfUrl(pdfUrl: MultipartField) = apply { body.pdfUrl(pdfUrl) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) + } + + 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 [CasParserNsdlParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): CasParserNsdlParams = + CasParserNsdlParams( + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): Map> = + (mapOf("password" to _password(), "pdf_file" to _pdfFile(), "pdf_url" to _pdfUrl()) + + _additionalBodyProperties().mapValues { (_, value) -> MultipartField.of(value) }) + .toImmutable() + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + class Body + private constructor( + private val password: MultipartField, + private val pdfFile: MultipartField, + private val pdfUrl: MultipartField, + private val additionalProperties: MutableMap, + ) { + + /** + * Password for the PDF file (if required) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun password(): Optional = password.value.getOptional("password") + + /** + * Base64 encoded CAS PDF file + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun pdfFile(): Optional = pdfFile.value.getOptional("pdf_file") + + /** + * URL to the CAS PDF file + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun pdfUrl(): Optional = pdfUrl.value.getOptional("pdf_url") + + /** + * Returns the raw multipart value of [password]. + * + * Unlike [password], this method doesn't throw if the multipart field has an unexpected + * type. + */ + @JsonProperty("password") @ExcludeMissing fun _password(): MultipartField = password + + /** + * Returns the raw multipart value of [pdfFile]. + * + * Unlike [pdfFile], this method doesn't throw if the multipart field has an unexpected + * type. + */ + @JsonProperty("pdf_file") @ExcludeMissing fun _pdfFile(): MultipartField = pdfFile + + /** + * Returns the raw multipart value of [pdfUrl]. + * + * Unlike [pdfUrl], this method doesn't throw if the multipart field has an unexpected type. + */ + @JsonProperty("pdf_url") @ExcludeMissing fun _pdfUrl(): MultipartField = pdfUrl + + @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 [Body]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var password: MultipartField = MultipartField.of(null) + private var pdfFile: MultipartField = MultipartField.of(null) + private var pdfUrl: MultipartField = MultipartField.of(null) + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + password = body.password + pdfFile = body.pdfFile + pdfUrl = body.pdfUrl + additionalProperties = body.additionalProperties.toMutableMap() + } + + /** Password for the PDF file (if required) */ + fun password(password: String) = password(MultipartField.of(password)) + + /** + * Sets [Builder.password] to an arbitrary multipart value. + * + * You should usually call [Builder.password] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun password(password: MultipartField) = apply { this.password = password } + + /** Base64 encoded CAS PDF file */ + fun pdfFile(pdfFile: String) = pdfFile(MultipartField.of(pdfFile)) + + /** + * Sets [Builder.pdfFile] to an arbitrary multipart value. + * + * You should usually call [Builder.pdfFile] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun pdfFile(pdfFile: MultipartField) = apply { this.pdfFile = pdfFile } + + /** URL to the CAS PDF file */ + fun pdfUrl(pdfUrl: String) = pdfUrl(MultipartField.of(pdfUrl)) + + /** + * Sets [Builder.pdfUrl] to an arbitrary multipart value. + * + * You should usually call [Builder.pdfUrl] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun pdfUrl(pdfUrl: MultipartField) = apply { this.pdfUrl = pdfUrl } + + 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 [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Body = Body(password, pdfFile, pdfUrl, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + password() + pdfFile() + pdfUrl() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + false + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + password == other.password && + pdfFile == other.pdfFile && + pdfUrl == other.pdfUrl && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(password, pdfFile, pdfUrl, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{password=$password, pdfFile=$pdfFile, pdfUrl=$pdfUrl, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is CasParserNsdlParams && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = Objects.hash(body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "CasParserNsdlParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserSmartParseParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserSmartParseParams.kt new file mode 100644 index 0000000..e625f1d --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserSmartParseParams.kt @@ -0,0 +1,504 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.casparser + +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.MultipartField +import com.cas_parser.api.core.Params +import com.cas_parser.api.core.http.Headers +import com.cas_parser.api.core.http.QueryParams +import com.cas_parser.api.core.toImmutable +import com.cas_parser.api.errors.CasParserInvalidDataException +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonProperty +import java.util.Collections +import java.util.Objects +import java.util.Optional + +/** + * This endpoint parses CAS (Consolidated Account Statement) PDF files from NSDL, CDSL, or + * CAMS/KFintech and returns data in a unified format. It auto-detects the CAS type and transforms + * the data into a consistent structure regardless of the source. + */ +class CasParserSmartParseParams +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Password for the PDF file (if required) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun password(): Optional = body.password() + + /** + * Base64 encoded CAS PDF file + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun pdfFile(): Optional = body.pdfFile() + + /** + * URL to the CAS PDF file + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun pdfUrl(): Optional = body.pdfUrl() + + /** + * Returns the raw multipart value of [password]. + * + * Unlike [password], this method doesn't throw if the multipart field has an unexpected type. + */ + fun _password(): MultipartField = body._password() + + /** + * Returns the raw multipart value of [pdfFile]. + * + * Unlike [pdfFile], this method doesn't throw if the multipart field has an unexpected type. + */ + fun _pdfFile(): MultipartField = body._pdfFile() + + /** + * Returns the raw multipart value of [pdfUrl]. + * + * Unlike [pdfUrl], this method doesn't throw if the multipart field has an unexpected type. + */ + fun _pdfUrl(): MultipartField = body._pdfUrl() + + fun _additionalBodyProperties(): Map = body._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 { + + @JvmStatic fun none(): CasParserSmartParseParams = builder().build() + + /** + * Returns a mutable builder for constructing an instance of [CasParserSmartParseParams]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [CasParserSmartParseParams]. */ + class Builder internal constructor() { + + private var body: Body.Builder = Body.builder() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(casParserSmartParseParams: CasParserSmartParseParams) = apply { + body = casParserSmartParseParams.body.toBuilder() + additionalHeaders = casParserSmartParseParams.additionalHeaders.toBuilder() + additionalQueryParams = casParserSmartParseParams.additionalQueryParams.toBuilder() + } + + /** + * Sets the entire request body. + * + * This is generally only useful if you are already constructing the body separately. + * Otherwise, it's more convenient to use the top-level setters instead: + * - [password] + * - [pdfFile] + * - [pdfUrl] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + /** Password for the PDF file (if required) */ + fun password(password: String) = apply { body.password(password) } + + /** + * Sets [Builder.password] to an arbitrary multipart value. + * + * You should usually call [Builder.password] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun password(password: MultipartField) = apply { body.password(password) } + + /** Base64 encoded CAS PDF file */ + fun pdfFile(pdfFile: String) = apply { body.pdfFile(pdfFile) } + + /** + * Sets [Builder.pdfFile] to an arbitrary multipart value. + * + * You should usually call [Builder.pdfFile] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun pdfFile(pdfFile: MultipartField) = apply { body.pdfFile(pdfFile) } + + /** URL to the CAS PDF file */ + fun pdfUrl(pdfUrl: String) = apply { body.pdfUrl(pdfUrl) } + + /** + * Sets [Builder.pdfUrl] to an arbitrary multipart value. + * + * You should usually call [Builder.pdfUrl] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun pdfUrl(pdfUrl: MultipartField) = apply { body.pdfUrl(pdfUrl) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) + } + + 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 [CasParserSmartParseParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): CasParserSmartParseParams = + CasParserSmartParseParams( + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): Map> = + (mapOf("password" to _password(), "pdf_file" to _pdfFile(), "pdf_url" to _pdfUrl()) + + _additionalBodyProperties().mapValues { (_, value) -> MultipartField.of(value) }) + .toImmutable() + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + class Body + private constructor( + private val password: MultipartField, + private val pdfFile: MultipartField, + private val pdfUrl: MultipartField, + private val additionalProperties: MutableMap, + ) { + + /** + * Password for the PDF file (if required) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun password(): Optional = password.value.getOptional("password") + + /** + * Base64 encoded CAS PDF file + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun pdfFile(): Optional = pdfFile.value.getOptional("pdf_file") + + /** + * URL to the CAS PDF file + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun pdfUrl(): Optional = pdfUrl.value.getOptional("pdf_url") + + /** + * Returns the raw multipart value of [password]. + * + * Unlike [password], this method doesn't throw if the multipart field has an unexpected + * type. + */ + @JsonProperty("password") @ExcludeMissing fun _password(): MultipartField = password + + /** + * Returns the raw multipart value of [pdfFile]. + * + * Unlike [pdfFile], this method doesn't throw if the multipart field has an unexpected + * type. + */ + @JsonProperty("pdf_file") @ExcludeMissing fun _pdfFile(): MultipartField = pdfFile + + /** + * Returns the raw multipart value of [pdfUrl]. + * + * Unlike [pdfUrl], this method doesn't throw if the multipart field has an unexpected type. + */ + @JsonProperty("pdf_url") @ExcludeMissing fun _pdfUrl(): MultipartField = pdfUrl + + @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 [Body]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var password: MultipartField = MultipartField.of(null) + private var pdfFile: MultipartField = MultipartField.of(null) + private var pdfUrl: MultipartField = MultipartField.of(null) + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + password = body.password + pdfFile = body.pdfFile + pdfUrl = body.pdfUrl + additionalProperties = body.additionalProperties.toMutableMap() + } + + /** Password for the PDF file (if required) */ + fun password(password: String) = password(MultipartField.of(password)) + + /** + * Sets [Builder.password] to an arbitrary multipart value. + * + * You should usually call [Builder.password] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun password(password: MultipartField) = apply { this.password = password } + + /** Base64 encoded CAS PDF file */ + fun pdfFile(pdfFile: String) = pdfFile(MultipartField.of(pdfFile)) + + /** + * Sets [Builder.pdfFile] to an arbitrary multipart value. + * + * You should usually call [Builder.pdfFile] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun pdfFile(pdfFile: MultipartField) = apply { this.pdfFile = pdfFile } + + /** URL to the CAS PDF file */ + fun pdfUrl(pdfUrl: String) = pdfUrl(MultipartField.of(pdfUrl)) + + /** + * Sets [Builder.pdfUrl] to an arbitrary multipart value. + * + * You should usually call [Builder.pdfUrl] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun pdfUrl(pdfUrl: MultipartField) = apply { this.pdfUrl = pdfUrl } + + 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 [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Body = Body(password, pdfFile, pdfUrl, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + password() + pdfFile() + pdfUrl() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + false + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + password == other.password && + pdfFile == other.pdfFile && + pdfUrl == other.pdfUrl && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(password, pdfFile, pdfUrl, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{password=$password, pdfFile=$pdfFile, pdfUrl=$pdfUrl, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is CasParserSmartParseParams && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = Objects.hash(body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "CasParserSmartParseParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/UnifiedResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/UnifiedResponse.kt new file mode 100644 index 0000000..2c18576 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/UnifiedResponse.kt @@ -0,0 +1,8005 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.casparser + +import com.cas_parser.api.core.Enum +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonField +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.checkKnown +import com.cas_parser.api.core.toImmutable +import com.cas_parser.api.errors.CasParserInvalidDataException +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.time.LocalDate +import java.time.OffsetDateTime +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +class UnifiedResponse +private constructor( + private val dematAccounts: JsonField>, + private val insurance: JsonField, + private val investor: JsonField, + private val meta: JsonField, + private val mutualFunds: JsonField>, + private val summary: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("demat_accounts") + @ExcludeMissing + dematAccounts: JsonField> = JsonMissing.of(), + @JsonProperty("insurance") + @ExcludeMissing + insurance: JsonField = JsonMissing.of(), + @JsonProperty("investor") @ExcludeMissing investor: JsonField = JsonMissing.of(), + @JsonProperty("meta") @ExcludeMissing meta: JsonField = JsonMissing.of(), + @JsonProperty("mutual_funds") + @ExcludeMissing + mutualFunds: JsonField> = JsonMissing.of(), + @JsonProperty("summary") @ExcludeMissing summary: JsonField = JsonMissing.of(), + ) : this(dematAccounts, insurance, investor, meta, mutualFunds, summary, mutableMapOf()) + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun dematAccounts(): Optional> = dematAccounts.getOptional("demat_accounts") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun insurance(): Optional = insurance.getOptional("insurance") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun investor(): Optional = investor.getOptional("investor") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun meta(): Optional = meta.getOptional("meta") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun mutualFunds(): Optional> = mutualFunds.getOptional("mutual_funds") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun summary(): Optional = summary.getOptional("summary") + + /** + * Returns the raw JSON value of [dematAccounts]. + * + * Unlike [dematAccounts], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("demat_accounts") + @ExcludeMissing + fun _dematAccounts(): JsonField> = dematAccounts + + /** + * Returns the raw JSON value of [insurance]. + * + * Unlike [insurance], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("insurance") @ExcludeMissing fun _insurance(): JsonField = insurance + + /** + * Returns the raw JSON value of [investor]. + * + * Unlike [investor], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("investor") @ExcludeMissing fun _investor(): JsonField = investor + + /** + * Returns the raw JSON value of [meta]. + * + * Unlike [meta], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("meta") @ExcludeMissing fun _meta(): JsonField = meta + + /** + * Returns the raw JSON value of [mutualFunds]. + * + * Unlike [mutualFunds], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("mutual_funds") + @ExcludeMissing + fun _mutualFunds(): JsonField> = mutualFunds + + /** + * Returns the raw JSON value of [summary]. + * + * Unlike [summary], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("summary") @ExcludeMissing fun _summary(): JsonField = summary + + @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 [UnifiedResponse]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [UnifiedResponse]. */ + class Builder internal constructor() { + + private var dematAccounts: JsonField>? = null + private var insurance: JsonField = JsonMissing.of() + private var investor: JsonField = JsonMissing.of() + private var meta: JsonField = JsonMissing.of() + private var mutualFunds: JsonField>? = null + private var summary: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(unifiedResponse: UnifiedResponse) = apply { + dematAccounts = unifiedResponse.dematAccounts.map { it.toMutableList() } + insurance = unifiedResponse.insurance + investor = unifiedResponse.investor + meta = unifiedResponse.meta + mutualFunds = unifiedResponse.mutualFunds.map { it.toMutableList() } + summary = unifiedResponse.summary + additionalProperties = unifiedResponse.additionalProperties.toMutableMap() + } + + fun dematAccounts(dematAccounts: List) = + dematAccounts(JsonField.of(dematAccounts)) + + /** + * Sets [Builder.dematAccounts] to an arbitrary JSON value. + * + * You should usually call [Builder.dematAccounts] with a well-typed `List` + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun dematAccounts(dematAccounts: JsonField>) = apply { + this.dematAccounts = dematAccounts.map { it.toMutableList() } + } + + /** + * Adds a single [DematAccount] to [dematAccounts]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addDematAccount(dematAccount: DematAccount) = apply { + dematAccounts = + (dematAccounts ?: JsonField.of(mutableListOf())).also { + checkKnown("dematAccounts", it).add(dematAccount) + } + } + + fun insurance(insurance: Insurance) = insurance(JsonField.of(insurance)) + + /** + * Sets [Builder.insurance] to an arbitrary JSON value. + * + * You should usually call [Builder.insurance] with a well-typed [Insurance] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun insurance(insurance: JsonField) = apply { this.insurance = insurance } + + fun investor(investor: Investor) = investor(JsonField.of(investor)) + + /** + * Sets [Builder.investor] to an arbitrary JSON value. + * + * You should usually call [Builder.investor] with a well-typed [Investor] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun investor(investor: JsonField) = apply { this.investor = investor } + + fun meta(meta: Meta) = meta(JsonField.of(meta)) + + /** + * Sets [Builder.meta] to an arbitrary JSON value. + * + * You should usually call [Builder.meta] with a well-typed [Meta] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun meta(meta: JsonField) = apply { this.meta = meta } + + fun mutualFunds(mutualFunds: List) = mutualFunds(JsonField.of(mutualFunds)) + + /** + * Sets [Builder.mutualFunds] to an arbitrary JSON value. + * + * You should usually call [Builder.mutualFunds] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun mutualFunds(mutualFunds: JsonField>) = apply { + this.mutualFunds = mutualFunds.map { it.toMutableList() } + } + + /** + * Adds a single [MutualFund] to [mutualFunds]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addMutualFund(mutualFund: MutualFund) = apply { + mutualFunds = + (mutualFunds ?: JsonField.of(mutableListOf())).also { + checkKnown("mutualFunds", it).add(mutualFund) + } + } + + fun summary(summary: Summary) = summary(JsonField.of(summary)) + + /** + * Sets [Builder.summary] to an arbitrary JSON value. + * + * You should usually call [Builder.summary] with a well-typed [Summary] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun summary(summary: JsonField) = apply { this.summary = summary } + + 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 [UnifiedResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): UnifiedResponse = + UnifiedResponse( + (dematAccounts ?: JsonMissing.of()).map { it.toImmutable() }, + insurance, + investor, + meta, + (mutualFunds ?: JsonMissing.of()).map { it.toImmutable() }, + summary, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): UnifiedResponse = apply { + if (validated) { + return@apply + } + + dematAccounts().ifPresent { it.forEach { it.validate() } } + insurance().ifPresent { it.validate() } + investor().ifPresent { it.validate() } + meta().ifPresent { it.validate() } + mutualFunds().ifPresent { it.forEach { it.validate() } } + summary().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 = + (dematAccounts.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (insurance.asKnown().getOrNull()?.validity() ?: 0) + + (investor.asKnown().getOrNull()?.validity() ?: 0) + + (meta.asKnown().getOrNull()?.validity() ?: 0) + + (mutualFunds.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (summary.asKnown().getOrNull()?.validity() ?: 0) + + class DematAccount + private constructor( + private val additionalInfo: JsonField, + private val boId: JsonField, + private val clientId: JsonField, + private val dematType: JsonField, + private val dpId: JsonField, + private val dpName: JsonField, + private val holdings: JsonField, + private val value: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("additional_info") + @ExcludeMissing + additionalInfo: JsonField = JsonMissing.of(), + @JsonProperty("bo_id") @ExcludeMissing boId: JsonField = JsonMissing.of(), + @JsonProperty("client_id") + @ExcludeMissing + clientId: JsonField = JsonMissing.of(), + @JsonProperty("demat_type") + @ExcludeMissing + dematType: JsonField = JsonMissing.of(), + @JsonProperty("dp_id") @ExcludeMissing dpId: JsonField = JsonMissing.of(), + @JsonProperty("dp_name") @ExcludeMissing dpName: JsonField = JsonMissing.of(), + @JsonProperty("holdings") + @ExcludeMissing + holdings: JsonField = JsonMissing.of(), + @JsonProperty("value") @ExcludeMissing value: JsonField = JsonMissing.of(), + ) : this( + additionalInfo, + boId, + clientId, + dematType, + dpId, + dpName, + holdings, + value, + mutableMapOf(), + ) + + /** + * Additional information specific to the demat account type + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun additionalInfo(): Optional = + additionalInfo.getOptional("additional_info") + + /** + * Beneficiary Owner ID (primarily for CDSL) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun boId(): Optional = boId.getOptional("bo_id") + + /** + * Client ID + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun clientId(): Optional = clientId.getOptional("client_id") + + /** + * Type of demat account + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun dematType(): Optional = dematType.getOptional("demat_type") + + /** + * Depository Participant ID + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun dpId(): Optional = dpId.getOptional("dp_id") + + /** + * Depository Participant name + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun dpName(): Optional = dpName.getOptional("dp_name") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun holdings(): Optional = holdings.getOptional("holdings") + + /** + * Total value of the demat account + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun value(): Optional = value.getOptional("value") + + /** + * Returns the raw JSON value of [additionalInfo]. + * + * Unlike [additionalInfo], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("additional_info") + @ExcludeMissing + fun _additionalInfo(): JsonField = additionalInfo + + /** + * Returns the raw JSON value of [boId]. + * + * Unlike [boId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("bo_id") @ExcludeMissing fun _boId(): JsonField = boId + + /** + * Returns the raw JSON value of [clientId]. + * + * Unlike [clientId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("client_id") @ExcludeMissing fun _clientId(): JsonField = clientId + + /** + * Returns the raw JSON value of [dematType]. + * + * Unlike [dematType], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("demat_type") + @ExcludeMissing + fun _dematType(): JsonField = dematType + + /** + * Returns the raw JSON value of [dpId]. + * + * Unlike [dpId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("dp_id") @ExcludeMissing fun _dpId(): JsonField = dpId + + /** + * Returns the raw JSON value of [dpName]. + * + * Unlike [dpName], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("dp_name") @ExcludeMissing fun _dpName(): JsonField = dpName + + /** + * Returns the raw JSON value of [holdings]. + * + * Unlike [holdings], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("holdings") @ExcludeMissing fun _holdings(): JsonField = holdings + + /** + * Returns the raw JSON value of [value]. + * + * Unlike [value], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("value") @ExcludeMissing fun _value(): JsonField = value + + @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 [DematAccount]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [DematAccount]. */ + class Builder internal constructor() { + + private var additionalInfo: JsonField = JsonMissing.of() + private var boId: JsonField = JsonMissing.of() + private var clientId: JsonField = JsonMissing.of() + private var dematType: JsonField = JsonMissing.of() + private var dpId: JsonField = JsonMissing.of() + private var dpName: JsonField = JsonMissing.of() + private var holdings: JsonField = JsonMissing.of() + private var value: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(dematAccount: DematAccount) = apply { + additionalInfo = dematAccount.additionalInfo + boId = dematAccount.boId + clientId = dematAccount.clientId + dematType = dematAccount.dematType + dpId = dematAccount.dpId + dpName = dematAccount.dpName + holdings = dematAccount.holdings + value = dematAccount.value + additionalProperties = dematAccount.additionalProperties.toMutableMap() + } + + /** Additional information specific to the demat account type */ + fun additionalInfo(additionalInfo: AdditionalInfo) = + additionalInfo(JsonField.of(additionalInfo)) + + /** + * Sets [Builder.additionalInfo] to an arbitrary JSON value. + * + * You should usually call [Builder.additionalInfo] with a well-typed [AdditionalInfo] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun additionalInfo(additionalInfo: JsonField) = apply { + this.additionalInfo = additionalInfo + } + + /** Beneficiary Owner ID (primarily for CDSL) */ + fun boId(boId: String) = boId(JsonField.of(boId)) + + /** + * Sets [Builder.boId] to an arbitrary JSON value. + * + * You should usually call [Builder.boId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun boId(boId: JsonField) = apply { this.boId = boId } + + /** Client ID */ + fun clientId(clientId: String) = clientId(JsonField.of(clientId)) + + /** + * Sets [Builder.clientId] to an arbitrary JSON value. + * + * You should usually call [Builder.clientId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun clientId(clientId: JsonField) = apply { this.clientId = clientId } + + /** Type of demat account */ + fun dematType(dematType: DematType) = dematType(JsonField.of(dematType)) + + /** + * Sets [Builder.dematType] to an arbitrary JSON value. + * + * You should usually call [Builder.dematType] with a well-typed [DematType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun dematType(dematType: JsonField) = apply { this.dematType = dematType } + + /** Depository Participant ID */ + fun dpId(dpId: String) = dpId(JsonField.of(dpId)) + + /** + * Sets [Builder.dpId] to an arbitrary JSON value. + * + * You should usually call [Builder.dpId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun dpId(dpId: JsonField) = apply { this.dpId = dpId } + + /** Depository Participant name */ + fun dpName(dpName: String) = dpName(JsonField.of(dpName)) + + /** + * Sets [Builder.dpName] to an arbitrary JSON value. + * + * You should usually call [Builder.dpName] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun dpName(dpName: JsonField) = apply { this.dpName = dpName } + + fun holdings(holdings: Holdings) = holdings(JsonField.of(holdings)) + + /** + * Sets [Builder.holdings] to an arbitrary JSON value. + * + * You should usually call [Builder.holdings] with a well-typed [Holdings] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun holdings(holdings: JsonField) = apply { this.holdings = holdings } + + /** Total value of the demat account */ + fun value(value: Float) = value(JsonField.of(value)) + + /** + * Sets [Builder.value] to an arbitrary JSON value. + * + * You should usually call [Builder.value] with a well-typed [Float] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun value(value: JsonField) = apply { this.value = value } + + 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 [DematAccount]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): DematAccount = + DematAccount( + additionalInfo, + boId, + clientId, + dematType, + dpId, + dpName, + holdings, + value, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): DematAccount = apply { + if (validated) { + return@apply + } + + additionalInfo().ifPresent { it.validate() } + boId() + clientId() + dematType().ifPresent { it.validate() } + dpId() + dpName() + holdings().ifPresent { it.validate() } + value() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 = + (additionalInfo.asKnown().getOrNull()?.validity() ?: 0) + + (if (boId.asKnown().isPresent) 1 else 0) + + (if (clientId.asKnown().isPresent) 1 else 0) + + (dematType.asKnown().getOrNull()?.validity() ?: 0) + + (if (dpId.asKnown().isPresent) 1 else 0) + + (if (dpName.asKnown().isPresent) 1 else 0) + + (holdings.asKnown().getOrNull()?.validity() ?: 0) + + (if (value.asKnown().isPresent) 1 else 0) + + /** Additional information specific to the demat account type */ + class AdditionalInfo + private constructor( + private val boStatus: JsonField, + private val boSubStatus: JsonField, + private val boType: JsonField, + private val bsda: JsonField, + private val email: JsonField, + private val linkedPans: JsonField>, + private val nominee: JsonField, + private val status: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("bo_status") + @ExcludeMissing + boStatus: JsonField = JsonMissing.of(), + @JsonProperty("bo_sub_status") + @ExcludeMissing + boSubStatus: JsonField = JsonMissing.of(), + @JsonProperty("bo_type") + @ExcludeMissing + boType: JsonField = JsonMissing.of(), + @JsonProperty("bsda") @ExcludeMissing bsda: JsonField = JsonMissing.of(), + @JsonProperty("email") @ExcludeMissing email: JsonField = JsonMissing.of(), + @JsonProperty("linked_pans") + @ExcludeMissing + linkedPans: JsonField> = JsonMissing.of(), + @JsonProperty("nominee") + @ExcludeMissing + nominee: JsonField = JsonMissing.of(), + @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(), + ) : this( + boStatus, + boSubStatus, + boType, + bsda, + email, + linkedPans, + nominee, + status, + mutableMapOf(), + ) + + /** + * Beneficiary Owner status (CDSL) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun boStatus(): Optional = boStatus.getOptional("bo_status") + + /** + * Beneficiary Owner sub-status (CDSL) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun boSubStatus(): Optional = boSubStatus.getOptional("bo_sub_status") + + /** + * Beneficiary Owner type (CDSL) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun boType(): Optional = boType.getOptional("bo_type") + + /** + * Basic Services Demat Account status (CDSL) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun bsda(): Optional = bsda.getOptional("bsda") + + /** + * Email associated with the demat account (CDSL) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun email(): Optional = email.getOptional("email") + + /** + * List of linked PAN numbers (NSDL) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun linkedPans(): Optional> = linkedPans.getOptional("linked_pans") + + /** + * Nominee details (CDSL) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun nominee(): Optional = nominee.getOptional("nominee") + + /** + * Account status (CDSL) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun status(): Optional = status.getOptional("status") + + /** + * Returns the raw JSON value of [boStatus]. + * + * Unlike [boStatus], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("bo_status") @ExcludeMissing fun _boStatus(): JsonField = boStatus + + /** + * Returns the raw JSON value of [boSubStatus]. + * + * Unlike [boSubStatus], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("bo_sub_status") + @ExcludeMissing + fun _boSubStatus(): JsonField = boSubStatus + + /** + * Returns the raw JSON value of [boType]. + * + * Unlike [boType], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("bo_type") @ExcludeMissing fun _boType(): JsonField = boType + + /** + * Returns the raw JSON value of [bsda]. + * + * Unlike [bsda], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("bsda") @ExcludeMissing fun _bsda(): JsonField = bsda + + /** + * Returns the raw JSON value of [email]. + * + * Unlike [email], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("email") @ExcludeMissing fun _email(): JsonField = email + + /** + * Returns the raw JSON value of [linkedPans]. + * + * Unlike [linkedPans], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("linked_pans") + @ExcludeMissing + fun _linkedPans(): JsonField> = linkedPans + + /** + * Returns the raw JSON value of [nominee]. + * + * Unlike [nominee], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("nominee") @ExcludeMissing fun _nominee(): JsonField = nominee + + /** + * Returns the raw JSON value of [status]. + * + * Unlike [status], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("status") @ExcludeMissing fun _status(): JsonField = status + + @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 [AdditionalInfo]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AdditionalInfo]. */ + class Builder internal constructor() { + + private var boStatus: JsonField = JsonMissing.of() + private var boSubStatus: JsonField = JsonMissing.of() + private var boType: JsonField = JsonMissing.of() + private var bsda: JsonField = JsonMissing.of() + private var email: JsonField = JsonMissing.of() + private var linkedPans: JsonField>? = null + private var nominee: JsonField = JsonMissing.of() + private var status: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(additionalInfo: AdditionalInfo) = apply { + boStatus = additionalInfo.boStatus + boSubStatus = additionalInfo.boSubStatus + boType = additionalInfo.boType + bsda = additionalInfo.bsda + email = additionalInfo.email + linkedPans = additionalInfo.linkedPans.map { it.toMutableList() } + nominee = additionalInfo.nominee + status = additionalInfo.status + additionalProperties = additionalInfo.additionalProperties.toMutableMap() + } + + /** Beneficiary Owner status (CDSL) */ + fun boStatus(boStatus: String) = boStatus(JsonField.of(boStatus)) + + /** + * Sets [Builder.boStatus] to an arbitrary JSON value. + * + * You should usually call [Builder.boStatus] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun boStatus(boStatus: JsonField) = apply { this.boStatus = boStatus } + + /** Beneficiary Owner sub-status (CDSL) */ + fun boSubStatus(boSubStatus: String) = boSubStatus(JsonField.of(boSubStatus)) + + /** + * Sets [Builder.boSubStatus] to an arbitrary JSON value. + * + * You should usually call [Builder.boSubStatus] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun boSubStatus(boSubStatus: JsonField) = apply { + this.boSubStatus = boSubStatus + } + + /** Beneficiary Owner type (CDSL) */ + fun boType(boType: String) = boType(JsonField.of(boType)) + + /** + * Sets [Builder.boType] to an arbitrary JSON value. + * + * You should usually call [Builder.boType] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun boType(boType: JsonField) = apply { this.boType = boType } + + /** Basic Services Demat Account status (CDSL) */ + fun bsda(bsda: String) = bsda(JsonField.of(bsda)) + + /** + * Sets [Builder.bsda] to an arbitrary JSON value. + * + * You should usually call [Builder.bsda] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun bsda(bsda: JsonField) = apply { this.bsda = bsda } + + /** Email associated with the demat account (CDSL) */ + fun email(email: String) = email(JsonField.of(email)) + + /** + * Sets [Builder.email] to an arbitrary JSON value. + * + * You should usually call [Builder.email] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun email(email: JsonField) = apply { this.email = email } + + /** List of linked PAN numbers (NSDL) */ + fun linkedPans(linkedPans: List) = linkedPans(JsonField.of(linkedPans)) + + /** + * Sets [Builder.linkedPans] to an arbitrary JSON value. + * + * You should usually call [Builder.linkedPans] with a well-typed `List` + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun linkedPans(linkedPans: JsonField>) = apply { + this.linkedPans = linkedPans.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [linkedPans]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addLinkedPan(linkedPan: String) = apply { + linkedPans = + (linkedPans ?: JsonField.of(mutableListOf())).also { + checkKnown("linkedPans", it).add(linkedPan) + } + } + + /** Nominee details (CDSL) */ + fun nominee(nominee: String) = nominee(JsonField.of(nominee)) + + /** + * Sets [Builder.nominee] to an arbitrary JSON value. + * + * You should usually call [Builder.nominee] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun nominee(nominee: JsonField) = apply { this.nominee = nominee } + + /** Account status (CDSL) */ + fun status(status: String) = status(JsonField.of(status)) + + /** + * Sets [Builder.status] to an arbitrary JSON value. + * + * You should usually call [Builder.status] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun status(status: JsonField) = apply { this.status = status } + + 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 [AdditionalInfo]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): AdditionalInfo = + AdditionalInfo( + boStatus, + boSubStatus, + boType, + bsda, + email, + (linkedPans ?: JsonMissing.of()).map { it.toImmutable() }, + nominee, + status, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): AdditionalInfo = apply { + if (validated) { + return@apply + } + + boStatus() + boSubStatus() + boType() + bsda() + email() + linkedPans() + nominee() + status() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (boStatus.asKnown().isPresent) 1 else 0) + + (if (boSubStatus.asKnown().isPresent) 1 else 0) + + (if (boType.asKnown().isPresent) 1 else 0) + + (if (bsda.asKnown().isPresent) 1 else 0) + + (if (email.asKnown().isPresent) 1 else 0) + + (linkedPans.asKnown().getOrNull()?.size ?: 0) + + (if (nominee.asKnown().isPresent) 1 else 0) + + (if (status.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AdditionalInfo && + boStatus == other.boStatus && + boSubStatus == other.boSubStatus && + boType == other.boType && + bsda == other.bsda && + email == other.email && + linkedPans == other.linkedPans && + nominee == other.nominee && + status == other.status && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + boStatus, + boSubStatus, + boType, + bsda, + email, + linkedPans, + nominee, + status, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AdditionalInfo{boStatus=$boStatus, boSubStatus=$boSubStatus, boType=$boType, bsda=$bsda, email=$email, linkedPans=$linkedPans, nominee=$nominee, status=$status, additionalProperties=$additionalProperties}" + } + + /** Type of demat account */ + class DematType @JsonCreator private constructor(private val value: JsonField) : + Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is + * on an older version than the API, then the API may respond with new members that the + * SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val NSDL = of("NSDL") + + @JvmField val CDSL = of("CDSL") + + @JvmStatic fun of(value: String) = DematType(JsonField.of(value)) + } + + /** An enum containing [DematType]'s known values. */ + enum class Known { + NSDL, + CDSL, + } + + /** + * An enum containing [DematType]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [DematType] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if + * the SDK is on an older version than the API, then the API may respond with new + * members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + NSDL, + CDSL, + /** + * An enum member indicating that [DematType] was instantiated with an unknown + * value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you + * want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + NSDL -> Value.NSDL + CDSL -> Value.CDSL + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and + * don't want to throw for the unknown case. + * + * @throws CasParserInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + NSDL -> Known.NSDL + CDSL -> Known.CDSL + else -> throw CasParserInvalidDataException("Unknown DematType: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws CasParserInvalidDataException if this class instance's value does not have + * the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CasParserInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): DematType = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is DematType && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + class Holdings + private constructor( + private val aifs: JsonField>, + private val corporateBonds: JsonField>, + private val dematMutualFunds: JsonField>, + private val equities: JsonField>, + private val governmentSecurities: JsonField>, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("aifs") @ExcludeMissing aifs: JsonField> = JsonMissing.of(), + @JsonProperty("corporate_bonds") + @ExcludeMissing + corporateBonds: JsonField> = JsonMissing.of(), + @JsonProperty("demat_mutual_funds") + @ExcludeMissing + dematMutualFunds: JsonField> = JsonMissing.of(), + @JsonProperty("equities") + @ExcludeMissing + equities: JsonField> = JsonMissing.of(), + @JsonProperty("government_securities") + @ExcludeMissing + governmentSecurities: JsonField> = JsonMissing.of(), + ) : this( + aifs, + corporateBonds, + dematMutualFunds, + equities, + governmentSecurities, + mutableMapOf(), + ) + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun aifs(): Optional> = aifs.getOptional("aifs") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun corporateBonds(): Optional> = + corporateBonds.getOptional("corporate_bonds") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun dematMutualFunds(): Optional> = + dematMutualFunds.getOptional("demat_mutual_funds") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun equities(): Optional> = equities.getOptional("equities") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun governmentSecurities(): Optional> = + governmentSecurities.getOptional("government_securities") + + /** + * Returns the raw JSON value of [aifs]. + * + * Unlike [aifs], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("aifs") @ExcludeMissing fun _aifs(): JsonField> = aifs + + /** + * Returns the raw JSON value of [corporateBonds]. + * + * Unlike [corporateBonds], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("corporate_bonds") + @ExcludeMissing + fun _corporateBonds(): JsonField> = corporateBonds + + /** + * Returns the raw JSON value of [dematMutualFunds]. + * + * Unlike [dematMutualFunds], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("demat_mutual_funds") + @ExcludeMissing + fun _dematMutualFunds(): JsonField> = dematMutualFunds + + /** + * Returns the raw JSON value of [equities]. + * + * Unlike [equities], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("equities") + @ExcludeMissing + fun _equities(): JsonField> = equities + + /** + * Returns the raw JSON value of [governmentSecurities]. + * + * Unlike [governmentSecurities], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("government_securities") + @ExcludeMissing + fun _governmentSecurities(): JsonField> = governmentSecurities + + @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 [Holdings]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Holdings]. */ + class Builder internal constructor() { + + private var aifs: JsonField>? = null + private var corporateBonds: JsonField>? = null + private var dematMutualFunds: JsonField>? = null + private var equities: JsonField>? = null + private var governmentSecurities: JsonField>? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(holdings: Holdings) = apply { + aifs = holdings.aifs.map { it.toMutableList() } + corporateBonds = holdings.corporateBonds.map { it.toMutableList() } + dematMutualFunds = holdings.dematMutualFunds.map { it.toMutableList() } + equities = holdings.equities.map { it.toMutableList() } + governmentSecurities = holdings.governmentSecurities.map { it.toMutableList() } + additionalProperties = holdings.additionalProperties.toMutableMap() + } + + fun aifs(aifs: List) = aifs(JsonField.of(aifs)) + + /** + * Sets [Builder.aifs] to an arbitrary JSON value. + * + * You should usually call [Builder.aifs] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun aifs(aifs: JsonField>) = apply { + this.aifs = aifs.map { it.toMutableList() } + } + + /** + * Adds a single [Aif] to [aifs]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addAif(aif: Aif) = apply { + aifs = + (aifs ?: JsonField.of(mutableListOf())).also { + checkKnown("aifs", it).add(aif) + } + } + + fun corporateBonds(corporateBonds: List) = + corporateBonds(JsonField.of(corporateBonds)) + + /** + * Sets [Builder.corporateBonds] to an arbitrary JSON value. + * + * You should usually call [Builder.corporateBonds] with a well-typed + * `List` value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun corporateBonds(corporateBonds: JsonField>) = apply { + this.corporateBonds = corporateBonds.map { it.toMutableList() } + } + + /** + * Adds a single [CorporateBond] to [corporateBonds]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addCorporateBond(corporateBond: CorporateBond) = apply { + corporateBonds = + (corporateBonds ?: JsonField.of(mutableListOf())).also { + checkKnown("corporateBonds", it).add(corporateBond) + } + } + + fun dematMutualFunds(dematMutualFunds: List) = + dematMutualFunds(JsonField.of(dematMutualFunds)) + + /** + * Sets [Builder.dematMutualFunds] to an arbitrary JSON value. + * + * You should usually call [Builder.dematMutualFunds] with a well-typed + * `List` value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun dematMutualFunds(dematMutualFunds: JsonField>) = apply { + this.dematMutualFunds = dematMutualFunds.map { it.toMutableList() } + } + + /** + * Adds a single [DematMutualFund] to [dematMutualFunds]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addDematMutualFund(dematMutualFund: DematMutualFund) = apply { + dematMutualFunds = + (dematMutualFunds ?: JsonField.of(mutableListOf())).also { + checkKnown("dematMutualFunds", it).add(dematMutualFund) + } + } + + fun equities(equities: List) = equities(JsonField.of(equities)) + + /** + * Sets [Builder.equities] to an arbitrary JSON value. + * + * You should usually call [Builder.equities] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun equities(equities: JsonField>) = apply { + this.equities = equities.map { it.toMutableList() } + } + + /** + * Adds a single [Equity] to [equities]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addEquity(equity: Equity) = apply { + equities = + (equities ?: JsonField.of(mutableListOf())).also { + checkKnown("equities", it).add(equity) + } + } + + fun governmentSecurities(governmentSecurities: List) = + governmentSecurities(JsonField.of(governmentSecurities)) + + /** + * Sets [Builder.governmentSecurities] to an arbitrary JSON value. + * + * You should usually call [Builder.governmentSecurities] with a well-typed + * `List` value instead. This method is primarily for setting + * the field to an undocumented or not yet supported value. + */ + fun governmentSecurities( + governmentSecurities: JsonField> + ) = apply { + this.governmentSecurities = governmentSecurities.map { it.toMutableList() } + } + + /** + * Adds a single [GovernmentSecurity] to [governmentSecurities]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addGovernmentSecurity(governmentSecurity: GovernmentSecurity) = apply { + governmentSecurities = + (governmentSecurities ?: JsonField.of(mutableListOf())).also { + checkKnown("governmentSecurities", it).add(governmentSecurity) + } + } + + 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 [Holdings]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Holdings = + Holdings( + (aifs ?: JsonMissing.of()).map { it.toImmutable() }, + (corporateBonds ?: JsonMissing.of()).map { it.toImmutable() }, + (dematMutualFunds ?: JsonMissing.of()).map { it.toImmutable() }, + (equities ?: JsonMissing.of()).map { it.toImmutable() }, + (governmentSecurities ?: JsonMissing.of()).map { it.toImmutable() }, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Holdings = apply { + if (validated) { + return@apply + } + + aifs().ifPresent { it.forEach { it.validate() } } + corporateBonds().ifPresent { it.forEach { it.validate() } } + dematMutualFunds().ifPresent { it.forEach { it.validate() } } + equities().ifPresent { it.forEach { it.validate() } } + governmentSecurities().ifPresent { it.forEach { it.validate() } } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 = + (aifs.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (corporateBonds.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (dematMutualFunds.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (equities.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (governmentSecurities.asKnown().getOrNull()?.sumOf { it.validity().toInt() } + ?: 0) + + class Aif + private constructor( + private val additionalInfo: JsonValue, + private val isin: JsonField, + private val name: JsonField, + private val units: JsonField, + private val value: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("additional_info") + @ExcludeMissing + additionalInfo: JsonValue = JsonMissing.of(), + @JsonProperty("isin") + @ExcludeMissing + isin: JsonField = JsonMissing.of(), + @JsonProperty("name") + @ExcludeMissing + name: JsonField = JsonMissing.of(), + @JsonProperty("units") + @ExcludeMissing + units: JsonField = JsonMissing.of(), + @JsonProperty("value") + @ExcludeMissing + value: JsonField = JsonMissing.of(), + ) : this(additionalInfo, isin, name, units, value, mutableMapOf()) + + /** Additional information specific to the AIF */ + @JsonProperty("additional_info") + @ExcludeMissing + fun _additionalInfo(): JsonValue = additionalInfo + + /** + * ISIN code of the AIF + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun isin(): Optional = isin.getOptional("isin") + + /** + * Name of the AIF + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun name(): Optional = name.getOptional("name") + + /** + * Number of units held + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun units(): Optional = units.getOptional("units") + + /** + * Current market value of the holding + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun value(): Optional = value.getOptional("value") + + /** + * Returns the raw JSON value of [isin]. + * + * Unlike [isin], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("isin") @ExcludeMissing fun _isin(): JsonField = isin + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + + /** + * Returns the raw JSON value of [units]. + * + * Unlike [units], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("units") @ExcludeMissing fun _units(): JsonField = units + + /** + * Returns the raw JSON value of [value]. + * + * Unlike [value], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("value") @ExcludeMissing fun _value(): JsonField = value + + @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 [Aif]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Aif]. */ + class Builder internal constructor() { + + private var additionalInfo: JsonValue = JsonMissing.of() + private var isin: JsonField = JsonMissing.of() + private var name: JsonField = JsonMissing.of() + private var units: JsonField = JsonMissing.of() + private var value: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(aif: Aif) = apply { + additionalInfo = aif.additionalInfo + isin = aif.isin + name = aif.name + units = aif.units + value = aif.value + additionalProperties = aif.additionalProperties.toMutableMap() + } + + /** Additional information specific to the AIF */ + fun additionalInfo(additionalInfo: JsonValue) = apply { + this.additionalInfo = additionalInfo + } + + /** ISIN code of the AIF */ + fun isin(isin: String) = isin(JsonField.of(isin)) + + /** + * Sets [Builder.isin] to an arbitrary JSON value. + * + * You should usually call [Builder.isin] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun isin(isin: JsonField) = apply { this.isin = isin } + + /** Name of the AIF */ + fun name(name: String) = name(JsonField.of(name)) + + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun name(name: JsonField) = apply { this.name = name } + + /** Number of units held */ + fun units(units: Float) = units(JsonField.of(units)) + + /** + * Sets [Builder.units] to an arbitrary JSON value. + * + * You should usually call [Builder.units] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun units(units: JsonField) = apply { this.units = units } + + /** Current market value of the holding */ + fun value(value: Float) = value(JsonField.of(value)) + + /** + * Sets [Builder.value] to an arbitrary JSON value. + * + * You should usually call [Builder.value] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun value(value: JsonField) = apply { this.value = value } + + 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 [Aif]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Aif = + Aif( + additionalInfo, + isin, + name, + units, + value, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Aif = apply { + if (validated) { + return@apply + } + + isin() + name() + units() + value() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (isin.asKnown().isPresent) 1 else 0) + + (if (name.asKnown().isPresent) 1 else 0) + + (if (units.asKnown().isPresent) 1 else 0) + + (if (value.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Aif && + additionalInfo == other.additionalInfo && + isin == other.isin && + name == other.name && + units == other.units && + value == other.value && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(additionalInfo, isin, name, units, value, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Aif{additionalInfo=$additionalInfo, isin=$isin, name=$name, units=$units, value=$value, additionalProperties=$additionalProperties}" + } + + class CorporateBond + private constructor( + private val additionalInfo: JsonValue, + private val isin: JsonField, + private val name: JsonField, + private val units: JsonField, + private val value: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("additional_info") + @ExcludeMissing + additionalInfo: JsonValue = JsonMissing.of(), + @JsonProperty("isin") + @ExcludeMissing + isin: JsonField = JsonMissing.of(), + @JsonProperty("name") + @ExcludeMissing + name: JsonField = JsonMissing.of(), + @JsonProperty("units") + @ExcludeMissing + units: JsonField = JsonMissing.of(), + @JsonProperty("value") + @ExcludeMissing + value: JsonField = JsonMissing.of(), + ) : this(additionalInfo, isin, name, units, value, mutableMapOf()) + + /** Additional information specific to the corporate bond */ + @JsonProperty("additional_info") + @ExcludeMissing + fun _additionalInfo(): JsonValue = additionalInfo + + /** + * ISIN code of the corporate bond + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun isin(): Optional = isin.getOptional("isin") + + /** + * Name of the corporate bond + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun name(): Optional = name.getOptional("name") + + /** + * Number of units held + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun units(): Optional = units.getOptional("units") + + /** + * Current market value of the holding + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun value(): Optional = value.getOptional("value") + + /** + * Returns the raw JSON value of [isin]. + * + * Unlike [isin], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("isin") @ExcludeMissing fun _isin(): JsonField = isin + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + + /** + * Returns the raw JSON value of [units]. + * + * Unlike [units], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("units") @ExcludeMissing fun _units(): JsonField = units + + /** + * Returns the raw JSON value of [value]. + * + * Unlike [value], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("value") @ExcludeMissing fun _value(): JsonField = value + + @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 [CorporateBond]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [CorporateBond]. */ + class Builder internal constructor() { + + private var additionalInfo: JsonValue = JsonMissing.of() + private var isin: JsonField = JsonMissing.of() + private var name: JsonField = JsonMissing.of() + private var units: JsonField = JsonMissing.of() + private var value: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(corporateBond: CorporateBond) = apply { + additionalInfo = corporateBond.additionalInfo + isin = corporateBond.isin + name = corporateBond.name + units = corporateBond.units + value = corporateBond.value + additionalProperties = corporateBond.additionalProperties.toMutableMap() + } + + /** Additional information specific to the corporate bond */ + fun additionalInfo(additionalInfo: JsonValue) = apply { + this.additionalInfo = additionalInfo + } + + /** ISIN code of the corporate bond */ + fun isin(isin: String) = isin(JsonField.of(isin)) + + /** + * Sets [Builder.isin] to an arbitrary JSON value. + * + * You should usually call [Builder.isin] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun isin(isin: JsonField) = apply { this.isin = isin } + + /** Name of the corporate bond */ + fun name(name: String) = name(JsonField.of(name)) + + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun name(name: JsonField) = apply { this.name = name } + + /** Number of units held */ + fun units(units: Float) = units(JsonField.of(units)) + + /** + * Sets [Builder.units] to an arbitrary JSON value. + * + * You should usually call [Builder.units] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun units(units: JsonField) = apply { this.units = units } + + /** Current market value of the holding */ + fun value(value: Float) = value(JsonField.of(value)) + + /** + * Sets [Builder.value] to an arbitrary JSON value. + * + * You should usually call [Builder.value] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun value(value: JsonField) = apply { this.value = value } + + 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 [CorporateBond]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): CorporateBond = + CorporateBond( + additionalInfo, + isin, + name, + units, + value, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): CorporateBond = apply { + if (validated) { + return@apply + } + + isin() + name() + units() + value() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (isin.asKnown().isPresent) 1 else 0) + + (if (name.asKnown().isPresent) 1 else 0) + + (if (units.asKnown().isPresent) 1 else 0) + + (if (value.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is CorporateBond && + additionalInfo == other.additionalInfo && + isin == other.isin && + name == other.name && + units == other.units && + value == other.value && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(additionalInfo, isin, name, units, value, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "CorporateBond{additionalInfo=$additionalInfo, isin=$isin, name=$name, units=$units, value=$value, additionalProperties=$additionalProperties}" + } + + class DematMutualFund + private constructor( + private val additionalInfo: JsonValue, + private val isin: JsonField, + private val name: JsonField, + private val units: JsonField, + private val value: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("additional_info") + @ExcludeMissing + additionalInfo: JsonValue = JsonMissing.of(), + @JsonProperty("isin") + @ExcludeMissing + isin: JsonField = JsonMissing.of(), + @JsonProperty("name") + @ExcludeMissing + name: JsonField = JsonMissing.of(), + @JsonProperty("units") + @ExcludeMissing + units: JsonField = JsonMissing.of(), + @JsonProperty("value") + @ExcludeMissing + value: JsonField = JsonMissing.of(), + ) : this(additionalInfo, isin, name, units, value, mutableMapOf()) + + /** Additional information specific to the mutual fund */ + @JsonProperty("additional_info") + @ExcludeMissing + fun _additionalInfo(): JsonValue = additionalInfo + + /** + * ISIN code of the mutual fund + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun isin(): Optional = isin.getOptional("isin") + + /** + * Name of the mutual fund + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun name(): Optional = name.getOptional("name") + + /** + * Number of units held + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun units(): Optional = units.getOptional("units") + + /** + * Current market value of the holding + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun value(): Optional = value.getOptional("value") + + /** + * Returns the raw JSON value of [isin]. + * + * Unlike [isin], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("isin") @ExcludeMissing fun _isin(): JsonField = isin + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + + /** + * Returns the raw JSON value of [units]. + * + * Unlike [units], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("units") @ExcludeMissing fun _units(): JsonField = units + + /** + * Returns the raw JSON value of [value]. + * + * Unlike [value], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("value") @ExcludeMissing fun _value(): JsonField = value + + @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 [DematMutualFund]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [DematMutualFund]. */ + class Builder internal constructor() { + + private var additionalInfo: JsonValue = JsonMissing.of() + private var isin: JsonField = JsonMissing.of() + private var name: JsonField = JsonMissing.of() + private var units: JsonField = JsonMissing.of() + private var value: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(dematMutualFund: DematMutualFund) = apply { + additionalInfo = dematMutualFund.additionalInfo + isin = dematMutualFund.isin + name = dematMutualFund.name + units = dematMutualFund.units + value = dematMutualFund.value + additionalProperties = dematMutualFund.additionalProperties.toMutableMap() + } + + /** Additional information specific to the mutual fund */ + fun additionalInfo(additionalInfo: JsonValue) = apply { + this.additionalInfo = additionalInfo + } + + /** ISIN code of the mutual fund */ + fun isin(isin: String) = isin(JsonField.of(isin)) + + /** + * Sets [Builder.isin] to an arbitrary JSON value. + * + * You should usually call [Builder.isin] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun isin(isin: JsonField) = apply { this.isin = isin } + + /** Name of the mutual fund */ + fun name(name: String) = name(JsonField.of(name)) + + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun name(name: JsonField) = apply { this.name = name } + + /** Number of units held */ + fun units(units: Float) = units(JsonField.of(units)) + + /** + * Sets [Builder.units] to an arbitrary JSON value. + * + * You should usually call [Builder.units] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun units(units: JsonField) = apply { this.units = units } + + /** Current market value of the holding */ + fun value(value: Float) = value(JsonField.of(value)) + + /** + * Sets [Builder.value] to an arbitrary JSON value. + * + * You should usually call [Builder.value] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun value(value: JsonField) = apply { this.value = value } + + 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 [DematMutualFund]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): DematMutualFund = + DematMutualFund( + additionalInfo, + isin, + name, + units, + value, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): DematMutualFund = apply { + if (validated) { + return@apply + } + + isin() + name() + units() + value() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (isin.asKnown().isPresent) 1 else 0) + + (if (name.asKnown().isPresent) 1 else 0) + + (if (units.asKnown().isPresent) 1 else 0) + + (if (value.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is DematMutualFund && + additionalInfo == other.additionalInfo && + isin == other.isin && + name == other.name && + units == other.units && + value == other.value && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(additionalInfo, isin, name, units, value, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "DematMutualFund{additionalInfo=$additionalInfo, isin=$isin, name=$name, units=$units, value=$value, additionalProperties=$additionalProperties}" + } + + class Equity + private constructor( + private val additionalInfo: JsonValue, + private val isin: JsonField, + private val name: JsonField, + private val units: JsonField, + private val value: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("additional_info") + @ExcludeMissing + additionalInfo: JsonValue = JsonMissing.of(), + @JsonProperty("isin") + @ExcludeMissing + isin: JsonField = JsonMissing.of(), + @JsonProperty("name") + @ExcludeMissing + name: JsonField = JsonMissing.of(), + @JsonProperty("units") + @ExcludeMissing + units: JsonField = JsonMissing.of(), + @JsonProperty("value") + @ExcludeMissing + value: JsonField = JsonMissing.of(), + ) : this(additionalInfo, isin, name, units, value, mutableMapOf()) + + /** Additional information specific to the equity */ + @JsonProperty("additional_info") + @ExcludeMissing + fun _additionalInfo(): JsonValue = additionalInfo + + /** + * ISIN code of the equity + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun isin(): Optional = isin.getOptional("isin") + + /** + * Name of the equity + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun name(): Optional = name.getOptional("name") + + /** + * Number of units held + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun units(): Optional = units.getOptional("units") + + /** + * Current market value of the holding + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun value(): Optional = value.getOptional("value") + + /** + * Returns the raw JSON value of [isin]. + * + * Unlike [isin], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("isin") @ExcludeMissing fun _isin(): JsonField = isin + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + + /** + * Returns the raw JSON value of [units]. + * + * Unlike [units], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("units") @ExcludeMissing fun _units(): JsonField = units + + /** + * Returns the raw JSON value of [value]. + * + * Unlike [value], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("value") @ExcludeMissing fun _value(): JsonField = value + + @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 [Equity]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Equity]. */ + class Builder internal constructor() { + + private var additionalInfo: JsonValue = JsonMissing.of() + private var isin: JsonField = JsonMissing.of() + private var name: JsonField = JsonMissing.of() + private var units: JsonField = JsonMissing.of() + private var value: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(equity: Equity) = apply { + additionalInfo = equity.additionalInfo + isin = equity.isin + name = equity.name + units = equity.units + value = equity.value + additionalProperties = equity.additionalProperties.toMutableMap() + } + + /** Additional information specific to the equity */ + fun additionalInfo(additionalInfo: JsonValue) = apply { + this.additionalInfo = additionalInfo + } + + /** ISIN code of the equity */ + fun isin(isin: String) = isin(JsonField.of(isin)) + + /** + * Sets [Builder.isin] to an arbitrary JSON value. + * + * You should usually call [Builder.isin] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun isin(isin: JsonField) = apply { this.isin = isin } + + /** Name of the equity */ + fun name(name: String) = name(JsonField.of(name)) + + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun name(name: JsonField) = apply { this.name = name } + + /** Number of units held */ + fun units(units: Float) = units(JsonField.of(units)) + + /** + * Sets [Builder.units] to an arbitrary JSON value. + * + * You should usually call [Builder.units] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun units(units: JsonField) = apply { this.units = units } + + /** Current market value of the holding */ + fun value(value: Float) = value(JsonField.of(value)) + + /** + * Sets [Builder.value] to an arbitrary JSON value. + * + * You should usually call [Builder.value] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun value(value: JsonField) = apply { this.value = value } + + 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 [Equity]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Equity = + Equity( + additionalInfo, + isin, + name, + units, + value, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Equity = apply { + if (validated) { + return@apply + } + + isin() + name() + units() + value() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (isin.asKnown().isPresent) 1 else 0) + + (if (name.asKnown().isPresent) 1 else 0) + + (if (units.asKnown().isPresent) 1 else 0) + + (if (value.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Equity && + additionalInfo == other.additionalInfo && + isin == other.isin && + name == other.name && + units == other.units && + value == other.value && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(additionalInfo, isin, name, units, value, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Equity{additionalInfo=$additionalInfo, isin=$isin, name=$name, units=$units, value=$value, additionalProperties=$additionalProperties}" + } + + class GovernmentSecurity + private constructor( + private val additionalInfo: JsonValue, + private val isin: JsonField, + private val name: JsonField, + private val units: JsonField, + private val value: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("additional_info") + @ExcludeMissing + additionalInfo: JsonValue = JsonMissing.of(), + @JsonProperty("isin") + @ExcludeMissing + isin: JsonField = JsonMissing.of(), + @JsonProperty("name") + @ExcludeMissing + name: JsonField = JsonMissing.of(), + @JsonProperty("units") + @ExcludeMissing + units: JsonField = JsonMissing.of(), + @JsonProperty("value") + @ExcludeMissing + value: JsonField = JsonMissing.of(), + ) : this(additionalInfo, isin, name, units, value, mutableMapOf()) + + /** Additional information specific to the government security */ + @JsonProperty("additional_info") + @ExcludeMissing + fun _additionalInfo(): JsonValue = additionalInfo + + /** + * ISIN code of the government security + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun isin(): Optional = isin.getOptional("isin") + + /** + * Name of the government security + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun name(): Optional = name.getOptional("name") + + /** + * Number of units held + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun units(): Optional = units.getOptional("units") + + /** + * Current market value of the holding + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun value(): Optional = value.getOptional("value") + + /** + * Returns the raw JSON value of [isin]. + * + * Unlike [isin], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("isin") @ExcludeMissing fun _isin(): JsonField = isin + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + + /** + * Returns the raw JSON value of [units]. + * + * Unlike [units], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("units") @ExcludeMissing fun _units(): JsonField = units + + /** + * Returns the raw JSON value of [value]. + * + * Unlike [value], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("value") @ExcludeMissing fun _value(): JsonField = value + + @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 + * [GovernmentSecurity]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [GovernmentSecurity]. */ + class Builder internal constructor() { + + private var additionalInfo: JsonValue = JsonMissing.of() + private var isin: JsonField = JsonMissing.of() + private var name: JsonField = JsonMissing.of() + private var units: JsonField = JsonMissing.of() + private var value: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(governmentSecurity: GovernmentSecurity) = apply { + additionalInfo = governmentSecurity.additionalInfo + isin = governmentSecurity.isin + name = governmentSecurity.name + units = governmentSecurity.units + value = governmentSecurity.value + additionalProperties = + governmentSecurity.additionalProperties.toMutableMap() + } + + /** Additional information specific to the government security */ + fun additionalInfo(additionalInfo: JsonValue) = apply { + this.additionalInfo = additionalInfo + } + + /** ISIN code of the government security */ + fun isin(isin: String) = isin(JsonField.of(isin)) + + /** + * Sets [Builder.isin] to an arbitrary JSON value. + * + * You should usually call [Builder.isin] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun isin(isin: JsonField) = apply { this.isin = isin } + + /** Name of the government security */ + fun name(name: String) = name(JsonField.of(name)) + + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun name(name: JsonField) = apply { this.name = name } + + /** Number of units held */ + fun units(units: Float) = units(JsonField.of(units)) + + /** + * Sets [Builder.units] to an arbitrary JSON value. + * + * You should usually call [Builder.units] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun units(units: JsonField) = apply { this.units = units } + + /** Current market value of the holding */ + fun value(value: Float) = value(JsonField.of(value)) + + /** + * Sets [Builder.value] to an arbitrary JSON value. + * + * You should usually call [Builder.value] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun value(value: JsonField) = apply { this.value = value } + + 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 [GovernmentSecurity]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): GovernmentSecurity = + GovernmentSecurity( + additionalInfo, + isin, + name, + units, + value, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): GovernmentSecurity = apply { + if (validated) { + return@apply + } + + isin() + name() + units() + value() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (isin.asKnown().isPresent) 1 else 0) + + (if (name.asKnown().isPresent) 1 else 0) + + (if (units.asKnown().isPresent) 1 else 0) + + (if (value.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is GovernmentSecurity && + additionalInfo == other.additionalInfo && + isin == other.isin && + name == other.name && + units == other.units && + value == other.value && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(additionalInfo, isin, name, units, value, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "GovernmentSecurity{additionalInfo=$additionalInfo, isin=$isin, name=$name, units=$units, value=$value, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Holdings && + aifs == other.aifs && + corporateBonds == other.corporateBonds && + dematMutualFunds == other.dematMutualFunds && + equities == other.equities && + governmentSecurities == other.governmentSecurities && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + aifs, + corporateBonds, + dematMutualFunds, + equities, + governmentSecurities, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Holdings{aifs=$aifs, corporateBonds=$corporateBonds, dematMutualFunds=$dematMutualFunds, equities=$equities, governmentSecurities=$governmentSecurities, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is DematAccount && + additionalInfo == other.additionalInfo && + boId == other.boId && + clientId == other.clientId && + dematType == other.dematType && + dpId == other.dpId && + dpName == other.dpName && + holdings == other.holdings && + value == other.value && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + additionalInfo, + boId, + clientId, + dematType, + dpId, + dpName, + holdings, + value, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "DematAccount{additionalInfo=$additionalInfo, boId=$boId, clientId=$clientId, dematType=$dematType, dpId=$dpId, dpName=$dpName, holdings=$holdings, value=$value, additionalProperties=$additionalProperties}" + } + + class Insurance + private constructor( + private val lifeInsurancePolicies: JsonField>, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("life_insurance_policies") + @ExcludeMissing + lifeInsurancePolicies: JsonField> = JsonMissing.of() + ) : this(lifeInsurancePolicies, mutableMapOf()) + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun lifeInsurancePolicies(): Optional> = + lifeInsurancePolicies.getOptional("life_insurance_policies") + + /** + * Returns the raw JSON value of [lifeInsurancePolicies]. + * + * Unlike [lifeInsurancePolicies], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("life_insurance_policies") + @ExcludeMissing + fun _lifeInsurancePolicies(): JsonField> = lifeInsurancePolicies + + @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 [Insurance]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Insurance]. */ + class Builder internal constructor() { + + private var lifeInsurancePolicies: JsonField>? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(insurance: Insurance) = apply { + lifeInsurancePolicies = insurance.lifeInsurancePolicies.map { it.toMutableList() } + additionalProperties = insurance.additionalProperties.toMutableMap() + } + + fun lifeInsurancePolicies(lifeInsurancePolicies: List) = + lifeInsurancePolicies(JsonField.of(lifeInsurancePolicies)) + + /** + * Sets [Builder.lifeInsurancePolicies] to an arbitrary JSON value. + * + * You should usually call [Builder.lifeInsurancePolicies] with a well-typed + * `List` value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun lifeInsurancePolicies(lifeInsurancePolicies: JsonField>) = + apply { + this.lifeInsurancePolicies = lifeInsurancePolicies.map { it.toMutableList() } + } + + /** + * Adds a single [LifeInsurancePolicy] to [lifeInsurancePolicies]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addLifeInsurancePolicy(lifeInsurancePolicy: LifeInsurancePolicy) = apply { + lifeInsurancePolicies = + (lifeInsurancePolicies ?: JsonField.of(mutableListOf())).also { + checkKnown("lifeInsurancePolicies", it).add(lifeInsurancePolicy) + } + } + + 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 [Insurance]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Insurance = + Insurance( + (lifeInsurancePolicies ?: JsonMissing.of()).map { it.toImmutable() }, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Insurance = apply { + if (validated) { + return@apply + } + + lifeInsurancePolicies().ifPresent { it.forEach { it.validate() } } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 = + (lifeInsurancePolicies.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + class LifeInsurancePolicy + private constructor( + private val additionalInfo: JsonValue, + private val lifeAssured: JsonField, + private val policyName: JsonField, + private val policyNumber: JsonField, + private val premiumAmount: JsonField, + private val premiumFrequency: JsonField, + private val provider: JsonField, + private val status: JsonField, + private val sumAssured: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("additional_info") + @ExcludeMissing + additionalInfo: JsonValue = JsonMissing.of(), + @JsonProperty("life_assured") + @ExcludeMissing + lifeAssured: JsonField = JsonMissing.of(), + @JsonProperty("policy_name") + @ExcludeMissing + policyName: JsonField = JsonMissing.of(), + @JsonProperty("policy_number") + @ExcludeMissing + policyNumber: JsonField = JsonMissing.of(), + @JsonProperty("premium_amount") + @ExcludeMissing + premiumAmount: JsonField = JsonMissing.of(), + @JsonProperty("premium_frequency") + @ExcludeMissing + premiumFrequency: JsonField = JsonMissing.of(), + @JsonProperty("provider") + @ExcludeMissing + provider: JsonField = JsonMissing.of(), + @JsonProperty("status") + @ExcludeMissing + status: JsonField = JsonMissing.of(), + @JsonProperty("sum_assured") + @ExcludeMissing + sumAssured: JsonField = JsonMissing.of(), + ) : this( + additionalInfo, + lifeAssured, + policyName, + policyNumber, + premiumAmount, + premiumFrequency, + provider, + status, + sumAssured, + mutableMapOf(), + ) + + /** Additional information specific to the policy */ + @JsonProperty("additional_info") + @ExcludeMissing + fun _additionalInfo(): JsonValue = additionalInfo + + /** + * Name of the life assured + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun lifeAssured(): Optional = lifeAssured.getOptional("life_assured") + + /** + * Name of the insurance policy + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun policyName(): Optional = policyName.getOptional("policy_name") + + /** + * Insurance policy number + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun policyNumber(): Optional = policyNumber.getOptional("policy_number") + + /** + * Premium amount + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun premiumAmount(): Optional = premiumAmount.getOptional("premium_amount") + + /** + * Frequency of premium payment (e.g., Annual, Monthly) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun premiumFrequency(): Optional = + premiumFrequency.getOptional("premium_frequency") + + /** + * Insurance company name + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun provider(): Optional = provider.getOptional("provider") + + /** + * Status of the policy (e.g., Active, Lapsed) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun status(): Optional = status.getOptional("status") + + /** + * Sum assured amount + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun sumAssured(): Optional = sumAssured.getOptional("sum_assured") + + /** + * Returns the raw JSON value of [lifeAssured]. + * + * Unlike [lifeAssured], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("life_assured") + @ExcludeMissing + fun _lifeAssured(): JsonField = lifeAssured + + /** + * Returns the raw JSON value of [policyName]. + * + * Unlike [policyName], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("policy_name") + @ExcludeMissing + fun _policyName(): JsonField = policyName + + /** + * Returns the raw JSON value of [policyNumber]. + * + * Unlike [policyNumber], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("policy_number") + @ExcludeMissing + fun _policyNumber(): JsonField = policyNumber + + /** + * Returns the raw JSON value of [premiumAmount]. + * + * Unlike [premiumAmount], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("premium_amount") + @ExcludeMissing + fun _premiumAmount(): JsonField = premiumAmount + + /** + * Returns the raw JSON value of [premiumFrequency]. + * + * Unlike [premiumFrequency], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("premium_frequency") + @ExcludeMissing + fun _premiumFrequency(): JsonField = premiumFrequency + + /** + * Returns the raw JSON value of [provider]. + * + * Unlike [provider], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("provider") @ExcludeMissing fun _provider(): JsonField = provider + + /** + * Returns the raw JSON value of [status]. + * + * Unlike [status], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("status") @ExcludeMissing fun _status(): JsonField = status + + /** + * Returns the raw JSON value of [sumAssured]. + * + * Unlike [sumAssured], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("sum_assured") + @ExcludeMissing + fun _sumAssured(): JsonField = sumAssured + + @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 [LifeInsurancePolicy]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [LifeInsurancePolicy]. */ + class Builder internal constructor() { + + private var additionalInfo: JsonValue = JsonMissing.of() + private var lifeAssured: JsonField = JsonMissing.of() + private var policyName: JsonField = JsonMissing.of() + private var policyNumber: JsonField = JsonMissing.of() + private var premiumAmount: JsonField = JsonMissing.of() + private var premiumFrequency: JsonField = JsonMissing.of() + private var provider: JsonField = JsonMissing.of() + private var status: JsonField = JsonMissing.of() + private var sumAssured: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(lifeInsurancePolicy: LifeInsurancePolicy) = apply { + additionalInfo = lifeInsurancePolicy.additionalInfo + lifeAssured = lifeInsurancePolicy.lifeAssured + policyName = lifeInsurancePolicy.policyName + policyNumber = lifeInsurancePolicy.policyNumber + premiumAmount = lifeInsurancePolicy.premiumAmount + premiumFrequency = lifeInsurancePolicy.premiumFrequency + provider = lifeInsurancePolicy.provider + status = lifeInsurancePolicy.status + sumAssured = lifeInsurancePolicy.sumAssured + additionalProperties = lifeInsurancePolicy.additionalProperties.toMutableMap() + } + + /** Additional information specific to the policy */ + fun additionalInfo(additionalInfo: JsonValue) = apply { + this.additionalInfo = additionalInfo + } + + /** Name of the life assured */ + fun lifeAssured(lifeAssured: String) = lifeAssured(JsonField.of(lifeAssured)) + + /** + * Sets [Builder.lifeAssured] to an arbitrary JSON value. + * + * You should usually call [Builder.lifeAssured] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun lifeAssured(lifeAssured: JsonField) = apply { + this.lifeAssured = lifeAssured + } + + /** Name of the insurance policy */ + fun policyName(policyName: String) = policyName(JsonField.of(policyName)) + + /** + * Sets [Builder.policyName] to an arbitrary JSON value. + * + * You should usually call [Builder.policyName] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun policyName(policyName: JsonField) = apply { + this.policyName = policyName + } + + /** Insurance policy number */ + fun policyNumber(policyNumber: String) = policyNumber(JsonField.of(policyNumber)) + + /** + * Sets [Builder.policyNumber] to an arbitrary JSON value. + * + * You should usually call [Builder.policyNumber] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun policyNumber(policyNumber: JsonField) = apply { + this.policyNumber = policyNumber + } + + /** Premium amount */ + fun premiumAmount(premiumAmount: Float) = premiumAmount(JsonField.of(premiumAmount)) + + /** + * Sets [Builder.premiumAmount] to an arbitrary JSON value. + * + * You should usually call [Builder.premiumAmount] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun premiumAmount(premiumAmount: JsonField) = apply { + this.premiumAmount = premiumAmount + } + + /** Frequency of premium payment (e.g., Annual, Monthly) */ + fun premiumFrequency(premiumFrequency: String) = + premiumFrequency(JsonField.of(premiumFrequency)) + + /** + * Sets [Builder.premiumFrequency] to an arbitrary JSON value. + * + * You should usually call [Builder.premiumFrequency] with a well-typed [String] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun premiumFrequency(premiumFrequency: JsonField) = apply { + this.premiumFrequency = premiumFrequency + } + + /** Insurance company name */ + fun provider(provider: String) = provider(JsonField.of(provider)) + + /** + * Sets [Builder.provider] to an arbitrary JSON value. + * + * You should usually call [Builder.provider] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun provider(provider: JsonField) = apply { this.provider = provider } + + /** Status of the policy (e.g., Active, Lapsed) */ + fun status(status: String) = status(JsonField.of(status)) + + /** + * Sets [Builder.status] to an arbitrary JSON value. + * + * You should usually call [Builder.status] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun status(status: JsonField) = apply { this.status = status } + + /** Sum assured amount */ + fun sumAssured(sumAssured: Float) = sumAssured(JsonField.of(sumAssured)) + + /** + * Sets [Builder.sumAssured] to an arbitrary JSON value. + * + * You should usually call [Builder.sumAssured] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun sumAssured(sumAssured: JsonField) = apply { + this.sumAssured = sumAssured + } + + 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 [LifeInsurancePolicy]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): LifeInsurancePolicy = + LifeInsurancePolicy( + additionalInfo, + lifeAssured, + policyName, + policyNumber, + premiumAmount, + premiumFrequency, + provider, + status, + sumAssured, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): LifeInsurancePolicy = apply { + if (validated) { + return@apply + } + + lifeAssured() + policyName() + policyNumber() + premiumAmount() + premiumFrequency() + provider() + status() + sumAssured() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (lifeAssured.asKnown().isPresent) 1 else 0) + + (if (policyName.asKnown().isPresent) 1 else 0) + + (if (policyNumber.asKnown().isPresent) 1 else 0) + + (if (premiumAmount.asKnown().isPresent) 1 else 0) + + (if (premiumFrequency.asKnown().isPresent) 1 else 0) + + (if (provider.asKnown().isPresent) 1 else 0) + + (if (status.asKnown().isPresent) 1 else 0) + + (if (sumAssured.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is LifeInsurancePolicy && + additionalInfo == other.additionalInfo && + lifeAssured == other.lifeAssured && + policyName == other.policyName && + policyNumber == other.policyNumber && + premiumAmount == other.premiumAmount && + premiumFrequency == other.premiumFrequency && + provider == other.provider && + status == other.status && + sumAssured == other.sumAssured && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + additionalInfo, + lifeAssured, + policyName, + policyNumber, + premiumAmount, + premiumFrequency, + provider, + status, + sumAssured, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "LifeInsurancePolicy{additionalInfo=$additionalInfo, lifeAssured=$lifeAssured, policyName=$policyName, policyNumber=$policyNumber, premiumAmount=$premiumAmount, premiumFrequency=$premiumFrequency, provider=$provider, status=$status, sumAssured=$sumAssured, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Insurance && + lifeInsurancePolicies == other.lifeInsurancePolicies && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(lifeInsurancePolicies, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Insurance{lifeInsurancePolicies=$lifeInsurancePolicies, additionalProperties=$additionalProperties}" + } + + class Investor + private constructor( + private val address: JsonField, + private val casId: JsonField, + private val email: JsonField, + private val mobile: JsonField, + private val name: JsonField, + private val pan: JsonField, + private val pincode: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("address") @ExcludeMissing address: JsonField = JsonMissing.of(), + @JsonProperty("cas_id") @ExcludeMissing casId: JsonField = JsonMissing.of(), + @JsonProperty("email") @ExcludeMissing email: JsonField = JsonMissing.of(), + @JsonProperty("mobile") @ExcludeMissing mobile: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("pan") @ExcludeMissing pan: JsonField = JsonMissing.of(), + @JsonProperty("pincode") @ExcludeMissing pincode: JsonField = JsonMissing.of(), + ) : this(address, casId, email, mobile, name, pan, pincode, mutableMapOf()) + + /** + * Address of the investor + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun address(): Optional = address.getOptional("address") + + /** + * CAS ID of the investor (only for NSDL and CDSL) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun casId(): Optional = casId.getOptional("cas_id") + + /** + * Email address of the investor + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun email(): Optional = email.getOptional("email") + + /** + * Mobile number of the investor + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun mobile(): Optional = mobile.getOptional("mobile") + + /** + * Name of the investor + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun name(): Optional = name.getOptional("name") + + /** + * PAN (Permanent Account Number) of the investor + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun pan(): Optional = pan.getOptional("pan") + + /** + * Postal code of the investor's address + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun pincode(): Optional = pincode.getOptional("pincode") + + /** + * Returns the raw JSON value of [address]. + * + * Unlike [address], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("address") @ExcludeMissing fun _address(): JsonField = address + + /** + * Returns the raw JSON value of [casId]. + * + * Unlike [casId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("cas_id") @ExcludeMissing fun _casId(): JsonField = casId + + /** + * Returns the raw JSON value of [email]. + * + * Unlike [email], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("email") @ExcludeMissing fun _email(): JsonField = email + + /** + * Returns the raw JSON value of [mobile]. + * + * Unlike [mobile], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("mobile") @ExcludeMissing fun _mobile(): JsonField = mobile + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + + /** + * Returns the raw JSON value of [pan]. + * + * Unlike [pan], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("pan") @ExcludeMissing fun _pan(): JsonField = pan + + /** + * Returns the raw JSON value of [pincode]. + * + * Unlike [pincode], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("pincode") @ExcludeMissing fun _pincode(): JsonField = pincode + + @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 [Investor]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Investor]. */ + class Builder internal constructor() { + + private var address: JsonField = JsonMissing.of() + private var casId: JsonField = JsonMissing.of() + private var email: JsonField = JsonMissing.of() + private var mobile: JsonField = JsonMissing.of() + private var name: JsonField = JsonMissing.of() + private var pan: JsonField = JsonMissing.of() + private var pincode: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(investor: Investor) = apply { + address = investor.address + casId = investor.casId + email = investor.email + mobile = investor.mobile + name = investor.name + pan = investor.pan + pincode = investor.pincode + additionalProperties = investor.additionalProperties.toMutableMap() + } + + /** Address of the investor */ + fun address(address: String) = address(JsonField.of(address)) + + /** + * Sets [Builder.address] to an arbitrary JSON value. + * + * You should usually call [Builder.address] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun address(address: JsonField) = apply { this.address = address } + + /** CAS ID of the investor (only for NSDL and CDSL) */ + fun casId(casId: String) = casId(JsonField.of(casId)) + + /** + * Sets [Builder.casId] to an arbitrary JSON value. + * + * You should usually call [Builder.casId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun casId(casId: JsonField) = apply { this.casId = casId } + + /** Email address of the investor */ + fun email(email: String) = email(JsonField.of(email)) + + /** + * Sets [Builder.email] to an arbitrary JSON value. + * + * You should usually call [Builder.email] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun email(email: JsonField) = apply { this.email = email } + + /** Mobile number of the investor */ + fun mobile(mobile: String) = mobile(JsonField.of(mobile)) + + /** + * Sets [Builder.mobile] to an arbitrary JSON value. + * + * You should usually call [Builder.mobile] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun mobile(mobile: JsonField) = apply { this.mobile = mobile } + + /** Name of the investor */ + fun name(name: String) = name(JsonField.of(name)) + + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun name(name: JsonField) = apply { this.name = name } + + /** PAN (Permanent Account Number) of the investor */ + fun pan(pan: String) = pan(JsonField.of(pan)) + + /** + * Sets [Builder.pan] to an arbitrary JSON value. + * + * You should usually call [Builder.pan] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun pan(pan: JsonField) = apply { this.pan = pan } + + /** Postal code of the investor's address */ + fun pincode(pincode: String) = pincode(JsonField.of(pincode)) + + /** + * Sets [Builder.pincode] to an arbitrary JSON value. + * + * You should usually call [Builder.pincode] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun pincode(pincode: JsonField) = apply { this.pincode = pincode } + + 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 [Investor]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Investor = + Investor( + address, + casId, + email, + mobile, + name, + pan, + pincode, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Investor = apply { + if (validated) { + return@apply + } + + address() + casId() + email() + mobile() + name() + pan() + pincode() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (address.asKnown().isPresent) 1 else 0) + + (if (casId.asKnown().isPresent) 1 else 0) + + (if (email.asKnown().isPresent) 1 else 0) + + (if (mobile.asKnown().isPresent) 1 else 0) + + (if (name.asKnown().isPresent) 1 else 0) + + (if (pan.asKnown().isPresent) 1 else 0) + + (if (pincode.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Investor && + address == other.address && + casId == other.casId && + email == other.email && + mobile == other.mobile && + name == other.name && + pan == other.pan && + pincode == other.pincode && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(address, casId, email, mobile, name, pan, pincode, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Investor{address=$address, casId=$casId, email=$email, mobile=$mobile, name=$name, pan=$pan, pincode=$pincode, additionalProperties=$additionalProperties}" + } + + class Meta + private constructor( + private val casType: JsonField, + private val generatedAt: JsonField, + private val statementPeriod: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("cas_type") + @ExcludeMissing + casType: JsonField = JsonMissing.of(), + @JsonProperty("generated_at") + @ExcludeMissing + generatedAt: JsonField = JsonMissing.of(), + @JsonProperty("statement_period") + @ExcludeMissing + statementPeriod: JsonField = JsonMissing.of(), + ) : this(casType, generatedAt, statementPeriod, mutableMapOf()) + + /** + * Type of CAS detected and processed + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun casType(): Optional = casType.getOptional("cas_type") + + /** + * Timestamp when the response was generated + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun generatedAt(): Optional = generatedAt.getOptional("generated_at") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun statementPeriod(): Optional = + statementPeriod.getOptional("statement_period") + + /** + * Returns the raw JSON value of [casType]. + * + * Unlike [casType], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("cas_type") @ExcludeMissing fun _casType(): JsonField = casType + + /** + * Returns the raw JSON value of [generatedAt]. + * + * Unlike [generatedAt], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("generated_at") + @ExcludeMissing + fun _generatedAt(): JsonField = generatedAt + + /** + * Returns the raw JSON value of [statementPeriod]. + * + * Unlike [statementPeriod], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("statement_period") + @ExcludeMissing + fun _statementPeriod(): JsonField = statementPeriod + + @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 [Meta]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Meta]. */ + class Builder internal constructor() { + + private var casType: JsonField = JsonMissing.of() + private var generatedAt: JsonField = JsonMissing.of() + private var statementPeriod: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(meta: Meta) = apply { + casType = meta.casType + generatedAt = meta.generatedAt + statementPeriod = meta.statementPeriod + additionalProperties = meta.additionalProperties.toMutableMap() + } + + /** Type of CAS detected and processed */ + fun casType(casType: CasType) = casType(JsonField.of(casType)) + + /** + * Sets [Builder.casType] to an arbitrary JSON value. + * + * You should usually call [Builder.casType] with a well-typed [CasType] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun casType(casType: JsonField) = apply { this.casType = casType } + + /** Timestamp when the response was generated */ + fun generatedAt(generatedAt: OffsetDateTime) = generatedAt(JsonField.of(generatedAt)) + + /** + * Sets [Builder.generatedAt] to an arbitrary JSON value. + * + * You should usually call [Builder.generatedAt] with a well-typed [OffsetDateTime] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun generatedAt(generatedAt: JsonField) = apply { + this.generatedAt = generatedAt + } + + fun statementPeriod(statementPeriod: StatementPeriod) = + statementPeriod(JsonField.of(statementPeriod)) + + /** + * Sets [Builder.statementPeriod] to an arbitrary JSON value. + * + * You should usually call [Builder.statementPeriod] with a well-typed [StatementPeriod] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun statementPeriod(statementPeriod: JsonField) = apply { + this.statementPeriod = statementPeriod + } + + 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 [Meta]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Meta = + Meta(casType, generatedAt, statementPeriod, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Meta = apply { + if (validated) { + return@apply + } + + casType().ifPresent { it.validate() } + generatedAt() + statementPeriod().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 = + (casType.asKnown().getOrNull()?.validity() ?: 0) + + (if (generatedAt.asKnown().isPresent) 1 else 0) + + (statementPeriod.asKnown().getOrNull()?.validity() ?: 0) + + /** Type of CAS detected and processed */ + class CasType @JsonCreator private constructor(private val value: JsonField) : + Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is + * on an older version than the API, then the API may respond with new members that the + * SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val NSDL = of("NSDL") + + @JvmField val CDSL = of("CDSL") + + @JvmField val CAMS_KFINTECH = of("CAMS_KFINTECH") + + @JvmStatic fun of(value: String) = CasType(JsonField.of(value)) + } + + /** An enum containing [CasType]'s known values. */ + enum class Known { + NSDL, + CDSL, + CAMS_KFINTECH, + } + + /** + * An enum containing [CasType]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [CasType] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if + * the SDK is on an older version than the API, then the API may respond with new + * members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + NSDL, + CDSL, + CAMS_KFINTECH, + /** + * An enum member indicating that [CasType] was instantiated with an unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you + * want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + NSDL -> Value.NSDL + CDSL -> Value.CDSL + CAMS_KFINTECH -> Value.CAMS_KFINTECH + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and + * don't want to throw for the unknown case. + * + * @throws CasParserInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + NSDL -> Known.NSDL + CDSL -> Known.CDSL + CAMS_KFINTECH -> Known.CAMS_KFINTECH + else -> throw CasParserInvalidDataException("Unknown CasType: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws CasParserInvalidDataException if this class instance's value does not have + * the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CasParserInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): CasType = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is CasType && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + class StatementPeriod + private constructor( + private val from: JsonField, + private val to: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("from") @ExcludeMissing from: JsonField = JsonMissing.of(), + @JsonProperty("to") @ExcludeMissing to: JsonField = JsonMissing.of(), + ) : this(from, to, mutableMapOf()) + + /** + * Start date of the statement period + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun from(): Optional = from.getOptional("from") + + /** + * End date of the statement period + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun to(): Optional = to.getOptional("to") + + /** + * Returns the raw JSON value of [from]. + * + * Unlike [from], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("from") @ExcludeMissing fun _from(): JsonField = from + + /** + * Returns the raw JSON value of [to]. + * + * Unlike [to], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("to") @ExcludeMissing fun _to(): JsonField = to + + @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 [StatementPeriod]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [StatementPeriod]. */ + class Builder internal constructor() { + + private var from: JsonField = JsonMissing.of() + private var to: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(statementPeriod: StatementPeriod) = apply { + from = statementPeriod.from + to = statementPeriod.to + additionalProperties = statementPeriod.additionalProperties.toMutableMap() + } + + /** Start date of the statement period */ + fun from(from: LocalDate) = from(JsonField.of(from)) + + /** + * Sets [Builder.from] to an arbitrary JSON value. + * + * You should usually call [Builder.from] with a well-typed [LocalDate] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun from(from: JsonField) = apply { this.from = from } + + /** End date of the statement period */ + fun to(to: LocalDate) = to(JsonField.of(to)) + + /** + * Sets [Builder.to] to an arbitrary JSON value. + * + * You should usually call [Builder.to] with a well-typed [LocalDate] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun to(to: JsonField) = apply { this.to = to } + + 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 [StatementPeriod]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): StatementPeriod = + StatementPeriod(from, to, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): StatementPeriod = apply { + if (validated) { + return@apply + } + + from() + to() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (from.asKnown().isPresent) 1 else 0) + (if (to.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is StatementPeriod && + from == other.from && + to == other.to && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(from, to, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "StatementPeriod{from=$from, to=$to, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Meta && + casType == other.casType && + generatedAt == other.generatedAt && + statementPeriod == other.statementPeriod && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(casType, generatedAt, statementPeriod, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Meta{casType=$casType, generatedAt=$generatedAt, statementPeriod=$statementPeriod, additionalProperties=$additionalProperties}" + } + + class MutualFund + private constructor( + private val additionalInfo: JsonField, + private val amc: JsonField, + private val folioNumber: JsonField, + private val registrar: JsonField, + private val schemes: JsonField>, + private val value: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("additional_info") + @ExcludeMissing + additionalInfo: JsonField = JsonMissing.of(), + @JsonProperty("amc") @ExcludeMissing amc: JsonField = JsonMissing.of(), + @JsonProperty("folio_number") + @ExcludeMissing + folioNumber: JsonField = JsonMissing.of(), + @JsonProperty("registrar") + @ExcludeMissing + registrar: JsonField = JsonMissing.of(), + @JsonProperty("schemes") + @ExcludeMissing + schemes: JsonField> = JsonMissing.of(), + @JsonProperty("value") @ExcludeMissing value: JsonField = JsonMissing.of(), + ) : this(additionalInfo, amc, folioNumber, registrar, schemes, value, mutableMapOf()) + + /** + * Additional folio information + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun additionalInfo(): Optional = + additionalInfo.getOptional("additional_info") + + /** + * Asset Management Company name + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun amc(): Optional = amc.getOptional("amc") + + /** + * Folio number + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun folioNumber(): Optional = folioNumber.getOptional("folio_number") + + /** + * Registrar and Transfer Agent name + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun registrar(): Optional = registrar.getOptional("registrar") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun schemes(): Optional> = schemes.getOptional("schemes") + + /** + * Total value of the folio + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun value(): Optional = value.getOptional("value") + + /** + * Returns the raw JSON value of [additionalInfo]. + * + * Unlike [additionalInfo], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("additional_info") + @ExcludeMissing + fun _additionalInfo(): JsonField = additionalInfo + + /** + * Returns the raw JSON value of [amc]. + * + * Unlike [amc], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("amc") @ExcludeMissing fun _amc(): JsonField = amc + + /** + * Returns the raw JSON value of [folioNumber]. + * + * Unlike [folioNumber], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("folio_number") + @ExcludeMissing + fun _folioNumber(): JsonField = folioNumber + + /** + * Returns the raw JSON value of [registrar]. + * + * Unlike [registrar], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("registrar") @ExcludeMissing fun _registrar(): JsonField = registrar + + /** + * Returns the raw JSON value of [schemes]. + * + * Unlike [schemes], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("schemes") @ExcludeMissing fun _schemes(): JsonField> = schemes + + /** + * Returns the raw JSON value of [value]. + * + * Unlike [value], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("value") @ExcludeMissing fun _value(): JsonField = value + + @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 [MutualFund]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [MutualFund]. */ + class Builder internal constructor() { + + private var additionalInfo: JsonField = JsonMissing.of() + private var amc: JsonField = JsonMissing.of() + private var folioNumber: JsonField = JsonMissing.of() + private var registrar: JsonField = JsonMissing.of() + private var schemes: JsonField>? = null + private var value: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(mutualFund: MutualFund) = apply { + additionalInfo = mutualFund.additionalInfo + amc = mutualFund.amc + folioNumber = mutualFund.folioNumber + registrar = mutualFund.registrar + schemes = mutualFund.schemes.map { it.toMutableList() } + value = mutualFund.value + additionalProperties = mutualFund.additionalProperties.toMutableMap() + } + + /** Additional folio information */ + fun additionalInfo(additionalInfo: AdditionalInfo) = + additionalInfo(JsonField.of(additionalInfo)) + + /** + * Sets [Builder.additionalInfo] to an arbitrary JSON value. + * + * You should usually call [Builder.additionalInfo] with a well-typed [AdditionalInfo] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun additionalInfo(additionalInfo: JsonField) = apply { + this.additionalInfo = additionalInfo + } + + /** Asset Management Company name */ + fun amc(amc: String) = amc(JsonField.of(amc)) + + /** + * Sets [Builder.amc] to an arbitrary JSON value. + * + * You should usually call [Builder.amc] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun amc(amc: JsonField) = apply { this.amc = amc } + + /** Folio number */ + fun folioNumber(folioNumber: String) = folioNumber(JsonField.of(folioNumber)) + + /** + * Sets [Builder.folioNumber] to an arbitrary JSON value. + * + * You should usually call [Builder.folioNumber] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun folioNumber(folioNumber: JsonField) = apply { + this.folioNumber = folioNumber + } + + /** Registrar and Transfer Agent name */ + fun registrar(registrar: String) = registrar(JsonField.of(registrar)) + + /** + * Sets [Builder.registrar] to an arbitrary JSON value. + * + * You should usually call [Builder.registrar] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun registrar(registrar: JsonField) = apply { this.registrar = registrar } + + fun schemes(schemes: List) = schemes(JsonField.of(schemes)) + + /** + * Sets [Builder.schemes] to an arbitrary JSON value. + * + * You should usually call [Builder.schemes] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun schemes(schemes: JsonField>) = apply { + this.schemes = schemes.map { it.toMutableList() } + } + + /** + * Adds a single [Scheme] to [schemes]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addScheme(scheme: Scheme) = apply { + schemes = + (schemes ?: JsonField.of(mutableListOf())).also { + checkKnown("schemes", it).add(scheme) + } + } + + /** Total value of the folio */ + fun value(value: Float) = value(JsonField.of(value)) + + /** + * Sets [Builder.value] to an arbitrary JSON value. + * + * You should usually call [Builder.value] with a well-typed [Float] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun value(value: JsonField) = apply { this.value = value } + + 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 [MutualFund]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): MutualFund = + MutualFund( + additionalInfo, + amc, + folioNumber, + registrar, + (schemes ?: JsonMissing.of()).map { it.toImmutable() }, + value, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): MutualFund = apply { + if (validated) { + return@apply + } + + additionalInfo().ifPresent { it.validate() } + amc() + folioNumber() + registrar() + schemes().ifPresent { it.forEach { it.validate() } } + value() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 = + (additionalInfo.asKnown().getOrNull()?.validity() ?: 0) + + (if (amc.asKnown().isPresent) 1 else 0) + + (if (folioNumber.asKnown().isPresent) 1 else 0) + + (if (registrar.asKnown().isPresent) 1 else 0) + + (schemes.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (value.asKnown().isPresent) 1 else 0) + + /** Additional folio information */ + class AdditionalInfo + private constructor( + private val kyc: JsonField, + private val pan: JsonField, + private val pankyc: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("kyc") @ExcludeMissing kyc: JsonField = JsonMissing.of(), + @JsonProperty("pan") @ExcludeMissing pan: JsonField = JsonMissing.of(), + @JsonProperty("pankyc") @ExcludeMissing pankyc: JsonField = JsonMissing.of(), + ) : this(kyc, pan, pankyc, mutableMapOf()) + + /** + * KYC status of the folio + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun kyc(): Optional = kyc.getOptional("kyc") + + /** + * PAN associated with the folio + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun pan(): Optional = pan.getOptional("pan") + + /** + * PAN KYC status + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun pankyc(): Optional = pankyc.getOptional("pankyc") + + /** + * Returns the raw JSON value of [kyc]. + * + * Unlike [kyc], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("kyc") @ExcludeMissing fun _kyc(): JsonField = kyc + + /** + * Returns the raw JSON value of [pan]. + * + * Unlike [pan], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("pan") @ExcludeMissing fun _pan(): JsonField = pan + + /** + * Returns the raw JSON value of [pankyc]. + * + * Unlike [pankyc], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("pankyc") @ExcludeMissing fun _pankyc(): JsonField = pankyc + + @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 [AdditionalInfo]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AdditionalInfo]. */ + class Builder internal constructor() { + + private var kyc: JsonField = JsonMissing.of() + private var pan: JsonField = JsonMissing.of() + private var pankyc: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(additionalInfo: AdditionalInfo) = apply { + kyc = additionalInfo.kyc + pan = additionalInfo.pan + pankyc = additionalInfo.pankyc + additionalProperties = additionalInfo.additionalProperties.toMutableMap() + } + + /** KYC status of the folio */ + fun kyc(kyc: String) = kyc(JsonField.of(kyc)) + + /** + * Sets [Builder.kyc] to an arbitrary JSON value. + * + * You should usually call [Builder.kyc] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun kyc(kyc: JsonField) = apply { this.kyc = kyc } + + /** PAN associated with the folio */ + fun pan(pan: String) = pan(JsonField.of(pan)) + + /** + * Sets [Builder.pan] to an arbitrary JSON value. + * + * You should usually call [Builder.pan] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun pan(pan: JsonField) = apply { this.pan = pan } + + /** PAN KYC status */ + fun pankyc(pankyc: String) = pankyc(JsonField.of(pankyc)) + + /** + * Sets [Builder.pankyc] to an arbitrary JSON value. + * + * You should usually call [Builder.pankyc] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun pankyc(pankyc: JsonField) = apply { this.pankyc = pankyc } + + 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 [AdditionalInfo]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): AdditionalInfo = + AdditionalInfo(kyc, pan, pankyc, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): AdditionalInfo = apply { + if (validated) { + return@apply + } + + kyc() + pan() + pankyc() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (kyc.asKnown().isPresent) 1 else 0) + + (if (pan.asKnown().isPresent) 1 else 0) + + (if (pankyc.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AdditionalInfo && + kyc == other.kyc && + pan == other.pan && + pankyc == other.pankyc && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(kyc, pan, pankyc, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AdditionalInfo{kyc=$kyc, pan=$pan, pankyc=$pankyc, additionalProperties=$additionalProperties}" + } + + class Scheme + private constructor( + private val additionalInfo: JsonField, + private val cost: JsonField, + private val gain: JsonField, + private val isin: JsonField, + private val name: JsonField, + private val nav: JsonField, + private val nominees: JsonField>, + private val transactions: JsonField>, + private val type: JsonField, + private val units: JsonField, + private val value: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("additional_info") + @ExcludeMissing + additionalInfo: JsonField = JsonMissing.of(), + @JsonProperty("cost") @ExcludeMissing cost: JsonField = JsonMissing.of(), + @JsonProperty("gain") @ExcludeMissing gain: JsonField = JsonMissing.of(), + @JsonProperty("isin") @ExcludeMissing isin: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("nav") @ExcludeMissing nav: JsonField = JsonMissing.of(), + @JsonProperty("nominees") + @ExcludeMissing + nominees: JsonField> = JsonMissing.of(), + @JsonProperty("transactions") + @ExcludeMissing + transactions: JsonField> = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), + @JsonProperty("units") @ExcludeMissing units: JsonField = JsonMissing.of(), + @JsonProperty("value") @ExcludeMissing value: JsonField = JsonMissing.of(), + ) : this( + additionalInfo, + cost, + gain, + isin, + name, + nav, + nominees, + transactions, + type, + units, + value, + mutableMapOf(), + ) + + /** + * Additional information specific to the scheme + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun additionalInfo(): Optional = + additionalInfo.getOptional("additional_info") + + /** + * Cost of investment + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun cost(): Optional = cost.getOptional("cost") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun gain(): Optional = gain.getOptional("gain") + + /** + * ISIN code of the scheme + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun isin(): Optional = isin.getOptional("isin") + + /** + * Scheme name + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun name(): Optional = name.getOptional("name") + + /** + * Net Asset Value per unit + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun nav(): Optional = nav.getOptional("nav") + + /** + * List of nominees + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun nominees(): Optional> = nominees.getOptional("nominees") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun transactions(): Optional> = + transactions.getOptional("transactions") + + /** + * Type of mutual fund scheme + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun type(): Optional = type.getOptional("type") + + /** + * Number of units held + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun units(): Optional = units.getOptional("units") + + /** + * Current market value of the holding + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun value(): Optional = value.getOptional("value") + + /** + * Returns the raw JSON value of [additionalInfo]. + * + * Unlike [additionalInfo], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("additional_info") + @ExcludeMissing + fun _additionalInfo(): JsonField = additionalInfo + + /** + * Returns the raw JSON value of [cost]. + * + * Unlike [cost], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("cost") @ExcludeMissing fun _cost(): JsonField = cost + + /** + * Returns the raw JSON value of [gain]. + * + * Unlike [gain], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("gain") @ExcludeMissing fun _gain(): JsonField = gain + + /** + * Returns the raw JSON value of [isin]. + * + * Unlike [isin], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("isin") @ExcludeMissing fun _isin(): JsonField = isin + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + + /** + * Returns the raw JSON value of [nav]. + * + * Unlike [nav], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("nav") @ExcludeMissing fun _nav(): JsonField = nav + + /** + * Returns the raw JSON value of [nominees]. + * + * Unlike [nominees], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("nominees") + @ExcludeMissing + fun _nominees(): JsonField> = nominees + + /** + * Returns the raw JSON value of [transactions]. + * + * Unlike [transactions], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("transactions") + @ExcludeMissing + fun _transactions(): JsonField> = transactions + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + + /** + * Returns the raw JSON value of [units]. + * + * Unlike [units], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("units") @ExcludeMissing fun _units(): JsonField = units + + /** + * Returns the raw JSON value of [value]. + * + * Unlike [value], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("value") @ExcludeMissing fun _value(): JsonField = value + + @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 [Scheme]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Scheme]. */ + class Builder internal constructor() { + + private var additionalInfo: JsonField = JsonMissing.of() + private var cost: JsonField = JsonMissing.of() + private var gain: JsonField = JsonMissing.of() + private var isin: JsonField = JsonMissing.of() + private var name: JsonField = JsonMissing.of() + private var nav: JsonField = JsonMissing.of() + private var nominees: JsonField>? = null + private var transactions: JsonField>? = null + private var type: JsonField = JsonMissing.of() + private var units: JsonField = JsonMissing.of() + private var value: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(scheme: Scheme) = apply { + additionalInfo = scheme.additionalInfo + cost = scheme.cost + gain = scheme.gain + isin = scheme.isin + name = scheme.name + nav = scheme.nav + nominees = scheme.nominees.map { it.toMutableList() } + transactions = scheme.transactions.map { it.toMutableList() } + type = scheme.type + units = scheme.units + value = scheme.value + additionalProperties = scheme.additionalProperties.toMutableMap() + } + + /** Additional information specific to the scheme */ + fun additionalInfo(additionalInfo: AdditionalInfo) = + additionalInfo(JsonField.of(additionalInfo)) + + /** + * Sets [Builder.additionalInfo] to an arbitrary JSON value. + * + * You should usually call [Builder.additionalInfo] with a well-typed + * [AdditionalInfo] value instead. This method is primarily for setting the field to + * an undocumented or not yet supported value. + */ + fun additionalInfo(additionalInfo: JsonField) = apply { + this.additionalInfo = additionalInfo + } + + /** Cost of investment */ + fun cost(cost: Float) = cost(JsonField.of(cost)) + + /** + * Sets [Builder.cost] to an arbitrary JSON value. + * + * You should usually call [Builder.cost] with a well-typed [Float] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun cost(cost: JsonField) = apply { this.cost = cost } + + fun gain(gain: Gain) = gain(JsonField.of(gain)) + + /** + * Sets [Builder.gain] to an arbitrary JSON value. + * + * You should usually call [Builder.gain] with a well-typed [Gain] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun gain(gain: JsonField) = apply { this.gain = gain } + + /** ISIN code of the scheme */ + fun isin(isin: String) = isin(JsonField.of(isin)) + + /** + * Sets [Builder.isin] to an arbitrary JSON value. + * + * You should usually call [Builder.isin] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun isin(isin: JsonField) = apply { this.isin = isin } + + /** Scheme name */ + fun name(name: String) = name(JsonField.of(name)) + + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun name(name: JsonField) = apply { this.name = name } + + /** Net Asset Value per unit */ + fun nav(nav: Float) = nav(JsonField.of(nav)) + + /** + * Sets [Builder.nav] to an arbitrary JSON value. + * + * You should usually call [Builder.nav] with a well-typed [Float] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun nav(nav: JsonField) = apply { this.nav = nav } + + /** List of nominees */ + fun nominees(nominees: List) = nominees(JsonField.of(nominees)) + + /** + * Sets [Builder.nominees] to an arbitrary JSON value. + * + * You should usually call [Builder.nominees] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun nominees(nominees: JsonField>) = apply { + this.nominees = nominees.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [nominees]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addNominee(nominee: String) = apply { + nominees = + (nominees ?: JsonField.of(mutableListOf())).also { + checkKnown("nominees", it).add(nominee) + } + } + + fun transactions(transactions: List) = + transactions(JsonField.of(transactions)) + + /** + * Sets [Builder.transactions] to an arbitrary JSON value. + * + * You should usually call [Builder.transactions] with a well-typed + * `List` value instead. This method is primarily for setting the field + * to an undocumented or not yet supported value. + */ + fun transactions(transactions: JsonField>) = apply { + this.transactions = transactions.map { it.toMutableList() } + } + + /** + * Adds a single [Transaction] to [transactions]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addTransaction(transaction: Transaction) = apply { + transactions = + (transactions ?: JsonField.of(mutableListOf())).also { + checkKnown("transactions", it).add(transaction) + } + } + + /** Type of mutual fund scheme */ + fun type(type: Type) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonField) = apply { this.type = type } + + /** Number of units held */ + fun units(units: Float) = units(JsonField.of(units)) + + /** + * Sets [Builder.units] to an arbitrary JSON value. + * + * You should usually call [Builder.units] with a well-typed [Float] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun units(units: JsonField) = apply { this.units = units } + + /** Current market value of the holding */ + fun value(value: Float) = value(JsonField.of(value)) + + /** + * Sets [Builder.value] to an arbitrary JSON value. + * + * You should usually call [Builder.value] with a well-typed [Float] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun value(value: JsonField) = apply { this.value = value } + + 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 [Scheme]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Scheme = + Scheme( + additionalInfo, + cost, + gain, + isin, + name, + nav, + (nominees ?: JsonMissing.of()).map { it.toImmutable() }, + (transactions ?: JsonMissing.of()).map { it.toImmutable() }, + type, + units, + value, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Scheme = apply { + if (validated) { + return@apply + } + + additionalInfo().ifPresent { it.validate() } + cost() + gain().ifPresent { it.validate() } + isin() + name() + nav() + nominees() + transactions().ifPresent { it.forEach { it.validate() } } + type().ifPresent { it.validate() } + units() + value() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 = + (additionalInfo.asKnown().getOrNull()?.validity() ?: 0) + + (if (cost.asKnown().isPresent) 1 else 0) + + (gain.asKnown().getOrNull()?.validity() ?: 0) + + (if (isin.asKnown().isPresent) 1 else 0) + + (if (name.asKnown().isPresent) 1 else 0) + + (if (nav.asKnown().isPresent) 1 else 0) + + (nominees.asKnown().getOrNull()?.size ?: 0) + + (transactions.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (type.asKnown().getOrNull()?.validity() ?: 0) + + (if (units.asKnown().isPresent) 1 else 0) + + (if (value.asKnown().isPresent) 1 else 0) + + /** Additional information specific to the scheme */ + class AdditionalInfo + private constructor( + private val advisor: JsonField, + private val amfi: JsonField, + private val closeUnits: JsonField, + private val openUnits: JsonField, + private val rtaCode: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("advisor") + @ExcludeMissing + advisor: JsonField = JsonMissing.of(), + @JsonProperty("amfi") + @ExcludeMissing + amfi: JsonField = JsonMissing.of(), + @JsonProperty("close_units") + @ExcludeMissing + closeUnits: JsonField = JsonMissing.of(), + @JsonProperty("open_units") + @ExcludeMissing + openUnits: JsonField = JsonMissing.of(), + @JsonProperty("rta_code") + @ExcludeMissing + rtaCode: JsonField = JsonMissing.of(), + ) : this(advisor, amfi, closeUnits, openUnits, rtaCode, mutableMapOf()) + + /** + * Financial advisor name (CAMS/KFintech) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun advisor(): Optional = advisor.getOptional("advisor") + + /** + * AMFI code for the scheme (CAMS/KFintech) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun amfi(): Optional = amfi.getOptional("amfi") + + /** + * Closing balance units (CAMS/KFintech) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun closeUnits(): Optional = closeUnits.getOptional("close_units") + + /** + * Opening balance units (CAMS/KFintech) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun openUnits(): Optional = openUnits.getOptional("open_units") + + /** + * RTA code for the scheme (CAMS/KFintech) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun rtaCode(): Optional = rtaCode.getOptional("rta_code") + + /** + * Returns the raw JSON value of [advisor]. + * + * Unlike [advisor], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("advisor") @ExcludeMissing fun _advisor(): JsonField = advisor + + /** + * Returns the raw JSON value of [amfi]. + * + * Unlike [amfi], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("amfi") @ExcludeMissing fun _amfi(): JsonField = amfi + + /** + * Returns the raw JSON value of [closeUnits]. + * + * Unlike [closeUnits], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("close_units") + @ExcludeMissing + fun _closeUnits(): JsonField = closeUnits + + /** + * Returns the raw JSON value of [openUnits]. + * + * Unlike [openUnits], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("open_units") + @ExcludeMissing + fun _openUnits(): JsonField = openUnits + + /** + * Returns the raw JSON value of [rtaCode]. + * + * Unlike [rtaCode], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("rta_code") + @ExcludeMissing + fun _rtaCode(): JsonField = rtaCode + + @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 [AdditionalInfo]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AdditionalInfo]. */ + class Builder internal constructor() { + + private var advisor: JsonField = JsonMissing.of() + private var amfi: JsonField = JsonMissing.of() + private var closeUnits: JsonField = JsonMissing.of() + private var openUnits: JsonField = JsonMissing.of() + private var rtaCode: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(additionalInfo: AdditionalInfo) = apply { + advisor = additionalInfo.advisor + amfi = additionalInfo.amfi + closeUnits = additionalInfo.closeUnits + openUnits = additionalInfo.openUnits + rtaCode = additionalInfo.rtaCode + additionalProperties = additionalInfo.additionalProperties.toMutableMap() + } + + /** Financial advisor name (CAMS/KFintech) */ + fun advisor(advisor: String) = advisor(JsonField.of(advisor)) + + /** + * Sets [Builder.advisor] to an arbitrary JSON value. + * + * You should usually call [Builder.advisor] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun advisor(advisor: JsonField) = apply { this.advisor = advisor } + + /** AMFI code for the scheme (CAMS/KFintech) */ + fun amfi(amfi: String) = amfi(JsonField.of(amfi)) + + /** + * Sets [Builder.amfi] to an arbitrary JSON value. + * + * You should usually call [Builder.amfi] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun amfi(amfi: JsonField) = apply { this.amfi = amfi } + + /** Closing balance units (CAMS/KFintech) */ + fun closeUnits(closeUnits: Float) = closeUnits(JsonField.of(closeUnits)) + + /** + * Sets [Builder.closeUnits] to an arbitrary JSON value. + * + * You should usually call [Builder.closeUnits] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun closeUnits(closeUnits: JsonField) = apply { + this.closeUnits = closeUnits + } + + /** Opening balance units (CAMS/KFintech) */ + fun openUnits(openUnits: Float) = openUnits(JsonField.of(openUnits)) + + /** + * Sets [Builder.openUnits] to an arbitrary JSON value. + * + * You should usually call [Builder.openUnits] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun openUnits(openUnits: JsonField) = apply { + this.openUnits = openUnits + } + + /** RTA code for the scheme (CAMS/KFintech) */ + fun rtaCode(rtaCode: String) = rtaCode(JsonField.of(rtaCode)) + + /** + * Sets [Builder.rtaCode] to an arbitrary JSON value. + * + * You should usually call [Builder.rtaCode] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun rtaCode(rtaCode: JsonField) = apply { this.rtaCode = rtaCode } + + 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 [AdditionalInfo]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): AdditionalInfo = + AdditionalInfo( + advisor, + amfi, + closeUnits, + openUnits, + rtaCode, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): AdditionalInfo = apply { + if (validated) { + return@apply + } + + advisor() + amfi() + closeUnits() + openUnits() + rtaCode() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (advisor.asKnown().isPresent) 1 else 0) + + (if (amfi.asKnown().isPresent) 1 else 0) + + (if (closeUnits.asKnown().isPresent) 1 else 0) + + (if (openUnits.asKnown().isPresent) 1 else 0) + + (if (rtaCode.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AdditionalInfo && + advisor == other.advisor && + amfi == other.amfi && + closeUnits == other.closeUnits && + openUnits == other.openUnits && + rtaCode == other.rtaCode && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + advisor, + amfi, + closeUnits, + openUnits, + rtaCode, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AdditionalInfo{advisor=$advisor, amfi=$amfi, closeUnits=$closeUnits, openUnits=$openUnits, rtaCode=$rtaCode, additionalProperties=$additionalProperties}" + } + + class Gain + private constructor( + private val absolute: JsonField, + private val percentage: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("absolute") + @ExcludeMissing + absolute: JsonField = JsonMissing.of(), + @JsonProperty("percentage") + @ExcludeMissing + percentage: JsonField = JsonMissing.of(), + ) : this(absolute, percentage, mutableMapOf()) + + /** + * Absolute gain or loss + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun absolute(): Optional = absolute.getOptional("absolute") + + /** + * Percentage gain or loss + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun percentage(): Optional = percentage.getOptional("percentage") + + /** + * Returns the raw JSON value of [absolute]. + * + * Unlike [absolute], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("absolute") + @ExcludeMissing + fun _absolute(): JsonField = absolute + + /** + * Returns the raw JSON value of [percentage]. + * + * Unlike [percentage], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("percentage") + @ExcludeMissing + fun _percentage(): JsonField = percentage + + @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 [Gain]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Gain]. */ + class Builder internal constructor() { + + private var absolute: JsonField = JsonMissing.of() + private var percentage: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(gain: Gain) = apply { + absolute = gain.absolute + percentage = gain.percentage + additionalProperties = gain.additionalProperties.toMutableMap() + } + + /** Absolute gain or loss */ + fun absolute(absolute: Float) = absolute(JsonField.of(absolute)) + + /** + * Sets [Builder.absolute] to an arbitrary JSON value. + * + * You should usually call [Builder.absolute] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun absolute(absolute: JsonField) = apply { this.absolute = absolute } + + /** Percentage gain or loss */ + fun percentage(percentage: Float) = percentage(JsonField.of(percentage)) + + /** + * Sets [Builder.percentage] to an arbitrary JSON value. + * + * You should usually call [Builder.percentage] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun percentage(percentage: JsonField) = apply { + this.percentage = percentage + } + + 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 [Gain]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Gain = + Gain(absolute, percentage, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Gain = apply { + if (validated) { + return@apply + } + + absolute() + percentage() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (absolute.asKnown().isPresent) 1 else 0) + + (if (percentage.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Gain && + absolute == other.absolute && + percentage == other.percentage && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(absolute, percentage, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Gain{absolute=$absolute, percentage=$percentage, additionalProperties=$additionalProperties}" + } + + class Transaction + private constructor( + private val amount: JsonField, + private val balance: JsonField, + private val date: JsonField, + private val description: JsonField, + private val dividendRate: JsonField, + private val nav: JsonField, + private val type: JsonField, + private val units: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("amount") + @ExcludeMissing + amount: JsonField = JsonMissing.of(), + @JsonProperty("balance") + @ExcludeMissing + balance: JsonField = JsonMissing.of(), + @JsonProperty("date") + @ExcludeMissing + date: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + description: JsonField = JsonMissing.of(), + @JsonProperty("dividend_rate") + @ExcludeMissing + dividendRate: JsonField = JsonMissing.of(), + @JsonProperty("nav") @ExcludeMissing nav: JsonField = JsonMissing.of(), + @JsonProperty("type") + @ExcludeMissing + type: JsonField = JsonMissing.of(), + @JsonProperty("units") + @ExcludeMissing + units: JsonField = JsonMissing.of(), + ) : this( + amount, + balance, + date, + description, + dividendRate, + nav, + type, + units, + mutableMapOf(), + ) + + /** + * Transaction amount + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun amount(): Optional = amount.getOptional("amount") + + /** + * Balance units after transaction + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun balance(): Optional = balance.getOptional("balance") + + /** + * Transaction date + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun date(): Optional = date.getOptional("date") + + /** + * Transaction description + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun description(): Optional = description.getOptional("description") + + /** + * Dividend rate (for dividend transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun dividendRate(): Optional = dividendRate.getOptional("dividend_rate") + + /** + * NAV on transaction date + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun nav(): Optional = nav.getOptional("nav") + + /** + * Transaction type detected based on description. Possible values are + * PURCHASE,PURCHASE_SIP,REDEMPTION,SWITCH_IN,SWITCH_IN_MERGER,SWITCH_OUT,SWITCH_OUT_MERGER,DIVIDEND_PAYOUT,DIVIDEND_REINVESTMENT,SEGREGATION,STAMP_DUTY_TAX,TDS_TAX,STT_TAX,MISC. + * If dividend_rate is present, then possible values are dividend_rate is applicable + * only for DIVIDEND_PAYOUT and DIVIDEND_REINVESTMENT. + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun type(): Optional = type.getOptional("type") + + /** + * Number of units involved + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun units(): Optional = units.getOptional("units") + + /** + * Returns the raw JSON value of [amount]. + * + * Unlike [amount], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("amount") @ExcludeMissing fun _amount(): JsonField = amount + + /** + * Returns the raw JSON value of [balance]. + * + * Unlike [balance], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("balance") @ExcludeMissing fun _balance(): JsonField = balance + + /** + * Returns the raw JSON value of [date]. + * + * Unlike [date], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("date") @ExcludeMissing fun _date(): JsonField = date + + /** + * Returns the raw JSON value of [description]. + * + * Unlike [description], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("description") + @ExcludeMissing + fun _description(): JsonField = description + + /** + * Returns the raw JSON value of [dividendRate]. + * + * Unlike [dividendRate], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("dividend_rate") + @ExcludeMissing + fun _dividendRate(): JsonField = dividendRate + + /** + * Returns the raw JSON value of [nav]. + * + * Unlike [nav], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("nav") @ExcludeMissing fun _nav(): JsonField = nav + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + + /** + * Returns the raw JSON value of [units]. + * + * Unlike [units], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("units") @ExcludeMissing fun _units(): JsonField = units + + @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 [Transaction]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Transaction]. */ + class Builder internal constructor() { + + private var amount: JsonField = JsonMissing.of() + private var balance: JsonField = JsonMissing.of() + private var date: JsonField = JsonMissing.of() + private var description: JsonField = JsonMissing.of() + private var dividendRate: JsonField = JsonMissing.of() + private var nav: JsonField = JsonMissing.of() + private var type: JsonField = JsonMissing.of() + private var units: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(transaction: Transaction) = apply { + amount = transaction.amount + balance = transaction.balance + date = transaction.date + description = transaction.description + dividendRate = transaction.dividendRate + nav = transaction.nav + type = transaction.type + units = transaction.units + additionalProperties = transaction.additionalProperties.toMutableMap() + } + + /** Transaction amount */ + fun amount(amount: Float) = amount(JsonField.of(amount)) + + /** + * Sets [Builder.amount] to an arbitrary JSON value. + * + * You should usually call [Builder.amount] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun amount(amount: JsonField) = apply { this.amount = amount } + + /** Balance units after transaction */ + fun balance(balance: Float) = balance(JsonField.of(balance)) + + /** + * Sets [Builder.balance] to an arbitrary JSON value. + * + * You should usually call [Builder.balance] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun balance(balance: JsonField) = apply { this.balance = balance } + + /** Transaction date */ + fun date(date: LocalDate) = date(JsonField.of(date)) + + /** + * Sets [Builder.date] to an arbitrary JSON value. + * + * You should usually call [Builder.date] with a well-typed [LocalDate] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun date(date: JsonField) = apply { this.date = date } + + /** Transaction description */ + fun description(description: String) = description(JsonField.of(description)) + + /** + * Sets [Builder.description] to an arbitrary JSON value. + * + * You should usually call [Builder.description] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun description(description: JsonField) = apply { + this.description = description + } + + /** Dividend rate (for dividend transactions) */ + fun dividendRate(dividendRate: Float) = dividendRate(JsonField.of(dividendRate)) + + /** + * Sets [Builder.dividendRate] to an arbitrary JSON value. + * + * You should usually call [Builder.dividendRate] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun dividendRate(dividendRate: JsonField) = apply { + this.dividendRate = dividendRate + } + + /** NAV on transaction date */ + fun nav(nav: Float) = nav(JsonField.of(nav)) + + /** + * Sets [Builder.nav] to an arbitrary JSON value. + * + * You should usually call [Builder.nav] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun nav(nav: JsonField) = apply { this.nav = nav } + + /** + * Transaction type detected based on description. Possible values are + * PURCHASE,PURCHASE_SIP,REDEMPTION,SWITCH_IN,SWITCH_IN_MERGER,SWITCH_OUT,SWITCH_OUT_MERGER,DIVIDEND_PAYOUT,DIVIDEND_REINVESTMENT,SEGREGATION,STAMP_DUTY_TAX,TDS_TAX,STT_TAX,MISC. + * If dividend_rate is present, then possible values are dividend_rate is + * applicable only for DIVIDEND_PAYOUT and DIVIDEND_REINVESTMENT. + */ + fun type(type: String) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun type(type: JsonField) = apply { this.type = type } + + /** Number of units involved */ + fun units(units: Float) = units(JsonField.of(units)) + + /** + * Sets [Builder.units] to an arbitrary JSON value. + * + * You should usually call [Builder.units] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun units(units: JsonField) = apply { this.units = units } + + 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 [Transaction]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Transaction = + Transaction( + amount, + balance, + date, + description, + dividendRate, + nav, + type, + units, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Transaction = apply { + if (validated) { + return@apply + } + + amount() + balance() + date() + description() + dividendRate() + nav() + type() + units() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (amount.asKnown().isPresent) 1 else 0) + + (if (balance.asKnown().isPresent) 1 else 0) + + (if (date.asKnown().isPresent) 1 else 0) + + (if (description.asKnown().isPresent) 1 else 0) + + (if (dividendRate.asKnown().isPresent) 1 else 0) + + (if (nav.asKnown().isPresent) 1 else 0) + + (if (type.asKnown().isPresent) 1 else 0) + + (if (units.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Transaction && + amount == other.amount && + balance == other.balance && + date == other.date && + description == other.description && + dividendRate == other.dividendRate && + nav == other.nav && + type == other.type && + units == other.units && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + amount, + balance, + date, + description, + dividendRate, + nav, + type, + units, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Transaction{amount=$amount, balance=$balance, date=$date, description=$description, dividendRate=$dividendRate, nav=$nav, type=$type, units=$units, additionalProperties=$additionalProperties}" + } + + /** Type of mutual fund scheme */ + class Type @JsonCreator private constructor(private val value: JsonField) : + Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that + * doesn't match any known member, and you want to know that value. For example, if + * the SDK is on an older version than the API, then the API may respond with new + * members that the SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val EQUITY = of("Equity") + + @JvmField val DEBT = of("Debt") + + @JvmField val HYBRID = of("Hybrid") + + @JvmField val OTHER = of("Other") + + @JvmStatic fun of(value: String) = Type(JsonField.of(value)) + } + + /** An enum containing [Type]'s known values. */ + enum class Known { + EQUITY, + DEBT, + HYBRID, + OTHER, + } + + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Type] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, + * if the SDK is on an older version than the API, then the API may respond with + * new members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + EQUITY, + DEBT, + HYBRID, + OTHER, + /** + * An enum member indicating that [Type] was instantiated with an unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if + * you want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + EQUITY -> Value.EQUITY + DEBT -> Value.DEBT + HYBRID -> Value.HYBRID + OTHER -> Value.OTHER + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and + * don't want to throw for the unknown case. + * + * @throws CasParserInvalidDataException if this class instance's value is a not a + * known member. + */ + fun known(): Known = + when (this) { + EQUITY -> Known.EQUITY + DEBT -> Known.DEBT + HYBRID -> Known.HYBRID + OTHER -> Known.OTHER + else -> throw CasParserInvalidDataException("Unknown Type: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws CasParserInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CasParserInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): Type = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Type && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Scheme && + additionalInfo == other.additionalInfo && + cost == other.cost && + gain == other.gain && + isin == other.isin && + name == other.name && + nav == other.nav && + nominees == other.nominees && + transactions == other.transactions && + type == other.type && + units == other.units && + value == other.value && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + additionalInfo, + cost, + gain, + isin, + name, + nav, + nominees, + transactions, + type, + units, + value, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Scheme{additionalInfo=$additionalInfo, cost=$cost, gain=$gain, isin=$isin, name=$name, nav=$nav, nominees=$nominees, transactions=$transactions, type=$type, units=$units, value=$value, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is MutualFund && + additionalInfo == other.additionalInfo && + amc == other.amc && + folioNumber == other.folioNumber && + registrar == other.registrar && + schemes == other.schemes && + value == other.value && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + additionalInfo, + amc, + folioNumber, + registrar, + schemes, + value, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "MutualFund{additionalInfo=$additionalInfo, amc=$amc, folioNumber=$folioNumber, registrar=$registrar, schemes=$schemes, value=$value, additionalProperties=$additionalProperties}" + } + + class Summary + private constructor( + private val accounts: JsonField, + private val totalValue: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("accounts") + @ExcludeMissing + accounts: JsonField = JsonMissing.of(), + @JsonProperty("total_value") + @ExcludeMissing + totalValue: JsonField = JsonMissing.of(), + ) : this(accounts, totalValue, mutableMapOf()) + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun accounts(): Optional = accounts.getOptional("accounts") + + /** + * Total portfolio value across all accounts + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun totalValue(): Optional = totalValue.getOptional("total_value") + + /** + * Returns the raw JSON value of [accounts]. + * + * Unlike [accounts], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("accounts") @ExcludeMissing fun _accounts(): JsonField = accounts + + /** + * Returns the raw JSON value of [totalValue]. + * + * Unlike [totalValue], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("total_value") + @ExcludeMissing + fun _totalValue(): JsonField = totalValue + + @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 [Summary]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Summary]. */ + class Builder internal constructor() { + + private var accounts: JsonField = JsonMissing.of() + private var totalValue: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(summary: Summary) = apply { + accounts = summary.accounts + totalValue = summary.totalValue + additionalProperties = summary.additionalProperties.toMutableMap() + } + + fun accounts(accounts: Accounts) = accounts(JsonField.of(accounts)) + + /** + * Sets [Builder.accounts] to an arbitrary JSON value. + * + * You should usually call [Builder.accounts] with a well-typed [Accounts] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun accounts(accounts: JsonField) = apply { this.accounts = accounts } + + /** Total portfolio value across all accounts */ + fun totalValue(totalValue: Float) = totalValue(JsonField.of(totalValue)) + + /** + * Sets [Builder.totalValue] to an arbitrary JSON value. + * + * You should usually call [Builder.totalValue] with a well-typed [Float] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun totalValue(totalValue: JsonField) = apply { this.totalValue = totalValue } + + 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 [Summary]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Summary = + Summary(accounts, totalValue, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Summary = apply { + if (validated) { + return@apply + } + + accounts().ifPresent { it.validate() } + totalValue() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 = + (accounts.asKnown().getOrNull()?.validity() ?: 0) + + (if (totalValue.asKnown().isPresent) 1 else 0) + + class Accounts + private constructor( + private val demat: JsonField, + private val insurance: JsonField, + private val mutualFunds: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("demat") @ExcludeMissing demat: JsonField = JsonMissing.of(), + @JsonProperty("insurance") + @ExcludeMissing + insurance: JsonField = JsonMissing.of(), + @JsonProperty("mutual_funds") + @ExcludeMissing + mutualFunds: JsonField = JsonMissing.of(), + ) : this(demat, insurance, mutualFunds, mutableMapOf()) + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun demat(): Optional = demat.getOptional("demat") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun insurance(): Optional = insurance.getOptional("insurance") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun mutualFunds(): Optional = mutualFunds.getOptional("mutual_funds") + + /** + * Returns the raw JSON value of [demat]. + * + * Unlike [demat], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("demat") @ExcludeMissing fun _demat(): JsonField = demat + + /** + * Returns the raw JSON value of [insurance]. + * + * Unlike [insurance], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("insurance") + @ExcludeMissing + fun _insurance(): JsonField = insurance + + /** + * Returns the raw JSON value of [mutualFunds]. + * + * Unlike [mutualFunds], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("mutual_funds") + @ExcludeMissing + fun _mutualFunds(): JsonField = mutualFunds + + @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 [Accounts]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Accounts]. */ + class Builder internal constructor() { + + private var demat: JsonField = JsonMissing.of() + private var insurance: JsonField = JsonMissing.of() + private var mutualFunds: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(accounts: Accounts) = apply { + demat = accounts.demat + insurance = accounts.insurance + mutualFunds = accounts.mutualFunds + additionalProperties = accounts.additionalProperties.toMutableMap() + } + + fun demat(demat: Demat) = demat(JsonField.of(demat)) + + /** + * Sets [Builder.demat] to an arbitrary JSON value. + * + * You should usually call [Builder.demat] with a well-typed [Demat] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun demat(demat: JsonField) = apply { this.demat = demat } + + fun insurance(insurance: Insurance) = insurance(JsonField.of(insurance)) + + /** + * Sets [Builder.insurance] to an arbitrary JSON value. + * + * You should usually call [Builder.insurance] with a well-typed [Insurance] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun insurance(insurance: JsonField) = apply { + this.insurance = insurance + } + + fun mutualFunds(mutualFunds: MutualFunds) = mutualFunds(JsonField.of(mutualFunds)) + + /** + * Sets [Builder.mutualFunds] to an arbitrary JSON value. + * + * You should usually call [Builder.mutualFunds] with a well-typed [MutualFunds] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun mutualFunds(mutualFunds: JsonField) = apply { + this.mutualFunds = mutualFunds + } + + 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 [Accounts]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Accounts = + Accounts(demat, insurance, mutualFunds, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Accounts = apply { + if (validated) { + return@apply + } + + demat().ifPresent { it.validate() } + insurance().ifPresent { it.validate() } + mutualFunds().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 = + (demat.asKnown().getOrNull()?.validity() ?: 0) + + (insurance.asKnown().getOrNull()?.validity() ?: 0) + + (mutualFunds.asKnown().getOrNull()?.validity() ?: 0) + + class Demat + private constructor( + private val count: JsonField, + private val totalValue: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("count") + @ExcludeMissing + count: JsonField = JsonMissing.of(), + @JsonProperty("total_value") + @ExcludeMissing + totalValue: JsonField = JsonMissing.of(), + ) : this(count, totalValue, mutableMapOf()) + + /** + * Number of demat accounts + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun count(): Optional = count.getOptional("count") + + /** + * Total value of demat accounts + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun totalValue(): Optional = totalValue.getOptional("total_value") + + /** + * Returns the raw JSON value of [count]. + * + * Unlike [count], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("count") @ExcludeMissing fun _count(): JsonField = count + + /** + * Returns the raw JSON value of [totalValue]. + * + * Unlike [totalValue], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("total_value") + @ExcludeMissing + fun _totalValue(): JsonField = totalValue + + @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 [Demat]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Demat]. */ + class Builder internal constructor() { + + private var count: JsonField = JsonMissing.of() + private var totalValue: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(demat: Demat) = apply { + count = demat.count + totalValue = demat.totalValue + additionalProperties = demat.additionalProperties.toMutableMap() + } + + /** Number of demat accounts */ + fun count(count: Long) = count(JsonField.of(count)) + + /** + * Sets [Builder.count] to an arbitrary JSON value. + * + * You should usually call [Builder.count] with a well-typed [Long] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun count(count: JsonField) = apply { this.count = count } + + /** Total value of demat accounts */ + fun totalValue(totalValue: Float) = totalValue(JsonField.of(totalValue)) + + /** + * Sets [Builder.totalValue] to an arbitrary JSON value. + * + * You should usually call [Builder.totalValue] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun totalValue(totalValue: JsonField) = apply { + this.totalValue = totalValue + } + + 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 [Demat]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Demat = + Demat(count, totalValue, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Demat = apply { + if (validated) { + return@apply + } + + count() + totalValue() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (count.asKnown().isPresent) 1 else 0) + + (if (totalValue.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Demat && + count == other.count && + totalValue == other.totalValue && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(count, totalValue, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Demat{count=$count, totalValue=$totalValue, additionalProperties=$additionalProperties}" + } + + class Insurance + private constructor( + private val count: JsonField, + private val totalValue: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("count") + @ExcludeMissing + count: JsonField = JsonMissing.of(), + @JsonProperty("total_value") + @ExcludeMissing + totalValue: JsonField = JsonMissing.of(), + ) : this(count, totalValue, mutableMapOf()) + + /** + * Number of insurance policies + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun count(): Optional = count.getOptional("count") + + /** + * Total value of insurance policies + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun totalValue(): Optional = totalValue.getOptional("total_value") + + /** + * Returns the raw JSON value of [count]. + * + * Unlike [count], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("count") @ExcludeMissing fun _count(): JsonField = count + + /** + * Returns the raw JSON value of [totalValue]. + * + * Unlike [totalValue], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("total_value") + @ExcludeMissing + fun _totalValue(): JsonField = totalValue + + @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 [Insurance]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Insurance]. */ + class Builder internal constructor() { + + private var count: JsonField = JsonMissing.of() + private var totalValue: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(insurance: Insurance) = apply { + count = insurance.count + totalValue = insurance.totalValue + additionalProperties = insurance.additionalProperties.toMutableMap() + } + + /** Number of insurance policies */ + fun count(count: Long) = count(JsonField.of(count)) + + /** + * Sets [Builder.count] to an arbitrary JSON value. + * + * You should usually call [Builder.count] with a well-typed [Long] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun count(count: JsonField) = apply { this.count = count } + + /** Total value of insurance policies */ + fun totalValue(totalValue: Float) = totalValue(JsonField.of(totalValue)) + + /** + * Sets [Builder.totalValue] to an arbitrary JSON value. + * + * You should usually call [Builder.totalValue] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun totalValue(totalValue: JsonField) = apply { + this.totalValue = totalValue + } + + 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 [Insurance]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Insurance = + Insurance(count, totalValue, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Insurance = apply { + if (validated) { + return@apply + } + + count() + totalValue() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (count.asKnown().isPresent) 1 else 0) + + (if (totalValue.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Insurance && + count == other.count && + totalValue == other.totalValue && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(count, totalValue, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Insurance{count=$count, totalValue=$totalValue, additionalProperties=$additionalProperties}" + } + + class MutualFunds + private constructor( + private val count: JsonField, + private val totalValue: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("count") + @ExcludeMissing + count: JsonField = JsonMissing.of(), + @JsonProperty("total_value") + @ExcludeMissing + totalValue: JsonField = JsonMissing.of(), + ) : this(count, totalValue, mutableMapOf()) + + /** + * Number of mutual fund folios + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun count(): Optional = count.getOptional("count") + + /** + * Total value of mutual funds + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun totalValue(): Optional = totalValue.getOptional("total_value") + + /** + * Returns the raw JSON value of [count]. + * + * Unlike [count], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("count") @ExcludeMissing fun _count(): JsonField = count + + /** + * Returns the raw JSON value of [totalValue]. + * + * Unlike [totalValue], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("total_value") + @ExcludeMissing + fun _totalValue(): JsonField = totalValue + + @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 [MutualFunds]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [MutualFunds]. */ + class Builder internal constructor() { + + private var count: JsonField = JsonMissing.of() + private var totalValue: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(mutualFunds: MutualFunds) = apply { + count = mutualFunds.count + totalValue = mutualFunds.totalValue + additionalProperties = mutualFunds.additionalProperties.toMutableMap() + } + + /** Number of mutual fund folios */ + fun count(count: Long) = count(JsonField.of(count)) + + /** + * Sets [Builder.count] to an arbitrary JSON value. + * + * You should usually call [Builder.count] with a well-typed [Long] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun count(count: JsonField) = apply { this.count = count } + + /** Total value of mutual funds */ + fun totalValue(totalValue: Float) = totalValue(JsonField.of(totalValue)) + + /** + * Sets [Builder.totalValue] to an arbitrary JSON value. + * + * You should usually call [Builder.totalValue] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun totalValue(totalValue: JsonField) = apply { + this.totalValue = totalValue + } + + 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 [MutualFunds]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): MutualFunds = + MutualFunds(count, totalValue, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): MutualFunds = apply { + if (validated) { + return@apply + } + + count() + totalValue() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (count.asKnown().isPresent) 1 else 0) + + (if (totalValue.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is MutualFunds && + count == other.count && + totalValue == other.totalValue && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(count, totalValue, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "MutualFunds{count=$count, totalValue=$totalValue, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Accounts && + demat == other.demat && + insurance == other.insurance && + mutualFunds == other.mutualFunds && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(demat, insurance, mutualFunds, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Accounts{demat=$demat, insurance=$insurance, mutualFunds=$mutualFunds, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Summary && + accounts == other.accounts && + totalValue == other.totalValue && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(accounts, totalValue, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Summary{accounts=$accounts, totalValue=$totalValue, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is UnifiedResponse && + dematAccounts == other.dematAccounts && + insurance == other.insurance && + investor == other.investor && + meta == other.meta && + mutualFunds == other.mutualFunds && + summary == other.summary && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + dematAccounts, + insurance, + investor, + meta, + mutualFunds, + summary, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "UnifiedResponse{dematAccounts=$dematAccounts, insurance=$insurance, investor=$investor, meta=$meta, mutualFunds=$mutualFunds, summary=$summary, additionalProperties=$additionalProperties}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CasGeneratorServiceAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CasGeneratorServiceAsync.kt new file mode 100644 index 0000000..9eee1d4 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CasGeneratorServiceAsync.kt @@ -0,0 +1,73 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.models.casgenerator.CasGeneratorGenerateCasParams +import com.cas_parser.api.models.casgenerator.CasGeneratorGenerateCasResponse +import java.util.concurrent.CompletableFuture +import java.util.function.Consumer + +interface CasGeneratorServiceAsync { + + /** + * 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): CasGeneratorServiceAsync + + /** + * This endpoint generates CAS (Consolidated Account Statement) documents by submitting a + * mailback request to the specified CAS authority. Currently only supports KFintech, with plans + * to support CAMS, CDSL, and NSDL in the future. + */ + fun generateCas( + params: CasGeneratorGenerateCasParams + ): CompletableFuture = + generateCas(params, RequestOptions.none()) + + /** @see generateCas */ + fun generateCas( + params: CasGeneratorGenerateCasParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** + * A view of [CasGeneratorServiceAsync] 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 + ): CasGeneratorServiceAsync.WithRawResponse + + /** + * Returns a raw HTTP response for `post /v4/generate`, but is otherwise the same as + * [CasGeneratorServiceAsync.generateCas]. + */ + fun generateCas( + params: CasGeneratorGenerateCasParams + ): CompletableFuture> = + generateCas(params, RequestOptions.none()) + + /** @see generateCas */ + fun generateCas( + params: CasGeneratorGenerateCasParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CasGeneratorServiceAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CasGeneratorServiceAsyncImpl.kt new file mode 100644 index 0000000..b0b1ff9 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CasGeneratorServiceAsyncImpl.kt @@ -0,0 +1,86 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.handlers.errorBodyHandler +import com.cas_parser.api.core.handlers.errorHandler +import com.cas_parser.api.core.handlers.jsonHandler +import com.cas_parser.api.core.http.HttpMethod +import com.cas_parser.api.core.http.HttpRequest +import com.cas_parser.api.core.http.HttpResponse +import com.cas_parser.api.core.http.HttpResponse.Handler +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.core.http.json +import com.cas_parser.api.core.http.parseable +import com.cas_parser.api.core.prepareAsync +import com.cas_parser.api.models.casgenerator.CasGeneratorGenerateCasParams +import com.cas_parser.api.models.casgenerator.CasGeneratorGenerateCasResponse +import java.util.concurrent.CompletableFuture +import java.util.function.Consumer + +class CasGeneratorServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + CasGeneratorServiceAsync { + + private val withRawResponse: CasGeneratorServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): CasGeneratorServiceAsync.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): CasGeneratorServiceAsync = + CasGeneratorServiceAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun generateCas( + params: CasGeneratorGenerateCasParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v4/generate + withRawResponse().generateCas(params, requestOptions).thenApply { it.parse() } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + CasGeneratorServiceAsync.WithRawResponse { + + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + + override fun withOptions( + modifier: Consumer + ): CasGeneratorServiceAsync.WithRawResponse = + CasGeneratorServiceAsyncImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + private val generateCasHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun generateCas( + params: CasGeneratorGenerateCasParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v4", "generate") + .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 { generateCasHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CasParserServiceAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CasParserServiceAsync.kt new file mode 100644 index 0000000..319748a --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CasParserServiceAsync.kt @@ -0,0 +1,230 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.models.casparser.CasParserCamsKfintechParams +import com.cas_parser.api.models.casparser.CasParserCdslParams +import com.cas_parser.api.models.casparser.CasParserNsdlParams +import com.cas_parser.api.models.casparser.CasParserSmartParseParams +import com.cas_parser.api.models.casparser.UnifiedResponse +import java.util.concurrent.CompletableFuture +import java.util.function.Consumer + +interface CasParserServiceAsync { + + /** + * 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): CasParserServiceAsync + + /** + * This endpoint specifically parses CAMS/KFintech CAS (Consolidated Account Statement) PDF + * files and returns data in a unified format. Use this endpoint when you know the PDF is from + * CAMS or KFintech. + */ + fun camsKfintech(): CompletableFuture = + camsKfintech(CasParserCamsKfintechParams.none()) + + /** @see camsKfintech */ + fun camsKfintech( + params: CasParserCamsKfintechParams = CasParserCamsKfintechParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see camsKfintech */ + fun camsKfintech( + params: CasParserCamsKfintechParams = CasParserCamsKfintechParams.none() + ): CompletableFuture = camsKfintech(params, RequestOptions.none()) + + /** @see camsKfintech */ + fun camsKfintech(requestOptions: RequestOptions): CompletableFuture = + camsKfintech(CasParserCamsKfintechParams.none(), requestOptions) + + /** + * This endpoint specifically parses CDSL CAS (Consolidated Account Statement) PDF files and + * returns data in a unified format. Use this endpoint when you know the PDF is from CDSL. + */ + fun cdsl(): CompletableFuture = cdsl(CasParserCdslParams.none()) + + /** @see cdsl */ + fun cdsl( + params: CasParserCdslParams = CasParserCdslParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see cdsl */ + fun cdsl( + params: CasParserCdslParams = CasParserCdslParams.none() + ): CompletableFuture = cdsl(params, RequestOptions.none()) + + /** @see cdsl */ + fun cdsl(requestOptions: RequestOptions): CompletableFuture = + cdsl(CasParserCdslParams.none(), requestOptions) + + /** + * This endpoint specifically parses NSDL CAS (Consolidated Account Statement) PDF files and + * returns data in a unified format. Use this endpoint when you know the PDF is from NSDL. + */ + fun nsdl(): CompletableFuture = nsdl(CasParserNsdlParams.none()) + + /** @see nsdl */ + fun nsdl( + params: CasParserNsdlParams = CasParserNsdlParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see nsdl */ + fun nsdl( + params: CasParserNsdlParams = CasParserNsdlParams.none() + ): CompletableFuture = nsdl(params, RequestOptions.none()) + + /** @see nsdl */ + fun nsdl(requestOptions: RequestOptions): CompletableFuture = + nsdl(CasParserNsdlParams.none(), requestOptions) + + /** + * This endpoint parses CAS (Consolidated Account Statement) PDF files from NSDL, CDSL, or + * CAMS/KFintech and returns data in a unified format. It auto-detects the CAS type and + * transforms the data into a consistent structure regardless of the source. + */ + fun smartParse(): CompletableFuture = + smartParse(CasParserSmartParseParams.none()) + + /** @see smartParse */ + fun smartParse( + params: CasParserSmartParseParams = CasParserSmartParseParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see smartParse */ + fun smartParse( + params: CasParserSmartParseParams = CasParserSmartParseParams.none() + ): CompletableFuture = smartParse(params, RequestOptions.none()) + + /** @see smartParse */ + fun smartParse(requestOptions: RequestOptions): CompletableFuture = + smartParse(CasParserSmartParseParams.none(), requestOptions) + + /** + * A view of [CasParserServiceAsync] 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 + ): CasParserServiceAsync.WithRawResponse + + /** + * Returns a raw HTTP response for `post /v4/cams_kfintech/parse`, but is otherwise the same + * as [CasParserServiceAsync.camsKfintech]. + */ + fun camsKfintech(): CompletableFuture> = + camsKfintech(CasParserCamsKfintechParams.none()) + + /** @see camsKfintech */ + fun camsKfintech( + params: CasParserCamsKfintechParams = CasParserCamsKfintechParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see camsKfintech */ + fun camsKfintech( + params: CasParserCamsKfintechParams = CasParserCamsKfintechParams.none() + ): CompletableFuture> = + camsKfintech(params, RequestOptions.none()) + + /** @see camsKfintech */ + fun camsKfintech( + requestOptions: RequestOptions + ): CompletableFuture> = + camsKfintech(CasParserCamsKfintechParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `post /v4/cdsl/parse`, but is otherwise the same as + * [CasParserServiceAsync.cdsl]. + */ + fun cdsl(): CompletableFuture> = + cdsl(CasParserCdslParams.none()) + + /** @see cdsl */ + fun cdsl( + params: CasParserCdslParams = CasParserCdslParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see cdsl */ + fun cdsl( + params: CasParserCdslParams = CasParserCdslParams.none() + ): CompletableFuture> = cdsl(params, RequestOptions.none()) + + /** @see cdsl */ + fun cdsl( + requestOptions: RequestOptions + ): CompletableFuture> = + cdsl(CasParserCdslParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `post /v4/nsdl/parse`, but is otherwise the same as + * [CasParserServiceAsync.nsdl]. + */ + fun nsdl(): CompletableFuture> = + nsdl(CasParserNsdlParams.none()) + + /** @see nsdl */ + fun nsdl( + params: CasParserNsdlParams = CasParserNsdlParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see nsdl */ + fun nsdl( + params: CasParserNsdlParams = CasParserNsdlParams.none() + ): CompletableFuture> = nsdl(params, RequestOptions.none()) + + /** @see nsdl */ + fun nsdl( + requestOptions: RequestOptions + ): CompletableFuture> = + nsdl(CasParserNsdlParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `post /v4/smart/parse`, but is otherwise the same as + * [CasParserServiceAsync.smartParse]. + */ + fun smartParse(): CompletableFuture> = + smartParse(CasParserSmartParseParams.none()) + + /** @see smartParse */ + fun smartParse( + params: CasParserSmartParseParams = CasParserSmartParseParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see smartParse */ + fun smartParse( + params: CasParserSmartParseParams = CasParserSmartParseParams.none() + ): CompletableFuture> = + smartParse(params, RequestOptions.none()) + + /** @see smartParse */ + fun smartParse( + requestOptions: RequestOptions + ): CompletableFuture> = + smartParse(CasParserSmartParseParams.none(), requestOptions) + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CasParserServiceAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CasParserServiceAsyncImpl.kt new file mode 100644 index 0000000..747e8ed --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CasParserServiceAsyncImpl.kt @@ -0,0 +1,203 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.handlers.errorBodyHandler +import com.cas_parser.api.core.handlers.errorHandler +import com.cas_parser.api.core.handlers.jsonHandler +import com.cas_parser.api.core.http.HttpMethod +import com.cas_parser.api.core.http.HttpRequest +import com.cas_parser.api.core.http.HttpResponse +import com.cas_parser.api.core.http.HttpResponse.Handler +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.core.http.multipartFormData +import com.cas_parser.api.core.http.parseable +import com.cas_parser.api.core.prepareAsync +import com.cas_parser.api.models.casparser.CasParserCamsKfintechParams +import com.cas_parser.api.models.casparser.CasParserCdslParams +import com.cas_parser.api.models.casparser.CasParserNsdlParams +import com.cas_parser.api.models.casparser.CasParserSmartParseParams +import com.cas_parser.api.models.casparser.UnifiedResponse +import java.util.concurrent.CompletableFuture +import java.util.function.Consumer + +class CasParserServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + CasParserServiceAsync { + + private val withRawResponse: CasParserServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): CasParserServiceAsync.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): CasParserServiceAsync = + CasParserServiceAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun camsKfintech( + params: CasParserCamsKfintechParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v4/cams_kfintech/parse + withRawResponse().camsKfintech(params, requestOptions).thenApply { it.parse() } + + override fun cdsl( + params: CasParserCdslParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v4/cdsl/parse + withRawResponse().cdsl(params, requestOptions).thenApply { it.parse() } + + override fun nsdl( + params: CasParserNsdlParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v4/nsdl/parse + withRawResponse().nsdl(params, requestOptions).thenApply { it.parse() } + + override fun smartParse( + params: CasParserSmartParseParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v4/smart/parse + withRawResponse().smartParse(params, requestOptions).thenApply { it.parse() } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + CasParserServiceAsync.WithRawResponse { + + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + + override fun withOptions( + modifier: Consumer + ): CasParserServiceAsync.WithRawResponse = + CasParserServiceAsyncImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + private val camsKfintechHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun camsKfintech( + params: CasParserCamsKfintechParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v4", "cams_kfintech", "parse") + .body(multipartFormData(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 { camsKfintechHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + + private val cdslHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun cdsl( + params: CasParserCdslParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v4", "cdsl", "parse") + .body(multipartFormData(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 { cdslHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + + private val nsdlHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun nsdl( + params: CasParserNsdlParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v4", "nsdl", "parse") + .body(multipartFormData(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 { nsdlHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + + private val smartParseHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun smartParse( + params: CasParserSmartParseParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v4", "smart", "parse") + .body(multipartFormData(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 { smartParseHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CasGeneratorService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CasGeneratorService.kt new file mode 100644 index 0000000..b586008 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CasGeneratorService.kt @@ -0,0 +1,72 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.models.casgenerator.CasGeneratorGenerateCasParams +import com.cas_parser.api.models.casgenerator.CasGeneratorGenerateCasResponse +import com.google.errorprone.annotations.MustBeClosed +import java.util.function.Consumer + +interface CasGeneratorService { + + /** + * 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): CasGeneratorService + + /** + * This endpoint generates CAS (Consolidated Account Statement) documents by submitting a + * mailback request to the specified CAS authority. Currently only supports KFintech, with plans + * to support CAMS, CDSL, and NSDL in the future. + */ + fun generateCas(params: CasGeneratorGenerateCasParams): CasGeneratorGenerateCasResponse = + generateCas(params, RequestOptions.none()) + + /** @see generateCas */ + fun generateCas( + params: CasGeneratorGenerateCasParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CasGeneratorGenerateCasResponse + + /** + * A view of [CasGeneratorService] 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 + ): CasGeneratorService.WithRawResponse + + /** + * Returns a raw HTTP response for `post /v4/generate`, but is otherwise the same as + * [CasGeneratorService.generateCas]. + */ + @MustBeClosed + fun generateCas( + params: CasGeneratorGenerateCasParams + ): HttpResponseFor = + generateCas(params, RequestOptions.none()) + + /** @see generateCas */ + @MustBeClosed + fun generateCas( + params: CasGeneratorGenerateCasParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CasGeneratorServiceImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CasGeneratorServiceImpl.kt new file mode 100644 index 0000000..26bcfb5 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CasGeneratorServiceImpl.kt @@ -0,0 +1,82 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.handlers.errorBodyHandler +import com.cas_parser.api.core.handlers.errorHandler +import com.cas_parser.api.core.handlers.jsonHandler +import com.cas_parser.api.core.http.HttpMethod +import com.cas_parser.api.core.http.HttpRequest +import com.cas_parser.api.core.http.HttpResponse +import com.cas_parser.api.core.http.HttpResponse.Handler +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.core.http.json +import com.cas_parser.api.core.http.parseable +import com.cas_parser.api.core.prepare +import com.cas_parser.api.models.casgenerator.CasGeneratorGenerateCasParams +import com.cas_parser.api.models.casgenerator.CasGeneratorGenerateCasResponse +import java.util.function.Consumer + +class CasGeneratorServiceImpl internal constructor(private val clientOptions: ClientOptions) : + CasGeneratorService { + + private val withRawResponse: CasGeneratorService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): CasGeneratorService.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): CasGeneratorService = + CasGeneratorServiceImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun generateCas( + params: CasGeneratorGenerateCasParams, + requestOptions: RequestOptions, + ): CasGeneratorGenerateCasResponse = + // post /v4/generate + withRawResponse().generateCas(params, requestOptions).parse() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + CasGeneratorService.WithRawResponse { + + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + + override fun withOptions( + modifier: Consumer + ): CasGeneratorService.WithRawResponse = + CasGeneratorServiceImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + private val generateCasHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun generateCas( + params: CasGeneratorGenerateCasParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v4", "generate") + .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 { generateCasHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CasParserService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CasParserService.kt new file mode 100644 index 0000000..f526f80 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CasParserService.kt @@ -0,0 +1,226 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.models.casparser.CasParserCamsKfintechParams +import com.cas_parser.api.models.casparser.CasParserCdslParams +import com.cas_parser.api.models.casparser.CasParserNsdlParams +import com.cas_parser.api.models.casparser.CasParserSmartParseParams +import com.cas_parser.api.models.casparser.UnifiedResponse +import com.google.errorprone.annotations.MustBeClosed +import java.util.function.Consumer + +interface CasParserService { + + /** + * 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): CasParserService + + /** + * This endpoint specifically parses CAMS/KFintech CAS (Consolidated Account Statement) PDF + * files and returns data in a unified format. Use this endpoint when you know the PDF is from + * CAMS or KFintech. + */ + fun camsKfintech(): UnifiedResponse = camsKfintech(CasParserCamsKfintechParams.none()) + + /** @see camsKfintech */ + fun camsKfintech( + params: CasParserCamsKfintechParams = CasParserCamsKfintechParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): UnifiedResponse + + /** @see camsKfintech */ + fun camsKfintech( + params: CasParserCamsKfintechParams = CasParserCamsKfintechParams.none() + ): UnifiedResponse = camsKfintech(params, RequestOptions.none()) + + /** @see camsKfintech */ + fun camsKfintech(requestOptions: RequestOptions): UnifiedResponse = + camsKfintech(CasParserCamsKfintechParams.none(), requestOptions) + + /** + * This endpoint specifically parses CDSL CAS (Consolidated Account Statement) PDF files and + * returns data in a unified format. Use this endpoint when you know the PDF is from CDSL. + */ + fun cdsl(): UnifiedResponse = cdsl(CasParserCdslParams.none()) + + /** @see cdsl */ + fun cdsl( + params: CasParserCdslParams = CasParserCdslParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): UnifiedResponse + + /** @see cdsl */ + fun cdsl(params: CasParserCdslParams = CasParserCdslParams.none()): UnifiedResponse = + cdsl(params, RequestOptions.none()) + + /** @see cdsl */ + fun cdsl(requestOptions: RequestOptions): UnifiedResponse = + cdsl(CasParserCdslParams.none(), requestOptions) + + /** + * This endpoint specifically parses NSDL CAS (Consolidated Account Statement) PDF files and + * returns data in a unified format. Use this endpoint when you know the PDF is from NSDL. + */ + fun nsdl(): UnifiedResponse = nsdl(CasParserNsdlParams.none()) + + /** @see nsdl */ + fun nsdl( + params: CasParserNsdlParams = CasParserNsdlParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): UnifiedResponse + + /** @see nsdl */ + fun nsdl(params: CasParserNsdlParams = CasParserNsdlParams.none()): UnifiedResponse = + nsdl(params, RequestOptions.none()) + + /** @see nsdl */ + fun nsdl(requestOptions: RequestOptions): UnifiedResponse = + nsdl(CasParserNsdlParams.none(), requestOptions) + + /** + * This endpoint parses CAS (Consolidated Account Statement) PDF files from NSDL, CDSL, or + * CAMS/KFintech and returns data in a unified format. It auto-detects the CAS type and + * transforms the data into a consistent structure regardless of the source. + */ + fun smartParse(): UnifiedResponse = smartParse(CasParserSmartParseParams.none()) + + /** @see smartParse */ + fun smartParse( + params: CasParserSmartParseParams = CasParserSmartParseParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): UnifiedResponse + + /** @see smartParse */ + fun smartParse( + params: CasParserSmartParseParams = CasParserSmartParseParams.none() + ): UnifiedResponse = smartParse(params, RequestOptions.none()) + + /** @see smartParse */ + fun smartParse(requestOptions: RequestOptions): UnifiedResponse = + smartParse(CasParserSmartParseParams.none(), requestOptions) + + /** A view of [CasParserService] 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): CasParserService.WithRawResponse + + /** + * Returns a raw HTTP response for `post /v4/cams_kfintech/parse`, but is otherwise the same + * as [CasParserService.camsKfintech]. + */ + @MustBeClosed + fun camsKfintech(): HttpResponseFor = + camsKfintech(CasParserCamsKfintechParams.none()) + + /** @see camsKfintech */ + @MustBeClosed + fun camsKfintech( + params: CasParserCamsKfintechParams = CasParserCamsKfintechParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see camsKfintech */ + @MustBeClosed + fun camsKfintech( + params: CasParserCamsKfintechParams = CasParserCamsKfintechParams.none() + ): HttpResponseFor = camsKfintech(params, RequestOptions.none()) + + /** @see camsKfintech */ + @MustBeClosed + fun camsKfintech(requestOptions: RequestOptions): HttpResponseFor = + camsKfintech(CasParserCamsKfintechParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `post /v4/cdsl/parse`, but is otherwise the same as + * [CasParserService.cdsl]. + */ + @MustBeClosed + fun cdsl(): HttpResponseFor = cdsl(CasParserCdslParams.none()) + + /** @see cdsl */ + @MustBeClosed + fun cdsl( + params: CasParserCdslParams = CasParserCdslParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see cdsl */ + @MustBeClosed + fun cdsl( + params: CasParserCdslParams = CasParserCdslParams.none() + ): HttpResponseFor = cdsl(params, RequestOptions.none()) + + /** @see cdsl */ + @MustBeClosed + fun cdsl(requestOptions: RequestOptions): HttpResponseFor = + cdsl(CasParserCdslParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `post /v4/nsdl/parse`, but is otherwise the same as + * [CasParserService.nsdl]. + */ + @MustBeClosed + fun nsdl(): HttpResponseFor = nsdl(CasParserNsdlParams.none()) + + /** @see nsdl */ + @MustBeClosed + fun nsdl( + params: CasParserNsdlParams = CasParserNsdlParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see nsdl */ + @MustBeClosed + fun nsdl( + params: CasParserNsdlParams = CasParserNsdlParams.none() + ): HttpResponseFor = nsdl(params, RequestOptions.none()) + + /** @see nsdl */ + @MustBeClosed + fun nsdl(requestOptions: RequestOptions): HttpResponseFor = + nsdl(CasParserNsdlParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `post /v4/smart/parse`, but is otherwise the same as + * [CasParserService.smartParse]. + */ + @MustBeClosed + fun smartParse(): HttpResponseFor = + smartParse(CasParserSmartParseParams.none()) + + /** @see smartParse */ + @MustBeClosed + fun smartParse( + params: CasParserSmartParseParams = CasParserSmartParseParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see smartParse */ + @MustBeClosed + fun smartParse( + params: CasParserSmartParseParams = CasParserSmartParseParams.none() + ): HttpResponseFor = smartParse(params, RequestOptions.none()) + + /** @see smartParse */ + @MustBeClosed + fun smartParse(requestOptions: RequestOptions): HttpResponseFor = + smartParse(CasParserSmartParseParams.none(), requestOptions) + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CasParserServiceImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CasParserServiceImpl.kt new file mode 100644 index 0000000..8826c88 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CasParserServiceImpl.kt @@ -0,0 +1,190 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.handlers.errorBodyHandler +import com.cas_parser.api.core.handlers.errorHandler +import com.cas_parser.api.core.handlers.jsonHandler +import com.cas_parser.api.core.http.HttpMethod +import com.cas_parser.api.core.http.HttpRequest +import com.cas_parser.api.core.http.HttpResponse +import com.cas_parser.api.core.http.HttpResponse.Handler +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.core.http.multipartFormData +import com.cas_parser.api.core.http.parseable +import com.cas_parser.api.core.prepare +import com.cas_parser.api.models.casparser.CasParserCamsKfintechParams +import com.cas_parser.api.models.casparser.CasParserCdslParams +import com.cas_parser.api.models.casparser.CasParserNsdlParams +import com.cas_parser.api.models.casparser.CasParserSmartParseParams +import com.cas_parser.api.models.casparser.UnifiedResponse +import java.util.function.Consumer + +class CasParserServiceImpl internal constructor(private val clientOptions: ClientOptions) : + CasParserService { + + private val withRawResponse: CasParserService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): CasParserService.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): CasParserService = + CasParserServiceImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun camsKfintech( + params: CasParserCamsKfintechParams, + requestOptions: RequestOptions, + ): UnifiedResponse = + // post /v4/cams_kfintech/parse + withRawResponse().camsKfintech(params, requestOptions).parse() + + override fun cdsl( + params: CasParserCdslParams, + requestOptions: RequestOptions, + ): UnifiedResponse = + // post /v4/cdsl/parse + withRawResponse().cdsl(params, requestOptions).parse() + + override fun nsdl( + params: CasParserNsdlParams, + requestOptions: RequestOptions, + ): UnifiedResponse = + // post /v4/nsdl/parse + withRawResponse().nsdl(params, requestOptions).parse() + + override fun smartParse( + params: CasParserSmartParseParams, + requestOptions: RequestOptions, + ): UnifiedResponse = + // post /v4/smart/parse + withRawResponse().smartParse(params, requestOptions).parse() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + CasParserService.WithRawResponse { + + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + + override fun withOptions( + modifier: Consumer + ): CasParserService.WithRawResponse = + CasParserServiceImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + private val camsKfintechHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun camsKfintech( + params: CasParserCamsKfintechParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v4", "cams_kfintech", "parse") + .body(multipartFormData(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 { camsKfintechHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + + private val cdslHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun cdsl( + params: CasParserCdslParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v4", "cdsl", "parse") + .body(multipartFormData(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 { cdslHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + + private val nsdlHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun nsdl( + params: CasParserNsdlParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v4", "nsdl", "parse") + .body(multipartFormData(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 { nsdlHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + + private val smartParseHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun smartParse( + params: CasParserSmartParseParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v4", "smart", "parse") + .body(multipartFormData(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 { smartParseHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } +} diff --git a/cas-parser-java-core/src/main/resources/META-INF/proguard/cas-parser-java-core.pro b/cas-parser-java-core/src/main/resources/META-INF/proguard/cas-parser-java-core.pro new file mode 100644 index 0000000..8ee82ce --- /dev/null +++ b/cas-parser-java-core/src/main/resources/META-INF/proguard/cas-parser-java-core.pro @@ -0,0 +1,32 @@ +# Jackson uses reflection and depends heavily on runtime attributes. +-keepattributes Exceptions,InnerClasses,Signature,Deprecated,*Annotation* + +# Jackson uses Kotlin reflection utilities, which themselves use reflection to access things. +-keep class kotlin.reflect.** { *; } +-keep class kotlin.Metadata { *; } + +# Jackson uses reflection to access enum members (e.g. via `java.lang.Class.getEnumConstants()`). +-keepclassmembers class com.fasterxml.jackson.** extends java.lang.Enum { + ; + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +# Jackson uses reflection to access annotation members. +-keepclassmembers @interface com.fasterxml.jackson.annotation.** { + *; +} + +# Jackson uses reified type information to serialize and deserialize our classes (via `TypeReference`). +-keep class com.fasterxml.jackson.core.type.TypeReference { *; } +-keep class * extends com.fasterxml.jackson.core.type.TypeReference { *; } + +# Jackson uses reflection to access our class serializers and deserializers. +-keep @com.fasterxml.jackson.databind.annotation.JsonSerialize class com.cas_parser.api.** { *; } +-keep @com.fasterxml.jackson.databind.annotation.JsonDeserialize class com.cas_parser.api.** { *; } + +# Jackson uses reflection to serialize and deserialize our classes based on their constructors and annotated members. +-keepclassmembers class com.cas_parser.api.** { + (...); + @com.fasterxml.jackson.annotation.* *; +} \ No newline at end of file diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/TestServerExtension.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/TestServerExtension.kt new file mode 100644 index 0000000..a567645 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/TestServerExtension.kt @@ -0,0 +1,62 @@ +package com.cas_parser.api + +import java.lang.RuntimeException +import java.net.URL +import org.junit.jupiter.api.extension.BeforeAllCallback +import org.junit.jupiter.api.extension.ConditionEvaluationResult +import org.junit.jupiter.api.extension.ExecutionCondition +import org.junit.jupiter.api.extension.ExtensionContext + +class TestServerExtension : BeforeAllCallback, ExecutionCondition { + + override fun beforeAll(context: ExtensionContext?) { + try { + URL(BASE_URL).openConnection().connect() + } catch (e: Exception) { + throw RuntimeException( + """ + The test suite will not run without a mock Prism server running against your OpenAPI spec. + + You can set the environment variable `SKIP_MOCK_TESTS` to `true` to skip running any tests + that require the mock server. + + To fix: + + 1. Install Prism (requires Node 16+): + + With npm: + $ npm install -g @stoplight/prism-cli + + With yarn: + $ yarn global add @stoplight/prism-cli + + 2. Run the mock server + + To run the server, pass in the path of your OpenAPI spec to the prism command: + $ prism mock path/to/your.openapi.yml + """ + .trimIndent(), + e, + ) + } + } + + override fun evaluateExecutionCondition(context: ExtensionContext): ConditionEvaluationResult { + return if (System.getenv(SKIP_TESTS_ENV).toBoolean()) { + ConditionEvaluationResult.disabled( + "Environment variable $SKIP_TESTS_ENV is set to true" + ) + } else { + ConditionEvaluationResult.enabled( + "Environment variable $SKIP_TESTS_ENV is not set to true" + ) + } + } + + companion object { + + val BASE_URL = System.getenv("TEST_API_BASE_URL") ?: "http://localhost:4010" + + const val SKIP_TESTS_ENV: String = "SKIP_MOCK_TESTS" + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/ClientOptionsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/ClientOptionsTest.kt new file mode 100644 index 0000000..3859537 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/ClientOptionsTest.kt @@ -0,0 +1,34 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.core + +import com.cas_parser.api.core.http.HttpClient +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith +import org.mockito.junit.jupiter.MockitoExtension +import org.mockito.kotlin.mock +import org.mockito.kotlin.never +import org.mockito.kotlin.verify + +@ExtendWith(MockitoExtension::class) +internal class ClientOptionsTest { + + private val httpClient = mock() + + @Test + fun toBuilder_whenOriginalClientOptionsGarbageCollected_doesNotCloseOriginalClient() { + var clientOptions = + ClientOptions.builder().httpClient(httpClient).apiKey("My API Key").build() + verify(httpClient, never()).close() + + // Overwrite the `clientOptions` variable so that the original `ClientOptions` is GC'd. + clientOptions = clientOptions.toBuilder().build() + System.gc() + Thread.sleep(100) + + verify(httpClient, never()).close() + // This exists so that `clientOptions` is still reachable. + assertThat(clientOptions).isEqualTo(clientOptions) + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/ObjectMappersTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/ObjectMappersTest.kt new file mode 100644 index 0000000..c338d17 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/ObjectMappersTest.kt @@ -0,0 +1,102 @@ +package com.cas_parser.api.core + +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.databind.exc.MismatchedInputException +import com.fasterxml.jackson.module.kotlin.readValue +import java.time.LocalDateTime +import kotlin.reflect.KClass +import org.assertj.core.api.Assertions.assertThat +import org.assertj.core.api.Assertions.catchThrowable +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertDoesNotThrow +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.EnumSource +import org.junitpioneer.jupiter.cartesian.CartesianTest + +internal class ObjectMappersTest { + + internal class ClassWithBooleanFieldPrefixedWithIs(private val isActive: JsonField) { + + @JsonProperty("is_active") @ExcludeMissing fun _isActive() = isActive + } + + @Test + fun write_whenFieldPrefixedWithIs_keepsPrefix() { + val value = ClassWithBooleanFieldPrefixedWithIs(JsonField.of(true)) + + val json = jsonMapper().writeValueAsString(value) + + assertThat(json).isEqualTo("{\"is_active\":true}") + } + + internal class Class(@get:JsonProperty("field") @JsonProperty("field") val field: String) + + enum class ShapeTestCase(val value: Any, val kClass: KClass<*>) { + STRING("Hello World!", String::class), + BOOLEAN(true, Boolean::class), + FLOAT(3.14F, Float::class), + DOUBLE(3.14, Double::class), + INTEGER(42, Int::class), + LONG(42L, Long::class), + MAP(mapOf("property" to "value"), Map::class), + CLASS(Class("Hello World!"), Class::class), + LIST(listOf(1, 2, 3), List::class); + + companion object { + val VALID_CONVERSIONS = + listOf( + FLOAT to DOUBLE, + FLOAT to INTEGER, + FLOAT to LONG, + DOUBLE to FLOAT, + DOUBLE to INTEGER, + DOUBLE to LONG, + INTEGER to FLOAT, + INTEGER to DOUBLE, + INTEGER to LONG, + LONG to FLOAT, + LONG to DOUBLE, + LONG to INTEGER, + CLASS to MAP, + // These aren't actually valid, but coercion configs don't work for String until + // v2.14.0: https://github.com/FasterXML/jackson-databind/issues/3240 + // We currently test on v2.13.4. + BOOLEAN to STRING, + FLOAT to STRING, + DOUBLE to STRING, + INTEGER to STRING, + LONG to STRING, + ) + } + } + + @CartesianTest + fun read(@CartesianTest.Enum shape1: ShapeTestCase, @CartesianTest.Enum shape2: ShapeTestCase) { + val jsonMapper = jsonMapper() + val json = jsonMapper.writeValueAsString(shape1.value) + + val e = catchThrowable { jsonMapper.readValue(json, shape2.kClass.java) } + + if (shape1 == shape2 || shape1 to shape2 in ShapeTestCase.VALID_CONVERSIONS) { + assertThat(e).isNull() + } else { + assertThat(e).isInstanceOf(MismatchedInputException::class.java) + } + } + + enum class LenientLocalDateTimeTestCase(val string: String) { + DATE("1998-04-21"), + DATE_TIME("1998-04-21T04:00:00"), + ZONED_DATE_TIME_1("1998-04-21T04:00:00+03:00"), + ZONED_DATE_TIME_2("1998-04-21T04:00:00Z"), + } + + @ParameterizedTest + @EnumSource + fun readLocalDateTime_lenient(testCase: LenientLocalDateTimeTestCase) { + val jsonMapper = jsonMapper() + val json = jsonMapper.writeValueAsString(testCase.string) + + assertDoesNotThrow { jsonMapper().readValue(json) } + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/PhantomReachableTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/PhantomReachableTest.kt new file mode 100644 index 0000000..db10ab6 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/PhantomReachableTest.kt @@ -0,0 +1,27 @@ +package com.cas_parser.api.core + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class PhantomReachableTest { + + @Test + fun closeWhenPhantomReachable_whenObservedIsGarbageCollected_closesCloseable() { + var closed = false + val closeable = AutoCloseable { closed = true } + + closeWhenPhantomReachable( + // Pass an inline object for the object to observe so that it becomes immediately + // unreachable. + Any(), + closeable, + ) + + assertThat(closed).isFalse() + + System.gc() + Thread.sleep(100) + + assertThat(closed).isTrue() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/UtilsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/UtilsTest.kt new file mode 100644 index 0000000..fe6240b --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/UtilsTest.kt @@ -0,0 +1,33 @@ +package com.cas_parser.api.core + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class UtilsTest { + @Test + fun contentDeepEquals() { + assertThat(42 contentEquals 42).isTrue() + assertThat(42 contentEquals "Hello World!").isFalse() + assertThat(byteArrayOf(1, 2, 3) contentEquals byteArrayOf(1, 2, 3)).isTrue() + assertThat(byteArrayOf(1, 2, 3) contentEquals byteArrayOf(1, 2, 4)).isFalse() + assertThat( + arrayOf(byteArrayOf(1, 2), byteArrayOf(3)) contentEquals + arrayOf(byteArrayOf(1, 2), byteArrayOf(3)) + ) + .isTrue() + assertThat( + arrayOf(byteArrayOf(1, 2), byteArrayOf(3)) contentEquals + arrayOf(byteArrayOf(1), byteArrayOf(2, 3)) + ) + .isFalse() + } + + @Test + fun contentToString() { + assertThat((42).contentToString()).isEqualTo("42") + assertThat("Hello World!".contentToString()).isEqualTo("Hello World!") + assertThat(byteArrayOf(1, 2, 3).contentToString()).isEqualTo("[1, 2, 3]") + assertThat(arrayOf(byteArrayOf(1, 2), byteArrayOf(3)).contentToString()) + .isEqualTo("[[1, 2], [3]]") + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/ValuesTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/ValuesTest.kt new file mode 100644 index 0000000..8fd7b86 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/ValuesTest.kt @@ -0,0 +1,144 @@ +package com.cas_parser.api.core + +import java.util.Optional +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.EnumSource + +internal class ValuesTest { + companion object { + private val NON_JSON = Any() + } + + enum class TestCase( + val value: JsonField<*>, + val expectedIsMissing: Boolean = false, + val expectedIsNull: Boolean = false, + val expectedAsKnown: Optional<*> = Optional.empty(), + val expectedAsBoolean: Optional = Optional.empty(), + val expectedAsNumber: Optional = Optional.empty(), + val expectedAsString: Optional = Optional.empty(), + val expectedAsArray: Optional> = Optional.empty(), + val expectedAsObject: Optional> = Optional.empty(), + ) { + MISSING(JsonMissing.of(), expectedIsMissing = true), + NULL(JsonNull.of(), expectedIsNull = true), + KNOWN(KnownValue.of(NON_JSON), expectedAsKnown = Optional.of(NON_JSON)), + KNOWN_BOOLEAN( + KnownValue.of(true), + expectedAsKnown = Optional.of(true), + expectedAsBoolean = Optional.of(true), + ), + BOOLEAN(JsonBoolean.of(true), expectedAsBoolean = Optional.of(true)), + KNOWN_NUMBER( + KnownValue.of(42), + expectedAsKnown = Optional.of(42), + expectedAsNumber = Optional.of(42), + ), + NUMBER(JsonNumber.of(42), expectedAsNumber = Optional.of(42)), + KNOWN_STRING( + KnownValue.of("hello"), + expectedAsKnown = Optional.of("hello"), + expectedAsString = Optional.of("hello"), + ), + STRING(JsonString.of("hello"), expectedAsString = Optional.of("hello")), + KNOWN_ARRAY_NOT_ALL_JSON( + KnownValue.of(listOf("a", "b", NON_JSON)), + expectedAsKnown = Optional.of(listOf("a", "b", NON_JSON)), + ), + KNOWN_ARRAY( + KnownValue.of(listOf("a", "b", "c")), + expectedAsKnown = Optional.of(listOf("a", "b", "c")), + expectedAsArray = + Optional.of(listOf(JsonString.of("a"), JsonString.of("b"), JsonString.of("c"))), + ), + ARRAY( + JsonArray.of(listOf(JsonString.of("a"), JsonString.of("b"), JsonString.of("c"))), + expectedAsArray = + Optional.of(listOf(JsonString.of("a"), JsonString.of("b"), JsonString.of("c"))), + ), + KNOWN_OBJECT_NOT_ALL_STRING_KEYS( + KnownValue.of(mapOf("a" to "b", 42 to "c")), + expectedAsKnown = Optional.of(mapOf("a" to "b", 42 to "c")), + ), + KNOWN_OBJECT_NOT_ALL_JSON( + KnownValue.of(mapOf("a" to "b", "b" to NON_JSON)), + expectedAsKnown = Optional.of(mapOf("a" to "b", "b" to NON_JSON)), + ), + KNOWN_OBJECT( + KnownValue.of(mapOf("a" to "b", "b" to "c")), + expectedAsKnown = Optional.of(mapOf("a" to "b", "b" to "c")), + expectedAsObject = + Optional.of(mapOf("a" to JsonString.of("b"), "b" to JsonString.of("c"))), + ), + OBJECT( + JsonObject.of(mapOf("a" to JsonString.of("b"), "b" to JsonString.of("c"))), + expectedAsObject = + Optional.of(mapOf("a" to JsonString.of("b"), "b" to JsonString.of("c"))), + ), + } + + @ParameterizedTest + @EnumSource + fun isMissing(testCase: TestCase) { + val isMissing = testCase.value.isMissing() + + assertThat(isMissing).isEqualTo(testCase.expectedIsMissing) + } + + @ParameterizedTest + @EnumSource + fun isNull(testCase: TestCase) { + val isNull = testCase.value.isNull() + + assertThat(isNull).isEqualTo(testCase.expectedIsNull) + } + + @ParameterizedTest + @EnumSource + fun asKnown(testCase: TestCase) { + val known = testCase.value.asKnown() + + assertThat(known).isEqualTo(testCase.expectedAsKnown) + } + + @ParameterizedTest + @EnumSource + fun asBoolean(testCase: TestCase) { + val boolean = testCase.value.asBoolean() + + assertThat(boolean).isEqualTo(testCase.expectedAsBoolean) + } + + @ParameterizedTest + @EnumSource + fun asNumber(testCase: TestCase) { + val number = testCase.value.asNumber() + + assertThat(number).isEqualTo(testCase.expectedAsNumber) + } + + @ParameterizedTest + @EnumSource + fun asString(testCase: TestCase) { + val string = testCase.value.asString() + + assertThat(string).isEqualTo(testCase.expectedAsString) + } + + @ParameterizedTest + @EnumSource + fun asArray(testCase: TestCase) { + val array = testCase.value.asArray() + + assertThat(array).isEqualTo(testCase.expectedAsArray) + } + + @ParameterizedTest + @EnumSource + fun asObject(testCase: TestCase) { + val obj = testCase.value.asObject() + + assertThat(obj).isEqualTo(testCase.expectedAsObject) + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/AsyncStreamResponseTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/AsyncStreamResponseTest.kt new file mode 100644 index 0000000..6f3ec90 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/AsyncStreamResponseTest.kt @@ -0,0 +1,268 @@ +package com.cas_parser.api.core.http + +import java.util.* +import java.util.concurrent.CompletableFuture +import java.util.concurrent.Executor +import java.util.stream.Stream +import kotlin.streams.asStream +import org.assertj.core.api.Assertions.assertThat +import org.assertj.core.api.Assertions.catchThrowable +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertDoesNotThrow +import org.junit.jupiter.api.extension.ExtendWith +import org.mockito.junit.jupiter.MockitoExtension +import org.mockito.kotlin.* + +@ExtendWith(MockitoExtension::class) +internal class AsyncStreamResponseTest { + + companion object { + private val ERROR = RuntimeException("ERROR!") + } + + private val streamResponse = + spy> { + doReturn(Stream.of("chunk1", "chunk2", "chunk3")).whenever(it).stream() + } + private val erroringStreamResponse = + spy> { + doReturn( + sequence { + yield("chunk1") + yield("chunk2") + throw ERROR + } + .asStream() + ) + .whenever(it) + .stream() + } + private val executor = + spy { + doAnswer { invocation -> invocation.getArgument(0).run() } + .whenever(it) + .execute(any()) + } + private val handler = mock>() + + @Test + fun subscribe_whenAlreadySubscribed_throws() { + val asyncStreamResponse = CompletableFuture>().toAsync(executor) + asyncStreamResponse.subscribe {} + + val throwable = catchThrowable { asyncStreamResponse.subscribe {} } + + assertThat(throwable).isInstanceOf(IllegalStateException::class.java) + assertThat(throwable).hasMessage("Cannot subscribe more than once") + verify(executor, never()).execute(any()) + } + + @Test + fun subscribe_whenClosed_throws() { + val asyncStreamResponse = CompletableFuture>().toAsync(executor) + asyncStreamResponse.close() + + val throwable = catchThrowable { asyncStreamResponse.subscribe {} } + + assertThat(throwable).isInstanceOf(IllegalStateException::class.java) + assertThat(throwable).hasMessage("Cannot subscribe after the response is closed") + verify(executor, never()).execute(any()) + } + + @Test + fun subscribe_whenFutureCompletesAfterClose_doesNothing() { + val future = CompletableFuture>() + val asyncStreamResponse = future.toAsync(executor) + asyncStreamResponse.subscribe(handler) + asyncStreamResponse.close() + + future.complete(streamResponse) + + verify(handler, never()).onNext(any()) + verify(handler, never()).onComplete(any()) + verify(executor, times(1)).execute(any()) + } + + @Test + fun subscribe_whenFutureErrors_callsOnComplete() { + val future = CompletableFuture>() + val asyncStreamResponse = future.toAsync(executor) + asyncStreamResponse.subscribe(handler) + + future.completeExceptionally(ERROR) + + verify(handler, never()).onNext(any()) + verify(handler, times(1)).onComplete(Optional.of(ERROR)) + verify(executor, times(1)).execute(any()) + } + + @Test + fun subscribe_whenFutureCompletes_runsHandler() { + val future = CompletableFuture>() + val asyncStreamResponse = future.toAsync(executor) + asyncStreamResponse.subscribe(handler) + + future.complete(streamResponse) + + inOrder(handler, streamResponse) { + verify(handler, times(1)).onNext("chunk1") + verify(handler, times(1)).onNext("chunk2") + verify(handler, times(1)).onNext("chunk3") + verify(handler, times(1)).onComplete(Optional.empty()) + verify(streamResponse, times(1)).close() + } + verify(executor, times(1)).execute(any()) + } + + @Test + fun subscribe_whenStreamErrors_callsOnCompleteEarly() { + val future = CompletableFuture>() + val asyncStreamResponse = future.toAsync(executor) + asyncStreamResponse.subscribe(handler) + + future.complete(erroringStreamResponse) + + inOrder(handler, erroringStreamResponse) { + verify(handler, times(1)).onNext("chunk1") + verify(handler, times(1)).onNext("chunk2") + verify(handler, times(1)).onComplete(Optional.of(ERROR)) + verify(erroringStreamResponse, times(1)).close() + } + verify(executor, times(1)).execute(any()) + } + + @Test + fun onCompleteFuture_whenStreamResponseFutureNotCompleted_onCompleteFutureNotCompleted() { + val future = CompletableFuture>() + val asyncStreamResponse = future.toAsync(executor) + + val onCompletableFuture = asyncStreamResponse.onCompleteFuture() + + assertThat(onCompletableFuture).isNotCompleted + } + + @Test + fun onCompleteFuture_whenStreamResponseFutureErrors_onCompleteFutureCompletedExceptionally() { + val future = CompletableFuture>() + val asyncStreamResponse = future.toAsync(executor) + future.completeExceptionally(ERROR) + + val onCompletableFuture = asyncStreamResponse.onCompleteFuture() + + assertThat(onCompletableFuture).isCompletedExceptionally + } + + @Test + fun onCompleteFuture_whenStreamResponseFutureCompletedButStillStreaming_onCompleteFutureNotCompleted() { + val future = CompletableFuture>() + val asyncStreamResponse = future.toAsync(executor) + future.complete(streamResponse) + + val onCompletableFuture = asyncStreamResponse.onCompleteFuture() + + assertThat(onCompletableFuture).isNotCompleted + } + + @Test + fun onCompleteFuture_whenStreamResponseFutureCompletedAndStreamErrors_onCompleteFutureCompletedExceptionally() { + val future = CompletableFuture>() + val asyncStreamResponse = future.toAsync(executor) + asyncStreamResponse.subscribe(handler) + future.complete(erroringStreamResponse) + + val onCompletableFuture = asyncStreamResponse.onCompleteFuture() + + assertThat(onCompletableFuture).isCompletedExceptionally + } + + @Test + fun onCompleteFuture_whenStreamResponseFutureCompletedAndStreamCompleted_onCompleteFutureCompleted() { + val future = CompletableFuture>() + val asyncStreamResponse = future.toAsync(executor) + asyncStreamResponse.subscribe(handler) + future.complete(streamResponse) + + val onCompletableFuture = asyncStreamResponse.onCompleteFuture() + + assertThat(onCompletableFuture).isCompleted + } + + @Test + fun onCompleteFuture_whenHandlerOnCompleteWithoutThrowableThrows_onCompleteFutureCompleted() { + val future = CompletableFuture>() + val asyncStreamResponse = future.toAsync(executor) + asyncStreamResponse.subscribe( + object : AsyncStreamResponse.Handler { + override fun onNext(value: String) {} + + override fun onComplete(error: Optional) = throw ERROR + } + ) + future.complete(streamResponse) + + val onCompletableFuture = asyncStreamResponse.onCompleteFuture() + + assertThat(onCompletableFuture).isCompleted + } + + @Test + fun onCompleteFuture_whenHandlerOnCompleteWithThrowableThrows_onCompleteFutureCompletedExceptionally() { + val future = CompletableFuture>() + val asyncStreamResponse = future.toAsync(executor) + asyncStreamResponse.subscribe( + object : AsyncStreamResponse.Handler { + override fun onNext(value: String) {} + + override fun onComplete(error: Optional) = throw ERROR + } + ) + future.complete(erroringStreamResponse) + + val onCompletableFuture = asyncStreamResponse.onCompleteFuture() + + assertThat(onCompletableFuture).isCompletedExceptionally + } + + @Test + fun onCompleteFuture_whenClosed_onCompleteFutureCompleted() { + val future = CompletableFuture>() + val asyncStreamResponse = future.toAsync(executor) + asyncStreamResponse.close() + + val onCompletableFuture = asyncStreamResponse.onCompleteFuture() + + assertThat(onCompletableFuture).isCompleted + } + + @Test + fun close_whenNotClosed_closesStreamResponse() { + val future = CompletableFuture>() + val asyncStreamResponse = future.toAsync(executor) + + asyncStreamResponse.close() + future.complete(streamResponse) + + verify(streamResponse, times(1)).close() + } + + @Test + fun close_whenAlreadyClosed_doesNothing() { + val future = CompletableFuture>() + val asyncStreamResponse = future.toAsync(executor) + asyncStreamResponse.close() + future.complete(streamResponse) + + asyncStreamResponse.close() + + verify(streamResponse, times(1)).close() + } + + @Test + fun close_whenFutureErrors_doesNothing() { + val future = CompletableFuture>() + val asyncStreamResponse = future.toAsync(executor) + asyncStreamResponse.close() + + assertDoesNotThrow { future.completeExceptionally(ERROR) } + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/HeadersTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/HeadersTest.kt new file mode 100644 index 0000000..0105fd1 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/HeadersTest.kt @@ -0,0 +1,242 @@ +package com.cas_parser.api.core.http + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.EnumSource + +internal class HeadersTest { + + enum class TestCase( + val headers: Headers, + val expectedMap: Map>, + val expectedSize: Int, + ) { + EMPTY(Headers.builder().build(), expectedMap = mapOf(), expectedSize = 0), + PUT_ONE( + Headers.builder().put("name", "value").build(), + expectedMap = mapOf("name" to listOf("value")), + expectedSize = 1, + ), + PUT_MULTIPLE( + Headers.builder().put("name", listOf("value1", "value2")).build(), + expectedMap = mapOf("name" to listOf("value1", "value2")), + expectedSize = 2, + ), + MULTIPLE_PUT( + Headers.builder().put("name1", "value").put("name2", "value").build(), + expectedMap = mapOf("name1" to listOf("value"), "name2" to listOf("value")), + expectedSize = 2, + ), + MULTIPLE_PUT_SAME_NAME( + Headers.builder().put("name", "value1").put("name", "value2").build(), + expectedMap = mapOf("name" to listOf("value1", "value2")), + expectedSize = 2, + ), + MULTIPLE_PUT_MULTIPLE( + Headers.builder() + .put("name", listOf("value1", "value2")) + .put("name", listOf("value1", "value2")) + .build(), + expectedMap = mapOf("name" to listOf("value1", "value2", "value1", "value2")), + expectedSize = 4, + ), + PUT_CASE_INSENSITIVE( + Headers.builder() + .put("name", "value1") + .put("NAME", "value2") + .put("nAmE", "value3") + .build(), + expectedMap = mapOf("name" to listOf("value1", "value2", "value3")), + expectedSize = 3, + ), + PUT_ALL_MAP( + Headers.builder() + .putAll( + mapOf( + "name1" to listOf("value1", "value2"), + "name2" to listOf("value1", "value2"), + ) + ) + .build(), + expectedMap = + mapOf("name1" to listOf("value1", "value2"), "name2" to listOf("value1", "value2")), + expectedSize = 4, + ), + PUT_ALL_HEADERS( + Headers.builder().putAll(Headers.builder().put("name", "value").build()).build(), + expectedMap = mapOf("name" to listOf("value")), + expectedSize = 1, + ), + PUT_ALL_CASE_INSENSITIVE( + Headers.builder() + .putAll( + mapOf( + "name" to listOf("value1"), + "NAME" to listOf("value2"), + "nAmE" to listOf("value3"), + ) + ) + .build(), + expectedMap = mapOf("name" to listOf("value1", "value2", "value3")), + expectedSize = 3, + ), + REMOVE_ABSENT( + Headers.builder().remove("name").build(), + expectedMap = mapOf(), + expectedSize = 0, + ), + REMOVE_PRESENT_ONE( + Headers.builder().put("name", "value").remove("name").build(), + expectedMap = mapOf(), + expectedSize = 0, + ), + REMOVE_PRESENT_MULTIPLE( + Headers.builder().put("name", listOf("value1", "value2")).remove("name").build(), + expectedMap = mapOf(), + expectedSize = 0, + ), + REMOVE_CASE_INSENSITIVE( + Headers.builder().put("name", listOf("value1", "value2")).remove("NAME").build(), + expectedMap = mapOf(), + expectedSize = 0, + ), + REMOVE_ALL( + Headers.builder() + .put("name1", "value") + .put("name3", "value") + .removeAll(setOf("name1", "name2", "name3")) + .build(), + expectedMap = mapOf(), + expectedSize = 0, + ), + REMOVE_ALL_CASE_INSENSITIVE( + Headers.builder() + .put("name1", "value") + .put("name3", "value") + .removeAll(setOf("NAME1", "nAmE3")) + .build(), + expectedMap = mapOf(), + expectedSize = 0, + ), + CLEAR( + Headers.builder().put("name1", "value").put("name2", "value").clear().build(), + expectedMap = mapOf(), + expectedSize = 0, + ), + REPLACE_ONE_ABSENT( + Headers.builder().replace("name", "value").build(), + expectedMap = mapOf("name" to listOf("value")), + expectedSize = 1, + ), + REPLACE_ONE_PRESENT_ONE( + Headers.builder().put("name", "value1").replace("name", "value2").build(), + expectedMap = mapOf("name" to listOf("value2")), + expectedSize = 1, + ), + REPLACE_ONE_PRESENT_MULTIPLE( + Headers.builder() + .put("name", listOf("value1", "value2")) + .replace("name", "value3") + .build(), + expectedMap = mapOf("name" to listOf("value3")), + expectedSize = 1, + ), + REPLACE_MULTIPLE_ABSENT( + Headers.builder().replace("name", listOf("value1", "value2")).build(), + expectedMap = mapOf("name" to listOf("value1", "value2")), + expectedSize = 2, + ), + REPLACE_MULTIPLE_PRESENT_ONE( + Headers.builder() + .put("name", "value1") + .replace("name", listOf("value2", "value3")) + .build(), + expectedMap = mapOf("name" to listOf("value2", "value3")), + expectedSize = 2, + ), + REPLACE_MULTIPLE_PRESENT_MULTIPLE( + Headers.builder() + .put("name", listOf("value1", "value2")) + .replace("name", listOf("value3", "value4")) + .build(), + expectedMap = mapOf("name" to listOf("value3", "value4")), + expectedSize = 2, + ), + REPLACE_CASE_INSENSITIVE( + Headers.builder() + .put("name", "value1") + .replace("NAME", listOf("value2", "value3")) + .build(), + expectedMap = mapOf("NAME" to listOf("value2", "value3")), + expectedSize = 2, + ), + REPLACE_ALL_MAP( + Headers.builder() + .put("name1", "value1") + .put("name2", "value1") + .put("name3", "value1") + .replaceAll(mapOf("name1" to listOf("value2"), "name3" to listOf("value2"))) + .build(), + expectedMap = + mapOf( + "name1" to listOf("value2"), + "name2" to listOf("value1"), + "name3" to listOf("value2"), + ), + expectedSize = 3, + ), + REPLACE_ALL_HEADERS( + Headers.builder() + .put("name1", "value1") + .put("name2", "value1") + .put("name3", "value1") + .replaceAll(Headers.builder().put("name1", "value2").put("name3", "value2").build()) + .build(), + expectedMap = + mapOf( + "name1" to listOf("value2"), + "name2" to listOf("value1"), + "name3" to listOf("value2"), + ), + expectedSize = 3, + ), + REPLACE_ALL_CASE_INSENSITIVE( + Headers.builder() + .put("name1", "value1") + .put("name2", "value1") + .replaceAll(mapOf("NAME1" to listOf("value2"), "nAmE2" to listOf("value2"))) + .build(), + expectedMap = mapOf("NAME1" to listOf("value2"), "nAmE2" to listOf("value2")), + expectedSize = 2, + ), + } + + @ParameterizedTest + @EnumSource + fun namesAndValues(testCase: TestCase) { + val map = mutableMapOf>() + val headers = testCase.headers + headers.names().forEach { name -> map[name] = headers.values(name) } + + assertThat(map).isEqualTo(testCase.expectedMap) + } + + @ParameterizedTest + @EnumSource + fun caseInsensitiveNames(testCase: TestCase) { + val headers = testCase.headers + + for (name in headers.names()) { + assertThat(headers.values(name)).isEqualTo(headers.values(name.lowercase())) + assertThat(headers.values(name)).isEqualTo(headers.values(name.uppercase())) + } + } + + @ParameterizedTest + @EnumSource + fun size(testCase: TestCase) { + val size = testCase.headers.size + + assertThat(size).isEqualTo(testCase.expectedSize) + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/QueryParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/QueryParamsTest.kt new file mode 100644 index 0000000..8ad1fbc --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/QueryParamsTest.kt @@ -0,0 +1,180 @@ +package com.cas_parser.api.core.http + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.EnumSource + +internal class QueryParamsTest { + + enum class TestCase( + val queryParams: QueryParams, + val expectedMap: Map>, + val expectedSize: Int, + ) { + EMPTY(QueryParams.builder().build(), expectedMap = mapOf(), expectedSize = 0), + PUT_ONE( + QueryParams.builder().put("key", "value").build(), + expectedMap = mapOf("key" to listOf("value")), + expectedSize = 1, + ), + PUT_MULTIPLE( + QueryParams.builder().put("key", listOf("value1", "value2")).build(), + expectedMap = mapOf("key" to listOf("value1", "value2")), + expectedSize = 2, + ), + MULTIPLE_PUT( + QueryParams.builder().put("key1", "value").put("key2", "value").build(), + expectedMap = mapOf("key1" to listOf("value"), "key2" to listOf("value")), + expectedSize = 2, + ), + MULTIPLE_PUT_SAME_NAME( + QueryParams.builder().put("key", "value1").put("key", "value2").build(), + expectedMap = mapOf("key" to listOf("value1", "value2")), + expectedSize = 2, + ), + MULTIPLE_PUT_MULTIPLE( + QueryParams.builder() + .put("key", listOf("value1", "value2")) + .put("key", listOf("value1", "value2")) + .build(), + expectedMap = mapOf("key" to listOf("value1", "value2", "value1", "value2")), + expectedSize = 4, + ), + PUT_ALL_MAP( + QueryParams.builder() + .putAll( + mapOf( + "key1" to listOf("value1", "value2"), + "key2" to listOf("value1", "value2"), + ) + ) + .build(), + expectedMap = + mapOf("key1" to listOf("value1", "value2"), "key2" to listOf("value1", "value2")), + expectedSize = 4, + ), + PUT_ALL_HEADERS( + QueryParams.builder().putAll(QueryParams.builder().put("key", "value").build()).build(), + expectedMap = mapOf("key" to listOf("value")), + expectedSize = 1, + ), + REMOVE_ABSENT( + QueryParams.builder().remove("key").build(), + expectedMap = mapOf(), + expectedSize = 0, + ), + REMOVE_PRESENT_ONE( + QueryParams.builder().put("key", "value").remove("key").build(), + expectedMap = mapOf(), + expectedSize = 0, + ), + REMOVE_PRESENT_MULTIPLE( + QueryParams.builder().put("key", listOf("value1", "value2")).remove("key").build(), + expectedMap = mapOf(), + expectedSize = 0, + ), + REMOVE_ALL( + QueryParams.builder() + .put("key1", "value") + .put("key3", "value") + .removeAll(setOf("key1", "key2", "key3")) + .build(), + expectedMap = mapOf(), + expectedSize = 0, + ), + CLEAR( + QueryParams.builder().put("key1", "value").put("key2", "value").clear().build(), + expectedMap = mapOf(), + expectedSize = 0, + ), + REPLACE_ONE_ABSENT( + QueryParams.builder().replace("key", "value").build(), + expectedMap = mapOf("key" to listOf("value")), + expectedSize = 1, + ), + REPLACE_ONE_PRESENT_ONE( + QueryParams.builder().put("key", "value1").replace("key", "value2").build(), + expectedMap = mapOf("key" to listOf("value2")), + expectedSize = 1, + ), + REPLACE_ONE_PRESENT_MULTIPLE( + QueryParams.builder() + .put("key", listOf("value1", "value2")) + .replace("key", "value3") + .build(), + expectedMap = mapOf("key" to listOf("value3")), + expectedSize = 1, + ), + REPLACE_MULTIPLE_ABSENT( + QueryParams.builder().replace("key", listOf("value1", "value2")).build(), + expectedMap = mapOf("key" to listOf("value1", "value2")), + expectedSize = 2, + ), + REPLACE_MULTIPLE_PRESENT_ONE( + QueryParams.builder() + .put("key", "value1") + .replace("key", listOf("value2", "value3")) + .build(), + expectedMap = mapOf("key" to listOf("value2", "value3")), + expectedSize = 2, + ), + REPLACE_MULTIPLE_PRESENT_MULTIPLE( + QueryParams.builder() + .put("key", listOf("value1", "value2")) + .replace("key", listOf("value3", "value4")) + .build(), + expectedMap = mapOf("key" to listOf("value3", "value4")), + expectedSize = 2, + ), + REPLACE_ALL_MAP( + QueryParams.builder() + .put("key1", "value1") + .put("key2", "value1") + .put("key3", "value1") + .replaceAll(mapOf("key1" to listOf("value2"), "key3" to listOf("value2"))) + .build(), + expectedMap = + mapOf( + "key1" to listOf("value2"), + "key2" to listOf("value1"), + "key3" to listOf("value2"), + ), + expectedSize = 3, + ), + REPLACE_ALL_HEADERS( + QueryParams.builder() + .put("key1", "value1") + .put("key2", "value1") + .put("key3", "value1") + .replaceAll( + QueryParams.builder().put("key1", "value2").put("key3", "value2").build() + ) + .build(), + expectedMap = + mapOf( + "key1" to listOf("value2"), + "key2" to listOf("value1"), + "key3" to listOf("value2"), + ), + expectedSize = 3, + ), + } + + @ParameterizedTest + @EnumSource + fun keysAndValues(testCase: TestCase) { + val map = mutableMapOf>() + val queryParams = testCase.queryParams + queryParams.keys().forEach { key -> map[key] = queryParams.values(key) } + + assertThat(map).isEqualTo(testCase.expectedMap) + } + + @ParameterizedTest + @EnumSource + fun size(testCase: TestCase) { + val size = testCase.queryParams.size + + assertThat(size).isEqualTo(testCase.expectedSize) + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/RetryingHttpClientTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/RetryingHttpClientTest.kt new file mode 100644 index 0000000..d740df3 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/RetryingHttpClientTest.kt @@ -0,0 +1,351 @@ +package com.cas_parser.api.core.http + +import com.cas_parser.api.client.okhttp.OkHttpClient +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.errors.CasParserRetryableException +import com.github.tomakehurst.wiremock.client.WireMock.* +import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo +import com.github.tomakehurst.wiremock.junit5.WireMockTest +import com.github.tomakehurst.wiremock.stubbing.Scenario +import java.io.InputStream +import java.time.Duration +import java.util.concurrent.CompletableFuture +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.parallel.ResourceLock +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.ValueSource + +@WireMockTest +@ResourceLock("https://github.com/wiremock/wiremock/issues/169") +internal class RetryingHttpClientTest { + + private var openResponseCount = 0 + private lateinit var baseUrl: String + private lateinit var httpClient: HttpClient + + @BeforeEach + fun beforeEach(wmRuntimeInfo: WireMockRuntimeInfo) { + baseUrl = wmRuntimeInfo.httpBaseUrl + val okHttpClient = OkHttpClient.builder().build() + httpClient = + object : HttpClient { + + override fun execute( + request: HttpRequest, + requestOptions: RequestOptions, + ): HttpResponse = trackClose(okHttpClient.execute(request, requestOptions)) + + override fun executeAsync( + request: HttpRequest, + requestOptions: RequestOptions, + ): CompletableFuture = + okHttpClient.executeAsync(request, requestOptions).thenApply { trackClose(it) } + + override fun close() = okHttpClient.close() + + private fun trackClose(response: HttpResponse): HttpResponse { + openResponseCount++ + return object : HttpResponse { + + private var isClosed = false + + override fun statusCode(): Int = response.statusCode() + + override fun headers(): Headers = response.headers() + + override fun body(): InputStream = response.body() + + override fun close() { + response.close() + if (isClosed) { + return + } + openResponseCount-- + isClosed = true + } + } + } + } + resetAllScenarios() + } + + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun execute(async: Boolean) { + stubFor(post(urlPathEqualTo("/something")).willReturn(ok())) + val retryingClient = retryingHttpClientBuilder().build() + + val response = + retryingClient.execute( + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(baseUrl) + .addPathSegment("something") + .build(), + async, + ) + + assertThat(response.statusCode()).isEqualTo(200) + verify(1, postRequestedFor(urlPathEqualTo("/something"))) + assertNoResponseLeaks() + } + + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun execute_withIdempotencyHeader(async: Boolean) { + stubFor( + post(urlPathEqualTo("/something")) + .withHeader("X-Some-Header", matching("stainless-java-retry-.+")) + .willReturn(ok()) + ) + val retryingClient = + retryingHttpClientBuilder().maxRetries(2).idempotencyHeader("X-Some-Header").build() + + val response = + retryingClient.execute( + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(baseUrl) + .addPathSegment("something") + .build(), + async, + ) + + assertThat(response.statusCode()).isEqualTo(200) + verify(1, postRequestedFor(urlPathEqualTo("/something"))) + assertNoResponseLeaks() + } + + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun execute_withRetryAfterHeader(async: Boolean) { + stubFor( + post(urlPathEqualTo("/something")) + // First we fail with a retry after header given as a date + .inScenario("foo") + .whenScenarioStateIs(Scenario.STARTED) + .willReturn( + serviceUnavailable().withHeader("Retry-After", "Wed, 21 Oct 2015 07:28:00 GMT") + ) + .willSetStateTo("RETRY_AFTER_DATE") + ) + stubFor( + post(urlPathEqualTo("/something")) + // Then we fail with a retry after header given as a delay + .inScenario("foo") + .whenScenarioStateIs("RETRY_AFTER_DATE") + .willReturn(serviceUnavailable().withHeader("Retry-After", "1.234")) + .willSetStateTo("RETRY_AFTER_DELAY") + ) + stubFor( + post(urlPathEqualTo("/something")) + // Then we return a success + .inScenario("foo") + .whenScenarioStateIs("RETRY_AFTER_DELAY") + .willReturn(ok()) + .willSetStateTo("COMPLETED") + ) + val retryingClient = retryingHttpClientBuilder().maxRetries(2).build() + + val response = + retryingClient.execute( + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(baseUrl) + .addPathSegment("something") + .build(), + async, + ) + + assertThat(response.statusCode()).isEqualTo(200) + verify( + 1, + postRequestedFor(urlPathEqualTo("/something")) + .withHeader("x-stainless-retry-count", equalTo("0")), + ) + verify( + 1, + postRequestedFor(urlPathEqualTo("/something")) + .withHeader("x-stainless-retry-count", equalTo("1")), + ) + verify( + 1, + postRequestedFor(urlPathEqualTo("/something")) + .withHeader("x-stainless-retry-count", equalTo("2")), + ) + assertNoResponseLeaks() + } + + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun execute_withOverwrittenRetryCountHeader(async: Boolean) { + stubFor( + post(urlPathEqualTo("/something")) + .inScenario("foo") // first we fail with a retry after header given as a date + .whenScenarioStateIs(Scenario.STARTED) + .willReturn( + serviceUnavailable().withHeader("Retry-After", "Wed, 21 Oct 2015 07:28:00 GMT") + ) + .willSetStateTo("RETRY_AFTER_DATE") + ) + stubFor( + post(urlPathEqualTo("/something")) + .inScenario("foo") // then we return a success + .whenScenarioStateIs("RETRY_AFTER_DATE") + .willReturn(ok()) + .willSetStateTo("COMPLETED") + ) + val retryingClient = retryingHttpClientBuilder().maxRetries(2).build() + + val response = + retryingClient.execute( + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(baseUrl) + .addPathSegment("something") + .putHeader("x-stainless-retry-count", "42") + .build(), + async, + ) + + assertThat(response.statusCode()).isEqualTo(200) + verify( + 2, + postRequestedFor(urlPathEqualTo("/something")) + .withHeader("x-stainless-retry-count", equalTo("42")), + ) + assertNoResponseLeaks() + } + + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun execute_withRetryAfterMsHeader(async: Boolean) { + stubFor( + post(urlPathEqualTo("/something")) + .inScenario("foo") + .whenScenarioStateIs(Scenario.STARTED) + .willReturn(serviceUnavailable().withHeader("Retry-After-Ms", "10")) + .willSetStateTo("RETRY_AFTER_DELAY") + ) + stubFor( + post(urlPathEqualTo("/something")) + .inScenario("foo") // then we return a success + .whenScenarioStateIs("RETRY_AFTER_DELAY") + .willReturn(ok()) + .willSetStateTo("COMPLETED") + ) + val retryingClient = retryingHttpClientBuilder().maxRetries(1).build() + + val response = + retryingClient.execute( + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(baseUrl) + .addPathSegment("something") + .build(), + async, + ) + + assertThat(response.statusCode()).isEqualTo(200) + verify(2, postRequestedFor(urlPathEqualTo("/something"))) + assertNoResponseLeaks() + } + + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun execute_withRetryableException(async: Boolean) { + stubFor(post(urlPathEqualTo("/something")).willReturn(ok())) + + var callCount = 0 + val failingHttpClient = + object : HttpClient { + override fun execute( + request: HttpRequest, + requestOptions: RequestOptions, + ): HttpResponse { + callCount++ + if (callCount == 1) { + throw CasParserRetryableException("Simulated retryable failure") + } + return httpClient.execute(request, requestOptions) + } + + override fun executeAsync( + request: HttpRequest, + requestOptions: RequestOptions, + ): CompletableFuture { + callCount++ + if (callCount == 1) { + val future = CompletableFuture() + future.completeExceptionally( + CasParserRetryableException("Simulated retryable failure") + ) + return future + } + return httpClient.executeAsync(request, requestOptions) + } + + override fun close() = httpClient.close() + } + + val retryingClient = + RetryingHttpClient.builder() + .httpClient(failingHttpClient) + .maxRetries(2) + .sleeper( + object : RetryingHttpClient.Sleeper { + + override fun sleep(duration: Duration) {} + + override fun sleepAsync(duration: Duration): CompletableFuture = + CompletableFuture.completedFuture(null) + } + ) + .build() + + val response = + retryingClient.execute( + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(baseUrl) + .addPathSegment("something") + .build(), + async, + ) + + assertThat(response.statusCode()).isEqualTo(200) + verify( + 1, + postRequestedFor(urlPathEqualTo("/something")) + .withHeader("x-stainless-retry-count", equalTo("1")), + ) + verify( + 0, + postRequestedFor(urlPathEqualTo("/something")) + .withHeader("x-stainless-retry-count", equalTo("0")), + ) + assertNoResponseLeaks() + } + + private fun retryingHttpClientBuilder() = + RetryingHttpClient.builder() + .httpClient(httpClient) + // Use a no-op `Sleeper` to make the test fast. + .sleeper( + object : RetryingHttpClient.Sleeper { + + override fun sleep(duration: Duration) {} + + override fun sleepAsync(duration: Duration): CompletableFuture = + CompletableFuture.completedFuture(null) + } + ) + + private fun HttpClient.execute(request: HttpRequest, async: Boolean): HttpResponse = + if (async) executeAsync(request).get() else execute(request) + + // When retrying, all failed responses should be closed. Only the final returned response should + // be open. + private fun assertNoResponseLeaks() = assertThat(openResponseCount).isEqualTo(1) +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casgenerator/CasGeneratorGenerateCasParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casgenerator/CasGeneratorGenerateCasParamsTest.kt new file mode 100644 index 0000000..24f18c9 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casgenerator/CasGeneratorGenerateCasParamsTest.kt @@ -0,0 +1,62 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.casgenerator + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class CasGeneratorGenerateCasParamsTest { + + @Test + fun create() { + CasGeneratorGenerateCasParams.builder() + .email("user@example.com") + .fromDate("2023-01-01") + .password("Abcdefghi12\$") + .toDate("2023-12-31") + .casAuthority(CasGeneratorGenerateCasParams.CasAuthority.KFINTECH) + .panNo("ABCDE1234F") + .build() + } + + @Test + fun body() { + val params = + CasGeneratorGenerateCasParams.builder() + .email("user@example.com") + .fromDate("2023-01-01") + .password("Abcdefghi12\$") + .toDate("2023-12-31") + .casAuthority(CasGeneratorGenerateCasParams.CasAuthority.KFINTECH) + .panNo("ABCDE1234F") + .build() + + val body = params._body() + + assertThat(body.email()).isEqualTo("user@example.com") + assertThat(body.fromDate()).isEqualTo("2023-01-01") + assertThat(body.password()).isEqualTo("Abcdefghi12\$") + assertThat(body.toDate()).isEqualTo("2023-12-31") + assertThat(body.casAuthority()) + .contains(CasGeneratorGenerateCasParams.CasAuthority.KFINTECH) + assertThat(body.panNo()).contains("ABCDE1234F") + } + + @Test + fun bodyWithoutOptionalFields() { + val params = + CasGeneratorGenerateCasParams.builder() + .email("user@example.com") + .fromDate("2023-01-01") + .password("Abcdefghi12\$") + .toDate("2023-12-31") + .build() + + val body = params._body() + + assertThat(body.email()).isEqualTo("user@example.com") + assertThat(body.fromDate()).isEqualTo("2023-01-01") + assertThat(body.password()).isEqualTo("Abcdefghi12\$") + assertThat(body.toDate()).isEqualTo("2023-12-31") + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casgenerator/CasGeneratorGenerateCasResponseTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casgenerator/CasGeneratorGenerateCasResponseTest.kt new file mode 100644 index 0000000..c225afa --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casgenerator/CasGeneratorGenerateCasResponseTest.kt @@ -0,0 +1,49 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.casgenerator + +import com.cas_parser.api.core.jsonMapper +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class CasGeneratorGenerateCasResponseTest { + + @Test + fun create() { + val casGeneratorGenerateCasResponse = + CasGeneratorGenerateCasResponse.builder() + .msg( + "CAS generation request submitted successfully. The investor will receive the CAS file via email shortly." + ) + .status("success") + .build() + + assertThat(casGeneratorGenerateCasResponse.msg()) + .contains( + "CAS generation request submitted successfully. The investor will receive the CAS file via email shortly." + ) + assertThat(casGeneratorGenerateCasResponse.status()).contains("success") + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val casGeneratorGenerateCasResponse = + CasGeneratorGenerateCasResponse.builder() + .msg( + "CAS generation request submitted successfully. The investor will receive the CAS file via email shortly." + ) + .status("success") + .build() + + val roundtrippedCasGeneratorGenerateCasResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(casGeneratorGenerateCasResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedCasGeneratorGenerateCasResponse) + .isEqualTo(casGeneratorGenerateCasResponse) + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserCamsKfintechParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserCamsKfintechParamsTest.kt new file mode 100644 index 0000000..e85c9de --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserCamsKfintechParamsTest.kt @@ -0,0 +1,72 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.casparser + +import com.cas_parser.api.core.MultipartField +import java.io.InputStream +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class CasParserCamsKfintechParamsTest { + + @Test + fun create() { + CasParserCamsKfintechParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + } + + @Test + fun body() { + val params = + CasParserCamsKfintechParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + + val body = params._body() + + assertThat(body.filterValues { !it.value.isNull() }) + .usingRecursiveComparison() + // TODO(AssertJ): Replace this and the `mapValues` below with: + // https://github.com/assertj/assertj/issues/3165 + .withEqualsForType( + { a, b -> a.readBytes() contentEquals b.readBytes() }, + InputStream::class.java, + ) + .isEqualTo( + mapOf( + "password" to MultipartField.of("password"), + "pdf_file" to MultipartField.of("pdf_file"), + "pdf_url" to MultipartField.of("https://example.com"), + ) + .mapValues { (_, field) -> + field.map { (it as? ByteArray)?.inputStream() ?: it } + } + ) + } + + @Test + fun bodyWithoutOptionalFields() { + val params = CasParserCamsKfintechParams.builder().build() + + val body = params._body() + + assertThat(body.filterValues { !it.value.isNull() }) + .usingRecursiveComparison() + // TODO(AssertJ): Replace this and the `mapValues` below with: + // https://github.com/assertj/assertj/issues/3165 + .withEqualsForType( + { a, b -> a.readBytes() contentEquals b.readBytes() }, + InputStream::class.java, + ) + .isEqualTo( + mapOf().mapValues { (_, field) -> + field.map { (it as? ByteArray)?.inputStream() ?: it } + } + ) + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserCdslParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserCdslParamsTest.kt new file mode 100644 index 0000000..778a492 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserCdslParamsTest.kt @@ -0,0 +1,72 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.casparser + +import com.cas_parser.api.core.MultipartField +import java.io.InputStream +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class CasParserCdslParamsTest { + + @Test + fun create() { + CasParserCdslParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + } + + @Test + fun body() { + val params = + CasParserCdslParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + + val body = params._body() + + assertThat(body.filterValues { !it.value.isNull() }) + .usingRecursiveComparison() + // TODO(AssertJ): Replace this and the `mapValues` below with: + // https://github.com/assertj/assertj/issues/3165 + .withEqualsForType( + { a, b -> a.readBytes() contentEquals b.readBytes() }, + InputStream::class.java, + ) + .isEqualTo( + mapOf( + "password" to MultipartField.of("password"), + "pdf_file" to MultipartField.of("pdf_file"), + "pdf_url" to MultipartField.of("https://example.com"), + ) + .mapValues { (_, field) -> + field.map { (it as? ByteArray)?.inputStream() ?: it } + } + ) + } + + @Test + fun bodyWithoutOptionalFields() { + val params = CasParserCdslParams.builder().build() + + val body = params._body() + + assertThat(body.filterValues { !it.value.isNull() }) + .usingRecursiveComparison() + // TODO(AssertJ): Replace this and the `mapValues` below with: + // https://github.com/assertj/assertj/issues/3165 + .withEqualsForType( + { a, b -> a.readBytes() contentEquals b.readBytes() }, + InputStream::class.java, + ) + .isEqualTo( + mapOf().mapValues { (_, field) -> + field.map { (it as? ByteArray)?.inputStream() ?: it } + } + ) + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserNsdlParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserNsdlParamsTest.kt new file mode 100644 index 0000000..c593b64 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserNsdlParamsTest.kt @@ -0,0 +1,72 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.casparser + +import com.cas_parser.api.core.MultipartField +import java.io.InputStream +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class CasParserNsdlParamsTest { + + @Test + fun create() { + CasParserNsdlParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + } + + @Test + fun body() { + val params = + CasParserNsdlParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + + val body = params._body() + + assertThat(body.filterValues { !it.value.isNull() }) + .usingRecursiveComparison() + // TODO(AssertJ): Replace this and the `mapValues` below with: + // https://github.com/assertj/assertj/issues/3165 + .withEqualsForType( + { a, b -> a.readBytes() contentEquals b.readBytes() }, + InputStream::class.java, + ) + .isEqualTo( + mapOf( + "password" to MultipartField.of("password"), + "pdf_file" to MultipartField.of("pdf_file"), + "pdf_url" to MultipartField.of("https://example.com"), + ) + .mapValues { (_, field) -> + field.map { (it as? ByteArray)?.inputStream() ?: it } + } + ) + } + + @Test + fun bodyWithoutOptionalFields() { + val params = CasParserNsdlParams.builder().build() + + val body = params._body() + + assertThat(body.filterValues { !it.value.isNull() }) + .usingRecursiveComparison() + // TODO(AssertJ): Replace this and the `mapValues` below with: + // https://github.com/assertj/assertj/issues/3165 + .withEqualsForType( + { a, b -> a.readBytes() contentEquals b.readBytes() }, + InputStream::class.java, + ) + .isEqualTo( + mapOf().mapValues { (_, field) -> + field.map { (it as? ByteArray)?.inputStream() ?: it } + } + ) + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserSmartParseParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserSmartParseParamsTest.kt new file mode 100644 index 0000000..f3795e8 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserSmartParseParamsTest.kt @@ -0,0 +1,72 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.casparser + +import com.cas_parser.api.core.MultipartField +import java.io.InputStream +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class CasParserSmartParseParamsTest { + + @Test + fun create() { + CasParserSmartParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + } + + @Test + fun body() { + val params = + CasParserSmartParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + + val body = params._body() + + assertThat(body.filterValues { !it.value.isNull() }) + .usingRecursiveComparison() + // TODO(AssertJ): Replace this and the `mapValues` below with: + // https://github.com/assertj/assertj/issues/3165 + .withEqualsForType( + { a, b -> a.readBytes() contentEquals b.readBytes() }, + InputStream::class.java, + ) + .isEqualTo( + mapOf( + "password" to MultipartField.of("password"), + "pdf_file" to MultipartField.of("pdf_file"), + "pdf_url" to MultipartField.of("https://example.com"), + ) + .mapValues { (_, field) -> + field.map { (it as? ByteArray)?.inputStream() ?: it } + } + ) + } + + @Test + fun bodyWithoutOptionalFields() { + val params = CasParserSmartParseParams.builder().build() + + val body = params._body() + + assertThat(body.filterValues { !it.value.isNull() }) + .usingRecursiveComparison() + // TODO(AssertJ): Replace this and the `mapValues` below with: + // https://github.com/assertj/assertj/issues/3165 + .withEqualsForType( + { a, b -> a.readBytes() contentEquals b.readBytes() }, + InputStream::class.java, + ) + .isEqualTo( + mapOf().mapValues { (_, field) -> + field.map { (it as? ByteArray)?.inputStream() ?: it } + } + ) + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/UnifiedResponseTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/UnifiedResponseTest.kt new file mode 100644 index 0000000..1a5cffc --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/UnifiedResponseTest.kt @@ -0,0 +1,623 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.casparser + +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.jsonMapper +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import java.time.LocalDate +import java.time.OffsetDateTime +import kotlin.jvm.optionals.getOrNull +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class UnifiedResponseTest { + + @Test + fun create() { + val unifiedResponse = + UnifiedResponse.builder() + .addDematAccount( + UnifiedResponse.DematAccount.builder() + .additionalInfo( + UnifiedResponse.DematAccount.AdditionalInfo.builder() + .boStatus("bo_status") + .boSubStatus("bo_sub_status") + .boType("bo_type") + .bsda("bsda") + .email("dev@stainless.com") + .addLinkedPan("string") + .nominee("nominee") + .status("status") + .build() + ) + .boId("bo_id") + .clientId("client_id") + .dematType(UnifiedResponse.DematAccount.DematType.NSDL) + .dpId("dp_id") + .dpName("dp_name") + .holdings( + UnifiedResponse.DematAccount.Holdings.builder() + .addAif( + UnifiedResponse.DematAccount.Holdings.Aif.builder() + .additionalInfo(JsonValue.from(mapOf())) + .isin("isin") + .name("name") + .units(0.0f) + .value(0.0f) + .build() + ) + .addCorporateBond( + UnifiedResponse.DematAccount.Holdings.CorporateBond.builder() + .additionalInfo(JsonValue.from(mapOf())) + .isin("isin") + .name("name") + .units(0.0f) + .value(0.0f) + .build() + ) + .addDematMutualFund( + UnifiedResponse.DematAccount.Holdings.DematMutualFund.builder() + .additionalInfo(JsonValue.from(mapOf())) + .isin("isin") + .name("name") + .units(0.0f) + .value(0.0f) + .build() + ) + .addEquity( + UnifiedResponse.DematAccount.Holdings.Equity.builder() + .additionalInfo(JsonValue.from(mapOf())) + .isin("isin") + .name("name") + .units(0.0f) + .value(0.0f) + .build() + ) + .addGovernmentSecurity( + UnifiedResponse.DematAccount.Holdings.GovernmentSecurity + .builder() + .additionalInfo(JsonValue.from(mapOf())) + .isin("isin") + .name("name") + .units(0.0f) + .value(0.0f) + .build() + ) + .build() + ) + .value(0.0f) + .build() + ) + .insurance( + UnifiedResponse.Insurance.builder() + .addLifeInsurancePolicy( + UnifiedResponse.Insurance.LifeInsurancePolicy.builder() + .additionalInfo(JsonValue.from(mapOf())) + .lifeAssured("life_assured") + .policyName("policy_name") + .policyNumber("policy_number") + .premiumAmount(0.0f) + .premiumFrequency("premium_frequency") + .provider("provider") + .status("status") + .sumAssured(0.0f) + .build() + ) + .build() + ) + .investor( + UnifiedResponse.Investor.builder() + .address("address") + .casId("cas_id") + .email("dev@stainless.com") + .mobile("mobile") + .name("name") + .pan("pan") + .pincode("pincode") + .build() + ) + .meta( + UnifiedResponse.Meta.builder() + .casType(UnifiedResponse.Meta.CasType.NSDL) + .generatedAt(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .statementPeriod( + UnifiedResponse.Meta.StatementPeriod.builder() + .from(LocalDate.parse("2019-12-27")) + .to(LocalDate.parse("2019-12-27")) + .build() + ) + .build() + ) + .addMutualFund( + UnifiedResponse.MutualFund.builder() + .additionalInfo( + UnifiedResponse.MutualFund.AdditionalInfo.builder() + .kyc("kyc") + .pan("pan") + .pankyc("pankyc") + .build() + ) + .amc("amc") + .folioNumber("folio_number") + .registrar("registrar") + .addScheme( + UnifiedResponse.MutualFund.Scheme.builder() + .additionalInfo( + UnifiedResponse.MutualFund.Scheme.AdditionalInfo.builder() + .advisor("advisor") + .amfi("amfi") + .closeUnits(0.0f) + .openUnits(0.0f) + .rtaCode("rta_code") + .build() + ) + .cost(0.0f) + .gain( + UnifiedResponse.MutualFund.Scheme.Gain.builder() + .absolute(0.0f) + .percentage(0.0f) + .build() + ) + .isin("isin") + .name("name") + .nav(0.0f) + .addNominee("string") + .addTransaction( + UnifiedResponse.MutualFund.Scheme.Transaction.builder() + .amount(0.0f) + .balance(0.0f) + .date(LocalDate.parse("2019-12-27")) + .description("description") + .dividendRate(0.0f) + .nav(0.0f) + .type("type") + .units(0.0f) + .build() + ) + .type(UnifiedResponse.MutualFund.Scheme.Type.EQUITY) + .units(0.0f) + .value(0.0f) + .build() + ) + .value(0.0f) + .build() + ) + .summary( + UnifiedResponse.Summary.builder() + .accounts( + UnifiedResponse.Summary.Accounts.builder() + .demat( + UnifiedResponse.Summary.Accounts.Demat.builder() + .count(0L) + .totalValue(0.0f) + .build() + ) + .insurance( + UnifiedResponse.Summary.Accounts.Insurance.builder() + .count(0L) + .totalValue(0.0f) + .build() + ) + .mutualFunds( + UnifiedResponse.Summary.Accounts.MutualFunds.builder() + .count(0L) + .totalValue(0.0f) + .build() + ) + .build() + ) + .totalValue(0.0f) + .build() + ) + .build() + + assertThat(unifiedResponse.dematAccounts().getOrNull()) + .containsExactly( + UnifiedResponse.DematAccount.builder() + .additionalInfo( + UnifiedResponse.DematAccount.AdditionalInfo.builder() + .boStatus("bo_status") + .boSubStatus("bo_sub_status") + .boType("bo_type") + .bsda("bsda") + .email("dev@stainless.com") + .addLinkedPan("string") + .nominee("nominee") + .status("status") + .build() + ) + .boId("bo_id") + .clientId("client_id") + .dematType(UnifiedResponse.DematAccount.DematType.NSDL) + .dpId("dp_id") + .dpName("dp_name") + .holdings( + UnifiedResponse.DematAccount.Holdings.builder() + .addAif( + UnifiedResponse.DematAccount.Holdings.Aif.builder() + .additionalInfo(JsonValue.from(mapOf())) + .isin("isin") + .name("name") + .units(0.0f) + .value(0.0f) + .build() + ) + .addCorporateBond( + UnifiedResponse.DematAccount.Holdings.CorporateBond.builder() + .additionalInfo(JsonValue.from(mapOf())) + .isin("isin") + .name("name") + .units(0.0f) + .value(0.0f) + .build() + ) + .addDematMutualFund( + UnifiedResponse.DematAccount.Holdings.DematMutualFund.builder() + .additionalInfo(JsonValue.from(mapOf())) + .isin("isin") + .name("name") + .units(0.0f) + .value(0.0f) + .build() + ) + .addEquity( + UnifiedResponse.DematAccount.Holdings.Equity.builder() + .additionalInfo(JsonValue.from(mapOf())) + .isin("isin") + .name("name") + .units(0.0f) + .value(0.0f) + .build() + ) + .addGovernmentSecurity( + UnifiedResponse.DematAccount.Holdings.GovernmentSecurity.builder() + .additionalInfo(JsonValue.from(mapOf())) + .isin("isin") + .name("name") + .units(0.0f) + .value(0.0f) + .build() + ) + .build() + ) + .value(0.0f) + .build() + ) + assertThat(unifiedResponse.insurance()) + .contains( + UnifiedResponse.Insurance.builder() + .addLifeInsurancePolicy( + UnifiedResponse.Insurance.LifeInsurancePolicy.builder() + .additionalInfo(JsonValue.from(mapOf())) + .lifeAssured("life_assured") + .policyName("policy_name") + .policyNumber("policy_number") + .premiumAmount(0.0f) + .premiumFrequency("premium_frequency") + .provider("provider") + .status("status") + .sumAssured(0.0f) + .build() + ) + .build() + ) + assertThat(unifiedResponse.investor()) + .contains( + UnifiedResponse.Investor.builder() + .address("address") + .casId("cas_id") + .email("dev@stainless.com") + .mobile("mobile") + .name("name") + .pan("pan") + .pincode("pincode") + .build() + ) + assertThat(unifiedResponse.meta()) + .contains( + UnifiedResponse.Meta.builder() + .casType(UnifiedResponse.Meta.CasType.NSDL) + .generatedAt(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .statementPeriod( + UnifiedResponse.Meta.StatementPeriod.builder() + .from(LocalDate.parse("2019-12-27")) + .to(LocalDate.parse("2019-12-27")) + .build() + ) + .build() + ) + assertThat(unifiedResponse.mutualFunds().getOrNull()) + .containsExactly( + UnifiedResponse.MutualFund.builder() + .additionalInfo( + UnifiedResponse.MutualFund.AdditionalInfo.builder() + .kyc("kyc") + .pan("pan") + .pankyc("pankyc") + .build() + ) + .amc("amc") + .folioNumber("folio_number") + .registrar("registrar") + .addScheme( + UnifiedResponse.MutualFund.Scheme.builder() + .additionalInfo( + UnifiedResponse.MutualFund.Scheme.AdditionalInfo.builder() + .advisor("advisor") + .amfi("amfi") + .closeUnits(0.0f) + .openUnits(0.0f) + .rtaCode("rta_code") + .build() + ) + .cost(0.0f) + .gain( + UnifiedResponse.MutualFund.Scheme.Gain.builder() + .absolute(0.0f) + .percentage(0.0f) + .build() + ) + .isin("isin") + .name("name") + .nav(0.0f) + .addNominee("string") + .addTransaction( + UnifiedResponse.MutualFund.Scheme.Transaction.builder() + .amount(0.0f) + .balance(0.0f) + .date(LocalDate.parse("2019-12-27")) + .description("description") + .dividendRate(0.0f) + .nav(0.0f) + .type("type") + .units(0.0f) + .build() + ) + .type(UnifiedResponse.MutualFund.Scheme.Type.EQUITY) + .units(0.0f) + .value(0.0f) + .build() + ) + .value(0.0f) + .build() + ) + assertThat(unifiedResponse.summary()) + .contains( + UnifiedResponse.Summary.builder() + .accounts( + UnifiedResponse.Summary.Accounts.builder() + .demat( + UnifiedResponse.Summary.Accounts.Demat.builder() + .count(0L) + .totalValue(0.0f) + .build() + ) + .insurance( + UnifiedResponse.Summary.Accounts.Insurance.builder() + .count(0L) + .totalValue(0.0f) + .build() + ) + .mutualFunds( + UnifiedResponse.Summary.Accounts.MutualFunds.builder() + .count(0L) + .totalValue(0.0f) + .build() + ) + .build() + ) + .totalValue(0.0f) + .build() + ) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val unifiedResponse = + UnifiedResponse.builder() + .addDematAccount( + UnifiedResponse.DematAccount.builder() + .additionalInfo( + UnifiedResponse.DematAccount.AdditionalInfo.builder() + .boStatus("bo_status") + .boSubStatus("bo_sub_status") + .boType("bo_type") + .bsda("bsda") + .email("dev@stainless.com") + .addLinkedPan("string") + .nominee("nominee") + .status("status") + .build() + ) + .boId("bo_id") + .clientId("client_id") + .dematType(UnifiedResponse.DematAccount.DematType.NSDL) + .dpId("dp_id") + .dpName("dp_name") + .holdings( + UnifiedResponse.DematAccount.Holdings.builder() + .addAif( + UnifiedResponse.DematAccount.Holdings.Aif.builder() + .additionalInfo(JsonValue.from(mapOf())) + .isin("isin") + .name("name") + .units(0.0f) + .value(0.0f) + .build() + ) + .addCorporateBond( + UnifiedResponse.DematAccount.Holdings.CorporateBond.builder() + .additionalInfo(JsonValue.from(mapOf())) + .isin("isin") + .name("name") + .units(0.0f) + .value(0.0f) + .build() + ) + .addDematMutualFund( + UnifiedResponse.DematAccount.Holdings.DematMutualFund.builder() + .additionalInfo(JsonValue.from(mapOf())) + .isin("isin") + .name("name") + .units(0.0f) + .value(0.0f) + .build() + ) + .addEquity( + UnifiedResponse.DematAccount.Holdings.Equity.builder() + .additionalInfo(JsonValue.from(mapOf())) + .isin("isin") + .name("name") + .units(0.0f) + .value(0.0f) + .build() + ) + .addGovernmentSecurity( + UnifiedResponse.DematAccount.Holdings.GovernmentSecurity + .builder() + .additionalInfo(JsonValue.from(mapOf())) + .isin("isin") + .name("name") + .units(0.0f) + .value(0.0f) + .build() + ) + .build() + ) + .value(0.0f) + .build() + ) + .insurance( + UnifiedResponse.Insurance.builder() + .addLifeInsurancePolicy( + UnifiedResponse.Insurance.LifeInsurancePolicy.builder() + .additionalInfo(JsonValue.from(mapOf())) + .lifeAssured("life_assured") + .policyName("policy_name") + .policyNumber("policy_number") + .premiumAmount(0.0f) + .premiumFrequency("premium_frequency") + .provider("provider") + .status("status") + .sumAssured(0.0f) + .build() + ) + .build() + ) + .investor( + UnifiedResponse.Investor.builder() + .address("address") + .casId("cas_id") + .email("dev@stainless.com") + .mobile("mobile") + .name("name") + .pan("pan") + .pincode("pincode") + .build() + ) + .meta( + UnifiedResponse.Meta.builder() + .casType(UnifiedResponse.Meta.CasType.NSDL) + .generatedAt(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .statementPeriod( + UnifiedResponse.Meta.StatementPeriod.builder() + .from(LocalDate.parse("2019-12-27")) + .to(LocalDate.parse("2019-12-27")) + .build() + ) + .build() + ) + .addMutualFund( + UnifiedResponse.MutualFund.builder() + .additionalInfo( + UnifiedResponse.MutualFund.AdditionalInfo.builder() + .kyc("kyc") + .pan("pan") + .pankyc("pankyc") + .build() + ) + .amc("amc") + .folioNumber("folio_number") + .registrar("registrar") + .addScheme( + UnifiedResponse.MutualFund.Scheme.builder() + .additionalInfo( + UnifiedResponse.MutualFund.Scheme.AdditionalInfo.builder() + .advisor("advisor") + .amfi("amfi") + .closeUnits(0.0f) + .openUnits(0.0f) + .rtaCode("rta_code") + .build() + ) + .cost(0.0f) + .gain( + UnifiedResponse.MutualFund.Scheme.Gain.builder() + .absolute(0.0f) + .percentage(0.0f) + .build() + ) + .isin("isin") + .name("name") + .nav(0.0f) + .addNominee("string") + .addTransaction( + UnifiedResponse.MutualFund.Scheme.Transaction.builder() + .amount(0.0f) + .balance(0.0f) + .date(LocalDate.parse("2019-12-27")) + .description("description") + .dividendRate(0.0f) + .nav(0.0f) + .type("type") + .units(0.0f) + .build() + ) + .type(UnifiedResponse.MutualFund.Scheme.Type.EQUITY) + .units(0.0f) + .value(0.0f) + .build() + ) + .value(0.0f) + .build() + ) + .summary( + UnifiedResponse.Summary.builder() + .accounts( + UnifiedResponse.Summary.Accounts.builder() + .demat( + UnifiedResponse.Summary.Accounts.Demat.builder() + .count(0L) + .totalValue(0.0f) + .build() + ) + .insurance( + UnifiedResponse.Summary.Accounts.Insurance.builder() + .count(0L) + .totalValue(0.0f) + .build() + ) + .mutualFunds( + UnifiedResponse.Summary.Accounts.MutualFunds.builder() + .count(0L) + .totalValue(0.0f) + .build() + ) + .build() + ) + .totalValue(0.0f) + .build() + ) + .build() + + val roundtrippedUnifiedResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(unifiedResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedUnifiedResponse).isEqualTo(unifiedResponse) + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/ErrorHandlingTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/ErrorHandlingTest.kt new file mode 100644 index 0000000..71fb9b3 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/ErrorHandlingTest.kt @@ -0,0 +1,503 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services + +import com.cas_parser.api.client.CasParserClient +import com.cas_parser.api.client.okhttp.CasParserOkHttpClient +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.http.Headers +import com.cas_parser.api.core.jsonMapper +import com.cas_parser.api.errors.BadRequestException +import com.cas_parser.api.errors.CasParserException +import com.cas_parser.api.errors.InternalServerException +import com.cas_parser.api.errors.NotFoundException +import com.cas_parser.api.errors.PermissionDeniedException +import com.cas_parser.api.errors.RateLimitException +import com.cas_parser.api.errors.UnauthorizedException +import com.cas_parser.api.errors.UnexpectedStatusCodeException +import com.cas_parser.api.errors.UnprocessableEntityException +import com.cas_parser.api.models.casparser.CasParserSmartParseParams +import com.github.tomakehurst.wiremock.client.WireMock.anyUrl +import com.github.tomakehurst.wiremock.client.WireMock.post +import com.github.tomakehurst.wiremock.client.WireMock.status +import com.github.tomakehurst.wiremock.client.WireMock.stubFor +import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo +import com.github.tomakehurst.wiremock.junit5.WireMockTest +import org.assertj.core.api.Assertions.assertThat +import org.assertj.core.api.Assertions.entry +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import org.junit.jupiter.api.parallel.ResourceLock + +@WireMockTest +@ResourceLock("https://github.com/wiremock/wiremock/issues/169") +internal class ErrorHandlingTest { + + companion object { + + private val ERROR_JSON: JsonValue = JsonValue.from(mapOf("errorProperty" to "42")) + + private val ERROR_JSON_BYTES: ByteArray = jsonMapper().writeValueAsBytes(ERROR_JSON) + + private const val HEADER_NAME: String = "Error-Header" + + private const val HEADER_VALUE: String = "42" + + private const val NOT_JSON: String = "Not JSON" + } + + private lateinit var client: CasParserClient + + @BeforeEach + fun beforeEach(wmRuntimeInfo: WireMockRuntimeInfo) { + client = + CasParserOkHttpClient.builder() + .baseUrl(wmRuntimeInfo.httpBaseUrl) + .apiKey("My API Key") + .build() + } + + @Test + fun casParserSmartParse400() { + val casParserService = client.casParser() + stubFor( + post(anyUrl()) + .willReturn( + status(400).withHeader(HEADER_NAME, HEADER_VALUE).withBody(ERROR_JSON_BYTES) + ) + ) + + val e = + assertThrows { + casParserService.smartParse( + CasParserSmartParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + } + + assertThat(e.statusCode()).isEqualTo(400) + assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) + assertThat(e.body()).isEqualTo(ERROR_JSON) + } + + @Test + fun casParserSmartParse400WithRawResponse() { + val casParserService = client.casParser().withRawResponse() + stubFor( + post(anyUrl()) + .willReturn( + status(400).withHeader(HEADER_NAME, HEADER_VALUE).withBody(ERROR_JSON_BYTES) + ) + ) + + val e = + assertThrows { + casParserService.smartParse( + CasParserSmartParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + } + + assertThat(e.statusCode()).isEqualTo(400) + assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) + assertThat(e.body()).isEqualTo(ERROR_JSON) + } + + @Test + fun casParserSmartParse401() { + val casParserService = client.casParser() + stubFor( + post(anyUrl()) + .willReturn( + status(401).withHeader(HEADER_NAME, HEADER_VALUE).withBody(ERROR_JSON_BYTES) + ) + ) + + val e = + assertThrows { + casParserService.smartParse( + CasParserSmartParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + } + + assertThat(e.statusCode()).isEqualTo(401) + assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) + assertThat(e.body()).isEqualTo(ERROR_JSON) + } + + @Test + fun casParserSmartParse401WithRawResponse() { + val casParserService = client.casParser().withRawResponse() + stubFor( + post(anyUrl()) + .willReturn( + status(401).withHeader(HEADER_NAME, HEADER_VALUE).withBody(ERROR_JSON_BYTES) + ) + ) + + val e = + assertThrows { + casParserService.smartParse( + CasParserSmartParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + } + + assertThat(e.statusCode()).isEqualTo(401) + assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) + assertThat(e.body()).isEqualTo(ERROR_JSON) + } + + @Test + fun casParserSmartParse403() { + val casParserService = client.casParser() + stubFor( + post(anyUrl()) + .willReturn( + status(403).withHeader(HEADER_NAME, HEADER_VALUE).withBody(ERROR_JSON_BYTES) + ) + ) + + val e = + assertThrows { + casParserService.smartParse( + CasParserSmartParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + } + + assertThat(e.statusCode()).isEqualTo(403) + assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) + assertThat(e.body()).isEqualTo(ERROR_JSON) + } + + @Test + fun casParserSmartParse403WithRawResponse() { + val casParserService = client.casParser().withRawResponse() + stubFor( + post(anyUrl()) + .willReturn( + status(403).withHeader(HEADER_NAME, HEADER_VALUE).withBody(ERROR_JSON_BYTES) + ) + ) + + val e = + assertThrows { + casParserService.smartParse( + CasParserSmartParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + } + + assertThat(e.statusCode()).isEqualTo(403) + assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) + assertThat(e.body()).isEqualTo(ERROR_JSON) + } + + @Test + fun casParserSmartParse404() { + val casParserService = client.casParser() + stubFor( + post(anyUrl()) + .willReturn( + status(404).withHeader(HEADER_NAME, HEADER_VALUE).withBody(ERROR_JSON_BYTES) + ) + ) + + val e = + assertThrows { + casParserService.smartParse( + CasParserSmartParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + } + + assertThat(e.statusCode()).isEqualTo(404) + assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) + assertThat(e.body()).isEqualTo(ERROR_JSON) + } + + @Test + fun casParserSmartParse404WithRawResponse() { + val casParserService = client.casParser().withRawResponse() + stubFor( + post(anyUrl()) + .willReturn( + status(404).withHeader(HEADER_NAME, HEADER_VALUE).withBody(ERROR_JSON_BYTES) + ) + ) + + val e = + assertThrows { + casParserService.smartParse( + CasParserSmartParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + } + + assertThat(e.statusCode()).isEqualTo(404) + assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) + assertThat(e.body()).isEqualTo(ERROR_JSON) + } + + @Test + fun casParserSmartParse422() { + val casParserService = client.casParser() + stubFor( + post(anyUrl()) + .willReturn( + status(422).withHeader(HEADER_NAME, HEADER_VALUE).withBody(ERROR_JSON_BYTES) + ) + ) + + val e = + assertThrows { + casParserService.smartParse( + CasParserSmartParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + } + + assertThat(e.statusCode()).isEqualTo(422) + assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) + assertThat(e.body()).isEqualTo(ERROR_JSON) + } + + @Test + fun casParserSmartParse422WithRawResponse() { + val casParserService = client.casParser().withRawResponse() + stubFor( + post(anyUrl()) + .willReturn( + status(422).withHeader(HEADER_NAME, HEADER_VALUE).withBody(ERROR_JSON_BYTES) + ) + ) + + val e = + assertThrows { + casParserService.smartParse( + CasParserSmartParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + } + + assertThat(e.statusCode()).isEqualTo(422) + assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) + assertThat(e.body()).isEqualTo(ERROR_JSON) + } + + @Test + fun casParserSmartParse429() { + val casParserService = client.casParser() + stubFor( + post(anyUrl()) + .willReturn( + status(429).withHeader(HEADER_NAME, HEADER_VALUE).withBody(ERROR_JSON_BYTES) + ) + ) + + val e = + assertThrows { + casParserService.smartParse( + CasParserSmartParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + } + + assertThat(e.statusCode()).isEqualTo(429) + assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) + assertThat(e.body()).isEqualTo(ERROR_JSON) + } + + @Test + fun casParserSmartParse429WithRawResponse() { + val casParserService = client.casParser().withRawResponse() + stubFor( + post(anyUrl()) + .willReturn( + status(429).withHeader(HEADER_NAME, HEADER_VALUE).withBody(ERROR_JSON_BYTES) + ) + ) + + val e = + assertThrows { + casParserService.smartParse( + CasParserSmartParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + } + + assertThat(e.statusCode()).isEqualTo(429) + assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) + assertThat(e.body()).isEqualTo(ERROR_JSON) + } + + @Test + fun casParserSmartParse500() { + val casParserService = client.casParser() + stubFor( + post(anyUrl()) + .willReturn( + status(500).withHeader(HEADER_NAME, HEADER_VALUE).withBody(ERROR_JSON_BYTES) + ) + ) + + val e = + assertThrows { + casParserService.smartParse( + CasParserSmartParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + } + + assertThat(e.statusCode()).isEqualTo(500) + assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) + assertThat(e.body()).isEqualTo(ERROR_JSON) + } + + @Test + fun casParserSmartParse500WithRawResponse() { + val casParserService = client.casParser().withRawResponse() + stubFor( + post(anyUrl()) + .willReturn( + status(500).withHeader(HEADER_NAME, HEADER_VALUE).withBody(ERROR_JSON_BYTES) + ) + ) + + val e = + assertThrows { + casParserService.smartParse( + CasParserSmartParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + } + + assertThat(e.statusCode()).isEqualTo(500) + assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) + assertThat(e.body()).isEqualTo(ERROR_JSON) + } + + @Test + fun casParserSmartParse999() { + val casParserService = client.casParser() + stubFor( + post(anyUrl()) + .willReturn( + status(999).withHeader(HEADER_NAME, HEADER_VALUE).withBody(ERROR_JSON_BYTES) + ) + ) + + val e = + assertThrows { + casParserService.smartParse( + CasParserSmartParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + } + + assertThat(e.statusCode()).isEqualTo(999) + assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) + assertThat(e.body()).isEqualTo(ERROR_JSON) + } + + @Test + fun casParserSmartParse999WithRawResponse() { + val casParserService = client.casParser().withRawResponse() + stubFor( + post(anyUrl()) + .willReturn( + status(999).withHeader(HEADER_NAME, HEADER_VALUE).withBody(ERROR_JSON_BYTES) + ) + ) + + val e = + assertThrows { + casParserService.smartParse( + CasParserSmartParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + } + + assertThat(e.statusCode()).isEqualTo(999) + assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) + assertThat(e.body()).isEqualTo(ERROR_JSON) + } + + @Test + fun casParserSmartParseInvalidJsonBody() { + val casParserService = client.casParser() + stubFor( + post(anyUrl()) + .willReturn(status(200).withHeader(HEADER_NAME, HEADER_VALUE).withBody(NOT_JSON)) + ) + + val e = + assertThrows { + casParserService.smartParse( + CasParserSmartParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + } + + assertThat(e).hasMessage("Error reading response") + } + + private fun Headers.toMap(): Map> = + mutableMapOf>().also { map -> + names().forEach { map[it] = values(it) } + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/ServiceParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/ServiceParamsTest.kt new file mode 100644 index 0000000..5454df2 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/ServiceParamsTest.kt @@ -0,0 +1,63 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services + +import com.cas_parser.api.client.CasParserClient +import com.cas_parser.api.client.okhttp.CasParserOkHttpClient +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.models.casparser.CasParserSmartParseParams +import com.github.tomakehurst.wiremock.client.WireMock.anyUrl +import com.github.tomakehurst.wiremock.client.WireMock.equalTo +import com.github.tomakehurst.wiremock.client.WireMock.matchingJsonPath +import com.github.tomakehurst.wiremock.client.WireMock.ok +import com.github.tomakehurst.wiremock.client.WireMock.post +import com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor +import com.github.tomakehurst.wiremock.client.WireMock.stubFor +import com.github.tomakehurst.wiremock.client.WireMock.verify +import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo +import com.github.tomakehurst.wiremock.junit5.WireMockTest +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.parallel.ResourceLock + +@WireMockTest +@ResourceLock("https://github.com/wiremock/wiremock/issues/169") +internal class ServiceParamsTest { + + private lateinit var client: CasParserClient + + @BeforeEach + fun beforeEach(wmRuntimeInfo: WireMockRuntimeInfo) { + client = + CasParserOkHttpClient.builder() + .baseUrl(wmRuntimeInfo.httpBaseUrl) + .apiKey("My API Key") + .build() + } + + @Disabled("Prism tests are disabled") + @Test + fun smartParse() { + val casParserService = client.casParser() + stubFor(post(anyUrl()).willReturn(ok("{}"))) + + casParserService.smartParse( + CasParserSmartParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .putAdditionalHeader("Secret-Header", "42") + .putAdditionalQueryParam("secret_query_param", "42") + .putAdditionalBodyProperty("secretProperty", JsonValue.from("42")) + .build() + ) + + verify( + postRequestedFor(anyUrl()) + .withHeader("Secret-Header", equalTo("42")) + .withQueryParam("secret_query_param", equalTo("42")) + .withRequestBody(matchingJsonPath("$.secretProperty", equalTo("42"))) + ) + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CasGeneratorServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CasGeneratorServiceAsyncTest.kt new file mode 100644 index 0000000..c74ed37 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CasGeneratorServiceAsyncTest.kt @@ -0,0 +1,40 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.TestServerExtension +import com.cas_parser.api.client.okhttp.CasParserOkHttpClientAsync +import com.cas_parser.api.models.casgenerator.CasGeneratorGenerateCasParams +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class CasGeneratorServiceAsyncTest { + + @Disabled("Prism tests are disabled") + @Test + fun generateCas() { + val client = + CasParserOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val casGeneratorServiceAsync = client.casGenerator() + + val responseFuture = + casGeneratorServiceAsync.generateCas( + CasGeneratorGenerateCasParams.builder() + .email("user@example.com") + .fromDate("2023-01-01") + .password("Abcdefghi12\$") + .toDate("2023-12-31") + .casAuthority(CasGeneratorGenerateCasParams.CasAuthority.KFINTECH) + .panNo("ABCDE1234F") + .build() + ) + + val response = responseFuture.get() + response.validate() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CasParserServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CasParserServiceAsyncTest.kt new file mode 100644 index 0000000..363c5eb --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CasParserServiceAsyncTest.kt @@ -0,0 +1,109 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.TestServerExtension +import com.cas_parser.api.client.okhttp.CasParserOkHttpClientAsync +import com.cas_parser.api.models.casparser.CasParserCamsKfintechParams +import com.cas_parser.api.models.casparser.CasParserCdslParams +import com.cas_parser.api.models.casparser.CasParserNsdlParams +import com.cas_parser.api.models.casparser.CasParserSmartParseParams +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class CasParserServiceAsyncTest { + + @Disabled("Prism tests are disabled") + @Test + fun camsKfintech() { + val client = + CasParserOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val casParserServiceAsync = client.casParser() + + val unifiedResponseFuture = + casParserServiceAsync.camsKfintech( + CasParserCamsKfintechParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + + val unifiedResponse = unifiedResponseFuture.get() + unifiedResponse.validate() + } + + @Disabled("Prism tests are disabled") + @Test + fun cdsl() { + val client = + CasParserOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val casParserServiceAsync = client.casParser() + + val unifiedResponseFuture = + casParserServiceAsync.cdsl( + CasParserCdslParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + + val unifiedResponse = unifiedResponseFuture.get() + unifiedResponse.validate() + } + + @Disabled("Prism tests are disabled") + @Test + fun nsdl() { + val client = + CasParserOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val casParserServiceAsync = client.casParser() + + val unifiedResponseFuture = + casParserServiceAsync.nsdl( + CasParserNsdlParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + + val unifiedResponse = unifiedResponseFuture.get() + unifiedResponse.validate() + } + + @Disabled("Prism tests are disabled") + @Test + fun smartParse() { + val client = + CasParserOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val casParserServiceAsync = client.casParser() + + val unifiedResponseFuture = + casParserServiceAsync.smartParse( + CasParserSmartParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + + val unifiedResponse = unifiedResponseFuture.get() + unifiedResponse.validate() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CasGeneratorServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CasGeneratorServiceTest.kt new file mode 100644 index 0000000..e66dcfb --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CasGeneratorServiceTest.kt @@ -0,0 +1,39 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.TestServerExtension +import com.cas_parser.api.client.okhttp.CasParserOkHttpClient +import com.cas_parser.api.models.casgenerator.CasGeneratorGenerateCasParams +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class CasGeneratorServiceTest { + + @Disabled("Prism tests are disabled") + @Test + fun generateCas() { + val client = + CasParserOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val casGeneratorService = client.casGenerator() + + val response = + casGeneratorService.generateCas( + CasGeneratorGenerateCasParams.builder() + .email("user@example.com") + .fromDate("2023-01-01") + .password("Abcdefghi12\$") + .toDate("2023-12-31") + .casAuthority(CasGeneratorGenerateCasParams.CasAuthority.KFINTECH) + .panNo("ABCDE1234F") + .build() + ) + + response.validate() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CasParserServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CasParserServiceTest.kt new file mode 100644 index 0000000..9724ba1 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CasParserServiceTest.kt @@ -0,0 +1,105 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.TestServerExtension +import com.cas_parser.api.client.okhttp.CasParserOkHttpClient +import com.cas_parser.api.models.casparser.CasParserCamsKfintechParams +import com.cas_parser.api.models.casparser.CasParserCdslParams +import com.cas_parser.api.models.casparser.CasParserNsdlParams +import com.cas_parser.api.models.casparser.CasParserSmartParseParams +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class CasParserServiceTest { + + @Disabled("Prism tests are disabled") + @Test + fun camsKfintech() { + val client = + CasParserOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val casParserService = client.casParser() + + val unifiedResponse = + casParserService.camsKfintech( + CasParserCamsKfintechParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + + unifiedResponse.validate() + } + + @Disabled("Prism tests are disabled") + @Test + fun cdsl() { + val client = + CasParserOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val casParserService = client.casParser() + + val unifiedResponse = + casParserService.cdsl( + CasParserCdslParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + + unifiedResponse.validate() + } + + @Disabled("Prism tests are disabled") + @Test + fun nsdl() { + val client = + CasParserOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val casParserService = client.casParser() + + val unifiedResponse = + casParserService.nsdl( + CasParserNsdlParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + + unifiedResponse.validate() + } + + @Disabled("Prism tests are disabled") + @Test + fun smartParse() { + val client = + CasParserOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val casParserService = client.casParser() + + val unifiedResponse = + casParserService.smartParse( + CasParserSmartParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + + unifiedResponse.validate() + } +} diff --git a/cas-parser-java-example/build.gradle.kts b/cas-parser-java-example/build.gradle.kts new file mode 100644 index 0000000..f13aa5f --- /dev/null +++ b/cas-parser-java-example/build.gradle.kts @@ -0,0 +1,28 @@ +plugins { + id("cas-parser.java") + application +} + +repositories { + mavenCentral() +} + +dependencies { + implementation(project(":cas-parser-java")) +} + +tasks.withType().configureEach { + // Allow using more modern APIs, like `List.of` and `Map.of`, in examples. + options.release.set(9) +} + +application { + // Use `./gradlew :cas-parser-java-example:run` to run `Main` + // Use `./gradlew :cas-parser-java-example:run -Pexample=Something` to run `SomethingExample` + mainClass = "com.cas_parser.api.example.${ + if (project.hasProperty("example")) + "${project.property("example")}Example" + else + "Main" + }" +} diff --git a/cas-parser-java-lib/.keep b/cas-parser-java-lib/.keep new file mode 100644 index 0000000..5e2c99f --- /dev/null +++ b/cas-parser-java-lib/.keep @@ -0,0 +1,4 @@ +File generated from our OpenAPI spec by Stainless. + +This directory can be used to store custom files to expand the SDK. +It is ignored by Stainless code generation and its content (other than this keep file) won't be touched. \ No newline at end of file diff --git a/cas-parser-java-proguard-test/build.gradle.kts b/cas-parser-java-proguard-test/build.gradle.kts new file mode 100644 index 0000000..dc5f093 --- /dev/null +++ b/cas-parser-java-proguard-test/build.gradle.kts @@ -0,0 +1,103 @@ +plugins { + id("cas-parser.kotlin") + id("com.gradleup.shadow") version "8.3.8" +} + +buildscript { + repositories { + google() + } + + dependencies { + classpath("com.guardsquare:proguard-gradle:7.4.2") + classpath("com.android.tools:r8:8.3.37") + } +} + +dependencies { + testImplementation(project(":cas-parser-java")) + testImplementation(kotlin("test")) + testImplementation("org.junit.jupiter:junit-jupiter-api:5.9.3") + testImplementation("org.assertj:assertj-core:3.25.3") + testImplementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.13.4") +} + +tasks.shadowJar { + from(sourceSets.test.get().output) + configurations = listOf(project.configurations.testRuntimeClasspath.get()) +} + +val proguardJarPath = "${layout.buildDirectory.get()}/libs/${project.name}-${project.version}-proguard.jar" +val proguardJar by tasks.registering(proguard.gradle.ProGuardTask::class) { + group = "verification" + dependsOn(tasks.shadowJar) + notCompatibleWithConfigurationCache("ProGuard") + + injars(tasks.shadowJar) + outjars(proguardJarPath) + printmapping("${layout.buildDirectory.get()}/proguard-mapping.txt") + + dontwarn() + + val javaHome = System.getProperty("java.home") + if (System.getProperty("java.version").startsWith("1.")) { + // Before Java 9, the runtime classes were packaged in a single jar file. + libraryjars("$javaHome/lib/rt.jar") + } else { + // As of Java 9, the runtime classes are packaged in modular jmod files. + libraryjars( + // Filters must be specified first, as a map. + mapOf("jarfilter" to "!**.jar", "filter" to "!module-info.class"), + "$javaHome/jmods/java.base.jmod" + ) + } + + configuration("./test.pro") + configuration("../cas-parser-java-core/src/main/resources/META-INF/proguard/cas-parser-java-core.pro") +} + +val testProGuard by tasks.registering(JavaExec::class) { + group = "verification" + dependsOn(proguardJar) + notCompatibleWithConfigurationCache("ProGuard") + + mainClass.set("com.cas_parser.api.proguard.ProGuardCompatibilityTest") + classpath = files(proguardJarPath) +} + +val r8JarPath = "${layout.buildDirectory.get()}/libs/${project.name}-${project.version}-r8.jar" +val r8Jar by tasks.registering(JavaExec::class) { + group = "verification" + dependsOn(tasks.shadowJar) + notCompatibleWithConfigurationCache("R8") + + mainClass.set("com.android.tools.r8.R8") + classpath = buildscript.configurations["classpath"] + + args = listOf( + "--release", + "--classfile", + "--output", r8JarPath, + "--lib", System.getProperty("java.home"), + "--pg-conf", "./test.pro", + "--pg-conf", "../cas-parser-java-core/src/main/resources/META-INF/proguard/cas-parser-java-core.pro", + "--pg-map-output", "${layout.buildDirectory.get()}/r8-mapping.txt", + tasks.shadowJar.get().archiveFile.get().asFile.absolutePath, + ) +} + +val testR8 by tasks.registering(JavaExec::class) { + group = "verification" + dependsOn(r8Jar) + notCompatibleWithConfigurationCache("R8") + + mainClass.set("com.cas_parser.api.proguard.ProGuardCompatibilityTest") + classpath = files(r8JarPath) +} + +tasks.test { + dependsOn(testProGuard) + dependsOn(testR8) + // We defer to the tests run via the ProGuard JAR. + enabled = false +} diff --git a/cas-parser-java-proguard-test/src/test/kotlin/com/cas_parser/api/proguard/ProGuardCompatibilityTest.kt b/cas-parser-java-proguard-test/src/test/kotlin/com/cas_parser/api/proguard/ProGuardCompatibilityTest.kt new file mode 100644 index 0000000..f132d1f --- /dev/null +++ b/cas-parser-java-proguard-test/src/test/kotlin/com/cas_parser/api/proguard/ProGuardCompatibilityTest.kt @@ -0,0 +1,265 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.proguard + +import com.cas_parser.api.client.okhttp.CasParserOkHttpClient +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.jsonMapper +import com.cas_parser.api.models.casparser.UnifiedResponse +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import java.time.LocalDate +import java.time.OffsetDateTime +import kotlin.reflect.full.memberFunctions +import kotlin.reflect.jvm.javaMethod +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class ProGuardCompatibilityTest { + + companion object { + + @JvmStatic + fun main(args: Array) { + // To debug that we're using the right JAR. + val jarPath = this::class.java.getProtectionDomain().codeSource.location + println("JAR being used: $jarPath") + + // We have to manually run the test methods instead of using the JUnit runner because it + // seems impossible to get working with R8. + val test = ProGuardCompatibilityTest() + test::class + .memberFunctions + .asSequence() + .filter { function -> + function.javaMethod?.isAnnotationPresent(Test::class.java) == true + } + .forEach { it.call(test) } + } + } + + @Test + fun proguardRules() { + val rulesFile = + javaClass.classLoader.getResourceAsStream("META-INF/proguard/cas-parser-java-core.pro") + + assertThat(rulesFile).isNotNull() + } + + @Test + fun client() { + val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() + + assertThat(client).isNotNull() + assertThat(client.casParser()).isNotNull() + assertThat(client.casGenerator()).isNotNull() + } + + @Test + fun unifiedResponseRoundtrip() { + val jsonMapper = jsonMapper() + val unifiedResponse = + UnifiedResponse.builder() + .addDematAccount( + UnifiedResponse.DematAccount.builder() + .additionalInfo( + UnifiedResponse.DematAccount.AdditionalInfo.builder() + .boStatus("bo_status") + .boSubStatus("bo_sub_status") + .boType("bo_type") + .bsda("bsda") + .email("dev@stainless.com") + .addLinkedPan("string") + .nominee("nominee") + .status("status") + .build() + ) + .boId("bo_id") + .clientId("client_id") + .dematType(UnifiedResponse.DematAccount.DematType.NSDL) + .dpId("dp_id") + .dpName("dp_name") + .holdings( + UnifiedResponse.DematAccount.Holdings.builder() + .addAif( + UnifiedResponse.DematAccount.Holdings.Aif.builder() + .additionalInfo(JsonValue.from(mapOf())) + .isin("isin") + .name("name") + .units(0.0f) + .value(0.0f) + .build() + ) + .addCorporateBond( + UnifiedResponse.DematAccount.Holdings.CorporateBond.builder() + .additionalInfo(JsonValue.from(mapOf())) + .isin("isin") + .name("name") + .units(0.0f) + .value(0.0f) + .build() + ) + .addDematMutualFund( + UnifiedResponse.DematAccount.Holdings.DematMutualFund.builder() + .additionalInfo(JsonValue.from(mapOf())) + .isin("isin") + .name("name") + .units(0.0f) + .value(0.0f) + .build() + ) + .addEquity( + UnifiedResponse.DematAccount.Holdings.Equity.builder() + .additionalInfo(JsonValue.from(mapOf())) + .isin("isin") + .name("name") + .units(0.0f) + .value(0.0f) + .build() + ) + .addGovernmentSecurity( + UnifiedResponse.DematAccount.Holdings.GovernmentSecurity + .builder() + .additionalInfo(JsonValue.from(mapOf())) + .isin("isin") + .name("name") + .units(0.0f) + .value(0.0f) + .build() + ) + .build() + ) + .value(0.0f) + .build() + ) + .insurance( + UnifiedResponse.Insurance.builder() + .addLifeInsurancePolicy( + UnifiedResponse.Insurance.LifeInsurancePolicy.builder() + .additionalInfo(JsonValue.from(mapOf())) + .lifeAssured("life_assured") + .policyName("policy_name") + .policyNumber("policy_number") + .premiumAmount(0.0f) + .premiumFrequency("premium_frequency") + .provider("provider") + .status("status") + .sumAssured(0.0f) + .build() + ) + .build() + ) + .investor( + UnifiedResponse.Investor.builder() + .address("address") + .casId("cas_id") + .email("dev@stainless.com") + .mobile("mobile") + .name("name") + .pan("pan") + .pincode("pincode") + .build() + ) + .meta( + UnifiedResponse.Meta.builder() + .casType(UnifiedResponse.Meta.CasType.NSDL) + .generatedAt(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .statementPeriod( + UnifiedResponse.Meta.StatementPeriod.builder() + .from(LocalDate.parse("2019-12-27")) + .to(LocalDate.parse("2019-12-27")) + .build() + ) + .build() + ) + .addMutualFund( + UnifiedResponse.MutualFund.builder() + .additionalInfo( + UnifiedResponse.MutualFund.AdditionalInfo.builder() + .kyc("kyc") + .pan("pan") + .pankyc("pankyc") + .build() + ) + .amc("amc") + .folioNumber("folio_number") + .registrar("registrar") + .addScheme( + UnifiedResponse.MutualFund.Scheme.builder() + .additionalInfo( + UnifiedResponse.MutualFund.Scheme.AdditionalInfo.builder() + .advisor("advisor") + .amfi("amfi") + .closeUnits(0.0f) + .openUnits(0.0f) + .rtaCode("rta_code") + .build() + ) + .cost(0.0f) + .gain( + UnifiedResponse.MutualFund.Scheme.Gain.builder() + .absolute(0.0f) + .percentage(0.0f) + .build() + ) + .isin("isin") + .name("name") + .nav(0.0f) + .addNominee("string") + .addTransaction( + UnifiedResponse.MutualFund.Scheme.Transaction.builder() + .amount(0.0f) + .balance(0.0f) + .date(LocalDate.parse("2019-12-27")) + .description("description") + .dividendRate(0.0f) + .nav(0.0f) + .type("type") + .units(0.0f) + .build() + ) + .type(UnifiedResponse.MutualFund.Scheme.Type.EQUITY) + .units(0.0f) + .value(0.0f) + .build() + ) + .value(0.0f) + .build() + ) + .summary( + UnifiedResponse.Summary.builder() + .accounts( + UnifiedResponse.Summary.Accounts.builder() + .demat( + UnifiedResponse.Summary.Accounts.Demat.builder() + .count(0L) + .totalValue(0.0f) + .build() + ) + .insurance( + UnifiedResponse.Summary.Accounts.Insurance.builder() + .count(0L) + .totalValue(0.0f) + .build() + ) + .mutualFunds( + UnifiedResponse.Summary.Accounts.MutualFunds.builder() + .count(0L) + .totalValue(0.0f) + .build() + ) + .build() + ) + .totalValue(0.0f) + .build() + ) + .build() + + val roundtrippedUnifiedResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(unifiedResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedUnifiedResponse).isEqualTo(unifiedResponse) + } +} diff --git a/cas-parser-java-proguard-test/test.pro b/cas-parser-java-proguard-test/test.pro new file mode 100644 index 0000000..7cc2e8a --- /dev/null +++ b/cas-parser-java-proguard-test/test.pro @@ -0,0 +1,8 @@ +# Specify the entrypoint where ProGuard starts to determine what's reachable. +-keep class com.cas_parser.api.proguard.** { *; } + +# For the testing framework. +-keep class org.junit.** { *; } + +# Many warnings don't apply for our testing purposes. +-dontwarn \ No newline at end of file diff --git a/cas-parser-java/build.gradle.kts b/cas-parser-java/build.gradle.kts new file mode 100644 index 0000000..a6aacff --- /dev/null +++ b/cas-parser-java/build.gradle.kts @@ -0,0 +1,29 @@ +plugins { + id("cas-parser.kotlin") + id("cas-parser.publish") +} + +dependencies { + api(project(":cas-parser-java-client-okhttp")) +} + +// Redefine `dokkaJavadoc` to: +// - Depend on the root project's task for merging the docs of all the projects +// - Forward that task's output to this task's output +tasks.named("dokkaJavadoc").configure { + actions.clear() + + val dokkaJavadocCollector = rootProject.tasks["dokkaJavadocCollector"] + dependsOn(dokkaJavadocCollector) + + val outputDirectory = project.layout.buildDirectory.dir("dokka/javadoc") + doLast { + copy { + from(dokkaJavadocCollector.outputs.files) + into(outputDirectory) + duplicatesStrategy = DuplicatesStrategy.INCLUDE + } + } + + outputs.dir(outputDirectory) +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..6680f9c --- /dev/null +++ b/gradle.properties @@ -0,0 +1,18 @@ +org.gradle.caching=true +org.gradle.configuration-cache=true +org.gradle.parallel=true +org.gradle.daemon=false +# These options improve our compilation and test performance. They are inherited by the Kotlin daemon. +org.gradle.jvmargs=\ + -Xms2g \ + -Xmx8g \ + -XX:+UseParallelGC \ + -XX:InitialCodeCacheSize=256m \ + -XX:ReservedCodeCacheSize=1G \ + -XX:MetaspaceSize=512m \ + -XX:MaxMetaspaceSize=2G \ + -XX:TieredStopAtLevel=1 \ + -XX:GCTimeRatio=4 \ + -XX:CICompilerCount=4 \ + -XX:+OptimizeStringConcat \ + -XX:+UseStringDeduplication diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..a4b76b9530d66f5e68d973ea569d8e19de379189 GIT binary patch literal 43583 zcma&N1CXTcmMvW9vTb(Rwr$&4wr$(C?dmSu>@vG-+vuvg^_??!{yS%8zW-#zn-LkA z5&1^$^{lnmUON?}LBF8_K|(?T0Ra(xUH{($5eN!MR#ZihR#HxkUPe+_R8Cn`RRs(P z_^*#_XlXmGv7!4;*Y%p4nw?{bNp@UZHv1?Um8r6)Fei3p@ClJn0ECfg1hkeuUU@Or zDaPa;U3fE=3L}DooL;8f;P0ipPt0Z~9P0)lbStMS)ag54=uL9ia-Lm3nh|@(Y?B`; zx_#arJIpXH!U{fbCbI^17}6Ri*H<>OLR%c|^mh8+)*h~K8Z!9)DPf zR2h?lbDZQ`p9P;&DQ4F0sur@TMa!Y}S8irn(%d-gi0*WxxCSk*A?3lGh=gcYN?FGl z7D=Js!i~0=u3rox^eO3i@$0=n{K1lPNU zwmfjRVmLOCRfe=seV&P*1Iq=^i`502keY8Uy-WNPwVNNtJFx?IwAyRPZo2Wo1+S(xF37LJZ~%i)kpFQ3Fw=mXfd@>%+)RpYQLnr}B~~zoof(JVm^^&f zxKV^+3D3$A1G;qh4gPVjhrC8e(VYUHv#dy^)(RoUFM?o%W-EHxufuWf(l*@-l+7vt z=l`qmR56K~F|v<^Pd*p~1_y^P0P^aPC##d8+HqX4IR1gu+7w#~TBFphJxF)T$2WEa zxa?H&6=Qe7d(#tha?_1uQys2KtHQ{)Qco)qwGjrdNL7thd^G5i8Os)CHqc>iOidS} z%nFEDdm=GXBw=yXe1W-ShHHFb?Cc70+$W~z_+}nAoHFYI1MV1wZegw*0y^tC*s%3h zhD3tN8b=Gv&rj}!SUM6|ajSPp*58KR7MPpI{oAJCtY~JECm)*m_x>AZEu>DFgUcby z1Qaw8lU4jZpQ_$;*7RME+gq1KySGG#Wql>aL~k9tLrSO()LWn*q&YxHEuzmwd1?aAtI zBJ>P=&$=l1efe1CDU;`Fd+_;&wI07?V0aAIgc(!{a z0Jg6Y=inXc3^n!U0Atk`iCFIQooHqcWhO(qrieUOW8X(x?(RD}iYDLMjSwffH2~tB z)oDgNBLB^AJBM1M^c5HdRx6fBfka`(LD-qrlh5jqH~);#nw|iyp)()xVYak3;Ybik z0j`(+69aK*B>)e_p%=wu8XC&9e{AO4c~O1U`5X9}?0mrd*m$_EUek{R?DNSh(=br# z#Q61gBzEpmy`$pA*6!87 zSDD+=@fTY7<4A?GLqpA?Pb2z$pbCc4B4zL{BeZ?F-8`s$?>*lXXtn*NC61>|*w7J* z$?!iB{6R-0=KFmyp1nnEmLsA-H0a6l+1uaH^g%c(p{iT&YFrbQ$&PRb8Up#X3@Zsk zD^^&LK~111%cqlP%!_gFNa^dTYT?rhkGl}5=fL{a`UViaXWI$k-UcHJwmaH1s=S$4 z%4)PdWJX;hh5UoK?6aWoyLxX&NhNRqKam7tcOkLh{%j3K^4Mgx1@i|Pi&}<^5>hs5 zm8?uOS>%)NzT(%PjVPGa?X%`N2TQCKbeH2l;cTnHiHppPSJ<7y-yEIiC!P*ikl&!B z%+?>VttCOQM@ShFguHVjxX^?mHX^hSaO_;pnyh^v9EumqSZTi+#f&_Vaija0Q-e*| z7ulQj6Fs*bbmsWp{`auM04gGwsYYdNNZcg|ph0OgD>7O}Asn7^Z=eI>`$2*v78;sj-}oMoEj&@)9+ycEOo92xSyY344^ z11Hb8^kdOvbf^GNAK++bYioknrpdN>+u8R?JxG=!2Kd9r=YWCOJYXYuM0cOq^FhEd zBg2puKy__7VT3-r*dG4c62Wgxi52EMCQ`bKgf*#*ou(D4-ZN$+mg&7$u!! z-^+Z%;-3IDwqZ|K=ah85OLwkO zKxNBh+4QHh)u9D?MFtpbl)us}9+V!D%w9jfAMYEb>%$A;u)rrI zuBudh;5PN}_6J_}l55P3l_)&RMlH{m!)ai-i$g)&*M`eN$XQMw{v^r@-125^RRCF0 z^2>|DxhQw(mtNEI2Kj(;KblC7x=JlK$@78`O~>V!`|1Lm-^JR$-5pUANAnb(5}B}JGjBsliK4& zk6y(;$e&h)lh2)L=bvZKbvh@>vLlreBdH8No2>$#%_Wp1U0N7Ank!6$dFSi#xzh|( zRi{Uw%-4W!{IXZ)fWx@XX6;&(m_F%c6~X8hx=BN1&q}*( zoaNjWabE{oUPb!Bt$eyd#$5j9rItB-h*5JiNi(v^e|XKAj*8(k<5-2$&ZBR5fF|JA z9&m4fbzNQnAU}r8ab>fFV%J0z5awe#UZ|bz?Ur)U9bCIKWEzi2%A+5CLqh?}K4JHi z4vtM;+uPsVz{Lfr;78W78gC;z*yTch~4YkLr&m-7%-xc ztw6Mh2d>_iO*$Rd8(-Cr1_V8EO1f*^@wRoSozS) zy1UoC@pruAaC8Z_7~_w4Q6n*&B0AjOmMWa;sIav&gu z|J5&|{=a@vR!~k-OjKEgPFCzcJ>#A1uL&7xTDn;{XBdeM}V=l3B8fE1--DHjSaxoSjNKEM9|U9#m2<3>n{Iuo`r3UZp;>GkT2YBNAh|b z^jTq-hJp(ebZh#Lk8hVBP%qXwv-@vbvoREX$TqRGTgEi$%_F9tZES@z8Bx}$#5eeG zk^UsLBH{bc2VBW)*EdS({yw=?qmevwi?BL6*=12k9zM5gJv1>y#ML4!)iiPzVaH9% zgSImetD@dam~e>{LvVh!phhzpW+iFvWpGT#CVE5TQ40n%F|p(sP5mXxna+Ev7PDwA zamaV4m*^~*xV+&p;W749xhb_X=$|LD;FHuB&JL5?*Y2-oIT(wYY2;73<^#46S~Gx| z^cez%V7x$81}UWqS13Gz80379Rj;6~WdiXWOSsdmzY39L;Hg3MH43o*y8ibNBBH`(av4|u;YPq%{R;IuYow<+GEsf@R?=@tT@!}?#>zIIn0CoyV!hq3mw zHj>OOjfJM3F{RG#6ujzo?y32m^tgSXf@v=J$ELdJ+=5j|=F-~hP$G&}tDZsZE?5rX ztGj`!S>)CFmdkccxM9eGIcGnS2AfK#gXwj%esuIBNJQP1WV~b~+D7PJTmWGTSDrR` zEAu4B8l>NPuhsk5a`rReSya2nfV1EK01+G!x8aBdTs3Io$u5!6n6KX%uv@DxAp3F@{4UYg4SWJtQ-W~0MDb|j-$lwVn znAm*Pl!?Ps&3wO=R115RWKb*JKoexo*)uhhHBncEDMSVa_PyA>k{Zm2(wMQ(5NM3# z)jkza|GoWEQo4^s*wE(gHz?Xsg4`}HUAcs42cM1-qq_=+=!Gk^y710j=66(cSWqUe zklbm8+zB_syQv5A2rj!Vbw8;|$@C!vfNmNV!yJIWDQ>{+2x zKjuFX`~~HKG~^6h5FntRpnnHt=D&rq0>IJ9#F0eM)Y-)GpRjiN7gkA8wvnG#K=q{q z9dBn8_~wm4J<3J_vl|9H{7q6u2A!cW{bp#r*-f{gOV^e=8S{nc1DxMHFwuM$;aVI^ zz6A*}m8N-&x8;aunp1w7_vtB*pa+OYBw=TMc6QK=mbA-|Cf* zvyh8D4LRJImooUaSb7t*fVfih<97Gf@VE0|z>NcBwBQze);Rh!k3K_sfunToZY;f2 z^HmC4KjHRVg+eKYj;PRN^|E0>Gj_zagfRbrki68I^#~6-HaHg3BUW%+clM1xQEdPYt_g<2K+z!$>*$9nQ>; zf9Bei{?zY^-e{q_*|W#2rJG`2fy@{%6u0i_VEWTq$*(ZN37|8lFFFt)nCG({r!q#9 z5VK_kkSJ3?zOH)OezMT{!YkCuSSn!K#-Rhl$uUM(bq*jY? zi1xbMVthJ`E>d>(f3)~fozjg^@eheMF6<)I`oeJYx4*+M&%c9VArn(OM-wp%M<-`x z7sLP1&3^%Nld9Dhm@$3f2}87!quhI@nwd@3~fZl_3LYW-B?Ia>ui`ELg z&Qfe!7m6ze=mZ`Ia9$z|ARSw|IdMpooY4YiPN8K z4B(ts3p%2i(Td=tgEHX z0UQ_>URBtG+-?0E;E7Ld^dyZ;jjw0}XZ(}-QzC6+NN=40oDb2^v!L1g9xRvE#@IBR zO!b-2N7wVfLV;mhEaXQ9XAU+>=XVA6f&T4Z-@AX!leJ8obP^P^wP0aICND?~w&NykJ#54x3_@r7IDMdRNy4Hh;h*!u(Ol(#0bJdwEo$5437-UBjQ+j=Ic>Q2z` zJNDf0yO6@mr6y1#n3)s(W|$iE_i8r@Gd@!DWDqZ7J&~gAm1#~maIGJ1sls^gxL9LLG_NhU!pTGty!TbhzQnu)I*S^54U6Yu%ZeCg`R>Q zhBv$n5j0v%O_j{QYWG!R9W?5_b&67KB$t}&e2LdMvd(PxN6Ir!H4>PNlerpBL>Zvyy!yw z-SOo8caEpDt(}|gKPBd$qND5#a5nju^O>V&;f890?yEOfkSG^HQVmEbM3Ugzu+UtH zC(INPDdraBN?P%kE;*Ae%Wto&sgw(crfZ#Qy(<4nk;S|hD3j{IQRI6Yq|f^basLY; z-HB&Je%Gg}Jt@={_C{L$!RM;$$|iD6vu#3w?v?*;&()uB|I-XqEKqZPS!reW9JkLewLb!70T7n`i!gNtb1%vN- zySZj{8-1>6E%H&=V}LM#xmt`J3XQoaD|@XygXjdZ1+P77-=;=eYpoEQ01B@L*a(uW zrZeZz?HJsw_4g0vhUgkg@VF8<-X$B8pOqCuWAl28uB|@r`19DTUQQsb^pfqB6QtiT z*`_UZ`fT}vtUY#%sq2{rchyfu*pCg;uec2$-$N_xgjZcoumE5vSI{+s@iLWoz^Mf; zuI8kDP{!XY6OP~q5}%1&L}CtfH^N<3o4L@J@zg1-mt{9L`s^z$Vgb|mr{@WiwAqKg zp#t-lhrU>F8o0s1q_9y`gQNf~Vb!F%70f}$>i7o4ho$`uciNf=xgJ>&!gSt0g;M>*x4-`U)ysFW&Vs^Vk6m%?iuWU+o&m(2Jm26Y(3%TL; zA7T)BP{WS!&xmxNw%J=$MPfn(9*^*TV;$JwRy8Zl*yUZi8jWYF>==j~&S|Xinsb%c z2?B+kpet*muEW7@AzjBA^wAJBY8i|#C{WtO_or&Nj2{=6JTTX05}|H>N2B|Wf!*3_ z7hW*j6p3TvpghEc6-wufFiY!%-GvOx*bZrhZu+7?iSrZL5q9}igiF^*R3%DE4aCHZ zqu>xS8LkW+Auv%z-<1Xs92u23R$nk@Pk}MU5!gT|c7vGlEA%G^2th&Q*zfg%-D^=f z&J_}jskj|Q;73NP4<4k*Y%pXPU2Thoqr+5uH1yEYM|VtBPW6lXaetokD0u z9qVek6Q&wk)tFbQ8(^HGf3Wp16gKmr>G;#G(HRBx?F`9AIRboK+;OfHaLJ(P>IP0w zyTbTkx_THEOs%Q&aPrxbZrJlio+hCC_HK<4%f3ZoSAyG7Dn`=X=&h@m*|UYO-4Hq0 z-Bq&+Ie!S##4A6OGoC~>ZW`Y5J)*ouaFl_e9GA*VSL!O_@xGiBw!AF}1{tB)z(w%c zS1Hmrb9OC8>0a_$BzeiN?rkPLc9%&;1CZW*4}CDDNr2gcl_3z+WC15&H1Zc2{o~i) z)LLW=WQ{?ricmC`G1GfJ0Yp4Dy~Ba;j6ZV4r{8xRs`13{dD!xXmr^Aga|C=iSmor% z8hi|pTXH)5Yf&v~exp3o+sY4B^^b*eYkkCYl*T{*=-0HniSA_1F53eCb{x~1k3*`W zr~};p1A`k{1DV9=UPnLDgz{aJH=-LQo<5%+Em!DNN252xwIf*wF_zS^!(XSm(9eoj z=*dXG&n0>)_)N5oc6v!>-bd(2ragD8O=M|wGW z!xJQS<)u70m&6OmrF0WSsr@I%T*c#Qo#Ha4d3COcX+9}hM5!7JIGF>7<~C(Ear^Sn zm^ZFkV6~Ula6+8S?oOROOA6$C&q&dp`>oR-2Ym3(HT@O7Sd5c~+kjrmM)YmgPH*tL zX+znN>`tv;5eOfX?h{AuX^LK~V#gPCu=)Tigtq9&?7Xh$qN|%A$?V*v=&-2F$zTUv z`C#WyIrChS5|Kgm_GeudCFf;)!WH7FI60j^0o#65o6`w*S7R@)88n$1nrgU(oU0M9 zx+EuMkC>(4j1;m6NoGqEkpJYJ?vc|B zOlwT3t&UgL!pX_P*6g36`ZXQ; z9~Cv}ANFnJGp(;ZhS(@FT;3e)0)Kp;h^x;$*xZn*k0U6-&FwI=uOGaODdrsp-!K$Ac32^c{+FhI-HkYd5v=`PGsg%6I`4d9Jy)uW0y%) zm&j^9WBAp*P8#kGJUhB!L?a%h$hJgQrx!6KCB_TRo%9{t0J7KW8!o1B!NC)VGLM5! zpZy5Jc{`r{1e(jd%jsG7k%I+m#CGS*BPA65ZVW~fLYw0dA-H_}O zrkGFL&P1PG9p2(%QiEWm6x;U-U&I#;Em$nx-_I^wtgw3xUPVVu zqSuKnx&dIT-XT+T10p;yjo1Y)z(x1fb8Dzfn8e yu?e%!_ptzGB|8GrCfu%p?(_ zQccdaaVK$5bz;*rnyK{_SQYM>;aES6Qs^lj9lEs6_J+%nIiuQC*fN;z8md>r_~Mfl zU%p5Dt_YT>gQqfr@`cR!$NWr~+`CZb%dn;WtzrAOI>P_JtsB76PYe*<%H(y>qx-`Kq!X_; z<{RpAqYhE=L1r*M)gNF3B8r(<%8mo*SR2hu zccLRZwGARt)Hlo1euqTyM>^!HK*!Q2P;4UYrysje@;(<|$&%vQekbn|0Ruu_Io(w4#%p6ld2Yp7tlA`Y$cciThP zKzNGIMPXX%&Ud0uQh!uQZz|FB`4KGD?3!ND?wQt6!n*f4EmCoJUh&b?;B{|lxs#F- z31~HQ`SF4x$&v00@(P+j1pAaj5!s`)b2RDBp*PB=2IB>oBF!*6vwr7Dp%zpAx*dPr zb@Zjq^XjN?O4QcZ*O+8>)|HlrR>oD*?WQl5ri3R#2?*W6iJ>>kH%KnnME&TT@ZzrHS$Q%LC?n|e>V+D+8D zYc4)QddFz7I8#}y#Wj6>4P%34dZH~OUDb?uP%-E zwjXM(?Sg~1!|wI(RVuxbu)-rH+O=igSho_pDCw(c6b=P zKk4ATlB?bj9+HHlh<_!&z0rx13K3ZrAR8W)!@Y}o`?a*JJsD+twZIv`W)@Y?Amu_u zz``@-e2X}27$i(2=9rvIu5uTUOVhzwu%mNazS|lZb&PT;XE2|B&W1>=B58#*!~D&) zfVmJGg8UdP*fx(>Cj^?yS^zH#o-$Q-*$SnK(ZVFkw+er=>N^7!)FtP3y~Xxnu^nzY zikgB>Nj0%;WOltWIob|}%lo?_C7<``a5hEkx&1ku$|)i>Rh6@3h*`slY=9U}(Ql_< zaNG*J8vb&@zpdhAvv`?{=zDedJ23TD&Zg__snRAH4eh~^oawdYi6A3w8<Ozh@Kw)#bdktM^GVb zrG08?0bG?|NG+w^&JvD*7LAbjED{_Zkc`3H!My>0u5Q}m!+6VokMLXxl`Mkd=g&Xx z-a>m*#G3SLlhbKB!)tnzfWOBV;u;ftU}S!NdD5+YtOjLg?X}dl>7m^gOpihrf1;PY zvll&>dIuUGs{Qnd- zwIR3oIrct8Va^Tm0t#(bJD7c$Z7DO9*7NnRZorrSm`b`cxz>OIC;jSE3DO8`hX955ui`s%||YQtt2 z5DNA&pG-V+4oI2s*x^>-$6J?p=I>C|9wZF8z;VjR??Icg?1w2v5Me+FgAeGGa8(3S z4vg*$>zC-WIVZtJ7}o9{D-7d>zCe|z#<9>CFve-OPAYsneTb^JH!Enaza#j}^mXy1 z+ULn^10+rWLF6j2>Ya@@Kq?26>AqK{A_| zQKb*~F1>sE*=d?A?W7N2j?L09_7n+HGi{VY;MoTGr_)G9)ot$p!-UY5zZ2Xtbm=t z@dpPSGwgH=QtIcEulQNI>S-#ifbnO5EWkI;$A|pxJd885oM+ zGZ0_0gDvG8q2xebj+fbCHYfAXuZStH2j~|d^sBAzo46(K8n59+T6rzBwK)^rfPT+B zyIFw)9YC-V^rhtK`!3jrhmW-sTmM+tPH+;nwjL#-SjQPUZ53L@A>y*rt(#M(qsiB2 zx6B)dI}6Wlsw%bJ8h|(lhkJVogQZA&n{?Vgs6gNSXzuZpEyu*xySy8ro07QZ7Vk1!3tJphN_5V7qOiyK8p z#@jcDD8nmtYi1^l8ml;AF<#IPK?!pqf9D4moYk>d99Im}Jtwj6c#+A;f)CQ*f-hZ< z=p_T86jog%!p)D&5g9taSwYi&eP z#JuEK%+NULWus;0w32-SYFku#i}d~+{Pkho&^{;RxzP&0!RCm3-9K6`>KZpnzS6?L z^H^V*s!8<>x8bomvD%rh>Zp3>Db%kyin;qtl+jAv8Oo~1g~mqGAC&Qi_wy|xEt2iz zWAJEfTV%cl2Cs<1L&DLRVVH05EDq`pH7Oh7sR`NNkL%wi}8n>IXcO40hp+J+sC!W?!krJf!GJNE8uj zg-y~Ns-<~D?yqbzVRB}G>0A^f0!^N7l=$m0OdZuqAOQqLc zX?AEGr1Ht+inZ-Qiwnl@Z0qukd__a!C*CKuGdy5#nD7VUBM^6OCpxCa2A(X;e0&V4 zM&WR8+wErQ7UIc6LY~Q9x%Sn*Tn>>P`^t&idaOEnOd(Ufw#>NoR^1QdhJ8s`h^|R_ zXX`c5*O~Xdvh%q;7L!_!ohf$NfEBmCde|#uVZvEo>OfEq%+Ns7&_f$OR9xsihRpBb z+cjk8LyDm@U{YN>+r46?nn{7Gh(;WhFw6GAxtcKD+YWV?uge>;+q#Xx4!GpRkVZYu zzsF}1)7$?%s9g9CH=Zs+B%M_)+~*j3L0&Q9u7!|+T`^O{xE6qvAP?XWv9_MrZKdo& z%IyU)$Q95AB4!#hT!_dA>4e@zjOBD*Y=XjtMm)V|+IXzjuM;(l+8aA5#Kaz_$rR6! zj>#&^DidYD$nUY(D$mH`9eb|dtV0b{S>H6FBfq>t5`;OxA4Nn{J(+XihF(stSche7$es&~N$epi&PDM_N`As;*9D^L==2Q7Z2zD+CiU(|+-kL*VG+&9!Yb3LgPy?A zm7Z&^qRG_JIxK7-FBzZI3Q<;{`DIxtc48k> zc|0dmX;Z=W$+)qE)~`yn6MdoJ4co;%!`ddy+FV538Y)j(vg}5*k(WK)KWZ3WaOG!8 z!syGn=s{H$odtpqFrT#JGM*utN7B((abXnpDM6w56nhw}OY}0TiTG1#f*VFZr+^-g zbP10`$LPq_;PvrA1XXlyx2uM^mrjTzX}w{yuLo-cOClE8MMk47T25G8M!9Z5ypOSV zAJUBGEg5L2fY)ZGJb^E34R2zJ?}Vf>{~gB!8=5Z) z9y$>5c)=;o0HeHHSuE4U)#vG&KF|I%-cF6f$~pdYJWk_dD}iOA>iA$O$+4%@>JU08 zS`ep)$XLPJ+n0_i@PkF#ri6T8?ZeAot$6JIYHm&P6EB=BiaNY|aA$W0I+nz*zkz_z zkEru!tj!QUffq%)8y0y`T&`fuus-1p>=^hnBiBqD^hXrPs`PY9tU3m0np~rISY09> z`P3s=-kt_cYcxWd{de@}TwSqg*xVhp;E9zCsnXo6z z?f&Sv^U7n4`xr=mXle94HzOdN!2kB~4=%)u&N!+2;z6UYKUDqi-s6AZ!haB;@&B`? z_TRX0%@suz^TRdCb?!vNJYPY8L_}&07uySH9%W^Tc&1pia6y1q#?*Drf}GjGbPjBS zbOPcUY#*$3sL2x4v_i*Y=N7E$mR}J%|GUI(>WEr+28+V z%v5{#e!UF*6~G&%;l*q*$V?&r$Pp^sE^i-0$+RH3ERUUdQ0>rAq2(2QAbG}$y{de( z>{qD~GGuOk559Y@%$?N^1ApVL_a704>8OD%8Y%8B;FCt%AoPu8*D1 zLB5X>b}Syz81pn;xnB}%0FnwazlWfUV)Z-~rZg6~b z6!9J$EcE&sEbzcy?CI~=boWA&eeIa%z(7SE^qgVLz??1Vbc1*aRvc%Mri)AJaAG!p z$X!_9Ds;Zz)f+;%s&dRcJt2==P{^j3bf0M=nJd&xwUGlUFn?H=2W(*2I2Gdu zv!gYCwM10aeus)`RIZSrCK=&oKaO_Ry~D1B5!y0R=%!i2*KfXGYX&gNv_u+n9wiR5 z*e$Zjju&ODRW3phN925%S(jL+bCHv6rZtc?!*`1TyYXT6%Ju=|X;6D@lq$8T zW{Y|e39ioPez(pBH%k)HzFITXHvnD6hw^lIoUMA;qAJ^CU?top1fo@s7xT13Fvn1H z6JWa-6+FJF#x>~+A;D~;VDs26>^oH0EI`IYT2iagy23?nyJ==i{g4%HrAf1-*v zK1)~@&(KkwR7TL}L(A@C_S0G;-GMDy=MJn2$FP5s<%wC)4jC5PXoxrQBFZ_k0P{{s@sz+gX`-!=T8rcB(=7vW}^K6oLWMmp(rwDh}b zwaGGd>yEy6fHv%jM$yJXo5oMAQ>c9j`**}F?MCry;T@47@r?&sKHgVe$MCqk#Z_3S z1GZI~nOEN*P~+UaFGnj{{Jo@16`(qVNtbU>O0Hf57-P>x8Jikp=`s8xWs^dAJ9lCQ z)GFm+=OV%AMVqVATtN@|vp61VVAHRn87}%PC^RAzJ%JngmZTasWBAWsoAqBU+8L8u z4A&Pe?fmTm0?mK-BL9t+{y7o(7jm+RpOhL9KnY#E&qu^}B6=K_dB}*VlSEiC9fn)+V=J;OnN)Ta5v66ic1rG+dGAJ1 z1%Zb_+!$=tQ~lxQrzv3x#CPb?CekEkA}0MYSgx$Jdd}q8+R=ma$|&1a#)TQ=l$1tQ z=tL9&_^vJ)Pk}EDO-va`UCT1m#Uty1{v^A3P~83_#v^ozH}6*9mIjIr;t3Uv%@VeW zGL6(CwCUp)Jq%G0bIG%?{_*Y#5IHf*5M@wPo6A{$Um++Co$wLC=J1aoG93&T7Ho}P z=mGEPP7GbvoG!uD$k(H3A$Z))+i{Hy?QHdk>3xSBXR0j!11O^mEe9RHmw!pvzv?Ua~2_l2Yh~_!s1qS`|0~0)YsbHSz8!mG)WiJE| z2f($6TQtt6L_f~ApQYQKSb=`053LgrQq7G@98#igV>y#i==-nEjQ!XNu9 z~;mE+gtj4IDDNQJ~JVk5Ux6&LCSFL!y=>79kE9=V}J7tD==Ga+IW zX)r7>VZ9dY=V&}DR))xUoV!u(Z|%3ciQi_2jl}3=$Agc(`RPb z8kEBpvY>1FGQ9W$n>Cq=DIpski};nE)`p3IUw1Oz0|wxll^)4dq3;CCY@RyJgFgc# zKouFh!`?Xuo{IMz^xi-h=StCis_M7yq$u) z?XHvw*HP0VgR+KR6wI)jEMX|ssqYvSf*_3W8zVTQzD?3>H!#>InzpSO)@SC8q*ii- z%%h}_#0{4JG;Jm`4zg};BPTGkYamx$Xo#O~lBirRY)q=5M45n{GCfV7h9qwyu1NxOMoP4)jjZMxmT|IQQh0U7C$EbnMN<3)Kk?fFHYq$d|ICu>KbY_hO zTZM+uKHe(cIZfEqyzyYSUBZa8;Fcut-GN!HSA9ius`ltNebF46ZX_BbZNU}}ZOm{M2&nANL9@0qvih15(|`S~z}m&h!u4x~(%MAO$jHRWNfuxWF#B)E&g3ghSQ9|> z(MFaLQj)NE0lowyjvg8z0#m6FIuKE9lDO~Glg}nSb7`~^&#(Lw{}GVOS>U)m8bF}x zVjbXljBm34Cs-yM6TVusr+3kYFjr28STT3g056y3cH5Tmge~ASxBj z%|yb>$eF;WgrcOZf569sDZOVwoo%8>XO>XQOX1OyN9I-SQgrm;U;+#3OI(zrWyow3 zk==|{lt2xrQ%FIXOTejR>;wv(Pb8u8}BUpx?yd(Abh6? zsoO3VYWkeLnF43&@*#MQ9-i-d0t*xN-UEyNKeyNMHw|A(k(_6QKO=nKMCxD(W(Yop zsRQ)QeL4X3Lxp^L%wzi2-WVSsf61dqliPUM7srDB?Wm6Lzn0&{*}|IsKQW;02(Y&| zaTKv|`U(pSzuvR6Rduu$wzK_W-Y-7>7s?G$)U}&uK;<>vU}^^ns@Z!p+9?St1s)dG zK%y6xkPyyS1$~&6v{kl?Md6gwM|>mt6Upm>oa8RLD^8T{0?HC!Z>;(Bob7el(DV6x zi`I)$&E&ngwFS@bi4^xFLAn`=fzTC;aimE^!cMI2n@Vo%Ae-ne`RF((&5y6xsjjAZ zVguVoQ?Z9uk$2ON;ersE%PU*xGO@T*;j1BO5#TuZKEf(mB7|g7pcEA=nYJ{s3vlbg zd4-DUlD{*6o%Gc^N!Nptgay>j6E5;3psI+C3Q!1ZIbeCubW%w4pq9)MSDyB{HLm|k zxv-{$$A*pS@csolri$Ge<4VZ}e~78JOL-EVyrbxKra^d{?|NnPp86!q>t<&IP07?Z z^>~IK^k#OEKgRH+LjllZXk7iA>2cfH6+(e&9ku5poo~6y{GC5>(bRK7hwjiurqAiZ zg*DmtgY}v83IjE&AbiWgMyFbaRUPZ{lYiz$U^&Zt2YjG<%m((&_JUbZcfJ22(>bi5 z!J?<7AySj0JZ&<-qXX;mcV!f~>G=sB0KnjWca4}vrtunD^1TrpfeS^4dvFr!65knK zZh`d;*VOkPs4*-9kL>$GP0`(M!j~B;#x?Ba~&s6CopvO86oM?-? zOw#dIRc;6A6T?B`Qp%^<U5 z19x(ywSH$_N+Io!6;e?`tWaM$`=Db!gzx|lQ${DG!zb1Zl&|{kX0y6xvO1o z220r<-oaS^^R2pEyY;=Qllqpmue|5yI~D|iI!IGt@iod{Opz@*ml^w2bNs)p`M(Io z|E;;m*Xpjd9l)4G#KaWfV(t8YUn@A;nK^#xgv=LtnArX|vWQVuw3}B${h+frU2>9^ z!l6)!Uo4`5k`<<;E(ido7M6lKTgWezNLq>U*=uz&s=cc$1%>VrAeOoUtA|T6gO4>UNqsdK=NF*8|~*sl&wI=x9-EGiq*aqV!(VVXA57 zw9*o6Ir8Lj1npUXvlevtn(_+^X5rzdR>#(}4YcB9O50q97%rW2me5_L=%ffYPUSRc z!vv?Kv>dH994Qi>U(a<0KF6NH5b16enCp+mw^Hb3Xs1^tThFpz!3QuN#}KBbww`(h z7GO)1olDqy6?T$()R7y%NYx*B0k_2IBiZ14&8|JPFxeMF{vW>HF-Vi3+ZOI=+qP}n zw(+!WcTd~4ZJX1!ZM&y!+uyt=&i!+~d(V%GjH;-NsEEv6nS1TERt|RHh!0>W4+4pp z1-*EzAM~i`+1f(VEHI8So`S`akPfPTfq*`l{Fz`hS%k#JS0cjT2mS0#QLGf=J?1`he3W*;m4)ce8*WFq1sdP=~$5RlH1EdWm|~dCvKOi4*I_96{^95p#B<(n!d?B z=o`0{t+&OMwKcxiBECznJcfH!fL(z3OvmxP#oWd48|mMjpE||zdiTBdWelj8&Qosv zZFp@&UgXuvJw5y=q6*28AtxZzo-UUpkRW%ne+Ylf!V-0+uQXBW=5S1o#6LXNtY5!I z%Rkz#(S8Pjz*P7bqB6L|M#Er{|QLae-Y{KA>`^} z@lPjeX>90X|34S-7}ZVXe{wEei1<{*e8T-Nbj8JmD4iwcE+Hg_zhkPVm#=@b$;)h6 z<<6y`nPa`f3I6`!28d@kdM{uJOgM%`EvlQ5B2bL)Sl=|y@YB3KeOzz=9cUW3clPAU z^sYc}xf9{4Oj?L5MOlYxR{+>w=vJjvbyO5}ptT(o6dR|ygO$)nVCvNGnq(6;bHlBd zl?w-|plD8spjDF03g5ip;W3Z z><0{BCq!Dw;h5~#1BuQilq*TwEu)qy50@+BE4bX28+7erX{BD4H)N+7U`AVEuREE8 z;X?~fyhF-x_sRfHIj~6f(+^@H)D=ngP;mwJjxhQUbUdzk8f94Ab%59-eRIq?ZKrwD z(BFI=)xrUlgu(b|hAysqK<}8bslmNNeD=#JW*}^~Nrswn^xw*nL@Tx!49bfJecV&KC2G4q5a!NSv)06A_5N3Y?veAz;Gv+@U3R% z)~UA8-0LvVE{}8LVDOHzp~2twReqf}ODIyXMM6=W>kL|OHcx9P%+aJGYi_Om)b!xe zF40Vntn0+VP>o<$AtP&JANjXBn7$}C@{+@3I@cqlwR2MdwGhVPxlTIcRVu@Ho-wO` z_~Or~IMG)A_`6-p)KPS@cT9mu9RGA>dVh5wY$NM9-^c@N=hcNaw4ITjm;iWSP^ZX| z)_XpaI61<+La+U&&%2a z0za$)-wZP@mwSELo#3!PGTt$uy0C(nTT@9NX*r3Ctw6J~7A(m#8fE)0RBd`TdKfAT zCf@$MAxjP`O(u9s@c0Fd@|}UQ6qp)O5Q5DPCeE6mSIh|Rj{$cAVIWsA=xPKVKxdhg zLzPZ`3CS+KIO;T}0Ip!fAUaNU>++ZJZRk@I(h<)RsJUhZ&Ru9*!4Ptn;gX^~4E8W^TSR&~3BAZc#HquXn)OW|TJ`CTahk+{qe`5+ixON^zA9IFd8)kc%*!AiLu z>`SFoZ5bW-%7}xZ>gpJcx_hpF$2l+533{gW{a7ce^B9sIdmLrI0)4yivZ^(Vh@-1q zFT!NQK$Iz^xu%|EOK=n>ug;(7J4OnS$;yWmq>A;hsD_0oAbLYhW^1Vdt9>;(JIYjf zdb+&f&D4@4AS?!*XpH>8egQvSVX`36jMd>$+RgI|pEg))^djhGSo&#lhS~9%NuWfX zDDH;3T*GzRT@5=7ibO>N-6_XPBYxno@mD_3I#rDD?iADxX`! zh*v8^i*JEMzyN#bGEBz7;UYXki*Xr(9xXax(_1qVW=Ml)kSuvK$coq2A(5ZGhs_pF z$*w}FbN6+QDseuB9=fdp_MTs)nQf!2SlROQ!gBJBCXD&@-VurqHj0wm@LWX-TDmS= z71M__vAok|@!qgi#H&H%Vg-((ZfxPAL8AI{x|VV!9)ZE}_l>iWk8UPTGHs*?u7RfP z5MC&=c6X;XlUzrz5q?(!eO@~* zoh2I*%J7dF!!_!vXoSIn5o|wj1#_>K*&CIn{qSaRc&iFVxt*^20ngCL;QonIS>I5^ zMw8HXm>W0PGd*}Ko)f|~dDd%;Wu_RWI_d;&2g6R3S63Uzjd7dn%Svu-OKpx*o|N>F zZg=-~qLb~VRLpv`k zWSdfHh@?dp=s_X`{yxOlxE$4iuyS;Z-x!*E6eqmEm*j2bE@=ZI0YZ5%Yj29!5+J$4h{s($nakA`xgbO8w zi=*r}PWz#lTL_DSAu1?f%-2OjD}NHXp4pXOsCW;DS@BC3h-q4_l`<))8WgzkdXg3! zs1WMt32kS2E#L0p_|x+x**TFV=gn`m9BWlzF{b%6j-odf4{7a4y4Uaef@YaeuPhU8 zHBvRqN^;$Jizy+ z=zW{E5<>2gp$pH{M@S*!sJVQU)b*J5*bX4h>5VJve#Q6ga}cQ&iL#=(u+KroWrxa%8&~p{WEUF0il=db;-$=A;&9M{Rq`ouZ5m%BHT6%st%saGsD6)fQgLN}x@d3q>FC;=f%O3Cyg=Ke@Gh`XW za@RajqOE9UB6eE=zhG%|dYS)IW)&y&Id2n7r)6p_)vlRP7NJL(x4UbhlcFXWT8?K=%s7;z?Vjts?y2+r|uk8Wt(DM*73^W%pAkZa1Jd zNoE)8FvQA>Z`eR5Z@Ig6kS5?0h;`Y&OL2D&xnnAUzQz{YSdh0k zB3exx%A2TyI)M*EM6htrxSlep!Kk(P(VP`$p0G~f$smld6W1r_Z+o?=IB@^weq>5VYsYZZR@` z&XJFxd5{|KPZmVOSxc@^%71C@;z}}WhbF9p!%yLj3j%YOlPL5s>7I3vj25 z@xmf=*z%Wb4;Va6SDk9cv|r*lhZ`(y_*M@>q;wrn)oQx%B(2A$9(74>;$zmQ!4fN; z>XurIk-7@wZys<+7XL@0Fhe-f%*=(weaQEdR9Eh6>Kl-EcI({qoZqyzziGwpg-GM#251sK_ z=3|kitS!j%;fpc@oWn65SEL73^N&t>Ix37xgs= zYG%eQDJc|rqHFia0!_sm7`@lvcv)gfy(+KXA@E{3t1DaZ$DijWAcA)E0@X?2ziJ{v z&KOYZ|DdkM{}t+@{@*6ge}m%xfjIxi%qh`=^2Rwz@w0cCvZ&Tc#UmCDbVwABrON^x zEBK43FO@weA8s7zggCOWhMvGGE`baZ62cC)VHyy!5Zbt%ieH+XN|OLbAFPZWyC6)p z4P3%8sq9HdS3=ih^0OOlqTPbKuzQ?lBEI{w^ReUO{V?@`ARsL|S*%yOS=Z%sF)>-y z(LAQdhgAcuF6LQjRYfdbD1g4o%tV4EiK&ElLB&^VZHbrV1K>tHTO{#XTo>)2UMm`2 z^t4s;vnMQgf-njU-RVBRw0P0-m#d-u`(kq7NL&2T)TjI_@iKuPAK-@oH(J8?%(e!0Ir$yG32@CGUPn5w4)+9@8c&pGx z+K3GKESI4*`tYlmMHt@br;jBWTei&(a=iYslc^c#RU3Q&sYp zSG){)V<(g7+8W!Wxeb5zJb4XE{I|&Y4UrFWr%LHkdQ;~XU zgy^dH-Z3lmY+0G~?DrC_S4@=>0oM8Isw%g(id10gWkoz2Q%7W$bFk@mIzTCcIB(K8 zc<5h&ZzCdT=9n-D>&a8vl+=ZF*`uTvQviG_bLde*k>{^)&0o*b05x$MO3gVLUx`xZ z43j+>!u?XV)Yp@MmG%Y`+COH2?nQcMrQ%k~6#O%PeD_WvFO~Kct za4XoCM_X!c5vhRkIdV=xUB3xI2NNStK*8_Zl!cFjOvp-AY=D;5{uXj}GV{LK1~IE2 z|KffUiBaStRr;10R~K2VVtf{TzM7FaPm;Y(zQjILn+tIPSrJh&EMf6evaBKIvi42-WYU9Vhj~3< zZSM-B;E`g_o8_XTM9IzEL=9Lb^SPhe(f(-`Yh=X6O7+6ALXnTcUFpI>ekl6v)ZQeNCg2 z^H|{SKXHU*%nBQ@I3It0m^h+6tvI@FS=MYS$ZpBaG7j#V@P2ZuYySbp@hA# ze(kc;P4i_-_UDP?%<6>%tTRih6VBgScKU^BV6Aoeg6Uh(W^#J^V$Xo^4#Ekp ztqQVK^g9gKMTHvV7nb64UU7p~!B?>Y0oFH5T7#BSW#YfSB@5PtE~#SCCg3p^o=NkMk$<8- z6PT*yIKGrvne7+y3}_!AC8NNeI?iTY(&nakN>>U-zT0wzZf-RuyZk^X9H-DT_*wk= z;&0}6LsGtfVa1q)CEUPlx#(ED@-?H<1_FrHU#z5^P3lEB|qsxEyn%FOpjx z3S?~gvoXy~L(Q{Jh6*i~=f%9kM1>RGjBzQh_SaIDfSU_9!<>*Pm>l)cJD@wlyxpBV z4Fmhc2q=R_wHCEK69<*wG%}mgD1=FHi4h!98B-*vMu4ZGW~%IrYSLGU{^TuseqVgV zLP<%wirIL`VLyJv9XG_p8w@Q4HzNt-o;U@Au{7%Ji;53!7V8Rv0^Lu^Vf*sL>R(;c zQG_ZuFl)Mh-xEIkGu}?_(HwkB2jS;HdPLSxVU&Jxy9*XRG~^HY(f0g8Q}iqnVmgjI zfd=``2&8GsycjR?M%(zMjn;tn9agcq;&rR!Hp z$B*gzHsQ~aXw8c|a(L^LW(|`yGc!qOnV(ZjU_Q-4z1&0;jG&vAKuNG=F|H?@m5^N@ zq{E!1n;)kNTJ>|Hb2ODt-7U~-MOIFo%9I)_@7fnX+eMMNh>)V$IXesJpBn|uo8f~#aOFytCT zf9&%MCLf8mp4kwHTcojWmM3LU=#|{3L>E}SKwOd?%{HogCZ_Z1BSA}P#O(%H$;z7XyJ^sjGX;j5 zrzp>|Ud;*&VAU3x#f{CKwY7Vc{%TKKqmB@oTHA9;>?!nvMA;8+Jh=cambHz#J18x~ zs!dF>$*AnsQ{{82r5Aw&^7eRCdvcgyxH?*DV5(I$qXh^zS>us*I66_MbL8y4d3ULj z{S(ipo+T3Ag!+5`NU2sc+@*m{_X|&p#O-SAqF&g_n7ObB82~$p%fXA5GLHMC+#qqL zdt`sJC&6C2)=juQ_!NeD>U8lDVpAOkW*khf7MCcs$A(wiIl#B9HM%~GtQ^}yBPjT@ z+E=|A!Z?A(rwzZ;T}o6pOVqHzTr*i;Wrc%&36kc@jXq~+w8kVrs;%=IFdACoLAcCAmhFNpbP8;s`zG|HC2Gv?I~w4ITy=g$`0qMQdkijLSOtX6xW%Z9Nw<;M- zMN`c7=$QxN00DiSjbVt9Mi6-pjv*j(_8PyV-il8Q-&TwBwH1gz1uoxs6~uU}PrgWB zIAE_I-a1EqlIaGQNbcp@iI8W1sm9fBBNOk(k&iLBe%MCo#?xI$%ZmGA?=)M9D=0t7 zc)Q0LnI)kCy{`jCGy9lYX%mUsDWwsY`;jE(;Us@gmWPqjmXL+Hu#^;k%eT>{nMtzj zsV`Iy6leTA8-PndszF;N^X@CJrTw5IIm!GPeu)H2#FQitR{1p;MasQVAG3*+=9FYK zw*k!HT(YQorfQj+1*mCV458(T5=fH`um$gS38hw(OqVMyunQ;rW5aPbF##A3fGH6h z@W)i9Uff?qz`YbK4c}JzQpuxuE3pcQO)%xBRZp{zJ^-*|oryTxJ-rR+MXJ)!f=+pp z10H|DdGd2exhi+hftcYbM0_}C0ZI-2vh+$fU1acsB-YXid7O|=9L!3e@$H*6?G*Zp z%qFB(sgl=FcC=E4CYGp4CN>=M8#5r!RU!u+FJVlH6=gI5xHVD&k;Ta*M28BsxfMV~ zLz+@6TxnfLhF@5=yQo^1&S}cmTN@m!7*c6z;}~*!hNBjuE>NLVl2EwN!F+)0$R1S! zR|lF%n!9fkZ@gPW|x|B={V6x3`=jS*$Pu0+5OWf?wnIy>Y1MbbGSncpKO0qE(qO=ts z!~@&!N`10S593pVQu4FzpOh!tvg}p%zCU(aV5=~K#bKi zHdJ1>tQSrhW%KOky;iW+O_n;`l9~omqM%sdxdLtI`TrJzN6BQz+7xOl*rM>xVI2~# z)7FJ^Dc{DC<%~VS?@WXzuOG$YPLC;>#vUJ^MmtbSL`_yXtNKa$Hk+l-c!aC7gn(Cg ze?YPYZ(2Jw{SF6MiO5(%_pTo7j@&DHNW`|lD`~{iH+_eSTS&OC*2WTT*a`?|9w1dh zh1nh@$a}T#WE5$7Od~NvSEU)T(W$p$s5fe^GpG+7fdJ9=enRT9$wEk+ZaB>G3$KQO zgq?-rZZnIv!p#>Ty~}c*Lb_jxJg$eGM*XwHUwuQ|o^}b3^T6Bxx{!?va8aC@-xK*H ztJBFvFfsSWu89%@b^l3-B~O!CXs)I6Y}y#0C0U0R0WG zybjroj$io0j}3%P7zADXOwHwafT#uu*zfM!oD$6aJx7+WL%t-@6^rD_a_M?S^>c;z zMK580bZXo1f*L$CuMeM4Mp!;P@}b~$cd(s5*q~FP+NHSq;nw3fbWyH)i2)-;gQl{S zZO!T}A}fC}vUdskGSq&{`oxt~0i?0xhr6I47_tBc`fqaSrMOzR4>0H^;A zF)hX1nfHs)%Zb-(YGX;=#2R6C{BG;k=?FfP?9{_uFLri~-~AJ;jw({4MU7e*d)?P@ zXX*GkNY9ItFjhwgAIWq7Y!ksbMzfqpG)IrqKx9q{zu%Mdl+{Dis#p9q`02pr1LG8R z@As?eG!>IoROgS!@J*to<27coFc1zpkh?w=)h9CbYe%^Q!Ui46Y*HO0mr% zEff-*$ndMNw}H2a5@BsGj5oFfd!T(F&0$<{GO!Qdd?McKkorh=5{EIjDTHU`So>8V zBA-fqVLb2;u7UhDV1xMI?y>fe3~4urv3%PX)lDw+HYa;HFkaLqi4c~VtCm&Ca+9C~ zge+67hp#R9`+Euq59WhHX&7~RlXn=--m8$iZ~~1C8cv^2(qO#X0?vl91gzUKBeR1J z^p4!!&7)3#@@X&2aF2-)1Ffcc^F8r|RtdL2X%HgN&XU-KH2SLCbpw?J5xJ*!F-ypZ zMG%AJ!Pr&}`LW?E!K~=(NJxuSVTRCGJ$2a*Ao=uUDSys!OFYu!Vs2IT;xQ6EubLIl z+?+nMGeQQhh~??0!s4iQ#gm3!BpMpnY?04kK375e((Uc7B3RMj;wE?BCoQGu=UlZt!EZ1Q*auI)dj3Jj{Ujgt zW5hd~-HWBLI_3HuO) zNrb^XzPsTIb=*a69wAAA3J6AAZZ1VsYbIG}a`=d6?PjM)3EPaDpW2YP$|GrBX{q*! z$KBHNif)OKMBCFP5>!1d=DK>8u+Upm-{hj5o|Wn$vh1&K!lVfDB&47lw$tJ?d5|=B z^(_9=(1T3Fte)z^>|3**n}mIX;mMN5v2F#l(q*CvU{Ga`@VMp#%rQkDBy7kYbmb-q z<5!4iuB#Q_lLZ8}h|hPODI^U6`gzLJre9u3k3c#%86IKI*^H-@I48Bi*@avYm4v!n0+v zWu{M{&F8#p9cx+gF0yTB_<2QUrjMPo9*7^-uP#~gGW~y3nfPAoV%amgr>PSyVAd@l)}8#X zR5zV6t*uKJZL}?NYvPVK6J0v4iVpwiN|>+t3aYiZSp;m0!(1`bHO}TEtWR1tY%BPB z(W!0DmXbZAsT$iC13p4f>u*ZAy@JoLAkJhzFf1#4;#1deO8#8d&89}en&z!W&A3++^1(;>0SB1*54d@y&9Pn;^IAf3GiXbfT`_>{R+Xv; zQvgL>+0#8-laO!j#-WB~(I>l0NCMt_;@Gp_f0#^c)t?&#Xh1-7RR0@zPyBz!U#0Av zT?}n({(p?p7!4S2ZBw)#KdCG)uPnZe+U|0{BW!m)9 zi_9$F?m<`2!`JNFv+w8MK_K)qJ^aO@7-Ig>cM4-r0bi=>?B_2mFNJ}aE3<+QCzRr*NA!QjHw# z`1OsvcoD0?%jq{*7b!l|L1+Tw0TTAM4XMq7*ntc-Ived>Sj_ZtS|uVdpfg1_I9knY z2{GM_j5sDC7(W&}#s{jqbybqJWyn?{PW*&cQIU|*v8YGOKKlGl@?c#TCnmnAkAzV- zmK={|1G90zz=YUvC}+fMqts0d4vgA%t6Jhjv?d;(Z}(Ep8fTZfHA9``fdUHkA+z3+ zhh{ohP%Bj?T~{i0sYCQ}uC#5BwN`skI7`|c%kqkyWIQ;!ysvA8H`b-t()n6>GJj6xlYDu~8qX{AFo$Cm3d|XFL=4uvc?Keb zzb0ZmMoXca6Mob>JqkNuoP>B2Z>D`Q(TvrG6m`j}-1rGP!g|qoL=$FVQYxJQjFn33lODt3Wb1j8VR zlR++vIT6^DtYxAv_hxupbLLN3e0%A%a+hWTKDV3!Fjr^cWJ{scsAdfhpI)`Bms^M6 zQG$waKgFr=c|p9Piug=fcJvZ1ThMnNhQvBAg-8~b1?6wL*WyqXhtj^g(Ke}mEfZVM zJuLNTUVh#WsE*a6uqiz`b#9ZYg3+2%=C(6AvZGc=u&<6??!slB1a9K)=VL zY9EL^mfyKnD zSJyYBc_>G;5RRnrNgzJz#Rkn3S1`mZgO`(r5;Hw6MveN(URf_XS-r58Cn80K)ArH4 z#Rrd~LG1W&@ttw85cjp8xV&>$b%nSXH_*W}7Ch2pg$$c0BdEo-HWRTZcxngIBJad> z;C>b{jIXjb_9Jis?NZJsdm^EG}e*pR&DAy0EaSGi3XWTa(>C%tz1n$u?5Fb z1qtl?;_yjYo)(gB^iQq?=jusF%kywm?CJP~zEHi0NbZ);$(H$w(Hy@{i>$wcVRD_X|w-~(0Z9BJyh zhNh;+eQ9BEIs;tPz%jSVnfCP!3L&9YtEP;svoj_bNzeGSQIAjd zBss@A;)R^WAu-37RQrM%{DfBNRx>v!G31Z}8-El9IOJlb_MSoMu2}GDYycNaf>uny z+8xykD-7ONCM!APry_Lw6-yT>5!tR}W;W`C)1>pxSs5o1z#j7%m=&=7O4hz+Lsqm` z*>{+xsabZPr&X=}G@obTb{nPTkccJX8w3CG7X+1+t{JcMabv~UNv+G?txRqXib~c^Mo}`q{$`;EBNJ;#F*{gvS12kV?AZ%O0SFB$^ zn+}!HbmEj}w{Vq(G)OGAzH}R~kS^;(-s&=ectz8vN!_)Yl$$U@HNTI-pV`LSj7Opu zTZ5zZ)-S_{GcEQPIQXLQ#oMS`HPu{`SQiAZ)m1at*Hy%3xma|>o`h%E%8BEbi9p0r zVjcsh<{NBKQ4eKlXU|}@XJ#@uQw*$4BxKn6#W~I4T<^f99~(=}a`&3(ur8R9t+|AQ zWkQx7l}wa48-jO@ft2h+7qn%SJtL%~890FG0s5g*kNbL3I&@brh&f6)TlM`K^(bhr zJWM6N6x3flOw$@|C@kPi7yP&SP?bzP-E|HSXQXG>7gk|R9BTj`e=4de9C6+H7H7n# z#GJeVs1mtHhLDmVO?LkYRQc`DVOJ_vdl8VUihO-j#t=0T3%Fc1f9F73ufJz*adn*p zc%&vi(4NqHu^R>sAT_0EDjVR8bc%wTz#$;%NU-kbDyL_dg0%TFafZwZ?5KZpcuaO54Z9hX zD$u>q!-9`U6-D`E#`W~fIfiIF5_m6{fvM)b1NG3xf4Auw;Go~Fu7cth#DlUn{@~yu z=B;RT*dp?bO}o%4x7k9v{r=Y@^YQ^UUm(Qmliw8brO^=NP+UOohLYiaEB3^DB56&V zK?4jV61B|1Uj_5fBKW;8LdwOFZKWp)g{B%7g1~DgO&N& z#lisxf?R~Z@?3E$Mms$$JK8oe@X`5m98V*aV6Ua}8Xs2#A!{x?IP|N(%nxsH?^c{& z@vY&R1QmQs83BW28qAmJfS7MYi=h(YK??@EhjL-t*5W!p z^gYX!Q6-vBqcv~ruw@oMaU&qp0Fb(dbVzm5xJN%0o_^@fWq$oa3X?9s%+b)x4w-q5Koe(@j6Ez7V@~NRFvd zfBH~)U5!ix3isg`6be__wBJp=1@yfsCMw1C@y+9WYD9_C%{Q~7^0AF2KFryfLlUP# zwrtJEcH)jm48!6tUcxiurAMaiD04C&tPe6DI0#aoqz#Bt0_7_*X*TsF7u*zv(iEfA z;$@?XVu~oX#1YXtceQL{dSneL&*nDug^OW$DSLF0M1Im|sSX8R26&)<0Fbh^*l6!5wfSu8MpMoh=2l z^^0Sr$UpZp*9oqa23fcCfm7`ya2<4wzJ`Axt7e4jJrRFVf?nY~2&tRL* zd;6_njcz01c>$IvN=?K}9ie%Z(BO@JG2J}fT#BJQ+f5LFSgup7i!xWRKw6)iITjZU z%l6hPZia>R!`aZjwCp}I zg)%20;}f+&@t;(%5;RHL>K_&7MH^S+7<|(SZH!u zznW|jz$uA`P9@ZWtJgv$EFp>)K&Gt+4C6#*khZQXS*S~6N%JDT$r`aJDs9|uXWdbg zBwho$phWx}x!qy8&}6y5Vr$G{yGSE*r$^r{}pw zVTZKvikRZ`J_IJrjc=X1uw?estdwm&bEahku&D04HD+0Bm~q#YGS6gp!KLf$A{%Qd z&&yX@Hp>~(wU{|(#U&Bf92+1i&Q*-S+=y=3pSZy$#8Uc$#7oiJUuO{cE6=tsPhwPe| zxQpK>`Dbka`V)$}e6_OXKLB%i76~4N*zA?X+PrhH<&)}prET;kel24kW%+9))G^JI zsq7L{P}^#QsZViX%KgxBvEugr>ZmFqe^oAg?{EI=&_O#e)F3V#rc z8$4}0Zr19qd3tE4#$3_f=Bbx9oV6VO!d3(R===i-7p=Vj`520w0D3W6lQfY48}!D* z&)lZMG;~er2qBoI2gsX+Ts-hnpS~NYRDtPd^FPzn!^&yxRy#CSz(b&E*tL|jIkq|l zf%>)7Dtu>jCf`-7R#*GhGn4FkYf;B$+9IxmqH|lf6$4irg{0ept__%)V*R_OK=T06 zyT_m-o@Kp6U{l5h>W1hGq*X#8*y@<;vsOFqEjTQXFEotR+{3}ODDnj;o0@!bB5x=N z394FojuGOtVKBlVRLtHp%EJv_G5q=AgF)SKyRN5=cGBjDWv4LDn$IL`*=~J7u&Dy5 zrMc83y+w^F&{?X(KOOAl-sWZDb{9X9#jrQtmrEXD?;h-}SYT7yM(X_6qksM=K_a;Z z3u0qT0TtaNvDER_8x*rxXw&C^|h{P1qxK|@pS7vdlZ#P z7PdB7MmC2}%sdzAxt>;WM1s0??`1983O4nFK|hVAbHcZ3x{PzytQLkCVk7hA!Lo` zEJH?4qw|}WH{dc4z%aB=0XqsFW?^p=X}4xnCJXK%c#ItOSjdSO`UXJyuc8bh^Cf}8 z@Ht|vXd^6{Fgai8*tmyRGmD_s_nv~r^Fy7j`Bu`6=G)5H$i7Q7lvQnmea&TGvJp9a|qOrUymZ$6G|Ly z#zOCg++$3iB$!6!>215A4!iryregKuUT344X)jQb3|9qY>c0LO{6Vby05n~VFzd?q zgGZv&FGlkiH*`fTurp>B8v&nSxNz)=5IF$=@rgND4d`!AaaX;_lK~)-U8la_Wa8i?NJC@BURO*sUW)E9oyv3RG^YGfN%BmxzjlT)bp*$<| zX3tt?EAy<&K+bhIuMs-g#=d1}N_?isY)6Ay$mDOKRh z4v1asEGWoAp=srraLW^h&_Uw|6O+r;wns=uwYm=JN4Q!quD8SQRSeEcGh|Eb5Jg8m zOT}u;N|x@aq)=&;wufCc^#)5U^VcZw;d_wwaoh9$p@Xrc{DD6GZUqZ ziC6OT^zSq@-lhbgR8B+e;7_Giv;DK5gn^$bs<6~SUadiosfewWDJu`XsBfOd1|p=q zE>m=zF}!lObA%ePey~gqU8S6h-^J2Y?>7)L2+%8kV}Gp=h`Xm_}rlm)SyUS=`=S7msKu zC|T!gPiI1rWGb1z$Md?0YJQ;%>uPLOXf1Z>N~`~JHJ!^@D5kSXQ4ugnFZ>^`zH8CAiZmp z6Ms|#2gcGsQ{{u7+Nb9sA?U>(0e$5V1|WVwY`Kn)rsnnZ4=1u=7u!4WexZD^IQ1Jk zfF#NLe>W$3m&C^ULjdw+5|)-BSHwpegdyt9NYC{3@QtMfd8GrIWDu`gd0nv-3LpGCh@wgBaG z176tikL!_NXM+Bv#7q^cyn9$XSeZR6#!B4JE@GVH zoobHZN_*RF#@_SVYKkQ_igme-Y5U}cV(hkR#k1c{bQNMji zU7aE`?dHyx=1`kOYZo_8U7?3-7vHOp`Qe%Z*i+FX!s?6huNp0iCEW-Z7E&jRWmUW_ z67j>)Ew!yq)hhG4o?^z}HWH-e=es#xJUhDRc4B51M4~E-l5VZ!&zQq`gWe`?}#b~7w1LH4Xa-UCT5LXkXQWheBa2YJYbyQ zl1pXR%b(KCXMO0OsXgl0P0Og<{(@&z1aokU-Pq`eQq*JYgt8xdFQ6S z6Z3IFSua8W&M#`~*L#r>Jfd6*BzJ?JFdBR#bDv$_0N!_5vnmo@!>vULcDm`MFU823 zpG9pqjqz^FE5zMDoGqhs5OMmC{Y3iVcl>F}5Rs24Y5B^mYQ;1T&ks@pIApHOdrzXF z-SdX}Hf{X;TaSxG_T$0~#RhqKISGKNK47}0*x&nRIPtmdwxc&QT3$8&!3fWu1eZ_P zJveQj^hJL#Sn!*4k`3}(d(aasl&7G0j0-*_2xtAnoX1@9+h zO#c>YQg60Z;o{Bi=3i7S`Ic+ZE>K{(u|#)9y}q*j8uKQ1^>+(BI}m%1v3$=4ojGBc zm+o1*!T&b}-lVvZqIUBc8V}QyFEgm#oyIuC{8WqUNV{Toz`oxhYpP!_p2oHHh5P@iB*NVo~2=GQm+8Yrkm2Xjc_VyHg1c0>+o~@>*Qzo zHVBJS>$$}$_4EniTI;b1WShX<5-p#TPB&!;lP!lBVBbLOOxh6FuYloD%m;n{r|;MU3!q4AVkua~fieeWu2 zQAQ$ue(IklX6+V;F1vCu-&V?I3d42FgWgsb_e^29ol}HYft?{SLf>DrmOp9o!t>I^ zY7fBCk+E8n_|apgM|-;^=#B?6RnFKlN`oR)`e$+;D=yO-(U^jV;rft^G_zl`n7qnM zL z*-Y4Phq+ZI1$j$F-f;`CD#|`-T~OM5Q>x}a>B~Gb3-+9i>Lfr|Ca6S^8g*{*?_5!x zH_N!SoRP=gX1?)q%>QTY!r77e2j9W(I!uAz{T`NdNmPBBUzi2{`XMB^zJGGwFWeA9 z{fk33#*9SO0)DjROug+(M)I-pKA!CX;IY(#gE!UxXVsa)X!UftIN98{pt#4MJHOhY zM$_l}-TJlxY?LS6Nuz1T<44m<4i^8k@D$zuCPrkmz@sdv+{ciyFJG2Zwy&%c7;atIeTdh!a(R^QXnu1Oq1b42*OQFWnyQ zWeQrdvP|w_idy53Wa<{QH^lFmEd+VlJkyiC>6B#s)F;w-{c;aKIm;Kp50HnA-o3lY z9B~F$gJ@yYE#g#X&3ADx&tO+P_@mnQTz9gv30_sTsaGXkfNYXY{$(>*PEN3QL>I!k zp)KibPhrfX3%Z$H6SY`rXGYS~143wZrG2;=FLj50+VM6soI~up_>fU(2Wl@{BRsMi zO%sL3x?2l1cXTF)k&moNsHfQrQ+wu(gBt{sk#CU=UhrvJIncy@tJX5klLjgMn>~h= zg|FR&;@eh|C7`>s_9c~0-{IAPV){l|Ts`i=)AW;d9&KPc3fMeoTS%8@V~D8*h;&(^>yjT84MM}=%#LS7shLAuuj(0VAYoozhWjq z4LEr?wUe2^WGwdTIgWBkDUJa>YP@5d9^Rs$kCXmMRxuF*YMVrn?0NFyPl}>`&dqZb z<5eqR=ZG3>n2{6v6BvJ`YBZeeTtB88TAY(x0a58EWyuf>+^|x8Qa6wA|1Nb_p|nA zWWa}|z8a)--Wj`LqyFk_a3gN2>5{Rl_wbW?#by7&i*^hRknK%jwIH6=dQ8*-_{*x0j^DUfMX0`|K@6C<|1cgZ~D(e5vBFFm;HTZF(!vT8=T$K+|F)x3kqzBV4-=p1V(lzi(s7jdu0>LD#N=$Lk#3HkG!a zIF<7>%B7sRNzJ66KrFV76J<2bdYhxll0y2^_rdG=I%AgW4~)1Nvz=$1UkE^J%BxLo z+lUci`UcU062os*=`-j4IfSQA{w@y|3}Vk?i;&SSdh8n+$iHA#%ERL{;EpXl6u&8@ zzg}?hkEOUOJt?ZL=pWZFJ19mI1@P=$U5*Im1e_8Z${JsM>Ov?nh8Z zP5QvI!{Jy@&BP48%P2{Jr_VgzW;P@7)M9n|lDT|Ep#}7C$&ud&6>C^5ZiwKIg2McPU(4jhM!BD@@L(Gd*Nu$ji(ljZ<{FIeW_1Mmf;76{LU z-ywN~=uNN)Xi6$<12A9y)K%X|(W0p|&>>4OXB?IiYr||WKDOJPxiSe01NSV-h24^L z_>m$;|C+q!Mj**-qQ$L-*++en(g|hw;M!^%_h-iDjFHLo-n3JpB;p?+o2;`*jpvJU zLY^lt)Un4joij^^)O(CKs@7E%*!w>!HA4Q?0}oBJ7Nr8NQ7QmY^4~jvf0-`%waOLn zdNjAPaC0_7c|RVhw)+71NWjRi!y>C+Bl;Z`NiL^zn2*0kmj5gyhCLCxts*cWCdRI| zjsd=sT5BVJc^$GxP~YF$-U{-?kW6r@^vHXB%{CqYzU@1>dzf#3SYedJG-Rm6^RB7s zGM5PR(yKPKR)>?~vpUIeTP7A1sc8-knnJk*9)3t^e%izbdm>Y=W{$wm(cy1RB-19i za#828DMBY+ps#7Y8^6t)=Ea@%Nkt)O6JCx|ybC;Ap}Z@Zw~*}3P>MZLPb4Enxz9Wf zssobT^(R@KuShj8>@!1M7tm|2%-pYYDxz-5`rCbaTCG5{;Uxm z*g=+H1X8{NUvFGzz~wXa%Eo};I;~`37*WrRU&K0dPSB$yk(Z*@K&+mFal^?c zurbqB-+|Kb5|sznT;?Pj!+kgFY1#Dr;_%A(GIQC{3ct|{*Bji%FNa6c-thbpBkA;U zURV!Dr&X{0J}iht#-Qp2=xzuh(fM>zRoiGrYl5ttw2#r34gC41CCOC31m~^UPTK@s z6;A@)7O7_%C)>bnAXerYuAHdE93>j2N}H${zEc6&SbZ|-fiG*-qtGuy-qDelH(|u$ zorf8_T6Zqe#Ub!+e3oSyrskt_HyW_^5lrWt#30l)tHk|j$@YyEkXUOV;6B51L;M@=NIWZXU;GrAa(LGxO%|im%7F<-6N;en0Cr zLH>l*y?pMwt`1*cH~LdBPFY_l;~`N!Clyfr;7w<^X;&(ZiVdF1S5e(+Q%60zgh)s4 zn2yj$+mE=miVERP(g8}G4<85^-5f@qxh2ec?n+$A_`?qN=iyT1?U@t?V6DM~BIlBB z>u~eXm-aE>R0sQy!-I4xtCNi!!qh?R1!kKf6BoH2GG{L4%PAz0{Sh6xpuyI%*~u)s z%rLuFl)uQUCBQAtMyN;%)zFMx4loh7uTfKeB2Xif`lN?2gq6NhWhfz0u5WP9J>=V2 zo{mLtSy&BA!mSzs&CrKWq^y40JF5a&GSXIi2= z{EYb59J4}VwikL4P=>+mc6{($FNE@e=VUwG+KV21;<@lrN`mnz5jYGASyvz7BOG_6(p^eTxD-4O#lROgon;R35=|nj#eHIfJBYPWG>H>`dHKCDZ3`R{-?HO0mE~(5_WYcFmp8sU?wr*UkAQiNDGc6T zA%}GOLXlOWqL?WwfHO8MB#8M8*~Y*gz;1rWWoVSXP&IbKxbQ8+s%4Jnt?kDsq7btI zCDr0PZ)b;B%!lu&CT#RJzm{l{2fq|BcY85`w~3LSK<><@(2EdzFLt9Y_`;WXL6x`0 zDoQ?=?I@Hbr;*VVll1Gmd8*%tiXggMK81a+T(5Gx6;eNb8=uYn z5BG-0g>pP21NPn>$ntBh>`*})Fl|38oC^9Qz>~MAazH%3Q~Qb!ALMf$srexgPZ2@&c~+hxRi1;}+)-06)!#Mq<6GhP z-Q?qmgo${aFBApb5p}$1OJKTClfi8%PpnczyVKkoHw7Ml9e7ikrF0d~UB}i3vizos zXW4DN$SiEV9{faLt5bHy2a>33K%7Td-n5C*N;f&ZqAg#2hIqEb(y<&f4u5BWJ>2^4 z414GosL=Aom#m&=x_v<0-fp1r%oVJ{T-(xnomNJ(Dryv zh?vj+%=II_nV+@NR+(!fZZVM&(W6{6%9cm+o+Z6}KqzLw{(>E86uA1`_K$HqINlb1 zKelh3-jr2I9V?ych`{hta9wQ2c9=MM`2cC{m6^MhlL2{DLv7C^j z$xXBCnDl_;l|bPGMX@*tV)B!c|4oZyftUlP*?$YU9C_eAsuVHJ58?)zpbr30P*C`T z7y#ao`uE-SOG(Pi+`$=e^mle~)pRrdwL5)N;o{gpW21of(QE#U6w%*C~`v-z0QqBML!!5EeYA5IQB0 z^l01c;L6E(iytN!LhL}wfwP7W9PNAkb+)Cst?qg#$n;z41O4&v+8-zPs+XNb-q zIeeBCh#ivnFLUCwfS;p{LC0O7tm+Sf9Jn)~b%uwP{%69;QC)Ok0t%*a5M+=;y8j=v z#!*pp$9@!x;UMIs4~hP#pnfVc!%-D<+wsG@R2+J&%73lK|2G!EQC)O05TCV=&3g)C!lT=czLpZ@Sa%TYuoE?v8T8`V;e$#Zf2_Nj6nvBgh1)2 GZ~q4|mN%#X literal 0 HcmV?d00001 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..cea7a79 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100755 index 0000000..f3b75f3 --- /dev/null +++ b/gradlew @@ -0,0 +1,251 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..9d21a21 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,94 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/scripts/build b/scripts/build new file mode 100755 index 0000000..f406348 --- /dev/null +++ b/scripts/build @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +set -e + +cd "$(dirname "$0")/.." + +echo "==> Building classes" +./gradlew build testClasses -x test diff --git a/scripts/format b/scripts/format new file mode 100755 index 0000000..7c0be4d --- /dev/null +++ b/scripts/format @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +set -e + +cd "$(dirname "$0")/.." + +echo "==> Running formatters" +./gradlew format diff --git a/scripts/lint b/scripts/lint new file mode 100755 index 0000000..aea8af7 --- /dev/null +++ b/scripts/lint @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +set -e + +cd "$(dirname "$0")/.." + +echo "==> Running lints" +./gradlew lint diff --git a/scripts/mock b/scripts/mock new file mode 100755 index 0000000..0b28f6e --- /dev/null +++ b/scripts/mock @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +set -e + +cd "$(dirname "$0")/.." + +if [[ -n "$1" && "$1" != '--'* ]]; then + URL="$1" + shift +else + URL="$(grep 'openapi_spec_url' .stats.yml | cut -d' ' -f2)" +fi + +# Check if the URL is empty +if [ -z "$URL" ]; then + echo "Error: No OpenAPI spec path/url provided or found in .stats.yml" + exit 1 +fi + +echo "==> Starting mock server with URL ${URL}" + +# Run prism mock on the given spec +if [ "$1" == "--daemon" ]; then + npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock "$URL" &> .prism.log & + + # Wait for server to come online + echo -n "Waiting for server" + while ! grep -q "✖ fatal\|Prism is listening" ".prism.log" ; do + 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" +fi diff --git a/scripts/test b/scripts/test new file mode 100755 index 0000000..047bc1d --- /dev/null +++ b/scripts/test @@ -0,0 +1,56 @@ +#!/usr/bin/env bash + +set -e + +cd "$(dirname "$0")/.." + +RED='\033[0;31m' +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 +} + +kill_server_on_port() { + pids=$(lsof -t -i tcp:"$1" || echo "") + if [ "$pids" != "" ]; then + kill "$pids" + echo "Stopped $pids." + fi +} + +function is_overriding_api_base_url() { + [ -n "$TEST_API_BASE_URL" ] +} + +if ! is_overriding_api_base_url && ! prism_is_running ; then + # When we exit this script, make sure to kill the background mock server process + trap 'kill_server_on_port 4010' EXIT + + # Start the dev server + ./scripts/mock --daemon +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" + 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 + echo -e " \$ ${YELLOW}npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock path/to/your.openapi.yml${NC}" + echo + + exit 1 +else + echo -e "${GREEN}✔ Mock prism server is running with your OpenAPI spec${NC}" + echo +fi + +echo "==> Running tests" +./gradlew test "$@" diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 0000000..03a6894 --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1,14 @@ +rootProject.name = "cas-parser-java-root" + +val projectNames = rootDir.listFiles() + ?.asSequence() + .orEmpty() + .filter { file -> + file.isDirectory && + file.name.startsWith("cas-parser-java") && + file.listFiles()?.asSequence().orEmpty().any { it.name == "build.gradle.kts" } + } + .map { it.name } + .toList() +println("projects: $projectNames") +projectNames.forEach { include(it) } From 201702c69619d095fa9cf2061258da78f16bf248 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 18 Aug 2025 08:10:57 +0000 Subject: [PATCH 02/99] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index aa8116c..af747c5 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 5 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-b7fdba3d3f97c7debc22c7ca30b828bce81bcd64648df8c94029b27a3321ebb9.yml openapi_spec_hash: 03f1315f1d32ada42445ca920f047dff -config_hash: 05034d55bf9f8573b1160f7825bcd9b9 +config_hash: d34508a94d94e1155705c01231bd6f17 From 9ea394cc67d0f1762f51454615f7bbfdedaafbe9 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 18 Aug 2025 08:13:08 +0000 Subject: [PATCH 03/99] chore: update SDK settings --- .github/workflows/publish-sonatype.yml | 41 ++++++++++++ .github/workflows/release-doctor.yml | 24 +++++++ .release-please-manifest.json | 3 + .stats.yml | 2 +- README.md | 14 +++- bin/check-release-environment | 33 +++++++++ build.gradle.kts | 2 +- .../main/kotlin/cas-parser.publish.gradle.kts | 6 +- .../kotlin/com/cas_parser/api/core/Check.kt | 2 +- release-please-config.json | 67 +++++++++++++++++++ 10 files changed, 187 insertions(+), 7 deletions(-) create mode 100644 .github/workflows/publish-sonatype.yml create mode 100644 .github/workflows/release-doctor.yml create mode 100644 .release-please-manifest.json create mode 100644 bin/check-release-environment create mode 100644 release-please-config.json diff --git a/.github/workflows/publish-sonatype.yml b/.github/workflows/publish-sonatype.yml new file mode 100644 index 0000000..54ab6a1 --- /dev/null +++ b/.github/workflows/publish-sonatype.yml @@ -0,0 +1,41 @@ +# This workflow is triggered when a GitHub release is created. +# It can also be run manually to re-publish to Sonatype in case it failed for some reason. +# You can run this workflow by navigating to https://www.github.com/CASParser/cas-parser-java/actions/workflows/publish-sonatype.yml +name: Publish Sonatype +on: + workflow_dispatch: + + release: + types: [published] + +jobs: + publish: + name: publish + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Set up Java + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: | + 8 + 17 + cache: gradle + + - name: Set up Gradle + uses: gradle/gradle-build-action@v2 + + - name: Publish to Sonatype + run: |- + export -- GPG_SIGNING_KEY_ID + printenv -- GPG_SIGNING_KEY | gpg --batch --passphrase-fd 3 --import 3<<< "$GPG_SIGNING_PASSWORD" + GPG_SIGNING_KEY_ID="$(gpg --with-colons --list-keys | awk -F : -- '/^pub:/ { getline; print "0x" substr($10, length($10) - 7) }')" + ./gradlew publish --no-configuration-cache + env: + SONATYPE_USERNAME: ${{ secrets.CAS_PARSER_SONATYPE_USERNAME || secrets.SONATYPE_USERNAME }} + SONATYPE_PASSWORD: ${{ secrets.CAS_PARSER_SONATYPE_PASSWORD || secrets.SONATYPE_PASSWORD }} + GPG_SIGNING_KEY: ${{ secrets.CAS_PARSER_SONATYPE_GPG_SIGNING_KEY || secrets.GPG_SIGNING_KEY }} + GPG_SIGNING_PASSWORD: ${{ secrets.CAS_PARSER_SONATYPE_GPG_SIGNING_PASSWORD || secrets.GPG_SIGNING_PASSWORD }} \ No newline at end of file diff --git a/.github/workflows/release-doctor.yml b/.github/workflows/release-doctor.yml new file mode 100644 index 0000000..87d49ed --- /dev/null +++ b/.github/workflows/release-doctor.yml @@ -0,0 +1,24 @@ +name: Release Doctor +on: + pull_request: + branches: + - main + workflow_dispatch: + +jobs: + release_doctor: + name: release doctor + runs-on: ubuntu-latest + if: github.repository == 'CASParser/cas-parser-java' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || startsWith(github.head_ref, 'release-please') || github.head_ref == 'next') + + steps: + - uses: actions/checkout@v4 + + - name: Check release environment + run: | + bash ./bin/check-release-environment + env: + SONATYPE_USERNAME: ${{ secrets.CAS_PARSER_SONATYPE_USERNAME || secrets.SONATYPE_USERNAME }} + SONATYPE_PASSWORD: ${{ secrets.CAS_PARSER_SONATYPE_PASSWORD || secrets.SONATYPE_PASSWORD }} + GPG_SIGNING_KEY: ${{ secrets.CAS_PARSER_SONATYPE_GPG_SIGNING_KEY || secrets.GPG_SIGNING_KEY }} + GPG_SIGNING_PASSWORD: ${{ secrets.CAS_PARSER_SONATYPE_GPG_SIGNING_PASSWORD || secrets.GPG_SIGNING_PASSWORD }} diff --git a/.release-please-manifest.json b/.release-please-manifest.json new file mode 100644 index 0000000..1332969 --- /dev/null +++ b/.release-please-manifest.json @@ -0,0 +1,3 @@ +{ + ".": "0.0.1" +} \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index af747c5..0caf7fc 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 5 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-b7fdba3d3f97c7debc22c7ca30b828bce81bcd64648df8c94029b27a3321ebb9.yml openapi_spec_hash: 03f1315f1d32ada42445ca920f047dff -config_hash: d34508a94d94e1155705c01231bd6f17 +config_hash: 0e1291f316b20497ad29b59a231a8680 diff --git a/README.md b/README.md index 2709980..0fe11bd 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,26 @@ # Cas Parser Java API Library + + [![Maven Central](https://img.shields.io/maven-central/v/com.cas_parser.api/cas-parser-java)](https://central.sonatype.com/artifact/com.cas_parser.api/cas-parser-java/0.0.1) [![javadoc](https://javadoc.io/badge2/com.cas_parser.api/cas-parser-java/0.0.1/javadoc.svg)](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.0.1) + + The Cas Parser Java SDK provides convenient access to the [Cas Parser REST API](https://docs.casparser.in/reference) from applications written in Java. It is generated with [Stainless](https://www.stainless.com/). + + The REST API documentation can be found on [docs.casparser.in](https://docs.casparser.in/reference). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.0.1). + + ## Installation + + ### Gradle ```kotlin @@ -27,6 +37,8 @@ implementation("com.cas_parser.api:cas-parser-java:0.0.1") ``` + + ## Requirements This library requires Java 8 or later. @@ -607,4 +619,4 @@ This package generally follows [SemVer](https://semver.org/spec/v2.0.0.html) con We take backwards-compatibility seriously and work hard to ensure you can rely on a smooth upgrade experience. -We are keen for your feedback; please open an [issue](https://www.github.com/stainless-sdks/cas-parser-java/issues) with questions, bugs, or suggestions. +We are keen for your feedback; please open an [issue](https://www.github.com/CASParser/cas-parser-java/issues) with questions, bugs, or suggestions. diff --git a/bin/check-release-environment b/bin/check-release-environment new file mode 100644 index 0000000..3a6a7b4 --- /dev/null +++ b/bin/check-release-environment @@ -0,0 +1,33 @@ +#!/usr/bin/env bash + +errors=() + +if [ -z "${SONATYPE_USERNAME}" ]; then + errors+=("The SONATYPE_USERNAME secret has not been set. Please set it in either this repository's secrets or your organization secrets") +fi + +if [ -z "${SONATYPE_PASSWORD}" ]; then + errors+=("The SONATYPE_PASSWORD secret has not been set. Please set it in either this repository's secrets or your organization secrets") +fi + +if [ -z "${GPG_SIGNING_KEY}" ]; then + errors+=("The GPG_SIGNING_KEY secret has not been set. Please set it in either this repository's secrets or your organization secrets") +fi + +if [ -z "${GPG_SIGNING_PASSWORD}" ]; then + errors+=("The GPG_SIGNING_PASSWORD secret has not been set. Please set it in either this repository's secrets or your organization secrets") +fi + +lenErrors=${#errors[@]} + +if [[ lenErrors -gt 0 ]]; then + echo -e "Found the following errors in the release environment:\n" + + for error in "${errors[@]}"; do + echo -e "- $error\n" + done + + exit 1 +fi + +echo "The environment is ready to push releases!" diff --git a/build.gradle.kts b/build.gradle.kts index 734b874..ef43958 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -9,7 +9,7 @@ repositories { allprojects { group = "com.cas_parser.api" - version = "0.0.1" + version = "0.0.1" // x-release-please-version } subprojects { diff --git a/buildSrc/src/main/kotlin/cas-parser.publish.gradle.kts b/buildSrc/src/main/kotlin/cas-parser.publish.gradle.kts index 12e6487..ef287d8 100644 --- a/buildSrc/src/main/kotlin/cas-parser.publish.gradle.kts +++ b/buildSrc/src/main/kotlin/cas-parser.publish.gradle.kts @@ -27,9 +27,9 @@ configure { } scm { - connection.set("scm:git:git://github.com/stainless-sdks/cas-parser-java.git") - developerConnection.set("scm:git:git://github.com/stainless-sdks/cas-parser-java.git") - url.set("https://github.com/stainless-sdks/cas-parser-java") + connection.set("scm:git:git://github.com/CASParser/cas-parser-java.git") + developerConnection.set("scm:git:git://github.com/CASParser/cas-parser-java.git") + url.set("https://github.com/CASParser/cas-parser-java") } versionMapping { diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Check.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Check.kt index 2e4c6e8..c0b5e80 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Check.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Check.kt @@ -77,7 +77,7 @@ This can happen if you are either: Double-check that you are depending on compatible Jackson versions. -See https://www.github.com/stainless-sdks/cas-parser-java#jackson for more information. +See https://www.github.com/CASParser/cas-parser-java#jackson for more information. """ .trimIndent() } diff --git a/release-please-config.json b/release-please-config.json new file mode 100644 index 0000000..8f98719 --- /dev/null +++ b/release-please-config.json @@ -0,0 +1,67 @@ +{ + "packages": { + ".": {} + }, + "$schema": "https://raw.githubusercontent.com/stainless-api/release-please/main/schemas/config.json", + "include-v-in-tag": true, + "include-component-in-tag": false, + "versioning": "prerelease", + "prerelease": true, + "bump-minor-pre-major": true, + "bump-patch-for-minor-pre-major": false, + "pull-request-header": "Automated Release PR", + "pull-request-title-pattern": "release: ${version}", + "changelog-sections": [ + { + "type": "feat", + "section": "Features" + }, + { + "type": "fix", + "section": "Bug Fixes" + }, + { + "type": "perf", + "section": "Performance Improvements" + }, + { + "type": "revert", + "section": "Reverts" + }, + { + "type": "chore", + "section": "Chores" + }, + { + "type": "docs", + "section": "Documentation" + }, + { + "type": "style", + "section": "Styles" + }, + { + "type": "refactor", + "section": "Refactors" + }, + { + "type": "test", + "section": "Tests", + "hidden": true + }, + { + "type": "build", + "section": "Build System" + }, + { + "type": "ci", + "section": "Continuous Integration", + "hidden": true + } + ], + "release-type": "simple", + "extra-files": [ + "README.md", + "build.gradle.kts" + ] +} \ No newline at end of file From 95a8882a71b9654708d83ca9c640409f9e545582 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 18 Aug 2025 08:15:30 +0000 Subject: [PATCH 04/99] chore(internal): version bump --- .release-please-manifest.json | 2 +- README.md | 10 +++++----- build.gradle.kts | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 1332969..c7159c1 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.0.1" + ".": "0.0.2" } \ No newline at end of file diff --git a/README.md b/README.md index 0fe11bd..7646bdb 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ -[![Maven Central](https://img.shields.io/maven-central/v/com.cas_parser.api/cas-parser-java)](https://central.sonatype.com/artifact/com.cas_parser.api/cas-parser-java/0.0.1) -[![javadoc](https://javadoc.io/badge2/com.cas_parser.api/cas-parser-java/0.0.1/javadoc.svg)](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.0.1) +[![Maven Central](https://img.shields.io/maven-central/v/com.cas_parser.api/cas-parser-java)](https://central.sonatype.com/artifact/com.cas_parser.api/cas-parser-java/0.0.2) +[![javadoc](https://javadoc.io/badge2/com.cas_parser.api/cas-parser-java/0.0.2/javadoc.svg)](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.0.2) @@ -13,7 +13,7 @@ It is generated with [Stainless](https://www.stainless.com/). -The REST API documentation can be found on [docs.casparser.in](https://docs.casparser.in/reference). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.0.1). +The REST API documentation can be found on [docs.casparser.in](https://docs.casparser.in/reference). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.0.2). @@ -24,7 +24,7 @@ The REST API documentation can be found on [docs.casparser.in](https://docs.casp ### Gradle ```kotlin -implementation("com.cas_parser.api:cas-parser-java:0.0.1") +implementation("com.cas_parser.api:cas-parser-java:0.0.2") ``` ### Maven @@ -33,7 +33,7 @@ implementation("com.cas_parser.api:cas-parser-java:0.0.1") com.cas_parser.api cas-parser-java - 0.0.1 + 0.0.2 ``` diff --git a/build.gradle.kts b/build.gradle.kts index ef43958..48085d5 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -9,7 +9,7 @@ repositories { allprojects { group = "com.cas_parser.api" - version = "0.0.1" // x-release-please-version + version = "0.0.2" // x-release-please-version } subprojects { From 32ebde3a13c2f6949aea9d2266bb5800190563fc Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 18 Aug 2025 10:03:02 +0000 Subject: [PATCH 05/99] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index 0caf7fc..6566ecd 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 5 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-b7fdba3d3f97c7debc22c7ca30b828bce81bcd64648df8c94029b27a3321ebb9.yml openapi_spec_hash: 03f1315f1d32ada42445ca920f047dff -config_hash: 0e1291f316b20497ad29b59a231a8680 +config_hash: 7e37f38c64335d64bc0f2bdd0a655a97 From 691a5e12cd878017b8bd2fb40b8d784e652d1f8e Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 18 Aug 2025 10:04:54 +0000 Subject: [PATCH 06/99] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index 6566ecd..92721c7 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 5 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-b7fdba3d3f97c7debc22c7ca30b828bce81bcd64648df8c94029b27a3321ebb9.yml openapi_spec_hash: 03f1315f1d32ada42445ca920f047dff -config_hash: 7e37f38c64335d64bc0f2bdd0a655a97 +config_hash: cb5d75abef6264b5d86448caf7295afa From b3441c9111fd9e638fc29c0c9a3f5c42716ae0ba Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 21 Aug 2025 04:21:59 +0000 Subject: [PATCH 07/99] chore(internal): fix multipart tests --- .../casparser/CasParserCamsKfintechParamsTest.kt | 14 +------------- .../models/casparser/CasParserCdslParamsTest.kt | 14 +------------- .../models/casparser/CasParserNsdlParamsTest.kt | 14 +------------- .../casparser/CasParserSmartParseParamsTest.kt | 14 +------------- 4 files changed, 4 insertions(+), 52 deletions(-) diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserCamsKfintechParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserCamsKfintechParamsTest.kt index e85c9de..7fd81ef 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserCamsKfintechParamsTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserCamsKfintechParamsTest.kt @@ -55,18 +55,6 @@ internal class CasParserCamsKfintechParamsTest { val body = params._body() - assertThat(body.filterValues { !it.value.isNull() }) - .usingRecursiveComparison() - // TODO(AssertJ): Replace this and the `mapValues` below with: - // https://github.com/assertj/assertj/issues/3165 - .withEqualsForType( - { a, b -> a.readBytes() contentEquals b.readBytes() }, - InputStream::class.java, - ) - .isEqualTo( - mapOf().mapValues { (_, field) -> - field.map { (it as? ByteArray)?.inputStream() ?: it } - } - ) + assertThat(body.filterValues { !it.value.isNull() }).isEmpty() } } diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserCdslParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserCdslParamsTest.kt index 778a492..6293280 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserCdslParamsTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserCdslParamsTest.kt @@ -55,18 +55,6 @@ internal class CasParserCdslParamsTest { val body = params._body() - assertThat(body.filterValues { !it.value.isNull() }) - .usingRecursiveComparison() - // TODO(AssertJ): Replace this and the `mapValues` below with: - // https://github.com/assertj/assertj/issues/3165 - .withEqualsForType( - { a, b -> a.readBytes() contentEquals b.readBytes() }, - InputStream::class.java, - ) - .isEqualTo( - mapOf().mapValues { (_, field) -> - field.map { (it as? ByteArray)?.inputStream() ?: it } - } - ) + assertThat(body.filterValues { !it.value.isNull() }).isEmpty() } } diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserNsdlParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserNsdlParamsTest.kt index c593b64..fba23f6 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserNsdlParamsTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserNsdlParamsTest.kt @@ -55,18 +55,6 @@ internal class CasParserNsdlParamsTest { val body = params._body() - assertThat(body.filterValues { !it.value.isNull() }) - .usingRecursiveComparison() - // TODO(AssertJ): Replace this and the `mapValues` below with: - // https://github.com/assertj/assertj/issues/3165 - .withEqualsForType( - { a, b -> a.readBytes() contentEquals b.readBytes() }, - InputStream::class.java, - ) - .isEqualTo( - mapOf().mapValues { (_, field) -> - field.map { (it as? ByteArray)?.inputStream() ?: it } - } - ) + assertThat(body.filterValues { !it.value.isNull() }).isEmpty() } } diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserSmartParseParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserSmartParseParamsTest.kt index f3795e8..795fbfd 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserSmartParseParamsTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserSmartParseParamsTest.kt @@ -55,18 +55,6 @@ internal class CasParserSmartParseParamsTest { val body = params._body() - assertThat(body.filterValues { !it.value.isNull() }) - .usingRecursiveComparison() - // TODO(AssertJ): Replace this and the `mapValues` below with: - // https://github.com/assertj/assertj/issues/3165 - .withEqualsForType( - { a, b -> a.readBytes() contentEquals b.readBytes() }, - InputStream::class.java, - ) - .isEqualTo( - mapOf().mapValues { (_, field) -> - field.map { (it as? ByteArray)?.inputStream() ?: it } - } - ) + assertThat(body.filterValues { !it.value.isNull() }).isEmpty() } } From 98dd2184220f7280a031c42ba5ec01162588f1f1 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 21 Aug 2025 04:23:45 +0000 Subject: [PATCH 08/99] chore(client): refactor closing / shutdown --- .../api/client/CasParserClientAsyncImpl.kt | 2 +- .../api/client/CasParserClientImpl.kt | 2 +- .../com/cas_parser/api/core/ClientOptions.kt | 18 ++++++ .../core/PhantomReachableExecutorService.kt | 58 +++++++++++++++++++ 4 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/PhantomReachableExecutorService.kt diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientAsyncImpl.kt index 2301ccd..d8b0b67 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientAsyncImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientAsyncImpl.kt @@ -46,7 +46,7 @@ class CasParserClientAsyncImpl(private val clientOptions: ClientOptions) : CasPa override fun casGenerator(): CasGeneratorServiceAsync = casGenerator - override fun close() = clientOptions.httpClient.close() + override fun close() = clientOptions.close() class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : CasParserClientAsync.WithRawResponse { diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientImpl.kt index 0104e8f..fe0f962 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientImpl.kt @@ -46,7 +46,7 @@ class CasParserClientImpl(private val clientOptions: ClientOptions) : CasParserC override fun casGenerator(): CasGeneratorService = casGenerator - override fun close() = clientOptions.httpClient.close() + override fun close() = clientOptions.close() class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : CasParserClient.WithRawResponse { diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ClientOptions.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ClientOptions.kt index 516a36d..d330bc7 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ClientOptions.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ClientOptions.kt @@ -21,6 +21,8 @@ private constructor( * The HTTP client to use in the SDK. * * Use the one published in `cas-parser-java-client-okhttp` or implement your own. + * + * This class takes ownership of the client and closes it when closed. */ @get:JvmName("httpClient") val httpClient: HttpClient, /** @@ -157,6 +159,8 @@ private constructor( * The HTTP client to use in the SDK. * * Use the one published in `cas-parser-java-client-okhttp` or implement your own. + * + * This class takes ownership of the client and closes it when closed. */ fun httpClient(httpClient: HttpClient) = apply { this.httpClient = PhantomReachableClosingHttpClient(httpClient) @@ -404,4 +408,18 @@ private constructor( ) } } + + /** + * Closes these client options, relinquishing any underlying resources. + * + * This is purposefully not inherited from [AutoCloseable] because the client options are + * long-lived and usually should not be synchronously closed via try-with-resources. + * + * It's also usually not necessary to call this method at all. the default client automatically + * releases threads and connections if they remain idle, but if you are writing an application + * that needs to aggressively release unused resources, then you may call this method. + */ + fun close() { + httpClient.close() + } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/PhantomReachableExecutorService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/PhantomReachableExecutorService.kt new file mode 100644 index 0000000..d26c7ba --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/PhantomReachableExecutorService.kt @@ -0,0 +1,58 @@ +package com.cas_parser.api.core + +import java.util.concurrent.Callable +import java.util.concurrent.ExecutorService +import java.util.concurrent.Future +import java.util.concurrent.TimeUnit + +/** + * A delegating wrapper around an [ExecutorService] that shuts it down once it's only phantom + * reachable. + * + * This class ensures the [ExecutorService] is shut down even if the user forgets to do it. + */ +internal class PhantomReachableExecutorService(private val executorService: ExecutorService) : + ExecutorService { + init { + closeWhenPhantomReachable(this) { executorService.shutdown() } + } + + override fun execute(command: Runnable) = executorService.execute(command) + + override fun shutdown() = executorService.shutdown() + + override fun shutdownNow(): MutableList = executorService.shutdownNow() + + override fun isShutdown(): Boolean = executorService.isShutdown + + override fun isTerminated(): Boolean = executorService.isTerminated + + override fun awaitTermination(timeout: Long, unit: TimeUnit): Boolean = + executorService.awaitTermination(timeout, unit) + + override fun submit(task: Callable): Future = executorService.submit(task) + + override fun submit(task: Runnable, result: T): Future = + executorService.submit(task, result) + + override fun submit(task: Runnable): Future<*> = executorService.submit(task) + + override fun invokeAll( + tasks: MutableCollection> + ): MutableList> = executorService.invokeAll(tasks) + + override fun invokeAll( + tasks: MutableCollection>, + timeout: Long, + unit: TimeUnit, + ): MutableList> = executorService.invokeAll(tasks, timeout, unit) + + override fun invokeAny(tasks: MutableCollection>): T = + executorService.invokeAny(tasks) + + override fun invokeAny( + tasks: MutableCollection>, + timeout: Long, + unit: TimeUnit, + ): T = executorService.invokeAny(tasks, timeout, unit) +} From e10a1c69bb637c3ba45ecf311fd17d5c12f6caa4 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 21 Aug 2025 04:30:12 +0000 Subject: [PATCH 09/99] chore(internal): support running formatters directly --- scripts/format | 17 +++++++++++++++-- scripts/java-format | 7 +++++++ scripts/kotlin-format | 7 +++++++ scripts/lint | 17 ++++++++++++++++- 4 files changed, 45 insertions(+), 3 deletions(-) create mode 100755 scripts/java-format create mode 100755 scripts/kotlin-format diff --git a/scripts/format b/scripts/format index 7c0be4d..65db176 100755 --- a/scripts/format +++ b/scripts/format @@ -4,5 +4,18 @@ set -e cd "$(dirname "$0")/.." -echo "==> Running formatters" -./gradlew format +if command -v ktfmt &> /dev/null; then + echo "==> Running ktfmt" + ./scripts/kotlin-format +else + echo "==> Running gradlew formatKotlin" + ./gradlew formatKotlin +fi + +if command -v palantir-java-format &> /dev/null; then + echo "==> Running palantir-java-format" + ./scripts/java-format +else + echo "==> Running gradlew formatJava" + ./gradlew formatJava +fi diff --git a/scripts/java-format b/scripts/java-format new file mode 100755 index 0000000..ad5febc --- /dev/null +++ b/scripts/java-format @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +set -e + +cd "$(dirname "$0")/.." + +find . -name "*.java" -not -path "./buildSrc/build/*" -print0 | xargs -0 -r palantir-java-format --palantir --replace "$@" diff --git a/scripts/kotlin-format b/scripts/kotlin-format new file mode 100755 index 0000000..3b8be9e --- /dev/null +++ b/scripts/kotlin-format @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +set -e + +cd "$(dirname "$0")/.." + +find . -name "*.kt" -not -path "./buildSrc/build/*" -print0 | xargs -0 -r ktfmt --kotlinlang-style "$@" diff --git a/scripts/lint b/scripts/lint index aea8af7..dbc8f77 100755 --- a/scripts/lint +++ b/scripts/lint @@ -5,4 +5,19 @@ set -e cd "$(dirname "$0")/.." echo "==> Running lints" -./gradlew lint + +if command -v ktfmt &> /dev/null; then + echo "==> Checking ktfmt" + ./scripts/kotlin-format --dry-run --set-exit-if-changed +else + echo "==> Running gradlew lintKotlin" + ./gradlew lintKotlin +fi + +if command -v palantir-java-format &> /dev/null; then + echo "==> Checking palantir-java-format" + ./scripts/java-format --dry-run --set-exit-if-changed +else + echo "==> Running gradlew lintJava" + ./gradlew lintJava +fi From d5a3746e8fe80f6fb01dc8600c949a99b9d64c0b Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 22 Aug 2025 05:56:35 +0000 Subject: [PATCH 10/99] chore(ci): reduce log noise --- cas-parser-java-proguard-test/build.gradle.kts | 2 -- cas-parser-java-proguard-test/test.pro | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/cas-parser-java-proguard-test/build.gradle.kts b/cas-parser-java-proguard-test/build.gradle.kts index dc5f093..de62f9c 100644 --- a/cas-parser-java-proguard-test/build.gradle.kts +++ b/cas-parser-java-proguard-test/build.gradle.kts @@ -37,8 +37,6 @@ val proguardJar by tasks.registering(proguard.gradle.ProGuardTask::class) { outjars(proguardJarPath) printmapping("${layout.buildDirectory.get()}/proguard-mapping.txt") - dontwarn() - val javaHome = System.getProperty("java.home") if (System.getProperty("java.version").startsWith("1.")) { // Before Java 9, the runtime classes were packaged in a single jar file. diff --git a/cas-parser-java-proguard-test/test.pro b/cas-parser-java-proguard-test/test.pro index 7cc2e8a..fcbe936 100644 --- a/cas-parser-java-proguard-test/test.pro +++ b/cas-parser-java-proguard-test/test.pro @@ -5,4 +5,5 @@ -keep class org.junit.** { *; } # Many warnings don't apply for our testing purposes. +-dontnote -dontwarn \ No newline at end of file From 16e9691a5fd08bd54c480cdd821b8ea220e19df7 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 3 Sep 2025 21:22:51 +0000 Subject: [PATCH 11/99] chore(internal): version bump --- .release-please-manifest.json | 2 +- README.md | 10 +++++----- build.gradle.kts | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index c7159c1..28e831b 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.0.2" + ".": "0.0.3" } \ No newline at end of file diff --git a/README.md b/README.md index 7646bdb..0a2616d 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ -[![Maven Central](https://img.shields.io/maven-central/v/com.cas_parser.api/cas-parser-java)](https://central.sonatype.com/artifact/com.cas_parser.api/cas-parser-java/0.0.2) -[![javadoc](https://javadoc.io/badge2/com.cas_parser.api/cas-parser-java/0.0.2/javadoc.svg)](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.0.2) +[![Maven Central](https://img.shields.io/maven-central/v/com.cas_parser.api/cas-parser-java)](https://central.sonatype.com/artifact/com.cas_parser.api/cas-parser-java/0.0.3) +[![javadoc](https://javadoc.io/badge2/com.cas_parser.api/cas-parser-java/0.0.3/javadoc.svg)](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.0.3) @@ -13,7 +13,7 @@ It is generated with [Stainless](https://www.stainless.com/). -The REST API documentation can be found on [docs.casparser.in](https://docs.casparser.in/reference). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.0.2). +The REST API documentation can be found on [docs.casparser.in](https://docs.casparser.in/reference). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.0.3). @@ -24,7 +24,7 @@ The REST API documentation can be found on [docs.casparser.in](https://docs.casp ### Gradle ```kotlin -implementation("com.cas_parser.api:cas-parser-java:0.0.2") +implementation("com.cas_parser.api:cas-parser-java:0.0.3") ``` ### Maven @@ -33,7 +33,7 @@ implementation("com.cas_parser.api:cas-parser-java:0.0.2") com.cas_parser.api cas-parser-java - 0.0.2 + 0.0.3 ``` diff --git a/build.gradle.kts b/build.gradle.kts index 48085d5..45a77c9 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -9,7 +9,7 @@ repositories { allprojects { group = "com.cas_parser.api" - version = "0.0.2" // x-release-please-version + version = "0.0.3" // x-release-please-version } subprojects { From 5b0fbb723ca0b53ff6d8668ad421c96b1e0cd996 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 4 Sep 2025 02:47:12 +0000 Subject: [PATCH 12/99] fix(ci): use java-version 21 for publish step --- .github/workflows/publish-sonatype.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-sonatype.yml b/.github/workflows/publish-sonatype.yml index 54ab6a1..1b11f45 100644 --- a/.github/workflows/publish-sonatype.yml +++ b/.github/workflows/publish-sonatype.yml @@ -22,7 +22,7 @@ jobs: distribution: temurin java-version: | 8 - 17 + 21 cache: gradle - name: Set up Gradle From 1a07ada9bd0372983517c5a6a4f2904cf40e3e98 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 12 Sep 2025 02:21:20 +0000 Subject: [PATCH 13/99] chore: improve formatter performance --- scripts/fast-format | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100755 scripts/fast-format diff --git a/scripts/fast-format b/scripts/fast-format new file mode 100755 index 0000000..2aa524f --- /dev/null +++ b/scripts/fast-format @@ -0,0 +1,39 @@ +#!/usr/bin/env bash + +set -euo pipefail + +cd "$(dirname "$0")/.." + +if [ $# -eq 0 ]; then + echo "Usage: $0 [additional-formatter-args...]" + echo "The file should contain one file path per line" + exit 1 +fi + +FILE_LIST="$1" + +if [ ! -f "$FILE_LIST" ]; then + echo "Error: File '$FILE_LIST' not found" + exit 1 +fi + +if command -v ktfmt-fast-format &> /dev/null; then + echo "Error: ktfmt-fast-format not found" + exit 1 +fi + +# Process Kotlin files +kt_files=$(grep -E '\.kt$' "$FILE_LIST" | grep -v './buildSrc/build/') +kt_files=$(grep -E '\.kt$' "$FILE_LIST" | grep -v './buildSrc/build/') +echo "==> Found $(echo "$kt_files" | wc -l) Kotlin files:" + +if [[ -n "$kt_files" ]]; then + echo "==> will format Kotlin files" + echo "$kt_files" | tr '\n' '\0' | xargs -0 ktfmt --kotlinlang-style "$@" +else + echo "No Kotlin files to format -- expected outcome during incremental formatting" +fi + +# TODO(mbudayr): support palantir-java-format +# Process Java files +# grep -E '\.java$' "$FILE_LIST" | grep -v './buildSrc/build/' | tr '\n' '\0' | xargs -0 -r palantir-java-format --palantir --replace "$@" From 3a4c34e4235306ce6a651a34d59f53092c4344b5 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 13 Sep 2025 02:58:13 +0000 Subject: [PATCH 14/99] chore(internal): codegen related update --- scripts/fast-format | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/fast-format b/scripts/fast-format index 2aa524f..c8b60da 100755 --- a/scripts/fast-format +++ b/scripts/fast-format @@ -17,7 +17,7 @@ if [ ! -f "$FILE_LIST" ]; then exit 1 fi -if command -v ktfmt-fast-format &> /dev/null; then +if ! command -v ktfmt-fast-format &> /dev/null; then echo "Error: ktfmt-fast-format not found" exit 1 fi From ced04effdc1a1d0928a379aa95696606de70c21c Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 13 Sep 2025 03:01:04 +0000 Subject: [PATCH 15/99] chore(internal): codegen related update --- scripts/fast-format | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/fast-format b/scripts/fast-format index c8b60da..e16bfc5 100755 --- a/scripts/fast-format +++ b/scripts/fast-format @@ -29,7 +29,7 @@ echo "==> Found $(echo "$kt_files" | wc -l) Kotlin files:" if [[ -n "$kt_files" ]]; then echo "==> will format Kotlin files" - echo "$kt_files" | tr '\n' '\0' | xargs -0 ktfmt --kotlinlang-style "$@" + echo "$kt_files" | tr '\n' '\0' | xargs -0 ktfmt-fast-format --kotlinlang-style "$@" else echo "No Kotlin files to format -- expected outcome during incremental formatting" fi From adb55778e2f259a43993b112ee127c6e8c531cdf Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 13 Sep 2025 19:13:40 +0000 Subject: [PATCH 16/99] chore(internal): version bump --- .release-please-manifest.json | 2 +- README.md | 10 +++++----- build.gradle.kts | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 28e831b..2ed3b71 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.0.3" + ".": "0.0.4" } \ No newline at end of file diff --git a/README.md b/README.md index 0a2616d..eb1c0bb 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ -[![Maven Central](https://img.shields.io/maven-central/v/com.cas_parser.api/cas-parser-java)](https://central.sonatype.com/artifact/com.cas_parser.api/cas-parser-java/0.0.3) -[![javadoc](https://javadoc.io/badge2/com.cas_parser.api/cas-parser-java/0.0.3/javadoc.svg)](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.0.3) +[![Maven Central](https://img.shields.io/maven-central/v/com.cas_parser.api/cas-parser-java)](https://central.sonatype.com/artifact/com.cas_parser.api/cas-parser-java/0.0.4) +[![javadoc](https://javadoc.io/badge2/com.cas_parser.api/cas-parser-java/0.0.4/javadoc.svg)](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.0.4) @@ -13,7 +13,7 @@ It is generated with [Stainless](https://www.stainless.com/). -The REST API documentation can be found on [docs.casparser.in](https://docs.casparser.in/reference). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.0.3). +The REST API documentation can be found on [docs.casparser.in](https://docs.casparser.in/reference). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.0.4). @@ -24,7 +24,7 @@ The REST API documentation can be found on [docs.casparser.in](https://docs.casp ### Gradle ```kotlin -implementation("com.cas_parser.api:cas-parser-java:0.0.3") +implementation("com.cas_parser.api:cas-parser-java:0.0.4") ``` ### Maven @@ -33,7 +33,7 @@ implementation("com.cas_parser.api:cas-parser-java:0.0.3") com.cas_parser.api cas-parser-java - 0.0.3 + 0.0.4 ``` diff --git a/build.gradle.kts b/build.gradle.kts index 45a77c9..d58d78e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -9,7 +9,7 @@ repositories { allprojects { group = "com.cas_parser.api" - version = "0.0.3" // x-release-please-version + version = "0.0.4" // x-release-please-version } subprojects { From 2c6b553dfa5fbb4f66eca1da981ea438e29bd1b7 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 16 Sep 2025 02:37:42 +0000 Subject: [PATCH 17/99] fix(client): incorrect `getPackageVersion` impl --- .../src/main/kotlin/com/cas_parser/api/core/Properties.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Properties.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Properties.kt index c715f1a..dc9a375 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Properties.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Properties.kt @@ -2,7 +2,7 @@ package com.cas_parser.api.core -import java.util.Properties +import com.cas_parser.api.client.CasParserClient fun getOsArch(): String { val osArch = System.getProperty("os.arch") @@ -16,7 +16,7 @@ fun getOsArch(): String { "x86_64" -> "x64" "arm" -> "arm" "aarch64" -> "arm64" - else -> "other:${osArch}" + else -> "other:$osArch" } } @@ -30,13 +30,13 @@ fun getOsName(): String { osName.startsWith("Linux") -> "Linux" osName.startsWith("Mac OS") -> "MacOS" osName.startsWith("Windows") -> "Windows" - else -> "Other:${osName}" + else -> "Other:$osName" } } fun getOsVersion(): String = System.getProperty("os.version", "unknown") fun getPackageVersion(): String = - Properties::class.java.`package`.implementationVersion ?: "unknown" + CasParserClient::class.java.`package`.implementationVersion ?: "unknown" fun getJavaVersion(): String = System.getProperty("java.version", "unknown") From fd3d0b3f869f30abf01bd5c12386a7a371cb5488 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 20 Sep 2025 02:32:51 +0000 Subject: [PATCH 18/99] feat(client): expose sleeper option fix(client): ensure single timer is created per client --- .../client/okhttp/CasParserOkHttpClient.kt | 12 ++++++ .../okhttp/CasParserOkHttpClientAsync.kt | 12 ++++++ .../com/cas_parser/api/core/ClientOptions.kt | 27 ++++++++++++ .../com/cas_parser/api/core/DefaultSleeper.kt | 28 +++++++++++++ .../api/core/PhantomReachableSleeper.kt | 23 +++++++++++ .../kotlin/com/cas_parser/api/core/Sleeper.kt | 21 ++++++++++ .../api/core/http/RetryingHttpClient.kt | 41 ++++--------------- .../api/core/http/RetryingHttpClientTest.kt | 9 +++- 8 files changed, 139 insertions(+), 34 deletions(-) create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/DefaultSleeper.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/PhantomReachableSleeper.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Sleeper.kt diff --git a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClient.kt b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClient.kt index 687527a..f75536a 100644 --- a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClient.kt +++ b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClient.kt @@ -5,6 +5,7 @@ package com.cas_parser.api.client.okhttp import com.cas_parser.api.client.CasParserClient import com.cas_parser.api.client.CasParserClientImpl import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.Sleeper import com.cas_parser.api.core.Timeout import com.cas_parser.api.core.http.Headers import com.cas_parser.api.core.http.HttpClient @@ -120,6 +121,17 @@ class CasParserOkHttpClient private constructor() { */ fun jsonMapper(jsonMapper: JsonMapper) = apply { clientOptions.jsonMapper(jsonMapper) } + /** + * The interface to use for delaying execution, like during retries. + * + * This is primarily useful for using fake delays in tests. + * + * Defaults to real execution delays. + * + * This class takes ownership of the sleeper and closes it when closed. + */ + fun sleeper(sleeper: Sleeper) = apply { clientOptions.sleeper(sleeper) } + /** * The clock to use for operations that require timing, like retries. * diff --git a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClientAsync.kt b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClientAsync.kt index 186bbe4..4142acc 100644 --- a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClientAsync.kt +++ b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClientAsync.kt @@ -5,6 +5,7 @@ package com.cas_parser.api.client.okhttp import com.cas_parser.api.client.CasParserClientAsync import com.cas_parser.api.client.CasParserClientAsyncImpl import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.Sleeper import com.cas_parser.api.core.Timeout import com.cas_parser.api.core.http.Headers import com.cas_parser.api.core.http.HttpClient @@ -120,6 +121,17 @@ class CasParserOkHttpClientAsync private constructor() { */ fun jsonMapper(jsonMapper: JsonMapper) = apply { clientOptions.jsonMapper(jsonMapper) } + /** + * The interface to use for delaying execution, like during retries. + * + * This is primarily useful for using fake delays in tests. + * + * Defaults to real execution delays. + * + * This class takes ownership of the sleeper and closes it when closed. + */ + fun sleeper(sleeper: Sleeper) = apply { clientOptions.sleeper(sleeper) } + /** * The clock to use for operations that require timing, like retries. * diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ClientOptions.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ClientOptions.kt index d330bc7..f5195cd 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ClientOptions.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ClientOptions.kt @@ -40,6 +40,16 @@ private constructor( * rarely needs to be overridden. */ @get:JvmName("jsonMapper") val jsonMapper: JsonMapper, + /** + * The interface to use for delaying execution, like during retries. + * + * This is primarily useful for using fake delays in tests. + * + * Defaults to real execution delays. + * + * This class takes ownership of the sleeper and closes it when closed. + */ + @get:JvmName("sleeper") val sleeper: Sleeper, /** * The clock to use for operations that require timing, like retries. * @@ -131,6 +141,7 @@ private constructor( private var httpClient: HttpClient? = null private var checkJacksonVersionCompatibility: Boolean = true private var jsonMapper: JsonMapper = jsonMapper() + private var sleeper: Sleeper? = null private var clock: Clock = Clock.systemUTC() private var baseUrl: String? = null private var headers: Headers.Builder = Headers.builder() @@ -145,6 +156,7 @@ private constructor( httpClient = clientOptions.originalHttpClient checkJacksonVersionCompatibility = clientOptions.checkJacksonVersionCompatibility jsonMapper = clientOptions.jsonMapper + sleeper = clientOptions.sleeper clock = clientOptions.clock baseUrl = clientOptions.baseUrl headers = clientOptions.headers.toBuilder() @@ -185,6 +197,17 @@ private constructor( */ fun jsonMapper(jsonMapper: JsonMapper) = apply { this.jsonMapper = jsonMapper } + /** + * The interface to use for delaying execution, like during retries. + * + * This is primarily useful for using fake delays in tests. + * + * Defaults to real execution delays. + * + * This class takes ownership of the sleeper and closes it when closed. + */ + fun sleeper(sleeper: Sleeper) = apply { this.sleeper = PhantomReachableSleeper(sleeper) } + /** * The clock to use for operations that require timing, like retries. * @@ -369,6 +392,7 @@ private constructor( */ fun build(): ClientOptions { val httpClient = checkRequired("httpClient", httpClient) + val sleeper = sleeper ?: PhantomReachableSleeper(DefaultSleeper()) val apiKey = checkRequired("apiKey", apiKey) val headers = Headers.builder() @@ -392,11 +416,13 @@ private constructor( httpClient, RetryingHttpClient.builder() .httpClient(httpClient) + .sleeper(sleeper) .clock(clock) .maxRetries(maxRetries) .build(), checkJacksonVersionCompatibility, jsonMapper, + sleeper, clock, baseUrl, headers.build(), @@ -421,5 +447,6 @@ private constructor( */ fun close() { httpClient.close() + sleeper.close() } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/DefaultSleeper.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/DefaultSleeper.kt new file mode 100644 index 0000000..5e092e2 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/DefaultSleeper.kt @@ -0,0 +1,28 @@ +package com.cas_parser.api.core + +import java.time.Duration +import java.util.Timer +import java.util.TimerTask +import java.util.concurrent.CompletableFuture + +class DefaultSleeper : Sleeper { + + private val timer = Timer("DefaultSleeper", true) + + override fun sleep(duration: Duration) = Thread.sleep(duration.toMillis()) + + override fun sleepAsync(duration: Duration): CompletableFuture { + val future = CompletableFuture() + timer.schedule( + object : TimerTask() { + override fun run() { + future.complete(null) + } + }, + duration.toMillis(), + ) + return future + } + + override fun close() = timer.cancel() +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/PhantomReachableSleeper.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/PhantomReachableSleeper.kt new file mode 100644 index 0000000..2b3afd5 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/PhantomReachableSleeper.kt @@ -0,0 +1,23 @@ +package com.cas_parser.api.core + +import java.time.Duration +import java.util.concurrent.CompletableFuture + +/** + * A delegating wrapper around a [Sleeper] that closes it once it's only phantom reachable. + * + * This class ensures the [Sleeper] is closed even if the user forgets to do it. + */ +internal class PhantomReachableSleeper(private val sleeper: Sleeper) : Sleeper { + + init { + closeWhenPhantomReachable(this, sleeper) + } + + override fun sleep(duration: Duration) = sleeper.sleep(duration) + + override fun sleepAsync(duration: Duration): CompletableFuture = + sleeper.sleepAsync(duration) + + override fun close() = sleeper.close() +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Sleeper.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Sleeper.kt new file mode 100644 index 0000000..5a93d9a --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Sleeper.kt @@ -0,0 +1,21 @@ +package com.cas_parser.api.core + +import java.time.Duration +import java.util.concurrent.CompletableFuture + +/** + * An interface for delaying execution for a specified amount of time. + * + * Useful for testing and cleaning up resources. + */ +interface Sleeper : AutoCloseable { + + /** Synchronously pauses execution for the given [duration]. */ + fun sleep(duration: Duration) + + /** Asynchronously pauses execution for the given [duration]. */ + fun sleepAsync(duration: Duration): CompletableFuture + + /** Overridden from [AutoCloseable] to not have a checked exception in its signature. */ + override fun close() +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/RetryingHttpClient.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/RetryingHttpClient.kt index 569b1aa..2bf9815 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/RetryingHttpClient.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/RetryingHttpClient.kt @@ -1,6 +1,8 @@ package com.cas_parser.api.core.http +import com.cas_parser.api.core.DefaultSleeper import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.Sleeper import com.cas_parser.api.core.checkRequired import com.cas_parser.api.errors.CasParserIoException import com.cas_parser.api.errors.CasParserRetryableException @@ -11,8 +13,6 @@ import java.time.OffsetDateTime import java.time.format.DateTimeFormatter import java.time.format.DateTimeParseException import java.time.temporal.ChronoUnit -import java.util.Timer -import java.util.TimerTask import java.util.UUID import java.util.concurrent.CompletableFuture import java.util.concurrent.ThreadLocalRandom @@ -130,7 +130,10 @@ private constructor( return executeWithRetries(modifiedRequest, requestOptions) } - override fun close() = httpClient.close() + override fun close() { + httpClient.close() + sleeper.close() + } private fun isRetryable(request: HttpRequest): Boolean = // Some requests, such as when a request body is being streamed, cannot be retried because @@ -235,33 +238,14 @@ private constructor( class Builder internal constructor() { private var httpClient: HttpClient? = null - private var sleeper: Sleeper = - object : Sleeper { - - private val timer = Timer("RetryingHttpClient", true) - - override fun sleep(duration: Duration) = Thread.sleep(duration.toMillis()) - - override fun sleepAsync(duration: Duration): CompletableFuture { - val future = CompletableFuture() - timer.schedule( - object : TimerTask() { - override fun run() { - future.complete(null) - } - }, - duration.toMillis(), - ) - return future - } - } + private var sleeper: Sleeper? = null private var clock: Clock = Clock.systemUTC() private var maxRetries: Int = 2 private var idempotencyHeader: String? = null fun httpClient(httpClient: HttpClient) = apply { this.httpClient = httpClient } - @JvmSynthetic internal fun sleeper(sleeper: Sleeper) = apply { this.sleeper = sleeper } + fun sleeper(sleeper: Sleeper) = apply { this.sleeper = sleeper } fun clock(clock: Clock) = apply { this.clock = clock } @@ -272,17 +256,10 @@ private constructor( fun build(): HttpClient = RetryingHttpClient( checkRequired("httpClient", httpClient), - sleeper, + sleeper ?: DefaultSleeper(), clock, maxRetries, idempotencyHeader, ) } - - internal interface Sleeper { - - fun sleep(duration: Duration) - - fun sleepAsync(duration: Duration): CompletableFuture - } } diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/RetryingHttpClientTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/RetryingHttpClientTest.kt index d740df3..90db8ea 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/RetryingHttpClientTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/RetryingHttpClientTest.kt @@ -2,6 +2,7 @@ package com.cas_parser.api.core.http import com.cas_parser.api.client.okhttp.OkHttpClient import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.Sleeper import com.cas_parser.api.errors.CasParserRetryableException import com.github.tomakehurst.wiremock.client.WireMock.* import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo @@ -294,12 +295,14 @@ internal class RetryingHttpClientTest { .httpClient(failingHttpClient) .maxRetries(2) .sleeper( - object : RetryingHttpClient.Sleeper { + object : Sleeper { override fun sleep(duration: Duration) {} override fun sleepAsync(duration: Duration): CompletableFuture = CompletableFuture.completedFuture(null) + + override fun close() {} } ) .build() @@ -333,12 +336,14 @@ internal class RetryingHttpClientTest { .httpClient(httpClient) // Use a no-op `Sleeper` to make the test fast. .sleeper( - object : RetryingHttpClient.Sleeper { + object : Sleeper { override fun sleep(duration: Duration) {} override fun sleepAsync(duration: Duration): CompletableFuture = CompletableFuture.completedFuture(null) + + override fun close() {} } ) From 7f8a7fa4c76145a5823d8c2d6a82f6190a297139 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 20 Sep 2025 03:22:45 +0000 Subject: [PATCH 19/99] chore: improve formatter performance --- scripts/fast-format | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/scripts/fast-format b/scripts/fast-format index e16bfc5..1b3bc47 100755 --- a/scripts/fast-format +++ b/scripts/fast-format @@ -2,7 +2,12 @@ set -euo pipefail +echo "Script started with $# arguments" +echo "Arguments: $*" +echo "Script location: $(dirname "$0")" + cd "$(dirname "$0")/.." +echo "Changed to directory: $(pwd)" if [ $# -eq 0 ]; then echo "Usage: $0 [additional-formatter-args...]" @@ -12,6 +17,8 @@ fi FILE_LIST="$1" +echo "Looking for file: $FILE_LIST" + if [ ! -f "$FILE_LIST" ]; then echo "Error: File '$FILE_LIST' not found" exit 1 @@ -23,9 +30,9 @@ if ! command -v ktfmt-fast-format &> /dev/null; then fi # Process Kotlin files -kt_files=$(grep -E '\.kt$' "$FILE_LIST" | grep -v './buildSrc/build/') -kt_files=$(grep -E '\.kt$' "$FILE_LIST" | grep -v './buildSrc/build/') -echo "==> Found $(echo "$kt_files" | wc -l) Kotlin files:" +echo "==> Looking for Kotlin files" +kt_files=$(grep -E '\.kt$' "$FILE_LIST" | grep -v './buildSrc/build/' || true) +echo "==> Done looking for Kotlin files" if [[ -n "$kt_files" ]]; then echo "==> will format Kotlin files" From 91b870b0422a094c5cd1b29edbfeb6ad9910a99b Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 22 Sep 2025 00:19:42 +0000 Subject: [PATCH 20/99] feat(api): api update --- .stats.yml | 4 +- .../api/models/casparser/UnifiedResponse.kt | 2058 ++++++++++++++++- .../models/casparser/UnifiedResponseTest.kt | 139 ++ .../api/proguard/ProGuardCompatibilityTest.kt | 47 + 4 files changed, 2185 insertions(+), 63 deletions(-) diff --git a/.stats.yml b/.stats.yml index 92721c7..06e7614 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 5 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-b7fdba3d3f97c7debc22c7ca30b828bce81bcd64648df8c94029b27a3321ebb9.yml -openapi_spec_hash: 03f1315f1d32ada42445ca920f047dff +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-9eaed98ce5934f11e901cef376a28257d2c196bd3dba7c690babc6741a730ded.yml +openapi_spec_hash: b76e4e830c4d03ba4cf9429bb9fb9c8a config_hash: cb5d75abef6264b5d86448caf7295afa diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/UnifiedResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/UnifiedResponse.kt index 2c18576..67cc09d 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/UnifiedResponse.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/UnifiedResponse.kt @@ -28,6 +28,7 @@ private constructor( private val investor: JsonField, private val meta: JsonField, private val mutualFunds: JsonField>, + private val nps: JsonField>, private val summary: JsonField, private val additionalProperties: MutableMap, ) { @@ -45,8 +46,9 @@ private constructor( @JsonProperty("mutual_funds") @ExcludeMissing mutualFunds: JsonField> = JsonMissing.of(), + @JsonProperty("nps") @ExcludeMissing nps: JsonField> = JsonMissing.of(), @JsonProperty("summary") @ExcludeMissing summary: JsonField = JsonMissing.of(), - ) : this(dematAccounts, insurance, investor, meta, mutualFunds, summary, mutableMapOf()) + ) : this(dematAccounts, insurance, investor, meta, mutualFunds, nps, summary, mutableMapOf()) /** * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the @@ -78,6 +80,14 @@ private constructor( */ fun mutualFunds(): Optional> = mutualFunds.getOptional("mutual_funds") + /** + * List of NPS accounts + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun nps(): Optional> = nps.getOptional("nps") + /** * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -123,6 +133,13 @@ private constructor( @ExcludeMissing fun _mutualFunds(): JsonField> = mutualFunds + /** + * Returns the raw JSON value of [nps]. + * + * Unlike [nps], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("nps") @ExcludeMissing fun _nps(): JsonField> = nps + /** * Returns the raw JSON value of [summary]. * @@ -156,6 +173,7 @@ private constructor( private var investor: JsonField = JsonMissing.of() private var meta: JsonField = JsonMissing.of() private var mutualFunds: JsonField>? = null + private var nps: JsonField>? = null private var summary: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @@ -166,6 +184,7 @@ private constructor( investor = unifiedResponse.investor meta = unifiedResponse.meta mutualFunds = unifiedResponse.mutualFunds.map { it.toMutableList() } + nps = unifiedResponse.nps.map { it.toMutableList() } summary = unifiedResponse.summary additionalProperties = unifiedResponse.additionalProperties.toMutableMap() } @@ -253,6 +272,26 @@ private constructor( } } + /** List of NPS accounts */ + fun nps(nps: List) = nps(JsonField.of(nps)) + + /** + * Sets [Builder.nps] to an arbitrary JSON value. + * + * You should usually call [Builder.nps] with a well-typed `List` value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun nps(nps: JsonField>) = apply { this.nps = nps.map { it.toMutableList() } } + + /** + * Adds a single [Np] to [nps]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addNp(np: Np) = apply { + nps = (nps ?: JsonField.of(mutableListOf())).also { checkKnown("nps", it).add(np) } + } + fun summary(summary: Summary) = summary(JsonField.of(summary)) /** @@ -294,6 +333,7 @@ private constructor( investor, meta, (mutualFunds ?: JsonMissing.of()).map { it.toImmutable() }, + (nps ?: JsonMissing.of()).map { it.toImmutable() }, summary, additionalProperties.toMutableMap(), ) @@ -311,6 +351,7 @@ private constructor( investor().ifPresent { it.validate() } meta().ifPresent { it.validate() } mutualFunds().ifPresent { it.forEach { it.validate() } } + nps().ifPresent { it.forEach { it.validate() } } summary().ifPresent { it.validate() } validated = true } @@ -335,6 +376,7 @@ private constructor( (investor.asKnown().getOrNull()?.validity() ?: 0) + (meta.asKnown().getOrNull()?.validity() ?: 0) + (mutualFunds.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (nps.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + (summary.asKnown().getOrNull()?.validity() ?: 0) class DematAccount @@ -346,6 +388,7 @@ private constructor( private val dpId: JsonField, private val dpName: JsonField, private val holdings: JsonField, + private val linkedHolders: JsonField>, private val value: JsonField, private val additionalProperties: MutableMap, ) { @@ -367,6 +410,9 @@ private constructor( @JsonProperty("holdings") @ExcludeMissing holdings: JsonField = JsonMissing.of(), + @JsonProperty("linked_holders") + @ExcludeMissing + linkedHolders: JsonField> = JsonMissing.of(), @JsonProperty("value") @ExcludeMissing value: JsonField = JsonMissing.of(), ) : this( additionalInfo, @@ -376,6 +422,7 @@ private constructor( dpId, dpName, holdings, + linkedHolders, value, mutableMapOf(), ) @@ -435,6 +482,15 @@ private constructor( */ fun holdings(): Optional = holdings.getOptional("holdings") + /** + * List of account holders linked to this demat account + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun linkedHolders(): Optional> = + linkedHolders.getOptional("linked_holders") + /** * Total value of the demat account * @@ -497,6 +553,16 @@ private constructor( */ @JsonProperty("holdings") @ExcludeMissing fun _holdings(): JsonField = holdings + /** + * Returns the raw JSON value of [linkedHolders]. + * + * Unlike [linkedHolders], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("linked_holders") + @ExcludeMissing + fun _linkedHolders(): JsonField> = linkedHolders + /** * Returns the raw JSON value of [value]. * @@ -532,6 +598,7 @@ private constructor( private var dpId: JsonField = JsonMissing.of() private var dpName: JsonField = JsonMissing.of() private var holdings: JsonField = JsonMissing.of() + private var linkedHolders: JsonField>? = null private var value: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @@ -544,6 +611,7 @@ private constructor( dpId = dematAccount.dpId dpName = dematAccount.dpName holdings = dematAccount.holdings + linkedHolders = dematAccount.linkedHolders.map { it.toMutableList() } value = dematAccount.value additionalProperties = dematAccount.additionalProperties.toMutableMap() } @@ -634,6 +702,33 @@ private constructor( */ fun holdings(holdings: JsonField) = apply { this.holdings = holdings } + /** List of account holders linked to this demat account */ + fun linkedHolders(linkedHolders: List) = + linkedHolders(JsonField.of(linkedHolders)) + + /** + * Sets [Builder.linkedHolders] to an arbitrary JSON value. + * + * You should usually call [Builder.linkedHolders] with a well-typed + * `List` value instead. This method is primarily for setting the field to + * an undocumented or not yet supported value. + */ + fun linkedHolders(linkedHolders: JsonField>) = apply { + this.linkedHolders = linkedHolders.map { it.toMutableList() } + } + + /** + * Adds a single [LinkedHolder] to [linkedHolders]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addLinkedHolder(linkedHolder: LinkedHolder) = apply { + linkedHolders = + (linkedHolders ?: JsonField.of(mutableListOf())).also { + checkKnown("linkedHolders", it).add(linkedHolder) + } + } + /** Total value of the demat account */ fun value(value: Float) = value(JsonField.of(value)) @@ -679,6 +774,7 @@ private constructor( dpId, dpName, holdings, + (linkedHolders ?: JsonMissing.of()).map { it.toImmutable() }, value, additionalProperties.toMutableMap(), ) @@ -698,6 +794,7 @@ private constructor( dpId() dpName() holdings().ifPresent { it.validate() } + linkedHolders().ifPresent { it.forEach { it.validate() } } value() validated = true } @@ -725,6 +822,7 @@ private constructor( (if (dpId.asKnown().isPresent) 1 else 0) + (if (dpName.asKnown().isPresent) 1 else 0) + (holdings.asKnown().getOrNull()?.validity() ?: 0) + + (linkedHolders.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + (if (value.asKnown().isPresent) 1 else 0) /** Additional information specific to the demat account type */ @@ -3136,6 +3234,185 @@ private constructor( "Holdings{aifs=$aifs, corporateBonds=$corporateBonds, dematMutualFunds=$dematMutualFunds, equities=$equities, governmentSecurities=$governmentSecurities, additionalProperties=$additionalProperties}" } + class LinkedHolder + private constructor( + private val name: JsonField, + private val pan: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("pan") @ExcludeMissing pan: JsonField = JsonMissing.of(), + ) : this(name, pan, mutableMapOf()) + + /** + * Name of the account holder + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun name(): Optional = name.getOptional("name") + + /** + * PAN of the account holder + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun pan(): Optional = pan.getOptional("pan") + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + + /** + * Returns the raw JSON value of [pan]. + * + * Unlike [pan], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("pan") @ExcludeMissing fun _pan(): JsonField = pan + + @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 [LinkedHolder]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [LinkedHolder]. */ + class Builder internal constructor() { + + private var name: JsonField = JsonMissing.of() + private var pan: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(linkedHolder: LinkedHolder) = apply { + name = linkedHolder.name + pan = linkedHolder.pan + additionalProperties = linkedHolder.additionalProperties.toMutableMap() + } + + /** Name of the account holder */ + fun name(name: String) = name(JsonField.of(name)) + + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun name(name: JsonField) = apply { this.name = name } + + /** PAN of the account holder */ + fun pan(pan: String) = pan(JsonField.of(pan)) + + /** + * Sets [Builder.pan] to an arbitrary JSON value. + * + * You should usually call [Builder.pan] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun pan(pan: JsonField) = apply { this.pan = pan } + + 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 [LinkedHolder]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): LinkedHolder = + LinkedHolder(name, pan, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): LinkedHolder = apply { + if (validated) { + return@apply + } + + name() + pan() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (name.asKnown().isPresent) 1 else 0) + (if (pan.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is LinkedHolder && + name == other.name && + pan == other.pan && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(name, pan, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "LinkedHolder{name=$name, pan=$pan, additionalProperties=$additionalProperties}" + } + override fun equals(other: Any?): Boolean { if (this === other) { return true @@ -3149,6 +3426,7 @@ private constructor( dpId == other.dpId && dpName == other.dpName && holdings == other.holdings && + linkedHolders == other.linkedHolders && value == other.value && additionalProperties == other.additionalProperties } @@ -3162,6 +3440,7 @@ private constructor( dpId, dpName, holdings, + linkedHolders, value, additionalProperties, ) @@ -3170,7 +3449,7 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "DematAccount{additionalInfo=$additionalInfo, boId=$boId, clientId=$clientId, dematType=$dematType, dpId=$dpId, dpName=$dpName, holdings=$holdings, value=$value, additionalProperties=$additionalProperties}" + "DematAccount{additionalInfo=$additionalInfo, boId=$boId, clientId=$clientId, dematType=$dematType, dpId=$dpId, dpName=$dpName, holdings=$holdings, linkedHolders=$linkedHolders, value=$value, additionalProperties=$additionalProperties}" } class Insurance @@ -4733,6 +5012,7 @@ private constructor( private val additionalInfo: JsonField, private val amc: JsonField, private val folioNumber: JsonField, + private val linkedHolders: JsonField>, private val registrar: JsonField, private val schemes: JsonField>, private val value: JsonField, @@ -4748,6 +5028,9 @@ private constructor( @JsonProperty("folio_number") @ExcludeMissing folioNumber: JsonField = JsonMissing.of(), + @JsonProperty("linked_holders") + @ExcludeMissing + linkedHolders: JsonField> = JsonMissing.of(), @JsonProperty("registrar") @ExcludeMissing registrar: JsonField = JsonMissing.of(), @@ -4755,7 +5038,16 @@ private constructor( @ExcludeMissing schemes: JsonField> = JsonMissing.of(), @JsonProperty("value") @ExcludeMissing value: JsonField = JsonMissing.of(), - ) : this(additionalInfo, amc, folioNumber, registrar, schemes, value, mutableMapOf()) + ) : this( + additionalInfo, + amc, + folioNumber, + linkedHolders, + registrar, + schemes, + value, + mutableMapOf(), + ) /** * Additional folio information @@ -4782,6 +5074,15 @@ private constructor( */ fun folioNumber(): Optional = folioNumber.getOptional("folio_number") + /** + * List of account holders linked to this mutual fund folio + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun linkedHolders(): Optional> = + linkedHolders.getOptional("linked_holders") + /** * Registrar and Transfer Agent name * @@ -4830,6 +5131,16 @@ private constructor( @ExcludeMissing fun _folioNumber(): JsonField = folioNumber + /** + * Returns the raw JSON value of [linkedHolders]. + * + * Unlike [linkedHolders], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("linked_holders") + @ExcludeMissing + fun _linkedHolders(): JsonField> = linkedHolders + /** * Returns the raw JSON value of [registrar]. * @@ -4875,6 +5186,7 @@ private constructor( private var additionalInfo: JsonField = JsonMissing.of() private var amc: JsonField = JsonMissing.of() private var folioNumber: JsonField = JsonMissing.of() + private var linkedHolders: JsonField>? = null private var registrar: JsonField = JsonMissing.of() private var schemes: JsonField>? = null private var value: JsonField = JsonMissing.of() @@ -4885,6 +5197,7 @@ private constructor( additionalInfo = mutualFund.additionalInfo amc = mutualFund.amc folioNumber = mutualFund.folioNumber + linkedHolders = mutualFund.linkedHolders.map { it.toMutableList() } registrar = mutualFund.registrar schemes = mutualFund.schemes.map { it.toMutableList() } value = mutualFund.value @@ -4932,6 +5245,33 @@ private constructor( this.folioNumber = folioNumber } + /** List of account holders linked to this mutual fund folio */ + fun linkedHolders(linkedHolders: List) = + linkedHolders(JsonField.of(linkedHolders)) + + /** + * Sets [Builder.linkedHolders] to an arbitrary JSON value. + * + * You should usually call [Builder.linkedHolders] with a well-typed + * `List` value instead. This method is primarily for setting the field to + * an undocumented or not yet supported value. + */ + fun linkedHolders(linkedHolders: JsonField>) = apply { + this.linkedHolders = linkedHolders.map { it.toMutableList() } + } + + /** + * Adds a single [LinkedHolder] to [linkedHolders]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addLinkedHolder(linkedHolder: LinkedHolder) = apply { + linkedHolders = + (linkedHolders ?: JsonField.of(mutableListOf())).also { + checkKnown("linkedHolders", it).add(linkedHolder) + } + } + /** Registrar and Transfer Agent name */ fun registrar(registrar: String) = registrar(JsonField.of(registrar)) @@ -5010,6 +5350,7 @@ private constructor( additionalInfo, amc, folioNumber, + (linkedHolders ?: JsonMissing.of()).map { it.toImmutable() }, registrar, (schemes ?: JsonMissing.of()).map { it.toImmutable() }, value, @@ -5027,6 +5368,7 @@ private constructor( additionalInfo().ifPresent { it.validate() } amc() folioNumber() + linkedHolders().ifPresent { it.forEach { it.validate() } } registrar() schemes().ifPresent { it.forEach { it.validate() } } value() @@ -5052,6 +5394,7 @@ private constructor( (additionalInfo.asKnown().getOrNull()?.validity() ?: 0) + (if (amc.asKnown().isPresent) 1 else 0) + (if (folioNumber.asKnown().isPresent) 1 else 0) + + (linkedHolders.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + (if (registrar.asKnown().isPresent) 1 else 0) + (schemes.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + (if (value.asKnown().isPresent) 1 else 0) @@ -5273,30 +5616,209 @@ private constructor( "AdditionalInfo{kyc=$kyc, pan=$pan, pankyc=$pankyc, additionalProperties=$additionalProperties}" } - class Scheme + class LinkedHolder private constructor( - private val additionalInfo: JsonField, - private val cost: JsonField, - private val gain: JsonField, - private val isin: JsonField, private val name: JsonField, - private val nav: JsonField, - private val nominees: JsonField>, - private val transactions: JsonField>, - private val type: JsonField, - private val units: JsonField, - private val value: JsonField, + private val pan: JsonField, private val additionalProperties: MutableMap, ) { @JsonCreator private constructor( - @JsonProperty("additional_info") - @ExcludeMissing - additionalInfo: JsonField = JsonMissing.of(), - @JsonProperty("cost") @ExcludeMissing cost: JsonField = JsonMissing.of(), - @JsonProperty("gain") @ExcludeMissing gain: JsonField = JsonMissing.of(), - @JsonProperty("isin") @ExcludeMissing isin: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("pan") @ExcludeMissing pan: JsonField = JsonMissing.of(), + ) : this(name, pan, mutableMapOf()) + + /** + * Name of the account holder + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun name(): Optional = name.getOptional("name") + + /** + * PAN of the account holder + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun pan(): Optional = pan.getOptional("pan") + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + + /** + * Returns the raw JSON value of [pan]. + * + * Unlike [pan], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("pan") @ExcludeMissing fun _pan(): JsonField = pan + + @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 [LinkedHolder]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [LinkedHolder]. */ + class Builder internal constructor() { + + private var name: JsonField = JsonMissing.of() + private var pan: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(linkedHolder: LinkedHolder) = apply { + name = linkedHolder.name + pan = linkedHolder.pan + additionalProperties = linkedHolder.additionalProperties.toMutableMap() + } + + /** Name of the account holder */ + fun name(name: String) = name(JsonField.of(name)) + + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun name(name: JsonField) = apply { this.name = name } + + /** PAN of the account holder */ + fun pan(pan: String) = pan(JsonField.of(pan)) + + /** + * Sets [Builder.pan] to an arbitrary JSON value. + * + * You should usually call [Builder.pan] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun pan(pan: JsonField) = apply { this.pan = pan } + + 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 [LinkedHolder]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): LinkedHolder = + LinkedHolder(name, pan, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): LinkedHolder = apply { + if (validated) { + return@apply + } + + name() + pan() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (name.asKnown().isPresent) 1 else 0) + (if (pan.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is LinkedHolder && + name == other.name && + pan == other.pan && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(name, pan, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "LinkedHolder{name=$name, pan=$pan, additionalProperties=$additionalProperties}" + } + + class Scheme + private constructor( + private val additionalInfo: JsonField, + private val cost: JsonField, + private val gain: JsonField, + private val isin: JsonField, + private val name: JsonField, + private val nav: JsonField, + private val nominees: JsonField>, + private val transactions: JsonField>, + private val type: JsonField, + private val units: JsonField, + private val value: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("additional_info") + @ExcludeMissing + additionalInfo: JsonField = JsonMissing.of(), + @JsonProperty("cost") @ExcludeMissing cost: JsonField = JsonMissing.of(), + @JsonProperty("gain") @ExcludeMissing gain: JsonField = JsonMissing.of(), + @JsonProperty("isin") @ExcludeMissing isin: JsonField = JsonMissing.of(), @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), @JsonProperty("nav") @ExcludeMissing nav: JsonField = JsonMissing.of(), @JsonProperty("nominees") @@ -6968,6 +7490,7 @@ private constructor( additionalInfo == other.additionalInfo && amc == other.amc && folioNumber == other.folioNumber && + linkedHolders == other.linkedHolders && registrar == other.registrar && schemes == other.schemes && value == other.value && @@ -6979,6 +7502,7 @@ private constructor( additionalInfo, amc, folioNumber, + linkedHolders, registrar, schemes, value, @@ -6989,55 +7513,115 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "MutualFund{additionalInfo=$additionalInfo, amc=$amc, folioNumber=$folioNumber, registrar=$registrar, schemes=$schemes, value=$value, additionalProperties=$additionalProperties}" + "MutualFund{additionalInfo=$additionalInfo, amc=$amc, folioNumber=$folioNumber, linkedHolders=$linkedHolders, registrar=$registrar, schemes=$schemes, value=$value, additionalProperties=$additionalProperties}" } - class Summary + class Np private constructor( - private val accounts: JsonField, - private val totalValue: JsonField, + private val additionalInfo: JsonValue, + private val cra: JsonField, + private val funds: JsonField>, + private val linkedHolders: JsonField>, + private val pran: JsonField, + private val value: JsonField, private val additionalProperties: MutableMap, ) { @JsonCreator private constructor( - @JsonProperty("accounts") + @JsonProperty("additional_info") @ExcludeMissing - accounts: JsonField = JsonMissing.of(), - @JsonProperty("total_value") + additionalInfo: JsonValue = JsonMissing.of(), + @JsonProperty("cra") @ExcludeMissing cra: JsonField = JsonMissing.of(), + @JsonProperty("funds") @ExcludeMissing funds: JsonField> = JsonMissing.of(), + @JsonProperty("linked_holders") @ExcludeMissing - totalValue: JsonField = JsonMissing.of(), - ) : this(accounts, totalValue, mutableMapOf()) + linkedHolders: JsonField> = JsonMissing.of(), + @JsonProperty("pran") @ExcludeMissing pran: JsonField = JsonMissing.of(), + @JsonProperty("value") @ExcludeMissing value: JsonField = JsonMissing.of(), + ) : this(additionalInfo, cra, funds, linkedHolders, pran, value, mutableMapOf()) + + /** Additional information specific to the NPS account */ + @JsonProperty("additional_info") + @ExcludeMissing + fun _additionalInfo(): JsonValue = additionalInfo /** + * Central Record Keeping Agency name + * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if * the server responded with an unexpected value). */ - fun accounts(): Optional = accounts.getOptional("accounts") + fun cra(): Optional = cra.getOptional("cra") /** - * Total portfolio value across all accounts + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun funds(): Optional> = funds.getOptional("funds") + + /** + * List of account holders linked to this NPS account * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if * the server responded with an unexpected value). */ - fun totalValue(): Optional = totalValue.getOptional("total_value") + fun linkedHolders(): Optional> = + linkedHolders.getOptional("linked_holders") /** - * Returns the raw JSON value of [accounts]. + * Permanent Retirement Account Number (PRAN) * - * Unlike [accounts], this method doesn't throw if the JSON field has an unexpected type. + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("accounts") @ExcludeMissing fun _accounts(): JsonField = accounts + fun pran(): Optional = pran.getOptional("pran") /** - * Returns the raw JSON value of [totalValue]. + * Total value of the NPS account * - * Unlike [totalValue], this method doesn't throw if the JSON field has an unexpected type. + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("total_value") + fun value(): Optional = value.getOptional("value") + + /** + * Returns the raw JSON value of [cra]. + * + * Unlike [cra], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("cra") @ExcludeMissing fun _cra(): JsonField = cra + + /** + * Returns the raw JSON value of [funds]. + * + * Unlike [funds], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("funds") @ExcludeMissing fun _funds(): JsonField> = funds + + /** + * Returns the raw JSON value of [linkedHolders]. + * + * Unlike [linkedHolders], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("linked_holders") @ExcludeMissing - fun _totalValue(): JsonField = totalValue + fun _linkedHolders(): JsonField> = linkedHolders + + /** + * Returns the raw JSON value of [pran]. + * + * Unlike [pran], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("pran") @ExcludeMissing fun _pran(): JsonField = pran + + /** + * Returns the raw JSON value of [value]. + * + * Unlike [value], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("value") @ExcludeMissing fun _value(): JsonField = value @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { @@ -7053,37 +7637,1159 @@ private constructor( companion object { - /** Returns a mutable builder for constructing an instance of [Summary]. */ + /** Returns a mutable builder for constructing an instance of [Np]. */ @JvmStatic fun builder() = Builder() } - /** A builder for [Summary]. */ + /** A builder for [Np]. */ class Builder internal constructor() { - private var accounts: JsonField = JsonMissing.of() - private var totalValue: JsonField = JsonMissing.of() + private var additionalInfo: JsonValue = JsonMissing.of() + private var cra: JsonField = JsonMissing.of() + private var funds: JsonField>? = null + private var linkedHolders: JsonField>? = null + private var pran: JsonField = JsonMissing.of() + private var value: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(summary: Summary) = apply { - accounts = summary.accounts - totalValue = summary.totalValue - additionalProperties = summary.additionalProperties.toMutableMap() + internal fun from(np: Np) = apply { + additionalInfo = np.additionalInfo + cra = np.cra + funds = np.funds.map { it.toMutableList() } + linkedHolders = np.linkedHolders.map { it.toMutableList() } + pran = np.pran + value = np.value + additionalProperties = np.additionalProperties.toMutableMap() } - fun accounts(accounts: Accounts) = accounts(JsonField.of(accounts)) + /** Additional information specific to the NPS account */ + fun additionalInfo(additionalInfo: JsonValue) = apply { + this.additionalInfo = additionalInfo + } + + /** Central Record Keeping Agency name */ + fun cra(cra: String) = cra(JsonField.of(cra)) /** - * Sets [Builder.accounts] to an arbitrary JSON value. + * Sets [Builder.cra] to an arbitrary JSON value. * - * You should usually call [Builder.accounts] with a well-typed [Accounts] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. + * You should usually call [Builder.cra] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. */ - fun accounts(accounts: JsonField) = apply { this.accounts = accounts } + fun cra(cra: JsonField) = apply { this.cra = cra } - /** Total portfolio value across all accounts */ - fun totalValue(totalValue: Float) = totalValue(JsonField.of(totalValue)) + fun funds(funds: List) = funds(JsonField.of(funds)) + + /** + * Sets [Builder.funds] to an arbitrary JSON value. + * + * You should usually call [Builder.funds] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun funds(funds: JsonField>) = apply { + this.funds = funds.map { it.toMutableList() } + } + + /** + * Adds a single [Fund] to [funds]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addFund(fund: Fund) = apply { + funds = + (funds ?: JsonField.of(mutableListOf())).also { + checkKnown("funds", it).add(fund) + } + } + + /** List of account holders linked to this NPS account */ + fun linkedHolders(linkedHolders: List) = + linkedHolders(JsonField.of(linkedHolders)) + + /** + * Sets [Builder.linkedHolders] to an arbitrary JSON value. + * + * You should usually call [Builder.linkedHolders] with a well-typed + * `List` value instead. This method is primarily for setting the field to + * an undocumented or not yet supported value. + */ + fun linkedHolders(linkedHolders: JsonField>) = apply { + this.linkedHolders = linkedHolders.map { it.toMutableList() } + } + + /** + * Adds a single [LinkedHolder] to [linkedHolders]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addLinkedHolder(linkedHolder: LinkedHolder) = apply { + linkedHolders = + (linkedHolders ?: JsonField.of(mutableListOf())).also { + checkKnown("linkedHolders", it).add(linkedHolder) + } + } + + /** Permanent Retirement Account Number (PRAN) */ + fun pran(pran: String) = pran(JsonField.of(pran)) + + /** + * Sets [Builder.pran] to an arbitrary JSON value. + * + * You should usually call [Builder.pran] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun pran(pran: JsonField) = apply { this.pran = pran } + + /** Total value of the NPS account */ + fun value(value: Float) = value(JsonField.of(value)) + + /** + * Sets [Builder.value] to an arbitrary JSON value. + * + * You should usually call [Builder.value] with a well-typed [Float] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun value(value: JsonField) = apply { this.value = value } + + 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 [Np]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Np = + Np( + additionalInfo, + cra, + (funds ?: JsonMissing.of()).map { it.toImmutable() }, + (linkedHolders ?: JsonMissing.of()).map { it.toImmutable() }, + pran, + value, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Np = apply { + if (validated) { + return@apply + } + + cra() + funds().ifPresent { it.forEach { it.validate() } } + linkedHolders().ifPresent { it.forEach { it.validate() } } + pran() + value() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (cra.asKnown().isPresent) 1 else 0) + + (funds.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (linkedHolders.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (pran.asKnown().isPresent) 1 else 0) + + (if (value.asKnown().isPresent) 1 else 0) + + class Fund + private constructor( + private val additionalInfo: JsonField, + private val cost: JsonField, + private val name: JsonField, + private val nav: JsonField, + private val units: JsonField, + private val value: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("additional_info") + @ExcludeMissing + additionalInfo: JsonField = JsonMissing.of(), + @JsonProperty("cost") @ExcludeMissing cost: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("nav") @ExcludeMissing nav: JsonField = JsonMissing.of(), + @JsonProperty("units") @ExcludeMissing units: JsonField = JsonMissing.of(), + @JsonProperty("value") @ExcludeMissing value: JsonField = JsonMissing.of(), + ) : this(additionalInfo, cost, name, nav, units, value, mutableMapOf()) + + /** + * Additional information specific to the NPS fund + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun additionalInfo(): Optional = + additionalInfo.getOptional("additional_info") + + /** + * Cost of investment + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun cost(): Optional = cost.getOptional("cost") + + /** + * Name of the NPS fund + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun name(): Optional = name.getOptional("name") + + /** + * Net Asset Value per unit + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun nav(): Optional = nav.getOptional("nav") + + /** + * Number of units held + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun units(): Optional = units.getOptional("units") + + /** + * Current market value of the holding + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun value(): Optional = value.getOptional("value") + + /** + * Returns the raw JSON value of [additionalInfo]. + * + * Unlike [additionalInfo], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("additional_info") + @ExcludeMissing + fun _additionalInfo(): JsonField = additionalInfo + + /** + * Returns the raw JSON value of [cost]. + * + * Unlike [cost], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("cost") @ExcludeMissing fun _cost(): JsonField = cost + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + + /** + * Returns the raw JSON value of [nav]. + * + * Unlike [nav], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("nav") @ExcludeMissing fun _nav(): JsonField = nav + + /** + * Returns the raw JSON value of [units]. + * + * Unlike [units], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("units") @ExcludeMissing fun _units(): JsonField = units + + /** + * Returns the raw JSON value of [value]. + * + * Unlike [value], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("value") @ExcludeMissing fun _value(): JsonField = value + + @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 [Fund]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Fund]. */ + class Builder internal constructor() { + + private var additionalInfo: JsonField = JsonMissing.of() + private var cost: JsonField = JsonMissing.of() + private var name: JsonField = JsonMissing.of() + private var nav: JsonField = JsonMissing.of() + private var units: JsonField = JsonMissing.of() + private var value: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(fund: Fund) = apply { + additionalInfo = fund.additionalInfo + cost = fund.cost + name = fund.name + nav = fund.nav + units = fund.units + value = fund.value + additionalProperties = fund.additionalProperties.toMutableMap() + } + + /** Additional information specific to the NPS fund */ + fun additionalInfo(additionalInfo: AdditionalInfo) = + additionalInfo(JsonField.of(additionalInfo)) + + /** + * Sets [Builder.additionalInfo] to an arbitrary JSON value. + * + * You should usually call [Builder.additionalInfo] with a well-typed + * [AdditionalInfo] value instead. This method is primarily for setting the field to + * an undocumented or not yet supported value. + */ + fun additionalInfo(additionalInfo: JsonField) = apply { + this.additionalInfo = additionalInfo + } + + /** Cost of investment */ + fun cost(cost: Float) = cost(JsonField.of(cost)) + + /** + * Sets [Builder.cost] to an arbitrary JSON value. + * + * You should usually call [Builder.cost] with a well-typed [Float] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun cost(cost: JsonField) = apply { this.cost = cost } + + /** Name of the NPS fund */ + fun name(name: String) = name(JsonField.of(name)) + + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun name(name: JsonField) = apply { this.name = name } + + /** Net Asset Value per unit */ + fun nav(nav: Float) = nav(JsonField.of(nav)) + + /** + * Sets [Builder.nav] to an arbitrary JSON value. + * + * You should usually call [Builder.nav] with a well-typed [Float] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun nav(nav: JsonField) = apply { this.nav = nav } + + /** Number of units held */ + fun units(units: Float) = units(JsonField.of(units)) + + /** + * Sets [Builder.units] to an arbitrary JSON value. + * + * You should usually call [Builder.units] with a well-typed [Float] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun units(units: JsonField) = apply { this.units = units } + + /** Current market value of the holding */ + fun value(value: Float) = value(JsonField.of(value)) + + /** + * Sets [Builder.value] to an arbitrary JSON value. + * + * You should usually call [Builder.value] with a well-typed [Float] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun value(value: JsonField) = apply { this.value = value } + + 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 [Fund]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Fund = + Fund( + additionalInfo, + cost, + name, + nav, + units, + value, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Fund = apply { + if (validated) { + return@apply + } + + additionalInfo().ifPresent { it.validate() } + cost() + name() + nav() + units() + value() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 = + (additionalInfo.asKnown().getOrNull()?.validity() ?: 0) + + (if (cost.asKnown().isPresent) 1 else 0) + + (if (name.asKnown().isPresent) 1 else 0) + + (if (nav.asKnown().isPresent) 1 else 0) + + (if (units.asKnown().isPresent) 1 else 0) + + (if (value.asKnown().isPresent) 1 else 0) + + /** Additional information specific to the NPS fund */ + class AdditionalInfo + private constructor( + private val manager: JsonField, + private val tier: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("manager") + @ExcludeMissing + manager: JsonField = JsonMissing.of(), + @JsonProperty("tier") @ExcludeMissing tier: JsonField = JsonMissing.of(), + ) : this(manager, tier, mutableMapOf()) + + /** + * Fund manager name + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun manager(): Optional = manager.getOptional("manager") + + /** + * NPS tier (Tier I or Tier II) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun tier(): Optional = tier.getOptional("tier") + + /** + * Returns the raw JSON value of [manager]. + * + * Unlike [manager], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("manager") @ExcludeMissing fun _manager(): JsonField = manager + + /** + * Returns the raw JSON value of [tier]. + * + * Unlike [tier], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("tier") @ExcludeMissing fun _tier(): JsonField = tier + + @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 [AdditionalInfo]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AdditionalInfo]. */ + class Builder internal constructor() { + + private var manager: JsonField = JsonMissing.of() + private var tier: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(additionalInfo: AdditionalInfo) = apply { + manager = additionalInfo.manager + tier = additionalInfo.tier + additionalProperties = additionalInfo.additionalProperties.toMutableMap() + } + + /** Fund manager name */ + fun manager(manager: String) = manager(JsonField.of(manager)) + + /** + * Sets [Builder.manager] to an arbitrary JSON value. + * + * You should usually call [Builder.manager] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun manager(manager: JsonField) = apply { this.manager = manager } + + /** NPS tier (Tier I or Tier II) */ + fun tier(tier: Tier?) = tier(JsonField.ofNullable(tier)) + + /** Alias for calling [Builder.tier] with `tier.orElse(null)`. */ + fun tier(tier: Optional) = tier(tier.getOrNull()) + + /** + * Sets [Builder.tier] to an arbitrary JSON value. + * + * You should usually call [Builder.tier] with a well-typed [Tier] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun tier(tier: JsonField) = apply { this.tier = tier } + + 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 [AdditionalInfo]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): AdditionalInfo = + AdditionalInfo(manager, tier, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): AdditionalInfo = apply { + if (validated) { + return@apply + } + + manager() + tier().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (manager.asKnown().isPresent) 1 else 0) + + (tier.asKnown().getOrNull()?.validity() ?: 0) + + /** NPS tier (Tier I or Tier II) */ + class Tier @JsonCreator private constructor(private val value: JsonField) : + Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that + * doesn't match any known member, and you want to know that value. For example, + * if the SDK is on an older version than the API, then the API may respond with + * new members that the SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue + fun _value(): JsonField = value + + companion object { + + @JvmField val _1 = of(1.0) + + @JvmField val _2 = of(2.0) + + @JvmStatic fun of(value: Double) = Tier(JsonField.of(value)) + } + + /** An enum containing [Tier]'s known values. */ + enum class Known { + _1, + _2, + } + + /** + * An enum containing [Tier]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Tier] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For + * example, if the SDK is on an older version than the API, then the API may + * respond with new members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + _1, + _2, + /** + * An enum member indicating that [Tier] was instantiated with an unknown + * value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or + * if you want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + _1 -> Value._1 + _2 -> Value._2 + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known + * and don't want to throw for the unknown case. + * + * @throws CasParserInvalidDataException if this class instance's value is a not + * a known member. + */ + fun known(): Known = + when (this) { + _1 -> Known._1 + _2 -> Known._2 + else -> throw CasParserInvalidDataException("Unknown Tier: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * @throws CasParserInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asDouble(): Double = + _value().asNumber().getOrNull()?.toDouble() + ?: throw CasParserInvalidDataException("Value is not a Double") + + private var validated: Boolean = false + + fun validate(): Tier = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Tier && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AdditionalInfo && + manager == other.manager && + tier == other.tier && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(manager, tier, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AdditionalInfo{manager=$manager, tier=$tier, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Fund && + additionalInfo == other.additionalInfo && + cost == other.cost && + name == other.name && + nav == other.nav && + units == other.units && + value == other.value && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(additionalInfo, cost, name, nav, units, value, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Fund{additionalInfo=$additionalInfo, cost=$cost, name=$name, nav=$nav, units=$units, value=$value, additionalProperties=$additionalProperties}" + } + + class LinkedHolder + private constructor( + private val name: JsonField, + private val pan: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("pan") @ExcludeMissing pan: JsonField = JsonMissing.of(), + ) : this(name, pan, mutableMapOf()) + + /** + * Name of the account holder + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun name(): Optional = name.getOptional("name") + + /** + * PAN of the account holder + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun pan(): Optional = pan.getOptional("pan") + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + + /** + * Returns the raw JSON value of [pan]. + * + * Unlike [pan], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("pan") @ExcludeMissing fun _pan(): JsonField = pan + + @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 [LinkedHolder]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [LinkedHolder]. */ + class Builder internal constructor() { + + private var name: JsonField = JsonMissing.of() + private var pan: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(linkedHolder: LinkedHolder) = apply { + name = linkedHolder.name + pan = linkedHolder.pan + additionalProperties = linkedHolder.additionalProperties.toMutableMap() + } + + /** Name of the account holder */ + fun name(name: String) = name(JsonField.of(name)) + + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun name(name: JsonField) = apply { this.name = name } + + /** PAN of the account holder */ + fun pan(pan: String) = pan(JsonField.of(pan)) + + /** + * Sets [Builder.pan] to an arbitrary JSON value. + * + * You should usually call [Builder.pan] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun pan(pan: JsonField) = apply { this.pan = pan } + + 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 [LinkedHolder]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): LinkedHolder = + LinkedHolder(name, pan, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): LinkedHolder = apply { + if (validated) { + return@apply + } + + name() + pan() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (name.asKnown().isPresent) 1 else 0) + (if (pan.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is LinkedHolder && + name == other.name && + pan == other.pan && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(name, pan, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "LinkedHolder{name=$name, pan=$pan, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Np && + additionalInfo == other.additionalInfo && + cra == other.cra && + funds == other.funds && + linkedHolders == other.linkedHolders && + pran == other.pran && + value == other.value && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + additionalInfo, + cra, + funds, + linkedHolders, + pran, + value, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Np{additionalInfo=$additionalInfo, cra=$cra, funds=$funds, linkedHolders=$linkedHolders, pran=$pran, value=$value, additionalProperties=$additionalProperties}" + } + + class Summary + private constructor( + private val accounts: JsonField, + private val totalValue: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("accounts") + @ExcludeMissing + accounts: JsonField = JsonMissing.of(), + @JsonProperty("total_value") + @ExcludeMissing + totalValue: JsonField = JsonMissing.of(), + ) : this(accounts, totalValue, mutableMapOf()) + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun accounts(): Optional = accounts.getOptional("accounts") + + /** + * Total portfolio value across all accounts + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun totalValue(): Optional = totalValue.getOptional("total_value") + + /** + * Returns the raw JSON value of [accounts]. + * + * Unlike [accounts], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("accounts") @ExcludeMissing fun _accounts(): JsonField = accounts + + /** + * Returns the raw JSON value of [totalValue]. + * + * Unlike [totalValue], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("total_value") + @ExcludeMissing + fun _totalValue(): JsonField = totalValue + + @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 [Summary]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Summary]. */ + class Builder internal constructor() { + + private var accounts: JsonField = JsonMissing.of() + private var totalValue: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(summary: Summary) = apply { + accounts = summary.accounts + totalValue = summary.totalValue + additionalProperties = summary.additionalProperties.toMutableMap() + } + + fun accounts(accounts: Accounts) = accounts(JsonField.of(accounts)) + + /** + * Sets [Builder.accounts] to an arbitrary JSON value. + * + * You should usually call [Builder.accounts] with a well-typed [Accounts] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun accounts(accounts: JsonField) = apply { this.accounts = accounts } + + /** Total portfolio value across all accounts */ + fun totalValue(totalValue: Float) = totalValue(JsonField.of(totalValue)) /** * Sets [Builder.totalValue] to an arbitrary JSON value. @@ -7158,6 +8864,7 @@ private constructor( private val demat: JsonField, private val insurance: JsonField, private val mutualFunds: JsonField, + private val nps: JsonField, private val additionalProperties: MutableMap, ) { @@ -7170,7 +8877,8 @@ private constructor( @JsonProperty("mutual_funds") @ExcludeMissing mutualFunds: JsonField = JsonMissing.of(), - ) : this(demat, insurance, mutualFunds, mutableMapOf()) + @JsonProperty("nps") @ExcludeMissing nps: JsonField = JsonMissing.of(), + ) : this(demat, insurance, mutualFunds, nps, mutableMapOf()) /** * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. @@ -7190,6 +8898,12 @@ private constructor( */ fun mutualFunds(): Optional = mutualFunds.getOptional("mutual_funds") + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun nps(): Optional = nps.getOptional("nps") + /** * Returns the raw JSON value of [demat]. * @@ -7217,6 +8931,13 @@ private constructor( @ExcludeMissing fun _mutualFunds(): JsonField = mutualFunds + /** + * Returns the raw JSON value of [nps]. + * + * Unlike [nps], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("nps") @ExcludeMissing fun _nps(): JsonField = nps + @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { additionalProperties.put(key, value) @@ -7241,6 +8962,7 @@ private constructor( private var demat: JsonField = JsonMissing.of() private var insurance: JsonField = JsonMissing.of() private var mutualFunds: JsonField = JsonMissing.of() + private var nps: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic @@ -7248,6 +8970,7 @@ private constructor( demat = accounts.demat insurance = accounts.insurance mutualFunds = accounts.mutualFunds + nps = accounts.nps additionalProperties = accounts.additionalProperties.toMutableMap() } @@ -7288,6 +9011,17 @@ private constructor( this.mutualFunds = mutualFunds } + fun nps(nps: Nps) = nps(JsonField.of(nps)) + + /** + * Sets [Builder.nps] to an arbitrary JSON value. + * + * You should usually call [Builder.nps] with a well-typed [Nps] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun nps(nps: JsonField) = apply { this.nps = nps } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() putAllAdditionalProperties(additionalProperties) @@ -7316,7 +9050,13 @@ private constructor( * Further updates to this [Builder] will not mutate the returned instance. */ fun build(): Accounts = - Accounts(demat, insurance, mutualFunds, additionalProperties.toMutableMap()) + Accounts( + demat, + insurance, + mutualFunds, + nps, + additionalProperties.toMutableMap(), + ) } private var validated: Boolean = false @@ -7329,6 +9069,7 @@ private constructor( demat().ifPresent { it.validate() } insurance().ifPresent { it.validate() } mutualFunds().ifPresent { it.validate() } + nps().ifPresent { it.validate() } validated = true } @@ -7350,7 +9091,8 @@ private constructor( internal fun validity(): Int = (demat.asKnown().getOrNull()?.validity() ?: 0) + (insurance.asKnown().getOrNull()?.validity() ?: 0) + - (mutualFunds.asKnown().getOrNull()?.validity() ?: 0) + (mutualFunds.asKnown().getOrNull()?.validity() ?: 0) + + (nps.asKnown().getOrNull()?.validity() ?: 0) class Demat private constructor( @@ -7928,6 +9670,197 @@ private constructor( "MutualFunds{count=$count, totalValue=$totalValue, additionalProperties=$additionalProperties}" } + class Nps + private constructor( + private val count: JsonField, + private val totalValue: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("count") + @ExcludeMissing + count: JsonField = JsonMissing.of(), + @JsonProperty("total_value") + @ExcludeMissing + totalValue: JsonField = JsonMissing.of(), + ) : this(count, totalValue, mutableMapOf()) + + /** + * Number of NPS accounts + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun count(): Optional = count.getOptional("count") + + /** + * Total value of NPS accounts + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun totalValue(): Optional = totalValue.getOptional("total_value") + + /** + * Returns the raw JSON value of [count]. + * + * Unlike [count], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("count") @ExcludeMissing fun _count(): JsonField = count + + /** + * Returns the raw JSON value of [totalValue]. + * + * Unlike [totalValue], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("total_value") + @ExcludeMissing + fun _totalValue(): JsonField = totalValue + + @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 [Nps]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Nps]. */ + class Builder internal constructor() { + + private var count: JsonField = JsonMissing.of() + private var totalValue: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(nps: Nps) = apply { + count = nps.count + totalValue = nps.totalValue + additionalProperties = nps.additionalProperties.toMutableMap() + } + + /** Number of NPS accounts */ + fun count(count: Long) = count(JsonField.of(count)) + + /** + * Sets [Builder.count] to an arbitrary JSON value. + * + * You should usually call [Builder.count] with a well-typed [Long] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun count(count: JsonField) = apply { this.count = count } + + /** Total value of NPS accounts */ + fun totalValue(totalValue: Float) = totalValue(JsonField.of(totalValue)) + + /** + * Sets [Builder.totalValue] to an arbitrary JSON value. + * + * You should usually call [Builder.totalValue] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun totalValue(totalValue: JsonField) = apply { + this.totalValue = totalValue + } + + 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 [Nps]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Nps = Nps(count, totalValue, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Nps = apply { + if (validated) { + return@apply + } + + count() + totalValue() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (count.asKnown().isPresent) 1 else 0) + + (if (totalValue.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Nps && + count == other.count && + totalValue == other.totalValue && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(count, totalValue, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Nps{count=$count, totalValue=$totalValue, additionalProperties=$additionalProperties}" + } + override fun equals(other: Any?): Boolean { if (this === other) { return true @@ -7937,17 +9870,18 @@ private constructor( demat == other.demat && insurance == other.insurance && mutualFunds == other.mutualFunds && + nps == other.nps && additionalProperties == other.additionalProperties } private val hashCode: Int by lazy { - Objects.hash(demat, insurance, mutualFunds, additionalProperties) + Objects.hash(demat, insurance, mutualFunds, nps, additionalProperties) } override fun hashCode(): Int = hashCode override fun toString() = - "Accounts{demat=$demat, insurance=$insurance, mutualFunds=$mutualFunds, additionalProperties=$additionalProperties}" + "Accounts{demat=$demat, insurance=$insurance, mutualFunds=$mutualFunds, nps=$nps, additionalProperties=$additionalProperties}" } override fun equals(other: Any?): Boolean { @@ -7982,6 +9916,7 @@ private constructor( investor == other.investor && meta == other.meta && mutualFunds == other.mutualFunds && + nps == other.nps && summary == other.summary && additionalProperties == other.additionalProperties } @@ -7993,6 +9928,7 @@ private constructor( investor, meta, mutualFunds, + nps, summary, additionalProperties, ) @@ -8001,5 +9937,5 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "UnifiedResponse{dematAccounts=$dematAccounts, insurance=$insurance, investor=$investor, meta=$meta, mutualFunds=$mutualFunds, summary=$summary, additionalProperties=$additionalProperties}" + "UnifiedResponse{dematAccounts=$dematAccounts, insurance=$insurance, investor=$investor, meta=$meta, mutualFunds=$mutualFunds, nps=$nps, summary=$summary, additionalProperties=$additionalProperties}" } diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/UnifiedResponseTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/UnifiedResponseTest.kt index 1a5cffc..86f7a31 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/UnifiedResponseTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/UnifiedResponseTest.kt @@ -86,6 +86,12 @@ internal class UnifiedResponseTest { ) .build() ) + .addLinkedHolder( + UnifiedResponse.DematAccount.LinkedHolder.builder() + .name("name") + .pan("pan") + .build() + ) .value(0.0f) .build() ) @@ -140,6 +146,12 @@ internal class UnifiedResponseTest { ) .amc("amc") .folioNumber("folio_number") + .addLinkedHolder( + UnifiedResponse.MutualFund.LinkedHolder.builder() + .name("name") + .pan("pan") + .build() + ) .registrar("registrar") .addScheme( UnifiedResponse.MutualFund.Scheme.builder() @@ -183,6 +195,35 @@ internal class UnifiedResponseTest { .value(0.0f) .build() ) + .addNp( + UnifiedResponse.Np.builder() + .additionalInfo(JsonValue.from(mapOf())) + .cra("cra") + .addFund( + UnifiedResponse.Np.Fund.builder() + .additionalInfo( + UnifiedResponse.Np.Fund.AdditionalInfo.builder() + .manager("manager") + .tier(UnifiedResponse.Np.Fund.AdditionalInfo.Tier._1) + .build() + ) + .cost(0.0f) + .name("name") + .nav(0.0f) + .units(0.0f) + .value(0.0f) + .build() + ) + .addLinkedHolder( + UnifiedResponse.Np.LinkedHolder.builder() + .name("name") + .pan("pan") + .build() + ) + .pran("pran") + .value(0.0f) + .build() + ) .summary( UnifiedResponse.Summary.builder() .accounts( @@ -205,6 +246,12 @@ internal class UnifiedResponseTest { .totalValue(0.0f) .build() ) + .nps( + UnifiedResponse.Summary.Accounts.Nps.builder() + .count(0L) + .totalValue(0.0f) + .build() + ) .build() ) .totalValue(0.0f) @@ -281,6 +328,12 @@ internal class UnifiedResponseTest { ) .build() ) + .addLinkedHolder( + UnifiedResponse.DematAccount.LinkedHolder.builder() + .name("name") + .pan("pan") + .build() + ) .value(0.0f) .build() ) @@ -339,6 +392,12 @@ internal class UnifiedResponseTest { ) .amc("amc") .folioNumber("folio_number") + .addLinkedHolder( + UnifiedResponse.MutualFund.LinkedHolder.builder() + .name("name") + .pan("pan") + .build() + ) .registrar("registrar") .addScheme( UnifiedResponse.MutualFund.Scheme.builder() @@ -382,6 +441,33 @@ internal class UnifiedResponseTest { .value(0.0f) .build() ) + assertThat(unifiedResponse.nps().getOrNull()) + .containsExactly( + UnifiedResponse.Np.builder() + .additionalInfo(JsonValue.from(mapOf())) + .cra("cra") + .addFund( + UnifiedResponse.Np.Fund.builder() + .additionalInfo( + UnifiedResponse.Np.Fund.AdditionalInfo.builder() + .manager("manager") + .tier(UnifiedResponse.Np.Fund.AdditionalInfo.Tier._1) + .build() + ) + .cost(0.0f) + .name("name") + .nav(0.0f) + .units(0.0f) + .value(0.0f) + .build() + ) + .addLinkedHolder( + UnifiedResponse.Np.LinkedHolder.builder().name("name").pan("pan").build() + ) + .pran("pran") + .value(0.0f) + .build() + ) assertThat(unifiedResponse.summary()) .contains( UnifiedResponse.Summary.builder() @@ -405,6 +491,12 @@ internal class UnifiedResponseTest { .totalValue(0.0f) .build() ) + .nps( + UnifiedResponse.Summary.Accounts.Nps.builder() + .count(0L) + .totalValue(0.0f) + .build() + ) .build() ) .totalValue(0.0f) @@ -486,6 +578,12 @@ internal class UnifiedResponseTest { ) .build() ) + .addLinkedHolder( + UnifiedResponse.DematAccount.LinkedHolder.builder() + .name("name") + .pan("pan") + .build() + ) .value(0.0f) .build() ) @@ -540,6 +638,12 @@ internal class UnifiedResponseTest { ) .amc("amc") .folioNumber("folio_number") + .addLinkedHolder( + UnifiedResponse.MutualFund.LinkedHolder.builder() + .name("name") + .pan("pan") + .build() + ) .registrar("registrar") .addScheme( UnifiedResponse.MutualFund.Scheme.builder() @@ -583,6 +687,35 @@ internal class UnifiedResponseTest { .value(0.0f) .build() ) + .addNp( + UnifiedResponse.Np.builder() + .additionalInfo(JsonValue.from(mapOf())) + .cra("cra") + .addFund( + UnifiedResponse.Np.Fund.builder() + .additionalInfo( + UnifiedResponse.Np.Fund.AdditionalInfo.builder() + .manager("manager") + .tier(UnifiedResponse.Np.Fund.AdditionalInfo.Tier._1) + .build() + ) + .cost(0.0f) + .name("name") + .nav(0.0f) + .units(0.0f) + .value(0.0f) + .build() + ) + .addLinkedHolder( + UnifiedResponse.Np.LinkedHolder.builder() + .name("name") + .pan("pan") + .build() + ) + .pran("pran") + .value(0.0f) + .build() + ) .summary( UnifiedResponse.Summary.builder() .accounts( @@ -605,6 +738,12 @@ internal class UnifiedResponseTest { .totalValue(0.0f) .build() ) + .nps( + UnifiedResponse.Summary.Accounts.Nps.builder() + .count(0L) + .totalValue(0.0f) + .build() + ) .build() ) .totalValue(0.0f) diff --git a/cas-parser-java-proguard-test/src/test/kotlin/com/cas_parser/api/proguard/ProGuardCompatibilityTest.kt b/cas-parser-java-proguard-test/src/test/kotlin/com/cas_parser/api/proguard/ProGuardCompatibilityTest.kt index f132d1f..e2b76ff 100644 --- a/cas-parser-java-proguard-test/src/test/kotlin/com/cas_parser/api/proguard/ProGuardCompatibilityTest.kt +++ b/cas-parser-java-proguard-test/src/test/kotlin/com/cas_parser/api/proguard/ProGuardCompatibilityTest.kt @@ -128,6 +128,12 @@ internal class ProGuardCompatibilityTest { ) .build() ) + .addLinkedHolder( + UnifiedResponse.DematAccount.LinkedHolder.builder() + .name("name") + .pan("pan") + .build() + ) .value(0.0f) .build() ) @@ -182,6 +188,12 @@ internal class ProGuardCompatibilityTest { ) .amc("amc") .folioNumber("folio_number") + .addLinkedHolder( + UnifiedResponse.MutualFund.LinkedHolder.builder() + .name("name") + .pan("pan") + .build() + ) .registrar("registrar") .addScheme( UnifiedResponse.MutualFund.Scheme.builder() @@ -225,6 +237,35 @@ internal class ProGuardCompatibilityTest { .value(0.0f) .build() ) + .addNp( + UnifiedResponse.Np.builder() + .additionalInfo(JsonValue.from(mapOf())) + .cra("cra") + .addFund( + UnifiedResponse.Np.Fund.builder() + .additionalInfo( + UnifiedResponse.Np.Fund.AdditionalInfo.builder() + .manager("manager") + .tier(UnifiedResponse.Np.Fund.AdditionalInfo.Tier._1) + .build() + ) + .cost(0.0f) + .name("name") + .nav(0.0f) + .units(0.0f) + .value(0.0f) + .build() + ) + .addLinkedHolder( + UnifiedResponse.Np.LinkedHolder.builder() + .name("name") + .pan("pan") + .build() + ) + .pran("pran") + .value(0.0f) + .build() + ) .summary( UnifiedResponse.Summary.builder() .accounts( @@ -247,6 +288,12 @@ internal class ProGuardCompatibilityTest { .totalValue(0.0f) .build() ) + .nps( + UnifiedResponse.Summary.Accounts.Nps.builder() + .count(0L) + .totalValue(0.0f) + .build() + ) .build() ) .totalValue(0.0f) From 2e71bb576d8cd7e5a472aae1765af154155884b4 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 26 Sep 2025 02:22:21 +0000 Subject: [PATCH 21/99] fix(client): deserialization of empty objects --- .../CasGeneratorGenerateCasParams.kt | 1 + .../CasGeneratorGenerateCasResponse.kt | 1 + .../api/models/casparser/UnifiedResponse.kt | 32 +++++++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casgenerator/CasGeneratorGenerateCasParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casgenerator/CasGeneratorGenerateCasParams.kt index eb7213c..598c6a2 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casgenerator/CasGeneratorGenerateCasParams.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casgenerator/CasGeneratorGenerateCasParams.kt @@ -394,6 +394,7 @@ private constructor( override fun _queryParams(): QueryParams = additionalQueryParams class Body + @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val email: JsonField, private val fromDate: JsonField, diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casgenerator/CasGeneratorGenerateCasResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casgenerator/CasGeneratorGenerateCasResponse.kt index 09df4cd..ad4901d 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casgenerator/CasGeneratorGenerateCasResponse.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casgenerator/CasGeneratorGenerateCasResponse.kt @@ -16,6 +16,7 @@ import java.util.Objects import java.util.Optional class CasGeneratorGenerateCasResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val msg: JsonField, private val status: JsonField, diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/UnifiedResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/UnifiedResponse.kt index 67cc09d..98a9131 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/UnifiedResponse.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/UnifiedResponse.kt @@ -22,6 +22,7 @@ import java.util.Optional import kotlin.jvm.optionals.getOrNull class UnifiedResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val dematAccounts: JsonField>, private val insurance: JsonField, @@ -380,6 +381,7 @@ private constructor( (summary.asKnown().getOrNull()?.validity() ?: 0) class DematAccount + @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val additionalInfo: JsonField, private val boId: JsonField, @@ -827,6 +829,7 @@ private constructor( /** Additional information specific to the demat account type */ class AdditionalInfo + @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val boStatus: JsonField, private val boSubStatus: JsonField, @@ -1408,6 +1411,7 @@ private constructor( } class Holdings + @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val aifs: JsonField>, private val corporateBonds: JsonField>, @@ -1766,6 +1770,7 @@ private constructor( ?: 0) class Aif + @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val additionalInfo: JsonValue, private val isin: JsonField, @@ -2052,6 +2057,7 @@ private constructor( } class CorporateBond + @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val additionalInfo: JsonValue, private val isin: JsonField, @@ -2340,6 +2346,7 @@ private constructor( } class DematMutualFund + @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val additionalInfo: JsonValue, private val isin: JsonField, @@ -2628,6 +2635,7 @@ private constructor( } class Equity + @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val additionalInfo: JsonValue, private val isin: JsonField, @@ -2914,6 +2922,7 @@ private constructor( } class GovernmentSecurity + @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val additionalInfo: JsonValue, private val isin: JsonField, @@ -3235,6 +3244,7 @@ private constructor( } class LinkedHolder + @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val name: JsonField, private val pan: JsonField, @@ -3453,6 +3463,7 @@ private constructor( } class Insurance + @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val lifeInsurancePolicies: JsonField>, private val additionalProperties: MutableMap, @@ -3600,6 +3611,7 @@ private constructor( (lifeInsurancePolicies.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) class LifeInsurancePolicy + @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val additionalInfo: JsonValue, private val lifeAssured: JsonField, @@ -4107,6 +4119,7 @@ private constructor( } class Investor + @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val address: JsonField, private val casId: JsonField, @@ -4465,6 +4478,7 @@ private constructor( } class Meta + @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val casType: JsonField, private val generatedAt: JsonField, @@ -4807,6 +4821,7 @@ private constructor( } class StatementPeriod + @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val from: JsonField, private val to: JsonField, @@ -5008,6 +5023,7 @@ private constructor( } class MutualFund + @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val additionalInfo: JsonField, private val amc: JsonField, @@ -5401,6 +5417,7 @@ private constructor( /** Additional folio information */ class AdditionalInfo + @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val kyc: JsonField, private val pan: JsonField, @@ -5617,6 +5634,7 @@ private constructor( } class LinkedHolder + @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val name: JsonField, private val pan: JsonField, @@ -5796,6 +5814,7 @@ private constructor( } class Scheme + @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val additionalInfo: JsonField, private val cost: JsonField, @@ -6324,6 +6343,7 @@ private constructor( /** Additional information specific to the scheme */ class AdditionalInfo + @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val advisor: JsonField, private val amfi: JsonField, @@ -6649,6 +6669,7 @@ private constructor( } class Gain + @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val absolute: JsonField, private val percentage: JsonField, @@ -6843,6 +6864,7 @@ private constructor( } class Transaction + @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val amount: JsonField, private val balance: JsonField, @@ -7517,6 +7539,7 @@ private constructor( } class Np + @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val additionalInfo: JsonValue, private val cra: JsonField, @@ -7830,6 +7853,7 @@ private constructor( (if (value.asKnown().isPresent) 1 else 0) class Fund + @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val additionalInfo: JsonField, private val cost: JsonField, @@ -8141,6 +8165,7 @@ private constructor( /** Additional information specific to the NPS fund */ class AdditionalInfo + @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val manager: JsonField, private val tier: JsonField, @@ -8487,6 +8512,7 @@ private constructor( } class LinkedHolder + @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val name: JsonField, private val pan: JsonField, @@ -8699,6 +8725,7 @@ private constructor( } class Summary + @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val accounts: JsonField, private val totalValue: JsonField, @@ -8860,6 +8887,7 @@ private constructor( (if (totalValue.asKnown().isPresent) 1 else 0) class Accounts + @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val demat: JsonField, private val insurance: JsonField, @@ -9095,6 +9123,7 @@ private constructor( (nps.asKnown().getOrNull()?.validity() ?: 0) class Demat + @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val count: JsonField, private val totalValue: JsonField, @@ -9287,6 +9316,7 @@ private constructor( } class Insurance + @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val count: JsonField, private val totalValue: JsonField, @@ -9479,6 +9509,7 @@ private constructor( } class MutualFunds + @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val count: JsonField, private val totalValue: JsonField, @@ -9671,6 +9702,7 @@ private constructor( } class Nps + @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val count: JsonField, private val totalValue: JsonField, From 3f62261ae07a5de9ead2362355c234bee0b1101e Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 1 Jan 2026 23:19:39 +0000 Subject: [PATCH 22/99] feat(api): api update --- .stats.yml | 4 +- LICENSE | 2 +- README.md | 4 +- .../build.gradle.kts | 1 + .../api/client/okhttp/OkHttpClient.kt | 40 +- .../api/client/okhttp/OkHttpClientTest.kt | 44 + .../api/models/casparser/UnifiedResponse.kt | 16489 ++++++++++++---- .../models/casparser/UnifiedResponseTest.kt | 688 +- .../api/proguard/ProGuardCompatibilityTest.kt | 231 +- 9 files changed, 13410 insertions(+), 4093 deletions(-) create mode 100644 cas-parser-java-client-okhttp/src/test/kotlin/com/cas_parser/api/client/okhttp/OkHttpClientTest.kt diff --git a/.stats.yml b/.stats.yml index 06e7614..48b33b3 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 5 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-9eaed98ce5934f11e901cef376a28257d2c196bd3dba7c690babc6741a730ded.yml -openapi_spec_hash: b76e4e830c4d03ba4cf9429bb9fb9c8a +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-38618cc5c938e87eeacf4893d6a6ba4e6ef7da390e6283dc7b50b484a7b97165.yml +openapi_spec_hash: b9e439ecee904ded01aa34efdee88856 config_hash: cb5d75abef6264b5d86448caf7295afa diff --git a/LICENSE b/LICENSE index f1756ce..6bbb512 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2025 Cas Parser + Copyright 2026 Cas Parser Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.md b/README.md index eb1c0bb..15ce0f4 100644 --- a/README.md +++ b/README.md @@ -248,13 +248,13 @@ The SDK uses the standard [OkHttp logging interceptor](https://github.com/square Enable logging by setting the `CAS_PARSER_LOG` environment variable to `info`: ```sh -$ export CAS_PARSER_LOG=info +export CAS_PARSER_LOG=info ``` Or to `debug` for more verbose logging: ```sh -$ export CAS_PARSER_LOG=debug +export CAS_PARSER_LOG=debug ``` ## ProGuard and R8 diff --git a/cas-parser-java-client-okhttp/build.gradle.kts b/cas-parser-java-client-okhttp/build.gradle.kts index 115d28c..91df2a9 100644 --- a/cas-parser-java-client-okhttp/build.gradle.kts +++ b/cas-parser-java-client-okhttp/build.gradle.kts @@ -11,4 +11,5 @@ dependencies { testImplementation(kotlin("test")) testImplementation("org.assertj:assertj-core:3.25.3") + testImplementation("com.github.tomakehurst:wiremock-jre8:2.35.2") } diff --git a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/OkHttpClient.kt b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/OkHttpClient.kt index 281e1c4..eee1317 100644 --- a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/OkHttpClient.kt +++ b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/OkHttpClient.kt @@ -13,6 +13,7 @@ import java.io.IOException import java.io.InputStream import java.net.Proxy import java.time.Duration +import java.util.concurrent.CancellationException import java.util.concurrent.CompletableFuture import javax.net.ssl.HostnameVerifier import javax.net.ssl.SSLSocketFactory @@ -29,8 +30,8 @@ import okhttp3.Response import okhttp3.logging.HttpLoggingInterceptor import okio.BufferedSink -class OkHttpClient private constructor(private val okHttpClient: okhttp3.OkHttpClient) : - HttpClient { +class OkHttpClient +private constructor(@JvmSynthetic internal val okHttpClient: okhttp3.OkHttpClient) : HttpClient { override fun execute(request: HttpRequest, requestOptions: RequestOptions): HttpResponse { val call = newCall(request, requestOptions) @@ -50,20 +51,25 @@ class OkHttpClient private constructor(private val okHttpClient: okhttp3.OkHttpC ): CompletableFuture { val future = CompletableFuture() - request.body?.run { future.whenComplete { _, _ -> close() } } - - newCall(request, requestOptions) - .enqueue( - object : Callback { - override fun onResponse(call: Call, response: Response) { - future.complete(response.toResponse()) - } + val call = newCall(request, requestOptions) + call.enqueue( + object : Callback { + override fun onResponse(call: Call, response: Response) { + future.complete(response.toResponse()) + } - override fun onFailure(call: Call, e: IOException) { - future.completeExceptionally(CasParserIoException("Request failed", e)) - } + override fun onFailure(call: Call, e: IOException) { + future.completeExceptionally(CasParserIoException("Request failed", e)) } - ) + } + ) + + future.whenComplete { _, e -> + if (e is CancellationException) { + call.cancel() + } + request.body?.close() + } return future } @@ -109,19 +115,19 @@ class OkHttpClient private constructor(private val okHttpClient: okhttp3.OkHttpC val builder = Request.Builder().url(toUrl()).method(method.name, body) headers.names().forEach { name -> - headers.values(name).forEach { builder.header(name, it) } + headers.values(name).forEach { builder.addHeader(name, it) } } if ( !headers.names().contains("X-Stainless-Read-Timeout") && client.readTimeoutMillis != 0 ) { - builder.header( + builder.addHeader( "X-Stainless-Read-Timeout", Duration.ofMillis(client.readTimeoutMillis.toLong()).seconds.toString(), ) } if (!headers.names().contains("X-Stainless-Timeout") && client.callTimeoutMillis != 0) { - builder.header( + builder.addHeader( "X-Stainless-Timeout", Duration.ofMillis(client.callTimeoutMillis.toLong()).seconds.toString(), ) diff --git a/cas-parser-java-client-okhttp/src/test/kotlin/com/cas_parser/api/client/okhttp/OkHttpClientTest.kt b/cas-parser-java-client-okhttp/src/test/kotlin/com/cas_parser/api/client/okhttp/OkHttpClientTest.kt new file mode 100644 index 0000000..457b40c --- /dev/null +++ b/cas-parser-java-client-okhttp/src/test/kotlin/com/cas_parser/api/client/okhttp/OkHttpClientTest.kt @@ -0,0 +1,44 @@ +package com.cas_parser.api.client.okhttp + +import com.cas_parser.api.core.http.HttpMethod +import com.cas_parser.api.core.http.HttpRequest +import com.github.tomakehurst.wiremock.client.WireMock.* +import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo +import com.github.tomakehurst.wiremock.junit5.WireMockTest +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.parallel.ResourceLock + +@WireMockTest +@ResourceLock("https://github.com/wiremock/wiremock/issues/169") +internal class OkHttpClientTest { + + private lateinit var baseUrl: String + private lateinit var httpClient: OkHttpClient + + @BeforeEach + fun beforeEach(wmRuntimeInfo: WireMockRuntimeInfo) { + baseUrl = wmRuntimeInfo.httpBaseUrl + httpClient = OkHttpClient.builder().build() + } + + @Test + fun executeAsync_whenFutureCancelled_cancelsUnderlyingCall() { + stubFor(post(urlPathEqualTo("/something")).willReturn(ok())) + val responseFuture = + httpClient.executeAsync( + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(baseUrl) + .addPathSegment("something") + .build() + ) + val call = httpClient.okHttpClient.dispatcher.runningCalls().single() + + responseFuture.cancel(false) + + // Should have cancelled the underlying call + assertThat(call.isCanceled()).isTrue() + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/UnifiedResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/UnifiedResponse.kt index 98a9131..e64ebfb 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/UnifiedResponse.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/UnifiedResponse.kt @@ -1772,9 +1772,10 @@ private constructor( class Aif @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( - private val additionalInfo: JsonValue, + private val additionalInfo: JsonField, private val isin: JsonField, private val name: JsonField, + private val transactions: JsonField>, private val units: JsonField, private val value: JsonField, private val additionalProperties: MutableMap, @@ -1784,25 +1785,32 @@ private constructor( private constructor( @JsonProperty("additional_info") @ExcludeMissing - additionalInfo: JsonValue = JsonMissing.of(), + additionalInfo: JsonField = JsonMissing.of(), @JsonProperty("isin") @ExcludeMissing isin: JsonField = JsonMissing.of(), @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("transactions") + @ExcludeMissing + transactions: JsonField> = JsonMissing.of(), @JsonProperty("units") @ExcludeMissing units: JsonField = JsonMissing.of(), @JsonProperty("value") @ExcludeMissing value: JsonField = JsonMissing.of(), - ) : this(additionalInfo, isin, name, units, value, mutableMapOf()) + ) : this(additionalInfo, isin, name, transactions, units, value, mutableMapOf()) - /** Additional information specific to the AIF */ - @JsonProperty("additional_info") - @ExcludeMissing - fun _additionalInfo(): JsonValue = additionalInfo + /** + * Additional information specific to the AIF + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun additionalInfo(): Optional = + additionalInfo.getOptional("additional_info") /** * ISIN code of the AIF @@ -1820,6 +1828,15 @@ private constructor( */ fun name(): Optional = name.getOptional("name") + /** + * List of transactions for this holding (beta) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun transactions(): Optional> = + transactions.getOptional("transactions") + /** * Number of units held * @@ -1836,6 +1853,16 @@ private constructor( */ fun value(): Optional = value.getOptional("value") + /** + * Returns the raw JSON value of [additionalInfo]. + * + * Unlike [additionalInfo], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("additional_info") + @ExcludeMissing + fun _additionalInfo(): JsonField = additionalInfo + /** * Returns the raw JSON value of [isin]. * @@ -1852,6 +1879,16 @@ private constructor( */ @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + /** + * Returns the raw JSON value of [transactions]. + * + * Unlike [transactions], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("transactions") + @ExcludeMissing + fun _transactions(): JsonField> = transactions + /** * Returns the raw JSON value of [units]. * @@ -1889,9 +1926,10 @@ private constructor( /** A builder for [Aif]. */ class Builder internal constructor() { - private var additionalInfo: JsonValue = JsonMissing.of() + private var additionalInfo: JsonField = JsonMissing.of() private var isin: JsonField = JsonMissing.of() private var name: JsonField = JsonMissing.of() + private var transactions: JsonField>? = null private var units: JsonField = JsonMissing.of() private var value: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @@ -1901,13 +1939,24 @@ private constructor( additionalInfo = aif.additionalInfo isin = aif.isin name = aif.name + transactions = aif.transactions.map { it.toMutableList() } units = aif.units value = aif.value additionalProperties = aif.additionalProperties.toMutableMap() } /** Additional information specific to the AIF */ - fun additionalInfo(additionalInfo: JsonValue) = apply { + fun additionalInfo(additionalInfo: AdditionalInfo) = + additionalInfo(JsonField.of(additionalInfo)) + + /** + * Sets [Builder.additionalInfo] to an arbitrary JSON value. + * + * You should usually call [Builder.additionalInfo] with a well-typed + * [AdditionalInfo] value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun additionalInfo(additionalInfo: JsonField) = apply { this.additionalInfo = additionalInfo } @@ -1935,6 +1984,33 @@ private constructor( */ fun name(name: JsonField) = apply { this.name = name } + /** List of transactions for this holding (beta) */ + fun transactions(transactions: List) = + transactions(JsonField.of(transactions)) + + /** + * Sets [Builder.transactions] to an arbitrary JSON value. + * + * You should usually call [Builder.transactions] with a well-typed + * `List` value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun transactions(transactions: JsonField>) = apply { + this.transactions = transactions.map { it.toMutableList() } + } + + /** + * Adds a single [Transaction] to [transactions]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addTransaction(transaction: Transaction) = apply { + transactions = + (transactions ?: JsonField.of(mutableListOf())).also { + checkKnown("transactions", it).add(transaction) + } + } + /** Number of units held */ fun units(units: Float) = units(JsonField.of(units)) @@ -1991,6 +2067,7 @@ private constructor( additionalInfo, isin, name, + (transactions ?: JsonMissing.of()).map { it.toImmutable() }, units, value, additionalProperties.toMutableMap(), @@ -2004,8 +2081,10 @@ private constructor( return@apply } + additionalInfo().ifPresent { it.validate() } isin() name() + transactions().ifPresent { it.forEach { it.validate() } } units() value() validated = true @@ -2027,650 +2106,1530 @@ private constructor( */ @JvmSynthetic internal fun validity(): Int = - (if (isin.asKnown().isPresent) 1 else 0) + + (additionalInfo.asKnown().getOrNull()?.validity() ?: 0) + + (if (isin.asKnown().isPresent) 1 else 0) + (if (name.asKnown().isPresent) 1 else 0) + + (transactions.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + (if (units.asKnown().isPresent) 1 else 0) + (if (value.asKnown().isPresent) 1 else 0) - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + /** Additional information specific to the AIF */ + class AdditionalInfo + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val closeUnits: JsonField, + private val openUnits: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("close_units") + @ExcludeMissing + closeUnits: JsonField = JsonMissing.of(), + @JsonProperty("open_units") + @ExcludeMissing + openUnits: JsonField = JsonMissing.of(), + ) : this(closeUnits, openUnits, mutableMapOf()) - return other is Aif && - additionalInfo == other.additionalInfo && - isin == other.isin && - name == other.name && - units == other.units && - value == other.value && - additionalProperties == other.additionalProperties - } + /** + * Closing balance units for the statement period (beta) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun closeUnits(): Optional = closeUnits.getOptional("close_units") - private val hashCode: Int by lazy { - Objects.hash(additionalInfo, isin, name, units, value, additionalProperties) - } + /** + * Opening balance units for the statement period (beta) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun openUnits(): Optional = openUnits.getOptional("open_units") - override fun hashCode(): Int = hashCode + /** + * Returns the raw JSON value of [closeUnits]. + * + * Unlike [closeUnits], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("close_units") + @ExcludeMissing + fun _closeUnits(): JsonField = closeUnits - override fun toString() = - "Aif{additionalInfo=$additionalInfo, isin=$isin, name=$name, units=$units, value=$value, additionalProperties=$additionalProperties}" - } + /** + * Returns the raw JSON value of [openUnits]. + * + * Unlike [openUnits], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("open_units") + @ExcludeMissing + fun _openUnits(): JsonField = openUnits - class CorporateBond - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val additionalInfo: JsonValue, - private val isin: JsonField, - private val name: JsonField, - private val units: JsonField, - private val value: JsonField, - private val additionalProperties: MutableMap, - ) { + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } - @JsonCreator - private constructor( - @JsonProperty("additional_info") - @ExcludeMissing - additionalInfo: JsonValue = JsonMissing.of(), - @JsonProperty("isin") + @JsonAnyGetter @ExcludeMissing - isin: JsonField = JsonMissing.of(), - @JsonProperty("name") - @ExcludeMissing - name: JsonField = JsonMissing.of(), - @JsonProperty("units") - @ExcludeMissing - units: JsonField = JsonMissing.of(), - @JsonProperty("value") - @ExcludeMissing - value: JsonField = JsonMissing.of(), - ) : this(additionalInfo, isin, name, units, value, mutableMapOf()) + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) - /** Additional information specific to the corporate bond */ - @JsonProperty("additional_info") - @ExcludeMissing - fun _additionalInfo(): JsonValue = additionalInfo + fun toBuilder() = Builder().from(this) - /** - * ISIN code of the corporate bond - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun isin(): Optional = isin.getOptional("isin") + companion object { - /** - * Name of the corporate bond - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun name(): Optional = name.getOptional("name") + /** + * Returns a mutable builder for constructing an instance of + * [AdditionalInfo]. + */ + @JvmStatic fun builder() = Builder() + } - /** - * Number of units held - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun units(): Optional = units.getOptional("units") + /** A builder for [AdditionalInfo]. */ + class Builder internal constructor() { - /** - * Current market value of the holding - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun value(): Optional = value.getOptional("value") + private var closeUnits: JsonField = JsonMissing.of() + private var openUnits: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = + mutableMapOf() - /** - * Returns the raw JSON value of [isin]. - * - * Unlike [isin], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("isin") @ExcludeMissing fun _isin(): JsonField = isin + @JvmSynthetic + internal fun from(additionalInfo: AdditionalInfo) = apply { + closeUnits = additionalInfo.closeUnits + openUnits = additionalInfo.openUnits + additionalProperties = + additionalInfo.additionalProperties.toMutableMap() + } - /** - * Returns the raw JSON value of [name]. - * - * Unlike [name], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + /** Closing balance units for the statement period (beta) */ + fun closeUnits(closeUnits: Float?) = + closeUnits(JsonField.ofNullable(closeUnits)) - /** - * Returns the raw JSON value of [units]. - * - * Unlike [units], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("units") @ExcludeMissing fun _units(): JsonField = units + /** + * Alias for [Builder.closeUnits]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun closeUnits(closeUnits: Float) = closeUnits(closeUnits as Float?) - /** - * Returns the raw JSON value of [value]. - * - * Unlike [value], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("value") @ExcludeMissing fun _value(): JsonField = value + /** + * Alias for calling [Builder.closeUnits] with `closeUnits.orElse(null)`. + */ + fun closeUnits(closeUnits: Optional) = + closeUnits(closeUnits.getOrNull()) - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } + /** + * Sets [Builder.closeUnits] to an arbitrary JSON value. + * + * You should usually call [Builder.closeUnits] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun closeUnits(closeUnits: JsonField) = apply { + this.closeUnits = closeUnits + } - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) + /** Opening balance units for the statement period (beta) */ + fun openUnits(openUnits: Float?) = + openUnits(JsonField.ofNullable(openUnits)) - fun toBuilder() = Builder().from(this) + /** + * Alias for [Builder.openUnits]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun openUnits(openUnits: Float) = openUnits(openUnits as Float?) - companion object { + /** Alias for calling [Builder.openUnits] with `openUnits.orElse(null)`. */ + fun openUnits(openUnits: Optional) = openUnits(openUnits.getOrNull()) - /** - * Returns a mutable builder for constructing an instance of [CorporateBond]. - */ - @JvmStatic fun builder() = Builder() - } + /** + * Sets [Builder.openUnits] to an arbitrary JSON value. + * + * You should usually call [Builder.openUnits] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun openUnits(openUnits: JsonField) = apply { + this.openUnits = openUnits + } - /** A builder for [CorporateBond]. */ - class Builder internal constructor() { + fun additionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } - private var additionalInfo: JsonValue = JsonMissing.of() - private var isin: JsonField = JsonMissing.of() - private var name: JsonField = JsonMissing.of() - private var units: JsonField = JsonMissing.of() - private var value: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } - @JvmSynthetic - internal fun from(corporateBond: CorporateBond) = apply { - additionalInfo = corporateBond.additionalInfo - isin = corporateBond.isin - name = corporateBond.name - units = corporateBond.units - value = corporateBond.value - additionalProperties = corporateBond.additionalProperties.toMutableMap() + 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 [AdditionalInfo]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): AdditionalInfo = + AdditionalInfo( + closeUnits, + openUnits, + additionalProperties.toMutableMap(), + ) } - /** Additional information specific to the corporate bond */ - fun additionalInfo(additionalInfo: JsonValue) = apply { - this.additionalInfo = additionalInfo + private var validated: Boolean = false + + fun validate(): AdditionalInfo = apply { + if (validated) { + return@apply + } + + closeUnits() + openUnits() + validated = true } - /** ISIN code of the corporate bond */ - fun isin(isin: String) = isin(JsonField.of(isin)) + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + false + } /** - * Sets [Builder.isin] to an arbitrary JSON value. + * Returns a score indicating how many valid values are contained in this object + * recursively. * - * You should usually call [Builder.isin] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. + * Used for best match union deserialization. */ - fun isin(isin: JsonField) = apply { this.isin = isin } + @JvmSynthetic + internal fun validity(): Int = + (if (closeUnits.asKnown().isPresent) 1 else 0) + + (if (openUnits.asKnown().isPresent) 1 else 0) - /** Name of the corporate bond */ - fun name(name: String) = name(JsonField.of(name)) + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - /** - * Sets [Builder.name] to an arbitrary JSON value. + return other is AdditionalInfo && + closeUnits == other.closeUnits && + openUnits == other.openUnits && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(closeUnits, openUnits, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AdditionalInfo{closeUnits=$closeUnits, openUnits=$openUnits, additionalProperties=$additionalProperties}" + } + + /** + * Unified transaction schema for all holding types (MF folios, equities, bonds, + * etc.) + */ + class Transaction + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val additionalInfo: JsonField, + private val amount: JsonField, + private val balance: JsonField, + private val date: JsonField, + private val description: JsonField, + private val dividendRate: JsonField, + private val nav: JsonField, + private val type: JsonField, + private val units: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("additional_info") + @ExcludeMissing + additionalInfo: JsonField = JsonMissing.of(), + @JsonProperty("amount") + @ExcludeMissing + amount: JsonField = JsonMissing.of(), + @JsonProperty("balance") + @ExcludeMissing + balance: JsonField = JsonMissing.of(), + @JsonProperty("date") + @ExcludeMissing + date: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + description: JsonField = JsonMissing.of(), + @JsonProperty("dividend_rate") + @ExcludeMissing + dividendRate: JsonField = JsonMissing.of(), + @JsonProperty("nav") + @ExcludeMissing + nav: JsonField = JsonMissing.of(), + @JsonProperty("type") + @ExcludeMissing + type: JsonField = JsonMissing.of(), + @JsonProperty("units") + @ExcludeMissing + units: JsonField = JsonMissing.of(), + ) : this( + additionalInfo, + amount, + balance, + date, + description, + dividendRate, + nav, + type, + units, + mutableMapOf(), + ) + + /** + * Additional transaction-specific fields that vary by source * - * You should usually call [Builder.name] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). */ - fun name(name: JsonField) = apply { this.name = name } + fun additionalInfo(): Optional = + additionalInfo.getOptional("additional_info") - /** Number of units held */ - fun units(units: Float) = units(JsonField.of(units)) + /** + * Transaction amount in currency (computed from units × price/NAV) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun amount(): Optional = amount.getOptional("amount") /** - * Sets [Builder.units] to an arbitrary JSON value. + * Balance units after transaction * - * You should usually call [Builder.units] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). */ - fun units(units: JsonField) = apply { this.units = units } + fun balance(): Optional = balance.getOptional("balance") - /** Current market value of the holding */ - fun value(value: Float) = value(JsonField.of(value)) + /** + * Transaction date (YYYY-MM-DD) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun date(): Optional = date.getOptional("date") /** - * Sets [Builder.value] to an arbitrary JSON value. + * Transaction description/particulars * - * You should usually call [Builder.value] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). */ - fun value(value: JsonField) = apply { this.value = value } + fun description(): Optional = description.getOptional("description") - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } + /** + * Dividend rate (for DIVIDEND_PAYOUT transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun dividendRate(): Optional = dividendRate.getOptional("dividend_rate") - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } + /** + * NAV/price per unit on transaction date + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun nav(): Optional = nav.getOptional("nav") - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } + /** + * Transaction type. Possible values are PURCHASE, PURCHASE_SIP, REDEMPTION, + * SWITCH_IN, SWITCH_IN_MERGER, SWITCH_OUT, SWITCH_OUT_MERGER, DIVIDEND_PAYOUT, + * DIVIDEND_REINVEST, SEGREGATION, STAMP_DUTY_TAX, TDS_TAX, STT_TAX, MISC, + * REVERSAL, UNKNOWN. + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun type(): Optional = type.getOptional("type") - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) - } + /** + * Number of units involved in transaction + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun units(): Optional = units.getOptional("units") - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } + /** + * Returns the raw JSON value of [additionalInfo]. + * + * Unlike [additionalInfo], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("additional_info") + @ExcludeMissing + fun _additionalInfo(): JsonField = additionalInfo /** - * Returns an immutable instance of [CorporateBond]. + * Returns the raw JSON value of [amount]. * - * Further updates to this [Builder] will not mutate the returned instance. + * Unlike [amount], this method doesn't throw if the JSON field has an + * unexpected type. */ - fun build(): CorporateBond = - CorporateBond( - additionalInfo, - isin, - name, - units, - value, - additionalProperties.toMutableMap(), - ) - } + @JsonProperty("amount") @ExcludeMissing fun _amount(): JsonField = amount - private var validated: Boolean = false + /** + * Returns the raw JSON value of [balance]. + * + * Unlike [balance], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("balance") + @ExcludeMissing + fun _balance(): JsonField = balance - fun validate(): CorporateBond = apply { - if (validated) { - return@apply - } + /** + * Returns the raw JSON value of [date]. + * + * Unlike [date], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("date") @ExcludeMissing fun _date(): JsonField = date - isin() - name() - units() - value() - validated = true - } + /** + * Returns the raw JSON value of [description]. + * + * Unlike [description], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("description") + @ExcludeMissing + fun _description(): JsonField = description - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - false - } + /** + * Returns the raw JSON value of [dividendRate]. + * + * Unlike [dividendRate], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("dividend_rate") + @ExcludeMissing + fun _dividendRate(): JsonField = dividendRate - /** - * 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 (isin.asKnown().isPresent) 1 else 0) + - (if (name.asKnown().isPresent) 1 else 0) + - (if (units.asKnown().isPresent) 1 else 0) + - (if (value.asKnown().isPresent) 1 else 0) + /** + * Returns the raw JSON value of [nav]. + * + * Unlike [nav], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("nav") @ExcludeMissing fun _nav(): JsonField = nav - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + + /** + * Returns the raw JSON value of [units]. + * + * Unlike [units], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("units") @ExcludeMissing fun _units(): JsonField = units + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) } - return other is CorporateBond && - additionalInfo == other.additionalInfo && - isin == other.isin && - name == other.name && - units == other.units && - value == other.value && - additionalProperties == other.additionalProperties - } + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) - private val hashCode: Int by lazy { - Objects.hash(additionalInfo, isin, name, units, value, additionalProperties) - } + fun toBuilder() = Builder().from(this) - override fun hashCode(): Int = hashCode + companion object { - override fun toString() = - "CorporateBond{additionalInfo=$additionalInfo, isin=$isin, name=$name, units=$units, value=$value, additionalProperties=$additionalProperties}" - } + /** + * Returns a mutable builder for constructing an instance of [Transaction]. + */ + @JvmStatic fun builder() = Builder() + } - class DematMutualFund - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val additionalInfo: JsonValue, - private val isin: JsonField, - private val name: JsonField, - private val units: JsonField, - private val value: JsonField, - private val additionalProperties: MutableMap, - ) { + /** A builder for [Transaction]. */ + class Builder internal constructor() { + + private var additionalInfo: JsonField = JsonMissing.of() + private var amount: JsonField = JsonMissing.of() + private var balance: JsonField = JsonMissing.of() + private var date: JsonField = JsonMissing.of() + private var description: JsonField = JsonMissing.of() + private var dividendRate: JsonField = JsonMissing.of() + private var nav: JsonField = JsonMissing.of() + private var type: JsonField = JsonMissing.of() + private var units: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = + mutableMapOf() + + @JvmSynthetic + internal fun from(transaction: Transaction) = apply { + additionalInfo = transaction.additionalInfo + amount = transaction.amount + balance = transaction.balance + date = transaction.date + description = transaction.description + dividendRate = transaction.dividendRate + nav = transaction.nav + type = transaction.type + units = transaction.units + additionalProperties = transaction.additionalProperties.toMutableMap() + } - @JsonCreator - private constructor( - @JsonProperty("additional_info") - @ExcludeMissing - additionalInfo: JsonValue = JsonMissing.of(), - @JsonProperty("isin") - @ExcludeMissing - isin: JsonField = JsonMissing.of(), - @JsonProperty("name") - @ExcludeMissing - name: JsonField = JsonMissing.of(), - @JsonProperty("units") - @ExcludeMissing - units: JsonField = JsonMissing.of(), - @JsonProperty("value") - @ExcludeMissing - value: JsonField = JsonMissing.of(), - ) : this(additionalInfo, isin, name, units, value, mutableMapOf()) + /** Additional transaction-specific fields that vary by source */ + fun additionalInfo(additionalInfo: AdditionalInfo) = + additionalInfo(JsonField.of(additionalInfo)) - /** Additional information specific to the mutual fund */ - @JsonProperty("additional_info") - @ExcludeMissing - fun _additionalInfo(): JsonValue = additionalInfo + /** + * Sets [Builder.additionalInfo] to an arbitrary JSON value. + * + * You should usually call [Builder.additionalInfo] with a well-typed + * [AdditionalInfo] value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun additionalInfo(additionalInfo: JsonField) = apply { + this.additionalInfo = additionalInfo + } - /** - * ISIN code of the mutual fund - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun isin(): Optional = isin.getOptional("isin") + /** Transaction amount in currency (computed from units × price/NAV) */ + fun amount(amount: Float?) = amount(JsonField.ofNullable(amount)) - /** - * Name of the mutual fund - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun name(): Optional = name.getOptional("name") + /** + * Alias for [Builder.amount]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun amount(amount: Float) = amount(amount as Float?) - /** - * Number of units held - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun units(): Optional = units.getOptional("units") + /** Alias for calling [Builder.amount] with `amount.orElse(null)`. */ + fun amount(amount: Optional) = amount(amount.getOrNull()) - /** - * Current market value of the holding - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun value(): Optional = value.getOptional("value") + /** + * Sets [Builder.amount] to an arbitrary JSON value. + * + * You should usually call [Builder.amount] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun amount(amount: JsonField) = apply { this.amount = amount } - /** - * Returns the raw JSON value of [isin]. - * - * Unlike [isin], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("isin") @ExcludeMissing fun _isin(): JsonField = isin + /** Balance units after transaction */ + fun balance(balance: Float) = balance(JsonField.of(balance)) - /** - * Returns the raw JSON value of [name]. - * - * Unlike [name], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + /** + * Sets [Builder.balance] to an arbitrary JSON value. + * + * You should usually call [Builder.balance] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun balance(balance: JsonField) = apply { this.balance = balance } - /** - * Returns the raw JSON value of [units]. - * - * Unlike [units], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("units") @ExcludeMissing fun _units(): JsonField = units + /** Transaction date (YYYY-MM-DD) */ + fun date(date: LocalDate) = date(JsonField.of(date)) - /** - * Returns the raw JSON value of [value]. - * - * Unlike [value], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("value") @ExcludeMissing fun _value(): JsonField = value + /** + * Sets [Builder.date] to an arbitrary JSON value. + * + * You should usually call [Builder.date] with a well-typed [LocalDate] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun date(date: JsonField) = apply { this.date = date } - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } + /** Transaction description/particulars */ + fun description(description: String) = + description(JsonField.of(description)) - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) + /** + * Sets [Builder.description] to an arbitrary JSON value. + * + * You should usually call [Builder.description] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun description(description: JsonField) = apply { + this.description = description + } - fun toBuilder() = Builder().from(this) + /** Dividend rate (for DIVIDEND_PAYOUT transactions) */ + fun dividendRate(dividendRate: Float?) = + dividendRate(JsonField.ofNullable(dividendRate)) - companion object { + /** + * Alias for [Builder.dividendRate]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun dividendRate(dividendRate: Float) = dividendRate(dividendRate as Float?) - /** - * Returns a mutable builder for constructing an instance of [DematMutualFund]. - */ - @JvmStatic fun builder() = Builder() - } + /** + * Alias for calling [Builder.dividendRate] with + * `dividendRate.orElse(null)`. + */ + fun dividendRate(dividendRate: Optional) = + dividendRate(dividendRate.getOrNull()) - /** A builder for [DematMutualFund]. */ - class Builder internal constructor() { + /** + * Sets [Builder.dividendRate] to an arbitrary JSON value. + * + * You should usually call [Builder.dividendRate] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun dividendRate(dividendRate: JsonField) = apply { + this.dividendRate = dividendRate + } - private var additionalInfo: JsonValue = JsonMissing.of() - private var isin: JsonField = JsonMissing.of() - private var name: JsonField = JsonMissing.of() - private var units: JsonField = JsonMissing.of() - private var value: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() + /** NAV/price per unit on transaction date */ + fun nav(nav: Float?) = nav(JsonField.ofNullable(nav)) - @JvmSynthetic - internal fun from(dematMutualFund: DematMutualFund) = apply { - additionalInfo = dematMutualFund.additionalInfo - isin = dematMutualFund.isin - name = dematMutualFund.name - units = dematMutualFund.units - value = dematMutualFund.value - additionalProperties = dematMutualFund.additionalProperties.toMutableMap() - } + /** + * Alias for [Builder.nav]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun nav(nav: Float) = nav(nav as Float?) - /** Additional information specific to the mutual fund */ - fun additionalInfo(additionalInfo: JsonValue) = apply { - this.additionalInfo = additionalInfo - } + /** Alias for calling [Builder.nav] with `nav.orElse(null)`. */ + fun nav(nav: Optional) = nav(nav.getOrNull()) - /** ISIN code of the mutual fund */ - fun isin(isin: String) = isin(JsonField.of(isin)) + /** + * Sets [Builder.nav] to an arbitrary JSON value. + * + * You should usually call [Builder.nav] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun nav(nav: JsonField) = apply { this.nav = nav } - /** - * Sets [Builder.isin] to an arbitrary JSON value. - * - * You should usually call [Builder.isin] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun isin(isin: JsonField) = apply { this.isin = isin } + /** + * Transaction type. Possible values are PURCHASE, PURCHASE_SIP, REDEMPTION, + * SWITCH_IN, SWITCH_IN_MERGER, SWITCH_OUT, SWITCH_OUT_MERGER, + * DIVIDEND_PAYOUT, DIVIDEND_REINVEST, SEGREGATION, STAMP_DUTY_TAX, TDS_TAX, + * STT_TAX, MISC, REVERSAL, UNKNOWN. + */ + fun type(type: Type) = type(JsonField.of(type)) - /** Name of the mutual fund */ - fun name(name: String) = name(JsonField.of(name)) + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun type(type: JsonField) = apply { this.type = type } - /** - * Sets [Builder.name] to an arbitrary JSON value. - * - * You should usually call [Builder.name] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun name(name: JsonField) = apply { this.name = name } + /** Number of units involved in transaction */ + fun units(units: Float) = units(JsonField.of(units)) - /** Number of units held */ - fun units(units: Float) = units(JsonField.of(units)) + /** + * Sets [Builder.units] to an arbitrary JSON value. + * + * You should usually call [Builder.units] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun units(units: JsonField) = apply { this.units = units } - /** - * Sets [Builder.units] to an arbitrary JSON value. - * - * You should usually call [Builder.units] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun units(units: JsonField) = apply { this.units = units } + fun additionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } - /** Current market value of the holding */ - fun value(value: Float) = value(JsonField.of(value)) + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } - /** - * Sets [Builder.value] to an arbitrary JSON value. - * - * You should usually call [Builder.value] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun value(value: JsonField) = apply { this.value = value } + fun putAllAdditionalProperties( + additionalProperties: Map + ) = apply { this.additionalProperties.putAll(additionalProperties) } - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Transaction]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Transaction = + Transaction( + additionalInfo, + amount, + balance, + date, + description, + dividendRate, + nav, + type, + units, + additionalProperties.toMutableMap(), + ) } - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) + private var validated: Boolean = false + + fun validate(): Transaction = apply { + if (validated) { + return@apply } - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) + additionalInfo().ifPresent { it.validate() } + amount() + balance() + date() + description() + dividendRate() + nav() + type().ifPresent { it.validate() } + units() + validated = true } - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + false + } /** - * Returns an immutable instance of [DematMutualFund]. + * Returns a score indicating how many valid values are contained in this object + * recursively. * - * Further updates to this [Builder] will not mutate the returned instance. + * Used for best match union deserialization. */ - fun build(): DematMutualFund = - DematMutualFund( - additionalInfo, - isin, - name, - units, - value, - additionalProperties.toMutableMap(), + @JvmSynthetic + internal fun validity(): Int = + (additionalInfo.asKnown().getOrNull()?.validity() ?: 0) + + (if (amount.asKnown().isPresent) 1 else 0) + + (if (balance.asKnown().isPresent) 1 else 0) + + (if (date.asKnown().isPresent) 1 else 0) + + (if (description.asKnown().isPresent) 1 else 0) + + (if (dividendRate.asKnown().isPresent) 1 else 0) + + (if (nav.asKnown().isPresent) 1 else 0) + + (type.asKnown().getOrNull()?.validity() ?: 0) + + (if (units.asKnown().isPresent) 1 else 0) + + /** Additional transaction-specific fields that vary by source */ + class AdditionalInfo + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val capitalWithdrawal: JsonField, + private val credit: JsonField, + private val debit: JsonField, + private val incomeDistribution: JsonField, + private val orderNo: JsonField, + private val price: JsonField, + private val stampDuty: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("capital_withdrawal") + @ExcludeMissing + capitalWithdrawal: JsonField = JsonMissing.of(), + @JsonProperty("credit") + @ExcludeMissing + credit: JsonField = JsonMissing.of(), + @JsonProperty("debit") + @ExcludeMissing + debit: JsonField = JsonMissing.of(), + @JsonProperty("income_distribution") + @ExcludeMissing + incomeDistribution: JsonField = JsonMissing.of(), + @JsonProperty("order_no") + @ExcludeMissing + orderNo: JsonField = JsonMissing.of(), + @JsonProperty("price") + @ExcludeMissing + price: JsonField = JsonMissing.of(), + @JsonProperty("stamp_duty") + @ExcludeMissing + stampDuty: JsonField = JsonMissing.of(), + ) : this( + capitalWithdrawal, + credit, + debit, + incomeDistribution, + orderNo, + price, + stampDuty, + mutableMapOf(), ) - } - private var validated: Boolean = false + /** + * Capital withdrawal amount (CDSL MF transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun capitalWithdrawal(): Optional = + capitalWithdrawal.getOptional("capital_withdrawal") - fun validate(): DematMutualFund = apply { - if (validated) { - return@apply - } + /** + * Units credited (demat transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun credit(): Optional = credit.getOptional("credit") - isin() - name() - units() - value() - validated = true - } + /** + * Units debited (demat transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun debit(): Optional = debit.getOptional("debit") - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - false - } + /** + * Income distribution amount (CDSL MF transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun incomeDistribution(): Optional = + incomeDistribution.getOptional("income_distribution") - /** - * 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 (isin.asKnown().isPresent) 1 else 0) + - (if (name.asKnown().isPresent) 1 else 0) + - (if (units.asKnown().isPresent) 1 else 0) + - (if (value.asKnown().isPresent) 1 else 0) + /** + * Order/transaction reference number (demat transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun orderNo(): Optional = orderNo.getOptional("order_no") - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + /** + * Price per unit (NSDL/CDSL MF transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun price(): Optional = price.getOptional("price") - return other is DematMutualFund && - additionalInfo == other.additionalInfo && - isin == other.isin && - name == other.name && - units == other.units && - value == other.value && - additionalProperties == other.additionalProperties - } + /** + * Stamp duty charged + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun stampDuty(): Optional = stampDuty.getOptional("stamp_duty") - private val hashCode: Int by lazy { - Objects.hash(additionalInfo, isin, name, units, value, additionalProperties) - } + /** + * Returns the raw JSON value of [capitalWithdrawal]. + * + * Unlike [capitalWithdrawal], this method doesn't throw if the JSON field + * has an unexpected type. + */ + @JsonProperty("capital_withdrawal") + @ExcludeMissing + fun _capitalWithdrawal(): JsonField = capitalWithdrawal - override fun hashCode(): Int = hashCode + /** + * Returns the raw JSON value of [credit]. + * + * Unlike [credit], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("credit") + @ExcludeMissing + fun _credit(): JsonField = credit - override fun toString() = - "DematMutualFund{additionalInfo=$additionalInfo, isin=$isin, name=$name, units=$units, value=$value, additionalProperties=$additionalProperties}" - } + /** + * Returns the raw JSON value of [debit]. + * + * Unlike [debit], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("debit") + @ExcludeMissing + fun _debit(): JsonField = debit - class Equity - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val additionalInfo: JsonValue, - private val isin: JsonField, - private val name: JsonField, - private val units: JsonField, - private val value: JsonField, - private val additionalProperties: MutableMap, - ) { + /** + * Returns the raw JSON value of [incomeDistribution]. + * + * Unlike [incomeDistribution], this method doesn't throw if the JSON field + * has an unexpected type. + */ + @JsonProperty("income_distribution") + @ExcludeMissing + fun _incomeDistribution(): JsonField = incomeDistribution - @JsonCreator - private constructor( - @JsonProperty("additional_info") - @ExcludeMissing - additionalInfo: JsonValue = JsonMissing.of(), - @JsonProperty("isin") - @ExcludeMissing - isin: JsonField = JsonMissing.of(), - @JsonProperty("name") - @ExcludeMissing - name: JsonField = JsonMissing.of(), - @JsonProperty("units") - @ExcludeMissing - units: JsonField = JsonMissing.of(), - @JsonProperty("value") - @ExcludeMissing - value: JsonField = JsonMissing.of(), - ) : this(additionalInfo, isin, name, units, value, mutableMapOf()) + /** + * Returns the raw JSON value of [orderNo]. + * + * Unlike [orderNo], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("order_no") + @ExcludeMissing + fun _orderNo(): JsonField = orderNo - /** Additional information specific to the equity */ - @JsonProperty("additional_info") - @ExcludeMissing - fun _additionalInfo(): JsonValue = additionalInfo + /** + * Returns the raw JSON value of [price]. + * + * Unlike [price], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("price") + @ExcludeMissing + fun _price(): JsonField = price - /** - * ISIN code of the equity + /** + * Returns the raw JSON value of [stampDuty]. + * + * Unlike [stampDuty], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("stamp_duty") + @ExcludeMissing + fun _stampDuty(): JsonField = stampDuty + + @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 + * [AdditionalInfo]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AdditionalInfo]. */ + class Builder internal constructor() { + + private var capitalWithdrawal: JsonField = JsonMissing.of() + private var credit: JsonField = JsonMissing.of() + private var debit: JsonField = JsonMissing.of() + private var incomeDistribution: JsonField = JsonMissing.of() + private var orderNo: JsonField = JsonMissing.of() + private var price: JsonField = JsonMissing.of() + private var stampDuty: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = + mutableMapOf() + + @JvmSynthetic + internal fun from(additionalInfo: AdditionalInfo) = apply { + capitalWithdrawal = additionalInfo.capitalWithdrawal + credit = additionalInfo.credit + debit = additionalInfo.debit + incomeDistribution = additionalInfo.incomeDistribution + orderNo = additionalInfo.orderNo + price = additionalInfo.price + stampDuty = additionalInfo.stampDuty + additionalProperties = + additionalInfo.additionalProperties.toMutableMap() + } + + /** Capital withdrawal amount (CDSL MF transactions) */ + fun capitalWithdrawal(capitalWithdrawal: Float) = + capitalWithdrawal(JsonField.of(capitalWithdrawal)) + + /** + * Sets [Builder.capitalWithdrawal] to an arbitrary JSON value. + * + * You should usually call [Builder.capitalWithdrawal] with a well-typed + * [Float] value instead. This method is primarily for setting the field + * to an undocumented or not yet supported value. + */ + fun capitalWithdrawal(capitalWithdrawal: JsonField) = apply { + this.capitalWithdrawal = capitalWithdrawal + } + + /** Units credited (demat transactions) */ + fun credit(credit: Float) = credit(JsonField.of(credit)) + + /** + * Sets [Builder.credit] to an arbitrary JSON value. + * + * You should usually call [Builder.credit] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun credit(credit: JsonField) = apply { this.credit = credit } + + /** Units debited (demat transactions) */ + fun debit(debit: Float) = debit(JsonField.of(debit)) + + /** + * Sets [Builder.debit] to an arbitrary JSON value. + * + * You should usually call [Builder.debit] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun debit(debit: JsonField) = apply { this.debit = debit } + + /** Income distribution amount (CDSL MF transactions) */ + fun incomeDistribution(incomeDistribution: Float) = + incomeDistribution(JsonField.of(incomeDistribution)) + + /** + * Sets [Builder.incomeDistribution] to an arbitrary JSON value. + * + * You should usually call [Builder.incomeDistribution] with a + * well-typed [Float] value instead. This method is primarily for + * setting the field to an undocumented or not yet supported value. + */ + fun incomeDistribution(incomeDistribution: JsonField) = apply { + this.incomeDistribution = incomeDistribution + } + + /** Order/transaction reference number (demat transactions) */ + fun orderNo(orderNo: String) = orderNo(JsonField.of(orderNo)) + + /** + * Sets [Builder.orderNo] to an arbitrary JSON value. + * + * You should usually call [Builder.orderNo] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun orderNo(orderNo: JsonField) = apply { + this.orderNo = orderNo + } + + /** Price per unit (NSDL/CDSL MF transactions) */ + fun price(price: Float) = price(JsonField.of(price)) + + /** + * Sets [Builder.price] to an arbitrary JSON value. + * + * You should usually call [Builder.price] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun price(price: JsonField) = apply { this.price = price } + + /** Stamp duty charged */ + fun stampDuty(stampDuty: Float) = stampDuty(JsonField.of(stampDuty)) + + /** + * Sets [Builder.stampDuty] to an arbitrary JSON value. + * + * You should usually call [Builder.stampDuty] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun stampDuty(stampDuty: JsonField) = apply { + this.stampDuty = stampDuty + } + + 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 [AdditionalInfo]. + * + * Further updates to this [Builder] will not mutate the returned + * instance. + */ + fun build(): AdditionalInfo = + AdditionalInfo( + capitalWithdrawal, + credit, + debit, + incomeDistribution, + orderNo, + price, + stampDuty, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): AdditionalInfo = apply { + if (validated) { + return@apply + } + + capitalWithdrawal() + credit() + debit() + incomeDistribution() + orderNo() + price() + stampDuty() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (capitalWithdrawal.asKnown().isPresent) 1 else 0) + + (if (credit.asKnown().isPresent) 1 else 0) + + (if (debit.asKnown().isPresent) 1 else 0) + + (if (incomeDistribution.asKnown().isPresent) 1 else 0) + + (if (orderNo.asKnown().isPresent) 1 else 0) + + (if (price.asKnown().isPresent) 1 else 0) + + (if (stampDuty.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AdditionalInfo && + capitalWithdrawal == other.capitalWithdrawal && + credit == other.credit && + debit == other.debit && + incomeDistribution == other.incomeDistribution && + orderNo == other.orderNo && + price == other.price && + stampDuty == other.stampDuty && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + capitalWithdrawal, + credit, + debit, + incomeDistribution, + orderNo, + price, + stampDuty, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AdditionalInfo{capitalWithdrawal=$capitalWithdrawal, credit=$credit, debit=$debit, incomeDistribution=$incomeDistribution, orderNo=$orderNo, price=$price, stampDuty=$stampDuty, additionalProperties=$additionalProperties}" + } + + /** + * Transaction type. Possible values are PURCHASE, PURCHASE_SIP, REDEMPTION, + * SWITCH_IN, SWITCH_IN_MERGER, SWITCH_OUT, SWITCH_OUT_MERGER, DIVIDEND_PAYOUT, + * DIVIDEND_REINVEST, SEGREGATION, STAMP_DUTY_TAX, TDS_TAX, STT_TAX, MISC, + * REVERSAL, UNKNOWN. + */ + class Type + @JsonCreator + private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data + * that doesn't match any known member, and you want to know that value. For + * example, if the SDK is on an older version than the API, then the API may + * respond with new members that the SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue + fun _value(): JsonField = value + + companion object { + + @JvmField val PURCHASE = of("PURCHASE") + + @JvmField val PURCHASE_SIP = of("PURCHASE_SIP") + + @JvmField val REDEMPTION = of("REDEMPTION") + + @JvmField val SWITCH_IN = of("SWITCH_IN") + + @JvmField val SWITCH_IN_MERGER = of("SWITCH_IN_MERGER") + + @JvmField val SWITCH_OUT = of("SWITCH_OUT") + + @JvmField val SWITCH_OUT_MERGER = of("SWITCH_OUT_MERGER") + + @JvmField val DIVIDEND_PAYOUT = of("DIVIDEND_PAYOUT") + + @JvmField val DIVIDEND_REINVEST = of("DIVIDEND_REINVEST") + + @JvmField val SEGREGATION = of("SEGREGATION") + + @JvmField val STAMP_DUTY_TAX = of("STAMP_DUTY_TAX") + + @JvmField val TDS_TAX = of("TDS_TAX") + + @JvmField val STT_TAX = of("STT_TAX") + + @JvmField val MISC = of("MISC") + + @JvmField val REVERSAL = of("REVERSAL") + + @JvmField val UNKNOWN = of("UNKNOWN") + + @JvmStatic fun of(value: String) = Type(JsonField.of(value)) + } + + /** An enum containing [Type]'s known values. */ + enum class Known { + PURCHASE, + PURCHASE_SIP, + REDEMPTION, + SWITCH_IN, + SWITCH_IN_MERGER, + SWITCH_OUT, + SWITCH_OUT_MERGER, + DIVIDEND_PAYOUT, + DIVIDEND_REINVEST, + SEGREGATION, + STAMP_DUTY_TAX, + TDS_TAX, + STT_TAX, + MISC, + REVERSAL, + UNKNOWN, + } + + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [Type] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For + * example, if the SDK is on an older version than the API, then the API + * may respond with new members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + PURCHASE, + PURCHASE_SIP, + REDEMPTION, + SWITCH_IN, + SWITCH_IN_MERGER, + SWITCH_OUT, + SWITCH_OUT_MERGER, + DIVIDEND_PAYOUT, + DIVIDEND_REINVEST, + SEGREGATION, + STAMP_DUTY_TAX, + TDS_TAX, + STT_TAX, + MISC, + REVERSAL, + UNKNOWN, + /** + * An enum member indicating that [Type] was instantiated with an + * unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always + * known or if you want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + PURCHASE -> Value.PURCHASE + PURCHASE_SIP -> Value.PURCHASE_SIP + REDEMPTION -> Value.REDEMPTION + SWITCH_IN -> Value.SWITCH_IN + SWITCH_IN_MERGER -> Value.SWITCH_IN_MERGER + SWITCH_OUT -> Value.SWITCH_OUT + SWITCH_OUT_MERGER -> Value.SWITCH_OUT_MERGER + DIVIDEND_PAYOUT -> Value.DIVIDEND_PAYOUT + DIVIDEND_REINVEST -> Value.DIVIDEND_REINVEST + SEGREGATION -> Value.SEGREGATION + STAMP_DUTY_TAX -> Value.STAMP_DUTY_TAX + TDS_TAX -> Value.TDS_TAX + STT_TAX -> Value.STT_TAX + MISC -> Value.MISC + REVERSAL -> Value.REVERSAL + UNKNOWN -> Value.UNKNOWN + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always + * known and don't want to throw for the unknown case. + * + * @throws CasParserInvalidDataException if this class instance's value is a + * not a known member. + */ + fun known(): Known = + when (this) { + PURCHASE -> Known.PURCHASE + PURCHASE_SIP -> Known.PURCHASE_SIP + REDEMPTION -> Known.REDEMPTION + SWITCH_IN -> Known.SWITCH_IN + SWITCH_IN_MERGER -> Known.SWITCH_IN_MERGER + SWITCH_OUT -> Known.SWITCH_OUT + SWITCH_OUT_MERGER -> Known.SWITCH_OUT_MERGER + DIVIDEND_PAYOUT -> Known.DIVIDEND_PAYOUT + DIVIDEND_REINVEST -> Known.DIVIDEND_REINVEST + SEGREGATION -> Known.SEGREGATION + STAMP_DUTY_TAX -> Known.STAMP_DUTY_TAX + TDS_TAX -> Known.TDS_TAX + STT_TAX -> Known.STT_TAX + MISC -> Known.MISC + REVERSAL -> Known.REVERSAL + UNKNOWN -> Known.UNKNOWN + else -> throw CasParserInvalidDataException("Unknown Type: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily + * for debugging and generally doesn't throw. + * + * @throws CasParserInvalidDataException if this class instance's value does + * not have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CasParserInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): Type = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Type && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Transaction && + additionalInfo == other.additionalInfo && + amount == other.amount && + balance == other.balance && + date == other.date && + description == other.description && + dividendRate == other.dividendRate && + nav == other.nav && + type == other.type && + units == other.units && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + additionalInfo, + amount, + balance, + date, + description, + dividendRate, + nav, + type, + units, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Transaction{additionalInfo=$additionalInfo, amount=$amount, balance=$balance, date=$date, description=$description, dividendRate=$dividendRate, nav=$nav, type=$type, units=$units, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Aif && + additionalInfo == other.additionalInfo && + isin == other.isin && + name == other.name && + transactions == other.transactions && + units == other.units && + value == other.value && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + additionalInfo, + isin, + name, + transactions, + units, + value, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Aif{additionalInfo=$additionalInfo, isin=$isin, name=$name, transactions=$transactions, units=$units, value=$value, additionalProperties=$additionalProperties}" + } + + class CorporateBond + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val additionalInfo: JsonField, + private val isin: JsonField, + private val name: JsonField, + private val transactions: JsonField>, + private val units: JsonField, + private val value: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("additional_info") + @ExcludeMissing + additionalInfo: JsonField = JsonMissing.of(), + @JsonProperty("isin") + @ExcludeMissing + isin: JsonField = JsonMissing.of(), + @JsonProperty("name") + @ExcludeMissing + name: JsonField = JsonMissing.of(), + @JsonProperty("transactions") + @ExcludeMissing + transactions: JsonField> = JsonMissing.of(), + @JsonProperty("units") + @ExcludeMissing + units: JsonField = JsonMissing.of(), + @JsonProperty("value") + @ExcludeMissing + value: JsonField = JsonMissing.of(), + ) : this(additionalInfo, isin, name, transactions, units, value, mutableMapOf()) + + /** + * Additional information specific to the corporate bond + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun additionalInfo(): Optional = + additionalInfo.getOptional("additional_info") + + /** + * ISIN code of the corporate bond * * @throws CasParserInvalidDataException if the JSON field has an unexpected type * (e.g. if the server responded with an unexpected value). @@ -2678,13 +3637,22 @@ private constructor( fun isin(): Optional = isin.getOptional("isin") /** - * Name of the equity + * Name of the corporate bond * * @throws CasParserInvalidDataException if the JSON field has an unexpected type * (e.g. if the server responded with an unexpected value). */ fun name(): Optional = name.getOptional("name") + /** + * List of transactions for this holding (beta) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun transactions(): Optional> = + transactions.getOptional("transactions") + /** * Number of units held * @@ -2701,6 +3669,16 @@ private constructor( */ fun value(): Optional = value.getOptional("value") + /** + * Returns the raw JSON value of [additionalInfo]. + * + * Unlike [additionalInfo], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("additional_info") + @ExcludeMissing + fun _additionalInfo(): JsonField = additionalInfo + /** * Returns the raw JSON value of [isin]. * @@ -2717,6 +3695,16 @@ private constructor( */ @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + /** + * Returns the raw JSON value of [transactions]. + * + * Unlike [transactions], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("transactions") + @ExcludeMissing + fun _transactions(): JsonField> = transactions + /** * Returns the raw JSON value of [units]. * @@ -2747,36 +3735,50 @@ private constructor( companion object { - /** Returns a mutable builder for constructing an instance of [Equity]. */ + /** + * Returns a mutable builder for constructing an instance of [CorporateBond]. + */ @JvmStatic fun builder() = Builder() } - /** A builder for [Equity]. */ + /** A builder for [CorporateBond]. */ class Builder internal constructor() { - private var additionalInfo: JsonValue = JsonMissing.of() + private var additionalInfo: JsonField = JsonMissing.of() private var isin: JsonField = JsonMissing.of() private var name: JsonField = JsonMissing.of() + private var transactions: JsonField>? = null private var units: JsonField = JsonMissing.of() private var value: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(equity: Equity) = apply { - additionalInfo = equity.additionalInfo - isin = equity.isin - name = equity.name - units = equity.units - value = equity.value - additionalProperties = equity.additionalProperties.toMutableMap() + internal fun from(corporateBond: CorporateBond) = apply { + additionalInfo = corporateBond.additionalInfo + isin = corporateBond.isin + name = corporateBond.name + transactions = corporateBond.transactions.map { it.toMutableList() } + units = corporateBond.units + value = corporateBond.value + additionalProperties = corporateBond.additionalProperties.toMutableMap() } - /** Additional information specific to the equity */ - fun additionalInfo(additionalInfo: JsonValue) = apply { + /** Additional information specific to the corporate bond */ + fun additionalInfo(additionalInfo: AdditionalInfo) = + additionalInfo(JsonField.of(additionalInfo)) + + /** + * Sets [Builder.additionalInfo] to an arbitrary JSON value. + * + * You should usually call [Builder.additionalInfo] with a well-typed + * [AdditionalInfo] value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun additionalInfo(additionalInfo: JsonField) = apply { this.additionalInfo = additionalInfo } - /** ISIN code of the equity */ + /** ISIN code of the corporate bond */ fun isin(isin: String) = isin(JsonField.of(isin)) /** @@ -2788,7 +3790,7 @@ private constructor( */ fun isin(isin: JsonField) = apply { this.isin = isin } - /** Name of the equity */ + /** Name of the corporate bond */ fun name(name: String) = name(JsonField.of(name)) /** @@ -2800,6 +3802,33 @@ private constructor( */ fun name(name: JsonField) = apply { this.name = name } + /** List of transactions for this holding (beta) */ + fun transactions(transactions: List) = + transactions(JsonField.of(transactions)) + + /** + * Sets [Builder.transactions] to an arbitrary JSON value. + * + * You should usually call [Builder.transactions] with a well-typed + * `List` value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun transactions(transactions: JsonField>) = apply { + this.transactions = transactions.map { it.toMutableList() } + } + + /** + * Adds a single [Transaction] to [transactions]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addTransaction(transaction: Transaction) = apply { + transactions = + (transactions ?: JsonField.of(mutableListOf())).also { + checkKnown("transactions", it).add(transaction) + } + } + /** Number of units held */ fun units(units: Float) = units(JsonField.of(units)) @@ -2847,15 +3876,16 @@ private constructor( } /** - * Returns an immutable instance of [Equity]. + * Returns an immutable instance of [CorporateBond]. * * Further updates to this [Builder] will not mutate the returned instance. */ - fun build(): Equity = - Equity( + fun build(): CorporateBond = + CorporateBond( additionalInfo, isin, name, + (transactions ?: JsonMissing.of()).map { it.toImmutable() }, units, value, additionalProperties.toMutableMap(), @@ -2864,13 +3894,15 @@ private constructor( private var validated: Boolean = false - fun validate(): Equity = apply { + fun validate(): CorporateBond = apply { if (validated) { return@apply } + additionalInfo().ifPresent { it.validate() } isin() name() + transactions().ifPresent { it.forEach { it.validate() } } units() value() validated = true @@ -2892,3571 +3924,10819 @@ private constructor( */ @JvmSynthetic internal fun validity(): Int = - (if (isin.asKnown().isPresent) 1 else 0) + + (additionalInfo.asKnown().getOrNull()?.validity() ?: 0) + + (if (isin.asKnown().isPresent) 1 else 0) + (if (name.asKnown().isPresent) 1 else 0) + + (transactions.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + (if (units.asKnown().isPresent) 1 else 0) + (if (value.asKnown().isPresent) 1 else 0) - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + /** Additional information specific to the corporate bond */ + class AdditionalInfo + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val closeUnits: JsonField, + private val openUnits: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("close_units") + @ExcludeMissing + closeUnits: JsonField = JsonMissing.of(), + @JsonProperty("open_units") + @ExcludeMissing + openUnits: JsonField = JsonMissing.of(), + ) : this(closeUnits, openUnits, mutableMapOf()) - return other is Equity && - additionalInfo == other.additionalInfo && - isin == other.isin && - name == other.name && - units == other.units && - value == other.value && - additionalProperties == other.additionalProperties - } + /** + * Closing balance units for the statement period (beta) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun closeUnits(): Optional = closeUnits.getOptional("close_units") - private val hashCode: Int by lazy { - Objects.hash(additionalInfo, isin, name, units, value, additionalProperties) - } + /** + * Opening balance units for the statement period (beta) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun openUnits(): Optional = openUnits.getOptional("open_units") - override fun hashCode(): Int = hashCode + /** + * Returns the raw JSON value of [closeUnits]. + * + * Unlike [closeUnits], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("close_units") + @ExcludeMissing + fun _closeUnits(): JsonField = closeUnits - override fun toString() = - "Equity{additionalInfo=$additionalInfo, isin=$isin, name=$name, units=$units, value=$value, additionalProperties=$additionalProperties}" - } + /** + * Returns the raw JSON value of [openUnits]. + * + * Unlike [openUnits], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("open_units") + @ExcludeMissing + fun _openUnits(): JsonField = openUnits - class GovernmentSecurity - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val additionalInfo: JsonValue, - private val isin: JsonField, - private val name: JsonField, - private val units: JsonField, - private val value: JsonField, - private val additionalProperties: MutableMap, - ) { + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } - @JsonCreator - private constructor( - @JsonProperty("additional_info") + @JsonAnyGetter @ExcludeMissing - additionalInfo: JsonValue = JsonMissing.of(), - @JsonProperty("isin") - @ExcludeMissing - isin: JsonField = JsonMissing.of(), - @JsonProperty("name") - @ExcludeMissing - name: JsonField = JsonMissing.of(), - @JsonProperty("units") - @ExcludeMissing - units: JsonField = JsonMissing.of(), - @JsonProperty("value") - @ExcludeMissing - value: JsonField = JsonMissing.of(), - ) : this(additionalInfo, isin, name, units, value, mutableMapOf()) + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) - /** Additional information specific to the government security */ - @JsonProperty("additional_info") - @ExcludeMissing - fun _additionalInfo(): JsonValue = additionalInfo + fun toBuilder() = Builder().from(this) - /** - * ISIN code of the government security - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun isin(): Optional = isin.getOptional("isin") + companion object { - /** - * Name of the government security - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun name(): Optional = name.getOptional("name") + /** + * Returns a mutable builder for constructing an instance of + * [AdditionalInfo]. + */ + @JvmStatic fun builder() = Builder() + } - /** - * Number of units held - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun units(): Optional = units.getOptional("units") + /** A builder for [AdditionalInfo]. */ + class Builder internal constructor() { - /** - * Current market value of the holding - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun value(): Optional = value.getOptional("value") + private var closeUnits: JsonField = JsonMissing.of() + private var openUnits: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = + mutableMapOf() - /** - * Returns the raw JSON value of [isin]. - * - * Unlike [isin], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("isin") @ExcludeMissing fun _isin(): JsonField = isin + @JvmSynthetic + internal fun from(additionalInfo: AdditionalInfo) = apply { + closeUnits = additionalInfo.closeUnits + openUnits = additionalInfo.openUnits + additionalProperties = + additionalInfo.additionalProperties.toMutableMap() + } - /** - * Returns the raw JSON value of [name]. - * - * Unlike [name], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + /** Closing balance units for the statement period (beta) */ + fun closeUnits(closeUnits: Float?) = + closeUnits(JsonField.ofNullable(closeUnits)) - /** - * Returns the raw JSON value of [units]. - * - * Unlike [units], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("units") @ExcludeMissing fun _units(): JsonField = units + /** + * Alias for [Builder.closeUnits]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun closeUnits(closeUnits: Float) = closeUnits(closeUnits as Float?) - /** - * Returns the raw JSON value of [value]. - * - * Unlike [value], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("value") @ExcludeMissing fun _value(): JsonField = value + /** + * Alias for calling [Builder.closeUnits] with `closeUnits.orElse(null)`. + */ + fun closeUnits(closeUnits: Optional) = + closeUnits(closeUnits.getOrNull()) - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } + /** + * Sets [Builder.closeUnits] to an arbitrary JSON value. + * + * You should usually call [Builder.closeUnits] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun closeUnits(closeUnits: JsonField) = apply { + this.closeUnits = closeUnits + } - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) + /** Opening balance units for the statement period (beta) */ + fun openUnits(openUnits: Float?) = + openUnits(JsonField.ofNullable(openUnits)) - fun toBuilder() = Builder().from(this) + /** + * Alias for [Builder.openUnits]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun openUnits(openUnits: Float) = openUnits(openUnits as Float?) - companion object { + /** Alias for calling [Builder.openUnits] with `openUnits.orElse(null)`. */ + fun openUnits(openUnits: Optional) = openUnits(openUnits.getOrNull()) - /** - * Returns a mutable builder for constructing an instance of - * [GovernmentSecurity]. - */ - @JvmStatic fun builder() = Builder() - } + /** + * Sets [Builder.openUnits] to an arbitrary JSON value. + * + * You should usually call [Builder.openUnits] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun openUnits(openUnits: JsonField) = apply { + this.openUnits = openUnits + } - /** A builder for [GovernmentSecurity]. */ - class Builder internal constructor() { + fun additionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } - private var additionalInfo: JsonValue = JsonMissing.of() - private var isin: JsonField = JsonMissing.of() - private var name: JsonField = JsonMissing.of() - private var units: JsonField = JsonMissing.of() - private var value: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } - @JvmSynthetic - internal fun from(governmentSecurity: GovernmentSecurity) = apply { - additionalInfo = governmentSecurity.additionalInfo - isin = governmentSecurity.isin - name = governmentSecurity.name - units = governmentSecurity.units - value = governmentSecurity.value - additionalProperties = - governmentSecurity.additionalProperties.toMutableMap() + 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 [AdditionalInfo]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): AdditionalInfo = + AdditionalInfo( + closeUnits, + openUnits, + additionalProperties.toMutableMap(), + ) } - /** Additional information specific to the government security */ - fun additionalInfo(additionalInfo: JsonValue) = apply { - this.additionalInfo = additionalInfo + private var validated: Boolean = false + + fun validate(): AdditionalInfo = apply { + if (validated) { + return@apply + } + + closeUnits() + openUnits() + validated = true } - /** ISIN code of the government security */ - fun isin(isin: String) = isin(JsonField.of(isin)) + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + false + } /** - * Sets [Builder.isin] to an arbitrary JSON value. + * Returns a score indicating how many valid values are contained in this object + * recursively. * - * You should usually call [Builder.isin] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. + * Used for best match union deserialization. */ - fun isin(isin: JsonField) = apply { this.isin = isin } + @JvmSynthetic + internal fun validity(): Int = + (if (closeUnits.asKnown().isPresent) 1 else 0) + + (if (openUnits.asKnown().isPresent) 1 else 0) - /** Name of the government security */ - fun name(name: String) = name(JsonField.of(name)) + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AdditionalInfo && + closeUnits == other.closeUnits && + openUnits == other.openUnits && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(closeUnits, openUnits, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AdditionalInfo{closeUnits=$closeUnits, openUnits=$openUnits, additionalProperties=$additionalProperties}" + } + + /** + * Unified transaction schema for all holding types (MF folios, equities, bonds, + * etc.) + */ + class Transaction + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val additionalInfo: JsonField, + private val amount: JsonField, + private val balance: JsonField, + private val date: JsonField, + private val description: JsonField, + private val dividendRate: JsonField, + private val nav: JsonField, + private val type: JsonField, + private val units: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("additional_info") + @ExcludeMissing + additionalInfo: JsonField = JsonMissing.of(), + @JsonProperty("amount") + @ExcludeMissing + amount: JsonField = JsonMissing.of(), + @JsonProperty("balance") + @ExcludeMissing + balance: JsonField = JsonMissing.of(), + @JsonProperty("date") + @ExcludeMissing + date: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + description: JsonField = JsonMissing.of(), + @JsonProperty("dividend_rate") + @ExcludeMissing + dividendRate: JsonField = JsonMissing.of(), + @JsonProperty("nav") + @ExcludeMissing + nav: JsonField = JsonMissing.of(), + @JsonProperty("type") + @ExcludeMissing + type: JsonField = JsonMissing.of(), + @JsonProperty("units") + @ExcludeMissing + units: JsonField = JsonMissing.of(), + ) : this( + additionalInfo, + amount, + balance, + date, + description, + dividendRate, + nav, + type, + units, + mutableMapOf(), + ) /** - * Sets [Builder.name] to an arbitrary JSON value. + * Additional transaction-specific fields that vary by source * - * You should usually call [Builder.name] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). */ - fun name(name: JsonField) = apply { this.name = name } + fun additionalInfo(): Optional = + additionalInfo.getOptional("additional_info") - /** Number of units held */ - fun units(units: Float) = units(JsonField.of(units)) + /** + * Transaction amount in currency (computed from units × price/NAV) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun amount(): Optional = amount.getOptional("amount") /** - * Sets [Builder.units] to an arbitrary JSON value. + * Balance units after transaction * - * You should usually call [Builder.units] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). */ - fun units(units: JsonField) = apply { this.units = units } + fun balance(): Optional = balance.getOptional("balance") - /** Current market value of the holding */ - fun value(value: Float) = value(JsonField.of(value)) + /** + * Transaction date (YYYY-MM-DD) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun date(): Optional = date.getOptional("date") /** - * Sets [Builder.value] to an arbitrary JSON value. + * Transaction description/particulars * - * You should usually call [Builder.value] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). */ - fun value(value: JsonField) = apply { this.value = value } + fun description(): Optional = description.getOptional("description") - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } + /** + * Dividend rate (for DIVIDEND_PAYOUT transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun dividendRate(): Optional = dividendRate.getOptional("dividend_rate") - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } + /** + * NAV/price per unit on transaction date + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun nav(): Optional = nav.getOptional("nav") - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } + /** + * Transaction type. Possible values are PURCHASE, PURCHASE_SIP, REDEMPTION, + * SWITCH_IN, SWITCH_IN_MERGER, SWITCH_OUT, SWITCH_OUT_MERGER, DIVIDEND_PAYOUT, + * DIVIDEND_REINVEST, SEGREGATION, STAMP_DUTY_TAX, TDS_TAX, STT_TAX, MISC, + * REVERSAL, UNKNOWN. + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun type(): Optional = type.getOptional("type") - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) - } + /** + * Number of units involved in transaction + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun units(): Optional = units.getOptional("units") - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } + /** + * Returns the raw JSON value of [additionalInfo]. + * + * Unlike [additionalInfo], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("additional_info") + @ExcludeMissing + fun _additionalInfo(): JsonField = additionalInfo /** - * Returns an immutable instance of [GovernmentSecurity]. + * Returns the raw JSON value of [amount]. * - * Further updates to this [Builder] will not mutate the returned instance. + * Unlike [amount], this method doesn't throw if the JSON field has an + * unexpected type. */ - fun build(): GovernmentSecurity = - GovernmentSecurity( - additionalInfo, - isin, - name, - units, - value, - additionalProperties.toMutableMap(), - ) - } + @JsonProperty("amount") @ExcludeMissing fun _amount(): JsonField = amount - private var validated: Boolean = false + /** + * Returns the raw JSON value of [balance]. + * + * Unlike [balance], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("balance") + @ExcludeMissing + fun _balance(): JsonField = balance - fun validate(): GovernmentSecurity = apply { - if (validated) { - return@apply - } + /** + * Returns the raw JSON value of [date]. + * + * Unlike [date], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("date") @ExcludeMissing fun _date(): JsonField = date - isin() - name() - units() - value() - validated = true - } + /** + * Returns the raw JSON value of [description]. + * + * Unlike [description], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("description") + @ExcludeMissing + fun _description(): JsonField = description - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - false - } + /** + * Returns the raw JSON value of [dividendRate]. + * + * Unlike [dividendRate], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("dividend_rate") + @ExcludeMissing + fun _dividendRate(): JsonField = dividendRate - /** - * 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 (isin.asKnown().isPresent) 1 else 0) + - (if (name.asKnown().isPresent) 1 else 0) + - (if (units.asKnown().isPresent) 1 else 0) + - (if (value.asKnown().isPresent) 1 else 0) + /** + * Returns the raw JSON value of [nav]. + * + * Unlike [nav], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("nav") @ExcludeMissing fun _nav(): JsonField = nav - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type - return other is GovernmentSecurity && - additionalInfo == other.additionalInfo && - isin == other.isin && - name == other.name && - units == other.units && - value == other.value && - additionalProperties == other.additionalProperties - } + /** + * Returns the raw JSON value of [units]. + * + * Unlike [units], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("units") @ExcludeMissing fun _units(): JsonField = units - private val hashCode: Int by lazy { - Objects.hash(additionalInfo, isin, name, units, value, additionalProperties) - } + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } - override fun hashCode(): Int = hashCode + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) - override fun toString() = - "GovernmentSecurity{additionalInfo=$additionalInfo, isin=$isin, name=$name, units=$units, value=$value, additionalProperties=$additionalProperties}" - } + fun toBuilder() = Builder().from(this) - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + companion object { - return other is Holdings && - aifs == other.aifs && - corporateBonds == other.corporateBonds && - dematMutualFunds == other.dematMutualFunds && - equities == other.equities && - governmentSecurities == other.governmentSecurities && - additionalProperties == other.additionalProperties - } + /** + * Returns a mutable builder for constructing an instance of [Transaction]. + */ + @JvmStatic fun builder() = Builder() + } - private val hashCode: Int by lazy { - Objects.hash( - aifs, - corporateBonds, - dematMutualFunds, - equities, - governmentSecurities, - additionalProperties, - ) - } + /** A builder for [Transaction]. */ + class Builder internal constructor() { + + private var additionalInfo: JsonField = JsonMissing.of() + private var amount: JsonField = JsonMissing.of() + private var balance: JsonField = JsonMissing.of() + private var date: JsonField = JsonMissing.of() + private var description: JsonField = JsonMissing.of() + private var dividendRate: JsonField = JsonMissing.of() + private var nav: JsonField = JsonMissing.of() + private var type: JsonField = JsonMissing.of() + private var units: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = + mutableMapOf() + + @JvmSynthetic + internal fun from(transaction: Transaction) = apply { + additionalInfo = transaction.additionalInfo + amount = transaction.amount + balance = transaction.balance + date = transaction.date + description = transaction.description + dividendRate = transaction.dividendRate + nav = transaction.nav + type = transaction.type + units = transaction.units + additionalProperties = transaction.additionalProperties.toMutableMap() + } - override fun hashCode(): Int = hashCode + /** Additional transaction-specific fields that vary by source */ + fun additionalInfo(additionalInfo: AdditionalInfo) = + additionalInfo(JsonField.of(additionalInfo)) - override fun toString() = - "Holdings{aifs=$aifs, corporateBonds=$corporateBonds, dematMutualFunds=$dematMutualFunds, equities=$equities, governmentSecurities=$governmentSecurities, additionalProperties=$additionalProperties}" - } + /** + * Sets [Builder.additionalInfo] to an arbitrary JSON value. + * + * You should usually call [Builder.additionalInfo] with a well-typed + * [AdditionalInfo] value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun additionalInfo(additionalInfo: JsonField) = apply { + this.additionalInfo = additionalInfo + } - class LinkedHolder - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val name: JsonField, - private val pan: JsonField, - private val additionalProperties: MutableMap, - ) { + /** Transaction amount in currency (computed from units × price/NAV) */ + fun amount(amount: Float?) = amount(JsonField.ofNullable(amount)) - @JsonCreator - private constructor( - @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), - @JsonProperty("pan") @ExcludeMissing pan: JsonField = JsonMissing.of(), - ) : this(name, pan, mutableMapOf()) + /** + * Alias for [Builder.amount]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun amount(amount: Float) = amount(amount as Float?) - /** - * Name of the account holder - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun name(): Optional = name.getOptional("name") + /** Alias for calling [Builder.amount] with `amount.orElse(null)`. */ + fun amount(amount: Optional) = amount(amount.getOrNull()) - /** - * PAN of the account holder - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun pan(): Optional = pan.getOptional("pan") + /** + * Sets [Builder.amount] to an arbitrary JSON value. + * + * You should usually call [Builder.amount] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun amount(amount: JsonField) = apply { this.amount = amount } - /** - * Returns the raw JSON value of [name]. - * - * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + /** Balance units after transaction */ + fun balance(balance: Float) = balance(JsonField.of(balance)) - /** - * Returns the raw JSON value of [pan]. - * - * Unlike [pan], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("pan") @ExcludeMissing fun _pan(): JsonField = pan + /** + * Sets [Builder.balance] to an arbitrary JSON value. + * + * You should usually call [Builder.balance] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun balance(balance: JsonField) = apply { this.balance = balance } - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } + /** Transaction date (YYYY-MM-DD) */ + fun date(date: LocalDate) = date(JsonField.of(date)) - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) + /** + * Sets [Builder.date] to an arbitrary JSON value. + * + * You should usually call [Builder.date] with a well-typed [LocalDate] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun date(date: JsonField) = apply { this.date = date } - fun toBuilder() = Builder().from(this) + /** Transaction description/particulars */ + fun description(description: String) = + description(JsonField.of(description)) - companion object { + /** + * Sets [Builder.description] to an arbitrary JSON value. + * + * You should usually call [Builder.description] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun description(description: JsonField) = apply { + this.description = description + } - /** Returns a mutable builder for constructing an instance of [LinkedHolder]. */ - @JvmStatic fun builder() = Builder() - } + /** Dividend rate (for DIVIDEND_PAYOUT transactions) */ + fun dividendRate(dividendRate: Float?) = + dividendRate(JsonField.ofNullable(dividendRate)) - /** A builder for [LinkedHolder]. */ - class Builder internal constructor() { + /** + * Alias for [Builder.dividendRate]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun dividendRate(dividendRate: Float) = dividendRate(dividendRate as Float?) - private var name: JsonField = JsonMissing.of() - private var pan: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() + /** + * Alias for calling [Builder.dividendRate] with + * `dividendRate.orElse(null)`. + */ + fun dividendRate(dividendRate: Optional) = + dividendRate(dividendRate.getOrNull()) - @JvmSynthetic - internal fun from(linkedHolder: LinkedHolder) = apply { - name = linkedHolder.name - pan = linkedHolder.pan - additionalProperties = linkedHolder.additionalProperties.toMutableMap() - } + /** + * Sets [Builder.dividendRate] to an arbitrary JSON value. + * + * You should usually call [Builder.dividendRate] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun dividendRate(dividendRate: JsonField) = apply { + this.dividendRate = dividendRate + } - /** Name of the account holder */ - fun name(name: String) = name(JsonField.of(name)) + /** NAV/price per unit on transaction date */ + fun nav(nav: Float?) = nav(JsonField.ofNullable(nav)) - /** - * Sets [Builder.name] to an arbitrary JSON value. - * - * You should usually call [Builder.name] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun name(name: JsonField) = apply { this.name = name } + /** + * Alias for [Builder.nav]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun nav(nav: Float) = nav(nav as Float?) - /** PAN of the account holder */ - fun pan(pan: String) = pan(JsonField.of(pan)) + /** Alias for calling [Builder.nav] with `nav.orElse(null)`. */ + fun nav(nav: Optional) = nav(nav.getOrNull()) - /** - * Sets [Builder.pan] to an arbitrary JSON value. - * - * You should usually call [Builder.pan] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun pan(pan: JsonField) = apply { this.pan = pan } + /** + * Sets [Builder.nav] to an arbitrary JSON value. + * + * You should usually call [Builder.nav] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun nav(nav: JsonField) = apply { this.nav = nav } - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } + /** + * Transaction type. Possible values are PURCHASE, PURCHASE_SIP, REDEMPTION, + * SWITCH_IN, SWITCH_IN_MERGER, SWITCH_OUT, SWITCH_OUT_MERGER, + * DIVIDEND_PAYOUT, DIVIDEND_REINVEST, SEGREGATION, STAMP_DUTY_TAX, TDS_TAX, + * STT_TAX, MISC, REVERSAL, UNKNOWN. + */ + fun type(type: Type) = type(JsonField.of(type)) - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun type(type: JsonField) = apply { this.type = type } - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } + /** Number of units involved in transaction */ + fun units(units: Float) = units(JsonField.of(units)) - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) - } + /** + * Sets [Builder.units] to an arbitrary JSON value. + * + * You should usually call [Builder.units] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun units(units: JsonField) = apply { this.units = units } - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } + fun additionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } - /** - * Returns an immutable instance of [LinkedHolder]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): LinkedHolder = - LinkedHolder(name, pan, additionalProperties.toMutableMap()) - } + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } - private var validated: Boolean = false + fun putAllAdditionalProperties( + additionalProperties: Map + ) = apply { this.additionalProperties.putAll(additionalProperties) } - fun validate(): LinkedHolder = apply { - if (validated) { - return@apply - } + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } - name() - pan() - validated = true - } + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - false - } + /** + * Returns an immutable instance of [Transaction]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Transaction = + Transaction( + additionalInfo, + amount, + balance, + date, + description, + dividendRate, + nav, + type, + units, + additionalProperties.toMutableMap(), + ) + } - /** - * 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 (name.asKnown().isPresent) 1 else 0) + (if (pan.asKnown().isPresent) 1 else 0) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + fun validate(): Transaction = apply { + if (validated) { + return@apply + } - return other is LinkedHolder && - name == other.name && - pan == other.pan && - additionalProperties == other.additionalProperties - } + additionalInfo().ifPresent { it.validate() } + amount() + balance() + date() + description() + dividendRate() + nav() + type().ifPresent { it.validate() } + units() + validated = true + } - private val hashCode: Int by lazy { Objects.hash(name, pan, additionalProperties) } + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + false + } - override fun hashCode(): Int = hashCode + /** + * 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 = + (additionalInfo.asKnown().getOrNull()?.validity() ?: 0) + + (if (amount.asKnown().isPresent) 1 else 0) + + (if (balance.asKnown().isPresent) 1 else 0) + + (if (date.asKnown().isPresent) 1 else 0) + + (if (description.asKnown().isPresent) 1 else 0) + + (if (dividendRate.asKnown().isPresent) 1 else 0) + + (if (nav.asKnown().isPresent) 1 else 0) + + (type.asKnown().getOrNull()?.validity() ?: 0) + + (if (units.asKnown().isPresent) 1 else 0) + + /** Additional transaction-specific fields that vary by source */ + class AdditionalInfo + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val capitalWithdrawal: JsonField, + private val credit: JsonField, + private val debit: JsonField, + private val incomeDistribution: JsonField, + private val orderNo: JsonField, + private val price: JsonField, + private val stampDuty: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("capital_withdrawal") + @ExcludeMissing + capitalWithdrawal: JsonField = JsonMissing.of(), + @JsonProperty("credit") + @ExcludeMissing + credit: JsonField = JsonMissing.of(), + @JsonProperty("debit") + @ExcludeMissing + debit: JsonField = JsonMissing.of(), + @JsonProperty("income_distribution") + @ExcludeMissing + incomeDistribution: JsonField = JsonMissing.of(), + @JsonProperty("order_no") + @ExcludeMissing + orderNo: JsonField = JsonMissing.of(), + @JsonProperty("price") + @ExcludeMissing + price: JsonField = JsonMissing.of(), + @JsonProperty("stamp_duty") + @ExcludeMissing + stampDuty: JsonField = JsonMissing.of(), + ) : this( + capitalWithdrawal, + credit, + debit, + incomeDistribution, + orderNo, + price, + stampDuty, + mutableMapOf(), + ) - override fun toString() = - "LinkedHolder{name=$name, pan=$pan, additionalProperties=$additionalProperties}" - } + /** + * Capital withdrawal amount (CDSL MF transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun capitalWithdrawal(): Optional = + capitalWithdrawal.getOptional("capital_withdrawal") - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + /** + * Units credited (demat transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun credit(): Optional = credit.getOptional("credit") - return other is DematAccount && - additionalInfo == other.additionalInfo && - boId == other.boId && - clientId == other.clientId && - dematType == other.dematType && - dpId == other.dpId && - dpName == other.dpName && - holdings == other.holdings && - linkedHolders == other.linkedHolders && - value == other.value && - additionalProperties == other.additionalProperties - } + /** + * Units debited (demat transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun debit(): Optional = debit.getOptional("debit") - private val hashCode: Int by lazy { - Objects.hash( - additionalInfo, - boId, - clientId, - dematType, - dpId, - dpName, - holdings, - linkedHolders, - value, - additionalProperties, - ) - } + /** + * Income distribution amount (CDSL MF transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun incomeDistribution(): Optional = + incomeDistribution.getOptional("income_distribution") - override fun hashCode(): Int = hashCode + /** + * Order/transaction reference number (demat transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun orderNo(): Optional = orderNo.getOptional("order_no") - override fun toString() = - "DematAccount{additionalInfo=$additionalInfo, boId=$boId, clientId=$clientId, dematType=$dematType, dpId=$dpId, dpName=$dpName, holdings=$holdings, linkedHolders=$linkedHolders, value=$value, additionalProperties=$additionalProperties}" - } + /** + * Price per unit (NSDL/CDSL MF transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun price(): Optional = price.getOptional("price") - class Insurance - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val lifeInsurancePolicies: JsonField>, - private val additionalProperties: MutableMap, - ) { + /** + * Stamp duty charged + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun stampDuty(): Optional = stampDuty.getOptional("stamp_duty") - @JsonCreator - private constructor( - @JsonProperty("life_insurance_policies") - @ExcludeMissing - lifeInsurancePolicies: JsonField> = JsonMissing.of() - ) : this(lifeInsurancePolicies, mutableMapOf()) + /** + * Returns the raw JSON value of [capitalWithdrawal]. + * + * Unlike [capitalWithdrawal], this method doesn't throw if the JSON field + * has an unexpected type. + */ + @JsonProperty("capital_withdrawal") + @ExcludeMissing + fun _capitalWithdrawal(): JsonField = capitalWithdrawal - /** - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun lifeInsurancePolicies(): Optional> = - lifeInsurancePolicies.getOptional("life_insurance_policies") + /** + * Returns the raw JSON value of [credit]. + * + * Unlike [credit], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("credit") + @ExcludeMissing + fun _credit(): JsonField = credit - /** - * Returns the raw JSON value of [lifeInsurancePolicies]. - * - * Unlike [lifeInsurancePolicies], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("life_insurance_policies") - @ExcludeMissing - fun _lifeInsurancePolicies(): JsonField> = lifeInsurancePolicies + /** + * Returns the raw JSON value of [debit]. + * + * Unlike [debit], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("debit") + @ExcludeMissing + fun _debit(): JsonField = debit - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } + /** + * Returns the raw JSON value of [incomeDistribution]. + * + * Unlike [incomeDistribution], this method doesn't throw if the JSON field + * has an unexpected type. + */ + @JsonProperty("income_distribution") + @ExcludeMissing + fun _incomeDistribution(): JsonField = incomeDistribution - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) + /** + * Returns the raw JSON value of [orderNo]. + * + * Unlike [orderNo], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("order_no") + @ExcludeMissing + fun _orderNo(): JsonField = orderNo - fun toBuilder() = Builder().from(this) + /** + * Returns the raw JSON value of [price]. + * + * Unlike [price], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("price") + @ExcludeMissing + fun _price(): JsonField = price - companion object { + /** + * Returns the raw JSON value of [stampDuty]. + * + * Unlike [stampDuty], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("stamp_duty") + @ExcludeMissing + fun _stampDuty(): JsonField = stampDuty - /** Returns a mutable builder for constructing an instance of [Insurance]. */ - @JvmStatic fun builder() = Builder() - } + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } - /** A builder for [Insurance]. */ - class Builder internal constructor() { + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) - private var lifeInsurancePolicies: JsonField>? = null - private var additionalProperties: MutableMap = mutableMapOf() + fun toBuilder() = Builder().from(this) - @JvmSynthetic - internal fun from(insurance: Insurance) = apply { - lifeInsurancePolicies = insurance.lifeInsurancePolicies.map { it.toMutableList() } - additionalProperties = insurance.additionalProperties.toMutableMap() - } + companion object { - fun lifeInsurancePolicies(lifeInsurancePolicies: List) = - lifeInsurancePolicies(JsonField.of(lifeInsurancePolicies)) + /** + * Returns a mutable builder for constructing an instance of + * [AdditionalInfo]. + */ + @JvmStatic fun builder() = Builder() + } - /** - * Sets [Builder.lifeInsurancePolicies] to an arbitrary JSON value. - * - * You should usually call [Builder.lifeInsurancePolicies] with a well-typed - * `List` value instead. This method is primarily for setting the - * field to an undocumented or not yet supported value. - */ - fun lifeInsurancePolicies(lifeInsurancePolicies: JsonField>) = - apply { - this.lifeInsurancePolicies = lifeInsurancePolicies.map { it.toMutableList() } - } + /** A builder for [AdditionalInfo]. */ + class Builder internal constructor() { + + private var capitalWithdrawal: JsonField = JsonMissing.of() + private var credit: JsonField = JsonMissing.of() + private var debit: JsonField = JsonMissing.of() + private var incomeDistribution: JsonField = JsonMissing.of() + private var orderNo: JsonField = JsonMissing.of() + private var price: JsonField = JsonMissing.of() + private var stampDuty: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = + mutableMapOf() + + @JvmSynthetic + internal fun from(additionalInfo: AdditionalInfo) = apply { + capitalWithdrawal = additionalInfo.capitalWithdrawal + credit = additionalInfo.credit + debit = additionalInfo.debit + incomeDistribution = additionalInfo.incomeDistribution + orderNo = additionalInfo.orderNo + price = additionalInfo.price + stampDuty = additionalInfo.stampDuty + additionalProperties = + additionalInfo.additionalProperties.toMutableMap() + } + + /** Capital withdrawal amount (CDSL MF transactions) */ + fun capitalWithdrawal(capitalWithdrawal: Float) = + capitalWithdrawal(JsonField.of(capitalWithdrawal)) + + /** + * Sets [Builder.capitalWithdrawal] to an arbitrary JSON value. + * + * You should usually call [Builder.capitalWithdrawal] with a well-typed + * [Float] value instead. This method is primarily for setting the field + * to an undocumented or not yet supported value. + */ + fun capitalWithdrawal(capitalWithdrawal: JsonField) = apply { + this.capitalWithdrawal = capitalWithdrawal + } + + /** Units credited (demat transactions) */ + fun credit(credit: Float) = credit(JsonField.of(credit)) + + /** + * Sets [Builder.credit] to an arbitrary JSON value. + * + * You should usually call [Builder.credit] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun credit(credit: JsonField) = apply { this.credit = credit } + + /** Units debited (demat transactions) */ + fun debit(debit: Float) = debit(JsonField.of(debit)) + + /** + * Sets [Builder.debit] to an arbitrary JSON value. + * + * You should usually call [Builder.debit] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun debit(debit: JsonField) = apply { this.debit = debit } + + /** Income distribution amount (CDSL MF transactions) */ + fun incomeDistribution(incomeDistribution: Float) = + incomeDistribution(JsonField.of(incomeDistribution)) + + /** + * Sets [Builder.incomeDistribution] to an arbitrary JSON value. + * + * You should usually call [Builder.incomeDistribution] with a + * well-typed [Float] value instead. This method is primarily for + * setting the field to an undocumented or not yet supported value. + */ + fun incomeDistribution(incomeDistribution: JsonField) = apply { + this.incomeDistribution = incomeDistribution + } + + /** Order/transaction reference number (demat transactions) */ + fun orderNo(orderNo: String) = orderNo(JsonField.of(orderNo)) + + /** + * Sets [Builder.orderNo] to an arbitrary JSON value. + * + * You should usually call [Builder.orderNo] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun orderNo(orderNo: JsonField) = apply { + this.orderNo = orderNo + } + + /** Price per unit (NSDL/CDSL MF transactions) */ + fun price(price: Float) = price(JsonField.of(price)) + + /** + * Sets [Builder.price] to an arbitrary JSON value. + * + * You should usually call [Builder.price] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun price(price: JsonField) = apply { this.price = price } + + /** Stamp duty charged */ + fun stampDuty(stampDuty: Float) = stampDuty(JsonField.of(stampDuty)) + + /** + * Sets [Builder.stampDuty] to an arbitrary JSON value. + * + * You should usually call [Builder.stampDuty] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun stampDuty(stampDuty: JsonField) = apply { + this.stampDuty = stampDuty + } + + 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 [AdditionalInfo]. + * + * Further updates to this [Builder] will not mutate the returned + * instance. + */ + fun build(): AdditionalInfo = + AdditionalInfo( + capitalWithdrawal, + credit, + debit, + incomeDistribution, + orderNo, + price, + stampDuty, + additionalProperties.toMutableMap(), + ) + } - /** - * Adds a single [LifeInsurancePolicy] to [lifeInsurancePolicies]. - * - * @throws IllegalStateException if the field was previously set to a non-list. - */ - fun addLifeInsurancePolicy(lifeInsurancePolicy: LifeInsurancePolicy) = apply { - lifeInsurancePolicies = - (lifeInsurancePolicies ?: JsonField.of(mutableListOf())).also { - checkKnown("lifeInsurancePolicies", it).add(lifeInsurancePolicy) + private var validated: Boolean = false + + fun validate(): AdditionalInfo = apply { + if (validated) { + return@apply + } + + capitalWithdrawal() + credit() + debit() + incomeDistribution() + orderNo() + price() + stampDuty() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (capitalWithdrawal.asKnown().isPresent) 1 else 0) + + (if (credit.asKnown().isPresent) 1 else 0) + + (if (debit.asKnown().isPresent) 1 else 0) + + (if (incomeDistribution.asKnown().isPresent) 1 else 0) + + (if (orderNo.asKnown().isPresent) 1 else 0) + + (if (price.asKnown().isPresent) 1 else 0) + + (if (stampDuty.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AdditionalInfo && + capitalWithdrawal == other.capitalWithdrawal && + credit == other.credit && + debit == other.debit && + incomeDistribution == other.incomeDistribution && + orderNo == other.orderNo && + price == other.price && + stampDuty == other.stampDuty && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + capitalWithdrawal, + credit, + debit, + incomeDistribution, + orderNo, + price, + stampDuty, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AdditionalInfo{capitalWithdrawal=$capitalWithdrawal, credit=$credit, debit=$debit, incomeDistribution=$incomeDistribution, orderNo=$orderNo, price=$price, stampDuty=$stampDuty, additionalProperties=$additionalProperties}" } - } - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } + /** + * Transaction type. Possible values are PURCHASE, PURCHASE_SIP, REDEMPTION, + * SWITCH_IN, SWITCH_IN_MERGER, SWITCH_OUT, SWITCH_OUT_MERGER, DIVIDEND_PAYOUT, + * DIVIDEND_REINVEST, SEGREGATION, STAMP_DUTY_TAX, TDS_TAX, STT_TAX, MISC, + * REVERSAL, UNKNOWN. + */ + class Type + @JsonCreator + private constructor(private val value: JsonField) : Enum { - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data + * that doesn't match any known member, and you want to know that value. For + * example, if the SDK is on an older version than the API, then the API may + * respond with new members that the SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue + fun _value(): JsonField = value - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } + companion object { - fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + @JvmField val PURCHASE = of("PURCHASE") - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } + @JvmField val PURCHASE_SIP = of("PURCHASE_SIP") - /** - * Returns an immutable instance of [Insurance]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): Insurance = - Insurance( - (lifeInsurancePolicies ?: JsonMissing.of()).map { it.toImmutable() }, - additionalProperties.toMutableMap(), - ) - } + @JvmField val REDEMPTION = of("REDEMPTION") - private var validated: Boolean = false + @JvmField val SWITCH_IN = of("SWITCH_IN") - fun validate(): Insurance = apply { - if (validated) { - return@apply - } + @JvmField val SWITCH_IN_MERGER = of("SWITCH_IN_MERGER") - lifeInsurancePolicies().ifPresent { it.forEach { it.validate() } } - validated = true - } + @JvmField val SWITCH_OUT = of("SWITCH_OUT") - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - false - } + @JvmField val SWITCH_OUT_MERGER = of("SWITCH_OUT_MERGER") - /** - * 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 = - (lifeInsurancePolicies.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + @JvmField val DIVIDEND_PAYOUT = of("DIVIDEND_PAYOUT") - class LifeInsurancePolicy - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val additionalInfo: JsonValue, - private val lifeAssured: JsonField, - private val policyName: JsonField, - private val policyNumber: JsonField, - private val premiumAmount: JsonField, - private val premiumFrequency: JsonField, - private val provider: JsonField, - private val status: JsonField, - private val sumAssured: JsonField, - private val additionalProperties: MutableMap, - ) { + @JvmField val DIVIDEND_REINVEST = of("DIVIDEND_REINVEST") - @JsonCreator - private constructor( - @JsonProperty("additional_info") - @ExcludeMissing - additionalInfo: JsonValue = JsonMissing.of(), - @JsonProperty("life_assured") - @ExcludeMissing - lifeAssured: JsonField = JsonMissing.of(), - @JsonProperty("policy_name") - @ExcludeMissing - policyName: JsonField = JsonMissing.of(), - @JsonProperty("policy_number") - @ExcludeMissing - policyNumber: JsonField = JsonMissing.of(), - @JsonProperty("premium_amount") - @ExcludeMissing - premiumAmount: JsonField = JsonMissing.of(), - @JsonProperty("premium_frequency") - @ExcludeMissing - premiumFrequency: JsonField = JsonMissing.of(), - @JsonProperty("provider") - @ExcludeMissing - provider: JsonField = JsonMissing.of(), - @JsonProperty("status") - @ExcludeMissing - status: JsonField = JsonMissing.of(), - @JsonProperty("sum_assured") - @ExcludeMissing - sumAssured: JsonField = JsonMissing.of(), - ) : this( - additionalInfo, - lifeAssured, - policyName, - policyNumber, - premiumAmount, - premiumFrequency, - provider, - status, - sumAssured, - mutableMapOf(), - ) + @JvmField val SEGREGATION = of("SEGREGATION") - /** Additional information specific to the policy */ - @JsonProperty("additional_info") - @ExcludeMissing - fun _additionalInfo(): JsonValue = additionalInfo + @JvmField val STAMP_DUTY_TAX = of("STAMP_DUTY_TAX") - /** - * Name of the life assured - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun lifeAssured(): Optional = lifeAssured.getOptional("life_assured") + @JvmField val TDS_TAX = of("TDS_TAX") - /** - * Name of the insurance policy - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun policyName(): Optional = policyName.getOptional("policy_name") + @JvmField val STT_TAX = of("STT_TAX") - /** - * Insurance policy number - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun policyNumber(): Optional = policyNumber.getOptional("policy_number") + @JvmField val MISC = of("MISC") - /** - * Premium amount - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun premiumAmount(): Optional = premiumAmount.getOptional("premium_amount") + @JvmField val REVERSAL = of("REVERSAL") - /** - * Frequency of premium payment (e.g., Annual, Monthly) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun premiumFrequency(): Optional = - premiumFrequency.getOptional("premium_frequency") + @JvmField val UNKNOWN = of("UNKNOWN") - /** - * Insurance company name - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun provider(): Optional = provider.getOptional("provider") + @JvmStatic fun of(value: String) = Type(JsonField.of(value)) + } - /** - * Status of the policy (e.g., Active, Lapsed) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun status(): Optional = status.getOptional("status") + /** An enum containing [Type]'s known values. */ + enum class Known { + PURCHASE, + PURCHASE_SIP, + REDEMPTION, + SWITCH_IN, + SWITCH_IN_MERGER, + SWITCH_OUT, + SWITCH_OUT_MERGER, + DIVIDEND_PAYOUT, + DIVIDEND_REINVEST, + SEGREGATION, + STAMP_DUTY_TAX, + TDS_TAX, + STT_TAX, + MISC, + REVERSAL, + UNKNOWN, + } - /** - * Sum assured amount - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun sumAssured(): Optional = sumAssured.getOptional("sum_assured") + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [Type] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For + * example, if the SDK is on an older version than the API, then the API + * may respond with new members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + PURCHASE, + PURCHASE_SIP, + REDEMPTION, + SWITCH_IN, + SWITCH_IN_MERGER, + SWITCH_OUT, + SWITCH_OUT_MERGER, + DIVIDEND_PAYOUT, + DIVIDEND_REINVEST, + SEGREGATION, + STAMP_DUTY_TAX, + TDS_TAX, + STT_TAX, + MISC, + REVERSAL, + UNKNOWN, + /** + * An enum member indicating that [Type] was instantiated with an + * unknown value. + */ + _UNKNOWN, + } - /** - * Returns the raw JSON value of [lifeAssured]. - * - * Unlike [lifeAssured], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("life_assured") - @ExcludeMissing - fun _lifeAssured(): JsonField = lifeAssured + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always + * known or if you want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + PURCHASE -> Value.PURCHASE + PURCHASE_SIP -> Value.PURCHASE_SIP + REDEMPTION -> Value.REDEMPTION + SWITCH_IN -> Value.SWITCH_IN + SWITCH_IN_MERGER -> Value.SWITCH_IN_MERGER + SWITCH_OUT -> Value.SWITCH_OUT + SWITCH_OUT_MERGER -> Value.SWITCH_OUT_MERGER + DIVIDEND_PAYOUT -> Value.DIVIDEND_PAYOUT + DIVIDEND_REINVEST -> Value.DIVIDEND_REINVEST + SEGREGATION -> Value.SEGREGATION + STAMP_DUTY_TAX -> Value.STAMP_DUTY_TAX + TDS_TAX -> Value.TDS_TAX + STT_TAX -> Value.STT_TAX + MISC -> Value.MISC + REVERSAL -> Value.REVERSAL + UNKNOWN -> Value.UNKNOWN + else -> Value._UNKNOWN + } - /** - * Returns the raw JSON value of [policyName]. - * - * Unlike [policyName], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("policy_name") - @ExcludeMissing - fun _policyName(): JsonField = policyName + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always + * known and don't want to throw for the unknown case. + * + * @throws CasParserInvalidDataException if this class instance's value is a + * not a known member. + */ + fun known(): Known = + when (this) { + PURCHASE -> Known.PURCHASE + PURCHASE_SIP -> Known.PURCHASE_SIP + REDEMPTION -> Known.REDEMPTION + SWITCH_IN -> Known.SWITCH_IN + SWITCH_IN_MERGER -> Known.SWITCH_IN_MERGER + SWITCH_OUT -> Known.SWITCH_OUT + SWITCH_OUT_MERGER -> Known.SWITCH_OUT_MERGER + DIVIDEND_PAYOUT -> Known.DIVIDEND_PAYOUT + DIVIDEND_REINVEST -> Known.DIVIDEND_REINVEST + SEGREGATION -> Known.SEGREGATION + STAMP_DUTY_TAX -> Known.STAMP_DUTY_TAX + TDS_TAX -> Known.TDS_TAX + STT_TAX -> Known.STT_TAX + MISC -> Known.MISC + REVERSAL -> Known.REVERSAL + UNKNOWN -> Known.UNKNOWN + else -> throw CasParserInvalidDataException("Unknown Type: $value") + } - /** - * Returns the raw JSON value of [policyNumber]. - * - * Unlike [policyNumber], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("policy_number") - @ExcludeMissing - fun _policyNumber(): JsonField = policyNumber + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily + * for debugging and generally doesn't throw. + * + * @throws CasParserInvalidDataException if this class instance's value does + * not have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CasParserInvalidDataException("Value is not a String") + } - /** - * Returns the raw JSON value of [premiumAmount]. - * - * Unlike [premiumAmount], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("premium_amount") - @ExcludeMissing - fun _premiumAmount(): JsonField = premiumAmount + private var validated: Boolean = false - /** - * Returns the raw JSON value of [premiumFrequency]. - * - * Unlike [premiumFrequency], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("premium_frequency") - @ExcludeMissing - fun _premiumFrequency(): JsonField = premiumFrequency + fun validate(): Type = apply { + if (validated) { + return@apply + } - /** - * Returns the raw JSON value of [provider]. - * - * Unlike [provider], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("provider") @ExcludeMissing fun _provider(): JsonField = provider + known() + validated = true + } - /** - * Returns the raw JSON value of [status]. - * - * Unlike [status], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("status") @ExcludeMissing fun _status(): JsonField = status + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + false + } - /** - * Returns the raw JSON value of [sumAssured]. - * - * Unlike [sumAssured], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("sum_assured") - @ExcludeMissing - fun _sumAssured(): JsonField = sumAssured + /** + * 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 (value() == Value._UNKNOWN) 0 else 1 - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) + return other is Type && value == other.value + } - fun toBuilder() = Builder().from(this) + override fun hashCode() = value.hashCode() - companion object { + override fun toString() = value.toString() + } - /** - * Returns a mutable builder for constructing an instance of [LifeInsurancePolicy]. - */ - @JvmStatic fun builder() = Builder() - } + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - /** A builder for [LifeInsurancePolicy]. */ - class Builder internal constructor() { + return other is Transaction && + additionalInfo == other.additionalInfo && + amount == other.amount && + balance == other.balance && + date == other.date && + description == other.description && + dividendRate == other.dividendRate && + nav == other.nav && + type == other.type && + units == other.units && + additionalProperties == other.additionalProperties + } - private var additionalInfo: JsonValue = JsonMissing.of() - private var lifeAssured: JsonField = JsonMissing.of() - private var policyName: JsonField = JsonMissing.of() - private var policyNumber: JsonField = JsonMissing.of() - private var premiumAmount: JsonField = JsonMissing.of() - private var premiumFrequency: JsonField = JsonMissing.of() - private var provider: JsonField = JsonMissing.of() - private var status: JsonField = JsonMissing.of() - private var sumAssured: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() + private val hashCode: Int by lazy { + Objects.hash( + additionalInfo, + amount, + balance, + date, + description, + dividendRate, + nav, + type, + units, + additionalProperties, + ) + } - @JvmSynthetic - internal fun from(lifeInsurancePolicy: LifeInsurancePolicy) = apply { - additionalInfo = lifeInsurancePolicy.additionalInfo - lifeAssured = lifeInsurancePolicy.lifeAssured - policyName = lifeInsurancePolicy.policyName - policyNumber = lifeInsurancePolicy.policyNumber - premiumAmount = lifeInsurancePolicy.premiumAmount - premiumFrequency = lifeInsurancePolicy.premiumFrequency - provider = lifeInsurancePolicy.provider - status = lifeInsurancePolicy.status - sumAssured = lifeInsurancePolicy.sumAssured - additionalProperties = lifeInsurancePolicy.additionalProperties.toMutableMap() + override fun hashCode(): Int = hashCode + + override fun toString() = + "Transaction{additionalInfo=$additionalInfo, amount=$amount, balance=$balance, date=$date, description=$description, dividendRate=$dividendRate, nav=$nav, type=$type, units=$units, additionalProperties=$additionalProperties}" } - /** Additional information specific to the policy */ - fun additionalInfo(additionalInfo: JsonValue) = apply { - this.additionalInfo = additionalInfo + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is CorporateBond && + additionalInfo == other.additionalInfo && + isin == other.isin && + name == other.name && + transactions == other.transactions && + units == other.units && + value == other.value && + additionalProperties == other.additionalProperties } - /** Name of the life assured */ - fun lifeAssured(lifeAssured: String) = lifeAssured(JsonField.of(lifeAssured)) + private val hashCode: Int by lazy { + Objects.hash( + additionalInfo, + isin, + name, + transactions, + units, + value, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "CorporateBond{additionalInfo=$additionalInfo, isin=$isin, name=$name, transactions=$transactions, units=$units, value=$value, additionalProperties=$additionalProperties}" + } + + class DematMutualFund + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val additionalInfo: JsonField, + private val isin: JsonField, + private val name: JsonField, + private val transactions: JsonField>, + private val units: JsonField, + private val value: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("additional_info") + @ExcludeMissing + additionalInfo: JsonField = JsonMissing.of(), + @JsonProperty("isin") + @ExcludeMissing + isin: JsonField = JsonMissing.of(), + @JsonProperty("name") + @ExcludeMissing + name: JsonField = JsonMissing.of(), + @JsonProperty("transactions") + @ExcludeMissing + transactions: JsonField> = JsonMissing.of(), + @JsonProperty("units") + @ExcludeMissing + units: JsonField = JsonMissing.of(), + @JsonProperty("value") + @ExcludeMissing + value: JsonField = JsonMissing.of(), + ) : this(additionalInfo, isin, name, transactions, units, value, mutableMapOf()) /** - * Sets [Builder.lifeAssured] to an arbitrary JSON value. + * Additional information specific to the mutual fund * - * You should usually call [Builder.lifeAssured] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). */ - fun lifeAssured(lifeAssured: JsonField) = apply { - this.lifeAssured = lifeAssured - } - - /** Name of the insurance policy */ - fun policyName(policyName: String) = policyName(JsonField.of(policyName)) + fun additionalInfo(): Optional = + additionalInfo.getOptional("additional_info") /** - * Sets [Builder.policyName] to an arbitrary JSON value. + * ISIN code of the mutual fund * - * You should usually call [Builder.policyName] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). */ - fun policyName(policyName: JsonField) = apply { - this.policyName = policyName - } - - /** Insurance policy number */ - fun policyNumber(policyNumber: String) = policyNumber(JsonField.of(policyNumber)) + fun isin(): Optional = isin.getOptional("isin") /** - * Sets [Builder.policyNumber] to an arbitrary JSON value. + * Name of the mutual fund * - * You should usually call [Builder.policyNumber] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). */ - fun policyNumber(policyNumber: JsonField) = apply { - this.policyNumber = policyNumber - } - - /** Premium amount */ - fun premiumAmount(premiumAmount: Float) = premiumAmount(JsonField.of(premiumAmount)) + fun name(): Optional = name.getOptional("name") /** - * Sets [Builder.premiumAmount] to an arbitrary JSON value. + * List of transactions for this holding (beta) * - * You should usually call [Builder.premiumAmount] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). */ - fun premiumAmount(premiumAmount: JsonField) = apply { - this.premiumAmount = premiumAmount - } - - /** Frequency of premium payment (e.g., Annual, Monthly) */ - fun premiumFrequency(premiumFrequency: String) = - premiumFrequency(JsonField.of(premiumFrequency)) + fun transactions(): Optional> = + transactions.getOptional("transactions") /** - * Sets [Builder.premiumFrequency] to an arbitrary JSON value. + * Number of units held * - * You should usually call [Builder.premiumFrequency] with a well-typed [String] - * value instead. This method is primarily for setting the field to an undocumented - * or not yet supported value. + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). */ - fun premiumFrequency(premiumFrequency: JsonField) = apply { - this.premiumFrequency = premiumFrequency - } + fun units(): Optional = units.getOptional("units") - /** Insurance company name */ - fun provider(provider: String) = provider(JsonField.of(provider)) + /** + * Current market value of the holding + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun value(): Optional = value.getOptional("value") /** - * Sets [Builder.provider] to an arbitrary JSON value. + * Returns the raw JSON value of [additionalInfo]. * - * You should usually call [Builder.provider] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. + * Unlike [additionalInfo], this method doesn't throw if the JSON field has an + * unexpected type. */ - fun provider(provider: JsonField) = apply { this.provider = provider } + @JsonProperty("additional_info") + @ExcludeMissing + fun _additionalInfo(): JsonField = additionalInfo - /** Status of the policy (e.g., Active, Lapsed) */ - fun status(status: String) = status(JsonField.of(status)) + /** + * Returns the raw JSON value of [isin]. + * + * Unlike [isin], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("isin") @ExcludeMissing fun _isin(): JsonField = isin /** - * Sets [Builder.status] to an arbitrary JSON value. + * Returns the raw JSON value of [name]. * - * You should usually call [Builder.status] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. + * Unlike [name], this method doesn't throw if the JSON field has an unexpected + * type. */ - fun status(status: JsonField) = apply { this.status = status } + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name - /** Sum assured amount */ - fun sumAssured(sumAssured: Float) = sumAssured(JsonField.of(sumAssured)) + /** + * Returns the raw JSON value of [transactions]. + * + * Unlike [transactions], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("transactions") + @ExcludeMissing + fun _transactions(): JsonField> = transactions /** - * Sets [Builder.sumAssured] to an arbitrary JSON value. + * Returns the raw JSON value of [units]. * - * You should usually call [Builder.sumAssured] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. + * Unlike [units], this method doesn't throw if the JSON field has an unexpected + * type. */ - fun sumAssured(sumAssured: JsonField) = apply { - this.sumAssured = sumAssured - } + @JsonProperty("units") @ExcludeMissing fun _units(): JsonField = units - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } + /** + * Returns the raw JSON value of [value]. + * + * Unlike [value], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("value") @ExcludeMissing fun _value(): JsonField = value - fun putAdditionalProperty(key: String, value: JsonValue) = apply { + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { additionalProperties.put(key, value) } - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) - } + fun toBuilder() = Builder().from(this) - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) + companion object { + + /** + * Returns a mutable builder for constructing an instance of [DematMutualFund]. + */ + @JvmStatic fun builder() = Builder() } - /** - * Returns an immutable instance of [LifeInsurancePolicy]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): LifeInsurancePolicy = - LifeInsurancePolicy( - additionalInfo, - lifeAssured, - policyName, - policyNumber, - premiumAmount, - premiumFrequency, - provider, - status, - sumAssured, - additionalProperties.toMutableMap(), - ) - } + /** A builder for [DematMutualFund]. */ + class Builder internal constructor() { - private var validated: Boolean = false + private var additionalInfo: JsonField = JsonMissing.of() + private var isin: JsonField = JsonMissing.of() + private var name: JsonField = JsonMissing.of() + private var transactions: JsonField>? = null + private var units: JsonField = JsonMissing.of() + private var value: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() - fun validate(): LifeInsurancePolicy = apply { - if (validated) { - return@apply - } + @JvmSynthetic + internal fun from(dematMutualFund: DematMutualFund) = apply { + additionalInfo = dematMutualFund.additionalInfo + isin = dematMutualFund.isin + name = dematMutualFund.name + transactions = dematMutualFund.transactions.map { it.toMutableList() } + units = dematMutualFund.units + value = dematMutualFund.value + additionalProperties = dematMutualFund.additionalProperties.toMutableMap() + } - lifeAssured() - policyName() - policyNumber() - premiumAmount() - premiumFrequency() - provider() - status() - sumAssured() - validated = true - } + /** Additional information specific to the mutual fund */ + fun additionalInfo(additionalInfo: AdditionalInfo) = + additionalInfo(JsonField.of(additionalInfo)) - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - false - } + /** + * Sets [Builder.additionalInfo] to an arbitrary JSON value. + * + * You should usually call [Builder.additionalInfo] with a well-typed + * [AdditionalInfo] value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun additionalInfo(additionalInfo: JsonField) = apply { + this.additionalInfo = additionalInfo + } - /** - * 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 (lifeAssured.asKnown().isPresent) 1 else 0) + - (if (policyName.asKnown().isPresent) 1 else 0) + - (if (policyNumber.asKnown().isPresent) 1 else 0) + - (if (premiumAmount.asKnown().isPresent) 1 else 0) + - (if (premiumFrequency.asKnown().isPresent) 1 else 0) + - (if (provider.asKnown().isPresent) 1 else 0) + - (if (status.asKnown().isPresent) 1 else 0) + - (if (sumAssured.asKnown().isPresent) 1 else 0) + /** ISIN code of the mutual fund */ + fun isin(isin: String) = isin(JsonField.of(isin)) - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + /** + * Sets [Builder.isin] to an arbitrary JSON value. + * + * You should usually call [Builder.isin] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun isin(isin: JsonField) = apply { this.isin = isin } - return other is LifeInsurancePolicy && - additionalInfo == other.additionalInfo && - lifeAssured == other.lifeAssured && - policyName == other.policyName && - policyNumber == other.policyNumber && - premiumAmount == other.premiumAmount && - premiumFrequency == other.premiumFrequency && - provider == other.provider && - status == other.status && - sumAssured == other.sumAssured && - additionalProperties == other.additionalProperties - } + /** Name of the mutual fund */ + fun name(name: String) = name(JsonField.of(name)) - private val hashCode: Int by lazy { - Objects.hash( - additionalInfo, - lifeAssured, - policyName, - policyNumber, - premiumAmount, - premiumFrequency, - provider, - status, - sumAssured, - additionalProperties, - ) - } + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun name(name: JsonField) = apply { this.name = name } - override fun hashCode(): Int = hashCode + /** List of transactions for this holding (beta) */ + fun transactions(transactions: List) = + transactions(JsonField.of(transactions)) - override fun toString() = - "LifeInsurancePolicy{additionalInfo=$additionalInfo, lifeAssured=$lifeAssured, policyName=$policyName, policyNumber=$policyNumber, premiumAmount=$premiumAmount, premiumFrequency=$premiumFrequency, provider=$provider, status=$status, sumAssured=$sumAssured, additionalProperties=$additionalProperties}" - } + /** + * Sets [Builder.transactions] to an arbitrary JSON value. + * + * You should usually call [Builder.transactions] with a well-typed + * `List` value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun transactions(transactions: JsonField>) = apply { + this.transactions = transactions.map { it.toMutableList() } + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + /** + * Adds a single [Transaction] to [transactions]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addTransaction(transaction: Transaction) = apply { + transactions = + (transactions ?: JsonField.of(mutableListOf())).also { + checkKnown("transactions", it).add(transaction) + } + } - return other is Insurance && - lifeInsurancePolicies == other.lifeInsurancePolicies && - additionalProperties == other.additionalProperties - } + /** Number of units held */ + fun units(units: Float) = units(JsonField.of(units)) - private val hashCode: Int by lazy { - Objects.hash(lifeInsurancePolicies, additionalProperties) - } + /** + * Sets [Builder.units] to an arbitrary JSON value. + * + * You should usually call [Builder.units] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun units(units: JsonField) = apply { this.units = units } - override fun hashCode(): Int = hashCode + /** Current market value of the holding */ + fun value(value: Float) = value(JsonField.of(value)) - override fun toString() = - "Insurance{lifeInsurancePolicies=$lifeInsurancePolicies, additionalProperties=$additionalProperties}" - } + /** + * Sets [Builder.value] to an arbitrary JSON value. + * + * You should usually call [Builder.value] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun value(value: JsonField) = apply { this.value = value } - class Investor - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val address: JsonField, - private val casId: JsonField, - private val email: JsonField, - private val mobile: JsonField, - private val name: JsonField, - private val pan: JsonField, - private val pincode: JsonField, - private val additionalProperties: MutableMap, - ) { + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } - @JsonCreator - private constructor( - @JsonProperty("address") @ExcludeMissing address: JsonField = JsonMissing.of(), - @JsonProperty("cas_id") @ExcludeMissing casId: JsonField = JsonMissing.of(), - @JsonProperty("email") @ExcludeMissing email: JsonField = JsonMissing.of(), - @JsonProperty("mobile") @ExcludeMissing mobile: JsonField = JsonMissing.of(), - @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), - @JsonProperty("pan") @ExcludeMissing pan: JsonField = JsonMissing.of(), - @JsonProperty("pincode") @ExcludeMissing pincode: JsonField = JsonMissing.of(), - ) : this(address, casId, email, mobile, name, pan, pincode, mutableMapOf()) + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } - /** - * Address of the investor - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun address(): Optional = address.getOptional("address") + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } - /** - * CAS ID of the investor (only for NSDL and CDSL) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun casId(): Optional = casId.getOptional("cas_id") + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } - /** - * Email address of the investor - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun email(): Optional = email.getOptional("email") + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } - /** - * Mobile number of the investor - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun mobile(): Optional = mobile.getOptional("mobile") + /** + * Returns an immutable instance of [DematMutualFund]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): DematMutualFund = + DematMutualFund( + additionalInfo, + isin, + name, + (transactions ?: JsonMissing.of()).map { it.toImmutable() }, + units, + value, + additionalProperties.toMutableMap(), + ) + } - /** - * Name of the investor - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun name(): Optional = name.getOptional("name") + private var validated: Boolean = false - /** - * PAN (Permanent Account Number) of the investor - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun pan(): Optional = pan.getOptional("pan") - - /** - * Postal code of the investor's address - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun pincode(): Optional = pincode.getOptional("pincode") + fun validate(): DematMutualFund = apply { + if (validated) { + return@apply + } - /** - * Returns the raw JSON value of [address]. - * - * Unlike [address], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("address") @ExcludeMissing fun _address(): JsonField = address + additionalInfo().ifPresent { it.validate() } + isin() + name() + transactions().ifPresent { it.forEach { it.validate() } } + units() + value() + validated = true + } - /** - * Returns the raw JSON value of [casId]. - * - * Unlike [casId], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("cas_id") @ExcludeMissing fun _casId(): JsonField = casId + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + false + } - /** - * Returns the raw JSON value of [email]. - * - * Unlike [email], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("email") @ExcludeMissing fun _email(): JsonField = email + /** + * 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 = + (additionalInfo.asKnown().getOrNull()?.validity() ?: 0) + + (if (isin.asKnown().isPresent) 1 else 0) + + (if (name.asKnown().isPresent) 1 else 0) + + (transactions.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (units.asKnown().isPresent) 1 else 0) + + (if (value.asKnown().isPresent) 1 else 0) - /** - * Returns the raw JSON value of [mobile]. - * - * Unlike [mobile], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("mobile") @ExcludeMissing fun _mobile(): JsonField = mobile + /** Additional information specific to the mutual fund */ + class AdditionalInfo + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val closeUnits: JsonField, + private val openUnits: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("close_units") + @ExcludeMissing + closeUnits: JsonField = JsonMissing.of(), + @JsonProperty("open_units") + @ExcludeMissing + openUnits: JsonField = JsonMissing.of(), + ) : this(closeUnits, openUnits, mutableMapOf()) - /** - * Returns the raw JSON value of [name]. - * - * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + /** + * Closing balance units for the statement period (beta) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun closeUnits(): Optional = closeUnits.getOptional("close_units") - /** - * Returns the raw JSON value of [pan]. - * - * Unlike [pan], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("pan") @ExcludeMissing fun _pan(): JsonField = pan + /** + * Opening balance units for the statement period (beta) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun openUnits(): Optional = openUnits.getOptional("open_units") - /** - * Returns the raw JSON value of [pincode]. - * - * Unlike [pincode], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("pincode") @ExcludeMissing fun _pincode(): JsonField = pincode + /** + * Returns the raw JSON value of [closeUnits]. + * + * Unlike [closeUnits], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("close_units") + @ExcludeMissing + fun _closeUnits(): JsonField = closeUnits - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } + /** + * Returns the raw JSON value of [openUnits]. + * + * Unlike [openUnits], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("open_units") + @ExcludeMissing + fun _openUnits(): JsonField = openUnits - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } - fun toBuilder() = Builder().from(this) + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) - companion object { + fun toBuilder() = Builder().from(this) - /** Returns a mutable builder for constructing an instance of [Investor]. */ - @JvmStatic fun builder() = Builder() - } + companion object { - /** A builder for [Investor]. */ - class Builder internal constructor() { + /** + * Returns a mutable builder for constructing an instance of + * [AdditionalInfo]. + */ + @JvmStatic fun builder() = Builder() + } - private var address: JsonField = JsonMissing.of() - private var casId: JsonField = JsonMissing.of() - private var email: JsonField = JsonMissing.of() - private var mobile: JsonField = JsonMissing.of() - private var name: JsonField = JsonMissing.of() - private var pan: JsonField = JsonMissing.of() - private var pincode: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() + /** A builder for [AdditionalInfo]. */ + class Builder internal constructor() { - @JvmSynthetic - internal fun from(investor: Investor) = apply { - address = investor.address - casId = investor.casId - email = investor.email - mobile = investor.mobile - name = investor.name - pan = investor.pan - pincode = investor.pincode - additionalProperties = investor.additionalProperties.toMutableMap() - } + private var closeUnits: JsonField = JsonMissing.of() + private var openUnits: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = + mutableMapOf() - /** Address of the investor */ - fun address(address: String) = address(JsonField.of(address)) + @JvmSynthetic + internal fun from(additionalInfo: AdditionalInfo) = apply { + closeUnits = additionalInfo.closeUnits + openUnits = additionalInfo.openUnits + additionalProperties = + additionalInfo.additionalProperties.toMutableMap() + } - /** - * Sets [Builder.address] to an arbitrary JSON value. - * - * You should usually call [Builder.address] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun address(address: JsonField) = apply { this.address = address } + /** Closing balance units for the statement period (beta) */ + fun closeUnits(closeUnits: Float?) = + closeUnits(JsonField.ofNullable(closeUnits)) - /** CAS ID of the investor (only for NSDL and CDSL) */ - fun casId(casId: String) = casId(JsonField.of(casId)) + /** + * Alias for [Builder.closeUnits]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun closeUnits(closeUnits: Float) = closeUnits(closeUnits as Float?) - /** - * Sets [Builder.casId] to an arbitrary JSON value. - * - * You should usually call [Builder.casId] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun casId(casId: JsonField) = apply { this.casId = casId } + /** + * Alias for calling [Builder.closeUnits] with `closeUnits.orElse(null)`. + */ + fun closeUnits(closeUnits: Optional) = + closeUnits(closeUnits.getOrNull()) - /** Email address of the investor */ - fun email(email: String) = email(JsonField.of(email)) + /** + * Sets [Builder.closeUnits] to an arbitrary JSON value. + * + * You should usually call [Builder.closeUnits] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun closeUnits(closeUnits: JsonField) = apply { + this.closeUnits = closeUnits + } - /** - * Sets [Builder.email] to an arbitrary JSON value. - * - * You should usually call [Builder.email] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun email(email: JsonField) = apply { this.email = email } + /** Opening balance units for the statement period (beta) */ + fun openUnits(openUnits: Float?) = + openUnits(JsonField.ofNullable(openUnits)) - /** Mobile number of the investor */ - fun mobile(mobile: String) = mobile(JsonField.of(mobile)) + /** + * Alias for [Builder.openUnits]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun openUnits(openUnits: Float) = openUnits(openUnits as Float?) - /** - * Sets [Builder.mobile] to an arbitrary JSON value. - * - * You should usually call [Builder.mobile] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun mobile(mobile: JsonField) = apply { this.mobile = mobile } + /** Alias for calling [Builder.openUnits] with `openUnits.orElse(null)`. */ + fun openUnits(openUnits: Optional) = openUnits(openUnits.getOrNull()) - /** Name of the investor */ - fun name(name: String) = name(JsonField.of(name)) + /** + * Sets [Builder.openUnits] to an arbitrary JSON value. + * + * You should usually call [Builder.openUnits] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun openUnits(openUnits: JsonField) = apply { + this.openUnits = openUnits + } - /** - * Sets [Builder.name] to an arbitrary JSON value. - * - * You should usually call [Builder.name] with a well-typed [String] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported - * value. - */ - fun name(name: JsonField) = apply { this.name = name } + fun additionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } - /** PAN (Permanent Account Number) of the investor */ - fun pan(pan: String) = pan(JsonField.of(pan)) + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } - /** - * Sets [Builder.pan] to an arbitrary JSON value. - * - * You should usually call [Builder.pan] with a well-typed [String] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported - * value. - */ - fun pan(pan: JsonField) = apply { this.pan = pan } + fun putAllAdditionalProperties( + additionalProperties: Map + ) = apply { this.additionalProperties.putAll(additionalProperties) } - /** Postal code of the investor's address */ - fun pincode(pincode: String) = pincode(JsonField.of(pincode)) + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } - /** - * Sets [Builder.pincode] to an arbitrary JSON value. - * - * You should usually call [Builder.pincode] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun pincode(pincode: JsonField) = apply { this.pincode = pincode } + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } + /** + * Returns an immutable instance of [AdditionalInfo]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): AdditionalInfo = + AdditionalInfo( + closeUnits, + openUnits, + additionalProperties.toMutableMap(), + ) + } - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } + private var validated: Boolean = false - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } + fun validate(): AdditionalInfo = apply { + if (validated) { + return@apply + } - fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + closeUnits() + openUnits() + validated = true + } - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + false + } - /** - * Returns an immutable instance of [Investor]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): Investor = - Investor( - address, - casId, - email, - mobile, - name, - pan, - pincode, - additionalProperties.toMutableMap(), - ) - } + /** + * 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 (closeUnits.asKnown().isPresent) 1 else 0) + + (if (openUnits.asKnown().isPresent) 1 else 0) - private var validated: Boolean = false + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - fun validate(): Investor = apply { - if (validated) { - return@apply - } + return other is AdditionalInfo && + closeUnits == other.closeUnits && + openUnits == other.openUnits && + additionalProperties == other.additionalProperties + } - address() - casId() - email() - mobile() - name() - pan() - pincode() - validated = true - } + private val hashCode: Int by lazy { + Objects.hash(closeUnits, openUnits, additionalProperties) + } - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - false - } + override fun hashCode(): Int = hashCode - /** - * 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 (address.asKnown().isPresent) 1 else 0) + - (if (casId.asKnown().isPresent) 1 else 0) + - (if (email.asKnown().isPresent) 1 else 0) + - (if (mobile.asKnown().isPresent) 1 else 0) + - (if (name.asKnown().isPresent) 1 else 0) + - (if (pan.asKnown().isPresent) 1 else 0) + - (if (pincode.asKnown().isPresent) 1 else 0) + override fun toString() = + "AdditionalInfo{closeUnits=$closeUnits, openUnits=$openUnits, additionalProperties=$additionalProperties}" + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + /** + * Unified transaction schema for all holding types (MF folios, equities, bonds, + * etc.) + */ + class Transaction + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val additionalInfo: JsonField, + private val amount: JsonField, + private val balance: JsonField, + private val date: JsonField, + private val description: JsonField, + private val dividendRate: JsonField, + private val nav: JsonField, + private val type: JsonField, + private val units: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("additional_info") + @ExcludeMissing + additionalInfo: JsonField = JsonMissing.of(), + @JsonProperty("amount") + @ExcludeMissing + amount: JsonField = JsonMissing.of(), + @JsonProperty("balance") + @ExcludeMissing + balance: JsonField = JsonMissing.of(), + @JsonProperty("date") + @ExcludeMissing + date: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + description: JsonField = JsonMissing.of(), + @JsonProperty("dividend_rate") + @ExcludeMissing + dividendRate: JsonField = JsonMissing.of(), + @JsonProperty("nav") + @ExcludeMissing + nav: JsonField = JsonMissing.of(), + @JsonProperty("type") + @ExcludeMissing + type: JsonField = JsonMissing.of(), + @JsonProperty("units") + @ExcludeMissing + units: JsonField = JsonMissing.of(), + ) : this( + additionalInfo, + amount, + balance, + date, + description, + dividendRate, + nav, + type, + units, + mutableMapOf(), + ) - return other is Investor && - address == other.address && - casId == other.casId && - email == other.email && - mobile == other.mobile && - name == other.name && - pan == other.pan && - pincode == other.pincode && - additionalProperties == other.additionalProperties - } + /** + * Additional transaction-specific fields that vary by source + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun additionalInfo(): Optional = + additionalInfo.getOptional("additional_info") - private val hashCode: Int by lazy { - Objects.hash(address, casId, email, mobile, name, pan, pincode, additionalProperties) - } + /** + * Transaction amount in currency (computed from units × price/NAV) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun amount(): Optional = amount.getOptional("amount") - override fun hashCode(): Int = hashCode + /** + * Balance units after transaction + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun balance(): Optional = balance.getOptional("balance") - override fun toString() = - "Investor{address=$address, casId=$casId, email=$email, mobile=$mobile, name=$name, pan=$pan, pincode=$pincode, additionalProperties=$additionalProperties}" - } + /** + * Transaction date (YYYY-MM-DD) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun date(): Optional = date.getOptional("date") - class Meta - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val casType: JsonField, - private val generatedAt: JsonField, - private val statementPeriod: JsonField, - private val additionalProperties: MutableMap, - ) { + /** + * Transaction description/particulars + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun description(): Optional = description.getOptional("description") - @JsonCreator - private constructor( - @JsonProperty("cas_type") - @ExcludeMissing - casType: JsonField = JsonMissing.of(), - @JsonProperty("generated_at") - @ExcludeMissing - generatedAt: JsonField = JsonMissing.of(), - @JsonProperty("statement_period") - @ExcludeMissing - statementPeriod: JsonField = JsonMissing.of(), - ) : this(casType, generatedAt, statementPeriod, mutableMapOf()) + /** + * Dividend rate (for DIVIDEND_PAYOUT transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun dividendRate(): Optional = dividendRate.getOptional("dividend_rate") - /** - * Type of CAS detected and processed - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun casType(): Optional = casType.getOptional("cas_type") + /** + * NAV/price per unit on transaction date + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun nav(): Optional = nav.getOptional("nav") - /** - * Timestamp when the response was generated - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun generatedAt(): Optional = generatedAt.getOptional("generated_at") + /** + * Transaction type. Possible values are PURCHASE, PURCHASE_SIP, REDEMPTION, + * SWITCH_IN, SWITCH_IN_MERGER, SWITCH_OUT, SWITCH_OUT_MERGER, DIVIDEND_PAYOUT, + * DIVIDEND_REINVEST, SEGREGATION, STAMP_DUTY_TAX, TDS_TAX, STT_TAX, MISC, + * REVERSAL, UNKNOWN. + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun type(): Optional = type.getOptional("type") - /** - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun statementPeriod(): Optional = - statementPeriod.getOptional("statement_period") + /** + * Number of units involved in transaction + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun units(): Optional = units.getOptional("units") - /** - * Returns the raw JSON value of [casType]. - * - * Unlike [casType], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("cas_type") @ExcludeMissing fun _casType(): JsonField = casType + /** + * Returns the raw JSON value of [additionalInfo]. + * + * Unlike [additionalInfo], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("additional_info") + @ExcludeMissing + fun _additionalInfo(): JsonField = additionalInfo - /** - * Returns the raw JSON value of [generatedAt]. - * - * Unlike [generatedAt], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("generated_at") - @ExcludeMissing - fun _generatedAt(): JsonField = generatedAt + /** + * Returns the raw JSON value of [amount]. + * + * Unlike [amount], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("amount") @ExcludeMissing fun _amount(): JsonField = amount - /** - * Returns the raw JSON value of [statementPeriod]. - * - * Unlike [statementPeriod], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("statement_period") - @ExcludeMissing - fun _statementPeriod(): JsonField = statementPeriod + /** + * Returns the raw JSON value of [balance]. + * + * Unlike [balance], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("balance") + @ExcludeMissing + fun _balance(): JsonField = balance - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } + /** + * Returns the raw JSON value of [date]. + * + * Unlike [date], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("date") @ExcludeMissing fun _date(): JsonField = date - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) + /** + * Returns the raw JSON value of [description]. + * + * Unlike [description], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("description") + @ExcludeMissing + fun _description(): JsonField = description - fun toBuilder() = Builder().from(this) + /** + * Returns the raw JSON value of [dividendRate]. + * + * Unlike [dividendRate], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("dividend_rate") + @ExcludeMissing + fun _dividendRate(): JsonField = dividendRate - companion object { + /** + * Returns the raw JSON value of [nav]. + * + * Unlike [nav], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("nav") @ExcludeMissing fun _nav(): JsonField = nav - /** Returns a mutable builder for constructing an instance of [Meta]. */ - @JvmStatic fun builder() = Builder() - } + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type - /** A builder for [Meta]. */ - class Builder internal constructor() { + /** + * Returns the raw JSON value of [units]. + * + * Unlike [units], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("units") @ExcludeMissing fun _units(): JsonField = units - private var casType: JsonField = JsonMissing.of() - private var generatedAt: JsonField = JsonMissing.of() - private var statementPeriod: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } - @JvmSynthetic - internal fun from(meta: Meta) = apply { - casType = meta.casType - generatedAt = meta.generatedAt - statementPeriod = meta.statementPeriod - additionalProperties = meta.additionalProperties.toMutableMap() - } + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) - /** Type of CAS detected and processed */ - fun casType(casType: CasType) = casType(JsonField.of(casType)) + fun toBuilder() = Builder().from(this) - /** - * Sets [Builder.casType] to an arbitrary JSON value. - * - * You should usually call [Builder.casType] with a well-typed [CasType] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun casType(casType: JsonField) = apply { this.casType = casType } + companion object { - /** Timestamp when the response was generated */ - fun generatedAt(generatedAt: OffsetDateTime) = generatedAt(JsonField.of(generatedAt)) + /** + * Returns a mutable builder for constructing an instance of [Transaction]. + */ + @JvmStatic fun builder() = Builder() + } - /** - * Sets [Builder.generatedAt] to an arbitrary JSON value. - * - * You should usually call [Builder.generatedAt] with a well-typed [OffsetDateTime] - * value instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun generatedAt(generatedAt: JsonField) = apply { - this.generatedAt = generatedAt - } + /** A builder for [Transaction]. */ + class Builder internal constructor() { + + private var additionalInfo: JsonField = JsonMissing.of() + private var amount: JsonField = JsonMissing.of() + private var balance: JsonField = JsonMissing.of() + private var date: JsonField = JsonMissing.of() + private var description: JsonField = JsonMissing.of() + private var dividendRate: JsonField = JsonMissing.of() + private var nav: JsonField = JsonMissing.of() + private var type: JsonField = JsonMissing.of() + private var units: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = + mutableMapOf() + + @JvmSynthetic + internal fun from(transaction: Transaction) = apply { + additionalInfo = transaction.additionalInfo + amount = transaction.amount + balance = transaction.balance + date = transaction.date + description = transaction.description + dividendRate = transaction.dividendRate + nav = transaction.nav + type = transaction.type + units = transaction.units + additionalProperties = transaction.additionalProperties.toMutableMap() + } - fun statementPeriod(statementPeriod: StatementPeriod) = - statementPeriod(JsonField.of(statementPeriod)) + /** Additional transaction-specific fields that vary by source */ + fun additionalInfo(additionalInfo: AdditionalInfo) = + additionalInfo(JsonField.of(additionalInfo)) - /** - * Sets [Builder.statementPeriod] to an arbitrary JSON value. - * - * You should usually call [Builder.statementPeriod] with a well-typed [StatementPeriod] - * value instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun statementPeriod(statementPeriod: JsonField) = apply { - this.statementPeriod = statementPeriod - } + /** + * Sets [Builder.additionalInfo] to an arbitrary JSON value. + * + * You should usually call [Builder.additionalInfo] with a well-typed + * [AdditionalInfo] value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun additionalInfo(additionalInfo: JsonField) = apply { + this.additionalInfo = additionalInfo + } - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } + /** Transaction amount in currency (computed from units × price/NAV) */ + fun amount(amount: Float?) = amount(JsonField.ofNullable(amount)) - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } + /** + * Alias for [Builder.amount]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun amount(amount: Float) = amount(amount as Float?) - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } + /** Alias for calling [Builder.amount] with `amount.orElse(null)`. */ + fun amount(amount: Optional) = amount(amount.getOrNull()) - fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + /** + * Sets [Builder.amount] to an arbitrary JSON value. + * + * You should usually call [Builder.amount] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun amount(amount: JsonField) = apply { this.amount = amount } - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } + /** Balance units after transaction */ + fun balance(balance: Float) = balance(JsonField.of(balance)) - /** - * Returns an immutable instance of [Meta]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): Meta = - Meta(casType, generatedAt, statementPeriod, additionalProperties.toMutableMap()) - } + /** + * Sets [Builder.balance] to an arbitrary JSON value. + * + * You should usually call [Builder.balance] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun balance(balance: JsonField) = apply { this.balance = balance } - private var validated: Boolean = false + /** Transaction date (YYYY-MM-DD) */ + fun date(date: LocalDate) = date(JsonField.of(date)) - fun validate(): Meta = apply { - if (validated) { - return@apply - } + /** + * Sets [Builder.date] to an arbitrary JSON value. + * + * You should usually call [Builder.date] with a well-typed [LocalDate] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun date(date: JsonField) = apply { this.date = date } - casType().ifPresent { it.validate() } - generatedAt() - statementPeriod().ifPresent { it.validate() } - validated = true - } + /** Transaction description/particulars */ + fun description(description: String) = + description(JsonField.of(description)) - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - false - } + /** + * Sets [Builder.description] to an arbitrary JSON value. + * + * You should usually call [Builder.description] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun description(description: JsonField) = apply { + this.description = description + } - /** - * 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 = - (casType.asKnown().getOrNull()?.validity() ?: 0) + - (if (generatedAt.asKnown().isPresent) 1 else 0) + - (statementPeriod.asKnown().getOrNull()?.validity() ?: 0) + /** Dividend rate (for DIVIDEND_PAYOUT transactions) */ + fun dividendRate(dividendRate: Float?) = + dividendRate(JsonField.ofNullable(dividendRate)) - /** Type of CAS detected and processed */ - class CasType @JsonCreator private constructor(private val value: JsonField) : - Enum { + /** + * Alias for [Builder.dividendRate]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun dividendRate(dividendRate: Float) = dividendRate(dividendRate as Float?) - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that doesn't - * match any known member, and you want to know that value. For example, if the SDK is - * on an older version than the API, then the API may respond with new members that the - * SDK is unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + /** + * Alias for calling [Builder.dividendRate] with + * `dividendRate.orElse(null)`. + */ + fun dividendRate(dividendRate: Optional) = + dividendRate(dividendRate.getOrNull()) - companion object { + /** + * Sets [Builder.dividendRate] to an arbitrary JSON value. + * + * You should usually call [Builder.dividendRate] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun dividendRate(dividendRate: JsonField) = apply { + this.dividendRate = dividendRate + } - @JvmField val NSDL = of("NSDL") + /** NAV/price per unit on transaction date */ + fun nav(nav: Float?) = nav(JsonField.ofNullable(nav)) - @JvmField val CDSL = of("CDSL") + /** + * Alias for [Builder.nav]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun nav(nav: Float) = nav(nav as Float?) - @JvmField val CAMS_KFINTECH = of("CAMS_KFINTECH") + /** Alias for calling [Builder.nav] with `nav.orElse(null)`. */ + fun nav(nav: Optional) = nav(nav.getOrNull()) - @JvmStatic fun of(value: String) = CasType(JsonField.of(value)) - } + /** + * Sets [Builder.nav] to an arbitrary JSON value. + * + * You should usually call [Builder.nav] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun nav(nav: JsonField) = apply { this.nav = nav } - /** An enum containing [CasType]'s known values. */ - enum class Known { - NSDL, - CDSL, - CAMS_KFINTECH, - } + /** + * Transaction type. Possible values are PURCHASE, PURCHASE_SIP, REDEMPTION, + * SWITCH_IN, SWITCH_IN_MERGER, SWITCH_OUT, SWITCH_OUT_MERGER, + * DIVIDEND_PAYOUT, DIVIDEND_REINVEST, SEGREGATION, STAMP_DUTY_TAX, TDS_TAX, + * STT_TAX, MISC, REVERSAL, UNKNOWN. + */ + fun type(type: Type) = type(JsonField.of(type)) - /** - * An enum containing [CasType]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [CasType] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For example, if - * the SDK is on an older version than the API, then the API may respond with new - * members that the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - NSDL, - CDSL, - CAMS_KFINTECH, - /** - * An enum member indicating that [CasType] was instantiated with an unknown value. - */ - _UNKNOWN, - } + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun type(type: JsonField) = apply { this.type = type } - /** - * Returns an enum member corresponding to this class instance's value, or - * [Value._UNKNOWN] if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or if you - * want to throw for the unknown case. - */ - fun value(): Value = - when (this) { - NSDL -> Value.NSDL - CDSL -> Value.CDSL - CAMS_KFINTECH -> Value.CAMS_KFINTECH - else -> Value._UNKNOWN - } + /** Number of units involved in transaction */ + fun units(units: Float) = units(JsonField.of(units)) - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known and - * don't want to throw for the unknown case. - * - * @throws CasParserInvalidDataException if this class instance's value is a not a known - * member. - */ - fun known(): Known = - when (this) { - NSDL -> Known.NSDL - CDSL -> Known.CDSL - CAMS_KFINTECH -> Known.CAMS_KFINTECH - else -> throw CasParserInvalidDataException("Unknown CasType: $value") - } + /** + * Sets [Builder.units] to an arbitrary JSON value. + * + * You should usually call [Builder.units] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun units(units: JsonField) = apply { this.units = units } - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily for - * debugging and generally doesn't throw. - * - * @throws CasParserInvalidDataException if this class instance's value does not have - * the expected primitive type. - */ - fun asString(): String = - _value().asString().orElseThrow { - CasParserInvalidDataException("Value is not a String") - } + fun additionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } - private var validated: Boolean = false + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } - fun validate(): CasType = apply { - if (validated) { - return@apply - } + fun putAllAdditionalProperties( + additionalProperties: Map + ) = apply { this.additionalProperties.putAll(additionalProperties) } - known() - validated = true - } + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - false - } + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } - /** - * 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 (value() == Value._UNKNOWN) 0 else 1 + /** + * Returns an immutable instance of [Transaction]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Transaction = + Transaction( + additionalInfo, + amount, + balance, + date, + description, + dividendRate, + nav, + type, + units, + additionalProperties.toMutableMap(), + ) + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + private var validated: Boolean = false - return other is CasType && value == other.value - } + fun validate(): Transaction = apply { + if (validated) { + return@apply + } - override fun hashCode() = value.hashCode() + additionalInfo().ifPresent { it.validate() } + amount() + balance() + date() + description() + dividendRate() + nav() + type().ifPresent { it.validate() } + units() + validated = true + } - override fun toString() = value.toString() - } + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + false + } - class StatementPeriod - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val from: JsonField, - private val to: JsonField, - private val additionalProperties: MutableMap, - ) { + /** + * 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 = + (additionalInfo.asKnown().getOrNull()?.validity() ?: 0) + + (if (amount.asKnown().isPresent) 1 else 0) + + (if (balance.asKnown().isPresent) 1 else 0) + + (if (date.asKnown().isPresent) 1 else 0) + + (if (description.asKnown().isPresent) 1 else 0) + + (if (dividendRate.asKnown().isPresent) 1 else 0) + + (if (nav.asKnown().isPresent) 1 else 0) + + (type.asKnown().getOrNull()?.validity() ?: 0) + + (if (units.asKnown().isPresent) 1 else 0) + + /** Additional transaction-specific fields that vary by source */ + class AdditionalInfo + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val capitalWithdrawal: JsonField, + private val credit: JsonField, + private val debit: JsonField, + private val incomeDistribution: JsonField, + private val orderNo: JsonField, + private val price: JsonField, + private val stampDuty: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("capital_withdrawal") + @ExcludeMissing + capitalWithdrawal: JsonField = JsonMissing.of(), + @JsonProperty("credit") + @ExcludeMissing + credit: JsonField = JsonMissing.of(), + @JsonProperty("debit") + @ExcludeMissing + debit: JsonField = JsonMissing.of(), + @JsonProperty("income_distribution") + @ExcludeMissing + incomeDistribution: JsonField = JsonMissing.of(), + @JsonProperty("order_no") + @ExcludeMissing + orderNo: JsonField = JsonMissing.of(), + @JsonProperty("price") + @ExcludeMissing + price: JsonField = JsonMissing.of(), + @JsonProperty("stamp_duty") + @ExcludeMissing + stampDuty: JsonField = JsonMissing.of(), + ) : this( + capitalWithdrawal, + credit, + debit, + incomeDistribution, + orderNo, + price, + stampDuty, + mutableMapOf(), + ) - @JsonCreator - private constructor( - @JsonProperty("from") @ExcludeMissing from: JsonField = JsonMissing.of(), - @JsonProperty("to") @ExcludeMissing to: JsonField = JsonMissing.of(), - ) : this(from, to, mutableMapOf()) + /** + * Capital withdrawal amount (CDSL MF transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun capitalWithdrawal(): Optional = + capitalWithdrawal.getOptional("capital_withdrawal") - /** - * Start date of the statement period - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun from(): Optional = from.getOptional("from") + /** + * Units credited (demat transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun credit(): Optional = credit.getOptional("credit") - /** - * End date of the statement period - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun to(): Optional = to.getOptional("to") + /** + * Units debited (demat transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun debit(): Optional = debit.getOptional("debit") - /** - * Returns the raw JSON value of [from]. - * - * Unlike [from], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("from") @ExcludeMissing fun _from(): JsonField = from + /** + * Income distribution amount (CDSL MF transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun incomeDistribution(): Optional = + incomeDistribution.getOptional("income_distribution") - /** - * Returns the raw JSON value of [to]. - * - * Unlike [to], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("to") @ExcludeMissing fun _to(): JsonField = to + /** + * Order/transaction reference number (demat transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun orderNo(): Optional = orderNo.getOptional("order_no") - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } + /** + * Price per unit (NSDL/CDSL MF transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun price(): Optional = price.getOptional("price") - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) + /** + * Stamp duty charged + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun stampDuty(): Optional = stampDuty.getOptional("stamp_duty") - fun toBuilder() = Builder().from(this) + /** + * Returns the raw JSON value of [capitalWithdrawal]. + * + * Unlike [capitalWithdrawal], this method doesn't throw if the JSON field + * has an unexpected type. + */ + @JsonProperty("capital_withdrawal") + @ExcludeMissing + fun _capitalWithdrawal(): JsonField = capitalWithdrawal - companion object { + /** + * Returns the raw JSON value of [credit]. + * + * Unlike [credit], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("credit") + @ExcludeMissing + fun _credit(): JsonField = credit - /** Returns a mutable builder for constructing an instance of [StatementPeriod]. */ - @JvmStatic fun builder() = Builder() - } + /** + * Returns the raw JSON value of [debit]. + * + * Unlike [debit], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("debit") + @ExcludeMissing + fun _debit(): JsonField = debit - /** A builder for [StatementPeriod]. */ - class Builder internal constructor() { + /** + * Returns the raw JSON value of [incomeDistribution]. + * + * Unlike [incomeDistribution], this method doesn't throw if the JSON field + * has an unexpected type. + */ + @JsonProperty("income_distribution") + @ExcludeMissing + fun _incomeDistribution(): JsonField = incomeDistribution - private var from: JsonField = JsonMissing.of() - private var to: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() + /** + * Returns the raw JSON value of [orderNo]. + * + * Unlike [orderNo], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("order_no") + @ExcludeMissing + fun _orderNo(): JsonField = orderNo - @JvmSynthetic - internal fun from(statementPeriod: StatementPeriod) = apply { - from = statementPeriod.from - to = statementPeriod.to - additionalProperties = statementPeriod.additionalProperties.toMutableMap() - } + /** + * Returns the raw JSON value of [price]. + * + * Unlike [price], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("price") + @ExcludeMissing + fun _price(): JsonField = price - /** Start date of the statement period */ - fun from(from: LocalDate) = from(JsonField.of(from)) + /** + * Returns the raw JSON value of [stampDuty]. + * + * Unlike [stampDuty], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("stamp_duty") + @ExcludeMissing + fun _stampDuty(): JsonField = stampDuty - /** - * Sets [Builder.from] to an arbitrary JSON value. - * - * You should usually call [Builder.from] with a well-typed [LocalDate] value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. - */ - fun from(from: JsonField) = apply { this.from = from } + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } - /** End date of the statement period */ - fun to(to: LocalDate) = to(JsonField.of(to)) + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) - /** - * Sets [Builder.to] to an arbitrary JSON value. - * - * You should usually call [Builder.to] with a well-typed [LocalDate] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun to(to: JsonField) = apply { this.to = to } + fun toBuilder() = Builder().from(this) - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } + companion object { - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } + /** + * Returns a mutable builder for constructing an instance of + * [AdditionalInfo]. + */ + @JvmStatic fun builder() = Builder() + } - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) + /** A builder for [AdditionalInfo]. */ + class Builder internal constructor() { + + private var capitalWithdrawal: JsonField = JsonMissing.of() + private var credit: JsonField = JsonMissing.of() + private var debit: JsonField = JsonMissing.of() + private var incomeDistribution: JsonField = JsonMissing.of() + private var orderNo: JsonField = JsonMissing.of() + private var price: JsonField = JsonMissing.of() + private var stampDuty: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = + mutableMapOf() + + @JvmSynthetic + internal fun from(additionalInfo: AdditionalInfo) = apply { + capitalWithdrawal = additionalInfo.capitalWithdrawal + credit = additionalInfo.credit + debit = additionalInfo.debit + incomeDistribution = additionalInfo.incomeDistribution + orderNo = additionalInfo.orderNo + price = additionalInfo.price + stampDuty = additionalInfo.stampDuty + additionalProperties = + additionalInfo.additionalProperties.toMutableMap() + } + + /** Capital withdrawal amount (CDSL MF transactions) */ + fun capitalWithdrawal(capitalWithdrawal: Float) = + capitalWithdrawal(JsonField.of(capitalWithdrawal)) + + /** + * Sets [Builder.capitalWithdrawal] to an arbitrary JSON value. + * + * You should usually call [Builder.capitalWithdrawal] with a well-typed + * [Float] value instead. This method is primarily for setting the field + * to an undocumented or not yet supported value. + */ + fun capitalWithdrawal(capitalWithdrawal: JsonField) = apply { + this.capitalWithdrawal = capitalWithdrawal + } + + /** Units credited (demat transactions) */ + fun credit(credit: Float) = credit(JsonField.of(credit)) + + /** + * Sets [Builder.credit] to an arbitrary JSON value. + * + * You should usually call [Builder.credit] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun credit(credit: JsonField) = apply { this.credit = credit } + + /** Units debited (demat transactions) */ + fun debit(debit: Float) = debit(JsonField.of(debit)) + + /** + * Sets [Builder.debit] to an arbitrary JSON value. + * + * You should usually call [Builder.debit] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun debit(debit: JsonField) = apply { this.debit = debit } + + /** Income distribution amount (CDSL MF transactions) */ + fun incomeDistribution(incomeDistribution: Float) = + incomeDistribution(JsonField.of(incomeDistribution)) + + /** + * Sets [Builder.incomeDistribution] to an arbitrary JSON value. + * + * You should usually call [Builder.incomeDistribution] with a + * well-typed [Float] value instead. This method is primarily for + * setting the field to an undocumented or not yet supported value. + */ + fun incomeDistribution(incomeDistribution: JsonField) = apply { + this.incomeDistribution = incomeDistribution + } + + /** Order/transaction reference number (demat transactions) */ + fun orderNo(orderNo: String) = orderNo(JsonField.of(orderNo)) + + /** + * Sets [Builder.orderNo] to an arbitrary JSON value. + * + * You should usually call [Builder.orderNo] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun orderNo(orderNo: JsonField) = apply { + this.orderNo = orderNo + } + + /** Price per unit (NSDL/CDSL MF transactions) */ + fun price(price: Float) = price(JsonField.of(price)) + + /** + * Sets [Builder.price] to an arbitrary JSON value. + * + * You should usually call [Builder.price] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun price(price: JsonField) = apply { this.price = price } + + /** Stamp duty charged */ + fun stampDuty(stampDuty: Float) = stampDuty(JsonField.of(stampDuty)) + + /** + * Sets [Builder.stampDuty] to an arbitrary JSON value. + * + * You should usually call [Builder.stampDuty] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun stampDuty(stampDuty: JsonField) = apply { + this.stampDuty = stampDuty + } + + 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 [AdditionalInfo]. + * + * Further updates to this [Builder] will not mutate the returned + * instance. + */ + fun build(): AdditionalInfo = + AdditionalInfo( + capitalWithdrawal, + credit, + debit, + incomeDistribution, + orderNo, + price, + stampDuty, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): AdditionalInfo = apply { + if (validated) { + return@apply + } + + capitalWithdrawal() + credit() + debit() + incomeDistribution() + orderNo() + price() + stampDuty() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (capitalWithdrawal.asKnown().isPresent) 1 else 0) + + (if (credit.asKnown().isPresent) 1 else 0) + + (if (debit.asKnown().isPresent) 1 else 0) + + (if (incomeDistribution.asKnown().isPresent) 1 else 0) + + (if (orderNo.asKnown().isPresent) 1 else 0) + + (if (price.asKnown().isPresent) 1 else 0) + + (if (stampDuty.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AdditionalInfo && + capitalWithdrawal == other.capitalWithdrawal && + credit == other.credit && + debit == other.debit && + incomeDistribution == other.incomeDistribution && + orderNo == other.orderNo && + price == other.price && + stampDuty == other.stampDuty && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + capitalWithdrawal, + credit, + debit, + incomeDistribution, + orderNo, + price, + stampDuty, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AdditionalInfo{capitalWithdrawal=$capitalWithdrawal, credit=$credit, debit=$debit, incomeDistribution=$incomeDistribution, orderNo=$orderNo, price=$price, stampDuty=$stampDuty, additionalProperties=$additionalProperties}" } - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) - } + /** + * Transaction type. Possible values are PURCHASE, PURCHASE_SIP, REDEMPTION, + * SWITCH_IN, SWITCH_IN_MERGER, SWITCH_OUT, SWITCH_OUT_MERGER, DIVIDEND_PAYOUT, + * DIVIDEND_REINVEST, SEGREGATION, STAMP_DUTY_TAX, TDS_TAX, STT_TAX, MISC, + * REVERSAL, UNKNOWN. + */ + class Type + @JsonCreator + private constructor(private val value: JsonField) : Enum { - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data + * that doesn't match any known member, and you want to know that value. For + * example, if the SDK is on an older version than the API, then the API may + * respond with new members that the SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue + fun _value(): JsonField = value - /** - * Returns an immutable instance of [StatementPeriod]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): StatementPeriod = - StatementPeriod(from, to, additionalProperties.toMutableMap()) - } + companion object { - private var validated: Boolean = false + @JvmField val PURCHASE = of("PURCHASE") - fun validate(): StatementPeriod = apply { - if (validated) { - return@apply - } + @JvmField val PURCHASE_SIP = of("PURCHASE_SIP") - from() - to() - validated = true - } + @JvmField val REDEMPTION = of("REDEMPTION") - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - false - } + @JvmField val SWITCH_IN = of("SWITCH_IN") - /** - * 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 (from.asKnown().isPresent) 1 else 0) + (if (to.asKnown().isPresent) 1 else 0) + @JvmField val SWITCH_IN_MERGER = of("SWITCH_IN_MERGER") - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + @JvmField val SWITCH_OUT = of("SWITCH_OUT") - return other is StatementPeriod && - from == other.from && - to == other.to && - additionalProperties == other.additionalProperties - } + @JvmField val SWITCH_OUT_MERGER = of("SWITCH_OUT_MERGER") - private val hashCode: Int by lazy { Objects.hash(from, to, additionalProperties) } + @JvmField val DIVIDEND_PAYOUT = of("DIVIDEND_PAYOUT") - override fun hashCode(): Int = hashCode + @JvmField val DIVIDEND_REINVEST = of("DIVIDEND_REINVEST") - override fun toString() = - "StatementPeriod{from=$from, to=$to, additionalProperties=$additionalProperties}" - } + @JvmField val SEGREGATION = of("SEGREGATION") - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + @JvmField val STAMP_DUTY_TAX = of("STAMP_DUTY_TAX") - return other is Meta && - casType == other.casType && - generatedAt == other.generatedAt && - statementPeriod == other.statementPeriod && - additionalProperties == other.additionalProperties - } + @JvmField val TDS_TAX = of("TDS_TAX") - private val hashCode: Int by lazy { - Objects.hash(casType, generatedAt, statementPeriod, additionalProperties) - } + @JvmField val STT_TAX = of("STT_TAX") - override fun hashCode(): Int = hashCode + @JvmField val MISC = of("MISC") - override fun toString() = - "Meta{casType=$casType, generatedAt=$generatedAt, statementPeriod=$statementPeriod, additionalProperties=$additionalProperties}" - } + @JvmField val REVERSAL = of("REVERSAL") - class MutualFund - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val additionalInfo: JsonField, - private val amc: JsonField, - private val folioNumber: JsonField, - private val linkedHolders: JsonField>, - private val registrar: JsonField, - private val schemes: JsonField>, - private val value: JsonField, - private val additionalProperties: MutableMap, - ) { + @JvmField val UNKNOWN = of("UNKNOWN") - @JsonCreator - private constructor( - @JsonProperty("additional_info") - @ExcludeMissing - additionalInfo: JsonField = JsonMissing.of(), - @JsonProperty("amc") @ExcludeMissing amc: JsonField = JsonMissing.of(), - @JsonProperty("folio_number") - @ExcludeMissing - folioNumber: JsonField = JsonMissing.of(), - @JsonProperty("linked_holders") - @ExcludeMissing - linkedHolders: JsonField> = JsonMissing.of(), - @JsonProperty("registrar") - @ExcludeMissing - registrar: JsonField = JsonMissing.of(), - @JsonProperty("schemes") - @ExcludeMissing - schemes: JsonField> = JsonMissing.of(), - @JsonProperty("value") @ExcludeMissing value: JsonField = JsonMissing.of(), - ) : this( - additionalInfo, - amc, - folioNumber, - linkedHolders, - registrar, - schemes, - value, - mutableMapOf(), - ) + @JvmStatic fun of(value: String) = Type(JsonField.of(value)) + } - /** - * Additional folio information - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun additionalInfo(): Optional = - additionalInfo.getOptional("additional_info") + /** An enum containing [Type]'s known values. */ + enum class Known { + PURCHASE, + PURCHASE_SIP, + REDEMPTION, + SWITCH_IN, + SWITCH_IN_MERGER, + SWITCH_OUT, + SWITCH_OUT_MERGER, + DIVIDEND_PAYOUT, + DIVIDEND_REINVEST, + SEGREGATION, + STAMP_DUTY_TAX, + TDS_TAX, + STT_TAX, + MISC, + REVERSAL, + UNKNOWN, + } - /** - * Asset Management Company name - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun amc(): Optional = amc.getOptional("amc") + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [Type] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For + * example, if the SDK is on an older version than the API, then the API + * may respond with new members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + PURCHASE, + PURCHASE_SIP, + REDEMPTION, + SWITCH_IN, + SWITCH_IN_MERGER, + SWITCH_OUT, + SWITCH_OUT_MERGER, + DIVIDEND_PAYOUT, + DIVIDEND_REINVEST, + SEGREGATION, + STAMP_DUTY_TAX, + TDS_TAX, + STT_TAX, + MISC, + REVERSAL, + UNKNOWN, + /** + * An enum member indicating that [Type] was instantiated with an + * unknown value. + */ + _UNKNOWN, + } - /** - * Folio number - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun folioNumber(): Optional = folioNumber.getOptional("folio_number") + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always + * known or if you want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + PURCHASE -> Value.PURCHASE + PURCHASE_SIP -> Value.PURCHASE_SIP + REDEMPTION -> Value.REDEMPTION + SWITCH_IN -> Value.SWITCH_IN + SWITCH_IN_MERGER -> Value.SWITCH_IN_MERGER + SWITCH_OUT -> Value.SWITCH_OUT + SWITCH_OUT_MERGER -> Value.SWITCH_OUT_MERGER + DIVIDEND_PAYOUT -> Value.DIVIDEND_PAYOUT + DIVIDEND_REINVEST -> Value.DIVIDEND_REINVEST + SEGREGATION -> Value.SEGREGATION + STAMP_DUTY_TAX -> Value.STAMP_DUTY_TAX + TDS_TAX -> Value.TDS_TAX + STT_TAX -> Value.STT_TAX + MISC -> Value.MISC + REVERSAL -> Value.REVERSAL + UNKNOWN -> Value.UNKNOWN + else -> Value._UNKNOWN + } - /** - * List of account holders linked to this mutual fund folio - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun linkedHolders(): Optional> = - linkedHolders.getOptional("linked_holders") + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always + * known and don't want to throw for the unknown case. + * + * @throws CasParserInvalidDataException if this class instance's value is a + * not a known member. + */ + fun known(): Known = + when (this) { + PURCHASE -> Known.PURCHASE + PURCHASE_SIP -> Known.PURCHASE_SIP + REDEMPTION -> Known.REDEMPTION + SWITCH_IN -> Known.SWITCH_IN + SWITCH_IN_MERGER -> Known.SWITCH_IN_MERGER + SWITCH_OUT -> Known.SWITCH_OUT + SWITCH_OUT_MERGER -> Known.SWITCH_OUT_MERGER + DIVIDEND_PAYOUT -> Known.DIVIDEND_PAYOUT + DIVIDEND_REINVEST -> Known.DIVIDEND_REINVEST + SEGREGATION -> Known.SEGREGATION + STAMP_DUTY_TAX -> Known.STAMP_DUTY_TAX + TDS_TAX -> Known.TDS_TAX + STT_TAX -> Known.STT_TAX + MISC -> Known.MISC + REVERSAL -> Known.REVERSAL + UNKNOWN -> Known.UNKNOWN + else -> throw CasParserInvalidDataException("Unknown Type: $value") + } - /** - * Registrar and Transfer Agent name - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun registrar(): Optional = registrar.getOptional("registrar") + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily + * for debugging and generally doesn't throw. + * + * @throws CasParserInvalidDataException if this class instance's value does + * not have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CasParserInvalidDataException("Value is not a String") + } - /** - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun schemes(): Optional> = schemes.getOptional("schemes") + private var validated: Boolean = false - /** - * Total value of the folio - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun value(): Optional = value.getOptional("value") + fun validate(): Type = apply { + if (validated) { + return@apply + } - /** - * Returns the raw JSON value of [additionalInfo]. - * - * Unlike [additionalInfo], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("additional_info") - @ExcludeMissing - fun _additionalInfo(): JsonField = additionalInfo + known() + validated = true + } - /** - * Returns the raw JSON value of [amc]. - * - * Unlike [amc], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("amc") @ExcludeMissing fun _amc(): JsonField = amc + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + false + } - /** - * Returns the raw JSON value of [folioNumber]. - * - * Unlike [folioNumber], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("folio_number") - @ExcludeMissing - fun _folioNumber(): JsonField = folioNumber + /** + * 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 (value() == Value._UNKNOWN) 0 else 1 - /** - * Returns the raw JSON value of [linkedHolders]. - * - * Unlike [linkedHolders], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("linked_holders") - @ExcludeMissing - fun _linkedHolders(): JsonField> = linkedHolders + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - /** - * Returns the raw JSON value of [registrar]. - * - * Unlike [registrar], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("registrar") @ExcludeMissing fun _registrar(): JsonField = registrar + return other is Type && value == other.value + } - /** - * Returns the raw JSON value of [schemes]. - * - * Unlike [schemes], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("schemes") @ExcludeMissing fun _schemes(): JsonField> = schemes + override fun hashCode() = value.hashCode() - /** - * Returns the raw JSON value of [value]. - * - * Unlike [value], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("value") @ExcludeMissing fun _value(): JsonField = value + override fun toString() = value.toString() + } - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) + return other is Transaction && + additionalInfo == other.additionalInfo && + amount == other.amount && + balance == other.balance && + date == other.date && + description == other.description && + dividendRate == other.dividendRate && + nav == other.nav && + type == other.type && + units == other.units && + additionalProperties == other.additionalProperties + } - fun toBuilder() = Builder().from(this) + private val hashCode: Int by lazy { + Objects.hash( + additionalInfo, + amount, + balance, + date, + description, + dividendRate, + nav, + type, + units, + additionalProperties, + ) + } - companion object { + override fun hashCode(): Int = hashCode - /** Returns a mutable builder for constructing an instance of [MutualFund]. */ - @JvmStatic fun builder() = Builder() - } + override fun toString() = + "Transaction{additionalInfo=$additionalInfo, amount=$amount, balance=$balance, date=$date, description=$description, dividendRate=$dividendRate, nav=$nav, type=$type, units=$units, additionalProperties=$additionalProperties}" + } - /** A builder for [MutualFund]. */ - class Builder internal constructor() { + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - private var additionalInfo: JsonField = JsonMissing.of() - private var amc: JsonField = JsonMissing.of() - private var folioNumber: JsonField = JsonMissing.of() - private var linkedHolders: JsonField>? = null - private var registrar: JsonField = JsonMissing.of() - private var schemes: JsonField>? = null - private var value: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() + return other is DematMutualFund && + additionalInfo == other.additionalInfo && + isin == other.isin && + name == other.name && + transactions == other.transactions && + units == other.units && + value == other.value && + additionalProperties == other.additionalProperties + } - @JvmSynthetic - internal fun from(mutualFund: MutualFund) = apply { - additionalInfo = mutualFund.additionalInfo - amc = mutualFund.amc - folioNumber = mutualFund.folioNumber - linkedHolders = mutualFund.linkedHolders.map { it.toMutableList() } - registrar = mutualFund.registrar - schemes = mutualFund.schemes.map { it.toMutableList() } - value = mutualFund.value - additionalProperties = mutualFund.additionalProperties.toMutableMap() - } + private val hashCode: Int by lazy { + Objects.hash( + additionalInfo, + isin, + name, + transactions, + units, + value, + additionalProperties, + ) + } - /** Additional folio information */ - fun additionalInfo(additionalInfo: AdditionalInfo) = - additionalInfo(JsonField.of(additionalInfo)) + override fun hashCode(): Int = hashCode - /** - * Sets [Builder.additionalInfo] to an arbitrary JSON value. - * - * You should usually call [Builder.additionalInfo] with a well-typed [AdditionalInfo] - * value instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun additionalInfo(additionalInfo: JsonField) = apply { - this.additionalInfo = additionalInfo + override fun toString() = + "DematMutualFund{additionalInfo=$additionalInfo, isin=$isin, name=$name, transactions=$transactions, units=$units, value=$value, additionalProperties=$additionalProperties}" } - /** Asset Management Company name */ - fun amc(amc: String) = amc(JsonField.of(amc)) - - /** - * Sets [Builder.amc] to an arbitrary JSON value. - * - * You should usually call [Builder.amc] with a well-typed [String] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported - * value. - */ - fun amc(amc: JsonField) = apply { this.amc = amc } + class Equity + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val additionalInfo: JsonField, + private val isin: JsonField, + private val name: JsonField, + private val transactions: JsonField>, + private val units: JsonField, + private val value: JsonField, + private val additionalProperties: MutableMap, + ) { - /** Folio number */ - fun folioNumber(folioNumber: String) = folioNumber(JsonField.of(folioNumber)) + @JsonCreator + private constructor( + @JsonProperty("additional_info") + @ExcludeMissing + additionalInfo: JsonField = JsonMissing.of(), + @JsonProperty("isin") + @ExcludeMissing + isin: JsonField = JsonMissing.of(), + @JsonProperty("name") + @ExcludeMissing + name: JsonField = JsonMissing.of(), + @JsonProperty("transactions") + @ExcludeMissing + transactions: JsonField> = JsonMissing.of(), + @JsonProperty("units") + @ExcludeMissing + units: JsonField = JsonMissing.of(), + @JsonProperty("value") + @ExcludeMissing + value: JsonField = JsonMissing.of(), + ) : this(additionalInfo, isin, name, transactions, units, value, mutableMapOf()) - /** - * Sets [Builder.folioNumber] to an arbitrary JSON value. - * - * You should usually call [Builder.folioNumber] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun folioNumber(folioNumber: JsonField) = apply { - this.folioNumber = folioNumber - } + /** + * Additional information specific to the equity + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun additionalInfo(): Optional = + additionalInfo.getOptional("additional_info") - /** List of account holders linked to this mutual fund folio */ - fun linkedHolders(linkedHolders: List) = - linkedHolders(JsonField.of(linkedHolders)) + /** + * ISIN code of the equity + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun isin(): Optional = isin.getOptional("isin") - /** - * Sets [Builder.linkedHolders] to an arbitrary JSON value. - * - * You should usually call [Builder.linkedHolders] with a well-typed - * `List` value instead. This method is primarily for setting the field to - * an undocumented or not yet supported value. - */ - fun linkedHolders(linkedHolders: JsonField>) = apply { - this.linkedHolders = linkedHolders.map { it.toMutableList() } - } + /** + * Name of the equity + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun name(): Optional = name.getOptional("name") - /** - * Adds a single [LinkedHolder] to [linkedHolders]. - * - * @throws IllegalStateException if the field was previously set to a non-list. - */ - fun addLinkedHolder(linkedHolder: LinkedHolder) = apply { - linkedHolders = - (linkedHolders ?: JsonField.of(mutableListOf())).also { - checkKnown("linkedHolders", it).add(linkedHolder) - } - } + /** + * List of transactions for this holding (beta) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun transactions(): Optional> = + transactions.getOptional("transactions") - /** Registrar and Transfer Agent name */ - fun registrar(registrar: String) = registrar(JsonField.of(registrar)) + /** + * Number of units held + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun units(): Optional = units.getOptional("units") - /** - * Sets [Builder.registrar] to an arbitrary JSON value. - * - * You should usually call [Builder.registrar] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun registrar(registrar: JsonField) = apply { this.registrar = registrar } + /** + * Current market value of the holding + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun value(): Optional = value.getOptional("value") - fun schemes(schemes: List) = schemes(JsonField.of(schemes)) + /** + * Returns the raw JSON value of [additionalInfo]. + * + * Unlike [additionalInfo], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("additional_info") + @ExcludeMissing + fun _additionalInfo(): JsonField = additionalInfo - /** - * Sets [Builder.schemes] to an arbitrary JSON value. - * - * You should usually call [Builder.schemes] with a well-typed `List` value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun schemes(schemes: JsonField>) = apply { - this.schemes = schemes.map { it.toMutableList() } - } + /** + * Returns the raw JSON value of [isin]. + * + * Unlike [isin], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("isin") @ExcludeMissing fun _isin(): JsonField = isin - /** - * Adds a single [Scheme] to [schemes]. - * - * @throws IllegalStateException if the field was previously set to a non-list. - */ - fun addScheme(scheme: Scheme) = apply { - schemes = - (schemes ?: JsonField.of(mutableListOf())).also { - checkKnown("schemes", it).add(scheme) - } - } + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name - /** Total value of the folio */ - fun value(value: Float) = value(JsonField.of(value)) + /** + * Returns the raw JSON value of [transactions]. + * + * Unlike [transactions], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("transactions") + @ExcludeMissing + fun _transactions(): JsonField> = transactions - /** - * Sets [Builder.value] to an arbitrary JSON value. - * - * You should usually call [Builder.value] with a well-typed [Float] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported - * value. - */ - fun value(value: JsonField) = apply { this.value = value } + /** + * Returns the raw JSON value of [units]. + * + * Unlike [units], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("units") @ExcludeMissing fun _units(): JsonField = units - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } + /** + * Returns the raw JSON value of [value]. + * + * Unlike [value], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("value") @ExcludeMissing fun _value(): JsonField = value - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) - fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + fun toBuilder() = Builder().from(this) - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } + companion object { - /** - * Returns an immutable instance of [MutualFund]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): MutualFund = - MutualFund( - additionalInfo, - amc, - folioNumber, - (linkedHolders ?: JsonMissing.of()).map { it.toImmutable() }, - registrar, - (schemes ?: JsonMissing.of()).map { it.toImmutable() }, - value, - additionalProperties.toMutableMap(), - ) - } + /** Returns a mutable builder for constructing an instance of [Equity]. */ + @JvmStatic fun builder() = Builder() + } - private var validated: Boolean = false + /** A builder for [Equity]. */ + class Builder internal constructor() { - fun validate(): MutualFund = apply { - if (validated) { - return@apply - } + private var additionalInfo: JsonField = JsonMissing.of() + private var isin: JsonField = JsonMissing.of() + private var name: JsonField = JsonMissing.of() + private var transactions: JsonField>? = null + private var units: JsonField = JsonMissing.of() + private var value: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() - additionalInfo().ifPresent { it.validate() } - amc() - folioNumber() - linkedHolders().ifPresent { it.forEach { it.validate() } } - registrar() - schemes().ifPresent { it.forEach { it.validate() } } - value() - validated = true - } + @JvmSynthetic + internal fun from(equity: Equity) = apply { + additionalInfo = equity.additionalInfo + isin = equity.isin + name = equity.name + transactions = equity.transactions.map { it.toMutableList() } + units = equity.units + value = equity.value + additionalProperties = equity.additionalProperties.toMutableMap() + } - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - false - } + /** Additional information specific to the equity */ + fun additionalInfo(additionalInfo: AdditionalInfo) = + additionalInfo(JsonField.of(additionalInfo)) - /** - * 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 = - (additionalInfo.asKnown().getOrNull()?.validity() ?: 0) + - (if (amc.asKnown().isPresent) 1 else 0) + - (if (folioNumber.asKnown().isPresent) 1 else 0) + - (linkedHolders.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + - (if (registrar.asKnown().isPresent) 1 else 0) + - (schemes.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + - (if (value.asKnown().isPresent) 1 else 0) + /** + * Sets [Builder.additionalInfo] to an arbitrary JSON value. + * + * You should usually call [Builder.additionalInfo] with a well-typed + * [AdditionalInfo] value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun additionalInfo(additionalInfo: JsonField) = apply { + this.additionalInfo = additionalInfo + } - /** Additional folio information */ - class AdditionalInfo - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val kyc: JsonField, - private val pan: JsonField, - private val pankyc: JsonField, - private val additionalProperties: MutableMap, - ) { + /** ISIN code of the equity */ + fun isin(isin: String) = isin(JsonField.of(isin)) - @JsonCreator - private constructor( - @JsonProperty("kyc") @ExcludeMissing kyc: JsonField = JsonMissing.of(), - @JsonProperty("pan") @ExcludeMissing pan: JsonField = JsonMissing.of(), - @JsonProperty("pankyc") @ExcludeMissing pankyc: JsonField = JsonMissing.of(), - ) : this(kyc, pan, pankyc, mutableMapOf()) + /** + * Sets [Builder.isin] to an arbitrary JSON value. + * + * You should usually call [Builder.isin] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun isin(isin: JsonField) = apply { this.isin = isin } - /** - * KYC status of the folio - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun kyc(): Optional = kyc.getOptional("kyc") + /** Name of the equity */ + fun name(name: String) = name(JsonField.of(name)) - /** - * PAN associated with the folio - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun pan(): Optional = pan.getOptional("pan") + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun name(name: JsonField) = apply { this.name = name } - /** - * PAN KYC status - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun pankyc(): Optional = pankyc.getOptional("pankyc") + /** List of transactions for this holding (beta) */ + fun transactions(transactions: List) = + transactions(JsonField.of(transactions)) - /** - * Returns the raw JSON value of [kyc]. - * - * Unlike [kyc], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("kyc") @ExcludeMissing fun _kyc(): JsonField = kyc + /** + * Sets [Builder.transactions] to an arbitrary JSON value. + * + * You should usually call [Builder.transactions] with a well-typed + * `List` value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun transactions(transactions: JsonField>) = apply { + this.transactions = transactions.map { it.toMutableList() } + } - /** - * Returns the raw JSON value of [pan]. - * - * Unlike [pan], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("pan") @ExcludeMissing fun _pan(): JsonField = pan + /** + * Adds a single [Transaction] to [transactions]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addTransaction(transaction: Transaction) = apply { + transactions = + (transactions ?: JsonField.of(mutableListOf())).also { + checkKnown("transactions", it).add(transaction) + } + } - /** - * Returns the raw JSON value of [pankyc]. - * - * Unlike [pankyc], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("pankyc") @ExcludeMissing fun _pankyc(): JsonField = pankyc + /** Number of units held */ + fun units(units: Float) = units(JsonField.of(units)) - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } + /** + * Sets [Builder.units] to an arbitrary JSON value. + * + * You should usually call [Builder.units] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun units(units: JsonField) = apply { this.units = units } - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) + /** Current market value of the holding */ + fun value(value: Float) = value(JsonField.of(value)) - fun toBuilder() = Builder().from(this) + /** + * Sets [Builder.value] to an arbitrary JSON value. + * + * You should usually call [Builder.value] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun value(value: JsonField) = apply { this.value = value } - companion object { + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } - /** Returns a mutable builder for constructing an instance of [AdditionalInfo]. */ - @JvmStatic fun builder() = Builder() - } + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } - /** A builder for [AdditionalInfo]. */ - class Builder internal constructor() { + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } - private var kyc: JsonField = JsonMissing.of() - private var pan: JsonField = JsonMissing.of() - private var pankyc: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } - @JvmSynthetic - internal fun from(additionalInfo: AdditionalInfo) = apply { - kyc = additionalInfo.kyc - pan = additionalInfo.pan - pankyc = additionalInfo.pankyc - additionalProperties = additionalInfo.additionalProperties.toMutableMap() + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Equity]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Equity = + Equity( + additionalInfo, + isin, + name, + (transactions ?: JsonMissing.of()).map { it.toImmutable() }, + units, + value, + additionalProperties.toMutableMap(), + ) } - /** KYC status of the folio */ - fun kyc(kyc: String) = kyc(JsonField.of(kyc)) + private var validated: Boolean = false - /** - * Sets [Builder.kyc] to an arbitrary JSON value. - * - * You should usually call [Builder.kyc] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun kyc(kyc: JsonField) = apply { this.kyc = kyc } + fun validate(): Equity = apply { + if (validated) { + return@apply + } - /** PAN associated with the folio */ - fun pan(pan: String) = pan(JsonField.of(pan)) + additionalInfo().ifPresent { it.validate() } + isin() + name() + transactions().ifPresent { it.forEach { it.validate() } } + units() + value() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + false + } /** - * Sets [Builder.pan] to an arbitrary JSON value. + * Returns a score indicating how many valid values are contained in this object + * recursively. * - * You should usually call [Builder.pan] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. + * Used for best match union deserialization. */ - fun pan(pan: JsonField) = apply { this.pan = pan } + @JvmSynthetic + internal fun validity(): Int = + (additionalInfo.asKnown().getOrNull()?.validity() ?: 0) + + (if (isin.asKnown().isPresent) 1 else 0) + + (if (name.asKnown().isPresent) 1 else 0) + + (transactions.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (units.asKnown().isPresent) 1 else 0) + + (if (value.asKnown().isPresent) 1 else 0) - /** PAN KYC status */ - fun pankyc(pankyc: String) = pankyc(JsonField.of(pankyc)) + /** Additional information specific to the equity */ + class AdditionalInfo + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val closeUnits: JsonField, + private val openUnits: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("close_units") + @ExcludeMissing + closeUnits: JsonField = JsonMissing.of(), + @JsonProperty("open_units") + @ExcludeMissing + openUnits: JsonField = JsonMissing.of(), + ) : this(closeUnits, openUnits, mutableMapOf()) - /** - * Sets [Builder.pankyc] to an arbitrary JSON value. - * - * You should usually call [Builder.pankyc] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. - */ - fun pankyc(pankyc: JsonField) = apply { this.pankyc = pankyc } + /** + * Closing balance units for the statement period (beta) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun closeUnits(): Optional = closeUnits.getOptional("close_units") - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } + /** + * Opening balance units for the statement period (beta) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun openUnits(): Optional = openUnits.getOptional("open_units") - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } + /** + * Returns the raw JSON value of [closeUnits]. + * + * Unlike [closeUnits], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("close_units") + @ExcludeMissing + fun _closeUnits(): JsonField = closeUnits - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) + /** + * Returns the raw JSON value of [openUnits]. + * + * Unlike [openUnits], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("open_units") + @ExcludeMissing + fun _openUnits(): JsonField = openUnits + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) } - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) - } + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } + fun toBuilder() = Builder().from(this) - /** - * Returns an immutable instance of [AdditionalInfo]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): AdditionalInfo = - AdditionalInfo(kyc, pan, pankyc, additionalProperties.toMutableMap()) - } + companion object { - private var validated: Boolean = false + /** + * Returns a mutable builder for constructing an instance of + * [AdditionalInfo]. + */ + @JvmStatic fun builder() = Builder() + } - fun validate(): AdditionalInfo = apply { - if (validated) { - return@apply - } + /** A builder for [AdditionalInfo]. */ + class Builder internal constructor() { - kyc() - pan() - pankyc() - validated = true - } + private var closeUnits: JsonField = JsonMissing.of() + private var openUnits: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = + mutableMapOf() - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - 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 (kyc.asKnown().isPresent) 1 else 0) + - (if (pan.asKnown().isPresent) 1 else 0) + - (if (pankyc.asKnown().isPresent) 1 else 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is AdditionalInfo && - kyc == other.kyc && - pan == other.pan && - pankyc == other.pankyc && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash(kyc, pan, pankyc, additionalProperties) - } - - override fun hashCode(): Int = hashCode + @JvmSynthetic + internal fun from(additionalInfo: AdditionalInfo) = apply { + closeUnits = additionalInfo.closeUnits + openUnits = additionalInfo.openUnits + additionalProperties = + additionalInfo.additionalProperties.toMutableMap() + } - override fun toString() = - "AdditionalInfo{kyc=$kyc, pan=$pan, pankyc=$pankyc, additionalProperties=$additionalProperties}" - } + /** Closing balance units for the statement period (beta) */ + fun closeUnits(closeUnits: Float?) = + closeUnits(JsonField.ofNullable(closeUnits)) - class LinkedHolder - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val name: JsonField, - private val pan: JsonField, - private val additionalProperties: MutableMap, - ) { + /** + * Alias for [Builder.closeUnits]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun closeUnits(closeUnits: Float) = closeUnits(closeUnits as Float?) - @JsonCreator - private constructor( - @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), - @JsonProperty("pan") @ExcludeMissing pan: JsonField = JsonMissing.of(), - ) : this(name, pan, mutableMapOf()) + /** + * Alias for calling [Builder.closeUnits] with `closeUnits.orElse(null)`. + */ + fun closeUnits(closeUnits: Optional) = + closeUnits(closeUnits.getOrNull()) - /** - * Name of the account holder - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun name(): Optional = name.getOptional("name") + /** + * Sets [Builder.closeUnits] to an arbitrary JSON value. + * + * You should usually call [Builder.closeUnits] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun closeUnits(closeUnits: JsonField) = apply { + this.closeUnits = closeUnits + } - /** - * PAN of the account holder - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun pan(): Optional = pan.getOptional("pan") + /** Opening balance units for the statement period (beta) */ + fun openUnits(openUnits: Float?) = + openUnits(JsonField.ofNullable(openUnits)) - /** - * Returns the raw JSON value of [name]. - * - * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + /** + * Alias for [Builder.openUnits]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun openUnits(openUnits: Float) = openUnits(openUnits as Float?) - /** - * Returns the raw JSON value of [pan]. - * - * Unlike [pan], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("pan") @ExcludeMissing fun _pan(): JsonField = pan + /** Alias for calling [Builder.openUnits] with `openUnits.orElse(null)`. */ + fun openUnits(openUnits: Optional) = openUnits(openUnits.getOrNull()) - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } + /** + * Sets [Builder.openUnits] to an arbitrary JSON value. + * + * You should usually call [Builder.openUnits] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun openUnits(openUnits: JsonField) = apply { + this.openUnits = openUnits + } - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) + fun additionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } - fun toBuilder() = Builder().from(this) + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } - companion object { + fun putAllAdditionalProperties( + additionalProperties: Map + ) = apply { this.additionalProperties.putAll(additionalProperties) } - /** Returns a mutable builder for constructing an instance of [LinkedHolder]. */ - @JvmStatic fun builder() = Builder() - } + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } - /** A builder for [LinkedHolder]. */ - class Builder internal constructor() { + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } - private var name: JsonField = JsonMissing.of() - private var pan: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() + /** + * Returns an immutable instance of [AdditionalInfo]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): AdditionalInfo = + AdditionalInfo( + closeUnits, + openUnits, + additionalProperties.toMutableMap(), + ) + } - @JvmSynthetic - internal fun from(linkedHolder: LinkedHolder) = apply { - name = linkedHolder.name - pan = linkedHolder.pan - additionalProperties = linkedHolder.additionalProperties.toMutableMap() - } + private var validated: Boolean = false - /** Name of the account holder */ - fun name(name: String) = name(JsonField.of(name)) + fun validate(): AdditionalInfo = apply { + if (validated) { + return@apply + } - /** - * Sets [Builder.name] to an arbitrary JSON value. - * - * You should usually call [Builder.name] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun name(name: JsonField) = apply { this.name = name } + closeUnits() + openUnits() + validated = true + } - /** PAN of the account holder */ - fun pan(pan: String) = pan(JsonField.of(pan)) + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + false + } - /** - * Sets [Builder.pan] to an arbitrary JSON value. - * - * You should usually call [Builder.pan] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun pan(pan: JsonField) = apply { this.pan = pan } + /** + * 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 (closeUnits.asKnown().isPresent) 1 else 0) + + (if (openUnits.asKnown().isPresent) 1 else 0) - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } + return other is AdditionalInfo && + closeUnits == other.closeUnits && + openUnits == other.openUnits && + additionalProperties == other.additionalProperties + } - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) + private val hashCode: Int by lazy { + Objects.hash(closeUnits, openUnits, additionalProperties) } - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) - } + override fun hashCode(): Int = hashCode - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) + override fun toString() = + "AdditionalInfo{closeUnits=$closeUnits, openUnits=$openUnits, additionalProperties=$additionalProperties}" } /** - * Returns an immutable instance of [LinkedHolder]. - * - * Further updates to this [Builder] will not mutate the returned instance. + * Unified transaction schema for all holding types (MF folios, equities, bonds, + * etc.) */ - fun build(): LinkedHolder = - LinkedHolder(name, pan, additionalProperties.toMutableMap()) - } - - private var validated: Boolean = false + class Transaction + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val additionalInfo: JsonField, + private val amount: JsonField, + private val balance: JsonField, + private val date: JsonField, + private val description: JsonField, + private val dividendRate: JsonField, + private val nav: JsonField, + private val type: JsonField, + private val units: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("additional_info") + @ExcludeMissing + additionalInfo: JsonField = JsonMissing.of(), + @JsonProperty("amount") + @ExcludeMissing + amount: JsonField = JsonMissing.of(), + @JsonProperty("balance") + @ExcludeMissing + balance: JsonField = JsonMissing.of(), + @JsonProperty("date") + @ExcludeMissing + date: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + description: JsonField = JsonMissing.of(), + @JsonProperty("dividend_rate") + @ExcludeMissing + dividendRate: JsonField = JsonMissing.of(), + @JsonProperty("nav") + @ExcludeMissing + nav: JsonField = JsonMissing.of(), + @JsonProperty("type") + @ExcludeMissing + type: JsonField = JsonMissing.of(), + @JsonProperty("units") + @ExcludeMissing + units: JsonField = JsonMissing.of(), + ) : this( + additionalInfo, + amount, + balance, + date, + description, + dividendRate, + nav, + type, + units, + mutableMapOf(), + ) - fun validate(): LinkedHolder = apply { - if (validated) { - return@apply - } + /** + * Additional transaction-specific fields that vary by source + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun additionalInfo(): Optional = + additionalInfo.getOptional("additional_info") - name() - pan() - validated = true - } + /** + * Transaction amount in currency (computed from units × price/NAV) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun amount(): Optional = amount.getOptional("amount") - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - false - } + /** + * Balance units after transaction + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun balance(): Optional = balance.getOptional("balance") - /** - * 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 (name.asKnown().isPresent) 1 else 0) + (if (pan.asKnown().isPresent) 1 else 0) + /** + * Transaction date (YYYY-MM-DD) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun date(): Optional = date.getOptional("date") - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + /** + * Transaction description/particulars + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun description(): Optional = description.getOptional("description") - return other is LinkedHolder && - name == other.name && - pan == other.pan && - additionalProperties == other.additionalProperties - } + /** + * Dividend rate (for DIVIDEND_PAYOUT transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun dividendRate(): Optional = dividendRate.getOptional("dividend_rate") - private val hashCode: Int by lazy { Objects.hash(name, pan, additionalProperties) } + /** + * NAV/price per unit on transaction date + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun nav(): Optional = nav.getOptional("nav") - override fun hashCode(): Int = hashCode + /** + * Transaction type. Possible values are PURCHASE, PURCHASE_SIP, REDEMPTION, + * SWITCH_IN, SWITCH_IN_MERGER, SWITCH_OUT, SWITCH_OUT_MERGER, DIVIDEND_PAYOUT, + * DIVIDEND_REINVEST, SEGREGATION, STAMP_DUTY_TAX, TDS_TAX, STT_TAX, MISC, + * REVERSAL, UNKNOWN. + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun type(): Optional = type.getOptional("type") - override fun toString() = - "LinkedHolder{name=$name, pan=$pan, additionalProperties=$additionalProperties}" - } + /** + * Number of units involved in transaction + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun units(): Optional = units.getOptional("units") - class Scheme - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val additionalInfo: JsonField, - private val cost: JsonField, - private val gain: JsonField, - private val isin: JsonField, - private val name: JsonField, - private val nav: JsonField, - private val nominees: JsonField>, - private val transactions: JsonField>, - private val type: JsonField, - private val units: JsonField, - private val value: JsonField, - private val additionalProperties: MutableMap, - ) { + /** + * Returns the raw JSON value of [additionalInfo]. + * + * Unlike [additionalInfo], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("additional_info") + @ExcludeMissing + fun _additionalInfo(): JsonField = additionalInfo - @JsonCreator - private constructor( - @JsonProperty("additional_info") - @ExcludeMissing - additionalInfo: JsonField = JsonMissing.of(), - @JsonProperty("cost") @ExcludeMissing cost: JsonField = JsonMissing.of(), - @JsonProperty("gain") @ExcludeMissing gain: JsonField = JsonMissing.of(), - @JsonProperty("isin") @ExcludeMissing isin: JsonField = JsonMissing.of(), - @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), - @JsonProperty("nav") @ExcludeMissing nav: JsonField = JsonMissing.of(), - @JsonProperty("nominees") - @ExcludeMissing - nominees: JsonField> = JsonMissing.of(), - @JsonProperty("transactions") - @ExcludeMissing - transactions: JsonField> = JsonMissing.of(), - @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), - @JsonProperty("units") @ExcludeMissing units: JsonField = JsonMissing.of(), - @JsonProperty("value") @ExcludeMissing value: JsonField = JsonMissing.of(), - ) : this( - additionalInfo, - cost, - gain, - isin, - name, - nav, - nominees, - transactions, - type, - units, - value, - mutableMapOf(), - ) + /** + * Returns the raw JSON value of [amount]. + * + * Unlike [amount], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("amount") @ExcludeMissing fun _amount(): JsonField = amount - /** - * Additional information specific to the scheme - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun additionalInfo(): Optional = - additionalInfo.getOptional("additional_info") + /** + * Returns the raw JSON value of [balance]. + * + * Unlike [balance], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("balance") + @ExcludeMissing + fun _balance(): JsonField = balance - /** - * Cost of investment - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun cost(): Optional = cost.getOptional("cost") + /** + * Returns the raw JSON value of [date]. + * + * Unlike [date], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("date") @ExcludeMissing fun _date(): JsonField = date - /** - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun gain(): Optional = gain.getOptional("gain") + /** + * Returns the raw JSON value of [description]. + * + * Unlike [description], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("description") + @ExcludeMissing + fun _description(): JsonField = description - /** - * ISIN code of the scheme - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun isin(): Optional = isin.getOptional("isin") + /** + * Returns the raw JSON value of [dividendRate]. + * + * Unlike [dividendRate], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("dividend_rate") + @ExcludeMissing + fun _dividendRate(): JsonField = dividendRate - /** - * Scheme name - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun name(): Optional = name.getOptional("name") + /** + * Returns the raw JSON value of [nav]. + * + * Unlike [nav], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("nav") @ExcludeMissing fun _nav(): JsonField = nav - /** - * Net Asset Value per unit - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun nav(): Optional = nav.getOptional("nav") + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type - /** - * List of nominees - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun nominees(): Optional> = nominees.getOptional("nominees") + /** + * Returns the raw JSON value of [units]. + * + * Unlike [units], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("units") @ExcludeMissing fun _units(): JsonField = units - /** - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun transactions(): Optional> = - transactions.getOptional("transactions") + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } - /** - * Type of mutual fund scheme - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun type(): Optional = type.getOptional("type") + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) - /** - * Number of units held - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun units(): Optional = units.getOptional("units") + fun toBuilder() = Builder().from(this) - /** - * Current market value of the holding - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun value(): Optional = value.getOptional("value") + companion object { - /** - * Returns the raw JSON value of [additionalInfo]. - * - * Unlike [additionalInfo], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("additional_info") - @ExcludeMissing - fun _additionalInfo(): JsonField = additionalInfo + /** + * Returns a mutable builder for constructing an instance of [Transaction]. + */ + @JvmStatic fun builder() = Builder() + } - /** - * Returns the raw JSON value of [cost]. - * - * Unlike [cost], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("cost") @ExcludeMissing fun _cost(): JsonField = cost + /** A builder for [Transaction]. */ + class Builder internal constructor() { + + private var additionalInfo: JsonField = JsonMissing.of() + private var amount: JsonField = JsonMissing.of() + private var balance: JsonField = JsonMissing.of() + private var date: JsonField = JsonMissing.of() + private var description: JsonField = JsonMissing.of() + private var dividendRate: JsonField = JsonMissing.of() + private var nav: JsonField = JsonMissing.of() + private var type: JsonField = JsonMissing.of() + private var units: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = + mutableMapOf() + + @JvmSynthetic + internal fun from(transaction: Transaction) = apply { + additionalInfo = transaction.additionalInfo + amount = transaction.amount + balance = transaction.balance + date = transaction.date + description = transaction.description + dividendRate = transaction.dividendRate + nav = transaction.nav + type = transaction.type + units = transaction.units + additionalProperties = transaction.additionalProperties.toMutableMap() + } - /** - * Returns the raw JSON value of [gain]. - * - * Unlike [gain], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("gain") @ExcludeMissing fun _gain(): JsonField = gain + /** Additional transaction-specific fields that vary by source */ + fun additionalInfo(additionalInfo: AdditionalInfo) = + additionalInfo(JsonField.of(additionalInfo)) - /** - * Returns the raw JSON value of [isin]. - * - * Unlike [isin], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("isin") @ExcludeMissing fun _isin(): JsonField = isin + /** + * Sets [Builder.additionalInfo] to an arbitrary JSON value. + * + * You should usually call [Builder.additionalInfo] with a well-typed + * [AdditionalInfo] value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun additionalInfo(additionalInfo: JsonField) = apply { + this.additionalInfo = additionalInfo + } - /** - * Returns the raw JSON value of [name]. - * - * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + /** Transaction amount in currency (computed from units × price/NAV) */ + fun amount(amount: Float?) = amount(JsonField.ofNullable(amount)) - /** - * Returns the raw JSON value of [nav]. - * - * Unlike [nav], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("nav") @ExcludeMissing fun _nav(): JsonField = nav + /** + * Alias for [Builder.amount]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun amount(amount: Float) = amount(amount as Float?) - /** - * Returns the raw JSON value of [nominees]. - * - * Unlike [nominees], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("nominees") - @ExcludeMissing - fun _nominees(): JsonField> = nominees + /** Alias for calling [Builder.amount] with `amount.orElse(null)`. */ + fun amount(amount: Optional) = amount(amount.getOrNull()) - /** - * Returns the raw JSON value of [transactions]. - * - * Unlike [transactions], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("transactions") - @ExcludeMissing - fun _transactions(): JsonField> = transactions + /** + * Sets [Builder.amount] to an arbitrary JSON value. + * + * You should usually call [Builder.amount] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun amount(amount: JsonField) = apply { this.amount = amount } - /** - * Returns the raw JSON value of [type]. - * - * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + /** Balance units after transaction */ + fun balance(balance: Float) = balance(JsonField.of(balance)) - /** - * Returns the raw JSON value of [units]. - * - * Unlike [units], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("units") @ExcludeMissing fun _units(): JsonField = units + /** + * Sets [Builder.balance] to an arbitrary JSON value. + * + * You should usually call [Builder.balance] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun balance(balance: JsonField) = apply { this.balance = balance } - /** + /** Transaction date (YYYY-MM-DD) */ + fun date(date: LocalDate) = date(JsonField.of(date)) + + /** + * Sets [Builder.date] to an arbitrary JSON value. + * + * You should usually call [Builder.date] with a well-typed [LocalDate] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun date(date: JsonField) = apply { this.date = date } + + /** Transaction description/particulars */ + fun description(description: String) = + description(JsonField.of(description)) + + /** + * Sets [Builder.description] to an arbitrary JSON value. + * + * You should usually call [Builder.description] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun description(description: JsonField) = apply { + this.description = description + } + + /** Dividend rate (for DIVIDEND_PAYOUT transactions) */ + fun dividendRate(dividendRate: Float?) = + dividendRate(JsonField.ofNullable(dividendRate)) + + /** + * Alias for [Builder.dividendRate]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun dividendRate(dividendRate: Float) = dividendRate(dividendRate as Float?) + + /** + * Alias for calling [Builder.dividendRate] with + * `dividendRate.orElse(null)`. + */ + fun dividendRate(dividendRate: Optional) = + dividendRate(dividendRate.getOrNull()) + + /** + * Sets [Builder.dividendRate] to an arbitrary JSON value. + * + * You should usually call [Builder.dividendRate] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun dividendRate(dividendRate: JsonField) = apply { + this.dividendRate = dividendRate + } + + /** NAV/price per unit on transaction date */ + fun nav(nav: Float?) = nav(JsonField.ofNullable(nav)) + + /** + * Alias for [Builder.nav]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun nav(nav: Float) = nav(nav as Float?) + + /** Alias for calling [Builder.nav] with `nav.orElse(null)`. */ + fun nav(nav: Optional) = nav(nav.getOrNull()) + + /** + * Sets [Builder.nav] to an arbitrary JSON value. + * + * You should usually call [Builder.nav] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun nav(nav: JsonField) = apply { this.nav = nav } + + /** + * Transaction type. Possible values are PURCHASE, PURCHASE_SIP, REDEMPTION, + * SWITCH_IN, SWITCH_IN_MERGER, SWITCH_OUT, SWITCH_OUT_MERGER, + * DIVIDEND_PAYOUT, DIVIDEND_REINVEST, SEGREGATION, STAMP_DUTY_TAX, TDS_TAX, + * STT_TAX, MISC, REVERSAL, UNKNOWN. + */ + fun type(type: Type) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun type(type: JsonField) = apply { this.type = type } + + /** Number of units involved in transaction */ + fun units(units: Float) = units(JsonField.of(units)) + + /** + * Sets [Builder.units] to an arbitrary JSON value. + * + * You should usually call [Builder.units] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun units(units: JsonField) = apply { this.units = units } + + 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 [Transaction]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Transaction = + Transaction( + additionalInfo, + amount, + balance, + date, + description, + dividendRate, + nav, + type, + units, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Transaction = apply { + if (validated) { + return@apply + } + + additionalInfo().ifPresent { it.validate() } + amount() + balance() + date() + description() + dividendRate() + nav() + type().ifPresent { it.validate() } + units() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 = + (additionalInfo.asKnown().getOrNull()?.validity() ?: 0) + + (if (amount.asKnown().isPresent) 1 else 0) + + (if (balance.asKnown().isPresent) 1 else 0) + + (if (date.asKnown().isPresent) 1 else 0) + + (if (description.asKnown().isPresent) 1 else 0) + + (if (dividendRate.asKnown().isPresent) 1 else 0) + + (if (nav.asKnown().isPresent) 1 else 0) + + (type.asKnown().getOrNull()?.validity() ?: 0) + + (if (units.asKnown().isPresent) 1 else 0) + + /** Additional transaction-specific fields that vary by source */ + class AdditionalInfo + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val capitalWithdrawal: JsonField, + private val credit: JsonField, + private val debit: JsonField, + private val incomeDistribution: JsonField, + private val orderNo: JsonField, + private val price: JsonField, + private val stampDuty: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("capital_withdrawal") + @ExcludeMissing + capitalWithdrawal: JsonField = JsonMissing.of(), + @JsonProperty("credit") + @ExcludeMissing + credit: JsonField = JsonMissing.of(), + @JsonProperty("debit") + @ExcludeMissing + debit: JsonField = JsonMissing.of(), + @JsonProperty("income_distribution") + @ExcludeMissing + incomeDistribution: JsonField = JsonMissing.of(), + @JsonProperty("order_no") + @ExcludeMissing + orderNo: JsonField = JsonMissing.of(), + @JsonProperty("price") + @ExcludeMissing + price: JsonField = JsonMissing.of(), + @JsonProperty("stamp_duty") + @ExcludeMissing + stampDuty: JsonField = JsonMissing.of(), + ) : this( + capitalWithdrawal, + credit, + debit, + incomeDistribution, + orderNo, + price, + stampDuty, + mutableMapOf(), + ) + + /** + * Capital withdrawal amount (CDSL MF transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun capitalWithdrawal(): Optional = + capitalWithdrawal.getOptional("capital_withdrawal") + + /** + * Units credited (demat transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun credit(): Optional = credit.getOptional("credit") + + /** + * Units debited (demat transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun debit(): Optional = debit.getOptional("debit") + + /** + * Income distribution amount (CDSL MF transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun incomeDistribution(): Optional = + incomeDistribution.getOptional("income_distribution") + + /** + * Order/transaction reference number (demat transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun orderNo(): Optional = orderNo.getOptional("order_no") + + /** + * Price per unit (NSDL/CDSL MF transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun price(): Optional = price.getOptional("price") + + /** + * Stamp duty charged + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun stampDuty(): Optional = stampDuty.getOptional("stamp_duty") + + /** + * Returns the raw JSON value of [capitalWithdrawal]. + * + * Unlike [capitalWithdrawal], this method doesn't throw if the JSON field + * has an unexpected type. + */ + @JsonProperty("capital_withdrawal") + @ExcludeMissing + fun _capitalWithdrawal(): JsonField = capitalWithdrawal + + /** + * Returns the raw JSON value of [credit]. + * + * Unlike [credit], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("credit") + @ExcludeMissing + fun _credit(): JsonField = credit + + /** + * Returns the raw JSON value of [debit]. + * + * Unlike [debit], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("debit") + @ExcludeMissing + fun _debit(): JsonField = debit + + /** + * Returns the raw JSON value of [incomeDistribution]. + * + * Unlike [incomeDistribution], this method doesn't throw if the JSON field + * has an unexpected type. + */ + @JsonProperty("income_distribution") + @ExcludeMissing + fun _incomeDistribution(): JsonField = incomeDistribution + + /** + * Returns the raw JSON value of [orderNo]. + * + * Unlike [orderNo], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("order_no") + @ExcludeMissing + fun _orderNo(): JsonField = orderNo + + /** + * Returns the raw JSON value of [price]. + * + * Unlike [price], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("price") + @ExcludeMissing + fun _price(): JsonField = price + + /** + * Returns the raw JSON value of [stampDuty]. + * + * Unlike [stampDuty], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("stamp_duty") + @ExcludeMissing + fun _stampDuty(): JsonField = stampDuty + + @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 + * [AdditionalInfo]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AdditionalInfo]. */ + class Builder internal constructor() { + + private var capitalWithdrawal: JsonField = JsonMissing.of() + private var credit: JsonField = JsonMissing.of() + private var debit: JsonField = JsonMissing.of() + private var incomeDistribution: JsonField = JsonMissing.of() + private var orderNo: JsonField = JsonMissing.of() + private var price: JsonField = JsonMissing.of() + private var stampDuty: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = + mutableMapOf() + + @JvmSynthetic + internal fun from(additionalInfo: AdditionalInfo) = apply { + capitalWithdrawal = additionalInfo.capitalWithdrawal + credit = additionalInfo.credit + debit = additionalInfo.debit + incomeDistribution = additionalInfo.incomeDistribution + orderNo = additionalInfo.orderNo + price = additionalInfo.price + stampDuty = additionalInfo.stampDuty + additionalProperties = + additionalInfo.additionalProperties.toMutableMap() + } + + /** Capital withdrawal amount (CDSL MF transactions) */ + fun capitalWithdrawal(capitalWithdrawal: Float) = + capitalWithdrawal(JsonField.of(capitalWithdrawal)) + + /** + * Sets [Builder.capitalWithdrawal] to an arbitrary JSON value. + * + * You should usually call [Builder.capitalWithdrawal] with a well-typed + * [Float] value instead. This method is primarily for setting the field + * to an undocumented or not yet supported value. + */ + fun capitalWithdrawal(capitalWithdrawal: JsonField) = apply { + this.capitalWithdrawal = capitalWithdrawal + } + + /** Units credited (demat transactions) */ + fun credit(credit: Float) = credit(JsonField.of(credit)) + + /** + * Sets [Builder.credit] to an arbitrary JSON value. + * + * You should usually call [Builder.credit] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun credit(credit: JsonField) = apply { this.credit = credit } + + /** Units debited (demat transactions) */ + fun debit(debit: Float) = debit(JsonField.of(debit)) + + /** + * Sets [Builder.debit] to an arbitrary JSON value. + * + * You should usually call [Builder.debit] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun debit(debit: JsonField) = apply { this.debit = debit } + + /** Income distribution amount (CDSL MF transactions) */ + fun incomeDistribution(incomeDistribution: Float) = + incomeDistribution(JsonField.of(incomeDistribution)) + + /** + * Sets [Builder.incomeDistribution] to an arbitrary JSON value. + * + * You should usually call [Builder.incomeDistribution] with a + * well-typed [Float] value instead. This method is primarily for + * setting the field to an undocumented or not yet supported value. + */ + fun incomeDistribution(incomeDistribution: JsonField) = apply { + this.incomeDistribution = incomeDistribution + } + + /** Order/transaction reference number (demat transactions) */ + fun orderNo(orderNo: String) = orderNo(JsonField.of(orderNo)) + + /** + * Sets [Builder.orderNo] to an arbitrary JSON value. + * + * You should usually call [Builder.orderNo] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun orderNo(orderNo: JsonField) = apply { + this.orderNo = orderNo + } + + /** Price per unit (NSDL/CDSL MF transactions) */ + fun price(price: Float) = price(JsonField.of(price)) + + /** + * Sets [Builder.price] to an arbitrary JSON value. + * + * You should usually call [Builder.price] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun price(price: JsonField) = apply { this.price = price } + + /** Stamp duty charged */ + fun stampDuty(stampDuty: Float) = stampDuty(JsonField.of(stampDuty)) + + /** + * Sets [Builder.stampDuty] to an arbitrary JSON value. + * + * You should usually call [Builder.stampDuty] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun stampDuty(stampDuty: JsonField) = apply { + this.stampDuty = stampDuty + } + + 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 [AdditionalInfo]. + * + * Further updates to this [Builder] will not mutate the returned + * instance. + */ + fun build(): AdditionalInfo = + AdditionalInfo( + capitalWithdrawal, + credit, + debit, + incomeDistribution, + orderNo, + price, + stampDuty, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): AdditionalInfo = apply { + if (validated) { + return@apply + } + + capitalWithdrawal() + credit() + debit() + incomeDistribution() + orderNo() + price() + stampDuty() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (capitalWithdrawal.asKnown().isPresent) 1 else 0) + + (if (credit.asKnown().isPresent) 1 else 0) + + (if (debit.asKnown().isPresent) 1 else 0) + + (if (incomeDistribution.asKnown().isPresent) 1 else 0) + + (if (orderNo.asKnown().isPresent) 1 else 0) + + (if (price.asKnown().isPresent) 1 else 0) + + (if (stampDuty.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AdditionalInfo && + capitalWithdrawal == other.capitalWithdrawal && + credit == other.credit && + debit == other.debit && + incomeDistribution == other.incomeDistribution && + orderNo == other.orderNo && + price == other.price && + stampDuty == other.stampDuty && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + capitalWithdrawal, + credit, + debit, + incomeDistribution, + orderNo, + price, + stampDuty, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AdditionalInfo{capitalWithdrawal=$capitalWithdrawal, credit=$credit, debit=$debit, incomeDistribution=$incomeDistribution, orderNo=$orderNo, price=$price, stampDuty=$stampDuty, additionalProperties=$additionalProperties}" + } + + /** + * Transaction type. Possible values are PURCHASE, PURCHASE_SIP, REDEMPTION, + * SWITCH_IN, SWITCH_IN_MERGER, SWITCH_OUT, SWITCH_OUT_MERGER, DIVIDEND_PAYOUT, + * DIVIDEND_REINVEST, SEGREGATION, STAMP_DUTY_TAX, TDS_TAX, STT_TAX, MISC, + * REVERSAL, UNKNOWN. + */ + class Type + @JsonCreator + private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data + * that doesn't match any known member, and you want to know that value. For + * example, if the SDK is on an older version than the API, then the API may + * respond with new members that the SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue + fun _value(): JsonField = value + + companion object { + + @JvmField val PURCHASE = of("PURCHASE") + + @JvmField val PURCHASE_SIP = of("PURCHASE_SIP") + + @JvmField val REDEMPTION = of("REDEMPTION") + + @JvmField val SWITCH_IN = of("SWITCH_IN") + + @JvmField val SWITCH_IN_MERGER = of("SWITCH_IN_MERGER") + + @JvmField val SWITCH_OUT = of("SWITCH_OUT") + + @JvmField val SWITCH_OUT_MERGER = of("SWITCH_OUT_MERGER") + + @JvmField val DIVIDEND_PAYOUT = of("DIVIDEND_PAYOUT") + + @JvmField val DIVIDEND_REINVEST = of("DIVIDEND_REINVEST") + + @JvmField val SEGREGATION = of("SEGREGATION") + + @JvmField val STAMP_DUTY_TAX = of("STAMP_DUTY_TAX") + + @JvmField val TDS_TAX = of("TDS_TAX") + + @JvmField val STT_TAX = of("STT_TAX") + + @JvmField val MISC = of("MISC") + + @JvmField val REVERSAL = of("REVERSAL") + + @JvmField val UNKNOWN = of("UNKNOWN") + + @JvmStatic fun of(value: String) = Type(JsonField.of(value)) + } + + /** An enum containing [Type]'s known values. */ + enum class Known { + PURCHASE, + PURCHASE_SIP, + REDEMPTION, + SWITCH_IN, + SWITCH_IN_MERGER, + SWITCH_OUT, + SWITCH_OUT_MERGER, + DIVIDEND_PAYOUT, + DIVIDEND_REINVEST, + SEGREGATION, + STAMP_DUTY_TAX, + TDS_TAX, + STT_TAX, + MISC, + REVERSAL, + UNKNOWN, + } + + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [Type] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For + * example, if the SDK is on an older version than the API, then the API + * may respond with new members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + PURCHASE, + PURCHASE_SIP, + REDEMPTION, + SWITCH_IN, + SWITCH_IN_MERGER, + SWITCH_OUT, + SWITCH_OUT_MERGER, + DIVIDEND_PAYOUT, + DIVIDEND_REINVEST, + SEGREGATION, + STAMP_DUTY_TAX, + TDS_TAX, + STT_TAX, + MISC, + REVERSAL, + UNKNOWN, + /** + * An enum member indicating that [Type] was instantiated with an + * unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always + * known or if you want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + PURCHASE -> Value.PURCHASE + PURCHASE_SIP -> Value.PURCHASE_SIP + REDEMPTION -> Value.REDEMPTION + SWITCH_IN -> Value.SWITCH_IN + SWITCH_IN_MERGER -> Value.SWITCH_IN_MERGER + SWITCH_OUT -> Value.SWITCH_OUT + SWITCH_OUT_MERGER -> Value.SWITCH_OUT_MERGER + DIVIDEND_PAYOUT -> Value.DIVIDEND_PAYOUT + DIVIDEND_REINVEST -> Value.DIVIDEND_REINVEST + SEGREGATION -> Value.SEGREGATION + STAMP_DUTY_TAX -> Value.STAMP_DUTY_TAX + TDS_TAX -> Value.TDS_TAX + STT_TAX -> Value.STT_TAX + MISC -> Value.MISC + REVERSAL -> Value.REVERSAL + UNKNOWN -> Value.UNKNOWN + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always + * known and don't want to throw for the unknown case. + * + * @throws CasParserInvalidDataException if this class instance's value is a + * not a known member. + */ + fun known(): Known = + when (this) { + PURCHASE -> Known.PURCHASE + PURCHASE_SIP -> Known.PURCHASE_SIP + REDEMPTION -> Known.REDEMPTION + SWITCH_IN -> Known.SWITCH_IN + SWITCH_IN_MERGER -> Known.SWITCH_IN_MERGER + SWITCH_OUT -> Known.SWITCH_OUT + SWITCH_OUT_MERGER -> Known.SWITCH_OUT_MERGER + DIVIDEND_PAYOUT -> Known.DIVIDEND_PAYOUT + DIVIDEND_REINVEST -> Known.DIVIDEND_REINVEST + SEGREGATION -> Known.SEGREGATION + STAMP_DUTY_TAX -> Known.STAMP_DUTY_TAX + TDS_TAX -> Known.TDS_TAX + STT_TAX -> Known.STT_TAX + MISC -> Known.MISC + REVERSAL -> Known.REVERSAL + UNKNOWN -> Known.UNKNOWN + else -> throw CasParserInvalidDataException("Unknown Type: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily + * for debugging and generally doesn't throw. + * + * @throws CasParserInvalidDataException if this class instance's value does + * not have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CasParserInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): Type = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Type && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Transaction && + additionalInfo == other.additionalInfo && + amount == other.amount && + balance == other.balance && + date == other.date && + description == other.description && + dividendRate == other.dividendRate && + nav == other.nav && + type == other.type && + units == other.units && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + additionalInfo, + amount, + balance, + date, + description, + dividendRate, + nav, + type, + units, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Transaction{additionalInfo=$additionalInfo, amount=$amount, balance=$balance, date=$date, description=$description, dividendRate=$dividendRate, nav=$nav, type=$type, units=$units, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Equity && + additionalInfo == other.additionalInfo && + isin == other.isin && + name == other.name && + transactions == other.transactions && + units == other.units && + value == other.value && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + additionalInfo, + isin, + name, + transactions, + units, + value, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Equity{additionalInfo=$additionalInfo, isin=$isin, name=$name, transactions=$transactions, units=$units, value=$value, additionalProperties=$additionalProperties}" + } + + class GovernmentSecurity + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val additionalInfo: JsonField, + private val isin: JsonField, + private val name: JsonField, + private val transactions: JsonField>, + private val units: JsonField, + private val value: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("additional_info") + @ExcludeMissing + additionalInfo: JsonField = JsonMissing.of(), + @JsonProperty("isin") + @ExcludeMissing + isin: JsonField = JsonMissing.of(), + @JsonProperty("name") + @ExcludeMissing + name: JsonField = JsonMissing.of(), + @JsonProperty("transactions") + @ExcludeMissing + transactions: JsonField> = JsonMissing.of(), + @JsonProperty("units") + @ExcludeMissing + units: JsonField = JsonMissing.of(), + @JsonProperty("value") + @ExcludeMissing + value: JsonField = JsonMissing.of(), + ) : this(additionalInfo, isin, name, transactions, units, value, mutableMapOf()) + + /** + * Additional information specific to the government security + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun additionalInfo(): Optional = + additionalInfo.getOptional("additional_info") + + /** + * ISIN code of the government security + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun isin(): Optional = isin.getOptional("isin") + + /** + * Name of the government security + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun name(): Optional = name.getOptional("name") + + /** + * List of transactions for this holding (beta) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun transactions(): Optional> = + transactions.getOptional("transactions") + + /** + * Number of units held + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun units(): Optional = units.getOptional("units") + + /** + * Current market value of the holding + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun value(): Optional = value.getOptional("value") + + /** + * Returns the raw JSON value of [additionalInfo]. + * + * Unlike [additionalInfo], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("additional_info") + @ExcludeMissing + fun _additionalInfo(): JsonField = additionalInfo + + /** + * Returns the raw JSON value of [isin]. + * + * Unlike [isin], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("isin") @ExcludeMissing fun _isin(): JsonField = isin + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + + /** + * Returns the raw JSON value of [transactions]. + * + * Unlike [transactions], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("transactions") + @ExcludeMissing + fun _transactions(): JsonField> = transactions + + /** + * Returns the raw JSON value of [units]. + * + * Unlike [units], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("units") @ExcludeMissing fun _units(): JsonField = units + + /** + * Returns the raw JSON value of [value]. + * + * Unlike [value], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("value") @ExcludeMissing fun _value(): JsonField = value + + @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 + * [GovernmentSecurity]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [GovernmentSecurity]. */ + class Builder internal constructor() { + + private var additionalInfo: JsonField = JsonMissing.of() + private var isin: JsonField = JsonMissing.of() + private var name: JsonField = JsonMissing.of() + private var transactions: JsonField>? = null + private var units: JsonField = JsonMissing.of() + private var value: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(governmentSecurity: GovernmentSecurity) = apply { + additionalInfo = governmentSecurity.additionalInfo + isin = governmentSecurity.isin + name = governmentSecurity.name + transactions = governmentSecurity.transactions.map { it.toMutableList() } + units = governmentSecurity.units + value = governmentSecurity.value + additionalProperties = + governmentSecurity.additionalProperties.toMutableMap() + } + + /** Additional information specific to the government security */ + fun additionalInfo(additionalInfo: AdditionalInfo) = + additionalInfo(JsonField.of(additionalInfo)) + + /** + * Sets [Builder.additionalInfo] to an arbitrary JSON value. + * + * You should usually call [Builder.additionalInfo] with a well-typed + * [AdditionalInfo] value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun additionalInfo(additionalInfo: JsonField) = apply { + this.additionalInfo = additionalInfo + } + + /** ISIN code of the government security */ + fun isin(isin: String) = isin(JsonField.of(isin)) + + /** + * Sets [Builder.isin] to an arbitrary JSON value. + * + * You should usually call [Builder.isin] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun isin(isin: JsonField) = apply { this.isin = isin } + + /** Name of the government security */ + fun name(name: String) = name(JsonField.of(name)) + + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun name(name: JsonField) = apply { this.name = name } + + /** List of transactions for this holding (beta) */ + fun transactions(transactions: List) = + transactions(JsonField.of(transactions)) + + /** + * Sets [Builder.transactions] to an arbitrary JSON value. + * + * You should usually call [Builder.transactions] with a well-typed + * `List` value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun transactions(transactions: JsonField>) = apply { + this.transactions = transactions.map { it.toMutableList() } + } + + /** + * Adds a single [Transaction] to [transactions]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addTransaction(transaction: Transaction) = apply { + transactions = + (transactions ?: JsonField.of(mutableListOf())).also { + checkKnown("transactions", it).add(transaction) + } + } + + /** Number of units held */ + fun units(units: Float) = units(JsonField.of(units)) + + /** + * Sets [Builder.units] to an arbitrary JSON value. + * + * You should usually call [Builder.units] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun units(units: JsonField) = apply { this.units = units } + + /** Current market value of the holding */ + fun value(value: Float) = value(JsonField.of(value)) + + /** + * Sets [Builder.value] to an arbitrary JSON value. + * + * You should usually call [Builder.value] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun value(value: JsonField) = apply { this.value = value } + + 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 [GovernmentSecurity]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): GovernmentSecurity = + GovernmentSecurity( + additionalInfo, + isin, + name, + (transactions ?: JsonMissing.of()).map { it.toImmutable() }, + units, + value, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): GovernmentSecurity = apply { + if (validated) { + return@apply + } + + additionalInfo().ifPresent { it.validate() } + isin() + name() + transactions().ifPresent { it.forEach { it.validate() } } + units() + value() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 = + (additionalInfo.asKnown().getOrNull()?.validity() ?: 0) + + (if (isin.asKnown().isPresent) 1 else 0) + + (if (name.asKnown().isPresent) 1 else 0) + + (transactions.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (units.asKnown().isPresent) 1 else 0) + + (if (value.asKnown().isPresent) 1 else 0) + + /** Additional information specific to the government security */ + class AdditionalInfo + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val closeUnits: JsonField, + private val openUnits: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("close_units") + @ExcludeMissing + closeUnits: JsonField = JsonMissing.of(), + @JsonProperty("open_units") + @ExcludeMissing + openUnits: JsonField = JsonMissing.of(), + ) : this(closeUnits, openUnits, mutableMapOf()) + + /** + * Closing balance units for the statement period (beta) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun closeUnits(): Optional = closeUnits.getOptional("close_units") + + /** + * Opening balance units for the statement period (beta) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun openUnits(): Optional = openUnits.getOptional("open_units") + + /** + * Returns the raw JSON value of [closeUnits]. + * + * Unlike [closeUnits], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("close_units") + @ExcludeMissing + fun _closeUnits(): JsonField = closeUnits + + /** + * Returns the raw JSON value of [openUnits]. + * + * Unlike [openUnits], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("open_units") + @ExcludeMissing + fun _openUnits(): JsonField = openUnits + + @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 + * [AdditionalInfo]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AdditionalInfo]. */ + class Builder internal constructor() { + + private var closeUnits: JsonField = JsonMissing.of() + private var openUnits: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = + mutableMapOf() + + @JvmSynthetic + internal fun from(additionalInfo: AdditionalInfo) = apply { + closeUnits = additionalInfo.closeUnits + openUnits = additionalInfo.openUnits + additionalProperties = + additionalInfo.additionalProperties.toMutableMap() + } + + /** Closing balance units for the statement period (beta) */ + fun closeUnits(closeUnits: Float?) = + closeUnits(JsonField.ofNullable(closeUnits)) + + /** + * Alias for [Builder.closeUnits]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun closeUnits(closeUnits: Float) = closeUnits(closeUnits as Float?) + + /** + * Alias for calling [Builder.closeUnits] with `closeUnits.orElse(null)`. + */ + fun closeUnits(closeUnits: Optional) = + closeUnits(closeUnits.getOrNull()) + + /** + * Sets [Builder.closeUnits] to an arbitrary JSON value. + * + * You should usually call [Builder.closeUnits] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun closeUnits(closeUnits: JsonField) = apply { + this.closeUnits = closeUnits + } + + /** Opening balance units for the statement period (beta) */ + fun openUnits(openUnits: Float?) = + openUnits(JsonField.ofNullable(openUnits)) + + /** + * Alias for [Builder.openUnits]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun openUnits(openUnits: Float) = openUnits(openUnits as Float?) + + /** Alias for calling [Builder.openUnits] with `openUnits.orElse(null)`. */ + fun openUnits(openUnits: Optional) = openUnits(openUnits.getOrNull()) + + /** + * Sets [Builder.openUnits] to an arbitrary JSON value. + * + * You should usually call [Builder.openUnits] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun openUnits(openUnits: JsonField) = apply { + this.openUnits = openUnits + } + + 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 [AdditionalInfo]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): AdditionalInfo = + AdditionalInfo( + closeUnits, + openUnits, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): AdditionalInfo = apply { + if (validated) { + return@apply + } + + closeUnits() + openUnits() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (closeUnits.asKnown().isPresent) 1 else 0) + + (if (openUnits.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AdditionalInfo && + closeUnits == other.closeUnits && + openUnits == other.openUnits && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(closeUnits, openUnits, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AdditionalInfo{closeUnits=$closeUnits, openUnits=$openUnits, additionalProperties=$additionalProperties}" + } + + /** + * Unified transaction schema for all holding types (MF folios, equities, bonds, + * etc.) + */ + class Transaction + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val additionalInfo: JsonField, + private val amount: JsonField, + private val balance: JsonField, + private val date: JsonField, + private val description: JsonField, + private val dividendRate: JsonField, + private val nav: JsonField, + private val type: JsonField, + private val units: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("additional_info") + @ExcludeMissing + additionalInfo: JsonField = JsonMissing.of(), + @JsonProperty("amount") + @ExcludeMissing + amount: JsonField = JsonMissing.of(), + @JsonProperty("balance") + @ExcludeMissing + balance: JsonField = JsonMissing.of(), + @JsonProperty("date") + @ExcludeMissing + date: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + description: JsonField = JsonMissing.of(), + @JsonProperty("dividend_rate") + @ExcludeMissing + dividendRate: JsonField = JsonMissing.of(), + @JsonProperty("nav") + @ExcludeMissing + nav: JsonField = JsonMissing.of(), + @JsonProperty("type") + @ExcludeMissing + type: JsonField = JsonMissing.of(), + @JsonProperty("units") + @ExcludeMissing + units: JsonField = JsonMissing.of(), + ) : this( + additionalInfo, + amount, + balance, + date, + description, + dividendRate, + nav, + type, + units, + mutableMapOf(), + ) + + /** + * Additional transaction-specific fields that vary by source + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun additionalInfo(): Optional = + additionalInfo.getOptional("additional_info") + + /** + * Transaction amount in currency (computed from units × price/NAV) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun amount(): Optional = amount.getOptional("amount") + + /** + * Balance units after transaction + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun balance(): Optional = balance.getOptional("balance") + + /** + * Transaction date (YYYY-MM-DD) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun date(): Optional = date.getOptional("date") + + /** + * Transaction description/particulars + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun description(): Optional = description.getOptional("description") + + /** + * Dividend rate (for DIVIDEND_PAYOUT transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun dividendRate(): Optional = dividendRate.getOptional("dividend_rate") + + /** + * NAV/price per unit on transaction date + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun nav(): Optional = nav.getOptional("nav") + + /** + * Transaction type. Possible values are PURCHASE, PURCHASE_SIP, REDEMPTION, + * SWITCH_IN, SWITCH_IN_MERGER, SWITCH_OUT, SWITCH_OUT_MERGER, DIVIDEND_PAYOUT, + * DIVIDEND_REINVEST, SEGREGATION, STAMP_DUTY_TAX, TDS_TAX, STT_TAX, MISC, + * REVERSAL, UNKNOWN. + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun type(): Optional = type.getOptional("type") + + /** + * Number of units involved in transaction + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun units(): Optional = units.getOptional("units") + + /** + * Returns the raw JSON value of [additionalInfo]. + * + * Unlike [additionalInfo], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("additional_info") + @ExcludeMissing + fun _additionalInfo(): JsonField = additionalInfo + + /** + * Returns the raw JSON value of [amount]. + * + * Unlike [amount], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("amount") @ExcludeMissing fun _amount(): JsonField = amount + + /** + * Returns the raw JSON value of [balance]. + * + * Unlike [balance], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("balance") + @ExcludeMissing + fun _balance(): JsonField = balance + + /** + * Returns the raw JSON value of [date]. + * + * Unlike [date], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("date") @ExcludeMissing fun _date(): JsonField = date + + /** + * Returns the raw JSON value of [description]. + * + * Unlike [description], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("description") + @ExcludeMissing + fun _description(): JsonField = description + + /** + * Returns the raw JSON value of [dividendRate]. + * + * Unlike [dividendRate], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("dividend_rate") + @ExcludeMissing + fun _dividendRate(): JsonField = dividendRate + + /** + * Returns the raw JSON value of [nav]. + * + * Unlike [nav], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("nav") @ExcludeMissing fun _nav(): JsonField = nav + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + + /** + * Returns the raw JSON value of [units]. + * + * Unlike [units], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("units") @ExcludeMissing fun _units(): JsonField = units + + @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 [Transaction]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Transaction]. */ + class Builder internal constructor() { + + private var additionalInfo: JsonField = JsonMissing.of() + private var amount: JsonField = JsonMissing.of() + private var balance: JsonField = JsonMissing.of() + private var date: JsonField = JsonMissing.of() + private var description: JsonField = JsonMissing.of() + private var dividendRate: JsonField = JsonMissing.of() + private var nav: JsonField = JsonMissing.of() + private var type: JsonField = JsonMissing.of() + private var units: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = + mutableMapOf() + + @JvmSynthetic + internal fun from(transaction: Transaction) = apply { + additionalInfo = transaction.additionalInfo + amount = transaction.amount + balance = transaction.balance + date = transaction.date + description = transaction.description + dividendRate = transaction.dividendRate + nav = transaction.nav + type = transaction.type + units = transaction.units + additionalProperties = transaction.additionalProperties.toMutableMap() + } + + /** Additional transaction-specific fields that vary by source */ + fun additionalInfo(additionalInfo: AdditionalInfo) = + additionalInfo(JsonField.of(additionalInfo)) + + /** + * Sets [Builder.additionalInfo] to an arbitrary JSON value. + * + * You should usually call [Builder.additionalInfo] with a well-typed + * [AdditionalInfo] value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun additionalInfo(additionalInfo: JsonField) = apply { + this.additionalInfo = additionalInfo + } + + /** Transaction amount in currency (computed from units × price/NAV) */ + fun amount(amount: Float?) = amount(JsonField.ofNullable(amount)) + + /** + * Alias for [Builder.amount]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun amount(amount: Float) = amount(amount as Float?) + + /** Alias for calling [Builder.amount] with `amount.orElse(null)`. */ + fun amount(amount: Optional) = amount(amount.getOrNull()) + + /** + * Sets [Builder.amount] to an arbitrary JSON value. + * + * You should usually call [Builder.amount] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun amount(amount: JsonField) = apply { this.amount = amount } + + /** Balance units after transaction */ + fun balance(balance: Float) = balance(JsonField.of(balance)) + + /** + * Sets [Builder.balance] to an arbitrary JSON value. + * + * You should usually call [Builder.balance] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun balance(balance: JsonField) = apply { this.balance = balance } + + /** Transaction date (YYYY-MM-DD) */ + fun date(date: LocalDate) = date(JsonField.of(date)) + + /** + * Sets [Builder.date] to an arbitrary JSON value. + * + * You should usually call [Builder.date] with a well-typed [LocalDate] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun date(date: JsonField) = apply { this.date = date } + + /** Transaction description/particulars */ + fun description(description: String) = + description(JsonField.of(description)) + + /** + * Sets [Builder.description] to an arbitrary JSON value. + * + * You should usually call [Builder.description] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun description(description: JsonField) = apply { + this.description = description + } + + /** Dividend rate (for DIVIDEND_PAYOUT transactions) */ + fun dividendRate(dividendRate: Float?) = + dividendRate(JsonField.ofNullable(dividendRate)) + + /** + * Alias for [Builder.dividendRate]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun dividendRate(dividendRate: Float) = dividendRate(dividendRate as Float?) + + /** + * Alias for calling [Builder.dividendRate] with + * `dividendRate.orElse(null)`. + */ + fun dividendRate(dividendRate: Optional) = + dividendRate(dividendRate.getOrNull()) + + /** + * Sets [Builder.dividendRate] to an arbitrary JSON value. + * + * You should usually call [Builder.dividendRate] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun dividendRate(dividendRate: JsonField) = apply { + this.dividendRate = dividendRate + } + + /** NAV/price per unit on transaction date */ + fun nav(nav: Float?) = nav(JsonField.ofNullable(nav)) + + /** + * Alias for [Builder.nav]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun nav(nav: Float) = nav(nav as Float?) + + /** Alias for calling [Builder.nav] with `nav.orElse(null)`. */ + fun nav(nav: Optional) = nav(nav.getOrNull()) + + /** + * Sets [Builder.nav] to an arbitrary JSON value. + * + * You should usually call [Builder.nav] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun nav(nav: JsonField) = apply { this.nav = nav } + + /** + * Transaction type. Possible values are PURCHASE, PURCHASE_SIP, REDEMPTION, + * SWITCH_IN, SWITCH_IN_MERGER, SWITCH_OUT, SWITCH_OUT_MERGER, + * DIVIDEND_PAYOUT, DIVIDEND_REINVEST, SEGREGATION, STAMP_DUTY_TAX, TDS_TAX, + * STT_TAX, MISC, REVERSAL, UNKNOWN. + */ + fun type(type: Type) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun type(type: JsonField) = apply { this.type = type } + + /** Number of units involved in transaction */ + fun units(units: Float) = units(JsonField.of(units)) + + /** + * Sets [Builder.units] to an arbitrary JSON value. + * + * You should usually call [Builder.units] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun units(units: JsonField) = apply { this.units = units } + + 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 [Transaction]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Transaction = + Transaction( + additionalInfo, + amount, + balance, + date, + description, + dividendRate, + nav, + type, + units, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Transaction = apply { + if (validated) { + return@apply + } + + additionalInfo().ifPresent { it.validate() } + amount() + balance() + date() + description() + dividendRate() + nav() + type().ifPresent { it.validate() } + units() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 = + (additionalInfo.asKnown().getOrNull()?.validity() ?: 0) + + (if (amount.asKnown().isPresent) 1 else 0) + + (if (balance.asKnown().isPresent) 1 else 0) + + (if (date.asKnown().isPresent) 1 else 0) + + (if (description.asKnown().isPresent) 1 else 0) + + (if (dividendRate.asKnown().isPresent) 1 else 0) + + (if (nav.asKnown().isPresent) 1 else 0) + + (type.asKnown().getOrNull()?.validity() ?: 0) + + (if (units.asKnown().isPresent) 1 else 0) + + /** Additional transaction-specific fields that vary by source */ + class AdditionalInfo + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val capitalWithdrawal: JsonField, + private val credit: JsonField, + private val debit: JsonField, + private val incomeDistribution: JsonField, + private val orderNo: JsonField, + private val price: JsonField, + private val stampDuty: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("capital_withdrawal") + @ExcludeMissing + capitalWithdrawal: JsonField = JsonMissing.of(), + @JsonProperty("credit") + @ExcludeMissing + credit: JsonField = JsonMissing.of(), + @JsonProperty("debit") + @ExcludeMissing + debit: JsonField = JsonMissing.of(), + @JsonProperty("income_distribution") + @ExcludeMissing + incomeDistribution: JsonField = JsonMissing.of(), + @JsonProperty("order_no") + @ExcludeMissing + orderNo: JsonField = JsonMissing.of(), + @JsonProperty("price") + @ExcludeMissing + price: JsonField = JsonMissing.of(), + @JsonProperty("stamp_duty") + @ExcludeMissing + stampDuty: JsonField = JsonMissing.of(), + ) : this( + capitalWithdrawal, + credit, + debit, + incomeDistribution, + orderNo, + price, + stampDuty, + mutableMapOf(), + ) + + /** + * Capital withdrawal amount (CDSL MF transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun capitalWithdrawal(): Optional = + capitalWithdrawal.getOptional("capital_withdrawal") + + /** + * Units credited (demat transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun credit(): Optional = credit.getOptional("credit") + + /** + * Units debited (demat transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun debit(): Optional = debit.getOptional("debit") + + /** + * Income distribution amount (CDSL MF transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun incomeDistribution(): Optional = + incomeDistribution.getOptional("income_distribution") + + /** + * Order/transaction reference number (demat transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun orderNo(): Optional = orderNo.getOptional("order_no") + + /** + * Price per unit (NSDL/CDSL MF transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun price(): Optional = price.getOptional("price") + + /** + * Stamp duty charged + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun stampDuty(): Optional = stampDuty.getOptional("stamp_duty") + + /** + * Returns the raw JSON value of [capitalWithdrawal]. + * + * Unlike [capitalWithdrawal], this method doesn't throw if the JSON field + * has an unexpected type. + */ + @JsonProperty("capital_withdrawal") + @ExcludeMissing + fun _capitalWithdrawal(): JsonField = capitalWithdrawal + + /** + * Returns the raw JSON value of [credit]. + * + * Unlike [credit], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("credit") + @ExcludeMissing + fun _credit(): JsonField = credit + + /** + * Returns the raw JSON value of [debit]. + * + * Unlike [debit], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("debit") + @ExcludeMissing + fun _debit(): JsonField = debit + + /** + * Returns the raw JSON value of [incomeDistribution]. + * + * Unlike [incomeDistribution], this method doesn't throw if the JSON field + * has an unexpected type. + */ + @JsonProperty("income_distribution") + @ExcludeMissing + fun _incomeDistribution(): JsonField = incomeDistribution + + /** + * Returns the raw JSON value of [orderNo]. + * + * Unlike [orderNo], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("order_no") + @ExcludeMissing + fun _orderNo(): JsonField = orderNo + + /** + * Returns the raw JSON value of [price]. + * + * Unlike [price], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("price") + @ExcludeMissing + fun _price(): JsonField = price + + /** + * Returns the raw JSON value of [stampDuty]. + * + * Unlike [stampDuty], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("stamp_duty") + @ExcludeMissing + fun _stampDuty(): JsonField = stampDuty + + @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 + * [AdditionalInfo]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AdditionalInfo]. */ + class Builder internal constructor() { + + private var capitalWithdrawal: JsonField = JsonMissing.of() + private var credit: JsonField = JsonMissing.of() + private var debit: JsonField = JsonMissing.of() + private var incomeDistribution: JsonField = JsonMissing.of() + private var orderNo: JsonField = JsonMissing.of() + private var price: JsonField = JsonMissing.of() + private var stampDuty: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = + mutableMapOf() + + @JvmSynthetic + internal fun from(additionalInfo: AdditionalInfo) = apply { + capitalWithdrawal = additionalInfo.capitalWithdrawal + credit = additionalInfo.credit + debit = additionalInfo.debit + incomeDistribution = additionalInfo.incomeDistribution + orderNo = additionalInfo.orderNo + price = additionalInfo.price + stampDuty = additionalInfo.stampDuty + additionalProperties = + additionalInfo.additionalProperties.toMutableMap() + } + + /** Capital withdrawal amount (CDSL MF transactions) */ + fun capitalWithdrawal(capitalWithdrawal: Float) = + capitalWithdrawal(JsonField.of(capitalWithdrawal)) + + /** + * Sets [Builder.capitalWithdrawal] to an arbitrary JSON value. + * + * You should usually call [Builder.capitalWithdrawal] with a well-typed + * [Float] value instead. This method is primarily for setting the field + * to an undocumented or not yet supported value. + */ + fun capitalWithdrawal(capitalWithdrawal: JsonField) = apply { + this.capitalWithdrawal = capitalWithdrawal + } + + /** Units credited (demat transactions) */ + fun credit(credit: Float) = credit(JsonField.of(credit)) + + /** + * Sets [Builder.credit] to an arbitrary JSON value. + * + * You should usually call [Builder.credit] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun credit(credit: JsonField) = apply { this.credit = credit } + + /** Units debited (demat transactions) */ + fun debit(debit: Float) = debit(JsonField.of(debit)) + + /** + * Sets [Builder.debit] to an arbitrary JSON value. + * + * You should usually call [Builder.debit] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun debit(debit: JsonField) = apply { this.debit = debit } + + /** Income distribution amount (CDSL MF transactions) */ + fun incomeDistribution(incomeDistribution: Float) = + incomeDistribution(JsonField.of(incomeDistribution)) + + /** + * Sets [Builder.incomeDistribution] to an arbitrary JSON value. + * + * You should usually call [Builder.incomeDistribution] with a + * well-typed [Float] value instead. This method is primarily for + * setting the field to an undocumented or not yet supported value. + */ + fun incomeDistribution(incomeDistribution: JsonField) = apply { + this.incomeDistribution = incomeDistribution + } + + /** Order/transaction reference number (demat transactions) */ + fun orderNo(orderNo: String) = orderNo(JsonField.of(orderNo)) + + /** + * Sets [Builder.orderNo] to an arbitrary JSON value. + * + * You should usually call [Builder.orderNo] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun orderNo(orderNo: JsonField) = apply { + this.orderNo = orderNo + } + + /** Price per unit (NSDL/CDSL MF transactions) */ + fun price(price: Float) = price(JsonField.of(price)) + + /** + * Sets [Builder.price] to an arbitrary JSON value. + * + * You should usually call [Builder.price] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun price(price: JsonField) = apply { this.price = price } + + /** Stamp duty charged */ + fun stampDuty(stampDuty: Float) = stampDuty(JsonField.of(stampDuty)) + + /** + * Sets [Builder.stampDuty] to an arbitrary JSON value. + * + * You should usually call [Builder.stampDuty] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun stampDuty(stampDuty: JsonField) = apply { + this.stampDuty = stampDuty + } + + 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 [AdditionalInfo]. + * + * Further updates to this [Builder] will not mutate the returned + * instance. + */ + fun build(): AdditionalInfo = + AdditionalInfo( + capitalWithdrawal, + credit, + debit, + incomeDistribution, + orderNo, + price, + stampDuty, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): AdditionalInfo = apply { + if (validated) { + return@apply + } + + capitalWithdrawal() + credit() + debit() + incomeDistribution() + orderNo() + price() + stampDuty() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (capitalWithdrawal.asKnown().isPresent) 1 else 0) + + (if (credit.asKnown().isPresent) 1 else 0) + + (if (debit.asKnown().isPresent) 1 else 0) + + (if (incomeDistribution.asKnown().isPresent) 1 else 0) + + (if (orderNo.asKnown().isPresent) 1 else 0) + + (if (price.asKnown().isPresent) 1 else 0) + + (if (stampDuty.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AdditionalInfo && + capitalWithdrawal == other.capitalWithdrawal && + credit == other.credit && + debit == other.debit && + incomeDistribution == other.incomeDistribution && + orderNo == other.orderNo && + price == other.price && + stampDuty == other.stampDuty && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + capitalWithdrawal, + credit, + debit, + incomeDistribution, + orderNo, + price, + stampDuty, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AdditionalInfo{capitalWithdrawal=$capitalWithdrawal, credit=$credit, debit=$debit, incomeDistribution=$incomeDistribution, orderNo=$orderNo, price=$price, stampDuty=$stampDuty, additionalProperties=$additionalProperties}" + } + + /** + * Transaction type. Possible values are PURCHASE, PURCHASE_SIP, REDEMPTION, + * SWITCH_IN, SWITCH_IN_MERGER, SWITCH_OUT, SWITCH_OUT_MERGER, DIVIDEND_PAYOUT, + * DIVIDEND_REINVEST, SEGREGATION, STAMP_DUTY_TAX, TDS_TAX, STT_TAX, MISC, + * REVERSAL, UNKNOWN. + */ + class Type + @JsonCreator + private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data + * that doesn't match any known member, and you want to know that value. For + * example, if the SDK is on an older version than the API, then the API may + * respond with new members that the SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue + fun _value(): JsonField = value + + companion object { + + @JvmField val PURCHASE = of("PURCHASE") + + @JvmField val PURCHASE_SIP = of("PURCHASE_SIP") + + @JvmField val REDEMPTION = of("REDEMPTION") + + @JvmField val SWITCH_IN = of("SWITCH_IN") + + @JvmField val SWITCH_IN_MERGER = of("SWITCH_IN_MERGER") + + @JvmField val SWITCH_OUT = of("SWITCH_OUT") + + @JvmField val SWITCH_OUT_MERGER = of("SWITCH_OUT_MERGER") + + @JvmField val DIVIDEND_PAYOUT = of("DIVIDEND_PAYOUT") + + @JvmField val DIVIDEND_REINVEST = of("DIVIDEND_REINVEST") + + @JvmField val SEGREGATION = of("SEGREGATION") + + @JvmField val STAMP_DUTY_TAX = of("STAMP_DUTY_TAX") + + @JvmField val TDS_TAX = of("TDS_TAX") + + @JvmField val STT_TAX = of("STT_TAX") + + @JvmField val MISC = of("MISC") + + @JvmField val REVERSAL = of("REVERSAL") + + @JvmField val UNKNOWN = of("UNKNOWN") + + @JvmStatic fun of(value: String) = Type(JsonField.of(value)) + } + + /** An enum containing [Type]'s known values. */ + enum class Known { + PURCHASE, + PURCHASE_SIP, + REDEMPTION, + SWITCH_IN, + SWITCH_IN_MERGER, + SWITCH_OUT, + SWITCH_OUT_MERGER, + DIVIDEND_PAYOUT, + DIVIDEND_REINVEST, + SEGREGATION, + STAMP_DUTY_TAX, + TDS_TAX, + STT_TAX, + MISC, + REVERSAL, + UNKNOWN, + } + + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [Type] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For + * example, if the SDK is on an older version than the API, then the API + * may respond with new members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + PURCHASE, + PURCHASE_SIP, + REDEMPTION, + SWITCH_IN, + SWITCH_IN_MERGER, + SWITCH_OUT, + SWITCH_OUT_MERGER, + DIVIDEND_PAYOUT, + DIVIDEND_REINVEST, + SEGREGATION, + STAMP_DUTY_TAX, + TDS_TAX, + STT_TAX, + MISC, + REVERSAL, + UNKNOWN, + /** + * An enum member indicating that [Type] was instantiated with an + * unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always + * known or if you want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + PURCHASE -> Value.PURCHASE + PURCHASE_SIP -> Value.PURCHASE_SIP + REDEMPTION -> Value.REDEMPTION + SWITCH_IN -> Value.SWITCH_IN + SWITCH_IN_MERGER -> Value.SWITCH_IN_MERGER + SWITCH_OUT -> Value.SWITCH_OUT + SWITCH_OUT_MERGER -> Value.SWITCH_OUT_MERGER + DIVIDEND_PAYOUT -> Value.DIVIDEND_PAYOUT + DIVIDEND_REINVEST -> Value.DIVIDEND_REINVEST + SEGREGATION -> Value.SEGREGATION + STAMP_DUTY_TAX -> Value.STAMP_DUTY_TAX + TDS_TAX -> Value.TDS_TAX + STT_TAX -> Value.STT_TAX + MISC -> Value.MISC + REVERSAL -> Value.REVERSAL + UNKNOWN -> Value.UNKNOWN + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always + * known and don't want to throw for the unknown case. + * + * @throws CasParserInvalidDataException if this class instance's value is a + * not a known member. + */ + fun known(): Known = + when (this) { + PURCHASE -> Known.PURCHASE + PURCHASE_SIP -> Known.PURCHASE_SIP + REDEMPTION -> Known.REDEMPTION + SWITCH_IN -> Known.SWITCH_IN + SWITCH_IN_MERGER -> Known.SWITCH_IN_MERGER + SWITCH_OUT -> Known.SWITCH_OUT + SWITCH_OUT_MERGER -> Known.SWITCH_OUT_MERGER + DIVIDEND_PAYOUT -> Known.DIVIDEND_PAYOUT + DIVIDEND_REINVEST -> Known.DIVIDEND_REINVEST + SEGREGATION -> Known.SEGREGATION + STAMP_DUTY_TAX -> Known.STAMP_DUTY_TAX + TDS_TAX -> Known.TDS_TAX + STT_TAX -> Known.STT_TAX + MISC -> Known.MISC + REVERSAL -> Known.REVERSAL + UNKNOWN -> Known.UNKNOWN + else -> throw CasParserInvalidDataException("Unknown Type: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily + * for debugging and generally doesn't throw. + * + * @throws CasParserInvalidDataException if this class instance's value does + * not have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CasParserInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): Type = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Type && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Transaction && + additionalInfo == other.additionalInfo && + amount == other.amount && + balance == other.balance && + date == other.date && + description == other.description && + dividendRate == other.dividendRate && + nav == other.nav && + type == other.type && + units == other.units && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + additionalInfo, + amount, + balance, + date, + description, + dividendRate, + nav, + type, + units, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Transaction{additionalInfo=$additionalInfo, amount=$amount, balance=$balance, date=$date, description=$description, dividendRate=$dividendRate, nav=$nav, type=$type, units=$units, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is GovernmentSecurity && + additionalInfo == other.additionalInfo && + isin == other.isin && + name == other.name && + transactions == other.transactions && + units == other.units && + value == other.value && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + additionalInfo, + isin, + name, + transactions, + units, + value, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "GovernmentSecurity{additionalInfo=$additionalInfo, isin=$isin, name=$name, transactions=$transactions, units=$units, value=$value, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Holdings && + aifs == other.aifs && + corporateBonds == other.corporateBonds && + dematMutualFunds == other.dematMutualFunds && + equities == other.equities && + governmentSecurities == other.governmentSecurities && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + aifs, + corporateBonds, + dematMutualFunds, + equities, + governmentSecurities, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Holdings{aifs=$aifs, corporateBonds=$corporateBonds, dematMutualFunds=$dematMutualFunds, equities=$equities, governmentSecurities=$governmentSecurities, additionalProperties=$additionalProperties}" + } + + class LinkedHolder + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val name: JsonField, + private val pan: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("pan") @ExcludeMissing pan: JsonField = JsonMissing.of(), + ) : this(name, pan, mutableMapOf()) + + /** + * Name of the account holder + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun name(): Optional = name.getOptional("name") + + /** + * PAN of the account holder + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun pan(): Optional = pan.getOptional("pan") + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + + /** + * Returns the raw JSON value of [pan]. + * + * Unlike [pan], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("pan") @ExcludeMissing fun _pan(): JsonField = pan + + @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 [LinkedHolder]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [LinkedHolder]. */ + class Builder internal constructor() { + + private var name: JsonField = JsonMissing.of() + private var pan: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(linkedHolder: LinkedHolder) = apply { + name = linkedHolder.name + pan = linkedHolder.pan + additionalProperties = linkedHolder.additionalProperties.toMutableMap() + } + + /** Name of the account holder */ + fun name(name: String) = name(JsonField.of(name)) + + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun name(name: JsonField) = apply { this.name = name } + + /** PAN of the account holder */ + fun pan(pan: String) = pan(JsonField.of(pan)) + + /** + * Sets [Builder.pan] to an arbitrary JSON value. + * + * You should usually call [Builder.pan] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun pan(pan: JsonField) = apply { this.pan = pan } + + 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 [LinkedHolder]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): LinkedHolder = + LinkedHolder(name, pan, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): LinkedHolder = apply { + if (validated) { + return@apply + } + + name() + pan() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (name.asKnown().isPresent) 1 else 0) + (if (pan.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is LinkedHolder && + name == other.name && + pan == other.pan && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(name, pan, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "LinkedHolder{name=$name, pan=$pan, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is DematAccount && + additionalInfo == other.additionalInfo && + boId == other.boId && + clientId == other.clientId && + dematType == other.dematType && + dpId == other.dpId && + dpName == other.dpName && + holdings == other.holdings && + linkedHolders == other.linkedHolders && + value == other.value && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + additionalInfo, + boId, + clientId, + dematType, + dpId, + dpName, + holdings, + linkedHolders, + value, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "DematAccount{additionalInfo=$additionalInfo, boId=$boId, clientId=$clientId, dematType=$dematType, dpId=$dpId, dpName=$dpName, holdings=$holdings, linkedHolders=$linkedHolders, value=$value, additionalProperties=$additionalProperties}" + } + + class Insurance + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val lifeInsurancePolicies: JsonField>, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("life_insurance_policies") + @ExcludeMissing + lifeInsurancePolicies: JsonField> = JsonMissing.of() + ) : this(lifeInsurancePolicies, mutableMapOf()) + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun lifeInsurancePolicies(): Optional> = + lifeInsurancePolicies.getOptional("life_insurance_policies") + + /** + * Returns the raw JSON value of [lifeInsurancePolicies]. + * + * Unlike [lifeInsurancePolicies], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("life_insurance_policies") + @ExcludeMissing + fun _lifeInsurancePolicies(): JsonField> = lifeInsurancePolicies + + @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 [Insurance]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Insurance]. */ + class Builder internal constructor() { + + private var lifeInsurancePolicies: JsonField>? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(insurance: Insurance) = apply { + lifeInsurancePolicies = insurance.lifeInsurancePolicies.map { it.toMutableList() } + additionalProperties = insurance.additionalProperties.toMutableMap() + } + + fun lifeInsurancePolicies(lifeInsurancePolicies: List) = + lifeInsurancePolicies(JsonField.of(lifeInsurancePolicies)) + + /** + * Sets [Builder.lifeInsurancePolicies] to an arbitrary JSON value. + * + * You should usually call [Builder.lifeInsurancePolicies] with a well-typed + * `List` value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun lifeInsurancePolicies(lifeInsurancePolicies: JsonField>) = + apply { + this.lifeInsurancePolicies = lifeInsurancePolicies.map { it.toMutableList() } + } + + /** + * Adds a single [LifeInsurancePolicy] to [lifeInsurancePolicies]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addLifeInsurancePolicy(lifeInsurancePolicy: LifeInsurancePolicy) = apply { + lifeInsurancePolicies = + (lifeInsurancePolicies ?: JsonField.of(mutableListOf())).also { + checkKnown("lifeInsurancePolicies", it).add(lifeInsurancePolicy) + } + } + + 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 [Insurance]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Insurance = + Insurance( + (lifeInsurancePolicies ?: JsonMissing.of()).map { it.toImmutable() }, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Insurance = apply { + if (validated) { + return@apply + } + + lifeInsurancePolicies().ifPresent { it.forEach { it.validate() } } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 = + (lifeInsurancePolicies.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + class LifeInsurancePolicy + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val additionalInfo: JsonValue, + private val lifeAssured: JsonField, + private val policyName: JsonField, + private val policyNumber: JsonField, + private val premiumAmount: JsonField, + private val premiumFrequency: JsonField, + private val provider: JsonField, + private val status: JsonField, + private val sumAssured: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("additional_info") + @ExcludeMissing + additionalInfo: JsonValue = JsonMissing.of(), + @JsonProperty("life_assured") + @ExcludeMissing + lifeAssured: JsonField = JsonMissing.of(), + @JsonProperty("policy_name") + @ExcludeMissing + policyName: JsonField = JsonMissing.of(), + @JsonProperty("policy_number") + @ExcludeMissing + policyNumber: JsonField = JsonMissing.of(), + @JsonProperty("premium_amount") + @ExcludeMissing + premiumAmount: JsonField = JsonMissing.of(), + @JsonProperty("premium_frequency") + @ExcludeMissing + premiumFrequency: JsonField = JsonMissing.of(), + @JsonProperty("provider") + @ExcludeMissing + provider: JsonField = JsonMissing.of(), + @JsonProperty("status") + @ExcludeMissing + status: JsonField = JsonMissing.of(), + @JsonProperty("sum_assured") + @ExcludeMissing + sumAssured: JsonField = JsonMissing.of(), + ) : this( + additionalInfo, + lifeAssured, + policyName, + policyNumber, + premiumAmount, + premiumFrequency, + provider, + status, + sumAssured, + mutableMapOf(), + ) + + /** Additional information specific to the policy */ + @JsonProperty("additional_info") + @ExcludeMissing + fun _additionalInfo(): JsonValue = additionalInfo + + /** + * Name of the life assured + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun lifeAssured(): Optional = lifeAssured.getOptional("life_assured") + + /** + * Name of the insurance policy + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun policyName(): Optional = policyName.getOptional("policy_name") + + /** + * Insurance policy number + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun policyNumber(): Optional = policyNumber.getOptional("policy_number") + + /** + * Premium amount + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun premiumAmount(): Optional = premiumAmount.getOptional("premium_amount") + + /** + * Frequency of premium payment (e.g., Annual, Monthly) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun premiumFrequency(): Optional = + premiumFrequency.getOptional("premium_frequency") + + /** + * Insurance company name + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun provider(): Optional = provider.getOptional("provider") + + /** + * Status of the policy (e.g., Active, Lapsed) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun status(): Optional = status.getOptional("status") + + /** + * Sum assured amount + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun sumAssured(): Optional = sumAssured.getOptional("sum_assured") + + /** + * Returns the raw JSON value of [lifeAssured]. + * + * Unlike [lifeAssured], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("life_assured") + @ExcludeMissing + fun _lifeAssured(): JsonField = lifeAssured + + /** + * Returns the raw JSON value of [policyName]. + * + * Unlike [policyName], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("policy_name") + @ExcludeMissing + fun _policyName(): JsonField = policyName + + /** + * Returns the raw JSON value of [policyNumber]. + * + * Unlike [policyNumber], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("policy_number") + @ExcludeMissing + fun _policyNumber(): JsonField = policyNumber + + /** + * Returns the raw JSON value of [premiumAmount]. + * + * Unlike [premiumAmount], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("premium_amount") + @ExcludeMissing + fun _premiumAmount(): JsonField = premiumAmount + + /** + * Returns the raw JSON value of [premiumFrequency]. + * + * Unlike [premiumFrequency], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("premium_frequency") + @ExcludeMissing + fun _premiumFrequency(): JsonField = premiumFrequency + + /** + * Returns the raw JSON value of [provider]. + * + * Unlike [provider], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("provider") @ExcludeMissing fun _provider(): JsonField = provider + + /** + * Returns the raw JSON value of [status]. + * + * Unlike [status], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("status") @ExcludeMissing fun _status(): JsonField = status + + /** + * Returns the raw JSON value of [sumAssured]. + * + * Unlike [sumAssured], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("sum_assured") + @ExcludeMissing + fun _sumAssured(): JsonField = sumAssured + + @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 [LifeInsurancePolicy]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [LifeInsurancePolicy]. */ + class Builder internal constructor() { + + private var additionalInfo: JsonValue = JsonMissing.of() + private var lifeAssured: JsonField = JsonMissing.of() + private var policyName: JsonField = JsonMissing.of() + private var policyNumber: JsonField = JsonMissing.of() + private var premiumAmount: JsonField = JsonMissing.of() + private var premiumFrequency: JsonField = JsonMissing.of() + private var provider: JsonField = JsonMissing.of() + private var status: JsonField = JsonMissing.of() + private var sumAssured: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(lifeInsurancePolicy: LifeInsurancePolicy) = apply { + additionalInfo = lifeInsurancePolicy.additionalInfo + lifeAssured = lifeInsurancePolicy.lifeAssured + policyName = lifeInsurancePolicy.policyName + policyNumber = lifeInsurancePolicy.policyNumber + premiumAmount = lifeInsurancePolicy.premiumAmount + premiumFrequency = lifeInsurancePolicy.premiumFrequency + provider = lifeInsurancePolicy.provider + status = lifeInsurancePolicy.status + sumAssured = lifeInsurancePolicy.sumAssured + additionalProperties = lifeInsurancePolicy.additionalProperties.toMutableMap() + } + + /** Additional information specific to the policy */ + fun additionalInfo(additionalInfo: JsonValue) = apply { + this.additionalInfo = additionalInfo + } + + /** Name of the life assured */ + fun lifeAssured(lifeAssured: String) = lifeAssured(JsonField.of(lifeAssured)) + + /** + * Sets [Builder.lifeAssured] to an arbitrary JSON value. + * + * You should usually call [Builder.lifeAssured] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun lifeAssured(lifeAssured: JsonField) = apply { + this.lifeAssured = lifeAssured + } + + /** Name of the insurance policy */ + fun policyName(policyName: String) = policyName(JsonField.of(policyName)) + + /** + * Sets [Builder.policyName] to an arbitrary JSON value. + * + * You should usually call [Builder.policyName] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun policyName(policyName: JsonField) = apply { + this.policyName = policyName + } + + /** Insurance policy number */ + fun policyNumber(policyNumber: String) = policyNumber(JsonField.of(policyNumber)) + + /** + * Sets [Builder.policyNumber] to an arbitrary JSON value. + * + * You should usually call [Builder.policyNumber] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun policyNumber(policyNumber: JsonField) = apply { + this.policyNumber = policyNumber + } + + /** Premium amount */ + fun premiumAmount(premiumAmount: Float) = premiumAmount(JsonField.of(premiumAmount)) + + /** + * Sets [Builder.premiumAmount] to an arbitrary JSON value. + * + * You should usually call [Builder.premiumAmount] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun premiumAmount(premiumAmount: JsonField) = apply { + this.premiumAmount = premiumAmount + } + + /** Frequency of premium payment (e.g., Annual, Monthly) */ + fun premiumFrequency(premiumFrequency: String) = + premiumFrequency(JsonField.of(premiumFrequency)) + + /** + * Sets [Builder.premiumFrequency] to an arbitrary JSON value. + * + * You should usually call [Builder.premiumFrequency] with a well-typed [String] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun premiumFrequency(premiumFrequency: JsonField) = apply { + this.premiumFrequency = premiumFrequency + } + + /** Insurance company name */ + fun provider(provider: String) = provider(JsonField.of(provider)) + + /** + * Sets [Builder.provider] to an arbitrary JSON value. + * + * You should usually call [Builder.provider] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun provider(provider: JsonField) = apply { this.provider = provider } + + /** Status of the policy (e.g., Active, Lapsed) */ + fun status(status: String) = status(JsonField.of(status)) + + /** + * Sets [Builder.status] to an arbitrary JSON value. + * + * You should usually call [Builder.status] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun status(status: JsonField) = apply { this.status = status } + + /** Sum assured amount */ + fun sumAssured(sumAssured: Float) = sumAssured(JsonField.of(sumAssured)) + + /** + * Sets [Builder.sumAssured] to an arbitrary JSON value. + * + * You should usually call [Builder.sumAssured] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun sumAssured(sumAssured: JsonField) = apply { + this.sumAssured = sumAssured + } + + 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 [LifeInsurancePolicy]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): LifeInsurancePolicy = + LifeInsurancePolicy( + additionalInfo, + lifeAssured, + policyName, + policyNumber, + premiumAmount, + premiumFrequency, + provider, + status, + sumAssured, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): LifeInsurancePolicy = apply { + if (validated) { + return@apply + } + + lifeAssured() + policyName() + policyNumber() + premiumAmount() + premiumFrequency() + provider() + status() + sumAssured() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (lifeAssured.asKnown().isPresent) 1 else 0) + + (if (policyName.asKnown().isPresent) 1 else 0) + + (if (policyNumber.asKnown().isPresent) 1 else 0) + + (if (premiumAmount.asKnown().isPresent) 1 else 0) + + (if (premiumFrequency.asKnown().isPresent) 1 else 0) + + (if (provider.asKnown().isPresent) 1 else 0) + + (if (status.asKnown().isPresent) 1 else 0) + + (if (sumAssured.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is LifeInsurancePolicy && + additionalInfo == other.additionalInfo && + lifeAssured == other.lifeAssured && + policyName == other.policyName && + policyNumber == other.policyNumber && + premiumAmount == other.premiumAmount && + premiumFrequency == other.premiumFrequency && + provider == other.provider && + status == other.status && + sumAssured == other.sumAssured && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + additionalInfo, + lifeAssured, + policyName, + policyNumber, + premiumAmount, + premiumFrequency, + provider, + status, + sumAssured, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "LifeInsurancePolicy{additionalInfo=$additionalInfo, lifeAssured=$lifeAssured, policyName=$policyName, policyNumber=$policyNumber, premiumAmount=$premiumAmount, premiumFrequency=$premiumFrequency, provider=$provider, status=$status, sumAssured=$sumAssured, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Insurance && + lifeInsurancePolicies == other.lifeInsurancePolicies && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(lifeInsurancePolicies, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Insurance{lifeInsurancePolicies=$lifeInsurancePolicies, additionalProperties=$additionalProperties}" + } + + class Investor + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val address: JsonField, + private val casId: JsonField, + private val email: JsonField, + private val mobile: JsonField, + private val name: JsonField, + private val pan: JsonField, + private val pincode: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("address") @ExcludeMissing address: JsonField = JsonMissing.of(), + @JsonProperty("cas_id") @ExcludeMissing casId: JsonField = JsonMissing.of(), + @JsonProperty("email") @ExcludeMissing email: JsonField = JsonMissing.of(), + @JsonProperty("mobile") @ExcludeMissing mobile: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("pan") @ExcludeMissing pan: JsonField = JsonMissing.of(), + @JsonProperty("pincode") @ExcludeMissing pincode: JsonField = JsonMissing.of(), + ) : this(address, casId, email, mobile, name, pan, pincode, mutableMapOf()) + + /** + * Address of the investor + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun address(): Optional = address.getOptional("address") + + /** + * CAS ID of the investor (only for NSDL and CDSL) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun casId(): Optional = casId.getOptional("cas_id") + + /** + * Email address of the investor + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun email(): Optional = email.getOptional("email") + + /** + * Mobile number of the investor + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun mobile(): Optional = mobile.getOptional("mobile") + + /** + * Name of the investor + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun name(): Optional = name.getOptional("name") + + /** + * PAN (Permanent Account Number) of the investor + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun pan(): Optional = pan.getOptional("pan") + + /** + * Postal code of the investor's address + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun pincode(): Optional = pincode.getOptional("pincode") + + /** + * Returns the raw JSON value of [address]. + * + * Unlike [address], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("address") @ExcludeMissing fun _address(): JsonField = address + + /** + * Returns the raw JSON value of [casId]. + * + * Unlike [casId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("cas_id") @ExcludeMissing fun _casId(): JsonField = casId + + /** + * Returns the raw JSON value of [email]. + * + * Unlike [email], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("email") @ExcludeMissing fun _email(): JsonField = email + + /** + * Returns the raw JSON value of [mobile]. + * + * Unlike [mobile], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("mobile") @ExcludeMissing fun _mobile(): JsonField = mobile + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + + /** + * Returns the raw JSON value of [pan]. + * + * Unlike [pan], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("pan") @ExcludeMissing fun _pan(): JsonField = pan + + /** + * Returns the raw JSON value of [pincode]. + * + * Unlike [pincode], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("pincode") @ExcludeMissing fun _pincode(): JsonField = pincode + + @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 [Investor]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Investor]. */ + class Builder internal constructor() { + + private var address: JsonField = JsonMissing.of() + private var casId: JsonField = JsonMissing.of() + private var email: JsonField = JsonMissing.of() + private var mobile: JsonField = JsonMissing.of() + private var name: JsonField = JsonMissing.of() + private var pan: JsonField = JsonMissing.of() + private var pincode: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(investor: Investor) = apply { + address = investor.address + casId = investor.casId + email = investor.email + mobile = investor.mobile + name = investor.name + pan = investor.pan + pincode = investor.pincode + additionalProperties = investor.additionalProperties.toMutableMap() + } + + /** Address of the investor */ + fun address(address: String) = address(JsonField.of(address)) + + /** + * Sets [Builder.address] to an arbitrary JSON value. + * + * You should usually call [Builder.address] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun address(address: JsonField) = apply { this.address = address } + + /** CAS ID of the investor (only for NSDL and CDSL) */ + fun casId(casId: String) = casId(JsonField.of(casId)) + + /** + * Sets [Builder.casId] to an arbitrary JSON value. + * + * You should usually call [Builder.casId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun casId(casId: JsonField) = apply { this.casId = casId } + + /** Email address of the investor */ + fun email(email: String) = email(JsonField.of(email)) + + /** + * Sets [Builder.email] to an arbitrary JSON value. + * + * You should usually call [Builder.email] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun email(email: JsonField) = apply { this.email = email } + + /** Mobile number of the investor */ + fun mobile(mobile: String) = mobile(JsonField.of(mobile)) + + /** + * Sets [Builder.mobile] to an arbitrary JSON value. + * + * You should usually call [Builder.mobile] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun mobile(mobile: JsonField) = apply { this.mobile = mobile } + + /** Name of the investor */ + fun name(name: String) = name(JsonField.of(name)) + + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun name(name: JsonField) = apply { this.name = name } + + /** PAN (Permanent Account Number) of the investor */ + fun pan(pan: String) = pan(JsonField.of(pan)) + + /** + * Sets [Builder.pan] to an arbitrary JSON value. + * + * You should usually call [Builder.pan] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun pan(pan: JsonField) = apply { this.pan = pan } + + /** Postal code of the investor's address */ + fun pincode(pincode: String) = pincode(JsonField.of(pincode)) + + /** + * Sets [Builder.pincode] to an arbitrary JSON value. + * + * You should usually call [Builder.pincode] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun pincode(pincode: JsonField) = apply { this.pincode = pincode } + + 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 [Investor]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Investor = + Investor( + address, + casId, + email, + mobile, + name, + pan, + pincode, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Investor = apply { + if (validated) { + return@apply + } + + address() + casId() + email() + mobile() + name() + pan() + pincode() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (address.asKnown().isPresent) 1 else 0) + + (if (casId.asKnown().isPresent) 1 else 0) + + (if (email.asKnown().isPresent) 1 else 0) + + (if (mobile.asKnown().isPresent) 1 else 0) + + (if (name.asKnown().isPresent) 1 else 0) + + (if (pan.asKnown().isPresent) 1 else 0) + + (if (pincode.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Investor && + address == other.address && + casId == other.casId && + email == other.email && + mobile == other.mobile && + name == other.name && + pan == other.pan && + pincode == other.pincode && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(address, casId, email, mobile, name, pan, pincode, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Investor{address=$address, casId=$casId, email=$email, mobile=$mobile, name=$name, pan=$pan, pincode=$pincode, additionalProperties=$additionalProperties}" + } + + class Meta + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val casType: JsonField, + private val generatedAt: JsonField, + private val statementPeriod: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("cas_type") + @ExcludeMissing + casType: JsonField = JsonMissing.of(), + @JsonProperty("generated_at") + @ExcludeMissing + generatedAt: JsonField = JsonMissing.of(), + @JsonProperty("statement_period") + @ExcludeMissing + statementPeriod: JsonField = JsonMissing.of(), + ) : this(casType, generatedAt, statementPeriod, mutableMapOf()) + + /** + * Type of CAS detected and processed + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun casType(): Optional = casType.getOptional("cas_type") + + /** + * Timestamp when the response was generated + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun generatedAt(): Optional = generatedAt.getOptional("generated_at") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun statementPeriod(): Optional = + statementPeriod.getOptional("statement_period") + + /** + * Returns the raw JSON value of [casType]. + * + * Unlike [casType], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("cas_type") @ExcludeMissing fun _casType(): JsonField = casType + + /** + * Returns the raw JSON value of [generatedAt]. + * + * Unlike [generatedAt], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("generated_at") + @ExcludeMissing + fun _generatedAt(): JsonField = generatedAt + + /** + * Returns the raw JSON value of [statementPeriod]. + * + * Unlike [statementPeriod], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("statement_period") + @ExcludeMissing + fun _statementPeriod(): JsonField = statementPeriod + + @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 [Meta]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Meta]. */ + class Builder internal constructor() { + + private var casType: JsonField = JsonMissing.of() + private var generatedAt: JsonField = JsonMissing.of() + private var statementPeriod: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(meta: Meta) = apply { + casType = meta.casType + generatedAt = meta.generatedAt + statementPeriod = meta.statementPeriod + additionalProperties = meta.additionalProperties.toMutableMap() + } + + /** Type of CAS detected and processed */ + fun casType(casType: CasType) = casType(JsonField.of(casType)) + + /** + * Sets [Builder.casType] to an arbitrary JSON value. + * + * You should usually call [Builder.casType] with a well-typed [CasType] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun casType(casType: JsonField) = apply { this.casType = casType } + + /** Timestamp when the response was generated */ + fun generatedAt(generatedAt: OffsetDateTime) = generatedAt(JsonField.of(generatedAt)) + + /** + * Sets [Builder.generatedAt] to an arbitrary JSON value. + * + * You should usually call [Builder.generatedAt] with a well-typed [OffsetDateTime] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun generatedAt(generatedAt: JsonField) = apply { + this.generatedAt = generatedAt + } + + fun statementPeriod(statementPeriod: StatementPeriod) = + statementPeriod(JsonField.of(statementPeriod)) + + /** + * Sets [Builder.statementPeriod] to an arbitrary JSON value. + * + * You should usually call [Builder.statementPeriod] with a well-typed [StatementPeriod] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun statementPeriod(statementPeriod: JsonField) = apply { + this.statementPeriod = statementPeriod + } + + 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 [Meta]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Meta = + Meta(casType, generatedAt, statementPeriod, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Meta = apply { + if (validated) { + return@apply + } + + casType().ifPresent { it.validate() } + generatedAt() + statementPeriod().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 = + (casType.asKnown().getOrNull()?.validity() ?: 0) + + (if (generatedAt.asKnown().isPresent) 1 else 0) + + (statementPeriod.asKnown().getOrNull()?.validity() ?: 0) + + /** Type of CAS detected and processed */ + class CasType @JsonCreator private constructor(private val value: JsonField) : + Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is + * on an older version than the API, then the API may respond with new members that the + * SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val NSDL = of("NSDL") + + @JvmField val CDSL = of("CDSL") + + @JvmField val CAMS_KFINTECH = of("CAMS_KFINTECH") + + @JvmStatic fun of(value: String) = CasType(JsonField.of(value)) + } + + /** An enum containing [CasType]'s known values. */ + enum class Known { + NSDL, + CDSL, + CAMS_KFINTECH, + } + + /** + * An enum containing [CasType]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [CasType] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if + * the SDK is on an older version than the API, then the API may respond with new + * members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + NSDL, + CDSL, + CAMS_KFINTECH, + /** + * An enum member indicating that [CasType] was instantiated with an unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you + * want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + NSDL -> Value.NSDL + CDSL -> Value.CDSL + CAMS_KFINTECH -> Value.CAMS_KFINTECH + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and + * don't want to throw for the unknown case. + * + * @throws CasParserInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + NSDL -> Known.NSDL + CDSL -> Known.CDSL + CAMS_KFINTECH -> Known.CAMS_KFINTECH + else -> throw CasParserInvalidDataException("Unknown CasType: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws CasParserInvalidDataException if this class instance's value does not have + * the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CasParserInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): CasType = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is CasType && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + class StatementPeriod + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val from: JsonField, + private val to: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("from") @ExcludeMissing from: JsonField = JsonMissing.of(), + @JsonProperty("to") @ExcludeMissing to: JsonField = JsonMissing.of(), + ) : this(from, to, mutableMapOf()) + + /** + * Start date of the statement period + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun from(): Optional = from.getOptional("from") + + /** + * End date of the statement period + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun to(): Optional = to.getOptional("to") + + /** + * Returns the raw JSON value of [from]. + * + * Unlike [from], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("from") @ExcludeMissing fun _from(): JsonField = from + + /** + * Returns the raw JSON value of [to]. + * + * Unlike [to], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("to") @ExcludeMissing fun _to(): JsonField = to + + @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 [StatementPeriod]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [StatementPeriod]. */ + class Builder internal constructor() { + + private var from: JsonField = JsonMissing.of() + private var to: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(statementPeriod: StatementPeriod) = apply { + from = statementPeriod.from + to = statementPeriod.to + additionalProperties = statementPeriod.additionalProperties.toMutableMap() + } + + /** Start date of the statement period */ + fun from(from: LocalDate) = from(JsonField.of(from)) + + /** + * Sets [Builder.from] to an arbitrary JSON value. + * + * You should usually call [Builder.from] with a well-typed [LocalDate] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun from(from: JsonField) = apply { this.from = from } + + /** End date of the statement period */ + fun to(to: LocalDate) = to(JsonField.of(to)) + + /** + * Sets [Builder.to] to an arbitrary JSON value. + * + * You should usually call [Builder.to] with a well-typed [LocalDate] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun to(to: JsonField) = apply { this.to = to } + + 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 [StatementPeriod]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): StatementPeriod = + StatementPeriod(from, to, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): StatementPeriod = apply { + if (validated) { + return@apply + } + + from() + to() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (from.asKnown().isPresent) 1 else 0) + (if (to.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is StatementPeriod && + from == other.from && + to == other.to && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(from, to, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "StatementPeriod{from=$from, to=$to, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Meta && + casType == other.casType && + generatedAt == other.generatedAt && + statementPeriod == other.statementPeriod && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(casType, generatedAt, statementPeriod, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Meta{casType=$casType, generatedAt=$generatedAt, statementPeriod=$statementPeriod, additionalProperties=$additionalProperties}" + } + + class MutualFund + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val additionalInfo: JsonField, + private val amc: JsonField, + private val folioNumber: JsonField, + private val linkedHolders: JsonField>, + private val registrar: JsonField, + private val schemes: JsonField>, + private val value: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("additional_info") + @ExcludeMissing + additionalInfo: JsonField = JsonMissing.of(), + @JsonProperty("amc") @ExcludeMissing amc: JsonField = JsonMissing.of(), + @JsonProperty("folio_number") + @ExcludeMissing + folioNumber: JsonField = JsonMissing.of(), + @JsonProperty("linked_holders") + @ExcludeMissing + linkedHolders: JsonField> = JsonMissing.of(), + @JsonProperty("registrar") + @ExcludeMissing + registrar: JsonField = JsonMissing.of(), + @JsonProperty("schemes") + @ExcludeMissing + schemes: JsonField> = JsonMissing.of(), + @JsonProperty("value") @ExcludeMissing value: JsonField = JsonMissing.of(), + ) : this( + additionalInfo, + amc, + folioNumber, + linkedHolders, + registrar, + schemes, + value, + mutableMapOf(), + ) + + /** + * Additional folio information + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun additionalInfo(): Optional = + additionalInfo.getOptional("additional_info") + + /** + * Asset Management Company name + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun amc(): Optional = amc.getOptional("amc") + + /** + * Folio number + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun folioNumber(): Optional = folioNumber.getOptional("folio_number") + + /** + * List of account holders linked to this mutual fund folio + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun linkedHolders(): Optional> = + linkedHolders.getOptional("linked_holders") + + /** + * Registrar and Transfer Agent name + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun registrar(): Optional = registrar.getOptional("registrar") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun schemes(): Optional> = schemes.getOptional("schemes") + + /** + * Total value of the folio + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun value(): Optional = value.getOptional("value") + + /** + * Returns the raw JSON value of [additionalInfo]. + * + * Unlike [additionalInfo], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("additional_info") + @ExcludeMissing + fun _additionalInfo(): JsonField = additionalInfo + + /** + * Returns the raw JSON value of [amc]. + * + * Unlike [amc], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("amc") @ExcludeMissing fun _amc(): JsonField = amc + + /** + * Returns the raw JSON value of [folioNumber]. + * + * Unlike [folioNumber], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("folio_number") + @ExcludeMissing + fun _folioNumber(): JsonField = folioNumber + + /** + * Returns the raw JSON value of [linkedHolders]. + * + * Unlike [linkedHolders], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("linked_holders") + @ExcludeMissing + fun _linkedHolders(): JsonField> = linkedHolders + + /** + * Returns the raw JSON value of [registrar]. + * + * Unlike [registrar], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("registrar") @ExcludeMissing fun _registrar(): JsonField = registrar + + /** + * Returns the raw JSON value of [schemes]. + * + * Unlike [schemes], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("schemes") @ExcludeMissing fun _schemes(): JsonField> = schemes + + /** + * Returns the raw JSON value of [value]. + * + * Unlike [value], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("value") @ExcludeMissing fun _value(): JsonField = value + + @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 [MutualFund]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [MutualFund]. */ + class Builder internal constructor() { + + private var additionalInfo: JsonField = JsonMissing.of() + private var amc: JsonField = JsonMissing.of() + private var folioNumber: JsonField = JsonMissing.of() + private var linkedHolders: JsonField>? = null + private var registrar: JsonField = JsonMissing.of() + private var schemes: JsonField>? = null + private var value: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(mutualFund: MutualFund) = apply { + additionalInfo = mutualFund.additionalInfo + amc = mutualFund.amc + folioNumber = mutualFund.folioNumber + linkedHolders = mutualFund.linkedHolders.map { it.toMutableList() } + registrar = mutualFund.registrar + schemes = mutualFund.schemes.map { it.toMutableList() } + value = mutualFund.value + additionalProperties = mutualFund.additionalProperties.toMutableMap() + } + + /** Additional folio information */ + fun additionalInfo(additionalInfo: AdditionalInfo) = + additionalInfo(JsonField.of(additionalInfo)) + + /** + * Sets [Builder.additionalInfo] to an arbitrary JSON value. + * + * You should usually call [Builder.additionalInfo] with a well-typed [AdditionalInfo] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun additionalInfo(additionalInfo: JsonField) = apply { + this.additionalInfo = additionalInfo + } + + /** Asset Management Company name */ + fun amc(amc: String) = amc(JsonField.of(amc)) + + /** + * Sets [Builder.amc] to an arbitrary JSON value. + * + * You should usually call [Builder.amc] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun amc(amc: JsonField) = apply { this.amc = amc } + + /** Folio number */ + fun folioNumber(folioNumber: String) = folioNumber(JsonField.of(folioNumber)) + + /** + * Sets [Builder.folioNumber] to an arbitrary JSON value. + * + * You should usually call [Builder.folioNumber] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun folioNumber(folioNumber: JsonField) = apply { + this.folioNumber = folioNumber + } + + /** List of account holders linked to this mutual fund folio */ + fun linkedHolders(linkedHolders: List) = + linkedHolders(JsonField.of(linkedHolders)) + + /** + * Sets [Builder.linkedHolders] to an arbitrary JSON value. + * + * You should usually call [Builder.linkedHolders] with a well-typed + * `List` value instead. This method is primarily for setting the field to + * an undocumented or not yet supported value. + */ + fun linkedHolders(linkedHolders: JsonField>) = apply { + this.linkedHolders = linkedHolders.map { it.toMutableList() } + } + + /** + * Adds a single [LinkedHolder] to [linkedHolders]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addLinkedHolder(linkedHolder: LinkedHolder) = apply { + linkedHolders = + (linkedHolders ?: JsonField.of(mutableListOf())).also { + checkKnown("linkedHolders", it).add(linkedHolder) + } + } + + /** Registrar and Transfer Agent name */ + fun registrar(registrar: String) = registrar(JsonField.of(registrar)) + + /** + * Sets [Builder.registrar] to an arbitrary JSON value. + * + * You should usually call [Builder.registrar] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun registrar(registrar: JsonField) = apply { this.registrar = registrar } + + fun schemes(schemes: List) = schemes(JsonField.of(schemes)) + + /** + * Sets [Builder.schemes] to an arbitrary JSON value. + * + * You should usually call [Builder.schemes] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun schemes(schemes: JsonField>) = apply { + this.schemes = schemes.map { it.toMutableList() } + } + + /** + * Adds a single [Scheme] to [schemes]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addScheme(scheme: Scheme) = apply { + schemes = + (schemes ?: JsonField.of(mutableListOf())).also { + checkKnown("schemes", it).add(scheme) + } + } + + /** Total value of the folio */ + fun value(value: Float) = value(JsonField.of(value)) + + /** + * Sets [Builder.value] to an arbitrary JSON value. + * + * You should usually call [Builder.value] with a well-typed [Float] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun value(value: JsonField) = apply { this.value = value } + + 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 [MutualFund]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): MutualFund = + MutualFund( + additionalInfo, + amc, + folioNumber, + (linkedHolders ?: JsonMissing.of()).map { it.toImmutable() }, + registrar, + (schemes ?: JsonMissing.of()).map { it.toImmutable() }, + value, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): MutualFund = apply { + if (validated) { + return@apply + } + + additionalInfo().ifPresent { it.validate() } + amc() + folioNumber() + linkedHolders().ifPresent { it.forEach { it.validate() } } + registrar() + schemes().ifPresent { it.forEach { it.validate() } } + value() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 = + (additionalInfo.asKnown().getOrNull()?.validity() ?: 0) + + (if (amc.asKnown().isPresent) 1 else 0) + + (if (folioNumber.asKnown().isPresent) 1 else 0) + + (linkedHolders.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (registrar.asKnown().isPresent) 1 else 0) + + (schemes.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (value.asKnown().isPresent) 1 else 0) + + /** Additional folio information */ + class AdditionalInfo + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val kyc: JsonField, + private val pan: JsonField, + private val pankyc: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("kyc") @ExcludeMissing kyc: JsonField = JsonMissing.of(), + @JsonProperty("pan") @ExcludeMissing pan: JsonField = JsonMissing.of(), + @JsonProperty("pankyc") @ExcludeMissing pankyc: JsonField = JsonMissing.of(), + ) : this(kyc, pan, pankyc, mutableMapOf()) + + /** + * KYC status of the folio + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun kyc(): Optional = kyc.getOptional("kyc") + + /** + * PAN associated with the folio + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun pan(): Optional = pan.getOptional("pan") + + /** + * PAN KYC status + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun pankyc(): Optional = pankyc.getOptional("pankyc") + + /** + * Returns the raw JSON value of [kyc]. + * + * Unlike [kyc], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("kyc") @ExcludeMissing fun _kyc(): JsonField = kyc + + /** + * Returns the raw JSON value of [pan]. + * + * Unlike [pan], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("pan") @ExcludeMissing fun _pan(): JsonField = pan + + /** + * Returns the raw JSON value of [pankyc]. + * + * Unlike [pankyc], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("pankyc") @ExcludeMissing fun _pankyc(): JsonField = pankyc + + @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 [AdditionalInfo]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AdditionalInfo]. */ + class Builder internal constructor() { + + private var kyc: JsonField = JsonMissing.of() + private var pan: JsonField = JsonMissing.of() + private var pankyc: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(additionalInfo: AdditionalInfo) = apply { + kyc = additionalInfo.kyc + pan = additionalInfo.pan + pankyc = additionalInfo.pankyc + additionalProperties = additionalInfo.additionalProperties.toMutableMap() + } + + /** KYC status of the folio */ + fun kyc(kyc: String) = kyc(JsonField.of(kyc)) + + /** + * Sets [Builder.kyc] to an arbitrary JSON value. + * + * You should usually call [Builder.kyc] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun kyc(kyc: JsonField) = apply { this.kyc = kyc } + + /** PAN associated with the folio */ + fun pan(pan: String) = pan(JsonField.of(pan)) + + /** + * Sets [Builder.pan] to an arbitrary JSON value. + * + * You should usually call [Builder.pan] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun pan(pan: JsonField) = apply { this.pan = pan } + + /** PAN KYC status */ + fun pankyc(pankyc: String) = pankyc(JsonField.of(pankyc)) + + /** + * Sets [Builder.pankyc] to an arbitrary JSON value. + * + * You should usually call [Builder.pankyc] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun pankyc(pankyc: JsonField) = apply { this.pankyc = pankyc } + + 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 [AdditionalInfo]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): AdditionalInfo = + AdditionalInfo(kyc, pan, pankyc, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): AdditionalInfo = apply { + if (validated) { + return@apply + } + + kyc() + pan() + pankyc() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (kyc.asKnown().isPresent) 1 else 0) + + (if (pan.asKnown().isPresent) 1 else 0) + + (if (pankyc.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AdditionalInfo && + kyc == other.kyc && + pan == other.pan && + pankyc == other.pankyc && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(kyc, pan, pankyc, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AdditionalInfo{kyc=$kyc, pan=$pan, pankyc=$pankyc, additionalProperties=$additionalProperties}" + } + + class LinkedHolder + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val name: JsonField, + private val pan: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("pan") @ExcludeMissing pan: JsonField = JsonMissing.of(), + ) : this(name, pan, mutableMapOf()) + + /** + * Name of the account holder + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun name(): Optional = name.getOptional("name") + + /** + * PAN of the account holder + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun pan(): Optional = pan.getOptional("pan") + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + + /** + * Returns the raw JSON value of [pan]. + * + * Unlike [pan], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("pan") @ExcludeMissing fun _pan(): JsonField = pan + + @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 [LinkedHolder]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [LinkedHolder]. */ + class Builder internal constructor() { + + private var name: JsonField = JsonMissing.of() + private var pan: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(linkedHolder: LinkedHolder) = apply { + name = linkedHolder.name + pan = linkedHolder.pan + additionalProperties = linkedHolder.additionalProperties.toMutableMap() + } + + /** Name of the account holder */ + fun name(name: String) = name(JsonField.of(name)) + + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun name(name: JsonField) = apply { this.name = name } + + /** PAN of the account holder */ + fun pan(pan: String) = pan(JsonField.of(pan)) + + /** + * Sets [Builder.pan] to an arbitrary JSON value. + * + * You should usually call [Builder.pan] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun pan(pan: JsonField) = apply { this.pan = pan } + + 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 [LinkedHolder]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): LinkedHolder = + LinkedHolder(name, pan, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): LinkedHolder = apply { + if (validated) { + return@apply + } + + name() + pan() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (name.asKnown().isPresent) 1 else 0) + (if (pan.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is LinkedHolder && + name == other.name && + pan == other.pan && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(name, pan, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "LinkedHolder{name=$name, pan=$pan, additionalProperties=$additionalProperties}" + } + + class Scheme + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val additionalInfo: JsonField, + private val cost: JsonField, + private val gain: JsonField, + private val isin: JsonField, + private val name: JsonField, + private val nav: JsonField, + private val nominees: JsonField>, + private val transactions: JsonField>, + private val type: JsonField, + private val units: JsonField, + private val value: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("additional_info") + @ExcludeMissing + additionalInfo: JsonField = JsonMissing.of(), + @JsonProperty("cost") @ExcludeMissing cost: JsonField = JsonMissing.of(), + @JsonProperty("gain") @ExcludeMissing gain: JsonField = JsonMissing.of(), + @JsonProperty("isin") @ExcludeMissing isin: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("nav") @ExcludeMissing nav: JsonField = JsonMissing.of(), + @JsonProperty("nominees") + @ExcludeMissing + nominees: JsonField> = JsonMissing.of(), + @JsonProperty("transactions") + @ExcludeMissing + transactions: JsonField> = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), + @JsonProperty("units") @ExcludeMissing units: JsonField = JsonMissing.of(), + @JsonProperty("value") @ExcludeMissing value: JsonField = JsonMissing.of(), + ) : this( + additionalInfo, + cost, + gain, + isin, + name, + nav, + nominees, + transactions, + type, + units, + value, + mutableMapOf(), + ) + + /** + * Additional information specific to the scheme + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun additionalInfo(): Optional = + additionalInfo.getOptional("additional_info") + + /** + * Cost of investment + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun cost(): Optional = cost.getOptional("cost") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun gain(): Optional = gain.getOptional("gain") + + /** + * ISIN code of the scheme + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun isin(): Optional = isin.getOptional("isin") + + /** + * Scheme name + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun name(): Optional = name.getOptional("name") + + /** + * Net Asset Value per unit + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun nav(): Optional = nav.getOptional("nav") + + /** + * List of nominees + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun nominees(): Optional> = nominees.getOptional("nominees") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun transactions(): Optional> = + transactions.getOptional("transactions") + + /** + * Type of mutual fund scheme + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun type(): Optional = type.getOptional("type") + + /** + * Number of units held + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun units(): Optional = units.getOptional("units") + + /** + * Current market value of the holding + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun value(): Optional = value.getOptional("value") + + /** + * Returns the raw JSON value of [additionalInfo]. + * + * Unlike [additionalInfo], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("additional_info") + @ExcludeMissing + fun _additionalInfo(): JsonField = additionalInfo + + /** + * Returns the raw JSON value of [cost]. + * + * Unlike [cost], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("cost") @ExcludeMissing fun _cost(): JsonField = cost + + /** + * Returns the raw JSON value of [gain]. + * + * Unlike [gain], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("gain") @ExcludeMissing fun _gain(): JsonField = gain + + /** + * Returns the raw JSON value of [isin]. + * + * Unlike [isin], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("isin") @ExcludeMissing fun _isin(): JsonField = isin + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + + /** + * Returns the raw JSON value of [nav]. + * + * Unlike [nav], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("nav") @ExcludeMissing fun _nav(): JsonField = nav + + /** + * Returns the raw JSON value of [nominees]. + * + * Unlike [nominees], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("nominees") + @ExcludeMissing + fun _nominees(): JsonField> = nominees + + /** + * Returns the raw JSON value of [transactions]. + * + * Unlike [transactions], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("transactions") + @ExcludeMissing + fun _transactions(): JsonField> = transactions + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + + /** + * Returns the raw JSON value of [units]. + * + * Unlike [units], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("units") @ExcludeMissing fun _units(): JsonField = units + + /** * Returns the raw JSON value of [value]. * - * Unlike [value], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [value], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("value") @ExcludeMissing fun _value(): JsonField = value + + @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 [Scheme]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Scheme]. */ + class Builder internal constructor() { + + private var additionalInfo: JsonField = JsonMissing.of() + private var cost: JsonField = JsonMissing.of() + private var gain: JsonField = JsonMissing.of() + private var isin: JsonField = JsonMissing.of() + private var name: JsonField = JsonMissing.of() + private var nav: JsonField = JsonMissing.of() + private var nominees: JsonField>? = null + private var transactions: JsonField>? = null + private var type: JsonField = JsonMissing.of() + private var units: JsonField = JsonMissing.of() + private var value: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(scheme: Scheme) = apply { + additionalInfo = scheme.additionalInfo + cost = scheme.cost + gain = scheme.gain + isin = scheme.isin + name = scheme.name + nav = scheme.nav + nominees = scheme.nominees.map { it.toMutableList() } + transactions = scheme.transactions.map { it.toMutableList() } + type = scheme.type + units = scheme.units + value = scheme.value + additionalProperties = scheme.additionalProperties.toMutableMap() + } + + /** Additional information specific to the scheme */ + fun additionalInfo(additionalInfo: AdditionalInfo) = + additionalInfo(JsonField.of(additionalInfo)) + + /** + * Sets [Builder.additionalInfo] to an arbitrary JSON value. + * + * You should usually call [Builder.additionalInfo] with a well-typed + * [AdditionalInfo] value instead. This method is primarily for setting the field to + * an undocumented or not yet supported value. + */ + fun additionalInfo(additionalInfo: JsonField) = apply { + this.additionalInfo = additionalInfo + } + + /** Cost of investment */ + fun cost(cost: Float) = cost(JsonField.of(cost)) + + /** + * Sets [Builder.cost] to an arbitrary JSON value. + * + * You should usually call [Builder.cost] with a well-typed [Float] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun cost(cost: JsonField) = apply { this.cost = cost } + + fun gain(gain: Gain) = gain(JsonField.of(gain)) + + /** + * Sets [Builder.gain] to an arbitrary JSON value. + * + * You should usually call [Builder.gain] with a well-typed [Gain] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun gain(gain: JsonField) = apply { this.gain = gain } + + /** ISIN code of the scheme */ + fun isin(isin: String) = isin(JsonField.of(isin)) + + /** + * Sets [Builder.isin] to an arbitrary JSON value. + * + * You should usually call [Builder.isin] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun isin(isin: JsonField) = apply { this.isin = isin } + + /** Scheme name */ + fun name(name: String) = name(JsonField.of(name)) + + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun name(name: JsonField) = apply { this.name = name } + + /** Net Asset Value per unit */ + fun nav(nav: Float) = nav(JsonField.of(nav)) + + /** + * Sets [Builder.nav] to an arbitrary JSON value. + * + * You should usually call [Builder.nav] with a well-typed [Float] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun nav(nav: JsonField) = apply { this.nav = nav } + + /** List of nominees */ + fun nominees(nominees: List) = nominees(JsonField.of(nominees)) + + /** + * Sets [Builder.nominees] to an arbitrary JSON value. + * + * You should usually call [Builder.nominees] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun nominees(nominees: JsonField>) = apply { + this.nominees = nominees.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [nominees]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addNominee(nominee: String) = apply { + nominees = + (nominees ?: JsonField.of(mutableListOf())).also { + checkKnown("nominees", it).add(nominee) + } + } + + fun transactions(transactions: List) = + transactions(JsonField.of(transactions)) + + /** + * Sets [Builder.transactions] to an arbitrary JSON value. + * + * You should usually call [Builder.transactions] with a well-typed + * `List` value instead. This method is primarily for setting the field + * to an undocumented or not yet supported value. + */ + fun transactions(transactions: JsonField>) = apply { + this.transactions = transactions.map { it.toMutableList() } + } + + /** + * Adds a single [Transaction] to [transactions]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addTransaction(transaction: Transaction) = apply { + transactions = + (transactions ?: JsonField.of(mutableListOf())).also { + checkKnown("transactions", it).add(transaction) + } + } + + /** Type of mutual fund scheme */ + fun type(type: Type) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonField) = apply { this.type = type } + + /** Number of units held */ + fun units(units: Float) = units(JsonField.of(units)) + + /** + * Sets [Builder.units] to an arbitrary JSON value. + * + * You should usually call [Builder.units] with a well-typed [Float] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun units(units: JsonField) = apply { this.units = units } + + /** Current market value of the holding */ + fun value(value: Float) = value(JsonField.of(value)) + + /** + * Sets [Builder.value] to an arbitrary JSON value. + * + * You should usually call [Builder.value] with a well-typed [Float] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun value(value: JsonField) = apply { this.value = value } + + 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 [Scheme]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Scheme = + Scheme( + additionalInfo, + cost, + gain, + isin, + name, + nav, + (nominees ?: JsonMissing.of()).map { it.toImmutable() }, + (transactions ?: JsonMissing.of()).map { it.toImmutable() }, + type, + units, + value, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Scheme = apply { + if (validated) { + return@apply + } + + additionalInfo().ifPresent { it.validate() } + cost() + gain().ifPresent { it.validate() } + isin() + name() + nav() + nominees() + transactions().ifPresent { it.forEach { it.validate() } } + type().ifPresent { it.validate() } + units() + value() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. */ - @JsonProperty("value") @ExcludeMissing fun _value(): JsonField = value + @JvmSynthetic + internal fun validity(): Int = + (additionalInfo.asKnown().getOrNull()?.validity() ?: 0) + + (if (cost.asKnown().isPresent) 1 else 0) + + (gain.asKnown().getOrNull()?.validity() ?: 0) + + (if (isin.asKnown().isPresent) 1 else 0) + + (if (name.asKnown().isPresent) 1 else 0) + + (if (nav.asKnown().isPresent) 1 else 0) + + (nominees.asKnown().getOrNull()?.size ?: 0) + + (transactions.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (type.asKnown().getOrNull()?.validity() ?: 0) + + (if (units.asKnown().isPresent) 1 else 0) + + (if (value.asKnown().isPresent) 1 else 0) - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } + /** Additional information specific to the scheme */ + class AdditionalInfo + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val advisor: JsonField, + private val amfi: JsonField, + private val closeUnits: JsonField, + private val openUnits: JsonField, + private val rtaCode: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("advisor") + @ExcludeMissing + advisor: JsonField = JsonMissing.of(), + @JsonProperty("amfi") + @ExcludeMissing + amfi: JsonField = JsonMissing.of(), + @JsonProperty("close_units") + @ExcludeMissing + closeUnits: JsonField = JsonMissing.of(), + @JsonProperty("open_units") + @ExcludeMissing + openUnits: JsonField = JsonMissing.of(), + @JsonProperty("rta_code") + @ExcludeMissing + rtaCode: JsonField = JsonMissing.of(), + ) : this(advisor, amfi, closeUnits, openUnits, rtaCode, mutableMapOf()) + + /** + * Financial advisor name (CAMS/KFintech) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun advisor(): Optional = advisor.getOptional("advisor") + + /** + * AMFI code for the scheme (CAMS/KFintech) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun amfi(): Optional = amfi.getOptional("amfi") + + /** + * Closing balance units for the statement period + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun closeUnits(): Optional = closeUnits.getOptional("close_units") + + /** + * Opening balance units for the statement period + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun openUnits(): Optional = openUnits.getOptional("open_units") + + /** + * RTA code for the scheme (CAMS/KFintech) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun rtaCode(): Optional = rtaCode.getOptional("rta_code") + + /** + * Returns the raw JSON value of [advisor]. + * + * Unlike [advisor], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("advisor") @ExcludeMissing fun _advisor(): JsonField = advisor + + /** + * Returns the raw JSON value of [amfi]. + * + * Unlike [amfi], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("amfi") @ExcludeMissing fun _amfi(): JsonField = amfi + + /** + * Returns the raw JSON value of [closeUnits]. + * + * Unlike [closeUnits], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("close_units") + @ExcludeMissing + fun _closeUnits(): JsonField = closeUnits + + /** + * Returns the raw JSON value of [openUnits]. + * + * Unlike [openUnits], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("open_units") + @ExcludeMissing + fun _openUnits(): JsonField = openUnits + + /** + * Returns the raw JSON value of [rtaCode]. + * + * Unlike [rtaCode], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("rta_code") + @ExcludeMissing + fun _rtaCode(): JsonField = rtaCode + + @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 [AdditionalInfo]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AdditionalInfo]. */ + class Builder internal constructor() { + + private var advisor: JsonField = JsonMissing.of() + private var amfi: JsonField = JsonMissing.of() + private var closeUnits: JsonField = JsonMissing.of() + private var openUnits: JsonField = JsonMissing.of() + private var rtaCode: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(additionalInfo: AdditionalInfo) = apply { + advisor = additionalInfo.advisor + amfi = additionalInfo.amfi + closeUnits = additionalInfo.closeUnits + openUnits = additionalInfo.openUnits + rtaCode = additionalInfo.rtaCode + additionalProperties = additionalInfo.additionalProperties.toMutableMap() + } + + /** Financial advisor name (CAMS/KFintech) */ + fun advisor(advisor: String) = advisor(JsonField.of(advisor)) + + /** + * Sets [Builder.advisor] to an arbitrary JSON value. + * + * You should usually call [Builder.advisor] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun advisor(advisor: JsonField) = apply { this.advisor = advisor } + + /** AMFI code for the scheme (CAMS/KFintech) */ + fun amfi(amfi: String) = amfi(JsonField.of(amfi)) + + /** + * Sets [Builder.amfi] to an arbitrary JSON value. + * + * You should usually call [Builder.amfi] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun amfi(amfi: JsonField) = apply { this.amfi = amfi } + + /** Closing balance units for the statement period */ + fun closeUnits(closeUnits: Float?) = + closeUnits(JsonField.ofNullable(closeUnits)) + + /** + * Alias for [Builder.closeUnits]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun closeUnits(closeUnits: Float) = closeUnits(closeUnits as Float?) - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) + /** Alias for calling [Builder.closeUnits] with `closeUnits.orElse(null)`. */ + fun closeUnits(closeUnits: Optional) = closeUnits(closeUnits.getOrNull()) - fun toBuilder() = Builder().from(this) + /** + * Sets [Builder.closeUnits] to an arbitrary JSON value. + * + * You should usually call [Builder.closeUnits] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun closeUnits(closeUnits: JsonField) = apply { + this.closeUnits = closeUnits + } - companion object { + /** Opening balance units for the statement period */ + fun openUnits(openUnits: Float?) = openUnits(JsonField.ofNullable(openUnits)) - /** Returns a mutable builder for constructing an instance of [Scheme]. */ - @JvmStatic fun builder() = Builder() - } + /** + * Alias for [Builder.openUnits]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun openUnits(openUnits: Float) = openUnits(openUnits as Float?) - /** A builder for [Scheme]. */ - class Builder internal constructor() { + /** Alias for calling [Builder.openUnits] with `openUnits.orElse(null)`. */ + fun openUnits(openUnits: Optional) = openUnits(openUnits.getOrNull()) - private var additionalInfo: JsonField = JsonMissing.of() - private var cost: JsonField = JsonMissing.of() - private var gain: JsonField = JsonMissing.of() - private var isin: JsonField = JsonMissing.of() - private var name: JsonField = JsonMissing.of() - private var nav: JsonField = JsonMissing.of() - private var nominees: JsonField>? = null - private var transactions: JsonField>? = null - private var type: JsonField = JsonMissing.of() - private var units: JsonField = JsonMissing.of() - private var value: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() + /** + * Sets [Builder.openUnits] to an arbitrary JSON value. + * + * You should usually call [Builder.openUnits] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun openUnits(openUnits: JsonField) = apply { + this.openUnits = openUnits + } - @JvmSynthetic - internal fun from(scheme: Scheme) = apply { - additionalInfo = scheme.additionalInfo - cost = scheme.cost - gain = scheme.gain - isin = scheme.isin - name = scheme.name - nav = scheme.nav - nominees = scheme.nominees.map { it.toMutableList() } - transactions = scheme.transactions.map { it.toMutableList() } - type = scheme.type - units = scheme.units - value = scheme.value - additionalProperties = scheme.additionalProperties.toMutableMap() - } + /** RTA code for the scheme (CAMS/KFintech) */ + fun rtaCode(rtaCode: String) = rtaCode(JsonField.of(rtaCode)) - /** Additional information specific to the scheme */ - fun additionalInfo(additionalInfo: AdditionalInfo) = - additionalInfo(JsonField.of(additionalInfo)) + /** + * Sets [Builder.rtaCode] to an arbitrary JSON value. + * + * You should usually call [Builder.rtaCode] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun rtaCode(rtaCode: JsonField) = apply { this.rtaCode = rtaCode } - /** - * Sets [Builder.additionalInfo] to an arbitrary JSON value. - * - * You should usually call [Builder.additionalInfo] with a well-typed - * [AdditionalInfo] value instead. This method is primarily for setting the field to - * an undocumented or not yet supported value. - */ - fun additionalInfo(additionalInfo: JsonField) = apply { - this.additionalInfo = additionalInfo - } + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } - /** Cost of investment */ - fun cost(cost: Float) = cost(JsonField.of(cost)) + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } - /** - * Sets [Builder.cost] to an arbitrary JSON value. - * - * You should usually call [Builder.cost] with a well-typed [Float] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun cost(cost: JsonField) = apply { this.cost = cost } + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } - fun gain(gain: Gain) = gain(JsonField.of(gain)) + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } - /** - * Sets [Builder.gain] to an arbitrary JSON value. - * - * You should usually call [Builder.gain] with a well-typed [Gain] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun gain(gain: JsonField) = apply { this.gain = gain } + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } - /** ISIN code of the scheme */ - fun isin(isin: String) = isin(JsonField.of(isin)) + /** + * Returns an immutable instance of [AdditionalInfo]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): AdditionalInfo = + AdditionalInfo( + advisor, + amfi, + closeUnits, + openUnits, + rtaCode, + additionalProperties.toMutableMap(), + ) + } - /** - * Sets [Builder.isin] to an arbitrary JSON value. - * - * You should usually call [Builder.isin] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun isin(isin: JsonField) = apply { this.isin = isin } + private var validated: Boolean = false - /** Scheme name */ - fun name(name: String) = name(JsonField.of(name)) + fun validate(): AdditionalInfo = apply { + if (validated) { + return@apply + } - /** - * Sets [Builder.name] to an arbitrary JSON value. - * - * You should usually call [Builder.name] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun name(name: JsonField) = apply { this.name = name } + advisor() + amfi() + closeUnits() + openUnits() + rtaCode() + validated = true + } - /** Net Asset Value per unit */ - fun nav(nav: Float) = nav(JsonField.of(nav)) + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + false + } /** - * Sets [Builder.nav] to an arbitrary JSON value. + * Returns a score indicating how many valid values are contained in this object + * recursively. * - * You should usually call [Builder.nav] with a well-typed [Float] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. + * Used for best match union deserialization. */ - fun nav(nav: JsonField) = apply { this.nav = nav } + @JvmSynthetic + internal fun validity(): Int = + (if (advisor.asKnown().isPresent) 1 else 0) + + (if (amfi.asKnown().isPresent) 1 else 0) + + (if (closeUnits.asKnown().isPresent) 1 else 0) + + (if (openUnits.asKnown().isPresent) 1 else 0) + + (if (rtaCode.asKnown().isPresent) 1 else 0) - /** List of nominees */ - fun nominees(nominees: List) = nominees(JsonField.of(nominees)) + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - /** - * Sets [Builder.nominees] to an arbitrary JSON value. - * - * You should usually call [Builder.nominees] with a well-typed `List` value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. - */ - fun nominees(nominees: JsonField>) = apply { - this.nominees = nominees.map { it.toMutableList() } + return other is AdditionalInfo && + advisor == other.advisor && + amfi == other.amfi && + closeUnits == other.closeUnits && + openUnits == other.openUnits && + rtaCode == other.rtaCode && + additionalProperties == other.additionalProperties } - /** - * Adds a single [String] to [nominees]. - * - * @throws IllegalStateException if the field was previously set to a non-list. - */ - fun addNominee(nominee: String) = apply { - nominees = - (nominees ?: JsonField.of(mutableListOf())).also { - checkKnown("nominees", it).add(nominee) - } + private val hashCode: Int by lazy { + Objects.hash( + advisor, + amfi, + closeUnits, + openUnits, + rtaCode, + additionalProperties, + ) } - fun transactions(transactions: List) = - transactions(JsonField.of(transactions)) + override fun hashCode(): Int = hashCode + + override fun toString() = + "AdditionalInfo{advisor=$advisor, amfi=$amfi, closeUnits=$closeUnits, openUnits=$openUnits, rtaCode=$rtaCode, additionalProperties=$additionalProperties}" + } + + class Gain + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val absolute: JsonField, + private val percentage: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("absolute") + @ExcludeMissing + absolute: JsonField = JsonMissing.of(), + @JsonProperty("percentage") + @ExcludeMissing + percentage: JsonField = JsonMissing.of(), + ) : this(absolute, percentage, mutableMapOf()) /** - * Sets [Builder.transactions] to an arbitrary JSON value. + * Absolute gain or loss * - * You should usually call [Builder.transactions] with a well-typed - * `List` value instead. This method is primarily for setting the field - * to an undocumented or not yet supported value. + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). */ - fun transactions(transactions: JsonField>) = apply { - this.transactions = transactions.map { it.toMutableList() } - } + fun absolute(): Optional = absolute.getOptional("absolute") /** - * Adds a single [Transaction] to [transactions]. + * Percentage gain or loss * - * @throws IllegalStateException if the field was previously set to a non-list. + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). */ - fun addTransaction(transaction: Transaction) = apply { - transactions = - (transactions ?: JsonField.of(mutableListOf())).also { - checkKnown("transactions", it).add(transaction) - } - } - - /** Type of mutual fund scheme */ - fun type(type: Type) = type(JsonField.of(type)) + fun percentage(): Optional = percentage.getOptional("percentage") /** - * Sets [Builder.type] to an arbitrary JSON value. + * Returns the raw JSON value of [absolute]. * - * You should usually call [Builder.type] with a well-typed [Type] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. + * Unlike [absolute], this method doesn't throw if the JSON field has an unexpected + * type. */ - fun type(type: JsonField) = apply { this.type = type } - - /** Number of units held */ - fun units(units: Float) = units(JsonField.of(units)) + @JsonProperty("absolute") + @ExcludeMissing + fun _absolute(): JsonField = absolute /** - * Sets [Builder.units] to an arbitrary JSON value. + * Returns the raw JSON value of [percentage]. * - * You should usually call [Builder.units] with a well-typed [Float] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. + * Unlike [percentage], this method doesn't throw if the JSON field has an + * unexpected type. */ - fun units(units: JsonField) = apply { this.units = units } + @JsonProperty("percentage") + @ExcludeMissing + fun _percentage(): JsonField = percentage - /** Current market value of the holding */ - fun value(value: Float) = value(JsonField.of(value)) + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } - /** - * Sets [Builder.value] to an arbitrary JSON value. - * - * You should usually call [Builder.value] with a well-typed [Float] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun value(value: JsonField) = apply { this.value = value } + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } + fun toBuilder() = Builder().from(this) - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) + companion object { + + /** Returns a mutable builder for constructing an instance of [Gain]. */ + @JvmStatic fun builder() = Builder() } - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) + /** A builder for [Gain]. */ + class Builder internal constructor() { + + private var absolute: JsonField = JsonMissing.of() + private var percentage: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(gain: Gain) = apply { + absolute = gain.absolute + percentage = gain.percentage + additionalProperties = gain.additionalProperties.toMutableMap() } - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) + /** Absolute gain or loss */ + fun absolute(absolute: Float) = absolute(JsonField.of(absolute)) + + /** + * Sets [Builder.absolute] to an arbitrary JSON value. + * + * You should usually call [Builder.absolute] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun absolute(absolute: JsonField) = apply { this.absolute = absolute } + + /** Percentage gain or loss */ + fun percentage(percentage: Float) = percentage(JsonField.of(percentage)) + + /** + * Sets [Builder.percentage] to an arbitrary JSON value. + * + * You should usually call [Builder.percentage] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun percentage(percentage: JsonField) = apply { + this.percentage = percentage + } + + 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 [Gain]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Gain = + Gain(absolute, percentage, additionalProperties.toMutableMap()) } - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) + private var validated: Boolean = false + + fun validate(): Gain = apply { + if (validated) { + return@apply + } + + absolute() + percentage() + validated = true } + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + false + } + /** - * Returns an immutable instance of [Scheme]. + * Returns a score indicating how many valid values are contained in this object + * recursively. * - * Further updates to this [Builder] will not mutate the returned instance. + * Used for best match union deserialization. */ - fun build(): Scheme = - Scheme( - additionalInfo, - cost, - gain, - isin, - name, - nav, - (nominees ?: JsonMissing.of()).map { it.toImmutable() }, - (transactions ?: JsonMissing.of()).map { it.toImmutable() }, - type, - units, - value, - additionalProperties.toMutableMap(), - ) - } + @JvmSynthetic + internal fun validity(): Int = + (if (absolute.asKnown().isPresent) 1 else 0) + + (if (percentage.asKnown().isPresent) 1 else 0) - private var validated: Boolean = false + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - fun validate(): Scheme = apply { - if (validated) { - return@apply + return other is Gain && + absolute == other.absolute && + percentage == other.percentage && + additionalProperties == other.additionalProperties } - additionalInfo().ifPresent { it.validate() } - cost() - gain().ifPresent { it.validate() } - isin() - name() - nav() - nominees() - transactions().ifPresent { it.forEach { it.validate() } } - type().ifPresent { it.validate() } - units() - value() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - false + private val hashCode: Int by lazy { + Objects.hash(absolute, percentage, additionalProperties) } - /** - * 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 = - (additionalInfo.asKnown().getOrNull()?.validity() ?: 0) + - (if (cost.asKnown().isPresent) 1 else 0) + - (gain.asKnown().getOrNull()?.validity() ?: 0) + - (if (isin.asKnown().isPresent) 1 else 0) + - (if (name.asKnown().isPresent) 1 else 0) + - (if (nav.asKnown().isPresent) 1 else 0) + - (nominees.asKnown().getOrNull()?.size ?: 0) + - (transactions.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + - (type.asKnown().getOrNull()?.validity() ?: 0) + - (if (units.asKnown().isPresent) 1 else 0) + - (if (value.asKnown().isPresent) 1 else 0) + override fun hashCode(): Int = hashCode + + override fun toString() = + "Gain{absolute=$absolute, percentage=$percentage, additionalProperties=$additionalProperties}" + } - /** Additional information specific to the scheme */ - class AdditionalInfo + /** + * Unified transaction schema for all holding types (MF folios, equities, bonds, etc.) + */ + class Transaction @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( - private val advisor: JsonField, - private val amfi: JsonField, - private val closeUnits: JsonField, - private val openUnits: JsonField, - private val rtaCode: JsonField, + private val additionalInfo: JsonField, + private val amount: JsonField, + private val balance: JsonField, + private val date: JsonField, + private val description: JsonField, + private val dividendRate: JsonField, + private val nav: JsonField, + private val type: JsonField, + private val units: JsonField, private val additionalProperties: MutableMap, ) { @JsonCreator private constructor( - @JsonProperty("advisor") + @JsonProperty("additional_info") @ExcludeMissing - advisor: JsonField = JsonMissing.of(), - @JsonProperty("amfi") + additionalInfo: JsonField = JsonMissing.of(), + @JsonProperty("amount") @ExcludeMissing - amfi: JsonField = JsonMissing.of(), - @JsonProperty("close_units") + amount: JsonField = JsonMissing.of(), + @JsonProperty("balance") @ExcludeMissing - closeUnits: JsonField = JsonMissing.of(), - @JsonProperty("open_units") + balance: JsonField = JsonMissing.of(), + @JsonProperty("date") @ExcludeMissing - openUnits: JsonField = JsonMissing.of(), - @JsonProperty("rta_code") + date: JsonField = JsonMissing.of(), + @JsonProperty("description") @ExcludeMissing - rtaCode: JsonField = JsonMissing.of(), - ) : this(advisor, amfi, closeUnits, openUnits, rtaCode, mutableMapOf()) + description: JsonField = JsonMissing.of(), + @JsonProperty("dividend_rate") + @ExcludeMissing + dividendRate: JsonField = JsonMissing.of(), + @JsonProperty("nav") @ExcludeMissing nav: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), + @JsonProperty("units") + @ExcludeMissing + units: JsonField = JsonMissing.of(), + ) : this( + additionalInfo, + amount, + balance, + date, + description, + dividendRate, + nav, + type, + units, + mutableMapOf(), + ) /** - * Financial advisor name (CAMS/KFintech) + * Additional transaction-specific fields that vary by source * * @throws CasParserInvalidDataException if the JSON field has an unexpected type * (e.g. if the server responded with an unexpected value). */ - fun advisor(): Optional = advisor.getOptional("advisor") + fun additionalInfo(): Optional = + additionalInfo.getOptional("additional_info") /** - * AMFI code for the scheme (CAMS/KFintech) + * Transaction amount in currency (computed from units × price/NAV) * * @throws CasParserInvalidDataException if the JSON field has an unexpected type * (e.g. if the server responded with an unexpected value). */ - fun amfi(): Optional = amfi.getOptional("amfi") + fun amount(): Optional = amount.getOptional("amount") /** - * Closing balance units (CAMS/KFintech) + * Balance units after transaction * * @throws CasParserInvalidDataException if the JSON field has an unexpected type * (e.g. if the server responded with an unexpected value). */ - fun closeUnits(): Optional = closeUnits.getOptional("close_units") + fun balance(): Optional = balance.getOptional("balance") /** - * Opening balance units (CAMS/KFintech) + * Transaction date (YYYY-MM-DD) * * @throws CasParserInvalidDataException if the JSON field has an unexpected type * (e.g. if the server responded with an unexpected value). */ - fun openUnits(): Optional = openUnits.getOptional("open_units") + fun date(): Optional = date.getOptional("date") /** - * RTA code for the scheme (CAMS/KFintech) + * Transaction description/particulars * * @throws CasParserInvalidDataException if the JSON field has an unexpected type * (e.g. if the server responded with an unexpected value). */ - fun rtaCode(): Optional = rtaCode.getOptional("rta_code") + fun description(): Optional = description.getOptional("description") /** - * Returns the raw JSON value of [advisor]. + * Dividend rate (for DIVIDEND_PAYOUT transactions) * - * Unlike [advisor], this method doesn't throw if the JSON field has an unexpected + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun dividendRate(): Optional = dividendRate.getOptional("dividend_rate") + + /** + * NAV/price per unit on transaction date + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun nav(): Optional = nav.getOptional("nav") + + /** + * Transaction type. Possible values are PURCHASE, PURCHASE_SIP, REDEMPTION, + * SWITCH_IN, SWITCH_IN_MERGER, SWITCH_OUT, SWITCH_OUT_MERGER, DIVIDEND_PAYOUT, + * DIVIDEND_REINVEST, SEGREGATION, STAMP_DUTY_TAX, TDS_TAX, STT_TAX, MISC, REVERSAL, + * UNKNOWN. + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun type(): Optional = type.getOptional("type") + + /** + * Number of units involved in transaction + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun units(): Optional = units.getOptional("units") + + /** + * Returns the raw JSON value of [additionalInfo]. + * + * Unlike [additionalInfo], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("additional_info") + @ExcludeMissing + fun _additionalInfo(): JsonField = additionalInfo + + /** + * Returns the raw JSON value of [amount]. + * + * Unlike [amount], this method doesn't throw if the JSON field has an unexpected * type. */ - @JsonProperty("advisor") @ExcludeMissing fun _advisor(): JsonField = advisor + @JsonProperty("amount") @ExcludeMissing fun _amount(): JsonField = amount /** - * Returns the raw JSON value of [amfi]. + * Returns the raw JSON value of [balance]. * - * Unlike [amfi], this method doesn't throw if the JSON field has an unexpected + * Unlike [balance], this method doesn't throw if the JSON field has an unexpected * type. */ - @JsonProperty("amfi") @ExcludeMissing fun _amfi(): JsonField = amfi + @JsonProperty("balance") @ExcludeMissing fun _balance(): JsonField = balance /** - * Returns the raw JSON value of [closeUnits]. + * Returns the raw JSON value of [date]. * - * Unlike [closeUnits], this method doesn't throw if the JSON field has an + * Unlike [date], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("date") @ExcludeMissing fun _date(): JsonField = date + + /** + * Returns the raw JSON value of [description]. + * + * Unlike [description], this method doesn't throw if the JSON field has an * unexpected type. */ - @JsonProperty("close_units") + @JsonProperty("description") @ExcludeMissing - fun _closeUnits(): JsonField = closeUnits + fun _description(): JsonField = description /** - * Returns the raw JSON value of [openUnits]. + * Returns the raw JSON value of [dividendRate]. * - * Unlike [openUnits], this method doesn't throw if the JSON field has an unexpected - * type. + * Unlike [dividendRate], this method doesn't throw if the JSON field has an + * unexpected type. */ - @JsonProperty("open_units") + @JsonProperty("dividend_rate") @ExcludeMissing - fun _openUnits(): JsonField = openUnits + fun _dividendRate(): JsonField = dividendRate /** - * Returns the raw JSON value of [rtaCode]. + * Returns the raw JSON value of [nav]. * - * Unlike [rtaCode], this method doesn't throw if the JSON field has an unexpected + * Unlike [nav], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("nav") @ExcludeMissing fun _nav(): JsonField = nav + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected * type. */ - @JsonProperty("rta_code") - @ExcludeMissing - fun _rtaCode(): JsonField = rtaCode + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + + /** + * Returns the raw JSON value of [units]. + * + * Unlike [units], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("units") @ExcludeMissing fun _units(): JsonField = units @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { @@ -6472,95 +14752,191 @@ private constructor( companion object { - /** - * Returns a mutable builder for constructing an instance of [AdditionalInfo]. - */ + /** Returns a mutable builder for constructing an instance of [Transaction]. */ @JvmStatic fun builder() = Builder() } - /** A builder for [AdditionalInfo]. */ + /** A builder for [Transaction]. */ class Builder internal constructor() { - private var advisor: JsonField = JsonMissing.of() - private var amfi: JsonField = JsonMissing.of() - private var closeUnits: JsonField = JsonMissing.of() - private var openUnits: JsonField = JsonMissing.of() - private var rtaCode: JsonField = JsonMissing.of() + private var additionalInfo: JsonField = JsonMissing.of() + private var amount: JsonField = JsonMissing.of() + private var balance: JsonField = JsonMissing.of() + private var date: JsonField = JsonMissing.of() + private var description: JsonField = JsonMissing.of() + private var dividendRate: JsonField = JsonMissing.of() + private var nav: JsonField = JsonMissing.of() + private var type: JsonField = JsonMissing.of() + private var units: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(additionalInfo: AdditionalInfo) = apply { - advisor = additionalInfo.advisor - amfi = additionalInfo.amfi - closeUnits = additionalInfo.closeUnits - openUnits = additionalInfo.openUnits - rtaCode = additionalInfo.rtaCode - additionalProperties = additionalInfo.additionalProperties.toMutableMap() + internal fun from(transaction: Transaction) = apply { + additionalInfo = transaction.additionalInfo + amount = transaction.amount + balance = transaction.balance + date = transaction.date + description = transaction.description + dividendRate = transaction.dividendRate + nav = transaction.nav + type = transaction.type + units = transaction.units + additionalProperties = transaction.additionalProperties.toMutableMap() + } + + /** Additional transaction-specific fields that vary by source */ + fun additionalInfo(additionalInfo: AdditionalInfo) = + additionalInfo(JsonField.of(additionalInfo)) + + /** + * Sets [Builder.additionalInfo] to an arbitrary JSON value. + * + * You should usually call [Builder.additionalInfo] with a well-typed + * [AdditionalInfo] value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun additionalInfo(additionalInfo: JsonField) = apply { + this.additionalInfo = additionalInfo + } + + /** Transaction amount in currency (computed from units × price/NAV) */ + fun amount(amount: Float?) = amount(JsonField.ofNullable(amount)) + + /** + * Alias for [Builder.amount]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun amount(amount: Float) = amount(amount as Float?) + + /** Alias for calling [Builder.amount] with `amount.orElse(null)`. */ + fun amount(amount: Optional) = amount(amount.getOrNull()) + + /** + * Sets [Builder.amount] to an arbitrary JSON value. + * + * You should usually call [Builder.amount] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun amount(amount: JsonField) = apply { this.amount = amount } + + /** Balance units after transaction */ + fun balance(balance: Float) = balance(JsonField.of(balance)) + + /** + * Sets [Builder.balance] to an arbitrary JSON value. + * + * You should usually call [Builder.balance] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun balance(balance: JsonField) = apply { this.balance = balance } + + /** Transaction date (YYYY-MM-DD) */ + fun date(date: LocalDate) = date(JsonField.of(date)) + + /** + * Sets [Builder.date] to an arbitrary JSON value. + * + * You should usually call [Builder.date] with a well-typed [LocalDate] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun date(date: JsonField) = apply { this.date = date } + + /** Transaction description/particulars */ + fun description(description: String) = description(JsonField.of(description)) + + /** + * Sets [Builder.description] to an arbitrary JSON value. + * + * You should usually call [Builder.description] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun description(description: JsonField) = apply { + this.description = description } - /** Financial advisor name (CAMS/KFintech) */ - fun advisor(advisor: String) = advisor(JsonField.of(advisor)) + /** Dividend rate (for DIVIDEND_PAYOUT transactions) */ + fun dividendRate(dividendRate: Float?) = + dividendRate(JsonField.ofNullable(dividendRate)) /** - * Sets [Builder.advisor] to an arbitrary JSON value. + * Alias for [Builder.dividendRate]. * - * You should usually call [Builder.advisor] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. + * This unboxed primitive overload exists for backwards compatibility. */ - fun advisor(advisor: JsonField) = apply { this.advisor = advisor } + fun dividendRate(dividendRate: Float) = dividendRate(dividendRate as Float?) - /** AMFI code for the scheme (CAMS/KFintech) */ - fun amfi(amfi: String) = amfi(JsonField.of(amfi)) + /** + * Alias for calling [Builder.dividendRate] with `dividendRate.orElse(null)`. + */ + fun dividendRate(dividendRate: Optional) = + dividendRate(dividendRate.getOrNull()) /** - * Sets [Builder.amfi] to an arbitrary JSON value. + * Sets [Builder.dividendRate] to an arbitrary JSON value. * - * You should usually call [Builder.amfi] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. + * You should usually call [Builder.dividendRate] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. */ - fun amfi(amfi: JsonField) = apply { this.amfi = amfi } + fun dividendRate(dividendRate: JsonField) = apply { + this.dividendRate = dividendRate + } - /** Closing balance units (CAMS/KFintech) */ - fun closeUnits(closeUnits: Float) = closeUnits(JsonField.of(closeUnits)) + /** NAV/price per unit on transaction date */ + fun nav(nav: Float?) = nav(JsonField.ofNullable(nav)) /** - * Sets [Builder.closeUnits] to an arbitrary JSON value. + * Alias for [Builder.nav]. * - * You should usually call [Builder.closeUnits] with a well-typed [Float] value + * This unboxed primitive overload exists for backwards compatibility. + */ + fun nav(nav: Float) = nav(nav as Float?) + + /** Alias for calling [Builder.nav] with `nav.orElse(null)`. */ + fun nav(nav: Optional) = nav(nav.getOrNull()) + + /** + * Sets [Builder.nav] to an arbitrary JSON value. + * + * You should usually call [Builder.nav] with a well-typed [Float] value * instead. This method is primarily for setting the field to an undocumented or * not yet supported value. */ - fun closeUnits(closeUnits: JsonField) = apply { - this.closeUnits = closeUnits - } + fun nav(nav: JsonField) = apply { this.nav = nav } - /** Opening balance units (CAMS/KFintech) */ - fun openUnits(openUnits: Float) = openUnits(JsonField.of(openUnits)) + /** + * Transaction type. Possible values are PURCHASE, PURCHASE_SIP, REDEMPTION, + * SWITCH_IN, SWITCH_IN_MERGER, SWITCH_OUT, SWITCH_OUT_MERGER, DIVIDEND_PAYOUT, + * DIVIDEND_REINVEST, SEGREGATION, STAMP_DUTY_TAX, TDS_TAX, STT_TAX, MISC, + * REVERSAL, UNKNOWN. + */ + fun type(type: Type) = type(JsonField.of(type)) /** - * Sets [Builder.openUnits] to an arbitrary JSON value. + * Sets [Builder.type] to an arbitrary JSON value. * - * You should usually call [Builder.openUnits] with a well-typed [Float] value + * You should usually call [Builder.type] with a well-typed [Type] value * instead. This method is primarily for setting the field to an undocumented or * not yet supported value. */ - fun openUnits(openUnits: JsonField) = apply { - this.openUnits = openUnits - } + fun type(type: JsonField) = apply { this.type = type } - /** RTA code for the scheme (CAMS/KFintech) */ - fun rtaCode(rtaCode: String) = rtaCode(JsonField.of(rtaCode)) + /** Number of units involved in transaction */ + fun units(units: Float) = units(JsonField.of(units)) /** - * Sets [Builder.rtaCode] to an arbitrary JSON value. + * Sets [Builder.units] to an arbitrary JSON value. * - * You should usually call [Builder.rtaCode] with a well-typed [String] value + * You should usually call [Builder.units] with a well-typed [Float] value * instead. This method is primarily for setting the field to an undocumented or * not yet supported value. */ - fun rtaCode(rtaCode: JsonField) = apply { this.rtaCode = rtaCode } + fun units(units: JsonField) = apply { this.units = units } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() @@ -6585,33 +14961,41 @@ private constructor( } /** - * Returns an immutable instance of [AdditionalInfo]. + * Returns an immutable instance of [Transaction]. * * Further updates to this [Builder] will not mutate the returned instance. */ - fun build(): AdditionalInfo = - AdditionalInfo( - advisor, - amfi, - closeUnits, - openUnits, - rtaCode, + fun build(): Transaction = + Transaction( + additionalInfo, + amount, + balance, + date, + description, + dividendRate, + nav, + type, + units, additionalProperties.toMutableMap(), ) } private var validated: Boolean = false - fun validate(): AdditionalInfo = apply { + fun validate(): Transaction = apply { if (validated) { return@apply } - advisor() - amfi() - closeUnits() - openUnits() - rtaCode() + additionalInfo().ifPresent { it.validate() } + amount() + balance() + date() + description() + dividendRate() + nav() + type().ifPresent { it.validate() } + units() validated = true } @@ -6631,654 +15015,663 @@ private constructor( */ @JvmSynthetic internal fun validity(): Int = - (if (advisor.asKnown().isPresent) 1 else 0) + - (if (amfi.asKnown().isPresent) 1 else 0) + - (if (closeUnits.asKnown().isPresent) 1 else 0) + - (if (openUnits.asKnown().isPresent) 1 else 0) + - (if (rtaCode.asKnown().isPresent) 1 else 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is AdditionalInfo && - advisor == other.advisor && - amfi == other.amfi && - closeUnits == other.closeUnits && - openUnits == other.openUnits && - rtaCode == other.rtaCode && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash( - advisor, - amfi, - closeUnits, - openUnits, - rtaCode, - additionalProperties, - ) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "AdditionalInfo{advisor=$advisor, amfi=$amfi, closeUnits=$closeUnits, openUnits=$openUnits, rtaCode=$rtaCode, additionalProperties=$additionalProperties}" - } - - class Gain - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val absolute: JsonField, - private val percentage: JsonField, - private val additionalProperties: MutableMap, - ) { + (additionalInfo.asKnown().getOrNull()?.validity() ?: 0) + + (if (amount.asKnown().isPresent) 1 else 0) + + (if (balance.asKnown().isPresent) 1 else 0) + + (if (date.asKnown().isPresent) 1 else 0) + + (if (description.asKnown().isPresent) 1 else 0) + + (if (dividendRate.asKnown().isPresent) 1 else 0) + + (if (nav.asKnown().isPresent) 1 else 0) + + (type.asKnown().getOrNull()?.validity() ?: 0) + + (if (units.asKnown().isPresent) 1 else 0) - @JsonCreator + /** Additional transaction-specific fields that vary by source */ + class AdditionalInfo + @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( - @JsonProperty("absolute") - @ExcludeMissing - absolute: JsonField = JsonMissing.of(), - @JsonProperty("percentage") - @ExcludeMissing - percentage: JsonField = JsonMissing.of(), - ) : this(absolute, percentage, mutableMapOf()) - - /** - * Absolute gain or loss - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun absolute(): Optional = absolute.getOptional("absolute") - - /** - * Percentage gain or loss - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun percentage(): Optional = percentage.getOptional("percentage") + private val capitalWithdrawal: JsonField, + private val credit: JsonField, + private val debit: JsonField, + private val incomeDistribution: JsonField, + private val orderNo: JsonField, + private val price: JsonField, + private val stampDuty: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("capital_withdrawal") + @ExcludeMissing + capitalWithdrawal: JsonField = JsonMissing.of(), + @JsonProperty("credit") + @ExcludeMissing + credit: JsonField = JsonMissing.of(), + @JsonProperty("debit") + @ExcludeMissing + debit: JsonField = JsonMissing.of(), + @JsonProperty("income_distribution") + @ExcludeMissing + incomeDistribution: JsonField = JsonMissing.of(), + @JsonProperty("order_no") + @ExcludeMissing + orderNo: JsonField = JsonMissing.of(), + @JsonProperty("price") + @ExcludeMissing + price: JsonField = JsonMissing.of(), + @JsonProperty("stamp_duty") + @ExcludeMissing + stampDuty: JsonField = JsonMissing.of(), + ) : this( + capitalWithdrawal, + credit, + debit, + incomeDistribution, + orderNo, + price, + stampDuty, + mutableMapOf(), + ) - /** - * Returns the raw JSON value of [absolute]. - * - * Unlike [absolute], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("absolute") - @ExcludeMissing - fun _absolute(): JsonField = absolute + /** + * Capital withdrawal amount (CDSL MF transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun capitalWithdrawal(): Optional = + capitalWithdrawal.getOptional("capital_withdrawal") - /** - * Returns the raw JSON value of [percentage]. - * - * Unlike [percentage], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("percentage") - @ExcludeMissing - fun _percentage(): JsonField = percentage + /** + * Units credited (demat transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun credit(): Optional = credit.getOptional("credit") - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } + /** + * Units debited (demat transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun debit(): Optional = debit.getOptional("debit") - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) + /** + * Income distribution amount (CDSL MF transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun incomeDistribution(): Optional = + incomeDistribution.getOptional("income_distribution") - fun toBuilder() = Builder().from(this) + /** + * Order/transaction reference number (demat transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun orderNo(): Optional = orderNo.getOptional("order_no") - companion object { + /** + * Price per unit (NSDL/CDSL MF transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun price(): Optional = price.getOptional("price") - /** Returns a mutable builder for constructing an instance of [Gain]. */ - @JvmStatic fun builder() = Builder() - } + /** + * Stamp duty charged + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun stampDuty(): Optional = stampDuty.getOptional("stamp_duty") - /** A builder for [Gain]. */ - class Builder internal constructor() { + /** + * Returns the raw JSON value of [capitalWithdrawal]. + * + * Unlike [capitalWithdrawal], this method doesn't throw if the JSON field has + * an unexpected type. + */ + @JsonProperty("capital_withdrawal") + @ExcludeMissing + fun _capitalWithdrawal(): JsonField = capitalWithdrawal - private var absolute: JsonField = JsonMissing.of() - private var percentage: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() + /** + * Returns the raw JSON value of [credit]. + * + * Unlike [credit], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("credit") @ExcludeMissing fun _credit(): JsonField = credit - @JvmSynthetic - internal fun from(gain: Gain) = apply { - absolute = gain.absolute - percentage = gain.percentage - additionalProperties = gain.additionalProperties.toMutableMap() - } + /** + * Returns the raw JSON value of [debit]. + * + * Unlike [debit], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("debit") @ExcludeMissing fun _debit(): JsonField = debit - /** Absolute gain or loss */ - fun absolute(absolute: Float) = absolute(JsonField.of(absolute)) + /** + * Returns the raw JSON value of [incomeDistribution]. + * + * Unlike [incomeDistribution], this method doesn't throw if the JSON field has + * an unexpected type. + */ + @JsonProperty("income_distribution") + @ExcludeMissing + fun _incomeDistribution(): JsonField = incomeDistribution /** - * Sets [Builder.absolute] to an arbitrary JSON value. + * Returns the raw JSON value of [orderNo]. * - * You should usually call [Builder.absolute] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. + * Unlike [orderNo], this method doesn't throw if the JSON field has an + * unexpected type. */ - fun absolute(absolute: JsonField) = apply { this.absolute = absolute } + @JsonProperty("order_no") + @ExcludeMissing + fun _orderNo(): JsonField = orderNo - /** Percentage gain or loss */ - fun percentage(percentage: Float) = percentage(JsonField.of(percentage)) + /** + * Returns the raw JSON value of [price]. + * + * Unlike [price], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("price") @ExcludeMissing fun _price(): JsonField = price /** - * Sets [Builder.percentage] to an arbitrary JSON value. + * Returns the raw JSON value of [stampDuty]. * - * You should usually call [Builder.percentage] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. + * Unlike [stampDuty], this method doesn't throw if the JSON field has an + * unexpected type. */ - fun percentage(percentage: JsonField) = apply { - this.percentage = percentage - } + @JsonProperty("stamp_duty") + @ExcludeMissing + fun _stampDuty(): JsonField = stampDuty - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) } - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - 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 + * [AdditionalInfo]. + */ + @JvmStatic fun builder() = Builder() } - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) + /** A builder for [AdditionalInfo]. */ + class Builder internal constructor() { + + private var capitalWithdrawal: JsonField = JsonMissing.of() + private var credit: JsonField = JsonMissing.of() + private var debit: JsonField = JsonMissing.of() + private var incomeDistribution: JsonField = JsonMissing.of() + private var orderNo: JsonField = JsonMissing.of() + private var price: JsonField = JsonMissing.of() + private var stampDuty: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = + mutableMapOf() + + @JvmSynthetic + internal fun from(additionalInfo: AdditionalInfo) = apply { + capitalWithdrawal = additionalInfo.capitalWithdrawal + credit = additionalInfo.credit + debit = additionalInfo.debit + incomeDistribution = additionalInfo.incomeDistribution + orderNo = additionalInfo.orderNo + price = additionalInfo.price + stampDuty = additionalInfo.stampDuty + additionalProperties = + additionalInfo.additionalProperties.toMutableMap() } - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) - } + /** Capital withdrawal amount (CDSL MF transactions) */ + fun capitalWithdrawal(capitalWithdrawal: Float) = + capitalWithdrawal(JsonField.of(capitalWithdrawal)) - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } + /** + * Sets [Builder.capitalWithdrawal] to an arbitrary JSON value. + * + * You should usually call [Builder.capitalWithdrawal] with a well-typed + * [Float] value instead. This method is primarily for setting the field to + * an undocumented or not yet supported value. + */ + fun capitalWithdrawal(capitalWithdrawal: JsonField) = apply { + this.capitalWithdrawal = capitalWithdrawal + } - /** - * Returns an immutable instance of [Gain]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): Gain = - Gain(absolute, percentage, additionalProperties.toMutableMap()) - } + /** Units credited (demat transactions) */ + fun credit(credit: Float) = credit(JsonField.of(credit)) - private var validated: Boolean = false + /** + * Sets [Builder.credit] to an arbitrary JSON value. + * + * You should usually call [Builder.credit] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun credit(credit: JsonField) = apply { this.credit = credit } - fun validate(): Gain = apply { - if (validated) { - return@apply - } + /** Units debited (demat transactions) */ + fun debit(debit: Float) = debit(JsonField.of(debit)) - absolute() - percentage() - validated = true - } + /** + * Sets [Builder.debit] to an arbitrary JSON value. + * + * You should usually call [Builder.debit] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun debit(debit: JsonField) = apply { this.debit = debit } - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - false - } + /** Income distribution amount (CDSL MF transactions) */ + fun incomeDistribution(incomeDistribution: Float) = + incomeDistribution(JsonField.of(incomeDistribution)) - /** - * 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 (absolute.asKnown().isPresent) 1 else 0) + - (if (percentage.asKnown().isPresent) 1 else 0) + /** + * Sets [Builder.incomeDistribution] to an arbitrary JSON value. + * + * You should usually call [Builder.incomeDistribution] with a well-typed + * [Float] value instead. This method is primarily for setting the field to + * an undocumented or not yet supported value. + */ + fun incomeDistribution(incomeDistribution: JsonField) = apply { + this.incomeDistribution = incomeDistribution + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + /** Order/transaction reference number (demat transactions) */ + fun orderNo(orderNo: String) = orderNo(JsonField.of(orderNo)) - return other is Gain && - absolute == other.absolute && - percentage == other.percentage && - additionalProperties == other.additionalProperties - } + /** + * Sets [Builder.orderNo] to an arbitrary JSON value. + * + * You should usually call [Builder.orderNo] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun orderNo(orderNo: JsonField) = apply { this.orderNo = orderNo } - private val hashCode: Int by lazy { - Objects.hash(absolute, percentage, additionalProperties) - } + /** Price per unit (NSDL/CDSL MF transactions) */ + fun price(price: Float) = price(JsonField.of(price)) - override fun hashCode(): Int = hashCode + /** + * Sets [Builder.price] to an arbitrary JSON value. + * + * You should usually call [Builder.price] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun price(price: JsonField) = apply { this.price = price } - override fun toString() = - "Gain{absolute=$absolute, percentage=$percentage, additionalProperties=$additionalProperties}" - } + /** Stamp duty charged */ + fun stampDuty(stampDuty: Float) = stampDuty(JsonField.of(stampDuty)) - class Transaction - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val amount: JsonField, - private val balance: JsonField, - private val date: JsonField, - private val description: JsonField, - private val dividendRate: JsonField, - private val nav: JsonField, - private val type: JsonField, - private val units: JsonField, - private val additionalProperties: MutableMap, - ) { + /** + * Sets [Builder.stampDuty] to an arbitrary JSON value. + * + * You should usually call [Builder.stampDuty] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun stampDuty(stampDuty: JsonField) = apply { + this.stampDuty = stampDuty + } - @JsonCreator - private constructor( - @JsonProperty("amount") - @ExcludeMissing - amount: JsonField = JsonMissing.of(), - @JsonProperty("balance") - @ExcludeMissing - balance: JsonField = JsonMissing.of(), - @JsonProperty("date") - @ExcludeMissing - date: JsonField = JsonMissing.of(), - @JsonProperty("description") - @ExcludeMissing - description: JsonField = JsonMissing.of(), - @JsonProperty("dividend_rate") - @ExcludeMissing - dividendRate: JsonField = JsonMissing.of(), - @JsonProperty("nav") @ExcludeMissing nav: JsonField = JsonMissing.of(), - @JsonProperty("type") - @ExcludeMissing - type: JsonField = JsonMissing.of(), - @JsonProperty("units") - @ExcludeMissing - units: JsonField = JsonMissing.of(), - ) : this( - amount, - balance, - date, - description, - dividendRate, - nav, - type, - units, - mutableMapOf(), - ) + fun additionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } - /** - * Transaction amount - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun amount(): Optional = amount.getOptional("amount") + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } - /** - * Balance units after transaction - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun balance(): Optional = balance.getOptional("balance") + fun putAllAdditionalProperties( + additionalProperties: Map + ) = apply { this.additionalProperties.putAll(additionalProperties) } - /** - * Transaction date - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun date(): Optional = date.getOptional("date") + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } - /** - * Transaction description - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun description(): Optional = description.getOptional("description") + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } - /** - * Dividend rate (for dividend transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun dividendRate(): Optional = dividendRate.getOptional("dividend_rate") + /** + * Returns an immutable instance of [AdditionalInfo]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): AdditionalInfo = + AdditionalInfo( + capitalWithdrawal, + credit, + debit, + incomeDistribution, + orderNo, + price, + stampDuty, + additionalProperties.toMutableMap(), + ) + } - /** - * NAV on transaction date - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun nav(): Optional = nav.getOptional("nav") + private var validated: Boolean = false - /** - * Transaction type detected based on description. Possible values are - * PURCHASE,PURCHASE_SIP,REDEMPTION,SWITCH_IN,SWITCH_IN_MERGER,SWITCH_OUT,SWITCH_OUT_MERGER,DIVIDEND_PAYOUT,DIVIDEND_REINVESTMENT,SEGREGATION,STAMP_DUTY_TAX,TDS_TAX,STT_TAX,MISC. - * If dividend_rate is present, then possible values are dividend_rate is applicable - * only for DIVIDEND_PAYOUT and DIVIDEND_REINVESTMENT. - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun type(): Optional = type.getOptional("type") + fun validate(): AdditionalInfo = apply { + if (validated) { + return@apply + } - /** - * Number of units involved - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun units(): Optional = units.getOptional("units") + capitalWithdrawal() + credit() + debit() + incomeDistribution() + orderNo() + price() + stampDuty() + validated = true + } - /** - * Returns the raw JSON value of [amount]. - * - * Unlike [amount], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("amount") @ExcludeMissing fun _amount(): JsonField = amount + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + false + } - /** - * Returns the raw JSON value of [balance]. - * - * Unlike [balance], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("balance") @ExcludeMissing fun _balance(): JsonField = balance + /** + * 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 (capitalWithdrawal.asKnown().isPresent) 1 else 0) + + (if (credit.asKnown().isPresent) 1 else 0) + + (if (debit.asKnown().isPresent) 1 else 0) + + (if (incomeDistribution.asKnown().isPresent) 1 else 0) + + (if (orderNo.asKnown().isPresent) 1 else 0) + + (if (price.asKnown().isPresent) 1 else 0) + + (if (stampDuty.asKnown().isPresent) 1 else 0) - /** - * Returns the raw JSON value of [date]. - * - * Unlike [date], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("date") @ExcludeMissing fun _date(): JsonField = date + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - /** - * Returns the raw JSON value of [description]. - * - * Unlike [description], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("description") - @ExcludeMissing - fun _description(): JsonField = description + return other is AdditionalInfo && + capitalWithdrawal == other.capitalWithdrawal && + credit == other.credit && + debit == other.debit && + incomeDistribution == other.incomeDistribution && + orderNo == other.orderNo && + price == other.price && + stampDuty == other.stampDuty && + additionalProperties == other.additionalProperties + } - /** - * Returns the raw JSON value of [dividendRate]. - * - * Unlike [dividendRate], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("dividend_rate") - @ExcludeMissing - fun _dividendRate(): JsonField = dividendRate + private val hashCode: Int by lazy { + Objects.hash( + capitalWithdrawal, + credit, + debit, + incomeDistribution, + orderNo, + price, + stampDuty, + additionalProperties, + ) + } - /** - * Returns the raw JSON value of [nav]. - * - * Unlike [nav], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("nav") @ExcludeMissing fun _nav(): JsonField = nav + override fun hashCode(): Int = hashCode - /** - * Returns the raw JSON value of [type]. - * - * Unlike [type], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + override fun toString() = + "AdditionalInfo{capitalWithdrawal=$capitalWithdrawal, credit=$credit, debit=$debit, incomeDistribution=$incomeDistribution, orderNo=$orderNo, price=$price, stampDuty=$stampDuty, additionalProperties=$additionalProperties}" + } /** - * Returns the raw JSON value of [units]. - * - * Unlike [units], this method doesn't throw if the JSON field has an unexpected - * type. + * Transaction type. Possible values are PURCHASE, PURCHASE_SIP, REDEMPTION, + * SWITCH_IN, SWITCH_IN_MERGER, SWITCH_OUT, SWITCH_OUT_MERGER, DIVIDEND_PAYOUT, + * DIVIDEND_REINVEST, SEGREGATION, STAMP_DUTY_TAX, TDS_TAX, STT_TAX, MISC, REVERSAL, + * UNKNOWN. */ - @JsonProperty("units") @ExcludeMissing fun _units(): JsonField = units + class Type @JsonCreator private constructor(private val value: JsonField) : + Enum { - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that + * doesn't match any known member, and you want to know that value. For example, + * if the SDK is on an older version than the API, then the API may respond with + * new members that the SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue + fun _value(): JsonField = value - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) + companion object { - fun toBuilder() = Builder().from(this) + @JvmField val PURCHASE = of("PURCHASE") - companion object { + @JvmField val PURCHASE_SIP = of("PURCHASE_SIP") - /** Returns a mutable builder for constructing an instance of [Transaction]. */ - @JvmStatic fun builder() = Builder() - } + @JvmField val REDEMPTION = of("REDEMPTION") - /** A builder for [Transaction]. */ - class Builder internal constructor() { + @JvmField val SWITCH_IN = of("SWITCH_IN") - private var amount: JsonField = JsonMissing.of() - private var balance: JsonField = JsonMissing.of() - private var date: JsonField = JsonMissing.of() - private var description: JsonField = JsonMissing.of() - private var dividendRate: JsonField = JsonMissing.of() - private var nav: JsonField = JsonMissing.of() - private var type: JsonField = JsonMissing.of() - private var units: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() + @JvmField val SWITCH_IN_MERGER = of("SWITCH_IN_MERGER") - @JvmSynthetic - internal fun from(transaction: Transaction) = apply { - amount = transaction.amount - balance = transaction.balance - date = transaction.date - description = transaction.description - dividendRate = transaction.dividendRate - nav = transaction.nav - type = transaction.type - units = transaction.units - additionalProperties = transaction.additionalProperties.toMutableMap() - } + @JvmField val SWITCH_OUT = of("SWITCH_OUT") - /** Transaction amount */ - fun amount(amount: Float) = amount(JsonField.of(amount)) + @JvmField val SWITCH_OUT_MERGER = of("SWITCH_OUT_MERGER") - /** - * Sets [Builder.amount] to an arbitrary JSON value. - * - * You should usually call [Builder.amount] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun amount(amount: JsonField) = apply { this.amount = amount } + @JvmField val DIVIDEND_PAYOUT = of("DIVIDEND_PAYOUT") - /** Balance units after transaction */ - fun balance(balance: Float) = balance(JsonField.of(balance)) + @JvmField val DIVIDEND_REINVEST = of("DIVIDEND_REINVEST") - /** - * Sets [Builder.balance] to an arbitrary JSON value. - * - * You should usually call [Builder.balance] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun balance(balance: JsonField) = apply { this.balance = balance } + @JvmField val SEGREGATION = of("SEGREGATION") - /** Transaction date */ - fun date(date: LocalDate) = date(JsonField.of(date)) + @JvmField val STAMP_DUTY_TAX = of("STAMP_DUTY_TAX") - /** - * Sets [Builder.date] to an arbitrary JSON value. - * - * You should usually call [Builder.date] with a well-typed [LocalDate] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun date(date: JsonField) = apply { this.date = date } + @JvmField val TDS_TAX = of("TDS_TAX") - /** Transaction description */ - fun description(description: String) = description(JsonField.of(description)) + @JvmField val STT_TAX = of("STT_TAX") - /** - * Sets [Builder.description] to an arbitrary JSON value. - * - * You should usually call [Builder.description] with a well-typed [String] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun description(description: JsonField) = apply { - this.description = description - } + @JvmField val MISC = of("MISC") - /** Dividend rate (for dividend transactions) */ - fun dividendRate(dividendRate: Float) = dividendRate(JsonField.of(dividendRate)) + @JvmField val REVERSAL = of("REVERSAL") - /** - * Sets [Builder.dividendRate] to an arbitrary JSON value. - * - * You should usually call [Builder.dividendRate] with a well-typed [Float] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun dividendRate(dividendRate: JsonField) = apply { - this.dividendRate = dividendRate + @JvmField val UNKNOWN = of("UNKNOWN") + + @JvmStatic fun of(value: String) = Type(JsonField.of(value)) } - /** NAV on transaction date */ - fun nav(nav: Float) = nav(JsonField.of(nav)) + /** An enum containing [Type]'s known values. */ + enum class Known { + PURCHASE, + PURCHASE_SIP, + REDEMPTION, + SWITCH_IN, + SWITCH_IN_MERGER, + SWITCH_OUT, + SWITCH_OUT_MERGER, + DIVIDEND_PAYOUT, + DIVIDEND_REINVEST, + SEGREGATION, + STAMP_DUTY_TAX, + TDS_TAX, + STT_TAX, + MISC, + REVERSAL, + UNKNOWN, + } /** - * Sets [Builder.nav] to an arbitrary JSON value. + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. * - * You should usually call [Builder.nav] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. + * An instance of [Type] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For + * example, if the SDK is on an older version than the API, then the API may + * respond with new members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. */ - fun nav(nav: JsonField) = apply { this.nav = nav } + enum class Value { + PURCHASE, + PURCHASE_SIP, + REDEMPTION, + SWITCH_IN, + SWITCH_IN_MERGER, + SWITCH_OUT, + SWITCH_OUT_MERGER, + DIVIDEND_PAYOUT, + DIVIDEND_REINVEST, + SEGREGATION, + STAMP_DUTY_TAX, + TDS_TAX, + STT_TAX, + MISC, + REVERSAL, + UNKNOWN, + /** + * An enum member indicating that [Type] was instantiated with an unknown + * value. + */ + _UNKNOWN, + } /** - * Transaction type detected based on description. Possible values are - * PURCHASE,PURCHASE_SIP,REDEMPTION,SWITCH_IN,SWITCH_IN_MERGER,SWITCH_OUT,SWITCH_OUT_MERGER,DIVIDEND_PAYOUT,DIVIDEND_REINVESTMENT,SEGREGATION,STAMP_DUTY_TAX,TDS_TAX,STT_TAX,MISC. - * If dividend_rate is present, then possible values are dividend_rate is - * applicable only for DIVIDEND_PAYOUT and DIVIDEND_REINVESTMENT. + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or + * if you want to throw for the unknown case. */ - fun type(type: String) = type(JsonField.of(type)) + fun value(): Value = + when (this) { + PURCHASE -> Value.PURCHASE + PURCHASE_SIP -> Value.PURCHASE_SIP + REDEMPTION -> Value.REDEMPTION + SWITCH_IN -> Value.SWITCH_IN + SWITCH_IN_MERGER -> Value.SWITCH_IN_MERGER + SWITCH_OUT -> Value.SWITCH_OUT + SWITCH_OUT_MERGER -> Value.SWITCH_OUT_MERGER + DIVIDEND_PAYOUT -> Value.DIVIDEND_PAYOUT + DIVIDEND_REINVEST -> Value.DIVIDEND_REINVEST + SEGREGATION -> Value.SEGREGATION + STAMP_DUTY_TAX -> Value.STAMP_DUTY_TAX + TDS_TAX -> Value.TDS_TAX + STT_TAX -> Value.STT_TAX + MISC -> Value.MISC + REVERSAL -> Value.REVERSAL + UNKNOWN -> Value.UNKNOWN + else -> Value._UNKNOWN + } /** - * Sets [Builder.type] to an arbitrary JSON value. + * Returns an enum member corresponding to this class instance's value. * - * You should usually call [Builder.type] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. + * Use the [value] method instead if you're uncertain the value is always known + * and don't want to throw for the unknown case. + * + * @throws CasParserInvalidDataException if this class instance's value is a not + * a known member. */ - fun type(type: JsonField) = apply { this.type = type } - - /** Number of units involved */ - fun units(units: Float) = units(JsonField.of(units)) + fun known(): Known = + when (this) { + PURCHASE -> Known.PURCHASE + PURCHASE_SIP -> Known.PURCHASE_SIP + REDEMPTION -> Known.REDEMPTION + SWITCH_IN -> Known.SWITCH_IN + SWITCH_IN_MERGER -> Known.SWITCH_IN_MERGER + SWITCH_OUT -> Known.SWITCH_OUT + SWITCH_OUT_MERGER -> Known.SWITCH_OUT_MERGER + DIVIDEND_PAYOUT -> Known.DIVIDEND_PAYOUT + DIVIDEND_REINVEST -> Known.DIVIDEND_REINVEST + SEGREGATION -> Known.SEGREGATION + STAMP_DUTY_TAX -> Known.STAMP_DUTY_TAX + TDS_TAX -> Known.TDS_TAX + STT_TAX -> Known.STT_TAX + MISC -> Known.MISC + REVERSAL -> Known.REVERSAL + UNKNOWN -> Known.UNKNOWN + else -> throw CasParserInvalidDataException("Unknown Type: $value") + } /** - * Sets [Builder.units] to an arbitrary JSON value. + * Returns this class instance's primitive wire representation. * - * You should usually call [Builder.units] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws CasParserInvalidDataException if this class instance's value does not + * have the expected primitive type. */ - fun units(units: JsonField) = apply { this.units = units } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } + fun asString(): String = + _value().asString().orElseThrow { + CasParserInvalidDataException("Value is not a String") + } - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } + private var validated: Boolean = false - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) + fun validate(): Type = apply { + if (validated) { + return@apply } - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) + known() + validated = true } - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + false + } /** - * Returns an immutable instance of [Transaction]. + * Returns a score indicating how many valid values are contained in this object + * recursively. * - * Further updates to this [Builder] will not mutate the returned instance. + * Used for best match union deserialization. */ - fun build(): Transaction = - Transaction( - amount, - balance, - date, - description, - dividendRate, - nav, - type, - units, - additionalProperties.toMutableMap(), - ) - } + @JvmSynthetic + internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - private var validated: Boolean = false + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - fun validate(): Transaction = apply { - if (validated) { - return@apply + return other is Type && value == other.value } - amount() - balance() - date() - description() - dividendRate() - nav() - type() - units() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - false - } + override fun hashCode() = value.hashCode() - /** - * 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 (amount.asKnown().isPresent) 1 else 0) + - (if (balance.asKnown().isPresent) 1 else 0) + - (if (date.asKnown().isPresent) 1 else 0) + - (if (description.asKnown().isPresent) 1 else 0) + - (if (dividendRate.asKnown().isPresent) 1 else 0) + - (if (nav.asKnown().isPresent) 1 else 0) + - (if (type.asKnown().isPresent) 1 else 0) + - (if (units.asKnown().isPresent) 1 else 0) + override fun toString() = value.toString() + } override fun equals(other: Any?): Boolean { if (this === other) { @@ -7286,6 +15679,7 @@ private constructor( } return other is Transaction && + additionalInfo == other.additionalInfo && amount == other.amount && balance == other.balance && date == other.date && @@ -7299,6 +15693,7 @@ private constructor( private val hashCode: Int by lazy { Objects.hash( + additionalInfo, amount, balance, date, @@ -7314,7 +15709,7 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "Transaction{amount=$amount, balance=$balance, date=$date, description=$description, dividendRate=$dividendRate, nav=$nav, type=$type, units=$units, additionalProperties=$additionalProperties}" + "Transaction{additionalInfo=$additionalInfo, amount=$amount, balance=$balance, date=$date, description=$description, dividendRate=$dividendRate, nav=$nav, type=$type, units=$units, additionalProperties=$additionalProperties}" } /** Type of mutual fund scheme */ diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/UnifiedResponseTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/UnifiedResponseTest.kt index 86f7a31..f0fa2ca 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/UnifiedResponseTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/UnifiedResponseTest.kt @@ -40,36 +40,197 @@ internal class UnifiedResponseTest { UnifiedResponse.DematAccount.Holdings.builder() .addAif( UnifiedResponse.DematAccount.Holdings.Aif.builder() - .additionalInfo(JsonValue.from(mapOf())) + .additionalInfo( + UnifiedResponse.DematAccount.Holdings.Aif.AdditionalInfo + .builder() + .closeUnits(0.0f) + .openUnits(0.0f) + .build() + ) .isin("isin") .name("name") + .addTransaction( + UnifiedResponse.DematAccount.Holdings.Aif.Transaction + .builder() + .additionalInfo( + UnifiedResponse.DematAccount.Holdings.Aif + .Transaction + .AdditionalInfo + .builder() + .capitalWithdrawal(0.0f) + .credit(0.0f) + .debit(0.0f) + .incomeDistribution(0.0f) + .orderNo("order_no") + .price(0.0f) + .stampDuty(0.0f) + .build() + ) + .amount(0.0f) + .balance(0.0f) + .date(LocalDate.parse("2019-12-27")) + .description("description") + .dividendRate(0.0f) + .nav(0.0f) + .type( + UnifiedResponse.DematAccount.Holdings.Aif + .Transaction + .Type + .PURCHASE + ) + .units(0.0f) + .build() + ) .units(0.0f) .value(0.0f) .build() ) .addCorporateBond( UnifiedResponse.DematAccount.Holdings.CorporateBond.builder() - .additionalInfo(JsonValue.from(mapOf())) + .additionalInfo( + UnifiedResponse.DematAccount.Holdings.CorporateBond + .AdditionalInfo + .builder() + .closeUnits(0.0f) + .openUnits(0.0f) + .build() + ) .isin("isin") .name("name") + .addTransaction( + UnifiedResponse.DematAccount.Holdings.CorporateBond + .Transaction + .builder() + .additionalInfo( + UnifiedResponse.DematAccount.Holdings + .CorporateBond + .Transaction + .AdditionalInfo + .builder() + .capitalWithdrawal(0.0f) + .credit(0.0f) + .debit(0.0f) + .incomeDistribution(0.0f) + .orderNo("order_no") + .price(0.0f) + .stampDuty(0.0f) + .build() + ) + .amount(0.0f) + .balance(0.0f) + .date(LocalDate.parse("2019-12-27")) + .description("description") + .dividendRate(0.0f) + .nav(0.0f) + .type( + UnifiedResponse.DematAccount.Holdings + .CorporateBond + .Transaction + .Type + .PURCHASE + ) + .units(0.0f) + .build() + ) .units(0.0f) .value(0.0f) .build() ) .addDematMutualFund( UnifiedResponse.DematAccount.Holdings.DematMutualFund.builder() - .additionalInfo(JsonValue.from(mapOf())) + .additionalInfo( + UnifiedResponse.DematAccount.Holdings.DematMutualFund + .AdditionalInfo + .builder() + .closeUnits(0.0f) + .openUnits(0.0f) + .build() + ) .isin("isin") .name("name") + .addTransaction( + UnifiedResponse.DematAccount.Holdings.DematMutualFund + .Transaction + .builder() + .additionalInfo( + UnifiedResponse.DematAccount.Holdings + .DematMutualFund + .Transaction + .AdditionalInfo + .builder() + .capitalWithdrawal(0.0f) + .credit(0.0f) + .debit(0.0f) + .incomeDistribution(0.0f) + .orderNo("order_no") + .price(0.0f) + .stampDuty(0.0f) + .build() + ) + .amount(0.0f) + .balance(0.0f) + .date(LocalDate.parse("2019-12-27")) + .description("description") + .dividendRate(0.0f) + .nav(0.0f) + .type( + UnifiedResponse.DematAccount.Holdings + .DematMutualFund + .Transaction + .Type + .PURCHASE + ) + .units(0.0f) + .build() + ) .units(0.0f) .value(0.0f) .build() ) .addEquity( UnifiedResponse.DematAccount.Holdings.Equity.builder() - .additionalInfo(JsonValue.from(mapOf())) + .additionalInfo( + UnifiedResponse.DematAccount.Holdings.Equity + .AdditionalInfo + .builder() + .closeUnits(0.0f) + .openUnits(0.0f) + .build() + ) .isin("isin") .name("name") + .addTransaction( + UnifiedResponse.DematAccount.Holdings.Equity.Transaction + .builder() + .additionalInfo( + UnifiedResponse.DematAccount.Holdings.Equity + .Transaction + .AdditionalInfo + .builder() + .capitalWithdrawal(0.0f) + .credit(0.0f) + .debit(0.0f) + .incomeDistribution(0.0f) + .orderNo("order_no") + .price(0.0f) + .stampDuty(0.0f) + .build() + ) + .amount(0.0f) + .balance(0.0f) + .date(LocalDate.parse("2019-12-27")) + .description("description") + .dividendRate(0.0f) + .nav(0.0f) + .type( + UnifiedResponse.DematAccount.Holdings.Equity + .Transaction + .Type + .PURCHASE + ) + .units(0.0f) + .build() + ) .units(0.0f) .value(0.0f) .build() @@ -77,9 +238,51 @@ internal class UnifiedResponseTest { .addGovernmentSecurity( UnifiedResponse.DematAccount.Holdings.GovernmentSecurity .builder() - .additionalInfo(JsonValue.from(mapOf())) + .additionalInfo( + UnifiedResponse.DematAccount.Holdings.GovernmentSecurity + .AdditionalInfo + .builder() + .closeUnits(0.0f) + .openUnits(0.0f) + .build() + ) .isin("isin") .name("name") + .addTransaction( + UnifiedResponse.DematAccount.Holdings.GovernmentSecurity + .Transaction + .builder() + .additionalInfo( + UnifiedResponse.DematAccount.Holdings + .GovernmentSecurity + .Transaction + .AdditionalInfo + .builder() + .capitalWithdrawal(0.0f) + .credit(0.0f) + .debit(0.0f) + .incomeDistribution(0.0f) + .orderNo("order_no") + .price(0.0f) + .stampDuty(0.0f) + .build() + ) + .amount(0.0f) + .balance(0.0f) + .date(LocalDate.parse("2019-12-27")) + .description("description") + .dividendRate(0.0f) + .nav(0.0f) + .type( + UnifiedResponse.DematAccount.Holdings + .GovernmentSecurity + .Transaction + .Type + .PURCHASE + ) + .units(0.0f) + .build() + ) .units(0.0f) .value(0.0f) .build() @@ -177,13 +380,29 @@ internal class UnifiedResponseTest { .addNominee("string") .addTransaction( UnifiedResponse.MutualFund.Scheme.Transaction.builder() + .additionalInfo( + UnifiedResponse.MutualFund.Scheme.Transaction + .AdditionalInfo + .builder() + .capitalWithdrawal(0.0f) + .credit(0.0f) + .debit(0.0f) + .incomeDistribution(0.0f) + .orderNo("order_no") + .price(0.0f) + .stampDuty(0.0f) + .build() + ) .amount(0.0f) .balance(0.0f) .date(LocalDate.parse("2019-12-27")) .description("description") .dividendRate(0.0f) .nav(0.0f) - .type("type") + .type( + UnifiedResponse.MutualFund.Scheme.Transaction.Type + .PURCHASE + ) .units(0.0f) .build() ) @@ -283,45 +502,245 @@ internal class UnifiedResponseTest { UnifiedResponse.DematAccount.Holdings.builder() .addAif( UnifiedResponse.DematAccount.Holdings.Aif.builder() - .additionalInfo(JsonValue.from(mapOf())) + .additionalInfo( + UnifiedResponse.DematAccount.Holdings.Aif.AdditionalInfo + .builder() + .closeUnits(0.0f) + .openUnits(0.0f) + .build() + ) .isin("isin") .name("name") + .addTransaction( + UnifiedResponse.DematAccount.Holdings.Aif.Transaction + .builder() + .additionalInfo( + UnifiedResponse.DematAccount.Holdings.Aif + .Transaction + .AdditionalInfo + .builder() + .capitalWithdrawal(0.0f) + .credit(0.0f) + .debit(0.0f) + .incomeDistribution(0.0f) + .orderNo("order_no") + .price(0.0f) + .stampDuty(0.0f) + .build() + ) + .amount(0.0f) + .balance(0.0f) + .date(LocalDate.parse("2019-12-27")) + .description("description") + .dividendRate(0.0f) + .nav(0.0f) + .type( + UnifiedResponse.DematAccount.Holdings.Aif + .Transaction + .Type + .PURCHASE + ) + .units(0.0f) + .build() + ) .units(0.0f) .value(0.0f) .build() ) .addCorporateBond( UnifiedResponse.DematAccount.Holdings.CorporateBond.builder() - .additionalInfo(JsonValue.from(mapOf())) + .additionalInfo( + UnifiedResponse.DematAccount.Holdings.CorporateBond + .AdditionalInfo + .builder() + .closeUnits(0.0f) + .openUnits(0.0f) + .build() + ) .isin("isin") .name("name") + .addTransaction( + UnifiedResponse.DematAccount.Holdings.CorporateBond + .Transaction + .builder() + .additionalInfo( + UnifiedResponse.DematAccount.Holdings.CorporateBond + .Transaction + .AdditionalInfo + .builder() + .capitalWithdrawal(0.0f) + .credit(0.0f) + .debit(0.0f) + .incomeDistribution(0.0f) + .orderNo("order_no") + .price(0.0f) + .stampDuty(0.0f) + .build() + ) + .amount(0.0f) + .balance(0.0f) + .date(LocalDate.parse("2019-12-27")) + .description("description") + .dividendRate(0.0f) + .nav(0.0f) + .type( + UnifiedResponse.DematAccount.Holdings.CorporateBond + .Transaction + .Type + .PURCHASE + ) + .units(0.0f) + .build() + ) .units(0.0f) .value(0.0f) .build() ) .addDematMutualFund( UnifiedResponse.DematAccount.Holdings.DematMutualFund.builder() - .additionalInfo(JsonValue.from(mapOf())) + .additionalInfo( + UnifiedResponse.DematAccount.Holdings.DematMutualFund + .AdditionalInfo + .builder() + .closeUnits(0.0f) + .openUnits(0.0f) + .build() + ) .isin("isin") .name("name") + .addTransaction( + UnifiedResponse.DematAccount.Holdings.DematMutualFund + .Transaction + .builder() + .additionalInfo( + UnifiedResponse.DematAccount.Holdings + .DematMutualFund + .Transaction + .AdditionalInfo + .builder() + .capitalWithdrawal(0.0f) + .credit(0.0f) + .debit(0.0f) + .incomeDistribution(0.0f) + .orderNo("order_no") + .price(0.0f) + .stampDuty(0.0f) + .build() + ) + .amount(0.0f) + .balance(0.0f) + .date(LocalDate.parse("2019-12-27")) + .description("description") + .dividendRate(0.0f) + .nav(0.0f) + .type( + UnifiedResponse.DematAccount.Holdings + .DematMutualFund + .Transaction + .Type + .PURCHASE + ) + .units(0.0f) + .build() + ) .units(0.0f) .value(0.0f) .build() ) .addEquity( UnifiedResponse.DematAccount.Holdings.Equity.builder() - .additionalInfo(JsonValue.from(mapOf())) + .additionalInfo( + UnifiedResponse.DematAccount.Holdings.Equity.AdditionalInfo + .builder() + .closeUnits(0.0f) + .openUnits(0.0f) + .build() + ) .isin("isin") .name("name") + .addTransaction( + UnifiedResponse.DematAccount.Holdings.Equity.Transaction + .builder() + .additionalInfo( + UnifiedResponse.DematAccount.Holdings.Equity + .Transaction + .AdditionalInfo + .builder() + .capitalWithdrawal(0.0f) + .credit(0.0f) + .debit(0.0f) + .incomeDistribution(0.0f) + .orderNo("order_no") + .price(0.0f) + .stampDuty(0.0f) + .build() + ) + .amount(0.0f) + .balance(0.0f) + .date(LocalDate.parse("2019-12-27")) + .description("description") + .dividendRate(0.0f) + .nav(0.0f) + .type( + UnifiedResponse.DematAccount.Holdings.Equity + .Transaction + .Type + .PURCHASE + ) + .units(0.0f) + .build() + ) .units(0.0f) .value(0.0f) .build() ) .addGovernmentSecurity( UnifiedResponse.DematAccount.Holdings.GovernmentSecurity.builder() - .additionalInfo(JsonValue.from(mapOf())) + .additionalInfo( + UnifiedResponse.DematAccount.Holdings.GovernmentSecurity + .AdditionalInfo + .builder() + .closeUnits(0.0f) + .openUnits(0.0f) + .build() + ) .isin("isin") .name("name") + .addTransaction( + UnifiedResponse.DematAccount.Holdings.GovernmentSecurity + .Transaction + .builder() + .additionalInfo( + UnifiedResponse.DematAccount.Holdings + .GovernmentSecurity + .Transaction + .AdditionalInfo + .builder() + .capitalWithdrawal(0.0f) + .credit(0.0f) + .debit(0.0f) + .incomeDistribution(0.0f) + .orderNo("order_no") + .price(0.0f) + .stampDuty(0.0f) + .build() + ) + .amount(0.0f) + .balance(0.0f) + .date(LocalDate.parse("2019-12-27")) + .description("description") + .dividendRate(0.0f) + .nav(0.0f) + .type( + UnifiedResponse.DematAccount.Holdings + .GovernmentSecurity + .Transaction + .Type + .PURCHASE + ) + .units(0.0f) + .build() + ) .units(0.0f) .value(0.0f) .build() @@ -423,13 +842,27 @@ internal class UnifiedResponseTest { .addNominee("string") .addTransaction( UnifiedResponse.MutualFund.Scheme.Transaction.builder() + .additionalInfo( + UnifiedResponse.MutualFund.Scheme.Transaction.AdditionalInfo + .builder() + .capitalWithdrawal(0.0f) + .credit(0.0f) + .debit(0.0f) + .incomeDistribution(0.0f) + .orderNo("order_no") + .price(0.0f) + .stampDuty(0.0f) + .build() + ) .amount(0.0f) .balance(0.0f) .date(LocalDate.parse("2019-12-27")) .description("description") .dividendRate(0.0f) .nav(0.0f) - .type("type") + .type( + UnifiedResponse.MutualFund.Scheme.Transaction.Type.PURCHASE + ) .units(0.0f) .build() ) @@ -532,36 +965,197 @@ internal class UnifiedResponseTest { UnifiedResponse.DematAccount.Holdings.builder() .addAif( UnifiedResponse.DematAccount.Holdings.Aif.builder() - .additionalInfo(JsonValue.from(mapOf())) + .additionalInfo( + UnifiedResponse.DematAccount.Holdings.Aif.AdditionalInfo + .builder() + .closeUnits(0.0f) + .openUnits(0.0f) + .build() + ) .isin("isin") .name("name") + .addTransaction( + UnifiedResponse.DematAccount.Holdings.Aif.Transaction + .builder() + .additionalInfo( + UnifiedResponse.DematAccount.Holdings.Aif + .Transaction + .AdditionalInfo + .builder() + .capitalWithdrawal(0.0f) + .credit(0.0f) + .debit(0.0f) + .incomeDistribution(0.0f) + .orderNo("order_no") + .price(0.0f) + .stampDuty(0.0f) + .build() + ) + .amount(0.0f) + .balance(0.0f) + .date(LocalDate.parse("2019-12-27")) + .description("description") + .dividendRate(0.0f) + .nav(0.0f) + .type( + UnifiedResponse.DematAccount.Holdings.Aif + .Transaction + .Type + .PURCHASE + ) + .units(0.0f) + .build() + ) .units(0.0f) .value(0.0f) .build() ) .addCorporateBond( UnifiedResponse.DematAccount.Holdings.CorporateBond.builder() - .additionalInfo(JsonValue.from(mapOf())) + .additionalInfo( + UnifiedResponse.DematAccount.Holdings.CorporateBond + .AdditionalInfo + .builder() + .closeUnits(0.0f) + .openUnits(0.0f) + .build() + ) .isin("isin") .name("name") + .addTransaction( + UnifiedResponse.DematAccount.Holdings.CorporateBond + .Transaction + .builder() + .additionalInfo( + UnifiedResponse.DematAccount.Holdings + .CorporateBond + .Transaction + .AdditionalInfo + .builder() + .capitalWithdrawal(0.0f) + .credit(0.0f) + .debit(0.0f) + .incomeDistribution(0.0f) + .orderNo("order_no") + .price(0.0f) + .stampDuty(0.0f) + .build() + ) + .amount(0.0f) + .balance(0.0f) + .date(LocalDate.parse("2019-12-27")) + .description("description") + .dividendRate(0.0f) + .nav(0.0f) + .type( + UnifiedResponse.DematAccount.Holdings + .CorporateBond + .Transaction + .Type + .PURCHASE + ) + .units(0.0f) + .build() + ) .units(0.0f) .value(0.0f) .build() ) .addDematMutualFund( UnifiedResponse.DematAccount.Holdings.DematMutualFund.builder() - .additionalInfo(JsonValue.from(mapOf())) + .additionalInfo( + UnifiedResponse.DematAccount.Holdings.DematMutualFund + .AdditionalInfo + .builder() + .closeUnits(0.0f) + .openUnits(0.0f) + .build() + ) .isin("isin") .name("name") + .addTransaction( + UnifiedResponse.DematAccount.Holdings.DematMutualFund + .Transaction + .builder() + .additionalInfo( + UnifiedResponse.DematAccount.Holdings + .DematMutualFund + .Transaction + .AdditionalInfo + .builder() + .capitalWithdrawal(0.0f) + .credit(0.0f) + .debit(0.0f) + .incomeDistribution(0.0f) + .orderNo("order_no") + .price(0.0f) + .stampDuty(0.0f) + .build() + ) + .amount(0.0f) + .balance(0.0f) + .date(LocalDate.parse("2019-12-27")) + .description("description") + .dividendRate(0.0f) + .nav(0.0f) + .type( + UnifiedResponse.DematAccount.Holdings + .DematMutualFund + .Transaction + .Type + .PURCHASE + ) + .units(0.0f) + .build() + ) .units(0.0f) .value(0.0f) .build() ) .addEquity( UnifiedResponse.DematAccount.Holdings.Equity.builder() - .additionalInfo(JsonValue.from(mapOf())) + .additionalInfo( + UnifiedResponse.DematAccount.Holdings.Equity + .AdditionalInfo + .builder() + .closeUnits(0.0f) + .openUnits(0.0f) + .build() + ) .isin("isin") .name("name") + .addTransaction( + UnifiedResponse.DematAccount.Holdings.Equity.Transaction + .builder() + .additionalInfo( + UnifiedResponse.DematAccount.Holdings.Equity + .Transaction + .AdditionalInfo + .builder() + .capitalWithdrawal(0.0f) + .credit(0.0f) + .debit(0.0f) + .incomeDistribution(0.0f) + .orderNo("order_no") + .price(0.0f) + .stampDuty(0.0f) + .build() + ) + .amount(0.0f) + .balance(0.0f) + .date(LocalDate.parse("2019-12-27")) + .description("description") + .dividendRate(0.0f) + .nav(0.0f) + .type( + UnifiedResponse.DematAccount.Holdings.Equity + .Transaction + .Type + .PURCHASE + ) + .units(0.0f) + .build() + ) .units(0.0f) .value(0.0f) .build() @@ -569,9 +1163,51 @@ internal class UnifiedResponseTest { .addGovernmentSecurity( UnifiedResponse.DematAccount.Holdings.GovernmentSecurity .builder() - .additionalInfo(JsonValue.from(mapOf())) + .additionalInfo( + UnifiedResponse.DematAccount.Holdings.GovernmentSecurity + .AdditionalInfo + .builder() + .closeUnits(0.0f) + .openUnits(0.0f) + .build() + ) .isin("isin") .name("name") + .addTransaction( + UnifiedResponse.DematAccount.Holdings.GovernmentSecurity + .Transaction + .builder() + .additionalInfo( + UnifiedResponse.DematAccount.Holdings + .GovernmentSecurity + .Transaction + .AdditionalInfo + .builder() + .capitalWithdrawal(0.0f) + .credit(0.0f) + .debit(0.0f) + .incomeDistribution(0.0f) + .orderNo("order_no") + .price(0.0f) + .stampDuty(0.0f) + .build() + ) + .amount(0.0f) + .balance(0.0f) + .date(LocalDate.parse("2019-12-27")) + .description("description") + .dividendRate(0.0f) + .nav(0.0f) + .type( + UnifiedResponse.DematAccount.Holdings + .GovernmentSecurity + .Transaction + .Type + .PURCHASE + ) + .units(0.0f) + .build() + ) .units(0.0f) .value(0.0f) .build() @@ -669,13 +1305,29 @@ internal class UnifiedResponseTest { .addNominee("string") .addTransaction( UnifiedResponse.MutualFund.Scheme.Transaction.builder() + .additionalInfo( + UnifiedResponse.MutualFund.Scheme.Transaction + .AdditionalInfo + .builder() + .capitalWithdrawal(0.0f) + .credit(0.0f) + .debit(0.0f) + .incomeDistribution(0.0f) + .orderNo("order_no") + .price(0.0f) + .stampDuty(0.0f) + .build() + ) .amount(0.0f) .balance(0.0f) .date(LocalDate.parse("2019-12-27")) .description("description") .dividendRate(0.0f) .nav(0.0f) - .type("type") + .type( + UnifiedResponse.MutualFund.Scheme.Transaction.Type + .PURCHASE + ) .units(0.0f) .build() ) diff --git a/cas-parser-java-proguard-test/src/test/kotlin/com/cas_parser/api/proguard/ProGuardCompatibilityTest.kt b/cas-parser-java-proguard-test/src/test/kotlin/com/cas_parser/api/proguard/ProGuardCompatibilityTest.kt index e2b76ff..a975237 100644 --- a/cas-parser-java-proguard-test/src/test/kotlin/com/cas_parser/api/proguard/ProGuardCompatibilityTest.kt +++ b/cas-parser-java-proguard-test/src/test/kotlin/com/cas_parser/api/proguard/ProGuardCompatibilityTest.kt @@ -82,36 +82,197 @@ internal class ProGuardCompatibilityTest { UnifiedResponse.DematAccount.Holdings.builder() .addAif( UnifiedResponse.DematAccount.Holdings.Aif.builder() - .additionalInfo(JsonValue.from(mapOf())) + .additionalInfo( + UnifiedResponse.DematAccount.Holdings.Aif.AdditionalInfo + .builder() + .closeUnits(0.0f) + .openUnits(0.0f) + .build() + ) .isin("isin") .name("name") + .addTransaction( + UnifiedResponse.DematAccount.Holdings.Aif.Transaction + .builder() + .additionalInfo( + UnifiedResponse.DematAccount.Holdings.Aif + .Transaction + .AdditionalInfo + .builder() + .capitalWithdrawal(0.0f) + .credit(0.0f) + .debit(0.0f) + .incomeDistribution(0.0f) + .orderNo("order_no") + .price(0.0f) + .stampDuty(0.0f) + .build() + ) + .amount(0.0f) + .balance(0.0f) + .date(LocalDate.parse("2019-12-27")) + .description("description") + .dividendRate(0.0f) + .nav(0.0f) + .type( + UnifiedResponse.DematAccount.Holdings.Aif + .Transaction + .Type + .PURCHASE + ) + .units(0.0f) + .build() + ) .units(0.0f) .value(0.0f) .build() ) .addCorporateBond( UnifiedResponse.DematAccount.Holdings.CorporateBond.builder() - .additionalInfo(JsonValue.from(mapOf())) + .additionalInfo( + UnifiedResponse.DematAccount.Holdings.CorporateBond + .AdditionalInfo + .builder() + .closeUnits(0.0f) + .openUnits(0.0f) + .build() + ) .isin("isin") .name("name") + .addTransaction( + UnifiedResponse.DematAccount.Holdings.CorporateBond + .Transaction + .builder() + .additionalInfo( + UnifiedResponse.DematAccount.Holdings + .CorporateBond + .Transaction + .AdditionalInfo + .builder() + .capitalWithdrawal(0.0f) + .credit(0.0f) + .debit(0.0f) + .incomeDistribution(0.0f) + .orderNo("order_no") + .price(0.0f) + .stampDuty(0.0f) + .build() + ) + .amount(0.0f) + .balance(0.0f) + .date(LocalDate.parse("2019-12-27")) + .description("description") + .dividendRate(0.0f) + .nav(0.0f) + .type( + UnifiedResponse.DematAccount.Holdings + .CorporateBond + .Transaction + .Type + .PURCHASE + ) + .units(0.0f) + .build() + ) .units(0.0f) .value(0.0f) .build() ) .addDematMutualFund( UnifiedResponse.DematAccount.Holdings.DematMutualFund.builder() - .additionalInfo(JsonValue.from(mapOf())) + .additionalInfo( + UnifiedResponse.DematAccount.Holdings.DematMutualFund + .AdditionalInfo + .builder() + .closeUnits(0.0f) + .openUnits(0.0f) + .build() + ) .isin("isin") .name("name") + .addTransaction( + UnifiedResponse.DematAccount.Holdings.DematMutualFund + .Transaction + .builder() + .additionalInfo( + UnifiedResponse.DematAccount.Holdings + .DematMutualFund + .Transaction + .AdditionalInfo + .builder() + .capitalWithdrawal(0.0f) + .credit(0.0f) + .debit(0.0f) + .incomeDistribution(0.0f) + .orderNo("order_no") + .price(0.0f) + .stampDuty(0.0f) + .build() + ) + .amount(0.0f) + .balance(0.0f) + .date(LocalDate.parse("2019-12-27")) + .description("description") + .dividendRate(0.0f) + .nav(0.0f) + .type( + UnifiedResponse.DematAccount.Holdings + .DematMutualFund + .Transaction + .Type + .PURCHASE + ) + .units(0.0f) + .build() + ) .units(0.0f) .value(0.0f) .build() ) .addEquity( UnifiedResponse.DematAccount.Holdings.Equity.builder() - .additionalInfo(JsonValue.from(mapOf())) + .additionalInfo( + UnifiedResponse.DematAccount.Holdings.Equity + .AdditionalInfo + .builder() + .closeUnits(0.0f) + .openUnits(0.0f) + .build() + ) .isin("isin") .name("name") + .addTransaction( + UnifiedResponse.DematAccount.Holdings.Equity.Transaction + .builder() + .additionalInfo( + UnifiedResponse.DematAccount.Holdings.Equity + .Transaction + .AdditionalInfo + .builder() + .capitalWithdrawal(0.0f) + .credit(0.0f) + .debit(0.0f) + .incomeDistribution(0.0f) + .orderNo("order_no") + .price(0.0f) + .stampDuty(0.0f) + .build() + ) + .amount(0.0f) + .balance(0.0f) + .date(LocalDate.parse("2019-12-27")) + .description("description") + .dividendRate(0.0f) + .nav(0.0f) + .type( + UnifiedResponse.DematAccount.Holdings.Equity + .Transaction + .Type + .PURCHASE + ) + .units(0.0f) + .build() + ) .units(0.0f) .value(0.0f) .build() @@ -119,9 +280,51 @@ internal class ProGuardCompatibilityTest { .addGovernmentSecurity( UnifiedResponse.DematAccount.Holdings.GovernmentSecurity .builder() - .additionalInfo(JsonValue.from(mapOf())) + .additionalInfo( + UnifiedResponse.DematAccount.Holdings.GovernmentSecurity + .AdditionalInfo + .builder() + .closeUnits(0.0f) + .openUnits(0.0f) + .build() + ) .isin("isin") .name("name") + .addTransaction( + UnifiedResponse.DematAccount.Holdings.GovernmentSecurity + .Transaction + .builder() + .additionalInfo( + UnifiedResponse.DematAccount.Holdings + .GovernmentSecurity + .Transaction + .AdditionalInfo + .builder() + .capitalWithdrawal(0.0f) + .credit(0.0f) + .debit(0.0f) + .incomeDistribution(0.0f) + .orderNo("order_no") + .price(0.0f) + .stampDuty(0.0f) + .build() + ) + .amount(0.0f) + .balance(0.0f) + .date(LocalDate.parse("2019-12-27")) + .description("description") + .dividendRate(0.0f) + .nav(0.0f) + .type( + UnifiedResponse.DematAccount.Holdings + .GovernmentSecurity + .Transaction + .Type + .PURCHASE + ) + .units(0.0f) + .build() + ) .units(0.0f) .value(0.0f) .build() @@ -219,13 +422,29 @@ internal class ProGuardCompatibilityTest { .addNominee("string") .addTransaction( UnifiedResponse.MutualFund.Scheme.Transaction.builder() + .additionalInfo( + UnifiedResponse.MutualFund.Scheme.Transaction + .AdditionalInfo + .builder() + .capitalWithdrawal(0.0f) + .credit(0.0f) + .debit(0.0f) + .incomeDistribution(0.0f) + .orderNo("order_no") + .price(0.0f) + .stampDuty(0.0f) + .build() + ) .amount(0.0f) .balance(0.0f) .date(LocalDate.parse("2019-12-27")) .description("description") .dividendRate(0.0f) .nav(0.0f) - .type("type") + .type( + UnifiedResponse.MutualFund.Scheme.Transaction.Type + .PURCHASE + ) .units(0.0f) .build() ) From 2777cde0f09ffe3824505f707bcc7f9942b0e51d Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 5 Jan 2026 02:17:20 +0000 Subject: [PATCH 23/99] feat(api): api update --- .stats.yml | 6 +- README.md | 17 - .../CasGeneratorGenerateCasParams.kt | 919 ------------------ .../CasGeneratorGenerateCasResponse.kt | 189 ---- .../async/CasGeneratorServiceAsync.kt | 36 - .../async/CasGeneratorServiceAsyncImpl.kt | 56 -- .../services/blocking/CasGeneratorService.kt | 36 - .../blocking/CasGeneratorServiceImpl.kt | 52 - .../CasGeneratorGenerateCasParamsTest.kt | 62 -- .../CasGeneratorGenerateCasResponseTest.kt | 49 - .../async/CasGeneratorServiceAsyncTest.kt | 40 - .../blocking/CasGeneratorServiceTest.kt | 39 - 12 files changed, 3 insertions(+), 1498 deletions(-) delete mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casgenerator/CasGeneratorGenerateCasParams.kt delete mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casgenerator/CasGeneratorGenerateCasResponse.kt delete mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casgenerator/CasGeneratorGenerateCasParamsTest.kt delete mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casgenerator/CasGeneratorGenerateCasResponseTest.kt delete mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CasGeneratorServiceAsyncTest.kt delete mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CasGeneratorServiceTest.kt diff --git a/.stats.yml b/.stats.yml index 48b33b3..4465de7 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 5 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-38618cc5c938e87eeacf4893d6a6ba4e6ef7da390e6283dc7b50b484a7b97165.yml -openapi_spec_hash: b9e439ecee904ded01aa34efdee88856 +configured_endpoints: 4 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-7e6397bddc220d1a59b5e2c7e7c3ff38f1a6eb174f4e383e03bc49cf78c8c44f.yml +openapi_spec_hash: cb852eeb4ce89c80f4246815cbe21f72 config_hash: cb5d75abef6264b5d86448caf7295afa diff --git a/README.md b/README.md index 15ce0f4..878f4b9 100644 --- a/README.md +++ b/README.md @@ -476,23 +476,6 @@ JsonValue complexValue = JsonValue.from(Map.of( )); ``` -Normally a `Builder` class's `build` method will throw [`IllegalStateException`](https://docs.oracle.com/javase/8/docs/api/java/lang/IllegalStateException.html) if any required parameter or property is unset. - -To forcibly omit a required parameter or property, pass [`JsonMissing`](cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Values.kt): - -```java -import com.cas_parser.api.core.JsonMissing; -import com.cas_parser.api.models.casgenerator.CasGeneratorGenerateCasParams; -import com.cas_parser.api.models.casparser.CasParserSmartParseParams; - -CasParserSmartParseParams params = CasGeneratorGenerateCasParams.builder() - .fromDate("2023-01-01") - .password("Abcdefghi12$") - .toDate("2023-12-31") - .email(JsonMissing.of()) - .build(); -``` - ### Response properties To access undocumented response properties, call the `_additionalProperties()` method: diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casgenerator/CasGeneratorGenerateCasParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casgenerator/CasGeneratorGenerateCasParams.kt deleted file mode 100644 index 598c6a2..0000000 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casgenerator/CasGeneratorGenerateCasParams.kt +++ /dev/null @@ -1,919 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.models.casgenerator - -import com.cas_parser.api.core.Enum -import com.cas_parser.api.core.ExcludeMissing -import com.cas_parser.api.core.JsonField -import com.cas_parser.api.core.JsonMissing -import com.cas_parser.api.core.JsonValue -import com.cas_parser.api.core.Params -import com.cas_parser.api.core.checkRequired -import com.cas_parser.api.core.http.Headers -import com.cas_parser.api.core.http.QueryParams -import com.cas_parser.api.errors.CasParserInvalidDataException -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 - -/** - * This endpoint generates CAS (Consolidated Account Statement) documents by submitting a mailback - * request to the specified CAS authority. Currently only supports KFintech, with plans to support - * CAMS, CDSL, and NSDL in the future. - */ -class CasGeneratorGenerateCasParams -private constructor( - private val body: Body, - private val additionalHeaders: Headers, - private val additionalQueryParams: QueryParams, -) : Params { - - /** - * Email address to receive the CAS document - * - * @throws CasParserInvalidDataException 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 email(): String = body.email() - - /** - * Start date for the CAS period (format YYYY-MM-DD) - * - * @throws CasParserInvalidDataException 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 fromDate(): String = body.fromDate() - - /** - * Password to protect the generated CAS PDF - * - * @throws CasParserInvalidDataException 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 password(): String = body.password() - - /** - * End date for the CAS period (format YYYY-MM-DD) - * - * @throws CasParserInvalidDataException 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 toDate(): String = body.toDate() - - /** - * CAS authority to generate the document from (currently only kfintech is supported) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun casAuthority(): Optional = body.casAuthority() - - /** - * PAN number (optional for some CAS authorities) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun panNo(): Optional = body.panNo() - - /** - * Returns the raw JSON value of [email]. - * - * Unlike [email], this method doesn't throw if the JSON field has an unexpected type. - */ - fun _email(): JsonField = body._email() - - /** - * Returns the raw JSON value of [fromDate]. - * - * Unlike [fromDate], this method doesn't throw if the JSON field has an unexpected type. - */ - fun _fromDate(): JsonField = body._fromDate() - - /** - * Returns the raw JSON value of [password]. - * - * Unlike [password], this method doesn't throw if the JSON field has an unexpected type. - */ - fun _password(): JsonField = body._password() - - /** - * Returns the raw JSON value of [toDate]. - * - * Unlike [toDate], this method doesn't throw if the JSON field has an unexpected type. - */ - fun _toDate(): JsonField = body._toDate() - - /** - * Returns the raw JSON value of [casAuthority]. - * - * Unlike [casAuthority], this method doesn't throw if the JSON field has an unexpected type. - */ - fun _casAuthority(): JsonField = body._casAuthority() - - /** - * Returns the raw JSON value of [panNo]. - * - * Unlike [panNo], this method doesn't throw if the JSON field has an unexpected type. - */ - fun _panNo(): JsonField = body._panNo() - - fun _additionalBodyProperties(): Map = body._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 - * [CasGeneratorGenerateCasParams]. - * - * The following fields are required: - * ```java - * .email() - * .fromDate() - * .password() - * .toDate() - * ``` - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [CasGeneratorGenerateCasParams]. */ - class Builder internal constructor() { - - private var body: Body.Builder = Body.builder() - private var additionalHeaders: Headers.Builder = Headers.builder() - private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() - - @JvmSynthetic - internal fun from(casGeneratorGenerateCasParams: CasGeneratorGenerateCasParams) = apply { - body = casGeneratorGenerateCasParams.body.toBuilder() - additionalHeaders = casGeneratorGenerateCasParams.additionalHeaders.toBuilder() - additionalQueryParams = casGeneratorGenerateCasParams.additionalQueryParams.toBuilder() - } - - /** - * Sets the entire request body. - * - * This is generally only useful if you are already constructing the body separately. - * Otherwise, it's more convenient to use the top-level setters instead: - * - [email] - * - [fromDate] - * - [password] - * - [toDate] - * - [casAuthority] - * - etc. - */ - fun body(body: Body) = apply { this.body = body.toBuilder() } - - /** Email address to receive the CAS document */ - fun email(email: String) = apply { body.email(email) } - - /** - * Sets [Builder.email] to an arbitrary JSON value. - * - * You should usually call [Builder.email] with a well-typed [String] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun email(email: JsonField) = apply { body.email(email) } - - /** Start date for the CAS period (format YYYY-MM-DD) */ - fun fromDate(fromDate: String) = apply { body.fromDate(fromDate) } - - /** - * Sets [Builder.fromDate] to an arbitrary JSON value. - * - * You should usually call [Builder.fromDate] with a well-typed [String] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun fromDate(fromDate: JsonField) = apply { body.fromDate(fromDate) } - - /** Password to protect the generated CAS PDF */ - fun password(password: String) = apply { body.password(password) } - - /** - * Sets [Builder.password] to an arbitrary JSON value. - * - * You should usually call [Builder.password] with a well-typed [String] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun password(password: JsonField) = apply { body.password(password) } - - /** End date for the CAS period (format YYYY-MM-DD) */ - fun toDate(toDate: String) = apply { body.toDate(toDate) } - - /** - * Sets [Builder.toDate] to an arbitrary JSON value. - * - * You should usually call [Builder.toDate] with a well-typed [String] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun toDate(toDate: JsonField) = apply { body.toDate(toDate) } - - /** CAS authority to generate the document from (currently only kfintech is supported) */ - fun casAuthority(casAuthority: CasAuthority) = apply { body.casAuthority(casAuthority) } - - /** - * Sets [Builder.casAuthority] to an arbitrary JSON value. - * - * You should usually call [Builder.casAuthority] with a well-typed [CasAuthority] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun casAuthority(casAuthority: JsonField) = apply { - body.casAuthority(casAuthority) - } - - /** PAN number (optional for some CAS authorities) */ - fun panNo(panNo: String) = apply { body.panNo(panNo) } - - /** - * Sets [Builder.panNo] to an arbitrary JSON value. - * - * You should usually call [Builder.panNo] with a well-typed [String] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun panNo(panNo: JsonField) = apply { body.panNo(panNo) } - - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - body.additionalProperties(additionalBodyProperties) - } - - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - body.putAdditionalProperty(key, value) - } - - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = - apply { - body.putAllAdditionalProperties(additionalBodyProperties) - } - - fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } - - fun removeAllAdditionalBodyProperties(keys: Set) = apply { - body.removeAllAdditionalProperties(keys) - } - - 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 [CasGeneratorGenerateCasParams]. - * - * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .email() - * .fromDate() - * .password() - * .toDate() - * ``` - * - * @throws IllegalStateException if any required field is unset. - */ - fun build(): CasGeneratorGenerateCasParams = - CasGeneratorGenerateCasParams( - body.build(), - additionalHeaders.build(), - additionalQueryParams.build(), - ) - } - - fun _body(): Body = body - - override fun _headers(): Headers = additionalHeaders - - override fun _queryParams(): QueryParams = additionalQueryParams - - class Body - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val email: JsonField, - private val fromDate: JsonField, - private val password: JsonField, - private val toDate: JsonField, - private val casAuthority: JsonField, - private val panNo: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("email") @ExcludeMissing email: JsonField = JsonMissing.of(), - @JsonProperty("from_date") - @ExcludeMissing - fromDate: JsonField = JsonMissing.of(), - @JsonProperty("password") - @ExcludeMissing - password: JsonField = JsonMissing.of(), - @JsonProperty("to_date") @ExcludeMissing toDate: JsonField = JsonMissing.of(), - @JsonProperty("cas_authority") - @ExcludeMissing - casAuthority: JsonField = JsonMissing.of(), - @JsonProperty("pan_no") @ExcludeMissing panNo: JsonField = JsonMissing.of(), - ) : this(email, fromDate, password, toDate, casAuthority, panNo, mutableMapOf()) - - /** - * Email address to receive the CAS document - * - * @throws CasParserInvalidDataException 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 email(): String = email.getRequired("email") - - /** - * Start date for the CAS period (format YYYY-MM-DD) - * - * @throws CasParserInvalidDataException 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 fromDate(): String = fromDate.getRequired("from_date") - - /** - * Password to protect the generated CAS PDF - * - * @throws CasParserInvalidDataException 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 password(): String = password.getRequired("password") - - /** - * End date for the CAS period (format YYYY-MM-DD) - * - * @throws CasParserInvalidDataException 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 toDate(): String = toDate.getRequired("to_date") - - /** - * CAS authority to generate the document from (currently only kfintech is supported) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun casAuthority(): Optional = casAuthority.getOptional("cas_authority") - - /** - * PAN number (optional for some CAS authorities) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun panNo(): Optional = panNo.getOptional("pan_no") - - /** - * Returns the raw JSON value of [email]. - * - * Unlike [email], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("email") @ExcludeMissing fun _email(): JsonField = email - - /** - * Returns the raw JSON value of [fromDate]. - * - * Unlike [fromDate], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("from_date") @ExcludeMissing fun _fromDate(): JsonField = fromDate - - /** - * Returns the raw JSON value of [password]. - * - * Unlike [password], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("password") @ExcludeMissing fun _password(): JsonField = password - - /** - * Returns the raw JSON value of [toDate]. - * - * Unlike [toDate], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("to_date") @ExcludeMissing fun _toDate(): JsonField = toDate - - /** - * Returns the raw JSON value of [casAuthority]. - * - * Unlike [casAuthority], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("cas_authority") - @ExcludeMissing - fun _casAuthority(): JsonField = casAuthority - - /** - * Returns the raw JSON value of [panNo]. - * - * Unlike [panNo], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("pan_no") @ExcludeMissing fun _panNo(): JsonField = panNo - - @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 [Body]. - * - * The following fields are required: - * ```java - * .email() - * .fromDate() - * .password() - * .toDate() - * ``` - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Body]. */ - class Builder internal constructor() { - - private var email: JsonField? = null - private var fromDate: JsonField? = null - private var password: JsonField? = null - private var toDate: JsonField? = null - private var casAuthority: JsonField = JsonMissing.of() - private var panNo: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(body: Body) = apply { - email = body.email - fromDate = body.fromDate - password = body.password - toDate = body.toDate - casAuthority = body.casAuthority - panNo = body.panNo - additionalProperties = body.additionalProperties.toMutableMap() - } - - /** Email address to receive the CAS document */ - fun email(email: String) = email(JsonField.of(email)) - - /** - * Sets [Builder.email] to an arbitrary JSON value. - * - * You should usually call [Builder.email] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun email(email: JsonField) = apply { this.email = email } - - /** Start date for the CAS period (format YYYY-MM-DD) */ - fun fromDate(fromDate: String) = fromDate(JsonField.of(fromDate)) - - /** - * Sets [Builder.fromDate] to an arbitrary JSON value. - * - * You should usually call [Builder.fromDate] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun fromDate(fromDate: JsonField) = apply { this.fromDate = fromDate } - - /** Password to protect the generated CAS PDF */ - fun password(password: String) = password(JsonField.of(password)) - - /** - * Sets [Builder.password] to an arbitrary JSON value. - * - * You should usually call [Builder.password] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun password(password: JsonField) = apply { this.password = password } - - /** End date for the CAS period (format YYYY-MM-DD) */ - fun toDate(toDate: String) = toDate(JsonField.of(toDate)) - - /** - * Sets [Builder.toDate] to an arbitrary JSON value. - * - * You should usually call [Builder.toDate] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun toDate(toDate: JsonField) = apply { this.toDate = toDate } - - /** - * CAS authority to generate the document from (currently only kfintech is supported) - */ - fun casAuthority(casAuthority: CasAuthority) = casAuthority(JsonField.of(casAuthority)) - - /** - * Sets [Builder.casAuthority] to an arbitrary JSON value. - * - * You should usually call [Builder.casAuthority] with a well-typed [CasAuthority] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun casAuthority(casAuthority: JsonField) = apply { - this.casAuthority = casAuthority - } - - /** PAN number (optional for some CAS authorities) */ - fun panNo(panNo: String) = panNo(JsonField.of(panNo)) - - /** - * Sets [Builder.panNo] to an arbitrary JSON value. - * - * You should usually call [Builder.panNo] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun panNo(panNo: JsonField) = apply { this.panNo = panNo } - - 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 [Body]. - * - * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .email() - * .fromDate() - * .password() - * .toDate() - * ``` - * - * @throws IllegalStateException if any required field is unset. - */ - fun build(): Body = - Body( - checkRequired("email", email), - checkRequired("fromDate", fromDate), - checkRequired("password", password), - checkRequired("toDate", toDate), - casAuthority, - panNo, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): Body = apply { - if (validated) { - return@apply - } - - email() - fromDate() - password() - toDate() - casAuthority().ifPresent { it.validate() } - panNo() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - 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 (email.asKnown().isPresent) 1 else 0) + - (if (fromDate.asKnown().isPresent) 1 else 0) + - (if (password.asKnown().isPresent) 1 else 0) + - (if (toDate.asKnown().isPresent) 1 else 0) + - (casAuthority.asKnown().getOrNull()?.validity() ?: 0) + - (if (panNo.asKnown().isPresent) 1 else 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Body && - email == other.email && - fromDate == other.fromDate && - password == other.password && - toDate == other.toDate && - casAuthority == other.casAuthority && - panNo == other.panNo && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash( - email, - fromDate, - password, - toDate, - casAuthority, - panNo, - additionalProperties, - ) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Body{email=$email, fromDate=$fromDate, password=$password, toDate=$toDate, casAuthority=$casAuthority, panNo=$panNo, additionalProperties=$additionalProperties}" - } - - /** CAS authority to generate the document from (currently only kfintech is supported) */ - class CasAuthority @JsonCreator private constructor(private val value: JsonField) : - Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that doesn't - * match any known member, and you want to know that value. For example, if the SDK is on an - * older version than the API, then the API may respond with new members that the SDK is - * unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - companion object { - - @JvmField val KFINTECH = of("kfintech") - - @JvmField val CAMS = of("cams") - - @JvmField val CDSL = of("cdsl") - - @JvmField val NSDL = of("nsdl") - - @JvmStatic fun of(value: String) = CasAuthority(JsonField.of(value)) - } - - /** An enum containing [CasAuthority]'s known values. */ - enum class Known { - KFINTECH, - CAMS, - CDSL, - NSDL, - } - - /** - * An enum containing [CasAuthority]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [CasAuthority] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For example, if the - * SDK is on an older version than the API, then the API may respond with new members that - * the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - KFINTECH, - CAMS, - CDSL, - NSDL, - /** - * An enum member indicating that [CasAuthority] was instantiated with an unknown value. - */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] - * if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or if you want - * to throw for the unknown case. - */ - fun value(): Value = - when (this) { - KFINTECH -> Value.KFINTECH - CAMS -> Value.CAMS - CDSL -> Value.CDSL - NSDL -> Value.NSDL - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known and don't - * want to throw for the unknown case. - * - * @throws CasParserInvalidDataException if this class instance's value is a not a known - * member. - */ - fun known(): Known = - when (this) { - KFINTECH -> Known.KFINTECH - CAMS -> Known.CAMS - CDSL -> Known.CDSL - NSDL -> Known.NSDL - else -> throw CasParserInvalidDataException("Unknown CasAuthority: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily for debugging - * and generally doesn't throw. - * - * @throws CasParserInvalidDataException if this class instance's value does not have the - * expected primitive type. - */ - fun asString(): String = - _value().asString().orElseThrow { - CasParserInvalidDataException("Value is not a String") - } - - private var validated: Boolean = false - - fun validate(): CasAuthority = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - 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 (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is CasAuthority && value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is CasGeneratorGenerateCasParams && - body == other.body && - additionalHeaders == other.additionalHeaders && - additionalQueryParams == other.additionalQueryParams - } - - override fun hashCode(): Int = Objects.hash(body, additionalHeaders, additionalQueryParams) - - override fun toString() = - "CasGeneratorGenerateCasParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" -} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casgenerator/CasGeneratorGenerateCasResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casgenerator/CasGeneratorGenerateCasResponse.kt deleted file mode 100644 index ad4901d..0000000 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casgenerator/CasGeneratorGenerateCasResponse.kt +++ /dev/null @@ -1,189 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.models.casgenerator - -import com.cas_parser.api.core.ExcludeMissing -import com.cas_parser.api.core.JsonField -import com.cas_parser.api.core.JsonMissing -import com.cas_parser.api.core.JsonValue -import com.cas_parser.api.errors.CasParserInvalidDataException -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 - -class CasGeneratorGenerateCasResponse -@JsonCreator(mode = JsonCreator.Mode.DISABLED) -private constructor( - private val msg: JsonField, - private val status: JsonField, - private val additionalProperties: MutableMap, -) { - - @JsonCreator - private constructor( - @JsonProperty("msg") @ExcludeMissing msg: JsonField = JsonMissing.of(), - @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(), - ) : this(msg, status, mutableMapOf()) - - /** - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun msg(): Optional = msg.getOptional("msg") - - /** - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun status(): Optional = status.getOptional("status") - - /** - * Returns the raw JSON value of [msg]. - * - * Unlike [msg], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("msg") @ExcludeMissing fun _msg(): JsonField = msg - - /** - * Returns the raw JSON value of [status]. - * - * Unlike [status], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("status") @ExcludeMissing fun _status(): JsonField = status - - @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 - * [CasGeneratorGenerateCasResponse]. - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [CasGeneratorGenerateCasResponse]. */ - class Builder internal constructor() { - - private var msg: JsonField = JsonMissing.of() - private var status: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(casGeneratorGenerateCasResponse: CasGeneratorGenerateCasResponse) = - apply { - msg = casGeneratorGenerateCasResponse.msg - status = casGeneratorGenerateCasResponse.status - additionalProperties = - casGeneratorGenerateCasResponse.additionalProperties.toMutableMap() - } - - fun msg(msg: String) = msg(JsonField.of(msg)) - - /** - * Sets [Builder.msg] to an arbitrary JSON value. - * - * You should usually call [Builder.msg] with a well-typed [String] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun msg(msg: JsonField) = apply { this.msg = msg } - - fun status(status: String) = status(JsonField.of(status)) - - /** - * Sets [Builder.status] to an arbitrary JSON value. - * - * You should usually call [Builder.status] with a well-typed [String] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun status(status: JsonField) = apply { this.status = status } - - 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 [CasGeneratorGenerateCasResponse]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): CasGeneratorGenerateCasResponse = - CasGeneratorGenerateCasResponse(msg, status, additionalProperties.toMutableMap()) - } - - private var validated: Boolean = false - - fun validate(): CasGeneratorGenerateCasResponse = apply { - if (validated) { - return@apply - } - - msg() - status() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - 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 (msg.asKnown().isPresent) 1 else 0) + (if (status.asKnown().isPresent) 1 else 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is CasGeneratorGenerateCasResponse && - msg == other.msg && - status == other.status && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { Objects.hash(msg, status, additionalProperties) } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "CasGeneratorGenerateCasResponse{msg=$msg, status=$status, additionalProperties=$additionalProperties}" -} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CasGeneratorServiceAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CasGeneratorServiceAsync.kt index 9eee1d4..0e6995d 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CasGeneratorServiceAsync.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CasGeneratorServiceAsync.kt @@ -3,11 +3,6 @@ package com.cas_parser.api.services.async import com.cas_parser.api.core.ClientOptions -import com.cas_parser.api.core.RequestOptions -import com.cas_parser.api.core.http.HttpResponseFor -import com.cas_parser.api.models.casgenerator.CasGeneratorGenerateCasParams -import com.cas_parser.api.models.casgenerator.CasGeneratorGenerateCasResponse -import java.util.concurrent.CompletableFuture import java.util.function.Consumer interface CasGeneratorServiceAsync { @@ -24,22 +19,6 @@ interface CasGeneratorServiceAsync { */ fun withOptions(modifier: Consumer): CasGeneratorServiceAsync - /** - * This endpoint generates CAS (Consolidated Account Statement) documents by submitting a - * mailback request to the specified CAS authority. Currently only supports KFintech, with plans - * to support CAMS, CDSL, and NSDL in the future. - */ - fun generateCas( - params: CasGeneratorGenerateCasParams - ): CompletableFuture = - generateCas(params, RequestOptions.none()) - - /** @see generateCas */ - fun generateCas( - params: CasGeneratorGenerateCasParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture - /** * A view of [CasGeneratorServiceAsync] that provides access to raw HTTP responses for each * method. @@ -54,20 +33,5 @@ interface CasGeneratorServiceAsync { fun withOptions( modifier: Consumer ): CasGeneratorServiceAsync.WithRawResponse - - /** - * Returns a raw HTTP response for `post /v4/generate`, but is otherwise the same as - * [CasGeneratorServiceAsync.generateCas]. - */ - fun generateCas( - params: CasGeneratorGenerateCasParams - ): CompletableFuture> = - generateCas(params, RequestOptions.none()) - - /** @see generateCas */ - fun generateCas( - params: CasGeneratorGenerateCasParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture> } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CasGeneratorServiceAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CasGeneratorServiceAsyncImpl.kt index b0b1ff9..0bbd145 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CasGeneratorServiceAsyncImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CasGeneratorServiceAsyncImpl.kt @@ -3,21 +3,6 @@ package com.cas_parser.api.services.async import com.cas_parser.api.core.ClientOptions -import com.cas_parser.api.core.RequestOptions -import com.cas_parser.api.core.handlers.errorBodyHandler -import com.cas_parser.api.core.handlers.errorHandler -import com.cas_parser.api.core.handlers.jsonHandler -import com.cas_parser.api.core.http.HttpMethod -import com.cas_parser.api.core.http.HttpRequest -import com.cas_parser.api.core.http.HttpResponse -import com.cas_parser.api.core.http.HttpResponse.Handler -import com.cas_parser.api.core.http.HttpResponseFor -import com.cas_parser.api.core.http.json -import com.cas_parser.api.core.http.parseable -import com.cas_parser.api.core.prepareAsync -import com.cas_parser.api.models.casgenerator.CasGeneratorGenerateCasParams -import com.cas_parser.api.models.casgenerator.CasGeneratorGenerateCasResponse -import java.util.concurrent.CompletableFuture import java.util.function.Consumer class CasGeneratorServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : @@ -32,55 +17,14 @@ class CasGeneratorServiceAsyncImpl internal constructor(private val clientOption override fun withOptions(modifier: Consumer): CasGeneratorServiceAsync = CasGeneratorServiceAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build()) - override fun generateCas( - params: CasGeneratorGenerateCasParams, - requestOptions: RequestOptions, - ): CompletableFuture = - // post /v4/generate - withRawResponse().generateCas(params, requestOptions).thenApply { it.parse() } - class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : CasGeneratorServiceAsync.WithRawResponse { - private val errorHandler: Handler = - errorHandler(errorBodyHandler(clientOptions.jsonMapper)) - override fun withOptions( modifier: Consumer ): CasGeneratorServiceAsync.WithRawResponse = CasGeneratorServiceAsyncImpl.WithRawResponseImpl( clientOptions.toBuilder().apply(modifier::accept).build() ) - - private val generateCasHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - - override fun generateCas( - params: CasGeneratorGenerateCasParams, - requestOptions: RequestOptions, - ): CompletableFuture> { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .baseUrl(clientOptions.baseUrl()) - .addPathSegments("v4", "generate") - .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 { generateCasHandler.handle(it) } - .also { - if (requestOptions.responseValidation!!) { - it.validate() - } - } - } - } - } } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CasGeneratorService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CasGeneratorService.kt index b586008..f0ad062 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CasGeneratorService.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CasGeneratorService.kt @@ -3,11 +3,6 @@ package com.cas_parser.api.services.blocking import com.cas_parser.api.core.ClientOptions -import com.cas_parser.api.core.RequestOptions -import com.cas_parser.api.core.http.HttpResponseFor -import com.cas_parser.api.models.casgenerator.CasGeneratorGenerateCasParams -import com.cas_parser.api.models.casgenerator.CasGeneratorGenerateCasResponse -import com.google.errorprone.annotations.MustBeClosed import java.util.function.Consumer interface CasGeneratorService { @@ -24,20 +19,6 @@ interface CasGeneratorService { */ fun withOptions(modifier: Consumer): CasGeneratorService - /** - * This endpoint generates CAS (Consolidated Account Statement) documents by submitting a - * mailback request to the specified CAS authority. Currently only supports KFintech, with plans - * to support CAMS, CDSL, and NSDL in the future. - */ - fun generateCas(params: CasGeneratorGenerateCasParams): CasGeneratorGenerateCasResponse = - generateCas(params, RequestOptions.none()) - - /** @see generateCas */ - fun generateCas( - params: CasGeneratorGenerateCasParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): CasGeneratorGenerateCasResponse - /** * A view of [CasGeneratorService] that provides access to raw HTTP responses for each method. */ @@ -51,22 +32,5 @@ interface CasGeneratorService { fun withOptions( modifier: Consumer ): CasGeneratorService.WithRawResponse - - /** - * Returns a raw HTTP response for `post /v4/generate`, but is otherwise the same as - * [CasGeneratorService.generateCas]. - */ - @MustBeClosed - fun generateCas( - params: CasGeneratorGenerateCasParams - ): HttpResponseFor = - generateCas(params, RequestOptions.none()) - - /** @see generateCas */ - @MustBeClosed - fun generateCas( - params: CasGeneratorGenerateCasParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): HttpResponseFor } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CasGeneratorServiceImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CasGeneratorServiceImpl.kt index 26bcfb5..1d0054b 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CasGeneratorServiceImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CasGeneratorServiceImpl.kt @@ -3,20 +3,6 @@ package com.cas_parser.api.services.blocking import com.cas_parser.api.core.ClientOptions -import com.cas_parser.api.core.RequestOptions -import com.cas_parser.api.core.handlers.errorBodyHandler -import com.cas_parser.api.core.handlers.errorHandler -import com.cas_parser.api.core.handlers.jsonHandler -import com.cas_parser.api.core.http.HttpMethod -import com.cas_parser.api.core.http.HttpRequest -import com.cas_parser.api.core.http.HttpResponse -import com.cas_parser.api.core.http.HttpResponse.Handler -import com.cas_parser.api.core.http.HttpResponseFor -import com.cas_parser.api.core.http.json -import com.cas_parser.api.core.http.parseable -import com.cas_parser.api.core.prepare -import com.cas_parser.api.models.casgenerator.CasGeneratorGenerateCasParams -import com.cas_parser.api.models.casgenerator.CasGeneratorGenerateCasResponse import java.util.function.Consumer class CasGeneratorServiceImpl internal constructor(private val clientOptions: ClientOptions) : @@ -31,52 +17,14 @@ class CasGeneratorServiceImpl internal constructor(private val clientOptions: Cl override fun withOptions(modifier: Consumer): CasGeneratorService = CasGeneratorServiceImpl(clientOptions.toBuilder().apply(modifier::accept).build()) - override fun generateCas( - params: CasGeneratorGenerateCasParams, - requestOptions: RequestOptions, - ): CasGeneratorGenerateCasResponse = - // post /v4/generate - withRawResponse().generateCas(params, requestOptions).parse() - class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : CasGeneratorService.WithRawResponse { - private val errorHandler: Handler = - errorHandler(errorBodyHandler(clientOptions.jsonMapper)) - override fun withOptions( modifier: Consumer ): CasGeneratorService.WithRawResponse = CasGeneratorServiceImpl.WithRawResponseImpl( clientOptions.toBuilder().apply(modifier::accept).build() ) - - private val generateCasHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - - override fun generateCas( - params: CasGeneratorGenerateCasParams, - requestOptions: RequestOptions, - ): HttpResponseFor { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .baseUrl(clientOptions.baseUrl()) - .addPathSegments("v4", "generate") - .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 { generateCasHandler.handle(it) } - .also { - if (requestOptions.responseValidation!!) { - it.validate() - } - } - } - } } } diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casgenerator/CasGeneratorGenerateCasParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casgenerator/CasGeneratorGenerateCasParamsTest.kt deleted file mode 100644 index 24f18c9..0000000 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casgenerator/CasGeneratorGenerateCasParamsTest.kt +++ /dev/null @@ -1,62 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.models.casgenerator - -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -internal class CasGeneratorGenerateCasParamsTest { - - @Test - fun create() { - CasGeneratorGenerateCasParams.builder() - .email("user@example.com") - .fromDate("2023-01-01") - .password("Abcdefghi12\$") - .toDate("2023-12-31") - .casAuthority(CasGeneratorGenerateCasParams.CasAuthority.KFINTECH) - .panNo("ABCDE1234F") - .build() - } - - @Test - fun body() { - val params = - CasGeneratorGenerateCasParams.builder() - .email("user@example.com") - .fromDate("2023-01-01") - .password("Abcdefghi12\$") - .toDate("2023-12-31") - .casAuthority(CasGeneratorGenerateCasParams.CasAuthority.KFINTECH) - .panNo("ABCDE1234F") - .build() - - val body = params._body() - - assertThat(body.email()).isEqualTo("user@example.com") - assertThat(body.fromDate()).isEqualTo("2023-01-01") - assertThat(body.password()).isEqualTo("Abcdefghi12\$") - assertThat(body.toDate()).isEqualTo("2023-12-31") - assertThat(body.casAuthority()) - .contains(CasGeneratorGenerateCasParams.CasAuthority.KFINTECH) - assertThat(body.panNo()).contains("ABCDE1234F") - } - - @Test - fun bodyWithoutOptionalFields() { - val params = - CasGeneratorGenerateCasParams.builder() - .email("user@example.com") - .fromDate("2023-01-01") - .password("Abcdefghi12\$") - .toDate("2023-12-31") - .build() - - val body = params._body() - - assertThat(body.email()).isEqualTo("user@example.com") - assertThat(body.fromDate()).isEqualTo("2023-01-01") - assertThat(body.password()).isEqualTo("Abcdefghi12\$") - assertThat(body.toDate()).isEqualTo("2023-12-31") - } -} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casgenerator/CasGeneratorGenerateCasResponseTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casgenerator/CasGeneratorGenerateCasResponseTest.kt deleted file mode 100644 index c225afa..0000000 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casgenerator/CasGeneratorGenerateCasResponseTest.kt +++ /dev/null @@ -1,49 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.models.casgenerator - -import com.cas_parser.api.core.jsonMapper -import com.fasterxml.jackson.module.kotlin.jacksonTypeRef -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -internal class CasGeneratorGenerateCasResponseTest { - - @Test - fun create() { - val casGeneratorGenerateCasResponse = - CasGeneratorGenerateCasResponse.builder() - .msg( - "CAS generation request submitted successfully. The investor will receive the CAS file via email shortly." - ) - .status("success") - .build() - - assertThat(casGeneratorGenerateCasResponse.msg()) - .contains( - "CAS generation request submitted successfully. The investor will receive the CAS file via email shortly." - ) - assertThat(casGeneratorGenerateCasResponse.status()).contains("success") - } - - @Test - fun roundtrip() { - val jsonMapper = jsonMapper() - val casGeneratorGenerateCasResponse = - CasGeneratorGenerateCasResponse.builder() - .msg( - "CAS generation request submitted successfully. The investor will receive the CAS file via email shortly." - ) - .status("success") - .build() - - val roundtrippedCasGeneratorGenerateCasResponse = - jsonMapper.readValue( - jsonMapper.writeValueAsString(casGeneratorGenerateCasResponse), - jacksonTypeRef(), - ) - - assertThat(roundtrippedCasGeneratorGenerateCasResponse) - .isEqualTo(casGeneratorGenerateCasResponse) - } -} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CasGeneratorServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CasGeneratorServiceAsyncTest.kt deleted file mode 100644 index c74ed37..0000000 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CasGeneratorServiceAsyncTest.kt +++ /dev/null @@ -1,40 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.services.async - -import com.cas_parser.api.TestServerExtension -import com.cas_parser.api.client.okhttp.CasParserOkHttpClientAsync -import com.cas_parser.api.models.casgenerator.CasGeneratorGenerateCasParams -import org.junit.jupiter.api.Disabled -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith - -@ExtendWith(TestServerExtension::class) -internal class CasGeneratorServiceAsyncTest { - - @Disabled("Prism tests are disabled") - @Test - fun generateCas() { - val client = - CasParserOkHttpClientAsync.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() - val casGeneratorServiceAsync = client.casGenerator() - - val responseFuture = - casGeneratorServiceAsync.generateCas( - CasGeneratorGenerateCasParams.builder() - .email("user@example.com") - .fromDate("2023-01-01") - .password("Abcdefghi12\$") - .toDate("2023-12-31") - .casAuthority(CasGeneratorGenerateCasParams.CasAuthority.KFINTECH) - .panNo("ABCDE1234F") - .build() - ) - - val response = responseFuture.get() - response.validate() - } -} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CasGeneratorServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CasGeneratorServiceTest.kt deleted file mode 100644 index e66dcfb..0000000 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CasGeneratorServiceTest.kt +++ /dev/null @@ -1,39 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.services.blocking - -import com.cas_parser.api.TestServerExtension -import com.cas_parser.api.client.okhttp.CasParserOkHttpClient -import com.cas_parser.api.models.casgenerator.CasGeneratorGenerateCasParams -import org.junit.jupiter.api.Disabled -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith - -@ExtendWith(TestServerExtension::class) -internal class CasGeneratorServiceTest { - - @Disabled("Prism tests are disabled") - @Test - fun generateCas() { - val client = - CasParserOkHttpClient.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() - val casGeneratorService = client.casGenerator() - - val response = - casGeneratorService.generateCas( - CasGeneratorGenerateCasParams.builder() - .email("user@example.com") - .fromDate("2023-01-01") - .password("Abcdefghi12\$") - .toDate("2023-12-31") - .casAuthority(CasGeneratorGenerateCasParams.CasAuthority.KFINTECH) - .panNo("ABCDE1234F") - .build() - ) - - response.validate() - } -} From df10543d9461aa388d67437120ade7752a481acb Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 20 Jan 2026 02:17:26 +0000 Subject: [PATCH 24/99] feat(api): api update --- .github/workflows/ci.yml | 30 +++- .github/workflows/publish-sonatype.yml | 4 +- .github/workflows/release-doctor.yml | 2 +- .stats.yml | 4 +- README.md | 11 ++ .../main/kotlin/cas-parser.publish.gradle.kts | 8 + .../client/okhttp/CasParserOkHttpClient.kt | 22 +++ .../okhttp/CasParserOkHttpClientAsync.kt | 22 +++ .../api/client/okhttp/OkHttpClient.kt | 11 ++ cas-parser-java-core/build.gradle.kts | 18 ++- .../com/cas_parser/api/core/ObjectMappers.kt | 34 +++-- .../cas_parser/api/core/http/HttpRequest.kt | 30 ++++ .../api/core/http/RetryingHttpClient.kt | 20 +-- .../cas_parser/api/core/ObjectMappersTest.kt | 20 +-- .../api/core/http/HttpRequestTest.kt | 110 ++++++++++++++ .../build.gradle.kts | 2 +- scripts/upload-artifacts | 139 ++++++++++++++++++ 17 files changed, 429 insertions(+), 58 deletions(-) create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/HttpRequestTest.kt create mode 100755 scripts/upload-artifacts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index eedd0cf..30ff679 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,10 +20,10 @@ jobs: if: github.event_name == 'push' || github.event.pull_request.head.repo.fork steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Set up Java - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: temurin java-version: | @@ -40,14 +40,17 @@ jobs: build: timeout-minutes: 15 name: build + permissions: + contents: read + id-token: write runs-on: ${{ github.repository == 'stainless-sdks/cas-parser-java' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} if: github.event_name == 'push' || github.event.pull_request.head.repo.fork steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Set up Java - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: temurin java-version: | @@ -61,16 +64,31 @@ jobs: - name: Build SDK run: ./scripts/build + - name: Get GitHub OIDC Token + if: github.repository == 'stainless-sdks/cas-parser-java' + id: github-oidc + uses: actions/github-script@v6 + with: + script: core.setOutput('github_token', await core.getIDToken()); + + - name: Build and upload Maven artifacts + if: github.repository == 'stainless-sdks/cas-parser-java' + env: + URL: https://pkg.stainless.com/s + AUTH: ${{ steps.github-oidc.outputs.github_token }} + SHA: ${{ github.sha }} + PROJECT: cas-parser-java + run: ./scripts/upload-artifacts test: timeout-minutes: 15 name: test runs-on: ${{ github.repository == 'stainless-sdks/cas-parser-java' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} if: github.event_name == 'push' || github.event.pull_request.head.repo.fork steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Set up Java - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: temurin java-version: | diff --git a/.github/workflows/publish-sonatype.yml b/.github/workflows/publish-sonatype.yml index 1b11f45..2bfe3c5 100644 --- a/.github/workflows/publish-sonatype.yml +++ b/.github/workflows/publish-sonatype.yml @@ -14,10 +14,10 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Set up Java - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: temurin java-version: | diff --git a/.github/workflows/release-doctor.yml b/.github/workflows/release-doctor.yml index 87d49ed..a636804 100644 --- a/.github/workflows/release-doctor.yml +++ b/.github/workflows/release-doctor.yml @@ -12,7 +12,7 @@ jobs: if: github.repository == 'CASParser/cas-parser-java' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || startsWith(github.head_ref, 'release-please') || github.head_ref == 'next') steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Check release environment run: | diff --git a/.stats.yml b/.stats.yml index 4465de7..968a0a4 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 4 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-7e6397bddc220d1a59b5e2c7e7c3ff38f1a6eb174f4e383e03bc49cf78c8c44f.yml -openapi_spec_hash: cb852eeb4ce89c80f4246815cbe21f72 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-ce2296c4b14d27c141bb2745607d2456c923fdca3ae0a0a0800c26e564333850.yml +openapi_spec_hash: 8eb586ccf16b534c0c15ff6a22274c7d config_hash: cb5d75abef6264b5d86448caf7295afa diff --git a/README.md b/README.md index 878f4b9..3aed94e 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,15 @@ The Cas Parser Java SDK provides convenient access to the [Cas Parser REST API]( It is generated with [Stainless](https://www.stainless.com/). +## MCP Server + +Use the Cas Parser MCP Server to enable AI assistants to interact with this API, allowing them to explore endpoints, make test requests, and use documentation to help integrate this SDK into your application. + +[![Add to Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en-US/install-mcp?name=cas-parser-node-mcp&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsImNhcy1wYXJzZXItbm9kZS1tY3AiXX0) +[![Install in VS Code](https://img.shields.io/badge/_-Add_to_VS_Code-blue?style=for-the-badge&logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9Im5vbmUiIHZpZXdCb3g9IjAgMCA0MCA0MCI+PHBhdGggZmlsbD0iI0VFRSIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMzAuMjM1IDM5Ljg4NGEyLjQ5MSAyLjQ5MSAwIDAgMS0xLjc4MS0uNzNMMTIuNyAyNC43OGwtMy40NiAyLjYyNC0zLjQwNiAyLjU4MmExLjY2NSAxLjY2NSAwIDAgMS0xLjA4Mi4zMzggMS42NjQgMS42NjQgMCAwIDEtMS4wNDYtLjQzMWwtMi4yLTJhMS42NjYgMS42NjYgMCAwIDEgMC0yLjQ2M0w3LjQ1OCAyMCA0LjY3IDE3LjQ1MyAxLjUwNyAxNC41N2ExLjY2NSAxLjY2NSAwIDAgMSAwLTIuNDYzbDIuMi0yYTEuNjY1IDEuNjY1IDAgMCAxIDIuMTMtLjA5N2w2Ljg2MyA1LjIwOUwyOC40NTIuODQ0YTIuNDg4IDIuNDg4IDAgMCAxIDEuODQxLS43MjljLjM1MS4wMDkuNjk5LjA5MSAxLjAxOS4yNDVsOC4yMzYgMy45NjFhMi41IDIuNSAwIDAgMSAxLjQxNSAyLjI1M3YuMDk5LS4wNDVWMzMuMzd2LS4wNDUuMDk1YTIuNTAxIDIuNTAxIDAgMCAxLTEuNDE2IDIuMjU3bC04LjIzNSAzLjk2MWEyLjQ5MiAyLjQ5MiAwIDAgMS0xLjA3Ny4yNDZabS43MTYtMjguOTQ3LTExLjk0OCA5LjA2MiAxMS45NTIgOS4wNjUtLjAwNC0xOC4xMjdaIi8+PC9zdmc+)](https://vscode.stainless.com/mcp/%7B%22name%22%3A%22cas-parser-node-mcp%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22cas-parser-node-mcp%22%5D%7D) + +> Note: You may need to set environment variables in your MCP client. + The REST API documentation can be found on [docs.casparser.in](https://docs.casparser.in/reference). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.0.4). @@ -274,6 +283,8 @@ If the SDK threw an exception, but you're _certain_ the version is compatible, t > [!CAUTION] > We make no guarantee that the SDK works correctly when the Jackson version check is disabled. +Also note that there are bugs in older Jackson versions that can affect the SDK. We don't work around all Jackson bugs ([example](https://github.com/FasterXML/jackson-databind/issues/3240)) and expect users to upgrade Jackson for those instead. + ## Network options ### Retries diff --git a/buildSrc/src/main/kotlin/cas-parser.publish.gradle.kts b/buildSrc/src/main/kotlin/cas-parser.publish.gradle.kts index ef287d8..26aec10 100644 --- a/buildSrc/src/main/kotlin/cas-parser.publish.gradle.kts +++ b/buildSrc/src/main/kotlin/cas-parser.publish.gradle.kts @@ -40,6 +40,14 @@ configure { } } } + repositories { + if (project.hasProperty("publishLocal")) { + maven { + name = "LocalFileSystem" + url = uri("${rootProject.layout.buildDirectory.get()}/local-maven-repo") + } + } + } } signing { diff --git a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClient.kt b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClient.kt index f75536a..93a7aeb 100644 --- a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClient.kt +++ b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClient.kt @@ -16,6 +16,7 @@ import java.net.Proxy import java.time.Clock import java.time.Duration import java.util.Optional +import java.util.concurrent.ExecutorService import javax.net.ssl.HostnameVerifier import javax.net.ssl.SSLSocketFactory import javax.net.ssl.X509TrustManager @@ -44,11 +45,31 @@ class CasParserOkHttpClient private constructor() { class Builder internal constructor() { private var clientOptions: ClientOptions.Builder = ClientOptions.builder() + private var dispatcherExecutorService: ExecutorService? = null private var proxy: Proxy? = null private var sslSocketFactory: SSLSocketFactory? = null private var trustManager: X509TrustManager? = null private var hostnameVerifier: HostnameVerifier? = null + /** + * The executor service to use for running HTTP requests. + * + * Defaults to OkHttp's + * [default executor service](https://github.com/square/okhttp/blob/ace792f443b2ffb17974f5c0d1cecdf589309f26/okhttp/src/commonJvmAndroid/kotlin/okhttp3/Dispatcher.kt#L98-L104). + * + * This class takes ownership of the executor service and shuts it down when closed. + */ + fun dispatcherExecutorService(dispatcherExecutorService: ExecutorService?) = apply { + this.dispatcherExecutorService = dispatcherExecutorService + } + + /** + * Alias for calling [Builder.dispatcherExecutorService] with + * `dispatcherExecutorService.orElse(null)`. + */ + fun dispatcherExecutorService(dispatcherExecutorService: Optional) = + dispatcherExecutorService(dispatcherExecutorService.getOrNull()) + fun proxy(proxy: Proxy?) = apply { this.proxy = proxy } /** Alias for calling [Builder.proxy] with `proxy.orElse(null)`. */ @@ -297,6 +318,7 @@ class CasParserOkHttpClient private constructor() { OkHttpClient.builder() .timeout(clientOptions.timeout()) .proxy(proxy) + .dispatcherExecutorService(dispatcherExecutorService) .sslSocketFactory(sslSocketFactory) .trustManager(trustManager) .hostnameVerifier(hostnameVerifier) diff --git a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClientAsync.kt b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClientAsync.kt index 4142acc..f4858a0 100644 --- a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClientAsync.kt +++ b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClientAsync.kt @@ -16,6 +16,7 @@ import java.net.Proxy import java.time.Clock import java.time.Duration import java.util.Optional +import java.util.concurrent.ExecutorService import javax.net.ssl.HostnameVerifier import javax.net.ssl.SSLSocketFactory import javax.net.ssl.X509TrustManager @@ -44,11 +45,31 @@ class CasParserOkHttpClientAsync private constructor() { class Builder internal constructor() { private var clientOptions: ClientOptions.Builder = ClientOptions.builder() + private var dispatcherExecutorService: ExecutorService? = null private var proxy: Proxy? = null private var sslSocketFactory: SSLSocketFactory? = null private var trustManager: X509TrustManager? = null private var hostnameVerifier: HostnameVerifier? = null + /** + * The executor service to use for running HTTP requests. + * + * Defaults to OkHttp's + * [default executor service](https://github.com/square/okhttp/blob/ace792f443b2ffb17974f5c0d1cecdf589309f26/okhttp/src/commonJvmAndroid/kotlin/okhttp3/Dispatcher.kt#L98-L104). + * + * This class takes ownership of the executor service and shuts it down when closed. + */ + fun dispatcherExecutorService(dispatcherExecutorService: ExecutorService?) = apply { + this.dispatcherExecutorService = dispatcherExecutorService + } + + /** + * Alias for calling [Builder.dispatcherExecutorService] with + * `dispatcherExecutorService.orElse(null)`. + */ + fun dispatcherExecutorService(dispatcherExecutorService: Optional) = + dispatcherExecutorService(dispatcherExecutorService.getOrNull()) + fun proxy(proxy: Proxy?) = apply { this.proxy = proxy } /** Alias for calling [Builder.proxy] with `proxy.orElse(null)`. */ @@ -297,6 +318,7 @@ class CasParserOkHttpClientAsync private constructor() { OkHttpClient.builder() .timeout(clientOptions.timeout()) .proxy(proxy) + .dispatcherExecutorService(dispatcherExecutorService) .sslSocketFactory(sslSocketFactory) .trustManager(trustManager) .hostnameVerifier(hostnameVerifier) diff --git a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/OkHttpClient.kt b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/OkHttpClient.kt index eee1317..7079d3c 100644 --- a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/OkHttpClient.kt +++ b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/OkHttpClient.kt @@ -15,11 +15,13 @@ import java.net.Proxy import java.time.Duration import java.util.concurrent.CancellationException import java.util.concurrent.CompletableFuture +import java.util.concurrent.ExecutorService import javax.net.ssl.HostnameVerifier import javax.net.ssl.SSLSocketFactory import javax.net.ssl.X509TrustManager import okhttp3.Call import okhttp3.Callback +import okhttp3.Dispatcher import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.MediaType import okhttp3.MediaType.Companion.toMediaType @@ -198,6 +200,7 @@ private constructor(@JvmSynthetic internal val okHttpClient: okhttp3.OkHttpClien private var timeout: Timeout = Timeout.default() private var proxy: Proxy? = null + private var dispatcherExecutorService: ExecutorService? = null private var sslSocketFactory: SSLSocketFactory? = null private var trustManager: X509TrustManager? = null private var hostnameVerifier: HostnameVerifier? = null @@ -208,6 +211,10 @@ private constructor(@JvmSynthetic internal val okHttpClient: okhttp3.OkHttpClien fun proxy(proxy: Proxy?) = apply { this.proxy = proxy } + fun dispatcherExecutorService(dispatcherExecutorService: ExecutorService?) = apply { + this.dispatcherExecutorService = dispatcherExecutorService + } + fun sslSocketFactory(sslSocketFactory: SSLSocketFactory?) = apply { this.sslSocketFactory = sslSocketFactory } @@ -223,12 +230,16 @@ private constructor(@JvmSynthetic internal val okHttpClient: okhttp3.OkHttpClien fun build(): OkHttpClient = OkHttpClient( okhttp3.OkHttpClient.Builder() + // `RetryingHttpClient` handles retries if the user enabled them. + .retryOnConnectionFailure(false) .connectTimeout(timeout.connect()) .readTimeout(timeout.read()) .writeTimeout(timeout.write()) .callTimeout(timeout.request()) .proxy(proxy) .apply { + dispatcherExecutorService?.let { dispatcher(Dispatcher(it)) } + val sslSocketFactory = sslSocketFactory val trustManager = trustManager if (sslSocketFactory != null && trustManager != null) { diff --git a/cas-parser-java-core/build.gradle.kts b/cas-parser-java-core/build.gradle.kts index 9861d5b..7d1eeed 100644 --- a/cas-parser-java-core/build.gradle.kts +++ b/cas-parser-java-core/build.gradle.kts @@ -5,14 +5,16 @@ plugins { configurations.all { resolutionStrategy { - // Compile and test against a lower Jackson version to ensure we're compatible with it. - // We publish with a higher version (see below) to ensure users depend on a secure version by default. - force("com.fasterxml.jackson.core:jackson-core:2.13.4") - force("com.fasterxml.jackson.core:jackson-databind:2.13.4") - force("com.fasterxml.jackson.core:jackson-annotations:2.13.4") - force("com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.13.4") - force("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.4") - force("com.fasterxml.jackson.module:jackson-module-kotlin:2.13.4") + // Compile and test against a lower Jackson version to ensure we're compatible with it. Note that + // we generally support 2.13.4, but test against 2.14.0 because 2.13.4 has some annoying (but + // niche) bugs (users should upgrade if they encounter them). We publish with a higher version + // (see below) to ensure users depend on a secure version by default. + force("com.fasterxml.jackson.core:jackson-core:2.14.0") + force("com.fasterxml.jackson.core:jackson-databind:2.14.0") + force("com.fasterxml.jackson.core:jackson-annotations:2.14.0") + force("com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.14.0") + force("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.14.0") + force("com.fasterxml.jackson.module:jackson-module-kotlin:2.14.0") } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ObjectMappers.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ObjectMappers.kt index 85d0b7e..9096f88 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ObjectMappers.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ObjectMappers.kt @@ -24,6 +24,7 @@ import java.io.InputStream import java.time.DateTimeException import java.time.LocalDate import java.time.LocalDateTime +import java.time.OffsetDateTime import java.time.ZonedDateTime import java.time.format.DateTimeFormatter import java.time.temporal.ChronoField @@ -36,7 +37,7 @@ fun jsonMapper(): JsonMapper = .addModule( SimpleModule() .addSerializer(InputStreamSerializer) - .addDeserializer(LocalDateTime::class.java, LenientLocalDateTimeDeserializer()) + .addDeserializer(OffsetDateTime::class.java, LenientOffsetDateTimeDeserializer()) ) .withCoercionConfig(LogicalType.Boolean) { it.setCoercion(CoercionInputShape.Integer, CoercionAction.Fail) @@ -47,6 +48,7 @@ fun jsonMapper(): JsonMapper = } .withCoercionConfig(LogicalType.Integer) { it.setCoercion(CoercionInputShape.Boolean, CoercionAction.Fail) + .setCoercion(CoercionInputShape.Float, CoercionAction.Fail) .setCoercion(CoercionInputShape.String, CoercionAction.Fail) .setCoercion(CoercionInputShape.Array, CoercionAction.Fail) .setCoercion(CoercionInputShape.Object, CoercionAction.Fail) @@ -64,6 +66,12 @@ fun jsonMapper(): JsonMapper = .setCoercion(CoercionInputShape.Array, CoercionAction.Fail) .setCoercion(CoercionInputShape.Object, CoercionAction.Fail) } + .withCoercionConfig(LogicalType.DateTime) { + it.setCoercion(CoercionInputShape.Integer, CoercionAction.Fail) + .setCoercion(CoercionInputShape.Float, CoercionAction.Fail) + .setCoercion(CoercionInputShape.Array, CoercionAction.Fail) + .setCoercion(CoercionInputShape.Object, CoercionAction.Fail) + } .withCoercionConfig(LogicalType.Array) { it.setCoercion(CoercionInputShape.Boolean, CoercionAction.Fail) .setCoercion(CoercionInputShape.Integer, CoercionAction.Fail) @@ -124,10 +132,10 @@ private object InputStreamSerializer : BaseSerializer(InputStream:: } /** - * A deserializer that can deserialize [LocalDateTime] from datetimes, dates, and zoned datetimes. + * A deserializer that can deserialize [OffsetDateTime] from datetimes, dates, and zoned datetimes. */ -private class LenientLocalDateTimeDeserializer : - StdDeserializer(LocalDateTime::class.java) { +private class LenientOffsetDateTimeDeserializer : + StdDeserializer(OffsetDateTime::class.java) { companion object { @@ -141,7 +149,7 @@ private class LenientLocalDateTimeDeserializer : override fun logicalType(): LogicalType = LogicalType.DateTime - override fun deserialize(p: JsonParser, context: DeserializationContext?): LocalDateTime { + override fun deserialize(p: JsonParser, context: DeserializationContext): OffsetDateTime { val exceptions = mutableListOf() for (formatter in DATE_TIME_FORMATTERS) { @@ -149,18 +157,20 @@ private class LenientLocalDateTimeDeserializer : val temporal = formatter.parse(p.text) return when { - !temporal.isSupported(ChronoField.HOUR_OF_DAY) -> - LocalDate.from(temporal).atStartOfDay() - !temporal.isSupported(ChronoField.OFFSET_SECONDS) -> - LocalDateTime.from(temporal) - else -> ZonedDateTime.from(temporal).toLocalDateTime() - } + !temporal.isSupported(ChronoField.HOUR_OF_DAY) -> + LocalDate.from(temporal).atStartOfDay() + !temporal.isSupported(ChronoField.OFFSET_SECONDS) -> + LocalDateTime.from(temporal) + else -> ZonedDateTime.from(temporal).toLocalDateTime() + } + .atZone(context.timeZone.toZoneId()) + .toOffsetDateTime() } catch (e: DateTimeException) { exceptions.add(e) } } - throw JsonParseException(p, "Cannot parse `LocalDateTime` from value: ${p.text}").apply { + throw JsonParseException(p, "Cannot parse `OffsetDateTime` from value: ${p.text}").apply { exceptions.forEach { addSuppressed(it) } } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/HttpRequest.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/HttpRequest.kt index 7301769..9679caa 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/HttpRequest.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/HttpRequest.kt @@ -2,6 +2,7 @@ package com.cas_parser.api.core.http import com.cas_parser.api.core.checkRequired import com.cas_parser.api.core.toImmutable +import java.net.URLEncoder class HttpRequest private constructor( @@ -13,6 +14,35 @@ private constructor( @get:JvmName("body") val body: HttpRequestBody?, ) { + fun url(): String = buildString { + append(baseUrl) + + pathSegments.forEach { segment -> + if (!endsWith("/")) { + append("/") + } + append(URLEncoder.encode(segment, "UTF-8")) + } + + if (queryParams.isEmpty()) { + return@buildString + } + + append("?") + var isFirst = true + queryParams.keys().forEach { key -> + queryParams.values(key).forEach { value -> + if (!isFirst) { + append("&") + } + append(URLEncoder.encode(key, "UTF-8")) + append("=") + append(URLEncoder.encode(value, "UTF-8")) + isFirst = false + } + } + } + fun toBuilder(): Builder = Builder().from(this) override fun toString(): String = diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/RetryingHttpClient.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/RetryingHttpClient.kt index 2bf9815..3f34f6e 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/RetryingHttpClient.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/RetryingHttpClient.kt @@ -31,10 +31,6 @@ private constructor( ) : HttpClient { override fun execute(request: HttpRequest, requestOptions: RequestOptions): HttpResponse { - if (!isRetryable(request) || maxRetries <= 0) { - return httpClient.execute(request, requestOptions) - } - var modifiedRequest = maybeAddIdempotencyHeader(request) // Don't send the current retry count in the headers if the caller set their own value. @@ -48,6 +44,10 @@ private constructor( modifiedRequest = setRetryCountHeader(modifiedRequest, retries) } + if (!isRetryable(modifiedRequest)) { + return httpClient.execute(modifiedRequest, requestOptions) + } + val response = try { val response = httpClient.execute(modifiedRequest, requestOptions) @@ -75,10 +75,6 @@ private constructor( request: HttpRequest, requestOptions: RequestOptions, ): CompletableFuture { - if (!isRetryable(request) || maxRetries <= 0) { - return httpClient.executeAsync(request, requestOptions) - } - val modifiedRequest = maybeAddIdempotencyHeader(request) // Don't send the current retry count in the headers if the caller set their own value. @@ -94,8 +90,12 @@ private constructor( val requestWithRetryCount = if (shouldSendRetryCount) setRetryCountHeader(request, retries) else request - return httpClient - .executeAsync(requestWithRetryCount, requestOptions) + val responseFuture = httpClient.executeAsync(requestWithRetryCount, requestOptions) + if (!isRetryable(requestWithRetryCount)) { + return responseFuture + } + + return responseFuture .handleAsync( fun( response: HttpResponse?, diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/ObjectMappersTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/ObjectMappersTest.kt index c338d17..93a6a00 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/ObjectMappersTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/ObjectMappersTest.kt @@ -3,7 +3,7 @@ package com.cas_parser.api.core import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.databind.exc.MismatchedInputException import com.fasterxml.jackson.module.kotlin.readValue -import java.time.LocalDateTime +import java.time.OffsetDateTime import kotlin.reflect.KClass import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.catchThrowable @@ -46,11 +46,7 @@ internal class ObjectMappersTest { val VALID_CONVERSIONS = listOf( FLOAT to DOUBLE, - FLOAT to INTEGER, - FLOAT to LONG, DOUBLE to FLOAT, - DOUBLE to INTEGER, - DOUBLE to LONG, INTEGER to FLOAT, INTEGER to DOUBLE, INTEGER to LONG, @@ -58,14 +54,6 @@ internal class ObjectMappersTest { LONG to DOUBLE, LONG to INTEGER, CLASS to MAP, - // These aren't actually valid, but coercion configs don't work for String until - // v2.14.0: https://github.com/FasterXML/jackson-databind/issues/3240 - // We currently test on v2.13.4. - BOOLEAN to STRING, - FLOAT to STRING, - DOUBLE to STRING, - INTEGER to STRING, - LONG to STRING, ) } } @@ -84,7 +72,7 @@ internal class ObjectMappersTest { } } - enum class LenientLocalDateTimeTestCase(val string: String) { + enum class LenientOffsetDateTimeTestCase(val string: String) { DATE("1998-04-21"), DATE_TIME("1998-04-21T04:00:00"), ZONED_DATE_TIME_1("1998-04-21T04:00:00+03:00"), @@ -93,10 +81,10 @@ internal class ObjectMappersTest { @ParameterizedTest @EnumSource - fun readLocalDateTime_lenient(testCase: LenientLocalDateTimeTestCase) { + fun readOffsetDateTime_lenient(testCase: LenientOffsetDateTimeTestCase) { val jsonMapper = jsonMapper() val json = jsonMapper.writeValueAsString(testCase.string) - assertDoesNotThrow { jsonMapper().readValue(json) } + assertDoesNotThrow { jsonMapper().readValue(json) } } } diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/HttpRequestTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/HttpRequestTest.kt new file mode 100644 index 0000000..06e315d --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/HttpRequestTest.kt @@ -0,0 +1,110 @@ +package com.cas_parser.api.core.http + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.EnumSource + +internal class HttpRequestTest { + + enum class UrlTestCase(val request: HttpRequest, val expectedUrl: String) { + BASE_URL_ONLY( + HttpRequest.builder().method(HttpMethod.GET).baseUrl("https://api.example.com").build(), + expectedUrl = "https://api.example.com", + ), + BASE_URL_WITH_TRAILING_SLASH( + HttpRequest.builder() + .method(HttpMethod.GET) + .baseUrl("https://api.example.com/") + .build(), + expectedUrl = "https://api.example.com/", + ), + SINGLE_PATH_SEGMENT( + HttpRequest.builder() + .method(HttpMethod.GET) + .baseUrl("https://api.example.com") + .addPathSegment("users") + .build(), + expectedUrl = "https://api.example.com/users", + ), + MULTIPLE_PATH_SEGMENTS( + HttpRequest.builder() + .method(HttpMethod.GET) + .baseUrl("https://api.example.com") + .addPathSegments("users", "123", "profile") + .build(), + expectedUrl = "https://api.example.com/users/123/profile", + ), + PATH_SEGMENT_WITH_SPECIAL_CHARS( + HttpRequest.builder() + .method(HttpMethod.GET) + .baseUrl("https://api.example.com") + .addPathSegment("user name") + .build(), + expectedUrl = "https://api.example.com/user+name", + ), + SINGLE_QUERY_PARAM( + HttpRequest.builder() + .method(HttpMethod.GET) + .baseUrl("https://api.example.com") + .addPathSegment("users") + .putQueryParam("limit", "10") + .build(), + expectedUrl = "https://api.example.com/users?limit=10", + ), + MULTIPLE_QUERY_PARAMS( + HttpRequest.builder() + .method(HttpMethod.GET) + .baseUrl("https://api.example.com") + .addPathSegment("users") + .putQueryParam("limit", "10") + .putQueryParam("offset", "20") + .build(), + expectedUrl = "https://api.example.com/users?limit=10&offset=20", + ), + QUERY_PARAM_WITH_SPECIAL_CHARS( + HttpRequest.builder() + .method(HttpMethod.GET) + .baseUrl("https://api.example.com") + .addPathSegment("search") + .putQueryParam("q", "hello world") + .build(), + expectedUrl = "https://api.example.com/search?q=hello+world", + ), + MULTIPLE_VALUES_SAME_PARAM( + HttpRequest.builder() + .method(HttpMethod.GET) + .baseUrl("https://api.example.com") + .addPathSegment("users") + .putQueryParams("tags", listOf("admin", "user")) + .build(), + expectedUrl = "https://api.example.com/users?tags=admin&tags=user", + ), + BASE_URL_WITH_TRAILING_SLASH_AND_PATH( + HttpRequest.builder() + .method(HttpMethod.GET) + .baseUrl("https://api.example.com/") + .addPathSegment("users") + .build(), + expectedUrl = "https://api.example.com/users", + ), + COMPLEX_URL( + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl("https://api.example.com") + .addPathSegments("v1", "users", "123") + .putQueryParams("include", listOf("profile", "settings")) + .putQueryParam("format", "json") + .build(), + expectedUrl = + "https://api.example.com/v1/users/123?include=profile&include=settings&format=json", + ), + } + + @ParameterizedTest + @EnumSource + fun url(testCase: UrlTestCase) { + val actualUrl = testCase.request.url() + + assertThat(actualUrl).isEqualTo(testCase.expectedUrl) + } +} diff --git a/cas-parser-java-proguard-test/build.gradle.kts b/cas-parser-java-proguard-test/build.gradle.kts index de62f9c..bc6de2d 100644 --- a/cas-parser-java-proguard-test/build.gradle.kts +++ b/cas-parser-java-proguard-test/build.gradle.kts @@ -19,7 +19,7 @@ dependencies { testImplementation(kotlin("test")) testImplementation("org.junit.jupiter:junit-jupiter-api:5.9.3") testImplementation("org.assertj:assertj-core:3.25.3") - testImplementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.13.4") + testImplementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.14.0") } tasks.shadowJar { diff --git a/scripts/upload-artifacts b/scripts/upload-artifacts new file mode 100755 index 0000000..548d152 --- /dev/null +++ b/scripts/upload-artifacts @@ -0,0 +1,139 @@ +#!/usr/bin/env bash + +set -euo pipefail + +# ANSI Color Codes +GREEN='\033[32m' +RED='\033[31m' +NC='\033[0m' # No Color + +MAVEN_REPO_PATH="./build/local-maven-repo" + +log_error() { + local msg="$1" + local headers="$2" + local body="$3" + echo -e "${RED}${msg}${NC}" + [[ -f "$headers" ]] && echo -e "${RED}Headers:$(cat "$headers")${NC}" + echo -e "${RED}Body: ${body}${NC}" + exit 1 +} + +upload_file() { + local file_name="$1" + local tmp_headers + tmp_headers=$(mktemp) + + if [ -f "$file_name" ]; then + echo -e "${GREEN}Processing file: $file_name${NC}" + pkg_file_name="mvn${file_name#"${MAVEN_REPO_PATH}"}" + + # Get signed URL for uploading artifact file + signed_url_response=$(curl -X POST -G "$URL" \ + -sS --retry 5 \ + -D "$tmp_headers" \ + --data-urlencode "filename=$pkg_file_name" \ + -H "Authorization: Bearer $AUTH" \ + -H "Content-Type: application/json") + + # Validate JSON and extract URL + if ! signed_url=$(echo "$signed_url_response" | jq -e -r '.url' 2>/dev/null) || [[ "$signed_url" == "null" ]]; then + log_error "Failed to get valid signed URL" "$tmp_headers" "$signed_url_response" + fi + + # Set content-type based on file extension + local extension="${file_name##*.}" + local content_type + case "$extension" in + jar) content_type="application/java-archive" ;; + md5|sha1|sha256|sha512) content_type="text/plain" ;; + module) content_type="application/json" ;; + pom|xml) content_type="application/xml" ;; + html) content_type="text/html" ;; + *) content_type="application/octet-stream" ;; + esac + + # Upload file + upload_response=$(curl -v -X PUT \ + --retry 5 \ + --retry-all-errors \ + -D "$tmp_headers" \ + -H "Content-Type: $content_type" \ + --data-binary "@${file_name}" "$signed_url" 2>&1) + + if ! echo "$upload_response" | grep -q "HTTP/[0-9.]* 200"; then + log_error "Failed to upload artifact file" "$tmp_headers" "$upload_response" + fi + + # Insert small throttle to reduce rate limiting risk + sleep 0.1 + fi +} + +walk_tree() { + local current_dir="$1" + + for entry in "$current_dir"/*; do + # Check that entry is valid + [ -e "$entry" ] || [ -h "$entry" ] || continue + + if [ -d "$entry" ]; then + walk_tree "$entry" + else + upload_file "$entry" + fi + done +} + +generate_instructions() { + cat << EOF > "$MAVEN_REPO_PATH/index.html" + + + + Maven Repo + + +

Stainless SDK Maven Repository

+

This is the Maven repository for your Stainless Java SDK build.

+ +

Directions

+

To use the uploaded Maven repository, add the following to your project's pom.xml:

+
<repositories>
+    <repository>
+        <id>stainless-sdk-repo</id>
+        <url>https://pkg.stainless.com/s/${PROJECT}/${SHA}/mvn</url>
+    </repository>
+</repositories>
+ +

If you're using Gradle, add the following to your build.gradle file:

+
repositories {
+    maven {
+        url 'https://pkg.stainless.com/s/${PROJECT}/${SHA}/mvn'
+    }
+}
+ +

Once you've added the repository, you can include dependencies from it as usual. See your + project README + for more details.

+ + +EOF + upload_file "${MAVEN_REPO_PATH}/index.html" + + echo "Configure maven or gradle to use the repo located at 'https://pkg.stainless.com/s/${PROJECT}/${SHA}/mvn'" + echo "For more details, see the directions in https://pkg.stainless.com/s/${PROJECT}/${SHA}/mvn/index.html" +} + +cd "$(dirname "$0")/.." + +echo "::group::Creating local Maven content" +./gradlew publishMavenPublicationToLocalFileSystemRepository -PpublishLocal +echo "::endgroup::" + +echo "::group::Uploading to pkg.stainless.com" +walk_tree "$MAVEN_REPO_PATH" +echo "::endgroup::" + +echo "::group::Generating instructions" +generate_instructions +echo "::endgroup::" From 37c75add80583ebd72906269a05b7c34c60ad795 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sun, 1 Feb 2026 04:17:16 +0000 Subject: [PATCH 25/99] feat(api): api update --- .github/workflows/ci.yml | 2 +- .stats.yml | 4 +- README.md | 4 +- .../main/kotlin/cas-parser.kotlin.gradle.kts | 3 + .../com/cas_parser/api/core/ClientOptions.kt | 1 + .../com/cas_parser/api/core/ObjectMappers.kt | 19 +++--- .../api/models/casparser/UnifiedResponse.kt | 19 +++++- .../cas_parser/api/core/ObjectMappersTest.kt | 41 ++++++++++-- scripts/build | 2 +- scripts/upload-artifacts | 64 +++++++++++++++++-- 10 files changed, 130 insertions(+), 29 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 30ff679..2d1e49c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -67,7 +67,7 @@ jobs: - name: Get GitHub OIDC Token if: github.repository == 'stainless-sdks/cas-parser-java' id: github-oidc - uses: actions/github-script@v6 + uses: actions/github-script@v8 with: script: core.setOutput('github_token', await core.getIDToken()); diff --git a/.stats.yml b/.stats.yml index 968a0a4..9cc4732 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 4 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-ce2296c4b14d27c141bb2745607d2456c923fdca3ae0a0a0800c26e564333850.yml -openapi_spec_hash: 8eb586ccf16b534c0c15ff6a22274c7d +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-2e3df9c77e887f49ca3dffd5d68f30a8a0ea0b557f31282dd191ce85713e3e34.yml +openapi_spec_hash: 1cb90023118602a40a106cd51ed6a926 config_hash: cb5d75abef6264b5d86448caf7295afa diff --git a/README.md b/README.md index 3aed94e..aca8f7f 100644 --- a/README.md +++ b/README.md @@ -15,8 +15,8 @@ It is generated with [Stainless](https://www.stainless.com/). Use the Cas Parser MCP Server to enable AI assistants to interact with this API, allowing them to explore endpoints, make test requests, and use documentation to help integrate this SDK into your application. -[![Add to Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en-US/install-mcp?name=cas-parser-node-mcp&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsImNhcy1wYXJzZXItbm9kZS1tY3AiXX0) -[![Install in VS Code](https://img.shields.io/badge/_-Add_to_VS_Code-blue?style=for-the-badge&logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9Im5vbmUiIHZpZXdCb3g9IjAgMCA0MCA0MCI+PHBhdGggZmlsbD0iI0VFRSIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMzAuMjM1IDM5Ljg4NGEyLjQ5MSAyLjQ5MSAwIDAgMS0xLjc4MS0uNzNMMTIuNyAyNC43OGwtMy40NiAyLjYyNC0zLjQwNiAyLjU4MmExLjY2NSAxLjY2NSAwIDAgMS0xLjA4Mi4zMzggMS42NjQgMS42NjQgMCAwIDEtMS4wNDYtLjQzMWwtMi4yLTJhMS42NjYgMS42NjYgMCAwIDEgMC0yLjQ2M0w3LjQ1OCAyMCA0LjY3IDE3LjQ1MyAxLjUwNyAxNC41N2ExLjY2NSAxLjY2NSAwIDAgMSAwLTIuNDYzbDIuMi0yYTEuNjY1IDEuNjY1IDAgMCAxIDIuMTMtLjA5N2w2Ljg2MyA1LjIwOUwyOC40NTIuODQ0YTIuNDg4IDIuNDg4IDAgMCAxIDEuODQxLS43MjljLjM1MS4wMDkuNjk5LjA5MSAxLjAxOS4yNDVsOC4yMzYgMy45NjFhMi41IDIuNSAwIDAgMSAxLjQxNSAyLjI1M3YuMDk5LS4wNDVWMzMuMzd2LS4wNDUuMDk1YTIuNTAxIDIuNTAxIDAgMCAxLTEuNDE2IDIuMjU3bC04LjIzNSAzLjk2MWEyLjQ5MiAyLjQ5MiAwIDAgMS0xLjA3Ny4yNDZabS43MTYtMjguOTQ3LTExLjk0OCA5LjA2MiAxMS45NTIgOS4wNjUtLjAwNC0xOC4xMjdaIi8+PC9zdmc+)](https://vscode.stainless.com/mcp/%7B%22name%22%3A%22cas-parser-node-mcp%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22cas-parser-node-mcp%22%5D%7D) +[![Add to Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en-US/install-mcp?name=cas-parser-node-mcp&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsImNhcy1wYXJzZXItbm9kZS1tY3AiXSwiZW52Ijp7IkNBU19QQVJTRVJfQVBJX0tFWSI6Ik15IEFQSSBLZXkifX0) +[![Install in VS Code](https://img.shields.io/badge/_-Add_to_VS_Code-blue?style=for-the-badge&logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9Im5vbmUiIHZpZXdCb3g9IjAgMCA0MCA0MCI+PHBhdGggZmlsbD0iI0VFRSIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMzAuMjM1IDM5Ljg4NGEyLjQ5MSAyLjQ5MSAwIDAgMS0xLjc4MS0uNzNMMTIuNyAyNC43OGwtMy40NiAyLjYyNC0zLjQwNiAyLjU4MmExLjY2NSAxLjY2NSAwIDAgMS0xLjA4Mi4zMzggMS42NjQgMS42NjQgMCAwIDEtMS4wNDYtLjQzMWwtMi4yLTJhMS42NjYgMS42NjYgMCAwIDEgMC0yLjQ2M0w3LjQ1OCAyMCA0LjY3IDE3LjQ1MyAxLjUwNyAxNC41N2ExLjY2NSAxLjY2NSAwIDAgMSAwLTIuNDYzbDIuMi0yYTEuNjY1IDEuNjY1IDAgMCAxIDIuMTMtLjA5N2w2Ljg2MyA1LjIwOUwyOC40NTIuODQ0YTIuNDg4IDIuNDg4IDAgMCAxIDEuODQxLS43MjljLjM1MS4wMDkuNjk5LjA5MSAxLjAxOS4yNDVsOC4yMzYgMy45NjFhMi41IDIuNSAwIDAgMSAxLjQxNSAyLjI1M3YuMDk5LS4wNDVWMzMuMzd2LS4wNDUuMDk1YTIuNTAxIDIuNTAxIDAgMCAxLTEuNDE2IDIuMjU3bC04LjIzNSAzLjk2MWEyLjQ5MiAyLjQ5MiAwIDAgMS0xLjA3Ny4yNDZabS43MTYtMjguOTQ3LTExLjk0OCA5LjA2MiAxMS45NTIgOS4wNjUtLjAwNC0xOC4xMjdaIi8+PC9zdmc+)](https://vscode.stainless.com/mcp/%7B%22name%22%3A%22cas-parser-node-mcp%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22cas-parser-node-mcp%22%5D%2C%22env%22%3A%7B%22CAS_PARSER_API_KEY%22%3A%22My%20API%20Key%22%7D%7D) > Note: You may need to set environment variables in your MCP client. diff --git a/buildSrc/src/main/kotlin/cas-parser.kotlin.gradle.kts b/buildSrc/src/main/kotlin/cas-parser.kotlin.gradle.kts index 89a07ea..f1fa5f4 100644 --- a/buildSrc/src/main/kotlin/cas-parser.kotlin.gradle.kts +++ b/buildSrc/src/main/kotlin/cas-parser.kotlin.gradle.kts @@ -33,6 +33,9 @@ kotlin { tasks.withType().configureEach { systemProperty("junit.jupiter.execution.parallel.enabled", true) systemProperty("junit.jupiter.execution.parallel.mode.default", "concurrent") + + // `SKIP_MOCK_TESTS` affects which tests run so it must be added as input for proper cache invalidation. + inputs.property("skipMockTests", System.getenv("SKIP_MOCK_TESTS")).optional(true) } val ktfmt by configurations.creating diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ClientOptions.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ClientOptions.kt index f5195cd..1db211b 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ClientOptions.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ClientOptions.kt @@ -404,6 +404,7 @@ private constructor( headers.put("X-Stainless-Package-Version", getPackageVersion()) headers.put("X-Stainless-Runtime", "JRE") headers.put("X-Stainless-Runtime-Version", getJavaVersion()) + headers.put("X-Stainless-Kotlin-Version", KotlinVersion.CURRENT.toString()) apiKey.let { if (!it.isEmpty()) { headers.put("x-api-key", it) diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ObjectMappers.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ObjectMappers.kt index 9096f88..e067f70 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ObjectMappers.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ObjectMappers.kt @@ -25,7 +25,7 @@ import java.time.DateTimeException import java.time.LocalDate import java.time.LocalDateTime import java.time.OffsetDateTime -import java.time.ZonedDateTime +import java.time.ZoneId import java.time.format.DateTimeFormatter import java.time.temporal.ChronoField @@ -157,14 +157,15 @@ private class LenientOffsetDateTimeDeserializer : val temporal = formatter.parse(p.text) return when { - !temporal.isSupported(ChronoField.HOUR_OF_DAY) -> - LocalDate.from(temporal).atStartOfDay() - !temporal.isSupported(ChronoField.OFFSET_SECONDS) -> - LocalDateTime.from(temporal) - else -> ZonedDateTime.from(temporal).toLocalDateTime() - } - .atZone(context.timeZone.toZoneId()) - .toOffsetDateTime() + !temporal.isSupported(ChronoField.HOUR_OF_DAY) -> + LocalDate.from(temporal) + .atStartOfDay() + .atZone(ZoneId.of("UTC")) + .toOffsetDateTime() + !temporal.isSupported(ChronoField.OFFSET_SECONDS) -> + LocalDateTime.from(temporal).atZone(ZoneId.of("UTC")).toOffsetDateTime() + else -> OffsetDateTime.from(temporal) + } } catch (e: DateTimeException) { exceptions.add(e) } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/UnifiedResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/UnifiedResponse.kt index e64ebfb..40030b6 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/UnifiedResponse.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/UnifiedResponse.kt @@ -11312,7 +11312,15 @@ private constructor( mutableMapOf(), ) - /** Additional information specific to the policy */ + /** + * Additional information specific to the policy + * + * This arbitrary value can be deserialized into a custom type using the `convert` + * method: + * ```java + * MyClass myObject = lifeInsurancePolicy.additionalInfo().convert(MyClass.class); + * ``` + */ @JsonProperty("additional_info") @ExcludeMissing fun _additionalInfo(): JsonValue = additionalInfo @@ -15959,7 +15967,14 @@ private constructor( @JsonProperty("value") @ExcludeMissing value: JsonField = JsonMissing.of(), ) : this(additionalInfo, cra, funds, linkedHolders, pran, value, mutableMapOf()) - /** Additional information specific to the NPS account */ + /** + * Additional information specific to the NPS account + * + * This arbitrary value can be deserialized into a custom type using the `convert` method: + * ```java + * MyClass myObject = np.additionalInfo().convert(MyClass.class); + * ``` + */ @JsonProperty("additional_info") @ExcludeMissing fun _additionalInfo(): JsonValue = additionalInfo diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/ObjectMappersTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/ObjectMappersTest.kt index 93a6a00..8010442 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/ObjectMappersTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/ObjectMappersTest.kt @@ -3,12 +3,14 @@ package com.cas_parser.api.core import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.databind.exc.MismatchedInputException import com.fasterxml.jackson.module.kotlin.readValue +import java.time.LocalDate +import java.time.LocalTime import java.time.OffsetDateTime +import java.time.ZoneOffset import kotlin.reflect.KClass import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.catchThrowable import org.junit.jupiter.api.Test -import org.junit.jupiter.api.assertDoesNotThrow import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.EnumSource import org.junitpioneer.jupiter.cartesian.CartesianTest @@ -72,11 +74,34 @@ internal class ObjectMappersTest { } } - enum class LenientOffsetDateTimeTestCase(val string: String) { - DATE("1998-04-21"), - DATE_TIME("1998-04-21T04:00:00"), - ZONED_DATE_TIME_1("1998-04-21T04:00:00+03:00"), - ZONED_DATE_TIME_2("1998-04-21T04:00:00Z"), + enum class LenientOffsetDateTimeTestCase( + val string: String, + val expectedOffsetDateTime: OffsetDateTime, + ) { + DATE( + "1998-04-21", + expectedOffsetDateTime = + OffsetDateTime.of(LocalDate.of(1998, 4, 21), LocalTime.of(0, 0), ZoneOffset.UTC), + ), + DATE_TIME( + "1998-04-21T04:00:00", + expectedOffsetDateTime = + OffsetDateTime.of(LocalDate.of(1998, 4, 21), LocalTime.of(4, 0), ZoneOffset.UTC), + ), + ZONED_DATE_TIME_1( + "1998-04-21T04:00:00+03:00", + expectedOffsetDateTime = + OffsetDateTime.of( + LocalDate.of(1998, 4, 21), + LocalTime.of(4, 0), + ZoneOffset.ofHours(3), + ), + ), + ZONED_DATE_TIME_2( + "1998-04-21T04:00:00Z", + expectedOffsetDateTime = + OffsetDateTime.of(LocalDate.of(1998, 4, 21), LocalTime.of(4, 0), ZoneOffset.UTC), + ), } @ParameterizedTest @@ -85,6 +110,8 @@ internal class ObjectMappersTest { val jsonMapper = jsonMapper() val json = jsonMapper.writeValueAsString(testCase.string) - assertDoesNotThrow { jsonMapper().readValue(json) } + val offsetDateTime = jsonMapper().readValue(json) + + assertThat(offsetDateTime).isEqualTo(testCase.expectedOffsetDateTime) } } diff --git a/scripts/build b/scripts/build index f406348..16a2b00 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 diff --git a/scripts/upload-artifacts b/scripts/upload-artifacts index 548d152..10f3c70 100755 --- a/scripts/upload-artifacts +++ b/scripts/upload-artifacts @@ -96,8 +96,52 @@ generate_instructions() {

Stainless SDK Maven Repository

This is the Maven repository for your Stainless Java SDK build.

-

Directions

-

To use the uploaded Maven repository, add the following to your project's pom.xml:

+

Project configuration

+ +

The details depend on whether you're using Maven or Gradle as your build tool.

+ +

Maven

+ +

Add the following to your project's pom.xml:

+
<repositories>
+    <repository>
+        <id>stainless-sdk-repo</id>
+        <url>https://pkg.stainless.com/s/${PROJECT}/${SHA}/mvn</url>
+    </repository>
+</repositories>
+ +

Gradle

+

Add the following to your build.gradle file:

+
repositories {
+    maven {
+        url "https://pkg.stainless.com/s/${PROJECT}/${SHA}/mvn"
+    }
+}
+ +
+

Configuring authentication (if required)

+ +

Some accounts may require authentication to access the repository. If so, use the + following instructions, replacing YOUR_STAINLESS_API_TOKEN with your actual token.

+ +

Maven with authentication

+ +

First, ensure you have the following in your Maven settings.xml for repo authentication:

+
<servers>
+    <server>
+        <id>stainless-sdk-repo</id>
+        <configuration>
+            <httpHeaders>
+                <property>
+                    <name>Authorization</name>
+                    <value>Bearer YOUR_STAINLESS_API_TOKEN</value>
+                </property>
+            </httpHeaders>
+        </configuration>
+    </server>
+</servers>
+ +

Then, add the following to your project's pom.xml:

<repositories>
     <repository>
         <id>stainless-sdk-repo</id>
@@ -105,14 +149,24 @@ generate_instructions() {
     </repository>
 </repositories>
-

If you're using Gradle, add the following to your build.gradle file:

+

Gradle with authentication

+

Add the following to your build.gradle file:

repositories {
     maven {
-        url 'https://pkg.stainless.com/s/${PROJECT}/${SHA}/mvn'
+        url "https://pkg.stainless.com/s/${PROJECT}/${SHA}/mvn"
+        credentials(HttpHeaderCredentials) {
+            name = "Authorization"
+            value = "Bearer YOUR_STAINLESS_API_TOKEN"
+        }
+        authentication {
+            header(HttpHeaderAuthentication)
+        }
     }
 }
+
-

Once you've added the repository, you can include dependencies from it as usual. See your +

Using the repository

+

Once you've configured the repository, you can include dependencies from it as usual. See your project README for more details.

From cb92f7f6ea9ca48f574bcfca641bdf1ad7c3452f Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 3 Feb 2026 03:17:15 +0000 Subject: [PATCH 26/99] feat(api): api update --- .stats.yml | 4 ++-- .../casparser/CasParserCamsKfintechParams.kt | 17 +++++++++-------- .../api/models/casparser/CasParserCdslParams.kt | 17 +++++++++-------- .../api/models/casparser/CasParserNsdlParams.kt | 17 +++++++++-------- .../casparser/CasParserSmartParseParams.kt | 17 +++++++++-------- 5 files changed, 38 insertions(+), 34 deletions(-) diff --git a/.stats.yml b/.stats.yml index 9cc4732..2c90fa6 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 4 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-2e3df9c77e887f49ca3dffd5d68f30a8a0ea0b557f31282dd191ce85713e3e34.yml -openapi_spec_hash: 1cb90023118602a40a106cd51ed6a926 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-56b0f699c5437d9e5326626d35dfc972c17d01f12cb416c7f4854c8ea6d0e95e.yml +openapi_spec_hash: 158f405c1880706266d83e6ff16b9d2f config_hash: cb5d75abef6264b5d86448caf7295afa diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserCamsKfintechParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserCamsKfintechParams.kt index 6c18be5..131d1dd 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserCamsKfintechParams.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserCamsKfintechParams.kt @@ -38,7 +38,7 @@ private constructor( fun password(): Optional = body.password() /** - * Base64 encoded CAS PDF file + * Base64 encoded CAS PDF file (required if pdf_url not provided) * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -46,7 +46,7 @@ private constructor( fun pdfFile(): Optional = body.pdfFile() /** - * URL to the CAS PDF file + * URL to the CAS PDF file (required if pdf_file not provided) * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -130,7 +130,7 @@ private constructor( */ fun password(password: MultipartField) = apply { body.password(password) } - /** Base64 encoded CAS PDF file */ + /** Base64 encoded CAS PDF file (required if pdf_url not provided) */ fun pdfFile(pdfFile: String) = apply { body.pdfFile(pdfFile) } /** @@ -141,7 +141,7 @@ private constructor( */ fun pdfFile(pdfFile: MultipartField) = apply { body.pdfFile(pdfFile) } - /** URL to the CAS PDF file */ + /** URL to the CAS PDF file (required if pdf_file not provided) */ fun pdfUrl(pdfUrl: String) = apply { body.pdfUrl(pdfUrl) } /** @@ -291,6 +291,7 @@ private constructor( override fun _queryParams(): QueryParams = additionalQueryParams + /** Provide either `pdf_file` OR `pdf_url` (one is required) */ class Body private constructor( private val password: MultipartField, @@ -308,7 +309,7 @@ private constructor( fun password(): Optional = password.value.getOptional("password") /** - * Base64 encoded CAS PDF file + * Base64 encoded CAS PDF file (required if pdf_url not provided) * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if * the server responded with an unexpected value). @@ -316,7 +317,7 @@ private constructor( fun pdfFile(): Optional = pdfFile.value.getOptional("pdf_file") /** - * URL to the CAS PDF file + * URL to the CAS PDF file (required if pdf_file not provided) * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if * the server responded with an unexpected value). @@ -392,7 +393,7 @@ private constructor( */ fun password(password: MultipartField) = apply { this.password = password } - /** Base64 encoded CAS PDF file */ + /** Base64 encoded CAS PDF file (required if pdf_url not provided) */ fun pdfFile(pdfFile: String) = pdfFile(MultipartField.of(pdfFile)) /** @@ -404,7 +405,7 @@ private constructor( */ fun pdfFile(pdfFile: MultipartField) = apply { this.pdfFile = pdfFile } - /** URL to the CAS PDF file */ + /** URL to the CAS PDF file (required if pdf_file not provided) */ fun pdfUrl(pdfUrl: String) = pdfUrl(MultipartField.of(pdfUrl)) /** diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserCdslParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserCdslParams.kt index dac6268..8d90147 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserCdslParams.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserCdslParams.kt @@ -37,7 +37,7 @@ private constructor( fun password(): Optional = body.password() /** - * Base64 encoded CAS PDF file + * Base64 encoded CAS PDF file (required if pdf_url not provided) * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -45,7 +45,7 @@ private constructor( fun pdfFile(): Optional = body.pdfFile() /** - * URL to the CAS PDF file + * URL to the CAS PDF file (required if pdf_file not provided) * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -127,7 +127,7 @@ private constructor( */ fun password(password: MultipartField) = apply { body.password(password) } - /** Base64 encoded CAS PDF file */ + /** Base64 encoded CAS PDF file (required if pdf_url not provided) */ fun pdfFile(pdfFile: String) = apply { body.pdfFile(pdfFile) } /** @@ -138,7 +138,7 @@ private constructor( */ fun pdfFile(pdfFile: MultipartField) = apply { body.pdfFile(pdfFile) } - /** URL to the CAS PDF file */ + /** URL to the CAS PDF file (required if pdf_file not provided) */ fun pdfUrl(pdfUrl: String) = apply { body.pdfUrl(pdfUrl) } /** @@ -288,6 +288,7 @@ private constructor( override fun _queryParams(): QueryParams = additionalQueryParams + /** Provide either `pdf_file` OR `pdf_url` (one is required) */ class Body private constructor( private val password: MultipartField, @@ -305,7 +306,7 @@ private constructor( fun password(): Optional = password.value.getOptional("password") /** - * Base64 encoded CAS PDF file + * Base64 encoded CAS PDF file (required if pdf_url not provided) * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if * the server responded with an unexpected value). @@ -313,7 +314,7 @@ private constructor( fun pdfFile(): Optional = pdfFile.value.getOptional("pdf_file") /** - * URL to the CAS PDF file + * URL to the CAS PDF file (required if pdf_file not provided) * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if * the server responded with an unexpected value). @@ -389,7 +390,7 @@ private constructor( */ fun password(password: MultipartField) = apply { this.password = password } - /** Base64 encoded CAS PDF file */ + /** Base64 encoded CAS PDF file (required if pdf_url not provided) */ fun pdfFile(pdfFile: String) = pdfFile(MultipartField.of(pdfFile)) /** @@ -401,7 +402,7 @@ private constructor( */ fun pdfFile(pdfFile: MultipartField) = apply { this.pdfFile = pdfFile } - /** URL to the CAS PDF file */ + /** URL to the CAS PDF file (required if pdf_file not provided) */ fun pdfUrl(pdfUrl: String) = pdfUrl(MultipartField.of(pdfUrl)) /** diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserNsdlParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserNsdlParams.kt index 4692e36..87cec06 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserNsdlParams.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserNsdlParams.kt @@ -37,7 +37,7 @@ private constructor( fun password(): Optional = body.password() /** - * Base64 encoded CAS PDF file + * Base64 encoded CAS PDF file (required if pdf_url not provided) * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -45,7 +45,7 @@ private constructor( fun pdfFile(): Optional = body.pdfFile() /** - * URL to the CAS PDF file + * URL to the CAS PDF file (required if pdf_file not provided) * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -127,7 +127,7 @@ private constructor( */ fun password(password: MultipartField) = apply { body.password(password) } - /** Base64 encoded CAS PDF file */ + /** Base64 encoded CAS PDF file (required if pdf_url not provided) */ fun pdfFile(pdfFile: String) = apply { body.pdfFile(pdfFile) } /** @@ -138,7 +138,7 @@ private constructor( */ fun pdfFile(pdfFile: MultipartField) = apply { body.pdfFile(pdfFile) } - /** URL to the CAS PDF file */ + /** URL to the CAS PDF file (required if pdf_file not provided) */ fun pdfUrl(pdfUrl: String) = apply { body.pdfUrl(pdfUrl) } /** @@ -288,6 +288,7 @@ private constructor( override fun _queryParams(): QueryParams = additionalQueryParams + /** Provide either `pdf_file` OR `pdf_url` (one is required) */ class Body private constructor( private val password: MultipartField, @@ -305,7 +306,7 @@ private constructor( fun password(): Optional = password.value.getOptional("password") /** - * Base64 encoded CAS PDF file + * Base64 encoded CAS PDF file (required if pdf_url not provided) * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if * the server responded with an unexpected value). @@ -313,7 +314,7 @@ private constructor( fun pdfFile(): Optional = pdfFile.value.getOptional("pdf_file") /** - * URL to the CAS PDF file + * URL to the CAS PDF file (required if pdf_file not provided) * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if * the server responded with an unexpected value). @@ -389,7 +390,7 @@ private constructor( */ fun password(password: MultipartField) = apply { this.password = password } - /** Base64 encoded CAS PDF file */ + /** Base64 encoded CAS PDF file (required if pdf_url not provided) */ fun pdfFile(pdfFile: String) = pdfFile(MultipartField.of(pdfFile)) /** @@ -401,7 +402,7 @@ private constructor( */ fun pdfFile(pdfFile: MultipartField) = apply { this.pdfFile = pdfFile } - /** URL to the CAS PDF file */ + /** URL to the CAS PDF file (required if pdf_file not provided) */ fun pdfUrl(pdfUrl: String) = pdfUrl(MultipartField.of(pdfUrl)) /** diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserSmartParseParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserSmartParseParams.kt index e625f1d..99ecd8a 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserSmartParseParams.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserSmartParseParams.kt @@ -38,7 +38,7 @@ private constructor( fun password(): Optional = body.password() /** - * Base64 encoded CAS PDF file + * Base64 encoded CAS PDF file (required if pdf_url not provided) * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -46,7 +46,7 @@ private constructor( fun pdfFile(): Optional = body.pdfFile() /** - * URL to the CAS PDF file + * URL to the CAS PDF file (required if pdf_file not provided) * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -130,7 +130,7 @@ private constructor( */ fun password(password: MultipartField) = apply { body.password(password) } - /** Base64 encoded CAS PDF file */ + /** Base64 encoded CAS PDF file (required if pdf_url not provided) */ fun pdfFile(pdfFile: String) = apply { body.pdfFile(pdfFile) } /** @@ -141,7 +141,7 @@ private constructor( */ fun pdfFile(pdfFile: MultipartField) = apply { body.pdfFile(pdfFile) } - /** URL to the CAS PDF file */ + /** URL to the CAS PDF file (required if pdf_file not provided) */ fun pdfUrl(pdfUrl: String) = apply { body.pdfUrl(pdfUrl) } /** @@ -291,6 +291,7 @@ private constructor( override fun _queryParams(): QueryParams = additionalQueryParams + /** Provide either `pdf_file` OR `pdf_url` (one is required) */ class Body private constructor( private val password: MultipartField, @@ -308,7 +309,7 @@ private constructor( fun password(): Optional = password.value.getOptional("password") /** - * Base64 encoded CAS PDF file + * Base64 encoded CAS PDF file (required if pdf_url not provided) * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if * the server responded with an unexpected value). @@ -316,7 +317,7 @@ private constructor( fun pdfFile(): Optional = pdfFile.value.getOptional("pdf_file") /** - * URL to the CAS PDF file + * URL to the CAS PDF file (required if pdf_file not provided) * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if * the server responded with an unexpected value). @@ -392,7 +393,7 @@ private constructor( */ fun password(password: MultipartField) = apply { this.password = password } - /** Base64 encoded CAS PDF file */ + /** Base64 encoded CAS PDF file (required if pdf_url not provided) */ fun pdfFile(pdfFile: String) = pdfFile(MultipartField.of(pdfFile)) /** @@ -404,7 +405,7 @@ private constructor( */ fun pdfFile(pdfFile: MultipartField) = apply { this.pdfFile = pdfFile } - /** URL to the CAS PDF file */ + /** URL to the CAS PDF file (required if pdf_file not provided) */ fun pdfUrl(pdfUrl: String) = pdfUrl(MultipartField.of(pdfUrl)) /** From a139fe0fafe8faabf92d0f15791689e81e880a0b Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 14 Feb 2026 00:19:12 +0000 Subject: [PATCH 27/99] chore: update SDK settings --- cas-parser-java-client-okhttp/build.gradle.kts | 2 +- cas-parser-java-core/build.gradle.kts | 2 +- cas-parser-java-proguard-test/build.gradle.kts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cas-parser-java-client-okhttp/build.gradle.kts b/cas-parser-java-client-okhttp/build.gradle.kts index 91df2a9..b311e82 100644 --- a/cas-parser-java-client-okhttp/build.gradle.kts +++ b/cas-parser-java-client-okhttp/build.gradle.kts @@ -10,6 +10,6 @@ dependencies { implementation("com.squareup.okhttp3:logging-interceptor:4.12.0") testImplementation(kotlin("test")) - testImplementation("org.assertj:assertj-core:3.25.3") + testImplementation("org.assertj:assertj-core:3.27.7") testImplementation("com.github.tomakehurst:wiremock-jre8:2.35.2") } diff --git a/cas-parser-java-core/build.gradle.kts b/cas-parser-java-core/build.gradle.kts index 7d1eeed..5c40ab2 100644 --- a/cas-parser-java-core/build.gradle.kts +++ b/cas-parser-java-core/build.gradle.kts @@ -33,7 +33,7 @@ dependencies { testImplementation(kotlin("test")) testImplementation(project(":cas-parser-java-client-okhttp")) testImplementation("com.github.tomakehurst:wiremock-jre8:2.35.2") - testImplementation("org.assertj:assertj-core:3.25.3") + testImplementation("org.assertj:assertj-core:3.27.7") testImplementation("org.junit.jupiter:junit-jupiter-api:5.9.3") testImplementation("org.junit.jupiter:junit-jupiter-params:5.9.3") testImplementation("org.junit-pioneer:junit-pioneer:1.9.1") diff --git a/cas-parser-java-proguard-test/build.gradle.kts b/cas-parser-java-proguard-test/build.gradle.kts index bc6de2d..8846b0b 100644 --- a/cas-parser-java-proguard-test/build.gradle.kts +++ b/cas-parser-java-proguard-test/build.gradle.kts @@ -18,7 +18,7 @@ dependencies { testImplementation(project(":cas-parser-java")) testImplementation(kotlin("test")) testImplementation("org.junit.jupiter:junit-jupiter-api:5.9.3") - testImplementation("org.assertj:assertj-core:3.25.3") + testImplementation("org.assertj:assertj-core:3.27.7") testImplementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.14.0") } From 08c006aca62155dbcbd4e530c2c0b5240ad9f651 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 14 Feb 2026 00:20:15 +0000 Subject: [PATCH 28/99] chore(internal): version bump --- .release-please-manifest.json | 2 +- README.md | 10 +++++----- build.gradle.kts | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 2ed3b71..3d2ac0b 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.0.4" + ".": "0.1.0" } \ No newline at end of file diff --git a/README.md b/README.md index aca8f7f..dc0b1dc 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ -[![Maven Central](https://img.shields.io/maven-central/v/com.cas_parser.api/cas-parser-java)](https://central.sonatype.com/artifact/com.cas_parser.api/cas-parser-java/0.0.4) -[![javadoc](https://javadoc.io/badge2/com.cas_parser.api/cas-parser-java/0.0.4/javadoc.svg)](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.0.4) +[![Maven Central](https://img.shields.io/maven-central/v/com.cas_parser.api/cas-parser-java)](https://central.sonatype.com/artifact/com.cas_parser.api/cas-parser-java/0.1.0) +[![javadoc](https://javadoc.io/badge2/com.cas_parser.api/cas-parser-java/0.1.0/javadoc.svg)](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.1.0) @@ -22,7 +22,7 @@ Use the Cas Parser MCP Server to enable AI assistants to interact with this API, -The REST API documentation can be found on [docs.casparser.in](https://docs.casparser.in/reference). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.0.4). +The REST API documentation can be found on [docs.casparser.in](https://docs.casparser.in/reference). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.1.0). @@ -33,7 +33,7 @@ The REST API documentation can be found on [docs.casparser.in](https://docs.casp ### Gradle ```kotlin -implementation("com.cas_parser.api:cas-parser-java:0.0.4") +implementation("com.cas_parser.api:cas-parser-java:0.1.0") ``` ### Maven @@ -42,7 +42,7 @@ implementation("com.cas_parser.api:cas-parser-java:0.0.4") com.cas_parser.api cas-parser-java - 0.0.4 + 0.1.0 ``` diff --git a/build.gradle.kts b/build.gradle.kts index d58d78e..30b3cae 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -9,7 +9,7 @@ repositories { allprojects { group = "com.cas_parser.api" - version = "0.0.4" // x-release-please-version + version = "0.1.0" // x-release-please-version } subprojects { From 9455cda6af23b3c4230145af0e1a08987d075da1 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 14 Feb 2026 00:29:48 +0000 Subject: [PATCH 29/99] feat(api): manual updates --- .github/workflows/publish-sonatype.yml | 41 - .github/workflows/release-doctor.yml | 24 - .release-please-manifest.json | 3 - .stats.yml | 4 +- README.md | 144 +- bin/check-release-environment | 33 - build.gradle.kts | 2 +- .../main/kotlin/cas-parser.publish.gradle.kts | 8 +- .../client/okhttp/CasParserOkHttpClient.kt | 10 + .../okhttp/CasParserOkHttpClientAsync.kt | 10 + .../cas_parser/api/client/CasParserClient.kt | 57 +- .../api/client/CasParserClientAsync.kt | 57 +- .../api/client/CasParserClientAsyncImpl.kt | 152 +- .../api/client/CasParserClientImpl.kt | 146 +- .../kotlin/com/cas_parser/api/core/Check.kt | 2 +- .../com/cas_parser/api/core/ClientOptions.kt | 18 + .../accesstoken/AccessTokenCreateParams.kt | 410 + .../accesstoken/AccessTokenCreateResponse.kt | 239 + .../CamsKfintechParseParams.kt} | 30 +- .../api/models/camskfintech/LinkedHolder.kt | 189 + .../api/models/camskfintech/Transaction.kt | 1129 ++ .../UnifiedResponse.kt | 14784 ++++------------ .../CdslParsePdfParams.kt} | 28 +- .../cdsl/fetch/FetchRequestOtpParams.kt | 561 + .../cdsl/fetch/FetchRequestOtpResponse.kt | 219 + .../models/cdsl/fetch/FetchVerifyOtpParams.kt | 505 + .../cdsl/fetch/FetchVerifyOtpResponse.kt | 411 + .../contractnote/ContractNoteParseParams.kt | 742 + .../contractnote/ContractNoteParseResponse.kt | 3934 ++++ .../api/models/credits/CreditCheckParams.kt | 219 + .../api/models/credits/CreditCheckResponse.kt | 387 + .../inbox/InboxCheckConnectionStatusParams.kt | 252 + .../InboxCheckConnectionStatusResponse.kt | 265 + .../models/inbox/InboxConnectEmailParams.kt | 506 + .../models/inbox/InboxConnectEmailResponse.kt | 230 + .../inbox/InboxDisconnectEmailParams.kt | 251 + .../inbox/InboxDisconnectEmailResponse.kt | 186 + .../models/inbox/InboxListCasFilesParams.kt | 755 + .../models/inbox/InboxListCasFilesResponse.kt | 823 + .../kfintech/KfintechGenerateCasParams.kt | 693 + .../kfintech/KfintechGenerateCasResponse.kt | 186 + .../api/models/logs/LogCreateParams.kt | 528 + .../api/models/logs/LogCreateResponse.kt | 578 + .../api/models/logs/LogGetSummaryParams.kt | 468 + .../api/models/logs/LogGetSummaryResponse.kt | 663 + .../NsdlParseParams.kt} | 32 +- .../SmartParseCasPdfParams.kt} | 30 +- .../verifytoken/VerifyTokenVerifyParams.kt | 211 + .../verifytoken/VerifyTokenVerifyResponse.kt | 240 + .../services/async/AccessTokenServiceAsync.kt | 97 + .../async/AccessTokenServiceAsyncImpl.kt | 86 + .../async/CamsKfintechServiceAsync.kt | 89 + .../async/CamsKfintechServiceAsyncImpl.kt | 86 + .../async/CasGeneratorServiceAsync.kt | 37 - .../async/CasGeneratorServiceAsyncImpl.kt | 30 - .../services/async/CasParserServiceAsync.kt | 230 - .../api/services/async/CdslServiceAsync.kt | 88 + .../services/async/CdslServiceAsyncImpl.kt | 98 + .../async/ContractNoteServiceAsync.kt | 113 + .../async/ContractNoteServiceAsyncImpl.kt | 86 + .../api/services/async/CreditServiceAsync.kt | 93 + .../services/async/CreditServiceAsyncImpl.kt | 86 + .../api/services/async/InboxServiceAsync.kt | 188 + ...eAsyncImpl.kt => InboxServiceAsyncImpl.kt} | 137 +- .../services/async/KfintechServiceAsync.kt | 72 + .../async/KfintechServiceAsyncImpl.kt | 86 + .../api/services/async/LogServiceAsync.kt | 135 + .../api/services/async/LogServiceAsyncImpl.kt | 126 + .../api/services/async/NsdlServiceAsync.kt | 83 + .../services/async/NsdlServiceAsyncImpl.kt | 86 + .../api/services/async/SmartServiceAsync.kt | 87 + .../services/async/SmartServiceAsyncImpl.kt | 86 + .../services/async/VerifyTokenServiceAsync.kt | 86 + .../async/VerifyTokenServiceAsyncImpl.kt | 86 + .../services/async/cdsl/FetchServiceAsync.kt | 135 + .../async/cdsl/FetchServiceAsyncImpl.kt | 131 + .../services/blocking/AccessTokenService.kt | 96 + .../blocking/AccessTokenServiceImpl.kt | 82 + .../services/blocking/CamsKfintechService.kt | 87 + .../blocking/CamsKfintechServiceImpl.kt | 82 + .../services/blocking/CasGeneratorService.kt | 36 - .../blocking/CasGeneratorServiceImpl.kt | 30 - .../api/services/blocking/CasParserService.kt | 226 - .../api/services/blocking/CdslService.kt | 87 + .../api/services/blocking/CdslServiceImpl.kt | 93 + .../services/blocking/ContractNoteService.kt | 112 + .../blocking/ContractNoteServiceImpl.kt | 82 + .../api/services/blocking/CreditService.kt | 88 + .../services/blocking/CreditServiceImpl.kt | 82 + .../api/services/blocking/InboxService.kt | 187 + ...rserServiceImpl.kt => InboxServiceImpl.kt} | 137 +- .../api/services/blocking/KfintechService.kt | 68 + .../services/blocking/KfintechServiceImpl.kt | 82 + .../api/services/blocking/LogService.kt | 134 + .../api/services/blocking/LogServiceImpl.kt | 118 + .../api/services/blocking/NsdlService.kt | 81 + .../api/services/blocking/NsdlServiceImpl.kt | 78 + .../api/services/blocking/SmartService.kt | 85 + .../api/services/blocking/SmartServiceImpl.kt | 82 + .../services/blocking/VerifyTokenService.kt | 85 + .../blocking/VerifyTokenServiceImpl.kt | 82 + .../services/blocking/cdsl/FetchService.kt | 132 + .../blocking/cdsl/FetchServiceImpl.kt | 124 + .../AccessTokenCreateParamsTest.kt | 30 + .../AccessTokenCreateResponseTest.kt | 45 + .../CamsKfintechParseParamsTest.kt} | 10 +- .../models/camskfintech/LinkedHolderTest.kt | 33 + .../models/camskfintech/TransactionTest.kt | 94 + .../UnifiedResponseTest.kt | 343 +- .../CdslParsePdfParamsTest.kt} | 10 +- .../cdsl/fetch/FetchRequestOtpParamsTest.kt | 34 + .../cdsl/fetch/FetchRequestOtpResponseTest.kt | 45 + .../cdsl/fetch/FetchVerifyOtpParamsTest.kt | 47 + .../cdsl/fetch/FetchVerifyOtpResponseTest.kt | 67 + .../ContractNoteParseParamsTest.kt | 65 + .../ContractNoteParseResponseTest.kt | 304 + .../models/credits/CreditCheckParamsTest.kt | 13 + .../models/credits/CreditCheckResponseTest.kt | 61 + .../InboxCheckConnectionStatusParamsTest.kt | 25 + .../InboxCheckConnectionStatusResponseTest.kt | 48 + .../inbox/InboxConnectEmailParamsTest.kt | 43 + .../inbox/InboxConnectEmailResponseTest.kt | 45 + .../inbox/InboxDisconnectEmailParamsTest.kt | 25 + .../inbox/InboxDisconnectEmailResponseTest.kt | 41 + .../inbox/InboxListCasFilesParamsTest.kt | 79 + .../inbox/InboxListCasFilesResponseTest.kt | 84 + .../kfintech/KfintechGenerateCasParamsTest.kt | 58 + .../KfintechGenerateCasResponseTest.kt | 42 + .../api/models/logs/LogCreateParamsTest.kt | 42 + .../api/models/logs/LogCreateResponseTest.kt | 74 + .../models/logs/LogGetSummaryParamsTest.kt | 39 + .../models/logs/LogGetSummaryResponseTest.kt | 78 + .../NsdlParseParamsTest.kt} | 10 +- .../SmartParseCasPdfParamsTest.kt} | 10 +- .../VerifyTokenVerifyParamsTest.kt | 13 + .../VerifyTokenVerifyResponseTest.kt | 44 + .../api/services/ErrorHandlingTest.kt | 256 +- .../api/services/ServiceParamsTest.kt | 13 +- .../async/AccessTokenServiceAsyncTest.kt | 33 + .../async/CamsKfintechServiceAsyncTest.kt | 37 + .../async/CasParserServiceAsyncTest.kt | 109 - .../services/async/CdslServiceAsyncTest.kt | 37 + .../async/ContractNoteServiceAsyncTest.kt | 38 + .../services/async/CreditServiceAsyncTest.kt | 29 + .../services/async/InboxServiceAsyncTest.kt | 103 + .../async/KfintechServiceAsyncTest.kt | 39 + .../api/services/async/LogServiceAsyncTest.kt | 61 + .../services/async/NsdlServiceAsyncTest.kt | 37 + .../services/async/SmartServiceAsyncTest.kt | 37 + .../async/VerifyTokenServiceAsyncTest.kt | 29 + .../async/cdsl/FetchServiceAsyncTest.kt | 61 + .../blocking/AccessTokenServiceTest.kt | 30 + .../blocking/CamsKfintechServiceTest.kt | 36 + .../services/blocking/CasParserServiceTest.kt | 105 - .../api/services/blocking/CdslServiceTest.kt | 36 + .../blocking/ContractNoteServiceTest.kt | 37 + .../services/blocking/CreditServiceTest.kt | 28 + .../api/services/blocking/InboxServiceTest.kt | 99 + .../services/blocking/KfintechServiceTest.kt | 38 + .../api/services/blocking/LogServiceTest.kt | 59 + .../api/services/blocking/NsdlServiceTest.kt | 36 + .../api/services/blocking/SmartServiceTest.kt | 36 + .../blocking/VerifyTokenServiceTest.kt | 28 + .../blocking/cdsl/FetchServiceTest.kt | 59 + .../api/proguard/ProGuardCompatibilityTest.kt | 496 +- release-please-config.json | 67 - 166 files changed, 27355 insertions(+), 13551 deletions(-) delete mode 100644 .github/workflows/publish-sonatype.yml delete mode 100644 .github/workflows/release-doctor.yml delete mode 100644 .release-please-manifest.json delete mode 100644 bin/check-release-environment create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateParams.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateResponse.kt rename cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/{casparser/CasParserCamsKfintechParams.kt => camskfintech/CamsKfintechParseParams.kt} (94%) create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/camskfintech/LinkedHolder.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/camskfintech/Transaction.kt rename cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/{casparser => camskfintech}/UnifiedResponse.kt (54%) rename cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/{casparser/CasParserCdslParams.kt => cdsl/CdslParsePdfParams.kt} (95%) create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchRequestOtpParams.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchRequestOtpResponse.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchVerifyOtpParams.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchVerifyOtpResponse.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/contractnote/ContractNoteParseParams.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/contractnote/ContractNoteParseResponse.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/credits/CreditCheckParams.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/credits/CreditCheckResponse.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxCheckConnectionStatusParams.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxCheckConnectionStatusResponse.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxConnectEmailParams.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxConnectEmailResponse.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxDisconnectEmailParams.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxDisconnectEmailResponse.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesParams.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesResponse.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/kfintech/KfintechGenerateCasParams.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/kfintech/KfintechGenerateCasResponse.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogCreateParams.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogCreateResponse.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogGetSummaryParams.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogGetSummaryResponse.kt rename cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/{casparser/CasParserNsdlParams.kt => nsdl/NsdlParseParams.kt} (94%) rename cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/{casparser/CasParserSmartParseParams.kt => smart/SmartParseCasPdfParams.kt} (94%) create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyParams.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyResponse.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsync.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsyncImpl.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CamsKfintechServiceAsync.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CamsKfintechServiceAsyncImpl.kt delete mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CasGeneratorServiceAsync.kt delete mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CasGeneratorServiceAsyncImpl.kt delete mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CasParserServiceAsync.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CdslServiceAsync.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CdslServiceAsyncImpl.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/ContractNoteServiceAsync.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/ContractNoteServiceAsyncImpl.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CreditServiceAsync.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CreditServiceAsyncImpl.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/InboxServiceAsync.kt rename cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/{CasParserServiceAsyncImpl.kt => InboxServiceAsyncImpl.kt} (54%) create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/KfintechServiceAsync.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/KfintechServiceAsyncImpl.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/LogServiceAsync.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/LogServiceAsyncImpl.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/NsdlServiceAsync.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/NsdlServiceAsyncImpl.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/SmartServiceAsync.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/SmartServiceAsyncImpl.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsync.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsyncImpl.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/cdsl/FetchServiceAsync.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/cdsl/FetchServiceAsyncImpl.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/AccessTokenService.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/AccessTokenServiceImpl.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CamsKfintechService.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CamsKfintechServiceImpl.kt delete mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CasGeneratorService.kt delete mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CasGeneratorServiceImpl.kt delete mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CasParserService.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CdslService.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CdslServiceImpl.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/ContractNoteService.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/ContractNoteServiceImpl.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CreditService.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CreditServiceImpl.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/InboxService.kt rename cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/{CasParserServiceImpl.kt => InboxServiceImpl.kt} (52%) create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/KfintechService.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/KfintechServiceImpl.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/LogService.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/LogServiceImpl.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/NsdlService.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/NsdlServiceImpl.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/SmartService.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/SmartServiceImpl.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/VerifyTokenService.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/VerifyTokenServiceImpl.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/cdsl/FetchService.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/cdsl/FetchServiceImpl.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateParamsTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateResponseTest.kt rename cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/{casparser/CasParserSmartParseParamsTest.kt => camskfintech/CamsKfintechParseParamsTest.kt} (86%) create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/camskfintech/LinkedHolderTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/camskfintech/TransactionTest.kt rename cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/{casparser => camskfintech}/UnifiedResponseTest.kt (77%) rename cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/{casparser/CasParserNsdlParamsTest.kt => cdsl/CdslParsePdfParamsTest.kt} (87%) create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchRequestOtpParamsTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchRequestOtpResponseTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchVerifyOtpParamsTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchVerifyOtpResponseTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/contractnote/ContractNoteParseParamsTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/contractnote/ContractNoteParseResponseTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/credits/CreditCheckParamsTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/credits/CreditCheckResponseTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inbox/InboxCheckConnectionStatusParamsTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inbox/InboxCheckConnectionStatusResponseTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inbox/InboxConnectEmailParamsTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inbox/InboxConnectEmailResponseTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inbox/InboxDisconnectEmailParamsTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inbox/InboxDisconnectEmailResponseTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesParamsTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesResponseTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/kfintech/KfintechGenerateCasParamsTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/kfintech/KfintechGenerateCasResponseTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogCreateParamsTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogCreateResponseTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogGetSummaryParamsTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogGetSummaryResponseTest.kt rename cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/{casparser/CasParserCdslParamsTest.kt => nsdl/NsdlParseParamsTest.kt} (87%) rename cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/{casparser/CasParserCamsKfintechParamsTest.kt => smart/SmartParseCasPdfParamsTest.kt} (86%) create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyParamsTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyResponseTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsyncTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CamsKfintechServiceAsyncTest.kt delete mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CasParserServiceAsyncTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CdslServiceAsyncTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/ContractNoteServiceAsyncTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CreditServiceAsyncTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/InboxServiceAsyncTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/KfintechServiceAsyncTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/LogServiceAsyncTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/NsdlServiceAsyncTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/SmartServiceAsyncTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsyncTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/cdsl/FetchServiceAsyncTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/AccessTokenServiceTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CamsKfintechServiceTest.kt delete mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CasParserServiceTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CdslServiceTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/ContractNoteServiceTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CreditServiceTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/InboxServiceTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/KfintechServiceTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/LogServiceTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/NsdlServiceTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/SmartServiceTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/VerifyTokenServiceTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/cdsl/FetchServiceTest.kt delete mode 100644 release-please-config.json diff --git a/.github/workflows/publish-sonatype.yml b/.github/workflows/publish-sonatype.yml deleted file mode 100644 index 2bfe3c5..0000000 --- a/.github/workflows/publish-sonatype.yml +++ /dev/null @@ -1,41 +0,0 @@ -# This workflow is triggered when a GitHub release is created. -# It can also be run manually to re-publish to Sonatype in case it failed for some reason. -# You can run this workflow by navigating to https://www.github.com/CASParser/cas-parser-java/actions/workflows/publish-sonatype.yml -name: Publish Sonatype -on: - workflow_dispatch: - - release: - types: [published] - -jobs: - publish: - name: publish - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v6 - - - name: Set up Java - uses: actions/setup-java@v5 - with: - distribution: temurin - java-version: | - 8 - 21 - cache: gradle - - - name: Set up Gradle - uses: gradle/gradle-build-action@v2 - - - name: Publish to Sonatype - run: |- - export -- GPG_SIGNING_KEY_ID - printenv -- GPG_SIGNING_KEY | gpg --batch --passphrase-fd 3 --import 3<<< "$GPG_SIGNING_PASSWORD" - GPG_SIGNING_KEY_ID="$(gpg --with-colons --list-keys | awk -F : -- '/^pub:/ { getline; print "0x" substr($10, length($10) - 7) }')" - ./gradlew publish --no-configuration-cache - env: - SONATYPE_USERNAME: ${{ secrets.CAS_PARSER_SONATYPE_USERNAME || secrets.SONATYPE_USERNAME }} - SONATYPE_PASSWORD: ${{ secrets.CAS_PARSER_SONATYPE_PASSWORD || secrets.SONATYPE_PASSWORD }} - GPG_SIGNING_KEY: ${{ secrets.CAS_PARSER_SONATYPE_GPG_SIGNING_KEY || secrets.GPG_SIGNING_KEY }} - GPG_SIGNING_PASSWORD: ${{ secrets.CAS_PARSER_SONATYPE_GPG_SIGNING_PASSWORD || secrets.GPG_SIGNING_PASSWORD }} \ No newline at end of file diff --git a/.github/workflows/release-doctor.yml b/.github/workflows/release-doctor.yml deleted file mode 100644 index a636804..0000000 --- a/.github/workflows/release-doctor.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: Release Doctor -on: - pull_request: - branches: - - main - workflow_dispatch: - -jobs: - release_doctor: - name: release doctor - runs-on: ubuntu-latest - if: github.repository == 'CASParser/cas-parser-java' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || startsWith(github.head_ref, 'release-please') || github.head_ref == 'next') - - steps: - - uses: actions/checkout@v6 - - - name: Check release environment - run: | - bash ./bin/check-release-environment - env: - SONATYPE_USERNAME: ${{ secrets.CAS_PARSER_SONATYPE_USERNAME || secrets.SONATYPE_USERNAME }} - SONATYPE_PASSWORD: ${{ secrets.CAS_PARSER_SONATYPE_PASSWORD || secrets.SONATYPE_PASSWORD }} - GPG_SIGNING_KEY: ${{ secrets.CAS_PARSER_SONATYPE_GPG_SIGNING_KEY || secrets.GPG_SIGNING_KEY }} - GPG_SIGNING_PASSWORD: ${{ secrets.CAS_PARSER_SONATYPE_GPG_SIGNING_PASSWORD || secrets.GPG_SIGNING_PASSWORD }} diff --git a/.release-please-manifest.json b/.release-please-manifest.json deleted file mode 100644 index 3d2ac0b..0000000 --- a/.release-please-manifest.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - ".": "0.1.0" -} \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 2c90fa6..ff35822 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 4 +configured_endpoints: 17 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-56b0f699c5437d9e5326626d35dfc972c17d01f12cb416c7f4854c8ea6d0e95e.yml openapi_spec_hash: 158f405c1880706266d83e6ff16b9d2f -config_hash: cb5d75abef6264b5d86448caf7295afa +config_hash: 267be54ae6400ea329b16189da51ee06 diff --git a/README.md b/README.md index dc0b1dc..f63b8d7 100644 --- a/README.md +++ b/README.md @@ -1,35 +1,16 @@ # Cas Parser Java API Library - - [![Maven Central](https://img.shields.io/maven-central/v/com.cas_parser.api/cas-parser-java)](https://central.sonatype.com/artifact/com.cas_parser.api/cas-parser-java/0.1.0) [![javadoc](https://javadoc.io/badge2/com.cas_parser.api/cas-parser-java/0.1.0/javadoc.svg)](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.1.0) - - -The Cas Parser Java SDK provides convenient access to the [Cas Parser REST API](https://docs.casparser.in/reference) from applications written in Java. +The Cas Parser Java SDK provides convenient access to the Cas Parser REST API from applications written in Java. It is generated with [Stainless](https://www.stainless.com/). -## MCP Server - -Use the Cas Parser MCP Server to enable AI assistants to interact with this API, allowing them to explore endpoints, make test requests, and use documentation to help integrate this SDK into your application. - -[![Add to Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en-US/install-mcp?name=cas-parser-node-mcp&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsImNhcy1wYXJzZXItbm9kZS1tY3AiXSwiZW52Ijp7IkNBU19QQVJTRVJfQVBJX0tFWSI6Ik15IEFQSSBLZXkifX0) -[![Install in VS Code](https://img.shields.io/badge/_-Add_to_VS_Code-blue?style=for-the-badge&logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9Im5vbmUiIHZpZXdCb3g9IjAgMCA0MCA0MCI+PHBhdGggZmlsbD0iI0VFRSIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMzAuMjM1IDM5Ljg4NGEyLjQ5MSAyLjQ5MSAwIDAgMS0xLjc4MS0uNzNMMTIuNyAyNC43OGwtMy40NiAyLjYyNC0zLjQwNiAyLjU4MmExLjY2NSAxLjY2NSAwIDAgMS0xLjA4Mi4zMzggMS42NjQgMS42NjQgMCAwIDEtMS4wNDYtLjQzMWwtMi4yLTJhMS42NjYgMS42NjYgMCAwIDEgMC0yLjQ2M0w3LjQ1OCAyMCA0LjY3IDE3LjQ1MyAxLjUwNyAxNC41N2ExLjY2NSAxLjY2NSAwIDAgMSAwLTIuNDYzbDIuMi0yYTEuNjY1IDEuNjY1IDAgMCAxIDIuMTMtLjA5N2w2Ljg2MyA1LjIwOUwyOC40NTIuODQ0YTIuNDg4IDIuNDg4IDAgMCAxIDEuODQxLS43MjljLjM1MS4wMDkuNjk5LjA5MSAxLjAxOS4yNDVsOC4yMzYgMy45NjFhMi41IDIuNSAwIDAgMSAxLjQxNSAyLjI1M3YuMDk5LS4wNDVWMzMuMzd2LS4wNDUuMDk1YTIuNTAxIDIuNTAxIDAgMCAxLTEuNDE2IDIuMjU3bC04LjIzNSAzLjk2MWEyLjQ5MiAyLjQ5MiAwIDAgMS0xLjA3Ny4yNDZabS43MTYtMjguOTQ3LTExLjk0OCA5LjA2MiAxMS45NTIgOS4wNjUtLjAwNC0xOC4xMjdaIi8+PC9zdmc+)](https://vscode.stainless.com/mcp/%7B%22name%22%3A%22cas-parser-node-mcp%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22cas-parser-node-mcp%22%5D%2C%22env%22%3A%7B%22CAS_PARSER_API_KEY%22%3A%22My%20API%20Key%22%7D%7D) - -> Note: You may need to set environment variables in your MCP client. - - - -The REST API documentation can be found on [docs.casparser.in](https://docs.casparser.in/reference). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.1.0). - - +Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.1.0). ## Installation - - ### Gradle ```kotlin @@ -46,8 +27,6 @@ implementation("com.cas_parser.api:cas-parser-java:0.1.0") ``` - - ## Requirements This library requires Java 8 or later. @@ -57,18 +36,14 @@ This library requires Java 8 or later. ```java import com.cas_parser.api.client.CasParserClient; import com.cas_parser.api.client.okhttp.CasParserOkHttpClient; -import com.cas_parser.api.models.casparser.CasParserSmartParseParams; -import com.cas_parser.api.models.casparser.UnifiedResponse; +import com.cas_parser.api.models.credits.CreditCheckParams; +import com.cas_parser.api.models.credits.CreditCheckResponse; // Configures using the `casparser.apiKey` and `casparser.baseUrl` system properties // Or configures using the `CAS_PARSER_API_KEY` and `CAS_PARSER_BASE_URL` environment variables CasParserClient client = CasParserOkHttpClient.fromEnv(); -CasParserSmartParseParams params = CasParserSmartParseParams.builder() - .password("ABCDF") - .pdfUrl("https://your-cas-pdf-url-here.com") - .build(); -UnifiedResponse unifiedResponse = client.casParser().smartParse(params); +CreditCheckResponse response = client.credits().check(); ``` ## Client configuration @@ -141,7 +116,7 @@ The `withOptions()` method does not affect the original client or service. To send a request to the Cas Parser API, build an instance of some `Params` class and pass it to the corresponding client method. When the response is received, it will be deserialized into an instance of a Java class. -For example, `client.casParser().smartParse(...)` should be called with an instance of `CasParserSmartParseParams`, and it will return an instance of `UnifiedResponse`. +For example, `client.credits().check(...)` should be called with an instance of `CreditCheckParams`, and it will return an instance of `CreditCheckResponse`. ## Immutability @@ -158,19 +133,15 @@ The default client is synchronous. To switch to asynchronous execution, call the ```java import com.cas_parser.api.client.CasParserClient; import com.cas_parser.api.client.okhttp.CasParserOkHttpClient; -import com.cas_parser.api.models.casparser.CasParserSmartParseParams; -import com.cas_parser.api.models.casparser.UnifiedResponse; +import com.cas_parser.api.models.credits.CreditCheckParams; +import com.cas_parser.api.models.credits.CreditCheckResponse; import java.util.concurrent.CompletableFuture; // Configures using the `casparser.apiKey` and `casparser.baseUrl` system properties // Or configures using the `CAS_PARSER_API_KEY` and `CAS_PARSER_BASE_URL` environment variables CasParserClient client = CasParserOkHttpClient.fromEnv(); -CasParserSmartParseParams params = CasParserSmartParseParams.builder() - .password("ABCDF") - .pdfUrl("https://your-cas-pdf-url-here.com") - .build(); -CompletableFuture unifiedResponse = client.async().casParser().smartParse(params); +CompletableFuture response = client.async().credits().check(); ``` Or create an asynchronous client from the beginning: @@ -178,19 +149,15 @@ Or create an asynchronous client from the beginning: ```java import com.cas_parser.api.client.CasParserClientAsync; import com.cas_parser.api.client.okhttp.CasParserOkHttpClientAsync; -import com.cas_parser.api.models.casparser.CasParserSmartParseParams; -import com.cas_parser.api.models.casparser.UnifiedResponse; +import com.cas_parser.api.models.credits.CreditCheckParams; +import com.cas_parser.api.models.credits.CreditCheckResponse; import java.util.concurrent.CompletableFuture; // Configures using the `casparser.apiKey` and `casparser.baseUrl` system properties // Or configures using the `CAS_PARSER_API_KEY` and `CAS_PARSER_BASE_URL` environment variables CasParserClientAsync client = CasParserOkHttpClientAsync.fromEnv(); -CasParserSmartParseParams params = CasParserSmartParseParams.builder() - .password("ABCDF") - .pdfUrl("https://your-cas-pdf-url-here.com") - .build(); -CompletableFuture unifiedResponse = client.casParser().smartParse(params); +CompletableFuture response = client.credits().check(); ``` The asynchronous client supports the same options as the synchronous one, except most methods return `CompletableFuture`s. @@ -204,25 +171,21 @@ To access this data, prefix any HTTP method call on a client or service with `wi ```java import com.cas_parser.api.core.http.Headers; import com.cas_parser.api.core.http.HttpResponseFor; -import com.cas_parser.api.models.casparser.CasParserSmartParseParams; -import com.cas_parser.api.models.casparser.UnifiedResponse; +import com.cas_parser.api.models.credits.CreditCheckParams; +import com.cas_parser.api.models.credits.CreditCheckResponse; -CasParserSmartParseParams params = CasParserSmartParseParams.builder() - .password("ABCDF") - .pdfUrl("https://you-cas-pdf-url-here.com") - .build(); -HttpResponseFor unifiedResponse = client.casParser().withRawResponse().smartParse(params); +HttpResponseFor response = client.credits().withRawResponse().check(); -int statusCode = unifiedResponse.statusCode(); -Headers headers = unifiedResponse.headers(); +int statusCode = response.statusCode(); +Headers headers = response.headers(); ``` You can still deserialize the response into an instance of a Java class if needed: ```java -import com.cas_parser.api.models.casparser.UnifiedResponse; +import com.cas_parser.api.models.credits.CreditCheckResponse; -UnifiedResponse parsedUnifiedResponse = unifiedResponse.parse(); +CreditCheckResponse parsedResponse = response.parse(); ``` ## Error handling @@ -320,9 +283,9 @@ Requests time out after 1 minute by default. To set a custom timeout, configure the method call using the `timeout` method: ```java -import com.cas_parser.api.models.casparser.UnifiedResponse; +import com.cas_parser.api.models.credits.CreditCheckResponse; -UnifiedResponse unifiedResponse = client.casParser().smartParse(RequestOptions.builder().timeout(Duration.ofSeconds(30)).build()); +CreditCheckResponse response = client.credits().check(RequestOptions.builder().timeout(Duration.ofSeconds(30)).build()); ``` Or configure the default for all method calls at the client level: @@ -379,6 +342,21 @@ CasParserClient client = CasParserOkHttpClient.builder() .build(); ``` +### Environments + +The SDK sends requests to the production by default. To send requests to a different environment, configure the client like so: + +```java +import com.cas_parser.api.client.CasParserClient; +import com.cas_parser.api.client.okhttp.CasParserOkHttpClient; + +CasParserClient client = CasParserOkHttpClient.builder() + .fromEnv() + // Other options include `environment2` + .environment1() + .build(); +``` + ### Custom HTTP client The SDK consists of three artifacts: @@ -425,9 +403,9 @@ To set undocumented parameters, call the `putAdditionalHeader`, `putAdditionalQu ```java import com.cas_parser.api.core.JsonValue; -import com.cas_parser.api.models.casparser.CasParserSmartParseParams; +import com.cas_parser.api.models.credits.CreditCheckParams; -CasParserSmartParseParams params = CasParserSmartParseParams.builder() +CreditCheckParams params = CreditCheckParams.builder() .putAdditionalHeader("Secret-Header", "42") .putAdditionalQueryParam("secret_query_param", "42") .putAdditionalBodyProperty("secretProperty", JsonValue.from("42")) @@ -439,13 +417,9 @@ These can be accessed on the built object later using the `_additionalHeaders()` To set a documented parameter or property to an undocumented or not yet supported _value_, pass a [`JsonValue`](cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Values.kt) object to its setter: ```java -import com.cas_parser.api.core.JsonValue; -import com.cas_parser.api.models.casparser.CasParserSmartParseParams; +import com.cas_parser.api.models.credits.CreditCheckParams; -CasParserSmartParseParams params = CasParserSmartParseParams.builder() - .password(JsonValue.from(42)) - .pdfUrl("https://your-cas-pdf-url-here.com") - .build(); +CreditCheckParams params = CreditCheckParams.builder().build(); ``` The most straightforward way to create a [`JsonValue`](cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Values.kt) is using its `from(...)` method: @@ -487,6 +461,22 @@ JsonValue complexValue = JsonValue.from(Map.of( )); ``` +Normally a `Builder` class's `build` method will throw [`IllegalStateException`](https://docs.oracle.com/javase/8/docs/api/java/lang/IllegalStateException.html) if any required parameter or property is unset. + +To forcibly omit a required parameter or property, pass [`JsonMissing`](cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Values.kt): + +```java +import com.cas_parser.api.core.JsonMissing; +import com.cas_parser.api.models.cdsl.fetch.FetchRequestOtpParams; +import com.cas_parser.api.models.credits.CreditCheckParams; + +CreditCheckParams params = FetchRequestOtpParams.builder() + .dob("1990-01-15") + .pan("ABCDE1234F") + .boId(JsonMissing.of()) + .build(); +``` + ### Response properties To access undocumented response properties, call the `_additionalProperties()` method: @@ -495,7 +485,7 @@ To access undocumented response properties, call the `_additionalProperties()` m import com.cas_parser.api.core.JsonValue; import java.util.Map; -Map additionalProperties = client.casParser().smartParse(params)._additionalProperties(); +Map additionalProperties = client.credits().check(params)._additionalProperties(); JsonValue secretPropertyValue = additionalProperties.get("secretProperty"); String result = secretPropertyValue.accept(new JsonValue.Visitor<>() { @@ -525,19 +515,19 @@ To access a property's raw JSON value, which may be undocumented, call its `_` p import com.cas_parser.api.core.JsonField; import java.util.Optional; -JsonField password = client.casParser().smartParse(params)._password(); +JsonField field = client.credits().check(params)._field(); -if (password.isMissing()) { +if (field.isMissing()) { // The property is absent from the JSON response -} else if (password.isNull()) { +} else if (field.isNull()) { // The property was set to literal null } else { // Check if value was provided as a string // Other methods include `asNumber()`, `asBoolean()`, etc. - Optional jsonString = password.asString(); + Optional jsonString = field.asString(); // Try to deserialize into a custom type - MyClass myObject = password.asUnknown().orElseThrow().convert(MyClass.class); + MyClass myObject = field.asUnknown().orElseThrow().convert(MyClass.class); } ``` @@ -550,17 +540,17 @@ By default, the SDK will not throw an exception in this case. It will throw [`Ca If you would prefer to check that the response is completely well-typed upfront, then either call `validate()`: ```java -import com.cas_parser.api.models.casparser.UnifiedResponse; +import com.cas_parser.api.models.credits.CreditCheckResponse; -UnifiedResponse unifiedResponse = client.casParser().smartParse(params).validate(); +CreditCheckResponse response = client.credits().check(params).validate(); ``` Or configure the method call to validate the response using the `responseValidation` method: ```java -import com.cas_parser.api.models.casparser.UnifiedResponse; +import com.cas_parser.api.models.credits.CreditCheckResponse; -UnifiedResponse unifiedResponse = client.casParser().smartParse(RequestOptions.builder().responseValidation(true).build()); +CreditCheckResponse response = client.credits().check(RequestOptions.builder().responseValidation(true).build()); ``` Or configure the default for all method calls at the client level: @@ -613,4 +603,4 @@ This package generally follows [SemVer](https://semver.org/spec/v2.0.0.html) con We take backwards-compatibility seriously and work hard to ensure you can rely on a smooth upgrade experience. -We are keen for your feedback; please open an [issue](https://www.github.com/CASParser/cas-parser-java/issues) with questions, bugs, or suggestions. +We are keen for your feedback; please open an [issue](https://www.github.com/stainless-sdks/cas-parser-java/issues) with questions, bugs, or suggestions. diff --git a/bin/check-release-environment b/bin/check-release-environment deleted file mode 100644 index 3a6a7b4..0000000 --- a/bin/check-release-environment +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env bash - -errors=() - -if [ -z "${SONATYPE_USERNAME}" ]; then - errors+=("The SONATYPE_USERNAME secret has not been set. Please set it in either this repository's secrets or your organization secrets") -fi - -if [ -z "${SONATYPE_PASSWORD}" ]; then - errors+=("The SONATYPE_PASSWORD secret has not been set. Please set it in either this repository's secrets or your organization secrets") -fi - -if [ -z "${GPG_SIGNING_KEY}" ]; then - errors+=("The GPG_SIGNING_KEY secret has not been set. Please set it in either this repository's secrets or your organization secrets") -fi - -if [ -z "${GPG_SIGNING_PASSWORD}" ]; then - errors+=("The GPG_SIGNING_PASSWORD secret has not been set. Please set it in either this repository's secrets or your organization secrets") -fi - -lenErrors=${#errors[@]} - -if [[ lenErrors -gt 0 ]]; then - echo -e "Found the following errors in the release environment:\n" - - for error in "${errors[@]}"; do - echo -e "- $error\n" - done - - exit 1 -fi - -echo "The environment is ready to push releases!" diff --git a/build.gradle.kts b/build.gradle.kts index 30b3cae..abbbc45 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -9,7 +9,7 @@ repositories { allprojects { group = "com.cas_parser.api" - version = "0.1.0" // x-release-please-version + version = "0.1.0" } subprojects { diff --git a/buildSrc/src/main/kotlin/cas-parser.publish.gradle.kts b/buildSrc/src/main/kotlin/cas-parser.publish.gradle.kts index 26aec10..d4958ec 100644 --- a/buildSrc/src/main/kotlin/cas-parser.publish.gradle.kts +++ b/buildSrc/src/main/kotlin/cas-parser.publish.gradle.kts @@ -11,7 +11,7 @@ configure { pom { name.set("CAS Parser - Track Portfolios from CDSL, NSDL, CAMS, KFintech") description.set("API for parsing and analyzing CAS (Consolidated Account Statement) PDF files\nfrom NSDL, CDSL, and CAMS/KFintech, with a unified response format") - url.set("https://docs.casparser.in/reference") + url.set("https://www.github.com/stainless-sdks/cas-parser-java") licenses { license { @@ -27,9 +27,9 @@ configure { } scm { - connection.set("scm:git:git://github.com/CASParser/cas-parser-java.git") - developerConnection.set("scm:git:git://github.com/CASParser/cas-parser-java.git") - url.set("https://github.com/CASParser/cas-parser-java") + connection.set("scm:git:git://github.com/stainless-sdks/cas-parser-java.git") + developerConnection.set("scm:git:git://github.com/stainless-sdks/cas-parser-java.git") + url.set("https://github.com/stainless-sdks/cas-parser-java") } versionMapping { diff --git a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClient.kt b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClient.kt index 93a7aeb..dc713f6 100644 --- a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClient.kt +++ b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClient.kt @@ -166,12 +166,22 @@ class CasParserOkHttpClient private constructor() { * The base URL to use for every request. * * Defaults to the production environment: `https://portfolio-parser.api.casparser.in`. + * + * The following other environments, with dedicated builder methods, are available: + * - environment_1: `https://client-apis.casparser.in` + * - environment_2: `http://localhost:5000` */ fun baseUrl(baseUrl: String?) = apply { clientOptions.baseUrl(baseUrl) } /** Alias for calling [Builder.baseUrl] with `baseUrl.orElse(null)`. */ fun baseUrl(baseUrl: Optional) = baseUrl(baseUrl.getOrNull()) + /** Sets [baseUrl] to `https://client-apis.casparser.in`. */ + fun environment1() = apply { clientOptions.environment1() } + + /** Sets [baseUrl] to `http://localhost:5000`. */ + fun environment2() = apply { clientOptions.environment2() } + /** * Whether to call `validate` on every response before returning it. * diff --git a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClientAsync.kt b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClientAsync.kt index f4858a0..5d4beab 100644 --- a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClientAsync.kt +++ b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClientAsync.kt @@ -166,12 +166,22 @@ class CasParserOkHttpClientAsync private constructor() { * The base URL to use for every request. * * Defaults to the production environment: `https://portfolio-parser.api.casparser.in`. + * + * The following other environments, with dedicated builder methods, are available: + * - environment_1: `https://client-apis.casparser.in` + * - environment_2: `http://localhost:5000` */ fun baseUrl(baseUrl: String?) = apply { clientOptions.baseUrl(baseUrl) } /** Alias for calling [Builder.baseUrl] with `baseUrl.orElse(null)`. */ fun baseUrl(baseUrl: Optional) = baseUrl(baseUrl.getOrNull()) + /** Sets [baseUrl] to `https://client-apis.casparser.in`. */ + fun environment1() = apply { clientOptions.environment1() } + + /** Sets [baseUrl] to `http://localhost:5000`. */ + fun environment2() = apply { clientOptions.environment2() } + /** * Whether to call `validate` on every response before returning it. * diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClient.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClient.kt index 6a2e9fb..87a671b 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClient.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClient.kt @@ -3,8 +3,17 @@ package com.cas_parser.api.client import com.cas_parser.api.core.ClientOptions -import com.cas_parser.api.services.blocking.CasGeneratorService -import com.cas_parser.api.services.blocking.CasParserService +import com.cas_parser.api.services.blocking.AccessTokenService +import com.cas_parser.api.services.blocking.CamsKfintechService +import com.cas_parser.api.services.blocking.CdslService +import com.cas_parser.api.services.blocking.ContractNoteService +import com.cas_parser.api.services.blocking.CreditService +import com.cas_parser.api.services.blocking.InboxService +import com.cas_parser.api.services.blocking.KfintechService +import com.cas_parser.api.services.blocking.LogService +import com.cas_parser.api.services.blocking.NsdlService +import com.cas_parser.api.services.blocking.SmartService +import com.cas_parser.api.services.blocking.VerifyTokenService import java.util.function.Consumer /** @@ -43,9 +52,27 @@ interface CasParserClient { */ fun withOptions(modifier: Consumer): CasParserClient - fun casParser(): CasParserService + fun credits(): CreditService - fun casGenerator(): CasGeneratorService + fun logs(): LogService + + fun accessToken(): AccessTokenService + + fun verifyToken(): VerifyTokenService + + fun camsKfintech(): CamsKfintechService + + fun cdsl(): CdslService + + fun contractNote(): ContractNoteService + + fun inbox(): InboxService + + fun kfintech(): KfintechService + + fun nsdl(): NsdlService + + fun smart(): SmartService /** * Closes this client, relinquishing any underlying resources. @@ -70,8 +97,26 @@ interface CasParserClient { */ fun withOptions(modifier: Consumer): CasParserClient.WithRawResponse - fun casParser(): CasParserService.WithRawResponse + fun credits(): CreditService.WithRawResponse + + fun logs(): LogService.WithRawResponse + + fun accessToken(): AccessTokenService.WithRawResponse + + fun verifyToken(): VerifyTokenService.WithRawResponse + + fun camsKfintech(): CamsKfintechService.WithRawResponse + + fun cdsl(): CdslService.WithRawResponse + + fun contractNote(): ContractNoteService.WithRawResponse + + fun inbox(): InboxService.WithRawResponse + + fun kfintech(): KfintechService.WithRawResponse + + fun nsdl(): NsdlService.WithRawResponse - fun casGenerator(): CasGeneratorService.WithRawResponse + fun smart(): SmartService.WithRawResponse } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientAsync.kt index 24e7f4e..22f6ad3 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientAsync.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientAsync.kt @@ -3,8 +3,17 @@ package com.cas_parser.api.client import com.cas_parser.api.core.ClientOptions -import com.cas_parser.api.services.async.CasGeneratorServiceAsync -import com.cas_parser.api.services.async.CasParserServiceAsync +import com.cas_parser.api.services.async.AccessTokenServiceAsync +import com.cas_parser.api.services.async.CamsKfintechServiceAsync +import com.cas_parser.api.services.async.CdslServiceAsync +import com.cas_parser.api.services.async.ContractNoteServiceAsync +import com.cas_parser.api.services.async.CreditServiceAsync +import com.cas_parser.api.services.async.InboxServiceAsync +import com.cas_parser.api.services.async.KfintechServiceAsync +import com.cas_parser.api.services.async.LogServiceAsync +import com.cas_parser.api.services.async.NsdlServiceAsync +import com.cas_parser.api.services.async.SmartServiceAsync +import com.cas_parser.api.services.async.VerifyTokenServiceAsync import java.util.function.Consumer /** @@ -43,9 +52,27 @@ interface CasParserClientAsync { */ fun withOptions(modifier: Consumer): CasParserClientAsync - fun casParser(): CasParserServiceAsync + fun credits(): CreditServiceAsync - fun casGenerator(): CasGeneratorServiceAsync + fun logs(): LogServiceAsync + + fun accessToken(): AccessTokenServiceAsync + + fun verifyToken(): VerifyTokenServiceAsync + + fun camsKfintech(): CamsKfintechServiceAsync + + fun cdsl(): CdslServiceAsync + + fun contractNote(): ContractNoteServiceAsync + + fun inbox(): InboxServiceAsync + + fun kfintech(): KfintechServiceAsync + + fun nsdl(): NsdlServiceAsync + + fun smart(): SmartServiceAsync /** * Closes this client, relinquishing any underlying resources. @@ -74,8 +101,26 @@ interface CasParserClientAsync { modifier: Consumer ): CasParserClientAsync.WithRawResponse - fun casParser(): CasParserServiceAsync.WithRawResponse + fun credits(): CreditServiceAsync.WithRawResponse + + fun logs(): LogServiceAsync.WithRawResponse + + fun accessToken(): AccessTokenServiceAsync.WithRawResponse + + fun verifyToken(): VerifyTokenServiceAsync.WithRawResponse + + fun camsKfintech(): CamsKfintechServiceAsync.WithRawResponse + + fun cdsl(): CdslServiceAsync.WithRawResponse + + fun contractNote(): ContractNoteServiceAsync.WithRawResponse + + fun inbox(): InboxServiceAsync.WithRawResponse + + fun kfintech(): KfintechServiceAsync.WithRawResponse + + fun nsdl(): NsdlServiceAsync.WithRawResponse - fun casGenerator(): CasGeneratorServiceAsync.WithRawResponse + fun smart(): SmartServiceAsync.WithRawResponse } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientAsyncImpl.kt index d8b0b67..5f28136 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientAsyncImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientAsyncImpl.kt @@ -4,10 +4,28 @@ package com.cas_parser.api.client import com.cas_parser.api.core.ClientOptions import com.cas_parser.api.core.getPackageVersion -import com.cas_parser.api.services.async.CasGeneratorServiceAsync -import com.cas_parser.api.services.async.CasGeneratorServiceAsyncImpl -import com.cas_parser.api.services.async.CasParserServiceAsync -import com.cas_parser.api.services.async.CasParserServiceAsyncImpl +import com.cas_parser.api.services.async.AccessTokenServiceAsync +import com.cas_parser.api.services.async.AccessTokenServiceAsyncImpl +import com.cas_parser.api.services.async.CamsKfintechServiceAsync +import com.cas_parser.api.services.async.CamsKfintechServiceAsyncImpl +import com.cas_parser.api.services.async.CdslServiceAsync +import com.cas_parser.api.services.async.CdslServiceAsyncImpl +import com.cas_parser.api.services.async.ContractNoteServiceAsync +import com.cas_parser.api.services.async.ContractNoteServiceAsyncImpl +import com.cas_parser.api.services.async.CreditServiceAsync +import com.cas_parser.api.services.async.CreditServiceAsyncImpl +import com.cas_parser.api.services.async.InboxServiceAsync +import com.cas_parser.api.services.async.InboxServiceAsyncImpl +import com.cas_parser.api.services.async.KfintechServiceAsync +import com.cas_parser.api.services.async.KfintechServiceAsyncImpl +import com.cas_parser.api.services.async.LogServiceAsync +import com.cas_parser.api.services.async.LogServiceAsyncImpl +import com.cas_parser.api.services.async.NsdlServiceAsync +import com.cas_parser.api.services.async.NsdlServiceAsyncImpl +import com.cas_parser.api.services.async.SmartServiceAsync +import com.cas_parser.api.services.async.SmartServiceAsyncImpl +import com.cas_parser.api.services.async.VerifyTokenServiceAsync +import com.cas_parser.api.services.async.VerifyTokenServiceAsyncImpl import java.util.function.Consumer class CasParserClientAsyncImpl(private val clientOptions: ClientOptions) : CasParserClientAsync { @@ -27,12 +45,42 @@ class CasParserClientAsyncImpl(private val clientOptions: ClientOptions) : CasPa WithRawResponseImpl(clientOptions) } - private val casParser: CasParserServiceAsync by lazy { - CasParserServiceAsyncImpl(clientOptionsWithUserAgent) + private val credits: CreditServiceAsync by lazy { + CreditServiceAsyncImpl(clientOptionsWithUserAgent) } - private val casGenerator: CasGeneratorServiceAsync by lazy { - CasGeneratorServiceAsyncImpl(clientOptionsWithUserAgent) + private val logs: LogServiceAsync by lazy { LogServiceAsyncImpl(clientOptionsWithUserAgent) } + + private val accessToken: AccessTokenServiceAsync by lazy { + AccessTokenServiceAsyncImpl(clientOptionsWithUserAgent) + } + + private val verifyToken: VerifyTokenServiceAsync by lazy { + VerifyTokenServiceAsyncImpl(clientOptionsWithUserAgent) + } + + private val camsKfintech: CamsKfintechServiceAsync by lazy { + CamsKfintechServiceAsyncImpl(clientOptionsWithUserAgent) + } + + private val cdsl: CdslServiceAsync by lazy { CdslServiceAsyncImpl(clientOptionsWithUserAgent) } + + private val contractNote: ContractNoteServiceAsync by lazy { + ContractNoteServiceAsyncImpl(clientOptionsWithUserAgent) + } + + private val inbox: InboxServiceAsync by lazy { + InboxServiceAsyncImpl(clientOptionsWithUserAgent) + } + + private val kfintech: KfintechServiceAsync by lazy { + KfintechServiceAsyncImpl(clientOptionsWithUserAgent) + } + + private val nsdl: NsdlServiceAsync by lazy { NsdlServiceAsyncImpl(clientOptionsWithUserAgent) } + + private val smart: SmartServiceAsync by lazy { + SmartServiceAsyncImpl(clientOptionsWithUserAgent) } override fun sync(): CasParserClient = sync @@ -42,21 +90,75 @@ class CasParserClientAsyncImpl(private val clientOptions: ClientOptions) : CasPa override fun withOptions(modifier: Consumer): CasParserClientAsync = CasParserClientAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build()) - override fun casParser(): CasParserServiceAsync = casParser + override fun credits(): CreditServiceAsync = credits + + override fun logs(): LogServiceAsync = logs + + override fun accessToken(): AccessTokenServiceAsync = accessToken + + override fun verifyToken(): VerifyTokenServiceAsync = verifyToken + + override fun camsKfintech(): CamsKfintechServiceAsync = camsKfintech + + override fun cdsl(): CdslServiceAsync = cdsl - override fun casGenerator(): CasGeneratorServiceAsync = casGenerator + override fun contractNote(): ContractNoteServiceAsync = contractNote + + override fun inbox(): InboxServiceAsync = inbox + + override fun kfintech(): KfintechServiceAsync = kfintech + + override fun nsdl(): NsdlServiceAsync = nsdl + + override fun smart(): SmartServiceAsync = smart override fun close() = clientOptions.close() class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : CasParserClientAsync.WithRawResponse { - private val casParser: CasParserServiceAsync.WithRawResponse by lazy { - CasParserServiceAsyncImpl.WithRawResponseImpl(clientOptions) + private val credits: CreditServiceAsync.WithRawResponse by lazy { + CreditServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val logs: LogServiceAsync.WithRawResponse by lazy { + LogServiceAsyncImpl.WithRawResponseImpl(clientOptions) } - private val casGenerator: CasGeneratorServiceAsync.WithRawResponse by lazy { - CasGeneratorServiceAsyncImpl.WithRawResponseImpl(clientOptions) + private val accessToken: AccessTokenServiceAsync.WithRawResponse by lazy { + AccessTokenServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val verifyToken: VerifyTokenServiceAsync.WithRawResponse by lazy { + VerifyTokenServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val camsKfintech: CamsKfintechServiceAsync.WithRawResponse by lazy { + CamsKfintechServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val cdsl: CdslServiceAsync.WithRawResponse by lazy { + CdslServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val contractNote: ContractNoteServiceAsync.WithRawResponse by lazy { + ContractNoteServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val inbox: InboxServiceAsync.WithRawResponse by lazy { + InboxServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val kfintech: KfintechServiceAsync.WithRawResponse by lazy { + KfintechServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val nsdl: NsdlServiceAsync.WithRawResponse by lazy { + NsdlServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val smart: SmartServiceAsync.WithRawResponse by lazy { + SmartServiceAsyncImpl.WithRawResponseImpl(clientOptions) } override fun withOptions( @@ -66,8 +168,26 @@ class CasParserClientAsyncImpl(private val clientOptions: ClientOptions) : CasPa clientOptions.toBuilder().apply(modifier::accept).build() ) - override fun casParser(): CasParserServiceAsync.WithRawResponse = casParser + override fun credits(): CreditServiceAsync.WithRawResponse = credits + + override fun logs(): LogServiceAsync.WithRawResponse = logs + + override fun accessToken(): AccessTokenServiceAsync.WithRawResponse = accessToken + + override fun verifyToken(): VerifyTokenServiceAsync.WithRawResponse = verifyToken + + override fun camsKfintech(): CamsKfintechServiceAsync.WithRawResponse = camsKfintech + + override fun cdsl(): CdslServiceAsync.WithRawResponse = cdsl + + override fun contractNote(): ContractNoteServiceAsync.WithRawResponse = contractNote + + override fun inbox(): InboxServiceAsync.WithRawResponse = inbox + + override fun kfintech(): KfintechServiceAsync.WithRawResponse = kfintech + + override fun nsdl(): NsdlServiceAsync.WithRawResponse = nsdl - override fun casGenerator(): CasGeneratorServiceAsync.WithRawResponse = casGenerator + override fun smart(): SmartServiceAsync.WithRawResponse = smart } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientImpl.kt index fe0f962..f4b18e8 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientImpl.kt @@ -4,10 +4,28 @@ package com.cas_parser.api.client import com.cas_parser.api.core.ClientOptions import com.cas_parser.api.core.getPackageVersion -import com.cas_parser.api.services.blocking.CasGeneratorService -import com.cas_parser.api.services.blocking.CasGeneratorServiceImpl -import com.cas_parser.api.services.blocking.CasParserService -import com.cas_parser.api.services.blocking.CasParserServiceImpl +import com.cas_parser.api.services.blocking.AccessTokenService +import com.cas_parser.api.services.blocking.AccessTokenServiceImpl +import com.cas_parser.api.services.blocking.CamsKfintechService +import com.cas_parser.api.services.blocking.CamsKfintechServiceImpl +import com.cas_parser.api.services.blocking.CdslService +import com.cas_parser.api.services.blocking.CdslServiceImpl +import com.cas_parser.api.services.blocking.ContractNoteService +import com.cas_parser.api.services.blocking.ContractNoteServiceImpl +import com.cas_parser.api.services.blocking.CreditService +import com.cas_parser.api.services.blocking.CreditServiceImpl +import com.cas_parser.api.services.blocking.InboxService +import com.cas_parser.api.services.blocking.InboxServiceImpl +import com.cas_parser.api.services.blocking.KfintechService +import com.cas_parser.api.services.blocking.KfintechServiceImpl +import com.cas_parser.api.services.blocking.LogService +import com.cas_parser.api.services.blocking.LogServiceImpl +import com.cas_parser.api.services.blocking.NsdlService +import com.cas_parser.api.services.blocking.NsdlServiceImpl +import com.cas_parser.api.services.blocking.SmartService +import com.cas_parser.api.services.blocking.SmartServiceImpl +import com.cas_parser.api.services.blocking.VerifyTokenService +import com.cas_parser.api.services.blocking.VerifyTokenServiceImpl import java.util.function.Consumer class CasParserClientImpl(private val clientOptions: ClientOptions) : CasParserClient { @@ -27,14 +45,38 @@ class CasParserClientImpl(private val clientOptions: ClientOptions) : CasParserC WithRawResponseImpl(clientOptions) } - private val casParser: CasParserService by lazy { - CasParserServiceImpl(clientOptionsWithUserAgent) + private val credits: CreditService by lazy { CreditServiceImpl(clientOptionsWithUserAgent) } + + private val logs: LogService by lazy { LogServiceImpl(clientOptionsWithUserAgent) } + + private val accessToken: AccessTokenService by lazy { + AccessTokenServiceImpl(clientOptionsWithUserAgent) + } + + private val verifyToken: VerifyTokenService by lazy { + VerifyTokenServiceImpl(clientOptionsWithUserAgent) + } + + private val camsKfintech: CamsKfintechService by lazy { + CamsKfintechServiceImpl(clientOptionsWithUserAgent) } - private val casGenerator: CasGeneratorService by lazy { - CasGeneratorServiceImpl(clientOptionsWithUserAgent) + private val cdsl: CdslService by lazy { CdslServiceImpl(clientOptionsWithUserAgent) } + + private val contractNote: ContractNoteService by lazy { + ContractNoteServiceImpl(clientOptionsWithUserAgent) + } + + private val inbox: InboxService by lazy { InboxServiceImpl(clientOptionsWithUserAgent) } + + private val kfintech: KfintechService by lazy { + KfintechServiceImpl(clientOptionsWithUserAgent) } + private val nsdl: NsdlService by lazy { NsdlServiceImpl(clientOptionsWithUserAgent) } + + private val smart: SmartService by lazy { SmartServiceImpl(clientOptionsWithUserAgent) } + override fun async(): CasParserClientAsync = async override fun withRawResponse(): CasParserClient.WithRawResponse = withRawResponse @@ -42,21 +84,75 @@ class CasParserClientImpl(private val clientOptions: ClientOptions) : CasParserC override fun withOptions(modifier: Consumer): CasParserClient = CasParserClientImpl(clientOptions.toBuilder().apply(modifier::accept).build()) - override fun casParser(): CasParserService = casParser + override fun credits(): CreditService = credits - override fun casGenerator(): CasGeneratorService = casGenerator + override fun logs(): LogService = logs + + override fun accessToken(): AccessTokenService = accessToken + + override fun verifyToken(): VerifyTokenService = verifyToken + + override fun camsKfintech(): CamsKfintechService = camsKfintech + + override fun cdsl(): CdslService = cdsl + + override fun contractNote(): ContractNoteService = contractNote + + override fun inbox(): InboxService = inbox + + override fun kfintech(): KfintechService = kfintech + + override fun nsdl(): NsdlService = nsdl + + override fun smart(): SmartService = smart override fun close() = clientOptions.close() class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : CasParserClient.WithRawResponse { - private val casParser: CasParserService.WithRawResponse by lazy { - CasParserServiceImpl.WithRawResponseImpl(clientOptions) + private val credits: CreditService.WithRawResponse by lazy { + CreditServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val logs: LogService.WithRawResponse by lazy { + LogServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val accessToken: AccessTokenService.WithRawResponse by lazy { + AccessTokenServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val verifyToken: VerifyTokenService.WithRawResponse by lazy { + VerifyTokenServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val camsKfintech: CamsKfintechService.WithRawResponse by lazy { + CamsKfintechServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val cdsl: CdslService.WithRawResponse by lazy { + CdslServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val contractNote: ContractNoteService.WithRawResponse by lazy { + ContractNoteServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val inbox: InboxService.WithRawResponse by lazy { + InboxServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val kfintech: KfintechService.WithRawResponse by lazy { + KfintechServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val nsdl: NsdlService.WithRawResponse by lazy { + NsdlServiceImpl.WithRawResponseImpl(clientOptions) } - private val casGenerator: CasGeneratorService.WithRawResponse by lazy { - CasGeneratorServiceImpl.WithRawResponseImpl(clientOptions) + private val smart: SmartService.WithRawResponse by lazy { + SmartServiceImpl.WithRawResponseImpl(clientOptions) } override fun withOptions( @@ -66,8 +162,26 @@ class CasParserClientImpl(private val clientOptions: ClientOptions) : CasParserC clientOptions.toBuilder().apply(modifier::accept).build() ) - override fun casParser(): CasParserService.WithRawResponse = casParser + override fun credits(): CreditService.WithRawResponse = credits + + override fun logs(): LogService.WithRawResponse = logs + + override fun accessToken(): AccessTokenService.WithRawResponse = accessToken + + override fun verifyToken(): VerifyTokenService.WithRawResponse = verifyToken + + override fun camsKfintech(): CamsKfintechService.WithRawResponse = camsKfintech + + override fun cdsl(): CdslService.WithRawResponse = cdsl + + override fun contractNote(): ContractNoteService.WithRawResponse = contractNote + + override fun inbox(): InboxService.WithRawResponse = inbox + + override fun kfintech(): KfintechService.WithRawResponse = kfintech + + override fun nsdl(): NsdlService.WithRawResponse = nsdl - override fun casGenerator(): CasGeneratorService.WithRawResponse = casGenerator + override fun smart(): SmartService.WithRawResponse = smart } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Check.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Check.kt index c0b5e80..2e4c6e8 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Check.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Check.kt @@ -77,7 +77,7 @@ This can happen if you are either: Double-check that you are depending on compatible Jackson versions. -See https://www.github.com/CASParser/cas-parser-java#jackson for more information. +See https://www.github.com/stainless-sdks/cas-parser-java#jackson for more information. """ .trimIndent() } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ClientOptions.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ClientOptions.kt index 1db211b..e3e4eaf 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ClientOptions.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ClientOptions.kt @@ -107,6 +107,10 @@ private constructor( * The base URL to use for every request. * * Defaults to the production environment: `https://portfolio-parser.api.casparser.in`. + * + * The following other environments, with dedicated builder methods, are available: + * - environment_1: `https://client-apis.casparser.in` + * - environment_2: `http://localhost:5000` */ fun baseUrl(): String = baseUrl ?: PRODUCTION_URL @@ -116,6 +120,10 @@ private constructor( const val PRODUCTION_URL = "https://portfolio-parser.api.casparser.in" + const val ENVIRONMENT_1_URL = "https://client-apis.casparser.in" + + const val ENVIRONMENT_2_URL = "http://localhost:5000" + /** * Returns a mutable builder for constructing an instance of [ClientOptions]. * @@ -221,12 +229,22 @@ private constructor( * The base URL to use for every request. * * Defaults to the production environment: `https://portfolio-parser.api.casparser.in`. + * + * The following other environments, with dedicated builder methods, are available: + * - environment_1: `https://client-apis.casparser.in` + * - environment_2: `http://localhost:5000` */ fun baseUrl(baseUrl: String?) = apply { this.baseUrl = baseUrl } /** Alias for calling [Builder.baseUrl] with `baseUrl.orElse(null)`. */ fun baseUrl(baseUrl: Optional) = baseUrl(baseUrl.getOrNull()) + /** Sets [baseUrl] to `https://client-apis.casparser.in`. */ + fun environment1() = baseUrl(ENVIRONMENT_1_URL) + + /** Sets [baseUrl] to `http://localhost:5000`. */ + fun environment2() = baseUrl(ENVIRONMENT_2_URL) + /** * Whether to call `validate` on every response before returning it. * diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateParams.kt new file mode 100644 index 0000000..676dc4d --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateParams.kt @@ -0,0 +1,410 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.accesstoken + +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonField +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.Params +import com.cas_parser.api.core.http.Headers +import com.cas_parser.api.core.http.QueryParams +import com.cas_parser.api.errors.CasParserInvalidDataException +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 + +/** + * Generate a short-lived access token from your API key. + * + * **Use this endpoint from your backend** to create tokens that can be safely passed to + * frontend/SDK. + * + * Access tokens: + * - Are prefixed with `at_` for easy identification + * - Valid for up to 60 minutes + * - Can be used in place of API keys on all v4 endpoints + * - Cannot be used to generate other access tokens + */ +class AccessTokenCreateParams +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Token validity in minutes (max 60) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun expiryMinutes(): Optional = body.expiryMinutes() + + /** + * Returns the raw JSON value of [expiryMinutes]. + * + * Unlike [expiryMinutes], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _expiryMinutes(): JsonField = body._expiryMinutes() + + fun _additionalBodyProperties(): Map = body._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 { + + @JvmStatic fun none(): AccessTokenCreateParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [AccessTokenCreateParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AccessTokenCreateParams]. */ + class Builder internal constructor() { + + private var body: Body.Builder = Body.builder() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(accessTokenCreateParams: AccessTokenCreateParams) = apply { + body = accessTokenCreateParams.body.toBuilder() + additionalHeaders = accessTokenCreateParams.additionalHeaders.toBuilder() + additionalQueryParams = accessTokenCreateParams.additionalQueryParams.toBuilder() + } + + /** + * Sets the entire request body. + * + * This is generally only useful if you are already constructing the body separately. + * Otherwise, it's more convenient to use the top-level setters instead: + * - [expiryMinutes] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + /** Token validity in minutes (max 60) */ + fun expiryMinutes(expiryMinutes: Long) = apply { body.expiryMinutes(expiryMinutes) } + + /** + * Sets [Builder.expiryMinutes] to an arbitrary JSON value. + * + * You should usually call [Builder.expiryMinutes] with a well-typed [Long] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun expiryMinutes(expiryMinutes: JsonField) = apply { + body.expiryMinutes(expiryMinutes) + } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) + } + + 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 [AccessTokenCreateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): AccessTokenCreateParams = + AccessTokenCreateParams( + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + class Body + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val expiryMinutes: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("expiry_minutes") + @ExcludeMissing + expiryMinutes: JsonField = JsonMissing.of() + ) : this(expiryMinutes, mutableMapOf()) + + /** + * Token validity in minutes (max 60) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun expiryMinutes(): Optional = expiryMinutes.getOptional("expiry_minutes") + + /** + * Returns the raw JSON value of [expiryMinutes]. + * + * Unlike [expiryMinutes], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("expiry_minutes") + @ExcludeMissing + fun _expiryMinutes(): JsonField = expiryMinutes + + @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 [Body]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var expiryMinutes: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + expiryMinutes = body.expiryMinutes + additionalProperties = body.additionalProperties.toMutableMap() + } + + /** Token validity in minutes (max 60) */ + fun expiryMinutes(expiryMinutes: Long) = expiryMinutes(JsonField.of(expiryMinutes)) + + /** + * Sets [Builder.expiryMinutes] to an arbitrary JSON value. + * + * You should usually call [Builder.expiryMinutes] with a well-typed [Long] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun expiryMinutes(expiryMinutes: JsonField) = apply { + this.expiryMinutes = expiryMinutes + } + + 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 [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Body = Body(expiryMinutes, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + expiryMinutes() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (expiryMinutes.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + expiryMinutes == other.expiryMinutes && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(expiryMinutes, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{expiryMinutes=$expiryMinutes, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AccessTokenCreateParams && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = Objects.hash(body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "AccessTokenCreateParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateResponse.kt new file mode 100644 index 0000000..a23d37b --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateResponse.kt @@ -0,0 +1,239 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.accesstoken + +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonField +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.errors.CasParserInvalidDataException +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 + +class AccessTokenCreateResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val accessToken: JsonField, + private val expiresIn: JsonField, + private val tokenType: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("access_token") + @ExcludeMissing + accessToken: JsonField = JsonMissing.of(), + @JsonProperty("expires_in") @ExcludeMissing expiresIn: JsonField = JsonMissing.of(), + @JsonProperty("token_type") @ExcludeMissing tokenType: JsonField = JsonMissing.of(), + ) : this(accessToken, expiresIn, tokenType, mutableMapOf()) + + /** + * The at_ prefixed access token + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun accessToken(): Optional = accessToken.getOptional("access_token") + + /** + * Token validity in seconds + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun expiresIn(): Optional = expiresIn.getOptional("expires_in") + + /** + * Always "api_key" - token is a drop-in replacement for x-api-key header + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun tokenType(): Optional = tokenType.getOptional("token_type") + + /** + * Returns the raw JSON value of [accessToken]. + * + * Unlike [accessToken], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("access_token") + @ExcludeMissing + fun _accessToken(): JsonField = accessToken + + /** + * Returns the raw JSON value of [expiresIn]. + * + * Unlike [expiresIn], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("expires_in") @ExcludeMissing fun _expiresIn(): JsonField = expiresIn + + /** + * Returns the raw JSON value of [tokenType]. + * + * Unlike [tokenType], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("token_type") @ExcludeMissing fun _tokenType(): JsonField = tokenType + + @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 [AccessTokenCreateResponse]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AccessTokenCreateResponse]. */ + class Builder internal constructor() { + + private var accessToken: JsonField = JsonMissing.of() + private var expiresIn: JsonField = JsonMissing.of() + private var tokenType: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(accessTokenCreateResponse: AccessTokenCreateResponse) = apply { + accessToken = accessTokenCreateResponse.accessToken + expiresIn = accessTokenCreateResponse.expiresIn + tokenType = accessTokenCreateResponse.tokenType + additionalProperties = accessTokenCreateResponse.additionalProperties.toMutableMap() + } + + /** The at_ prefixed access token */ + fun accessToken(accessToken: String) = accessToken(JsonField.of(accessToken)) + + /** + * Sets [Builder.accessToken] to an arbitrary JSON value. + * + * You should usually call [Builder.accessToken] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun accessToken(accessToken: JsonField) = apply { this.accessToken = accessToken } + + /** Token validity in seconds */ + fun expiresIn(expiresIn: Long) = expiresIn(JsonField.of(expiresIn)) + + /** + * Sets [Builder.expiresIn] to an arbitrary JSON value. + * + * You should usually call [Builder.expiresIn] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun expiresIn(expiresIn: JsonField) = apply { this.expiresIn = expiresIn } + + /** Always "api_key" - token is a drop-in replacement for x-api-key header */ + fun tokenType(tokenType: String) = tokenType(JsonField.of(tokenType)) + + /** + * Sets [Builder.tokenType] to an arbitrary JSON value. + * + * You should usually call [Builder.tokenType] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun tokenType(tokenType: JsonField) = apply { this.tokenType = tokenType } + + 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 [AccessTokenCreateResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): AccessTokenCreateResponse = + AccessTokenCreateResponse( + accessToken, + expiresIn, + tokenType, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): AccessTokenCreateResponse = apply { + if (validated) { + return@apply + } + + accessToken() + expiresIn() + tokenType() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (accessToken.asKnown().isPresent) 1 else 0) + + (if (expiresIn.asKnown().isPresent) 1 else 0) + + (if (tokenType.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AccessTokenCreateResponse && + accessToken == other.accessToken && + expiresIn == other.expiresIn && + tokenType == other.tokenType && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(accessToken, expiresIn, tokenType, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AccessTokenCreateResponse{accessToken=$accessToken, expiresIn=$expiresIn, tokenType=$tokenType, additionalProperties=$additionalProperties}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserCamsKfintechParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/camskfintech/CamsKfintechParseParams.kt similarity index 94% rename from cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserCamsKfintechParams.kt rename to cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/camskfintech/CamsKfintechParseParams.kt index 131d1dd..2b503a6 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserCamsKfintechParams.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/camskfintech/CamsKfintechParseParams.kt @@ -1,6 +1,6 @@ // File generated from our OpenAPI spec by Stainless. -package com.cas_parser.api.models.casparser +package com.cas_parser.api.models.camskfintech import com.cas_parser.api.core.ExcludeMissing import com.cas_parser.api.core.JsonValue @@ -22,7 +22,7 @@ import java.util.Optional * and returns data in a unified format. Use this endpoint when you know the PDF is from CAMS or * KFintech. */ -class CasParserCamsKfintechParams +class CamsKfintechParseParams private constructor( private val body: Body, private val additionalHeaders: Headers, @@ -86,15 +86,13 @@ private constructor( companion object { - @JvmStatic fun none(): CasParserCamsKfintechParams = builder().build() + @JvmStatic fun none(): CamsKfintechParseParams = builder().build() - /** - * Returns a mutable builder for constructing an instance of [CasParserCamsKfintechParams]. - */ + /** Returns a mutable builder for constructing an instance of [CamsKfintechParseParams]. */ @JvmStatic fun builder() = Builder() } - /** A builder for [CasParserCamsKfintechParams]. */ + /** A builder for [CamsKfintechParseParams]. */ class Builder internal constructor() { private var body: Body.Builder = Body.builder() @@ -102,10 +100,10 @@ private constructor( private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic - internal fun from(casParserCamsKfintechParams: CasParserCamsKfintechParams) = apply { - body = casParserCamsKfintechParams.body.toBuilder() - additionalHeaders = casParserCamsKfintechParams.additionalHeaders.toBuilder() - additionalQueryParams = casParserCamsKfintechParams.additionalQueryParams.toBuilder() + internal fun from(camsKfintechParseParams: CamsKfintechParseParams) = apply { + body = camsKfintechParseParams.body.toBuilder() + additionalHeaders = camsKfintechParseParams.additionalHeaders.toBuilder() + additionalQueryParams = camsKfintechParseParams.additionalQueryParams.toBuilder() } /** @@ -270,12 +268,12 @@ private constructor( } /** - * Returns an immutable instance of [CasParserCamsKfintechParams]. + * Returns an immutable instance of [CamsKfintechParseParams]. * * Further updates to this [Builder] will not mutate the returned instance. */ - fun build(): CasParserCamsKfintechParams = - CasParserCamsKfintechParams( + fun build(): CamsKfintechParseParams = + CamsKfintechParseParams( body.build(), additionalHeaders.build(), additionalQueryParams.build(), @@ -492,7 +490,7 @@ private constructor( return true } - return other is CasParserCamsKfintechParams && + return other is CamsKfintechParseParams && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams @@ -501,5 +499,5 @@ private constructor( override fun hashCode(): Int = Objects.hash(body, additionalHeaders, additionalQueryParams) override fun toString() = - "CasParserCamsKfintechParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" + "CamsKfintechParseParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/camskfintech/LinkedHolder.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/camskfintech/LinkedHolder.kt new file mode 100644 index 0000000..9aa025d --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/camskfintech/LinkedHolder.kt @@ -0,0 +1,189 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.camskfintech + +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonField +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.errors.CasParserInvalidDataException +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 + +class LinkedHolder +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val name: JsonField, + private val pan: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("pan") @ExcludeMissing pan: JsonField = JsonMissing.of(), + ) : this(name, pan, mutableMapOf()) + + /** + * Name of the account holder + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun name(): Optional = name.getOptional("name") + + /** + * PAN of the account holder + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun pan(): Optional = pan.getOptional("pan") + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + + /** + * Returns the raw JSON value of [pan]. + * + * Unlike [pan], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("pan") @ExcludeMissing fun _pan(): JsonField = pan + + @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 [LinkedHolder]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [LinkedHolder]. */ + class Builder internal constructor() { + + private var name: JsonField = JsonMissing.of() + private var pan: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(linkedHolder: LinkedHolder) = apply { + name = linkedHolder.name + pan = linkedHolder.pan + additionalProperties = linkedHolder.additionalProperties.toMutableMap() + } + + /** Name of the account holder */ + fun name(name: String) = name(JsonField.of(name)) + + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun name(name: JsonField) = apply { this.name = name } + + /** PAN of the account holder */ + fun pan(pan: String) = pan(JsonField.of(pan)) + + /** + * Sets [Builder.pan] to an arbitrary JSON value. + * + * You should usually call [Builder.pan] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun pan(pan: JsonField) = apply { this.pan = pan } + + 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 [LinkedHolder]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): LinkedHolder = LinkedHolder(name, pan, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): LinkedHolder = apply { + if (validated) { + return@apply + } + + name() + pan() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (name.asKnown().isPresent) 1 else 0) + (if (pan.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is LinkedHolder && + name == other.name && + pan == other.pan && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(name, pan, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "LinkedHolder{name=$name, pan=$pan, additionalProperties=$additionalProperties}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/camskfintech/Transaction.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/camskfintech/Transaction.kt new file mode 100644 index 0000000..64c2700 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/camskfintech/Transaction.kt @@ -0,0 +1,1129 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.camskfintech + +import com.cas_parser.api.core.Enum +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonField +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.errors.CasParserInvalidDataException +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.time.LocalDate +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Unified transaction schema for all holding types (MF folios, equities, bonds, etc.) */ +class Transaction +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val additionalInfo: JsonField, + private val amount: JsonField, + private val balance: JsonField, + private val date: JsonField, + private val description: JsonField, + private val dividendRate: JsonField, + private val nav: JsonField, + private val type: JsonField, + private val units: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("additional_info") + @ExcludeMissing + additionalInfo: JsonField = JsonMissing.of(), + @JsonProperty("amount") @ExcludeMissing amount: JsonField = JsonMissing.of(), + @JsonProperty("balance") @ExcludeMissing balance: JsonField = JsonMissing.of(), + @JsonProperty("date") @ExcludeMissing date: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + description: JsonField = JsonMissing.of(), + @JsonProperty("dividend_rate") + @ExcludeMissing + dividendRate: JsonField = JsonMissing.of(), + @JsonProperty("nav") @ExcludeMissing nav: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), + @JsonProperty("units") @ExcludeMissing units: JsonField = JsonMissing.of(), + ) : this( + additionalInfo, + amount, + balance, + date, + description, + dividendRate, + nav, + type, + units, + mutableMapOf(), + ) + + /** + * Additional transaction-specific fields that vary by source + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun additionalInfo(): Optional = additionalInfo.getOptional("additional_info") + + /** + * Transaction amount in currency (computed from units × price/NAV) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun amount(): Optional = amount.getOptional("amount") + + /** + * Balance units after transaction + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun balance(): Optional = balance.getOptional("balance") + + /** + * Transaction date (YYYY-MM-DD) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun date(): Optional = date.getOptional("date") + + /** + * Transaction description/particulars + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = description.getOptional("description") + + /** + * Dividend rate (for DIVIDEND_PAYOUT transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun dividendRate(): Optional = dividendRate.getOptional("dividend_rate") + + /** + * NAV/price per unit on transaction date + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun nav(): Optional = nav.getOptional("nav") + + /** + * Transaction type. Possible values are PURCHASE, PURCHASE_SIP, REDEMPTION, SWITCH_IN, + * SWITCH_IN_MERGER, SWITCH_OUT, SWITCH_OUT_MERGER, DIVIDEND_PAYOUT, DIVIDEND_REINVEST, + * SEGREGATION, STAMP_DUTY_TAX, TDS_TAX, STT_TAX, MISC, REVERSAL, UNKNOWN. + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun type(): Optional = type.getOptional("type") + + /** + * Number of units involved in transaction + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun units(): Optional = units.getOptional("units") + + /** + * Returns the raw JSON value of [additionalInfo]. + * + * Unlike [additionalInfo], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("additional_info") + @ExcludeMissing + fun _additionalInfo(): JsonField = additionalInfo + + /** + * Returns the raw JSON value of [amount]. + * + * Unlike [amount], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("amount") @ExcludeMissing fun _amount(): JsonField = amount + + /** + * Returns the raw JSON value of [balance]. + * + * Unlike [balance], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("balance") @ExcludeMissing fun _balance(): JsonField = balance + + /** + * Returns the raw JSON value of [date]. + * + * Unlike [date], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("date") @ExcludeMissing fun _date(): JsonField = date + + /** + * Returns the raw JSON value of [description]. + * + * Unlike [description], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("description") @ExcludeMissing fun _description(): JsonField = description + + /** + * Returns the raw JSON value of [dividendRate]. + * + * Unlike [dividendRate], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("dividend_rate") + @ExcludeMissing + fun _dividendRate(): JsonField = dividendRate + + /** + * Returns the raw JSON value of [nav]. + * + * Unlike [nav], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("nav") @ExcludeMissing fun _nav(): JsonField = nav + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + + /** + * Returns the raw JSON value of [units]. + * + * Unlike [units], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("units") @ExcludeMissing fun _units(): JsonField = units + + @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 [Transaction]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Transaction]. */ + class Builder internal constructor() { + + private var additionalInfo: JsonField = JsonMissing.of() + private var amount: JsonField = JsonMissing.of() + private var balance: JsonField = JsonMissing.of() + private var date: JsonField = JsonMissing.of() + private var description: JsonField = JsonMissing.of() + private var dividendRate: JsonField = JsonMissing.of() + private var nav: JsonField = JsonMissing.of() + private var type: JsonField = JsonMissing.of() + private var units: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(transaction: Transaction) = apply { + additionalInfo = transaction.additionalInfo + amount = transaction.amount + balance = transaction.balance + date = transaction.date + description = transaction.description + dividendRate = transaction.dividendRate + nav = transaction.nav + type = transaction.type + units = transaction.units + additionalProperties = transaction.additionalProperties.toMutableMap() + } + + /** Additional transaction-specific fields that vary by source */ + fun additionalInfo(additionalInfo: AdditionalInfo) = + additionalInfo(JsonField.of(additionalInfo)) + + /** + * Sets [Builder.additionalInfo] to an arbitrary JSON value. + * + * You should usually call [Builder.additionalInfo] with a well-typed [AdditionalInfo] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun additionalInfo(additionalInfo: JsonField) = apply { + this.additionalInfo = additionalInfo + } + + /** Transaction amount in currency (computed from units × price/NAV) */ + fun amount(amount: Float?) = amount(JsonField.ofNullable(amount)) + + /** + * Alias for [Builder.amount]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun amount(amount: Float) = amount(amount as Float?) + + /** Alias for calling [Builder.amount] with `amount.orElse(null)`. */ + fun amount(amount: Optional) = amount(amount.getOrNull()) + + /** + * Sets [Builder.amount] to an arbitrary JSON value. + * + * You should usually call [Builder.amount] with a well-typed [Float] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun amount(amount: JsonField) = apply { this.amount = amount } + + /** Balance units after transaction */ + fun balance(balance: Float) = balance(JsonField.of(balance)) + + /** + * Sets [Builder.balance] to an arbitrary JSON value. + * + * You should usually call [Builder.balance] with a well-typed [Float] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun balance(balance: JsonField) = apply { this.balance = balance } + + /** Transaction date (YYYY-MM-DD) */ + fun date(date: LocalDate) = date(JsonField.of(date)) + + /** + * Sets [Builder.date] to an arbitrary JSON value. + * + * You should usually call [Builder.date] with a well-typed [LocalDate] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun date(date: JsonField) = apply { this.date = date } + + /** Transaction description/particulars */ + fun description(description: String) = description(JsonField.of(description)) + + /** + * Sets [Builder.description] to an arbitrary JSON value. + * + * You should usually call [Builder.description] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun description(description: JsonField) = apply { this.description = description } + + /** Dividend rate (for DIVIDEND_PAYOUT transactions) */ + fun dividendRate(dividendRate: Float?) = dividendRate(JsonField.ofNullable(dividendRate)) + + /** + * Alias for [Builder.dividendRate]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun dividendRate(dividendRate: Float) = dividendRate(dividendRate as Float?) + + /** Alias for calling [Builder.dividendRate] with `dividendRate.orElse(null)`. */ + fun dividendRate(dividendRate: Optional) = dividendRate(dividendRate.getOrNull()) + + /** + * Sets [Builder.dividendRate] to an arbitrary JSON value. + * + * You should usually call [Builder.dividendRate] with a well-typed [Float] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun dividendRate(dividendRate: JsonField) = apply { + this.dividendRate = dividendRate + } + + /** NAV/price per unit on transaction date */ + fun nav(nav: Float?) = nav(JsonField.ofNullable(nav)) + + /** + * Alias for [Builder.nav]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun nav(nav: Float) = nav(nav as Float?) + + /** Alias for calling [Builder.nav] with `nav.orElse(null)`. */ + fun nav(nav: Optional) = nav(nav.getOrNull()) + + /** + * Sets [Builder.nav] to an arbitrary JSON value. + * + * You should usually call [Builder.nav] with a well-typed [Float] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun nav(nav: JsonField) = apply { this.nav = nav } + + /** + * Transaction type. Possible values are PURCHASE, PURCHASE_SIP, REDEMPTION, SWITCH_IN, + * SWITCH_IN_MERGER, SWITCH_OUT, SWITCH_OUT_MERGER, DIVIDEND_PAYOUT, DIVIDEND_REINVEST, + * SEGREGATION, STAMP_DUTY_TAX, TDS_TAX, STT_TAX, MISC, REVERSAL, UNKNOWN. + */ + fun type(type: Type) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun type(type: JsonField) = apply { this.type = type } + + /** Number of units involved in transaction */ + fun units(units: Float) = units(JsonField.of(units)) + + /** + * Sets [Builder.units] to an arbitrary JSON value. + * + * You should usually call [Builder.units] with a well-typed [Float] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun units(units: JsonField) = apply { this.units = units } + + 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 [Transaction]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Transaction = + Transaction( + additionalInfo, + amount, + balance, + date, + description, + dividendRate, + nav, + type, + units, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Transaction = apply { + if (validated) { + return@apply + } + + additionalInfo().ifPresent { it.validate() } + amount() + balance() + date() + description() + dividendRate() + nav() + type().ifPresent { it.validate() } + units() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 = + (additionalInfo.asKnown().getOrNull()?.validity() ?: 0) + + (if (amount.asKnown().isPresent) 1 else 0) + + (if (balance.asKnown().isPresent) 1 else 0) + + (if (date.asKnown().isPresent) 1 else 0) + + (if (description.asKnown().isPresent) 1 else 0) + + (if (dividendRate.asKnown().isPresent) 1 else 0) + + (if (nav.asKnown().isPresent) 1 else 0) + + (type.asKnown().getOrNull()?.validity() ?: 0) + + (if (units.asKnown().isPresent) 1 else 0) + + /** Additional transaction-specific fields that vary by source */ + class AdditionalInfo + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val capitalWithdrawal: JsonField, + private val credit: JsonField, + private val debit: JsonField, + private val incomeDistribution: JsonField, + private val orderNo: JsonField, + private val price: JsonField, + private val stampDuty: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("capital_withdrawal") + @ExcludeMissing + capitalWithdrawal: JsonField = JsonMissing.of(), + @JsonProperty("credit") @ExcludeMissing credit: JsonField = JsonMissing.of(), + @JsonProperty("debit") @ExcludeMissing debit: JsonField = JsonMissing.of(), + @JsonProperty("income_distribution") + @ExcludeMissing + incomeDistribution: JsonField = JsonMissing.of(), + @JsonProperty("order_no") @ExcludeMissing orderNo: JsonField = JsonMissing.of(), + @JsonProperty("price") @ExcludeMissing price: JsonField = JsonMissing.of(), + @JsonProperty("stamp_duty") + @ExcludeMissing + stampDuty: JsonField = JsonMissing.of(), + ) : this( + capitalWithdrawal, + credit, + debit, + incomeDistribution, + orderNo, + price, + stampDuty, + mutableMapOf(), + ) + + /** + * Capital withdrawal amount (CDSL MF transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun capitalWithdrawal(): Optional = + capitalWithdrawal.getOptional("capital_withdrawal") + + /** + * Units credited (demat transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun credit(): Optional = credit.getOptional("credit") + + /** + * Units debited (demat transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun debit(): Optional = debit.getOptional("debit") + + /** + * Income distribution amount (CDSL MF transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun incomeDistribution(): Optional = + incomeDistribution.getOptional("income_distribution") + + /** + * Order/transaction reference number (demat transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun orderNo(): Optional = orderNo.getOptional("order_no") + + /** + * Price per unit (NSDL/CDSL MF transactions) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun price(): Optional = price.getOptional("price") + + /** + * Stamp duty charged + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun stampDuty(): Optional = stampDuty.getOptional("stamp_duty") + + /** + * Returns the raw JSON value of [capitalWithdrawal]. + * + * Unlike [capitalWithdrawal], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("capital_withdrawal") + @ExcludeMissing + fun _capitalWithdrawal(): JsonField = capitalWithdrawal + + /** + * Returns the raw JSON value of [credit]. + * + * Unlike [credit], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("credit") @ExcludeMissing fun _credit(): JsonField = credit + + /** + * Returns the raw JSON value of [debit]. + * + * Unlike [debit], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("debit") @ExcludeMissing fun _debit(): JsonField = debit + + /** + * Returns the raw JSON value of [incomeDistribution]. + * + * Unlike [incomeDistribution], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("income_distribution") + @ExcludeMissing + fun _incomeDistribution(): JsonField = incomeDistribution + + /** + * Returns the raw JSON value of [orderNo]. + * + * Unlike [orderNo], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("order_no") @ExcludeMissing fun _orderNo(): JsonField = orderNo + + /** + * Returns the raw JSON value of [price]. + * + * Unlike [price], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("price") @ExcludeMissing fun _price(): JsonField = price + + /** + * Returns the raw JSON value of [stampDuty]. + * + * Unlike [stampDuty], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("stamp_duty") @ExcludeMissing fun _stampDuty(): JsonField = stampDuty + + @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 [AdditionalInfo]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AdditionalInfo]. */ + class Builder internal constructor() { + + private var capitalWithdrawal: JsonField = JsonMissing.of() + private var credit: JsonField = JsonMissing.of() + private var debit: JsonField = JsonMissing.of() + private var incomeDistribution: JsonField = JsonMissing.of() + private var orderNo: JsonField = JsonMissing.of() + private var price: JsonField = JsonMissing.of() + private var stampDuty: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(additionalInfo: AdditionalInfo) = apply { + capitalWithdrawal = additionalInfo.capitalWithdrawal + credit = additionalInfo.credit + debit = additionalInfo.debit + incomeDistribution = additionalInfo.incomeDistribution + orderNo = additionalInfo.orderNo + price = additionalInfo.price + stampDuty = additionalInfo.stampDuty + additionalProperties = additionalInfo.additionalProperties.toMutableMap() + } + + /** Capital withdrawal amount (CDSL MF transactions) */ + fun capitalWithdrawal(capitalWithdrawal: Float) = + capitalWithdrawal(JsonField.of(capitalWithdrawal)) + + /** + * Sets [Builder.capitalWithdrawal] to an arbitrary JSON value. + * + * You should usually call [Builder.capitalWithdrawal] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun capitalWithdrawal(capitalWithdrawal: JsonField) = apply { + this.capitalWithdrawal = capitalWithdrawal + } + + /** Units credited (demat transactions) */ + fun credit(credit: Float) = credit(JsonField.of(credit)) + + /** + * Sets [Builder.credit] to an arbitrary JSON value. + * + * You should usually call [Builder.credit] with a well-typed [Float] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun credit(credit: JsonField) = apply { this.credit = credit } + + /** Units debited (demat transactions) */ + fun debit(debit: Float) = debit(JsonField.of(debit)) + + /** + * Sets [Builder.debit] to an arbitrary JSON value. + * + * You should usually call [Builder.debit] with a well-typed [Float] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun debit(debit: JsonField) = apply { this.debit = debit } + + /** Income distribution amount (CDSL MF transactions) */ + fun incomeDistribution(incomeDistribution: Float) = + incomeDistribution(JsonField.of(incomeDistribution)) + + /** + * Sets [Builder.incomeDistribution] to an arbitrary JSON value. + * + * You should usually call [Builder.incomeDistribution] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun incomeDistribution(incomeDistribution: JsonField) = apply { + this.incomeDistribution = incomeDistribution + } + + /** Order/transaction reference number (demat transactions) */ + fun orderNo(orderNo: String) = orderNo(JsonField.of(orderNo)) + + /** + * Sets [Builder.orderNo] to an arbitrary JSON value. + * + * You should usually call [Builder.orderNo] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun orderNo(orderNo: JsonField) = apply { this.orderNo = orderNo } + + /** Price per unit (NSDL/CDSL MF transactions) */ + fun price(price: Float) = price(JsonField.of(price)) + + /** + * Sets [Builder.price] to an arbitrary JSON value. + * + * You should usually call [Builder.price] with a well-typed [Float] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun price(price: JsonField) = apply { this.price = price } + + /** Stamp duty charged */ + fun stampDuty(stampDuty: Float) = stampDuty(JsonField.of(stampDuty)) + + /** + * Sets [Builder.stampDuty] to an arbitrary JSON value. + * + * You should usually call [Builder.stampDuty] with a well-typed [Float] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun stampDuty(stampDuty: JsonField) = apply { this.stampDuty = stampDuty } + + 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 [AdditionalInfo]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): AdditionalInfo = + AdditionalInfo( + capitalWithdrawal, + credit, + debit, + incomeDistribution, + orderNo, + price, + stampDuty, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): AdditionalInfo = apply { + if (validated) { + return@apply + } + + capitalWithdrawal() + credit() + debit() + incomeDistribution() + orderNo() + price() + stampDuty() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (capitalWithdrawal.asKnown().isPresent) 1 else 0) + + (if (credit.asKnown().isPresent) 1 else 0) + + (if (debit.asKnown().isPresent) 1 else 0) + + (if (incomeDistribution.asKnown().isPresent) 1 else 0) + + (if (orderNo.asKnown().isPresent) 1 else 0) + + (if (price.asKnown().isPresent) 1 else 0) + + (if (stampDuty.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AdditionalInfo && + capitalWithdrawal == other.capitalWithdrawal && + credit == other.credit && + debit == other.debit && + incomeDistribution == other.incomeDistribution && + orderNo == other.orderNo && + price == other.price && + stampDuty == other.stampDuty && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + capitalWithdrawal, + credit, + debit, + incomeDistribution, + orderNo, + price, + stampDuty, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AdditionalInfo{capitalWithdrawal=$capitalWithdrawal, credit=$credit, debit=$debit, incomeDistribution=$incomeDistribution, orderNo=$orderNo, price=$price, stampDuty=$stampDuty, additionalProperties=$additionalProperties}" + } + + /** + * Transaction type. Possible values are PURCHASE, PURCHASE_SIP, REDEMPTION, SWITCH_IN, + * SWITCH_IN_MERGER, SWITCH_OUT, SWITCH_OUT_MERGER, DIVIDEND_PAYOUT, DIVIDEND_REINVEST, + * SEGREGATION, STAMP_DUTY_TAX, TDS_TAX, STT_TAX, MISC, REVERSAL, UNKNOWN. + */ + class Type @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val PURCHASE = of("PURCHASE") + + @JvmField val PURCHASE_SIP = of("PURCHASE_SIP") + + @JvmField val REDEMPTION = of("REDEMPTION") + + @JvmField val SWITCH_IN = of("SWITCH_IN") + + @JvmField val SWITCH_IN_MERGER = of("SWITCH_IN_MERGER") + + @JvmField val SWITCH_OUT = of("SWITCH_OUT") + + @JvmField val SWITCH_OUT_MERGER = of("SWITCH_OUT_MERGER") + + @JvmField val DIVIDEND_PAYOUT = of("DIVIDEND_PAYOUT") + + @JvmField val DIVIDEND_REINVEST = of("DIVIDEND_REINVEST") + + @JvmField val SEGREGATION = of("SEGREGATION") + + @JvmField val STAMP_DUTY_TAX = of("STAMP_DUTY_TAX") + + @JvmField val TDS_TAX = of("TDS_TAX") + + @JvmField val STT_TAX = of("STT_TAX") + + @JvmField val MISC = of("MISC") + + @JvmField val REVERSAL = of("REVERSAL") + + @JvmField val UNKNOWN = of("UNKNOWN") + + @JvmStatic fun of(value: String) = Type(JsonField.of(value)) + } + + /** An enum containing [Type]'s known values. */ + enum class Known { + PURCHASE, + PURCHASE_SIP, + REDEMPTION, + SWITCH_IN, + SWITCH_IN_MERGER, + SWITCH_OUT, + SWITCH_OUT_MERGER, + DIVIDEND_PAYOUT, + DIVIDEND_REINVEST, + SEGREGATION, + STAMP_DUTY_TAX, + TDS_TAX, + STT_TAX, + MISC, + REVERSAL, + UNKNOWN, + } + + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Type] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + PURCHASE, + PURCHASE_SIP, + REDEMPTION, + SWITCH_IN, + SWITCH_IN_MERGER, + SWITCH_OUT, + SWITCH_OUT_MERGER, + DIVIDEND_PAYOUT, + DIVIDEND_REINVEST, + SEGREGATION, + STAMP_DUTY_TAX, + TDS_TAX, + STT_TAX, + MISC, + REVERSAL, + UNKNOWN, + /** An enum member indicating that [Type] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + PURCHASE -> Value.PURCHASE + PURCHASE_SIP -> Value.PURCHASE_SIP + REDEMPTION -> Value.REDEMPTION + SWITCH_IN -> Value.SWITCH_IN + SWITCH_IN_MERGER -> Value.SWITCH_IN_MERGER + SWITCH_OUT -> Value.SWITCH_OUT + SWITCH_OUT_MERGER -> Value.SWITCH_OUT_MERGER + DIVIDEND_PAYOUT -> Value.DIVIDEND_PAYOUT + DIVIDEND_REINVEST -> Value.DIVIDEND_REINVEST + SEGREGATION -> Value.SEGREGATION + STAMP_DUTY_TAX -> Value.STAMP_DUTY_TAX + TDS_TAX -> Value.TDS_TAX + STT_TAX -> Value.STT_TAX + MISC -> Value.MISC + REVERSAL -> Value.REVERSAL + UNKNOWN -> Value.UNKNOWN + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws CasParserInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + PURCHASE -> Known.PURCHASE + PURCHASE_SIP -> Known.PURCHASE_SIP + REDEMPTION -> Known.REDEMPTION + SWITCH_IN -> Known.SWITCH_IN + SWITCH_IN_MERGER -> Known.SWITCH_IN_MERGER + SWITCH_OUT -> Known.SWITCH_OUT + SWITCH_OUT_MERGER -> Known.SWITCH_OUT_MERGER + DIVIDEND_PAYOUT -> Known.DIVIDEND_PAYOUT + DIVIDEND_REINVEST -> Known.DIVIDEND_REINVEST + SEGREGATION -> Known.SEGREGATION + STAMP_DUTY_TAX -> Known.STAMP_DUTY_TAX + TDS_TAX -> Known.TDS_TAX + STT_TAX -> Known.STT_TAX + MISC -> Known.MISC + REVERSAL -> Known.REVERSAL + UNKNOWN -> Known.UNKNOWN + else -> throw CasParserInvalidDataException("Unknown Type: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws CasParserInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CasParserInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): Type = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Type && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Transaction && + additionalInfo == other.additionalInfo && + amount == other.amount && + balance == other.balance && + date == other.date && + description == other.description && + dividendRate == other.dividendRate && + nav == other.nav && + type == other.type && + units == other.units && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + additionalInfo, + amount, + balance, + date, + description, + dividendRate, + nav, + type, + units, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Transaction{additionalInfo=$additionalInfo, amount=$amount, balance=$balance, date=$date, description=$description, dividendRate=$dividendRate, nav=$nav, type=$type, units=$units, additionalProperties=$additionalProperties}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/UnifiedResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/camskfintech/UnifiedResponse.kt similarity index 54% rename from cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/UnifiedResponse.kt rename to cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/camskfintech/UnifiedResponse.kt index 40030b6..6a27c6f 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/UnifiedResponse.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/camskfintech/UnifiedResponse.kt @@ -1,6 +1,6 @@ // File generated from our OpenAPI spec by Stainless. -package com.cas_parser.api.models.casparser +package com.cas_parser.api.models.camskfintech import com.cas_parser.api.core.Enum import com.cas_parser.api.core.ExcludeMissing @@ -2345,1211 +2345,615 @@ private constructor( "AdditionalInfo{closeUnits=$closeUnits, openUnits=$openUnits, additionalProperties=$additionalProperties}" } - /** - * Unified transaction schema for all holding types (MF folios, equities, bonds, - * etc.) - */ - class Transaction - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val additionalInfo: JsonField, - private val amount: JsonField, - private val balance: JsonField, - private val date: JsonField, - private val description: JsonField, - private val dividendRate: JsonField, - private val nav: JsonField, - private val type: JsonField, - private val units: JsonField, - private val additionalProperties: MutableMap, - ) { + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - @JsonCreator - private constructor( - @JsonProperty("additional_info") - @ExcludeMissing - additionalInfo: JsonField = JsonMissing.of(), - @JsonProperty("amount") - @ExcludeMissing - amount: JsonField = JsonMissing.of(), - @JsonProperty("balance") - @ExcludeMissing - balance: JsonField = JsonMissing.of(), - @JsonProperty("date") - @ExcludeMissing - date: JsonField = JsonMissing.of(), - @JsonProperty("description") - @ExcludeMissing - description: JsonField = JsonMissing.of(), - @JsonProperty("dividend_rate") - @ExcludeMissing - dividendRate: JsonField = JsonMissing.of(), - @JsonProperty("nav") - @ExcludeMissing - nav: JsonField = JsonMissing.of(), - @JsonProperty("type") - @ExcludeMissing - type: JsonField = JsonMissing.of(), - @JsonProperty("units") - @ExcludeMissing - units: JsonField = JsonMissing.of(), - ) : this( + return other is Aif && + additionalInfo == other.additionalInfo && + isin == other.isin && + name == other.name && + transactions == other.transactions && + units == other.units && + value == other.value && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( additionalInfo, - amount, - balance, - date, - description, - dividendRate, - nav, - type, + isin, + name, + transactions, units, - mutableMapOf(), + value, + additionalProperties, ) + } - /** - * Additional transaction-specific fields that vary by source - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun additionalInfo(): Optional = - additionalInfo.getOptional("additional_info") - - /** - * Transaction amount in currency (computed from units × price/NAV) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun amount(): Optional = amount.getOptional("amount") - - /** - * Balance units after transaction - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun balance(): Optional = balance.getOptional("balance") - - /** - * Transaction date (YYYY-MM-DD) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun date(): Optional = date.getOptional("date") - - /** - * Transaction description/particulars - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun description(): Optional = description.getOptional("description") - - /** - * Dividend rate (for DIVIDEND_PAYOUT transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun dividendRate(): Optional = dividendRate.getOptional("dividend_rate") - - /** - * NAV/price per unit on transaction date - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun nav(): Optional = nav.getOptional("nav") + override fun hashCode(): Int = hashCode - /** - * Transaction type. Possible values are PURCHASE, PURCHASE_SIP, REDEMPTION, - * SWITCH_IN, SWITCH_IN_MERGER, SWITCH_OUT, SWITCH_OUT_MERGER, DIVIDEND_PAYOUT, - * DIVIDEND_REINVEST, SEGREGATION, STAMP_DUTY_TAX, TDS_TAX, STT_TAX, MISC, - * REVERSAL, UNKNOWN. - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun type(): Optional = type.getOptional("type") + override fun toString() = + "Aif{additionalInfo=$additionalInfo, isin=$isin, name=$name, transactions=$transactions, units=$units, value=$value, additionalProperties=$additionalProperties}" + } - /** - * Number of units involved in transaction - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun units(): Optional = units.getOptional("units") + class CorporateBond + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val additionalInfo: JsonField, + private val isin: JsonField, + private val name: JsonField, + private val transactions: JsonField>, + private val units: JsonField, + private val value: JsonField, + private val additionalProperties: MutableMap, + ) { - /** - * Returns the raw JSON value of [additionalInfo]. - * - * Unlike [additionalInfo], this method doesn't throw if the JSON field has an - * unexpected type. - */ + @JsonCreator + private constructor( @JsonProperty("additional_info") @ExcludeMissing - fun _additionalInfo(): JsonField = additionalInfo - - /** - * Returns the raw JSON value of [amount]. - * - * Unlike [amount], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("amount") @ExcludeMissing fun _amount(): JsonField = amount - - /** - * Returns the raw JSON value of [balance]. - * - * Unlike [balance], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("balance") + additionalInfo: JsonField = JsonMissing.of(), + @JsonProperty("isin") @ExcludeMissing - fun _balance(): JsonField = balance - - /** - * Returns the raw JSON value of [date]. - * - * Unlike [date], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("date") @ExcludeMissing fun _date(): JsonField = date - - /** - * Returns the raw JSON value of [description]. - * - * Unlike [description], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("description") + isin: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing - fun _description(): JsonField = description - - /** - * Returns the raw JSON value of [dividendRate]. - * - * Unlike [dividendRate], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("dividend_rate") + name: JsonField = JsonMissing.of(), + @JsonProperty("transactions") @ExcludeMissing - fun _dividendRate(): JsonField = dividendRate - - /** - * Returns the raw JSON value of [nav]. - * - * Unlike [nav], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("nav") @ExcludeMissing fun _nav(): JsonField = nav - - /** - * Returns the raw JSON value of [type]. - * - * Unlike [type], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type - - /** - * Returns the raw JSON value of [units]. - * - * Unlike [units], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("units") @ExcludeMissing fun _units(): JsonField = units - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter + transactions: JsonField> = JsonMissing.of(), + @JsonProperty("units") @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) + units: JsonField = JsonMissing.of(), + @JsonProperty("value") + @ExcludeMissing + value: JsonField = JsonMissing.of(), + ) : this(additionalInfo, isin, name, transactions, units, value, mutableMapOf()) - fun toBuilder() = Builder().from(this) + /** + * Additional information specific to the corporate bond + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun additionalInfo(): Optional = + additionalInfo.getOptional("additional_info") - companion object { + /** + * ISIN code of the corporate bond + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun isin(): Optional = isin.getOptional("isin") - /** - * Returns a mutable builder for constructing an instance of [Transaction]. - */ - @JvmStatic fun builder() = Builder() - } + /** + * Name of the corporate bond + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun name(): Optional = name.getOptional("name") - /** A builder for [Transaction]. */ - class Builder internal constructor() { + /** + * List of transactions for this holding (beta) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun transactions(): Optional> = + transactions.getOptional("transactions") - private var additionalInfo: JsonField = JsonMissing.of() - private var amount: JsonField = JsonMissing.of() - private var balance: JsonField = JsonMissing.of() - private var date: JsonField = JsonMissing.of() - private var description: JsonField = JsonMissing.of() - private var dividendRate: JsonField = JsonMissing.of() - private var nav: JsonField = JsonMissing.of() - private var type: JsonField = JsonMissing.of() - private var units: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = - mutableMapOf() + /** + * Number of units held + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun units(): Optional = units.getOptional("units") - @JvmSynthetic - internal fun from(transaction: Transaction) = apply { - additionalInfo = transaction.additionalInfo - amount = transaction.amount - balance = transaction.balance - date = transaction.date - description = transaction.description - dividendRate = transaction.dividendRate - nav = transaction.nav - type = transaction.type - units = transaction.units - additionalProperties = transaction.additionalProperties.toMutableMap() - } + /** + * Current market value of the holding + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun value(): Optional = value.getOptional("value") - /** Additional transaction-specific fields that vary by source */ - fun additionalInfo(additionalInfo: AdditionalInfo) = - additionalInfo(JsonField.of(additionalInfo)) + /** + * Returns the raw JSON value of [additionalInfo]. + * + * Unlike [additionalInfo], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("additional_info") + @ExcludeMissing + fun _additionalInfo(): JsonField = additionalInfo - /** - * Sets [Builder.additionalInfo] to an arbitrary JSON value. - * - * You should usually call [Builder.additionalInfo] with a well-typed - * [AdditionalInfo] value instead. This method is primarily for setting the - * field to an undocumented or not yet supported value. - */ - fun additionalInfo(additionalInfo: JsonField) = apply { - this.additionalInfo = additionalInfo - } + /** + * Returns the raw JSON value of [isin]. + * + * Unlike [isin], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("isin") @ExcludeMissing fun _isin(): JsonField = isin - /** Transaction amount in currency (computed from units × price/NAV) */ - fun amount(amount: Float?) = amount(JsonField.ofNullable(amount)) + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name - /** - * Alias for [Builder.amount]. - * - * This unboxed primitive overload exists for backwards compatibility. - */ - fun amount(amount: Float) = amount(amount as Float?) - - /** Alias for calling [Builder.amount] with `amount.orElse(null)`. */ - fun amount(amount: Optional) = amount(amount.getOrNull()) - - /** - * Sets [Builder.amount] to an arbitrary JSON value. - * - * You should usually call [Builder.amount] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun amount(amount: JsonField) = apply { this.amount = amount } + /** + * Returns the raw JSON value of [transactions]. + * + * Unlike [transactions], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("transactions") + @ExcludeMissing + fun _transactions(): JsonField> = transactions - /** Balance units after transaction */ - fun balance(balance: Float) = balance(JsonField.of(balance)) + /** + * Returns the raw JSON value of [units]. + * + * Unlike [units], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("units") @ExcludeMissing fun _units(): JsonField = units - /** - * Sets [Builder.balance] to an arbitrary JSON value. - * - * You should usually call [Builder.balance] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun balance(balance: JsonField) = apply { this.balance = balance } + /** + * Returns the raw JSON value of [value]. + * + * Unlike [value], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("value") @ExcludeMissing fun _value(): JsonField = value - /** Transaction date (YYYY-MM-DD) */ - fun date(date: LocalDate) = date(JsonField.of(date)) + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } - /** - * Sets [Builder.date] to an arbitrary JSON value. - * - * You should usually call [Builder.date] with a well-typed [LocalDate] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun date(date: JsonField) = apply { this.date = date } + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) - /** Transaction description/particulars */ - fun description(description: String) = - description(JsonField.of(description)) + fun toBuilder() = Builder().from(this) - /** - * Sets [Builder.description] to an arbitrary JSON value. - * - * You should usually call [Builder.description] with a well-typed [String] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun description(description: JsonField) = apply { - this.description = description - } + companion object { - /** Dividend rate (for DIVIDEND_PAYOUT transactions) */ - fun dividendRate(dividendRate: Float?) = - dividendRate(JsonField.ofNullable(dividendRate)) + /** + * Returns a mutable builder for constructing an instance of [CorporateBond]. + */ + @JvmStatic fun builder() = Builder() + } - /** - * Alias for [Builder.dividendRate]. - * - * This unboxed primitive overload exists for backwards compatibility. - */ - fun dividendRate(dividendRate: Float) = dividendRate(dividendRate as Float?) + /** A builder for [CorporateBond]. */ + class Builder internal constructor() { - /** - * Alias for calling [Builder.dividendRate] with - * `dividendRate.orElse(null)`. - */ - fun dividendRate(dividendRate: Optional) = - dividendRate(dividendRate.getOrNull()) + private var additionalInfo: JsonField = JsonMissing.of() + private var isin: JsonField = JsonMissing.of() + private var name: JsonField = JsonMissing.of() + private var transactions: JsonField>? = null + private var units: JsonField = JsonMissing.of() + private var value: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() - /** - * Sets [Builder.dividendRate] to an arbitrary JSON value. - * - * You should usually call [Builder.dividendRate] with a well-typed [Float] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun dividendRate(dividendRate: JsonField) = apply { - this.dividendRate = dividendRate - } + @JvmSynthetic + internal fun from(corporateBond: CorporateBond) = apply { + additionalInfo = corporateBond.additionalInfo + isin = corporateBond.isin + name = corporateBond.name + transactions = corporateBond.transactions.map { it.toMutableList() } + units = corporateBond.units + value = corporateBond.value + additionalProperties = corporateBond.additionalProperties.toMutableMap() + } - /** NAV/price per unit on transaction date */ - fun nav(nav: Float?) = nav(JsonField.ofNullable(nav)) + /** Additional information specific to the corporate bond */ + fun additionalInfo(additionalInfo: AdditionalInfo) = + additionalInfo(JsonField.of(additionalInfo)) - /** - * Alias for [Builder.nav]. - * - * This unboxed primitive overload exists for backwards compatibility. - */ - fun nav(nav: Float) = nav(nav as Float?) + /** + * Sets [Builder.additionalInfo] to an arbitrary JSON value. + * + * You should usually call [Builder.additionalInfo] with a well-typed + * [AdditionalInfo] value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun additionalInfo(additionalInfo: JsonField) = apply { + this.additionalInfo = additionalInfo + } - /** Alias for calling [Builder.nav] with `nav.orElse(null)`. */ - fun nav(nav: Optional) = nav(nav.getOrNull()) + /** ISIN code of the corporate bond */ + fun isin(isin: String) = isin(JsonField.of(isin)) - /** - * Sets [Builder.nav] to an arbitrary JSON value. - * - * You should usually call [Builder.nav] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun nav(nav: JsonField) = apply { this.nav = nav } + /** + * Sets [Builder.isin] to an arbitrary JSON value. + * + * You should usually call [Builder.isin] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun isin(isin: JsonField) = apply { this.isin = isin } - /** - * Transaction type. Possible values are PURCHASE, PURCHASE_SIP, REDEMPTION, - * SWITCH_IN, SWITCH_IN_MERGER, SWITCH_OUT, SWITCH_OUT_MERGER, - * DIVIDEND_PAYOUT, DIVIDEND_REINVEST, SEGREGATION, STAMP_DUTY_TAX, TDS_TAX, - * STT_TAX, MISC, REVERSAL, UNKNOWN. - */ - fun type(type: Type) = type(JsonField.of(type)) + /** Name of the corporate bond */ + fun name(name: String) = name(JsonField.of(name)) - /** - * Sets [Builder.type] to an arbitrary JSON value. - * - * You should usually call [Builder.type] with a well-typed [Type] value - * instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun type(type: JsonField) = apply { this.type = type } + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun name(name: JsonField) = apply { this.name = name } - /** Number of units involved in transaction */ - fun units(units: Float) = units(JsonField.of(units)) + /** List of transactions for this holding (beta) */ + fun transactions(transactions: List) = + transactions(JsonField.of(transactions)) - /** - * Sets [Builder.units] to an arbitrary JSON value. - * - * You should usually call [Builder.units] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun units(units: JsonField) = apply { this.units = units } + /** + * Sets [Builder.transactions] to an arbitrary JSON value. + * + * You should usually call [Builder.transactions] with a well-typed + * `List` value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun transactions(transactions: JsonField>) = apply { + this.transactions = transactions.map { it.toMutableList() } + } - fun additionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) + /** + * Adds a single [Transaction] to [transactions]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addTransaction(transaction: Transaction) = apply { + transactions = + (transactions ?: JsonField.of(mutableListOf())).also { + checkKnown("transactions", it).add(transaction) } + } - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } + /** Number of units held */ + fun units(units: Float) = units(JsonField.of(units)) - fun putAllAdditionalProperties( - additionalProperties: Map - ) = apply { this.additionalProperties.putAll(additionalProperties) } + /** + * Sets [Builder.units] to an arbitrary JSON value. + * + * You should usually call [Builder.units] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun units(units: JsonField) = apply { this.units = units } - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) - } + /** Current market value of the holding */ + fun value(value: Float) = value(JsonField.of(value)) - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } + /** + * Sets [Builder.value] to an arbitrary JSON value. + * + * You should usually call [Builder.value] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun value(value: JsonField) = apply { this.value = value } - /** - * Returns an immutable instance of [Transaction]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): Transaction = - Transaction( - additionalInfo, - amount, - balance, - date, - description, - dividendRate, - nav, - type, - units, - additionalProperties.toMutableMap(), - ) + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) } - private var validated: Boolean = false + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } - fun validate(): Transaction = apply { - if (validated) { - return@apply + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) } - additionalInfo().ifPresent { it.validate() } - amount() - balance() - date() - description() - dividendRate() - nav() - type().ifPresent { it.validate() } - units() - validated = true + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) } - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - false - } + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } /** - * Returns a score indicating how many valid values are contained in this object - * recursively. + * Returns an immutable instance of [CorporateBond]. * - * Used for best match union deserialization. + * Further updates to this [Builder] will not mutate the returned instance. */ - @JvmSynthetic - internal fun validity(): Int = - (additionalInfo.asKnown().getOrNull()?.validity() ?: 0) + - (if (amount.asKnown().isPresent) 1 else 0) + - (if (balance.asKnown().isPresent) 1 else 0) + - (if (date.asKnown().isPresent) 1 else 0) + - (if (description.asKnown().isPresent) 1 else 0) + - (if (dividendRate.asKnown().isPresent) 1 else 0) + - (if (nav.asKnown().isPresent) 1 else 0) + - (type.asKnown().getOrNull()?.validity() ?: 0) + - (if (units.asKnown().isPresent) 1 else 0) - - /** Additional transaction-specific fields that vary by source */ - class AdditionalInfo - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val capitalWithdrawal: JsonField, - private val credit: JsonField, - private val debit: JsonField, - private val incomeDistribution: JsonField, - private val orderNo: JsonField, - private val price: JsonField, - private val stampDuty: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("capital_withdrawal") - @ExcludeMissing - capitalWithdrawal: JsonField = JsonMissing.of(), - @JsonProperty("credit") - @ExcludeMissing - credit: JsonField = JsonMissing.of(), - @JsonProperty("debit") - @ExcludeMissing - debit: JsonField = JsonMissing.of(), - @JsonProperty("income_distribution") - @ExcludeMissing - incomeDistribution: JsonField = JsonMissing.of(), - @JsonProperty("order_no") - @ExcludeMissing - orderNo: JsonField = JsonMissing.of(), - @JsonProperty("price") - @ExcludeMissing - price: JsonField = JsonMissing.of(), - @JsonProperty("stamp_duty") - @ExcludeMissing - stampDuty: JsonField = JsonMissing.of(), - ) : this( - capitalWithdrawal, - credit, - debit, - incomeDistribution, - orderNo, - price, - stampDuty, - mutableMapOf(), + fun build(): CorporateBond = + CorporateBond( + additionalInfo, + isin, + name, + (transactions ?: JsonMissing.of()).map { it.toImmutable() }, + units, + value, + additionalProperties.toMutableMap(), ) + } - /** - * Capital withdrawal amount (CDSL MF transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun capitalWithdrawal(): Optional = - capitalWithdrawal.getOptional("capital_withdrawal") + private var validated: Boolean = false - /** - * Units credited (demat transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun credit(): Optional = credit.getOptional("credit") - - /** - * Units debited (demat transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun debit(): Optional = debit.getOptional("debit") + fun validate(): CorporateBond = apply { + if (validated) { + return@apply + } - /** - * Income distribution amount (CDSL MF transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun incomeDistribution(): Optional = - incomeDistribution.getOptional("income_distribution") + additionalInfo().ifPresent { it.validate() } + isin() + name() + transactions().ifPresent { it.forEach { it.validate() } } + units() + value() + validated = true + } - /** - * Order/transaction reference number (demat transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun orderNo(): Optional = orderNo.getOptional("order_no") + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + false + } - /** - * Price per unit (NSDL/CDSL MF transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun price(): Optional = price.getOptional("price") + /** + * 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 = + (additionalInfo.asKnown().getOrNull()?.validity() ?: 0) + + (if (isin.asKnown().isPresent) 1 else 0) + + (if (name.asKnown().isPresent) 1 else 0) + + (transactions.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (units.asKnown().isPresent) 1 else 0) + + (if (value.asKnown().isPresent) 1 else 0) - /** - * Stamp duty charged - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun stampDuty(): Optional = stampDuty.getOptional("stamp_duty") + /** Additional information specific to the corporate bond */ + class AdditionalInfo + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val closeUnits: JsonField, + private val openUnits: JsonField, + private val additionalProperties: MutableMap, + ) { - /** - * Returns the raw JSON value of [capitalWithdrawal]. - * - * Unlike [capitalWithdrawal], this method doesn't throw if the JSON field - * has an unexpected type. - */ - @JsonProperty("capital_withdrawal") + @JsonCreator + private constructor( + @JsonProperty("close_units") @ExcludeMissing - fun _capitalWithdrawal(): JsonField = capitalWithdrawal + closeUnits: JsonField = JsonMissing.of(), + @JsonProperty("open_units") + @ExcludeMissing + openUnits: JsonField = JsonMissing.of(), + ) : this(closeUnits, openUnits, mutableMapOf()) + + /** + * Closing balance units for the statement period (beta) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun closeUnits(): Optional = closeUnits.getOptional("close_units") + + /** + * Opening balance units for the statement period (beta) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun openUnits(): Optional = openUnits.getOptional("open_units") + + /** + * Returns the raw JSON value of [closeUnits]. + * + * Unlike [closeUnits], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("close_units") + @ExcludeMissing + fun _closeUnits(): JsonField = closeUnits + + /** + * Returns the raw JSON value of [openUnits]. + * + * Unlike [openUnits], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("open_units") + @ExcludeMissing + fun _openUnits(): JsonField = openUnits + + @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 the raw JSON value of [credit]. - * - * Unlike [credit], this method doesn't throw if the JSON field has an - * unexpected type. + * Returns a mutable builder for constructing an instance of + * [AdditionalInfo]. */ - @JsonProperty("credit") - @ExcludeMissing - fun _credit(): JsonField = credit + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AdditionalInfo]. */ + class Builder internal constructor() { + + private var closeUnits: JsonField = JsonMissing.of() + private var openUnits: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = + mutableMapOf() + + @JvmSynthetic + internal fun from(additionalInfo: AdditionalInfo) = apply { + closeUnits = additionalInfo.closeUnits + openUnits = additionalInfo.openUnits + additionalProperties = + additionalInfo.additionalProperties.toMutableMap() + } + + /** Closing balance units for the statement period (beta) */ + fun closeUnits(closeUnits: Float?) = + closeUnits(JsonField.ofNullable(closeUnits)) /** - * Returns the raw JSON value of [debit]. + * Alias for [Builder.closeUnits]. * - * Unlike [debit], this method doesn't throw if the JSON field has an - * unexpected type. + * This unboxed primitive overload exists for backwards compatibility. */ - @JsonProperty("debit") - @ExcludeMissing - fun _debit(): JsonField = debit + fun closeUnits(closeUnits: Float) = closeUnits(closeUnits as Float?) /** - * Returns the raw JSON value of [incomeDistribution]. - * - * Unlike [incomeDistribution], this method doesn't throw if the JSON field - * has an unexpected type. + * Alias for calling [Builder.closeUnits] with `closeUnits.orElse(null)`. */ - @JsonProperty("income_distribution") - @ExcludeMissing - fun _incomeDistribution(): JsonField = incomeDistribution + fun closeUnits(closeUnits: Optional) = + closeUnits(closeUnits.getOrNull()) /** - * Returns the raw JSON value of [orderNo]. + * Sets [Builder.closeUnits] to an arbitrary JSON value. * - * Unlike [orderNo], this method doesn't throw if the JSON field has an - * unexpected type. + * You should usually call [Builder.closeUnits] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. */ - @JsonProperty("order_no") - @ExcludeMissing - fun _orderNo(): JsonField = orderNo + fun closeUnits(closeUnits: JsonField) = apply { + this.closeUnits = closeUnits + } + + /** Opening balance units for the statement period (beta) */ + fun openUnits(openUnits: Float?) = + openUnits(JsonField.ofNullable(openUnits)) /** - * Returns the raw JSON value of [price]. + * Alias for [Builder.openUnits]. * - * Unlike [price], this method doesn't throw if the JSON field has an - * unexpected type. + * This unboxed primitive overload exists for backwards compatibility. */ - @JsonProperty("price") - @ExcludeMissing - fun _price(): JsonField = price + fun openUnits(openUnits: Float) = openUnits(openUnits as Float?) + + /** Alias for calling [Builder.openUnits] with `openUnits.orElse(null)`. */ + fun openUnits(openUnits: Optional) = openUnits(openUnits.getOrNull()) /** - * Returns the raw JSON value of [stampDuty]. + * Sets [Builder.openUnits] to an arbitrary JSON value. * - * Unlike [stampDuty], this method doesn't throw if the JSON field has an - * unexpected type. + * You should usually call [Builder.openUnits] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. */ - @JsonProperty("stamp_duty") - @ExcludeMissing - fun _stampDuty(): JsonField = stampDuty - - @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 - * [AdditionalInfo]. - */ - @JvmStatic fun builder() = Builder() + fun openUnits(openUnits: JsonField) = apply { + this.openUnits = openUnits } - /** A builder for [AdditionalInfo]. */ - class Builder internal constructor() { - - private var capitalWithdrawal: JsonField = JsonMissing.of() - private var credit: JsonField = JsonMissing.of() - private var debit: JsonField = JsonMissing.of() - private var incomeDistribution: JsonField = JsonMissing.of() - private var orderNo: JsonField = JsonMissing.of() - private var price: JsonField = JsonMissing.of() - private var stampDuty: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = - mutableMapOf() - - @JvmSynthetic - internal fun from(additionalInfo: AdditionalInfo) = apply { - capitalWithdrawal = additionalInfo.capitalWithdrawal - credit = additionalInfo.credit - debit = additionalInfo.debit - incomeDistribution = additionalInfo.incomeDistribution - orderNo = additionalInfo.orderNo - price = additionalInfo.price - stampDuty = additionalInfo.stampDuty - additionalProperties = - additionalInfo.additionalProperties.toMutableMap() - } - - /** Capital withdrawal amount (CDSL MF transactions) */ - fun capitalWithdrawal(capitalWithdrawal: Float) = - capitalWithdrawal(JsonField.of(capitalWithdrawal)) - - /** - * Sets [Builder.capitalWithdrawal] to an arbitrary JSON value. - * - * You should usually call [Builder.capitalWithdrawal] with a well-typed - * [Float] value instead. This method is primarily for setting the field - * to an undocumented or not yet supported value. - */ - fun capitalWithdrawal(capitalWithdrawal: JsonField) = apply { - this.capitalWithdrawal = capitalWithdrawal - } - - /** Units credited (demat transactions) */ - fun credit(credit: Float) = credit(JsonField.of(credit)) - - /** - * Sets [Builder.credit] to an arbitrary JSON value. - * - * You should usually call [Builder.credit] with a well-typed [Float] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun credit(credit: JsonField) = apply { this.credit = credit } - - /** Units debited (demat transactions) */ - fun debit(debit: Float) = debit(JsonField.of(debit)) - - /** - * Sets [Builder.debit] to an arbitrary JSON value. - * - * You should usually call [Builder.debit] with a well-typed [Float] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun debit(debit: JsonField) = apply { this.debit = debit } - - /** Income distribution amount (CDSL MF transactions) */ - fun incomeDistribution(incomeDistribution: Float) = - incomeDistribution(JsonField.of(incomeDistribution)) - - /** - * Sets [Builder.incomeDistribution] to an arbitrary JSON value. - * - * You should usually call [Builder.incomeDistribution] with a - * well-typed [Float] value instead. This method is primarily for - * setting the field to an undocumented or not yet supported value. - */ - fun incomeDistribution(incomeDistribution: JsonField) = apply { - this.incomeDistribution = incomeDistribution - } - - /** Order/transaction reference number (demat transactions) */ - fun orderNo(orderNo: String) = orderNo(JsonField.of(orderNo)) - - /** - * Sets [Builder.orderNo] to an arbitrary JSON value. - * - * You should usually call [Builder.orderNo] with a well-typed [String] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun orderNo(orderNo: JsonField) = apply { - this.orderNo = orderNo - } - - /** Price per unit (NSDL/CDSL MF transactions) */ - fun price(price: Float) = price(JsonField.of(price)) - - /** - * Sets [Builder.price] to an arbitrary JSON value. - * - * You should usually call [Builder.price] with a well-typed [Float] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun price(price: JsonField) = apply { this.price = price } - - /** Stamp duty charged */ - fun stampDuty(stampDuty: Float) = stampDuty(JsonField.of(stampDuty)) - - /** - * Sets [Builder.stampDuty] to an arbitrary JSON value. - * - * You should usually call [Builder.stampDuty] with a well-typed [Float] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun stampDuty(stampDuty: JsonField) = apply { - this.stampDuty = stampDuty - } - - 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) + fun additionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) } - /** - * Returns an immutable instance of [AdditionalInfo]. - * - * Further updates to this [Builder] will not mutate the returned - * instance. - */ - fun build(): AdditionalInfo = - AdditionalInfo( - capitalWithdrawal, - credit, - debit, - incomeDistribution, - orderNo, - price, - stampDuty, - additionalProperties.toMutableMap(), - ) + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) } - private var validated: Boolean = false - - fun validate(): AdditionalInfo = apply { - if (validated) { - return@apply - } + fun putAllAdditionalProperties( + additionalProperties: Map + ) = apply { this.additionalProperties.putAll(additionalProperties) } - capitalWithdrawal() - credit() - debit() - incomeDistribution() - orderNo() - price() - stampDuty() - validated = true + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) } - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - false - } + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } /** - * Returns a score indicating how many valid values are contained in this - * object recursively. + * Returns an immutable instance of [AdditionalInfo]. * - * Used for best match union deserialization. + * Further updates to this [Builder] will not mutate the returned instance. */ - @JvmSynthetic - internal fun validity(): Int = - (if (capitalWithdrawal.asKnown().isPresent) 1 else 0) + - (if (credit.asKnown().isPresent) 1 else 0) + - (if (debit.asKnown().isPresent) 1 else 0) + - (if (incomeDistribution.asKnown().isPresent) 1 else 0) + - (if (orderNo.asKnown().isPresent) 1 else 0) + - (if (price.asKnown().isPresent) 1 else 0) + - (if (stampDuty.asKnown().isPresent) 1 else 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + fun build(): AdditionalInfo = + AdditionalInfo( + closeUnits, + openUnits, + additionalProperties.toMutableMap(), + ) + } - return other is AdditionalInfo && - capitalWithdrawal == other.capitalWithdrawal && - credit == other.credit && - debit == other.debit && - incomeDistribution == other.incomeDistribution && - orderNo == other.orderNo && - price == other.price && - stampDuty == other.stampDuty && - additionalProperties == other.additionalProperties - } + private var validated: Boolean = false - private val hashCode: Int by lazy { - Objects.hash( - capitalWithdrawal, - credit, - debit, - incomeDistribution, - orderNo, - price, - stampDuty, - additionalProperties, - ) + fun validate(): AdditionalInfo = apply { + if (validated) { + return@apply } - override fun hashCode(): Int = hashCode - - override fun toString() = - "AdditionalInfo{capitalWithdrawal=$capitalWithdrawal, credit=$credit, debit=$debit, incomeDistribution=$incomeDistribution, orderNo=$orderNo, price=$price, stampDuty=$stampDuty, additionalProperties=$additionalProperties}" + closeUnits() + openUnits() + validated = true } + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + false + } + /** - * Transaction type. Possible values are PURCHASE, PURCHASE_SIP, REDEMPTION, - * SWITCH_IN, SWITCH_IN_MERGER, SWITCH_OUT, SWITCH_OUT_MERGER, DIVIDEND_PAYOUT, - * DIVIDEND_REINVEST, SEGREGATION, STAMP_DUTY_TAX, TDS_TAX, STT_TAX, MISC, - * REVERSAL, UNKNOWN. + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. */ - class Type - @JsonCreator - private constructor(private val value: JsonField) : Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data - * that doesn't match any known member, and you want to know that value. For - * example, if the SDK is on an older version than the API, then the API may - * respond with new members that the SDK is unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue - fun _value(): JsonField = value - - companion object { - - @JvmField val PURCHASE = of("PURCHASE") - - @JvmField val PURCHASE_SIP = of("PURCHASE_SIP") - - @JvmField val REDEMPTION = of("REDEMPTION") - - @JvmField val SWITCH_IN = of("SWITCH_IN") - - @JvmField val SWITCH_IN_MERGER = of("SWITCH_IN_MERGER") - - @JvmField val SWITCH_OUT = of("SWITCH_OUT") - - @JvmField val SWITCH_OUT_MERGER = of("SWITCH_OUT_MERGER") - - @JvmField val DIVIDEND_PAYOUT = of("DIVIDEND_PAYOUT") - - @JvmField val DIVIDEND_REINVEST = of("DIVIDEND_REINVEST") - - @JvmField val SEGREGATION = of("SEGREGATION") - - @JvmField val STAMP_DUTY_TAX = of("STAMP_DUTY_TAX") - - @JvmField val TDS_TAX = of("TDS_TAX") - - @JvmField val STT_TAX = of("STT_TAX") - - @JvmField val MISC = of("MISC") - - @JvmField val REVERSAL = of("REVERSAL") - - @JvmField val UNKNOWN = of("UNKNOWN") - - @JvmStatic fun of(value: String) = Type(JsonField.of(value)) - } - - /** An enum containing [Type]'s known values. */ - enum class Known { - PURCHASE, - PURCHASE_SIP, - REDEMPTION, - SWITCH_IN, - SWITCH_IN_MERGER, - SWITCH_OUT, - SWITCH_OUT_MERGER, - DIVIDEND_PAYOUT, - DIVIDEND_REINVEST, - SEGREGATION, - STAMP_DUTY_TAX, - TDS_TAX, - STT_TAX, - MISC, - REVERSAL, - UNKNOWN, - } - - /** - * An enum containing [Type]'s known values, as well as an [_UNKNOWN] - * member. - * - * An instance of [Type] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For - * example, if the SDK is on an older version than the API, then the API - * may respond with new members that the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - PURCHASE, - PURCHASE_SIP, - REDEMPTION, - SWITCH_IN, - SWITCH_IN_MERGER, - SWITCH_OUT, - SWITCH_OUT_MERGER, - DIVIDEND_PAYOUT, - DIVIDEND_REINVEST, - SEGREGATION, - STAMP_DUTY_TAX, - TDS_TAX, - STT_TAX, - MISC, - REVERSAL, - UNKNOWN, - /** - * An enum member indicating that [Type] was instantiated with an - * unknown value. - */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or - * [Value._UNKNOWN] if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always - * known or if you want to throw for the unknown case. - */ - fun value(): Value = - when (this) { - PURCHASE -> Value.PURCHASE - PURCHASE_SIP -> Value.PURCHASE_SIP - REDEMPTION -> Value.REDEMPTION - SWITCH_IN -> Value.SWITCH_IN - SWITCH_IN_MERGER -> Value.SWITCH_IN_MERGER - SWITCH_OUT -> Value.SWITCH_OUT - SWITCH_OUT_MERGER -> Value.SWITCH_OUT_MERGER - DIVIDEND_PAYOUT -> Value.DIVIDEND_PAYOUT - DIVIDEND_REINVEST -> Value.DIVIDEND_REINVEST - SEGREGATION -> Value.SEGREGATION - STAMP_DUTY_TAX -> Value.STAMP_DUTY_TAX - TDS_TAX -> Value.TDS_TAX - STT_TAX -> Value.STT_TAX - MISC -> Value.MISC - REVERSAL -> Value.REVERSAL - UNKNOWN -> Value.UNKNOWN - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always - * known and don't want to throw for the unknown case. - * - * @throws CasParserInvalidDataException if this class instance's value is a - * not a known member. - */ - fun known(): Known = - when (this) { - PURCHASE -> Known.PURCHASE - PURCHASE_SIP -> Known.PURCHASE_SIP - REDEMPTION -> Known.REDEMPTION - SWITCH_IN -> Known.SWITCH_IN - SWITCH_IN_MERGER -> Known.SWITCH_IN_MERGER - SWITCH_OUT -> Known.SWITCH_OUT - SWITCH_OUT_MERGER -> Known.SWITCH_OUT_MERGER - DIVIDEND_PAYOUT -> Known.DIVIDEND_PAYOUT - DIVIDEND_REINVEST -> Known.DIVIDEND_REINVEST - SEGREGATION -> Known.SEGREGATION - STAMP_DUTY_TAX -> Known.STAMP_DUTY_TAX - TDS_TAX -> Known.TDS_TAX - STT_TAX -> Known.STT_TAX - MISC -> Known.MISC - REVERSAL -> Known.REVERSAL - UNKNOWN -> Known.UNKNOWN - else -> throw CasParserInvalidDataException("Unknown Type: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily - * for debugging and generally doesn't throw. - * - * @throws CasParserInvalidDataException if this class instance's value does - * not have the expected primitive type. - */ - fun asString(): String = - _value().asString().orElseThrow { - CasParserInvalidDataException("Value is not a String") - } - - private var validated: Boolean = false - - fun validate(): Type = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - 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 (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Type && value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } + @JvmSynthetic + internal fun validity(): Int = + (if (closeUnits.asKnown().isPresent) 1 else 0) + + (if (openUnits.asKnown().isPresent) 1 else 0) override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is Transaction && - additionalInfo == other.additionalInfo && - amount == other.amount && - balance == other.balance && - date == other.date && - description == other.description && - dividendRate == other.dividendRate && - nav == other.nav && - type == other.type && - units == other.units && + return other is AdditionalInfo && + closeUnits == other.closeUnits && + openUnits == other.openUnits && additionalProperties == other.additionalProperties } private val hashCode: Int by lazy { - Objects.hash( - additionalInfo, - amount, - balance, - date, - description, - dividendRate, - nav, - type, - units, - additionalProperties, - ) + Objects.hash(closeUnits, openUnits, additionalProperties) } override fun hashCode(): Int = hashCode override fun toString() = - "Transaction{additionalInfo=$additionalInfo, amount=$amount, balance=$balance, date=$date, description=$description, dividendRate=$dividendRate, nav=$nav, type=$type, units=$units, additionalProperties=$additionalProperties}" + "AdditionalInfo{closeUnits=$closeUnits, openUnits=$openUnits, additionalProperties=$additionalProperties}" } override fun equals(other: Any?): Boolean { @@ -3557,7 +2961,7 @@ private constructor( return true } - return other is Aif && + return other is CorporateBond && additionalInfo == other.additionalInfo && isin == other.isin && name == other.name && @@ -3582,10 +2986,10 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "Aif{additionalInfo=$additionalInfo, isin=$isin, name=$name, transactions=$transactions, units=$units, value=$value, additionalProperties=$additionalProperties}" + "CorporateBond{additionalInfo=$additionalInfo, isin=$isin, name=$name, transactions=$transactions, units=$units, value=$value, additionalProperties=$additionalProperties}" } - class CorporateBond + class DematMutualFund @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val additionalInfo: JsonField, @@ -3620,7 +3024,7 @@ private constructor( ) : this(additionalInfo, isin, name, transactions, units, value, mutableMapOf()) /** - * Additional information specific to the corporate bond + * Additional information specific to the mutual fund * * @throws CasParserInvalidDataException if the JSON field has an unexpected type * (e.g. if the server responded with an unexpected value). @@ -3629,7 +3033,7 @@ private constructor( additionalInfo.getOptional("additional_info") /** - * ISIN code of the corporate bond + * ISIN code of the mutual fund * * @throws CasParserInvalidDataException if the JSON field has an unexpected type * (e.g. if the server responded with an unexpected value). @@ -3637,7 +3041,7 @@ private constructor( fun isin(): Optional = isin.getOptional("isin") /** - * Name of the corporate bond + * Name of the mutual fund * * @throws CasParserInvalidDataException if the JSON field has an unexpected type * (e.g. if the server responded with an unexpected value). @@ -3736,12 +3140,12 @@ private constructor( companion object { /** - * Returns a mutable builder for constructing an instance of [CorporateBond]. + * Returns a mutable builder for constructing an instance of [DematMutualFund]. */ @JvmStatic fun builder() = Builder() } - /** A builder for [CorporateBond]. */ + /** A builder for [DematMutualFund]. */ class Builder internal constructor() { private var additionalInfo: JsonField = JsonMissing.of() @@ -3753,17 +3157,17 @@ private constructor( private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(corporateBond: CorporateBond) = apply { - additionalInfo = corporateBond.additionalInfo - isin = corporateBond.isin - name = corporateBond.name - transactions = corporateBond.transactions.map { it.toMutableList() } - units = corporateBond.units - value = corporateBond.value - additionalProperties = corporateBond.additionalProperties.toMutableMap() + internal fun from(dematMutualFund: DematMutualFund) = apply { + additionalInfo = dematMutualFund.additionalInfo + isin = dematMutualFund.isin + name = dematMutualFund.name + transactions = dematMutualFund.transactions.map { it.toMutableList() } + units = dematMutualFund.units + value = dematMutualFund.value + additionalProperties = dematMutualFund.additionalProperties.toMutableMap() } - /** Additional information specific to the corporate bond */ + /** Additional information specific to the mutual fund */ fun additionalInfo(additionalInfo: AdditionalInfo) = additionalInfo(JsonField.of(additionalInfo)) @@ -3778,7 +3182,7 @@ private constructor( this.additionalInfo = additionalInfo } - /** ISIN code of the corporate bond */ + /** ISIN code of the mutual fund */ fun isin(isin: String) = isin(JsonField.of(isin)) /** @@ -3790,7 +3194,7 @@ private constructor( */ fun isin(isin: JsonField) = apply { this.isin = isin } - /** Name of the corporate bond */ + /** Name of the mutual fund */ fun name(name: String) = name(JsonField.of(name)) /** @@ -3876,12 +3280,12 @@ private constructor( } /** - * Returns an immutable instance of [CorporateBond]. + * Returns an immutable instance of [DematMutualFund]. * * Further updates to this [Builder] will not mutate the returned instance. */ - fun build(): CorporateBond = - CorporateBond( + fun build(): DematMutualFund = + DematMutualFund( additionalInfo, isin, name, @@ -3894,7 +3298,7 @@ private constructor( private var validated: Boolean = false - fun validate(): CorporateBond = apply { + fun validate(): DematMutualFund = apply { if (validated) { return@apply } @@ -3931,7 +3335,7 @@ private constructor( (if (units.asKnown().isPresent) 1 else 0) + (if (value.asKnown().isPresent) 1 else 0) - /** Additional information specific to the corporate bond */ + /** Additional information specific to the mutual fund */ class AdditionalInfo @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( @@ -4163,427 +3567,527 @@ private constructor( "AdditionalInfo{closeUnits=$closeUnits, openUnits=$openUnits, additionalProperties=$additionalProperties}" } - /** - * Unified transaction schema for all holding types (MF folios, equities, bonds, - * etc.) - */ - class Transaction - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val additionalInfo: JsonField, - private val amount: JsonField, - private val balance: JsonField, - private val date: JsonField, - private val description: JsonField, - private val dividendRate: JsonField, - private val nav: JsonField, - private val type: JsonField, - private val units: JsonField, - private val additionalProperties: MutableMap, - ) { + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - @JsonCreator - private constructor( - @JsonProperty("additional_info") - @ExcludeMissing - additionalInfo: JsonField = JsonMissing.of(), - @JsonProperty("amount") - @ExcludeMissing - amount: JsonField = JsonMissing.of(), - @JsonProperty("balance") - @ExcludeMissing - balance: JsonField = JsonMissing.of(), - @JsonProperty("date") - @ExcludeMissing - date: JsonField = JsonMissing.of(), - @JsonProperty("description") - @ExcludeMissing - description: JsonField = JsonMissing.of(), - @JsonProperty("dividend_rate") - @ExcludeMissing - dividendRate: JsonField = JsonMissing.of(), - @JsonProperty("nav") - @ExcludeMissing - nav: JsonField = JsonMissing.of(), - @JsonProperty("type") - @ExcludeMissing - type: JsonField = JsonMissing.of(), - @JsonProperty("units") - @ExcludeMissing - units: JsonField = JsonMissing.of(), - ) : this( + return other is DematMutualFund && + additionalInfo == other.additionalInfo && + isin == other.isin && + name == other.name && + transactions == other.transactions && + units == other.units && + value == other.value && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( additionalInfo, - amount, - balance, - date, - description, - dividendRate, - nav, - type, + isin, + name, + transactions, units, - mutableMapOf(), + value, + additionalProperties, ) + } - /** - * Additional transaction-specific fields that vary by source - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun additionalInfo(): Optional = - additionalInfo.getOptional("additional_info") - - /** - * Transaction amount in currency (computed from units × price/NAV) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun amount(): Optional = amount.getOptional("amount") - - /** - * Balance units after transaction - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun balance(): Optional = balance.getOptional("balance") - - /** - * Transaction date (YYYY-MM-DD) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun date(): Optional = date.getOptional("date") - - /** - * Transaction description/particulars - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun description(): Optional = description.getOptional("description") - - /** - * Dividend rate (for DIVIDEND_PAYOUT transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun dividendRate(): Optional = dividendRate.getOptional("dividend_rate") - - /** - * NAV/price per unit on transaction date - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun nav(): Optional = nav.getOptional("nav") + override fun hashCode(): Int = hashCode - /** - * Transaction type. Possible values are PURCHASE, PURCHASE_SIP, REDEMPTION, - * SWITCH_IN, SWITCH_IN_MERGER, SWITCH_OUT, SWITCH_OUT_MERGER, DIVIDEND_PAYOUT, - * DIVIDEND_REINVEST, SEGREGATION, STAMP_DUTY_TAX, TDS_TAX, STT_TAX, MISC, - * REVERSAL, UNKNOWN. - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun type(): Optional = type.getOptional("type") + override fun toString() = + "DematMutualFund{additionalInfo=$additionalInfo, isin=$isin, name=$name, transactions=$transactions, units=$units, value=$value, additionalProperties=$additionalProperties}" + } - /** - * Number of units involved in transaction - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun units(): Optional = units.getOptional("units") + class Equity + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val additionalInfo: JsonField, + private val isin: JsonField, + private val name: JsonField, + private val transactions: JsonField>, + private val units: JsonField, + private val value: JsonField, + private val additionalProperties: MutableMap, + ) { - /** - * Returns the raw JSON value of [additionalInfo]. - * - * Unlike [additionalInfo], this method doesn't throw if the JSON field has an - * unexpected type. - */ + @JsonCreator + private constructor( @JsonProperty("additional_info") @ExcludeMissing - fun _additionalInfo(): JsonField = additionalInfo - - /** - * Returns the raw JSON value of [amount]. - * - * Unlike [amount], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("amount") @ExcludeMissing fun _amount(): JsonField = amount - - /** - * Returns the raw JSON value of [balance]. - * - * Unlike [balance], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("balance") + additionalInfo: JsonField = JsonMissing.of(), + @JsonProperty("isin") @ExcludeMissing - fun _balance(): JsonField = balance - - /** - * Returns the raw JSON value of [date]. - * - * Unlike [date], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("date") @ExcludeMissing fun _date(): JsonField = date - - /** - * Returns the raw JSON value of [description]. - * - * Unlike [description], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("description") + isin: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing - fun _description(): JsonField = description - - /** - * Returns the raw JSON value of [dividendRate]. - * - * Unlike [dividendRate], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("dividend_rate") + name: JsonField = JsonMissing.of(), + @JsonProperty("transactions") + @ExcludeMissing + transactions: JsonField> = JsonMissing.of(), + @JsonProperty("units") + @ExcludeMissing + units: JsonField = JsonMissing.of(), + @JsonProperty("value") @ExcludeMissing - fun _dividendRate(): JsonField = dividendRate + value: JsonField = JsonMissing.of(), + ) : this(additionalInfo, isin, name, transactions, units, value, mutableMapOf()) - /** - * Returns the raw JSON value of [nav]. - * - * Unlike [nav], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("nav") @ExcludeMissing fun _nav(): JsonField = nav + /** + * Additional information specific to the equity + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun additionalInfo(): Optional = + additionalInfo.getOptional("additional_info") - /** - * Returns the raw JSON value of [type]. - * - * Unlike [type], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + /** + * ISIN code of the equity + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun isin(): Optional = isin.getOptional("isin") - /** - * Returns the raw JSON value of [units]. - * - * Unlike [units], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("units") @ExcludeMissing fun _units(): JsonField = units + /** + * Name of the equity + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun name(): Optional = name.getOptional("name") - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } + /** + * List of transactions for this holding (beta) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun transactions(): Optional> = + transactions.getOptional("transactions") - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) + /** + * Number of units held + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun units(): Optional = units.getOptional("units") - fun toBuilder() = Builder().from(this) + /** + * Current market value of the holding + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun value(): Optional = value.getOptional("value") - companion object { + /** + * Returns the raw JSON value of [additionalInfo]. + * + * Unlike [additionalInfo], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("additional_info") + @ExcludeMissing + fun _additionalInfo(): JsonField = additionalInfo - /** - * Returns a mutable builder for constructing an instance of [Transaction]. - */ - @JvmStatic fun builder() = Builder() - } + /** + * Returns the raw JSON value of [isin]. + * + * Unlike [isin], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("isin") @ExcludeMissing fun _isin(): JsonField = isin - /** A builder for [Transaction]. */ - class Builder internal constructor() { + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name - private var additionalInfo: JsonField = JsonMissing.of() - private var amount: JsonField = JsonMissing.of() - private var balance: JsonField = JsonMissing.of() - private var date: JsonField = JsonMissing.of() - private var description: JsonField = JsonMissing.of() - private var dividendRate: JsonField = JsonMissing.of() - private var nav: JsonField = JsonMissing.of() - private var type: JsonField = JsonMissing.of() - private var units: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = - mutableMapOf() + /** + * Returns the raw JSON value of [transactions]. + * + * Unlike [transactions], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("transactions") + @ExcludeMissing + fun _transactions(): JsonField> = transactions - @JvmSynthetic - internal fun from(transaction: Transaction) = apply { - additionalInfo = transaction.additionalInfo - amount = transaction.amount - balance = transaction.balance - date = transaction.date - description = transaction.description - dividendRate = transaction.dividendRate - nav = transaction.nav - type = transaction.type - units = transaction.units - additionalProperties = transaction.additionalProperties.toMutableMap() - } + /** + * Returns the raw JSON value of [units]. + * + * Unlike [units], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("units") @ExcludeMissing fun _units(): JsonField = units - /** Additional transaction-specific fields that vary by source */ - fun additionalInfo(additionalInfo: AdditionalInfo) = - additionalInfo(JsonField.of(additionalInfo)) + /** + * Returns the raw JSON value of [value]. + * + * Unlike [value], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("value") @ExcludeMissing fun _value(): JsonField = value - /** - * Sets [Builder.additionalInfo] to an arbitrary JSON value. - * - * You should usually call [Builder.additionalInfo] with a well-typed - * [AdditionalInfo] value instead. This method is primarily for setting the - * field to an undocumented or not yet supported value. - */ - fun additionalInfo(additionalInfo: JsonField) = apply { - this.additionalInfo = additionalInfo - } + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } - /** Transaction amount in currency (computed from units × price/NAV) */ - fun amount(amount: Float?) = amount(JsonField.ofNullable(amount)) + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) - /** - * Alias for [Builder.amount]. - * - * This unboxed primitive overload exists for backwards compatibility. - */ - fun amount(amount: Float) = amount(amount as Float?) + fun toBuilder() = Builder().from(this) - /** Alias for calling [Builder.amount] with `amount.orElse(null)`. */ - fun amount(amount: Optional) = amount(amount.getOrNull()) + companion object { - /** - * Sets [Builder.amount] to an arbitrary JSON value. - * - * You should usually call [Builder.amount] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun amount(amount: JsonField) = apply { this.amount = amount } + /** Returns a mutable builder for constructing an instance of [Equity]. */ + @JvmStatic fun builder() = Builder() + } - /** Balance units after transaction */ - fun balance(balance: Float) = balance(JsonField.of(balance)) + /** A builder for [Equity]. */ + class Builder internal constructor() { - /** - * Sets [Builder.balance] to an arbitrary JSON value. - * - * You should usually call [Builder.balance] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun balance(balance: JsonField) = apply { this.balance = balance } + private var additionalInfo: JsonField = JsonMissing.of() + private var isin: JsonField = JsonMissing.of() + private var name: JsonField = JsonMissing.of() + private var transactions: JsonField>? = null + private var units: JsonField = JsonMissing.of() + private var value: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() - /** Transaction date (YYYY-MM-DD) */ - fun date(date: LocalDate) = date(JsonField.of(date)) + @JvmSynthetic + internal fun from(equity: Equity) = apply { + additionalInfo = equity.additionalInfo + isin = equity.isin + name = equity.name + transactions = equity.transactions.map { it.toMutableList() } + units = equity.units + value = equity.value + additionalProperties = equity.additionalProperties.toMutableMap() + } - /** - * Sets [Builder.date] to an arbitrary JSON value. - * - * You should usually call [Builder.date] with a well-typed [LocalDate] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun date(date: JsonField) = apply { this.date = date } + /** Additional information specific to the equity */ + fun additionalInfo(additionalInfo: AdditionalInfo) = + additionalInfo(JsonField.of(additionalInfo)) - /** Transaction description/particulars */ - fun description(description: String) = - description(JsonField.of(description)) + /** + * Sets [Builder.additionalInfo] to an arbitrary JSON value. + * + * You should usually call [Builder.additionalInfo] with a well-typed + * [AdditionalInfo] value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun additionalInfo(additionalInfo: JsonField) = apply { + this.additionalInfo = additionalInfo + } - /** - * Sets [Builder.description] to an arbitrary JSON value. - * - * You should usually call [Builder.description] with a well-typed [String] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun description(description: JsonField) = apply { - this.description = description - } + /** ISIN code of the equity */ + fun isin(isin: String) = isin(JsonField.of(isin)) - /** Dividend rate (for DIVIDEND_PAYOUT transactions) */ - fun dividendRate(dividendRate: Float?) = - dividendRate(JsonField.ofNullable(dividendRate)) + /** + * Sets [Builder.isin] to an arbitrary JSON value. + * + * You should usually call [Builder.isin] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun isin(isin: JsonField) = apply { this.isin = isin } - /** - * Alias for [Builder.dividendRate]. - * - * This unboxed primitive overload exists for backwards compatibility. - */ - fun dividendRate(dividendRate: Float) = dividendRate(dividendRate as Float?) + /** Name of the equity */ + fun name(name: String) = name(JsonField.of(name)) - /** - * Alias for calling [Builder.dividendRate] with - * `dividendRate.orElse(null)`. - */ - fun dividendRate(dividendRate: Optional) = - dividendRate(dividendRate.getOrNull()) + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun name(name: JsonField) = apply { this.name = name } - /** - * Sets [Builder.dividendRate] to an arbitrary JSON value. - * - * You should usually call [Builder.dividendRate] with a well-typed [Float] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun dividendRate(dividendRate: JsonField) = apply { - this.dividendRate = dividendRate - } + /** List of transactions for this holding (beta) */ + fun transactions(transactions: List) = + transactions(JsonField.of(transactions)) - /** NAV/price per unit on transaction date */ - fun nav(nav: Float?) = nav(JsonField.ofNullable(nav)) + /** + * Sets [Builder.transactions] to an arbitrary JSON value. + * + * You should usually call [Builder.transactions] with a well-typed + * `List` value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun transactions(transactions: JsonField>) = apply { + this.transactions = transactions.map { it.toMutableList() } + } - /** - * Alias for [Builder.nav]. - * - * This unboxed primitive overload exists for backwards compatibility. + /** + * Adds a single [Transaction] to [transactions]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addTransaction(transaction: Transaction) = apply { + transactions = + (transactions ?: JsonField.of(mutableListOf())).also { + checkKnown("transactions", it).add(transaction) + } + } + + /** Number of units held */ + fun units(units: Float) = units(JsonField.of(units)) + + /** + * Sets [Builder.units] to an arbitrary JSON value. + * + * You should usually call [Builder.units] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun units(units: JsonField) = apply { this.units = units } + + /** Current market value of the holding */ + fun value(value: Float) = value(JsonField.of(value)) + + /** + * Sets [Builder.value] to an arbitrary JSON value. + * + * You should usually call [Builder.value] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun value(value: JsonField) = apply { this.value = value } + + 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 [Equity]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Equity = + Equity( + additionalInfo, + isin, + name, + (transactions ?: JsonMissing.of()).map { it.toImmutable() }, + units, + value, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Equity = apply { + if (validated) { + return@apply + } + + additionalInfo().ifPresent { it.validate() } + isin() + name() + transactions().ifPresent { it.forEach { it.validate() } } + units() + value() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 = + (additionalInfo.asKnown().getOrNull()?.validity() ?: 0) + + (if (isin.asKnown().isPresent) 1 else 0) + + (if (name.asKnown().isPresent) 1 else 0) + + (transactions.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (units.asKnown().isPresent) 1 else 0) + + (if (value.asKnown().isPresent) 1 else 0) + + /** Additional information specific to the equity */ + class AdditionalInfo + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val closeUnits: JsonField, + private val openUnits: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("close_units") + @ExcludeMissing + closeUnits: JsonField = JsonMissing.of(), + @JsonProperty("open_units") + @ExcludeMissing + openUnits: JsonField = JsonMissing.of(), + ) : this(closeUnits, openUnits, mutableMapOf()) + + /** + * Closing balance units for the statement period (beta) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun closeUnits(): Optional = closeUnits.getOptional("close_units") + + /** + * Opening balance units for the statement period (beta) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun openUnits(): Optional = openUnits.getOptional("open_units") + + /** + * Returns the raw JSON value of [closeUnits]. + * + * Unlike [closeUnits], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("close_units") + @ExcludeMissing + fun _closeUnits(): JsonField = closeUnits + + /** + * Returns the raw JSON value of [openUnits]. + * + * Unlike [openUnits], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("open_units") + @ExcludeMissing + fun _openUnits(): JsonField = openUnits + + @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 + * [AdditionalInfo]. */ - fun nav(nav: Float) = nav(nav as Float?) + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AdditionalInfo]. */ + class Builder internal constructor() { + + private var closeUnits: JsonField = JsonMissing.of() + private var openUnits: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = + mutableMapOf() + + @JvmSynthetic + internal fun from(additionalInfo: AdditionalInfo) = apply { + closeUnits = additionalInfo.closeUnits + openUnits = additionalInfo.openUnits + additionalProperties = + additionalInfo.additionalProperties.toMutableMap() + } - /** Alias for calling [Builder.nav] with `nav.orElse(null)`. */ - fun nav(nav: Optional) = nav(nav.getOrNull()) + /** Closing balance units for the statement period (beta) */ + fun closeUnits(closeUnits: Float?) = + closeUnits(JsonField.ofNullable(closeUnits)) /** - * Sets [Builder.nav] to an arbitrary JSON value. + * Alias for [Builder.closeUnits]. * - * You should usually call [Builder.nav] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. + * This unboxed primitive overload exists for backwards compatibility. */ - fun nav(nav: JsonField) = apply { this.nav = nav } + fun closeUnits(closeUnits: Float) = closeUnits(closeUnits as Float?) /** - * Transaction type. Possible values are PURCHASE, PURCHASE_SIP, REDEMPTION, - * SWITCH_IN, SWITCH_IN_MERGER, SWITCH_OUT, SWITCH_OUT_MERGER, - * DIVIDEND_PAYOUT, DIVIDEND_REINVEST, SEGREGATION, STAMP_DUTY_TAX, TDS_TAX, - * STT_TAX, MISC, REVERSAL, UNKNOWN. + * Alias for calling [Builder.closeUnits] with `closeUnits.orElse(null)`. */ - fun type(type: Type) = type(JsonField.of(type)) + fun closeUnits(closeUnits: Optional) = + closeUnits(closeUnits.getOrNull()) /** - * Sets [Builder.type] to an arbitrary JSON value. + * Sets [Builder.closeUnits] to an arbitrary JSON value. * - * You should usually call [Builder.type] with a well-typed [Type] value - * instead. This method is primarily for setting the field to an + * You should usually call [Builder.closeUnits] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an * undocumented or not yet supported value. */ - fun type(type: JsonField) = apply { this.type = type } + fun closeUnits(closeUnits: JsonField) = apply { + this.closeUnits = closeUnits + } + + /** Opening balance units for the statement period (beta) */ + fun openUnits(openUnits: Float?) = + openUnits(JsonField.ofNullable(openUnits)) + + /** + * Alias for [Builder.openUnits]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun openUnits(openUnits: Float) = openUnits(openUnits as Float?) - /** Number of units involved in transaction */ - fun units(units: Float) = units(JsonField.of(units)) + /** Alias for calling [Builder.openUnits] with `openUnits.orElse(null)`. */ + fun openUnits(openUnits: Optional) = openUnits(openUnits.getOrNull()) /** - * Sets [Builder.units] to an arbitrary JSON value. + * Sets [Builder.openUnits] to an arbitrary JSON value. * - * You should usually call [Builder.units] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an + * You should usually call [Builder.openUnits] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an * undocumented or not yet supported value. */ - fun units(units: JsonField) = apply { this.units = units } + fun openUnits(openUnits: JsonField) = apply { + this.openUnits = openUnits + } fun additionalProperties(additionalProperties: Map) = apply { @@ -4608,41 +4112,27 @@ private constructor( } /** - * Returns an immutable instance of [Transaction]. + * Returns an immutable instance of [AdditionalInfo]. * * Further updates to this [Builder] will not mutate the returned instance. */ - fun build(): Transaction = - Transaction( - additionalInfo, - amount, - balance, - date, - description, - dividendRate, - nav, - type, - units, + fun build(): AdditionalInfo = + AdditionalInfo( + closeUnits, + openUnits, additionalProperties.toMutableMap(), ) } private var validated: Boolean = false - fun validate(): Transaction = apply { + fun validate(): AdditionalInfo = apply { if (validated) { return@apply } - additionalInfo().ifPresent { it.validate() } - amount() - balance() - date() - description() - dividendRate() - nav() - type().ifPresent { it.validate() } - units() + closeUnits() + openUnits() validated = true } @@ -4662,712 +4152,28 @@ private constructor( */ @JvmSynthetic internal fun validity(): Int = - (additionalInfo.asKnown().getOrNull()?.validity() ?: 0) + - (if (amount.asKnown().isPresent) 1 else 0) + - (if (balance.asKnown().isPresent) 1 else 0) + - (if (date.asKnown().isPresent) 1 else 0) + - (if (description.asKnown().isPresent) 1 else 0) + - (if (dividendRate.asKnown().isPresent) 1 else 0) + - (if (nav.asKnown().isPresent) 1 else 0) + - (type.asKnown().getOrNull()?.validity() ?: 0) + - (if (units.asKnown().isPresent) 1 else 0) - - /** Additional transaction-specific fields that vary by source */ - class AdditionalInfo - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val capitalWithdrawal: JsonField, - private val credit: JsonField, - private val debit: JsonField, - private val incomeDistribution: JsonField, - private val orderNo: JsonField, - private val price: JsonField, - private val stampDuty: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("capital_withdrawal") - @ExcludeMissing - capitalWithdrawal: JsonField = JsonMissing.of(), - @JsonProperty("credit") - @ExcludeMissing - credit: JsonField = JsonMissing.of(), - @JsonProperty("debit") - @ExcludeMissing - debit: JsonField = JsonMissing.of(), - @JsonProperty("income_distribution") - @ExcludeMissing - incomeDistribution: JsonField = JsonMissing.of(), - @JsonProperty("order_no") - @ExcludeMissing - orderNo: JsonField = JsonMissing.of(), - @JsonProperty("price") - @ExcludeMissing - price: JsonField = JsonMissing.of(), - @JsonProperty("stamp_duty") - @ExcludeMissing - stampDuty: JsonField = JsonMissing.of(), - ) : this( - capitalWithdrawal, - credit, - debit, - incomeDistribution, - orderNo, - price, - stampDuty, - mutableMapOf(), - ) - - /** - * Capital withdrawal amount (CDSL MF transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun capitalWithdrawal(): Optional = - capitalWithdrawal.getOptional("capital_withdrawal") - - /** - * Units credited (demat transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun credit(): Optional = credit.getOptional("credit") - - /** - * Units debited (demat transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun debit(): Optional = debit.getOptional("debit") - - /** - * Income distribution amount (CDSL MF transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun incomeDistribution(): Optional = - incomeDistribution.getOptional("income_distribution") - - /** - * Order/transaction reference number (demat transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun orderNo(): Optional = orderNo.getOptional("order_no") - - /** - * Price per unit (NSDL/CDSL MF transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun price(): Optional = price.getOptional("price") - - /** - * Stamp duty charged - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun stampDuty(): Optional = stampDuty.getOptional("stamp_duty") - - /** - * Returns the raw JSON value of [capitalWithdrawal]. - * - * Unlike [capitalWithdrawal], this method doesn't throw if the JSON field - * has an unexpected type. - */ - @JsonProperty("capital_withdrawal") - @ExcludeMissing - fun _capitalWithdrawal(): JsonField = capitalWithdrawal - - /** - * Returns the raw JSON value of [credit]. - * - * Unlike [credit], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("credit") - @ExcludeMissing - fun _credit(): JsonField = credit - - /** - * Returns the raw JSON value of [debit]. - * - * Unlike [debit], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("debit") - @ExcludeMissing - fun _debit(): JsonField = debit - - /** - * Returns the raw JSON value of [incomeDistribution]. - * - * Unlike [incomeDistribution], this method doesn't throw if the JSON field - * has an unexpected type. - */ - @JsonProperty("income_distribution") - @ExcludeMissing - fun _incomeDistribution(): JsonField = incomeDistribution - - /** - * Returns the raw JSON value of [orderNo]. - * - * Unlike [orderNo], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("order_no") - @ExcludeMissing - fun _orderNo(): JsonField = orderNo - - /** - * Returns the raw JSON value of [price]. - * - * Unlike [price], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("price") - @ExcludeMissing - fun _price(): JsonField = price - - /** - * Returns the raw JSON value of [stampDuty]. - * - * Unlike [stampDuty], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("stamp_duty") - @ExcludeMissing - fun _stampDuty(): JsonField = stampDuty - - @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 - * [AdditionalInfo]. - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [AdditionalInfo]. */ - class Builder internal constructor() { - - private var capitalWithdrawal: JsonField = JsonMissing.of() - private var credit: JsonField = JsonMissing.of() - private var debit: JsonField = JsonMissing.of() - private var incomeDistribution: JsonField = JsonMissing.of() - private var orderNo: JsonField = JsonMissing.of() - private var price: JsonField = JsonMissing.of() - private var stampDuty: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = - mutableMapOf() - - @JvmSynthetic - internal fun from(additionalInfo: AdditionalInfo) = apply { - capitalWithdrawal = additionalInfo.capitalWithdrawal - credit = additionalInfo.credit - debit = additionalInfo.debit - incomeDistribution = additionalInfo.incomeDistribution - orderNo = additionalInfo.orderNo - price = additionalInfo.price - stampDuty = additionalInfo.stampDuty - additionalProperties = - additionalInfo.additionalProperties.toMutableMap() - } - - /** Capital withdrawal amount (CDSL MF transactions) */ - fun capitalWithdrawal(capitalWithdrawal: Float) = - capitalWithdrawal(JsonField.of(capitalWithdrawal)) - - /** - * Sets [Builder.capitalWithdrawal] to an arbitrary JSON value. - * - * You should usually call [Builder.capitalWithdrawal] with a well-typed - * [Float] value instead. This method is primarily for setting the field - * to an undocumented or not yet supported value. - */ - fun capitalWithdrawal(capitalWithdrawal: JsonField) = apply { - this.capitalWithdrawal = capitalWithdrawal - } - - /** Units credited (demat transactions) */ - fun credit(credit: Float) = credit(JsonField.of(credit)) - - /** - * Sets [Builder.credit] to an arbitrary JSON value. - * - * You should usually call [Builder.credit] with a well-typed [Float] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun credit(credit: JsonField) = apply { this.credit = credit } - - /** Units debited (demat transactions) */ - fun debit(debit: Float) = debit(JsonField.of(debit)) - - /** - * Sets [Builder.debit] to an arbitrary JSON value. - * - * You should usually call [Builder.debit] with a well-typed [Float] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun debit(debit: JsonField) = apply { this.debit = debit } - - /** Income distribution amount (CDSL MF transactions) */ - fun incomeDistribution(incomeDistribution: Float) = - incomeDistribution(JsonField.of(incomeDistribution)) - - /** - * Sets [Builder.incomeDistribution] to an arbitrary JSON value. - * - * You should usually call [Builder.incomeDistribution] with a - * well-typed [Float] value instead. This method is primarily for - * setting the field to an undocumented or not yet supported value. - */ - fun incomeDistribution(incomeDistribution: JsonField) = apply { - this.incomeDistribution = incomeDistribution - } - - /** Order/transaction reference number (demat transactions) */ - fun orderNo(orderNo: String) = orderNo(JsonField.of(orderNo)) - - /** - * Sets [Builder.orderNo] to an arbitrary JSON value. - * - * You should usually call [Builder.orderNo] with a well-typed [String] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun orderNo(orderNo: JsonField) = apply { - this.orderNo = orderNo - } - - /** Price per unit (NSDL/CDSL MF transactions) */ - fun price(price: Float) = price(JsonField.of(price)) - - /** - * Sets [Builder.price] to an arbitrary JSON value. - * - * You should usually call [Builder.price] with a well-typed [Float] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun price(price: JsonField) = apply { this.price = price } - - /** Stamp duty charged */ - fun stampDuty(stampDuty: Float) = stampDuty(JsonField.of(stampDuty)) - - /** - * Sets [Builder.stampDuty] to an arbitrary JSON value. - * - * You should usually call [Builder.stampDuty] with a well-typed [Float] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun stampDuty(stampDuty: JsonField) = apply { - this.stampDuty = stampDuty - } - - 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 [AdditionalInfo]. - * - * Further updates to this [Builder] will not mutate the returned - * instance. - */ - fun build(): AdditionalInfo = - AdditionalInfo( - capitalWithdrawal, - credit, - debit, - incomeDistribution, - orderNo, - price, - stampDuty, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): AdditionalInfo = apply { - if (validated) { - return@apply - } - - capitalWithdrawal() - credit() - debit() - incomeDistribution() - orderNo() - price() - stampDuty() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - 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 (capitalWithdrawal.asKnown().isPresent) 1 else 0) + - (if (credit.asKnown().isPresent) 1 else 0) + - (if (debit.asKnown().isPresent) 1 else 0) + - (if (incomeDistribution.asKnown().isPresent) 1 else 0) + - (if (orderNo.asKnown().isPresent) 1 else 0) + - (if (price.asKnown().isPresent) 1 else 0) + - (if (stampDuty.asKnown().isPresent) 1 else 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is AdditionalInfo && - capitalWithdrawal == other.capitalWithdrawal && - credit == other.credit && - debit == other.debit && - incomeDistribution == other.incomeDistribution && - orderNo == other.orderNo && - price == other.price && - stampDuty == other.stampDuty && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash( - capitalWithdrawal, - credit, - debit, - incomeDistribution, - orderNo, - price, - stampDuty, - additionalProperties, - ) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "AdditionalInfo{capitalWithdrawal=$capitalWithdrawal, credit=$credit, debit=$debit, incomeDistribution=$incomeDistribution, orderNo=$orderNo, price=$price, stampDuty=$stampDuty, additionalProperties=$additionalProperties}" - } - - /** - * Transaction type. Possible values are PURCHASE, PURCHASE_SIP, REDEMPTION, - * SWITCH_IN, SWITCH_IN_MERGER, SWITCH_OUT, SWITCH_OUT_MERGER, DIVIDEND_PAYOUT, - * DIVIDEND_REINVEST, SEGREGATION, STAMP_DUTY_TAX, TDS_TAX, STT_TAX, MISC, - * REVERSAL, UNKNOWN. - */ - class Type - @JsonCreator - private constructor(private val value: JsonField) : Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data - * that doesn't match any known member, and you want to know that value. For - * example, if the SDK is on an older version than the API, then the API may - * respond with new members that the SDK is unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue - fun _value(): JsonField = value - - companion object { - - @JvmField val PURCHASE = of("PURCHASE") - - @JvmField val PURCHASE_SIP = of("PURCHASE_SIP") - - @JvmField val REDEMPTION = of("REDEMPTION") - - @JvmField val SWITCH_IN = of("SWITCH_IN") - - @JvmField val SWITCH_IN_MERGER = of("SWITCH_IN_MERGER") - - @JvmField val SWITCH_OUT = of("SWITCH_OUT") - - @JvmField val SWITCH_OUT_MERGER = of("SWITCH_OUT_MERGER") - - @JvmField val DIVIDEND_PAYOUT = of("DIVIDEND_PAYOUT") - - @JvmField val DIVIDEND_REINVEST = of("DIVIDEND_REINVEST") - - @JvmField val SEGREGATION = of("SEGREGATION") - - @JvmField val STAMP_DUTY_TAX = of("STAMP_DUTY_TAX") - - @JvmField val TDS_TAX = of("TDS_TAX") - - @JvmField val STT_TAX = of("STT_TAX") - - @JvmField val MISC = of("MISC") - - @JvmField val REVERSAL = of("REVERSAL") - - @JvmField val UNKNOWN = of("UNKNOWN") - - @JvmStatic fun of(value: String) = Type(JsonField.of(value)) - } - - /** An enum containing [Type]'s known values. */ - enum class Known { - PURCHASE, - PURCHASE_SIP, - REDEMPTION, - SWITCH_IN, - SWITCH_IN_MERGER, - SWITCH_OUT, - SWITCH_OUT_MERGER, - DIVIDEND_PAYOUT, - DIVIDEND_REINVEST, - SEGREGATION, - STAMP_DUTY_TAX, - TDS_TAX, - STT_TAX, - MISC, - REVERSAL, - UNKNOWN, - } - - /** - * An enum containing [Type]'s known values, as well as an [_UNKNOWN] - * member. - * - * An instance of [Type] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For - * example, if the SDK is on an older version than the API, then the API - * may respond with new members that the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - PURCHASE, - PURCHASE_SIP, - REDEMPTION, - SWITCH_IN, - SWITCH_IN_MERGER, - SWITCH_OUT, - SWITCH_OUT_MERGER, - DIVIDEND_PAYOUT, - DIVIDEND_REINVEST, - SEGREGATION, - STAMP_DUTY_TAX, - TDS_TAX, - STT_TAX, - MISC, - REVERSAL, - UNKNOWN, - /** - * An enum member indicating that [Type] was instantiated with an - * unknown value. - */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or - * [Value._UNKNOWN] if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always - * known or if you want to throw for the unknown case. - */ - fun value(): Value = - when (this) { - PURCHASE -> Value.PURCHASE - PURCHASE_SIP -> Value.PURCHASE_SIP - REDEMPTION -> Value.REDEMPTION - SWITCH_IN -> Value.SWITCH_IN - SWITCH_IN_MERGER -> Value.SWITCH_IN_MERGER - SWITCH_OUT -> Value.SWITCH_OUT - SWITCH_OUT_MERGER -> Value.SWITCH_OUT_MERGER - DIVIDEND_PAYOUT -> Value.DIVIDEND_PAYOUT - DIVIDEND_REINVEST -> Value.DIVIDEND_REINVEST - SEGREGATION -> Value.SEGREGATION - STAMP_DUTY_TAX -> Value.STAMP_DUTY_TAX - TDS_TAX -> Value.TDS_TAX - STT_TAX -> Value.STT_TAX - MISC -> Value.MISC - REVERSAL -> Value.REVERSAL - UNKNOWN -> Value.UNKNOWN - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always - * known and don't want to throw for the unknown case. - * - * @throws CasParserInvalidDataException if this class instance's value is a - * not a known member. - */ - fun known(): Known = - when (this) { - PURCHASE -> Known.PURCHASE - PURCHASE_SIP -> Known.PURCHASE_SIP - REDEMPTION -> Known.REDEMPTION - SWITCH_IN -> Known.SWITCH_IN - SWITCH_IN_MERGER -> Known.SWITCH_IN_MERGER - SWITCH_OUT -> Known.SWITCH_OUT - SWITCH_OUT_MERGER -> Known.SWITCH_OUT_MERGER - DIVIDEND_PAYOUT -> Known.DIVIDEND_PAYOUT - DIVIDEND_REINVEST -> Known.DIVIDEND_REINVEST - SEGREGATION -> Known.SEGREGATION - STAMP_DUTY_TAX -> Known.STAMP_DUTY_TAX - TDS_TAX -> Known.TDS_TAX - STT_TAX -> Known.STT_TAX - MISC -> Known.MISC - REVERSAL -> Known.REVERSAL - UNKNOWN -> Known.UNKNOWN - else -> throw CasParserInvalidDataException("Unknown Type: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily - * for debugging and generally doesn't throw. - * - * @throws CasParserInvalidDataException if this class instance's value does - * not have the expected primitive type. - */ - fun asString(): String = - _value().asString().orElseThrow { - CasParserInvalidDataException("Value is not a String") - } - - private var validated: Boolean = false - - fun validate(): Type = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - 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 (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Type && value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } + (if (closeUnits.asKnown().isPresent) 1 else 0) + + (if (openUnits.asKnown().isPresent) 1 else 0) override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is Transaction && - additionalInfo == other.additionalInfo && - amount == other.amount && - balance == other.balance && - date == other.date && - description == other.description && - dividendRate == other.dividendRate && - nav == other.nav && - type == other.type && - units == other.units && + return other is AdditionalInfo && + closeUnits == other.closeUnits && + openUnits == other.openUnits && additionalProperties == other.additionalProperties } private val hashCode: Int by lazy { - Objects.hash( - additionalInfo, - amount, - balance, - date, - description, - dividendRate, - nav, - type, - units, - additionalProperties, - ) + Objects.hash(closeUnits, openUnits, additionalProperties) } override fun hashCode(): Int = hashCode override fun toString() = - "Transaction{additionalInfo=$additionalInfo, amount=$amount, balance=$balance, date=$date, description=$description, dividendRate=$dividendRate, nav=$nav, type=$type, units=$units, additionalProperties=$additionalProperties}" + "AdditionalInfo{closeUnits=$closeUnits, openUnits=$openUnits, additionalProperties=$additionalProperties}" } override fun equals(other: Any?): Boolean { @@ -5375,7 +4181,7 @@ private constructor( return true } - return other is CorporateBond && + return other is Equity && additionalInfo == other.additionalInfo && isin == other.isin && name == other.name && @@ -5400,10 +4206,10 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "CorporateBond{additionalInfo=$additionalInfo, isin=$isin, name=$name, transactions=$transactions, units=$units, value=$value, additionalProperties=$additionalProperties}" + "Equity{additionalInfo=$additionalInfo, isin=$isin, name=$name, transactions=$transactions, units=$units, value=$value, additionalProperties=$additionalProperties}" } - class DematMutualFund + class GovernmentSecurity @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val additionalInfo: JsonField, @@ -5438,7 +4244,7 @@ private constructor( ) : this(additionalInfo, isin, name, transactions, units, value, mutableMapOf()) /** - * Additional information specific to the mutual fund + * Additional information specific to the government security * * @throws CasParserInvalidDataException if the JSON field has an unexpected type * (e.g. if the server responded with an unexpected value). @@ -5447,7 +4253,7 @@ private constructor( additionalInfo.getOptional("additional_info") /** - * ISIN code of the mutual fund + * ISIN code of the government security * * @throws CasParserInvalidDataException if the JSON field has an unexpected type * (e.g. if the server responded with an unexpected value). @@ -5455,7 +4261,7 @@ private constructor( fun isin(): Optional = isin.getOptional("isin") /** - * Name of the mutual fund + * Name of the government security * * @throws CasParserInvalidDataException if the JSON field has an unexpected type * (e.g. if the server responded with an unexpected value). @@ -5554,12 +4360,13 @@ private constructor( companion object { /** - * Returns a mutable builder for constructing an instance of [DematMutualFund]. + * Returns a mutable builder for constructing an instance of + * [GovernmentSecurity]. */ @JvmStatic fun builder() = Builder() } - /** A builder for [DematMutualFund]. */ + /** A builder for [GovernmentSecurity]. */ class Builder internal constructor() { private var additionalInfo: JsonField = JsonMissing.of() @@ -5571,17 +4378,18 @@ private constructor( private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(dematMutualFund: DematMutualFund) = apply { - additionalInfo = dematMutualFund.additionalInfo - isin = dematMutualFund.isin - name = dematMutualFund.name - transactions = dematMutualFund.transactions.map { it.toMutableList() } - units = dematMutualFund.units - value = dematMutualFund.value - additionalProperties = dematMutualFund.additionalProperties.toMutableMap() + internal fun from(governmentSecurity: GovernmentSecurity) = apply { + additionalInfo = governmentSecurity.additionalInfo + isin = governmentSecurity.isin + name = governmentSecurity.name + transactions = governmentSecurity.transactions.map { it.toMutableList() } + units = governmentSecurity.units + value = governmentSecurity.value + additionalProperties = + governmentSecurity.additionalProperties.toMutableMap() } - /** Additional information specific to the mutual fund */ + /** Additional information specific to the government security */ fun additionalInfo(additionalInfo: AdditionalInfo) = additionalInfo(JsonField.of(additionalInfo)) @@ -5596,7 +4404,7 @@ private constructor( this.additionalInfo = additionalInfo } - /** ISIN code of the mutual fund */ + /** ISIN code of the government security */ fun isin(isin: String) = isin(JsonField.of(isin)) /** @@ -5608,7 +4416,7 @@ private constructor( */ fun isin(isin: JsonField) = apply { this.isin = isin } - /** Name of the mutual fund */ + /** Name of the government security */ fun name(name: String) = name(JsonField.of(name)) /** @@ -5694,12 +4502,12 @@ private constructor( } /** - * Returns an immutable instance of [DematMutualFund]. + * Returns an immutable instance of [GovernmentSecurity]. * * Further updates to this [Builder] will not mutate the returned instance. */ - fun build(): DematMutualFund = - DematMutualFund( + fun build(): GovernmentSecurity = + GovernmentSecurity( additionalInfo, isin, name, @@ -5712,7 +4520,7 @@ private constructor( private var validated: Boolean = false - fun validate(): DematMutualFund = apply { + fun validate(): GovernmentSecurity = apply { if (validated) { return@apply } @@ -5749,7 +4557,7 @@ private constructor( (if (units.asKnown().isPresent) 1 else 0) + (if (value.asKnown().isPresent) 1 else 0) - /** Additional information specific to the mutual fund */ + /** Additional information specific to the government security */ class AdditionalInfo @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( @@ -5981,7014 +4789,1027 @@ private constructor( "AdditionalInfo{closeUnits=$closeUnits, openUnits=$openUnits, additionalProperties=$additionalProperties}" } - /** - * Unified transaction schema for all holding types (MF folios, equities, bonds, - * etc.) - */ - class Transaction - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val additionalInfo: JsonField, - private val amount: JsonField, - private val balance: JsonField, - private val date: JsonField, - private val description: JsonField, - private val dividendRate: JsonField, - private val nav: JsonField, - private val type: JsonField, - private val units: JsonField, - private val additionalProperties: MutableMap, - ) { + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - @JsonCreator - private constructor( - @JsonProperty("additional_info") - @ExcludeMissing - additionalInfo: JsonField = JsonMissing.of(), - @JsonProperty("amount") - @ExcludeMissing - amount: JsonField = JsonMissing.of(), - @JsonProperty("balance") - @ExcludeMissing - balance: JsonField = JsonMissing.of(), - @JsonProperty("date") - @ExcludeMissing - date: JsonField = JsonMissing.of(), - @JsonProperty("description") - @ExcludeMissing - description: JsonField = JsonMissing.of(), - @JsonProperty("dividend_rate") - @ExcludeMissing - dividendRate: JsonField = JsonMissing.of(), - @JsonProperty("nav") - @ExcludeMissing - nav: JsonField = JsonMissing.of(), - @JsonProperty("type") - @ExcludeMissing - type: JsonField = JsonMissing.of(), - @JsonProperty("units") - @ExcludeMissing - units: JsonField = JsonMissing.of(), - ) : this( + return other is GovernmentSecurity && + additionalInfo == other.additionalInfo && + isin == other.isin && + name == other.name && + transactions == other.transactions && + units == other.units && + value == other.value && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( additionalInfo, - amount, - balance, - date, - description, - dividendRate, - nav, - type, + isin, + name, + transactions, units, - mutableMapOf(), + value, + additionalProperties, ) + } - /** - * Additional transaction-specific fields that vary by source - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun additionalInfo(): Optional = - additionalInfo.getOptional("additional_info") - - /** - * Transaction amount in currency (computed from units × price/NAV) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun amount(): Optional = amount.getOptional("amount") - - /** - * Balance units after transaction - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun balance(): Optional = balance.getOptional("balance") + override fun hashCode(): Int = hashCode - /** - * Transaction date (YYYY-MM-DD) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun date(): Optional = date.getOptional("date") + override fun toString() = + "GovernmentSecurity{additionalInfo=$additionalInfo, isin=$isin, name=$name, transactions=$transactions, units=$units, value=$value, additionalProperties=$additionalProperties}" + } - /** - * Transaction description/particulars - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun description(): Optional = description.getOptional("description") + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - /** - * Dividend rate (for DIVIDEND_PAYOUT transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun dividendRate(): Optional = dividendRate.getOptional("dividend_rate") + return other is Holdings && + aifs == other.aifs && + corporateBonds == other.corporateBonds && + dematMutualFunds == other.dematMutualFunds && + equities == other.equities && + governmentSecurities == other.governmentSecurities && + additionalProperties == other.additionalProperties + } - /** - * NAV/price per unit on transaction date - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun nav(): Optional = nav.getOptional("nav") + private val hashCode: Int by lazy { + Objects.hash( + aifs, + corporateBonds, + dematMutualFunds, + equities, + governmentSecurities, + additionalProperties, + ) + } - /** - * Transaction type. Possible values are PURCHASE, PURCHASE_SIP, REDEMPTION, - * SWITCH_IN, SWITCH_IN_MERGER, SWITCH_OUT, SWITCH_OUT_MERGER, DIVIDEND_PAYOUT, - * DIVIDEND_REINVEST, SEGREGATION, STAMP_DUTY_TAX, TDS_TAX, STT_TAX, MISC, - * REVERSAL, UNKNOWN. - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun type(): Optional = type.getOptional("type") + override fun hashCode(): Int = hashCode - /** - * Number of units involved in transaction - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun units(): Optional = units.getOptional("units") + override fun toString() = + "Holdings{aifs=$aifs, corporateBonds=$corporateBonds, dematMutualFunds=$dematMutualFunds, equities=$equities, governmentSecurities=$governmentSecurities, additionalProperties=$additionalProperties}" + } - /** - * Returns the raw JSON value of [additionalInfo]. - * - * Unlike [additionalInfo], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("additional_info") - @ExcludeMissing - fun _additionalInfo(): JsonField = additionalInfo + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - /** - * Returns the raw JSON value of [amount]. - * - * Unlike [amount], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("amount") @ExcludeMissing fun _amount(): JsonField = amount + return other is DematAccount && + additionalInfo == other.additionalInfo && + boId == other.boId && + clientId == other.clientId && + dematType == other.dematType && + dpId == other.dpId && + dpName == other.dpName && + holdings == other.holdings && + linkedHolders == other.linkedHolders && + value == other.value && + additionalProperties == other.additionalProperties + } - /** - * Returns the raw JSON value of [balance]. - * - * Unlike [balance], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("balance") - @ExcludeMissing - fun _balance(): JsonField = balance + private val hashCode: Int by lazy { + Objects.hash( + additionalInfo, + boId, + clientId, + dematType, + dpId, + dpName, + holdings, + linkedHolders, + value, + additionalProperties, + ) + } - /** - * Returns the raw JSON value of [date]. - * - * Unlike [date], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("date") @ExcludeMissing fun _date(): JsonField = date + override fun hashCode(): Int = hashCode - /** - * Returns the raw JSON value of [description]. - * - * Unlike [description], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("description") - @ExcludeMissing - fun _description(): JsonField = description + override fun toString() = + "DematAccount{additionalInfo=$additionalInfo, boId=$boId, clientId=$clientId, dematType=$dematType, dpId=$dpId, dpName=$dpName, holdings=$holdings, linkedHolders=$linkedHolders, value=$value, additionalProperties=$additionalProperties}" + } - /** - * Returns the raw JSON value of [dividendRate]. - * - * Unlike [dividendRate], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("dividend_rate") - @ExcludeMissing - fun _dividendRate(): JsonField = dividendRate + class Insurance + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val lifeInsurancePolicies: JsonField>, + private val additionalProperties: MutableMap, + ) { - /** - * Returns the raw JSON value of [nav]. - * - * Unlike [nav], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("nav") @ExcludeMissing fun _nav(): JsonField = nav + @JsonCreator + private constructor( + @JsonProperty("life_insurance_policies") + @ExcludeMissing + lifeInsurancePolicies: JsonField> = JsonMissing.of() + ) : this(lifeInsurancePolicies, mutableMapOf()) - /** - * Returns the raw JSON value of [type]. - * - * Unlike [type], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun lifeInsurancePolicies(): Optional> = + lifeInsurancePolicies.getOptional("life_insurance_policies") - /** - * Returns the raw JSON value of [units]. - * - * Unlike [units], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("units") @ExcludeMissing fun _units(): JsonField = units + /** + * Returns the raw JSON value of [lifeInsurancePolicies]. + * + * Unlike [lifeInsurancePolicies], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("life_insurance_policies") + @ExcludeMissing + fun _lifeInsurancePolicies(): JsonField> = lifeInsurancePolicies - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) - fun toBuilder() = Builder().from(this) + fun toBuilder() = Builder().from(this) - companion object { + companion object { - /** - * Returns a mutable builder for constructing an instance of [Transaction]. - */ - @JvmStatic fun builder() = Builder() - } + /** Returns a mutable builder for constructing an instance of [Insurance]. */ + @JvmStatic fun builder() = Builder() + } - /** A builder for [Transaction]. */ - class Builder internal constructor() { + /** A builder for [Insurance]. */ + class Builder internal constructor() { - private var additionalInfo: JsonField = JsonMissing.of() - private var amount: JsonField = JsonMissing.of() - private var balance: JsonField = JsonMissing.of() - private var date: JsonField = JsonMissing.of() - private var description: JsonField = JsonMissing.of() - private var dividendRate: JsonField = JsonMissing.of() - private var nav: JsonField = JsonMissing.of() - private var type: JsonField = JsonMissing.of() - private var units: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = - mutableMapOf() + private var lifeInsurancePolicies: JsonField>? = null + private var additionalProperties: MutableMap = mutableMapOf() - @JvmSynthetic - internal fun from(transaction: Transaction) = apply { - additionalInfo = transaction.additionalInfo - amount = transaction.amount - balance = transaction.balance - date = transaction.date - description = transaction.description - dividendRate = transaction.dividendRate - nav = transaction.nav - type = transaction.type - units = transaction.units - additionalProperties = transaction.additionalProperties.toMutableMap() - } + @JvmSynthetic + internal fun from(insurance: Insurance) = apply { + lifeInsurancePolicies = insurance.lifeInsurancePolicies.map { it.toMutableList() } + additionalProperties = insurance.additionalProperties.toMutableMap() + } - /** Additional transaction-specific fields that vary by source */ - fun additionalInfo(additionalInfo: AdditionalInfo) = - additionalInfo(JsonField.of(additionalInfo)) + fun lifeInsurancePolicies(lifeInsurancePolicies: List) = + lifeInsurancePolicies(JsonField.of(lifeInsurancePolicies)) - /** - * Sets [Builder.additionalInfo] to an arbitrary JSON value. - * - * You should usually call [Builder.additionalInfo] with a well-typed - * [AdditionalInfo] value instead. This method is primarily for setting the - * field to an undocumented or not yet supported value. - */ - fun additionalInfo(additionalInfo: JsonField) = apply { - this.additionalInfo = additionalInfo - } + /** + * Sets [Builder.lifeInsurancePolicies] to an arbitrary JSON value. + * + * You should usually call [Builder.lifeInsurancePolicies] with a well-typed + * `List` value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun lifeInsurancePolicies(lifeInsurancePolicies: JsonField>) = + apply { + this.lifeInsurancePolicies = lifeInsurancePolicies.map { it.toMutableList() } + } - /** Transaction amount in currency (computed from units × price/NAV) */ - fun amount(amount: Float?) = amount(JsonField.ofNullable(amount)) + /** + * Adds a single [LifeInsurancePolicy] to [lifeInsurancePolicies]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addLifeInsurancePolicy(lifeInsurancePolicy: LifeInsurancePolicy) = apply { + lifeInsurancePolicies = + (lifeInsurancePolicies ?: JsonField.of(mutableListOf())).also { + checkKnown("lifeInsurancePolicies", it).add(lifeInsurancePolicy) + } + } - /** - * Alias for [Builder.amount]. - * - * This unboxed primitive overload exists for backwards compatibility. - */ - fun amount(amount: Float) = amount(amount as Float?) + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } - /** Alias for calling [Builder.amount] with `amount.orElse(null)`. */ - fun amount(amount: Optional) = amount(amount.getOrNull()) + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } - /** - * Sets [Builder.amount] to an arbitrary JSON value. - * - * You should usually call [Builder.amount] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun amount(amount: JsonField) = apply { this.amount = amount } + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } - /** Balance units after transaction */ - fun balance(balance: Float) = balance(JsonField.of(balance)) + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - /** - * Sets [Builder.balance] to an arbitrary JSON value. - * - * You should usually call [Builder.balance] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun balance(balance: JsonField) = apply { this.balance = balance } + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } - /** Transaction date (YYYY-MM-DD) */ - fun date(date: LocalDate) = date(JsonField.of(date)) + /** + * Returns an immutable instance of [Insurance]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Insurance = + Insurance( + (lifeInsurancePolicies ?: JsonMissing.of()).map { it.toImmutable() }, + additionalProperties.toMutableMap(), + ) + } - /** - * Sets [Builder.date] to an arbitrary JSON value. - * - * You should usually call [Builder.date] with a well-typed [LocalDate] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun date(date: JsonField) = apply { this.date = date } + private var validated: Boolean = false - /** Transaction description/particulars */ - fun description(description: String) = - description(JsonField.of(description)) + fun validate(): Insurance = apply { + if (validated) { + return@apply + } - /** - * Sets [Builder.description] to an arbitrary JSON value. - * - * You should usually call [Builder.description] with a well-typed [String] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun description(description: JsonField) = apply { - this.description = description - } + lifeInsurancePolicies().ifPresent { it.forEach { it.validate() } } + validated = true + } - /** Dividend rate (for DIVIDEND_PAYOUT transactions) */ - fun dividendRate(dividendRate: Float?) = - dividendRate(JsonField.ofNullable(dividendRate)) + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + false + } - /** - * Alias for [Builder.dividendRate]. - * - * This unboxed primitive overload exists for backwards compatibility. - */ - fun dividendRate(dividendRate: Float) = dividendRate(dividendRate as Float?) + /** + * 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 = + (lifeInsurancePolicies.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) - /** - * Alias for calling [Builder.dividendRate] with - * `dividendRate.orElse(null)`. - */ - fun dividendRate(dividendRate: Optional) = - dividendRate(dividendRate.getOrNull()) + class LifeInsurancePolicy + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val additionalInfo: JsonValue, + private val lifeAssured: JsonField, + private val policyName: JsonField, + private val policyNumber: JsonField, + private val premiumAmount: JsonField, + private val premiumFrequency: JsonField, + private val provider: JsonField, + private val status: JsonField, + private val sumAssured: JsonField, + private val additionalProperties: MutableMap, + ) { - /** - * Sets [Builder.dividendRate] to an arbitrary JSON value. - * - * You should usually call [Builder.dividendRate] with a well-typed [Float] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun dividendRate(dividendRate: JsonField) = apply { - this.dividendRate = dividendRate - } + @JsonCreator + private constructor( + @JsonProperty("additional_info") + @ExcludeMissing + additionalInfo: JsonValue = JsonMissing.of(), + @JsonProperty("life_assured") + @ExcludeMissing + lifeAssured: JsonField = JsonMissing.of(), + @JsonProperty("policy_name") + @ExcludeMissing + policyName: JsonField = JsonMissing.of(), + @JsonProperty("policy_number") + @ExcludeMissing + policyNumber: JsonField = JsonMissing.of(), + @JsonProperty("premium_amount") + @ExcludeMissing + premiumAmount: JsonField = JsonMissing.of(), + @JsonProperty("premium_frequency") + @ExcludeMissing + premiumFrequency: JsonField = JsonMissing.of(), + @JsonProperty("provider") + @ExcludeMissing + provider: JsonField = JsonMissing.of(), + @JsonProperty("status") + @ExcludeMissing + status: JsonField = JsonMissing.of(), + @JsonProperty("sum_assured") + @ExcludeMissing + sumAssured: JsonField = JsonMissing.of(), + ) : this( + additionalInfo, + lifeAssured, + policyName, + policyNumber, + premiumAmount, + premiumFrequency, + provider, + status, + sumAssured, + mutableMapOf(), + ) - /** NAV/price per unit on transaction date */ - fun nav(nav: Float?) = nav(JsonField.ofNullable(nav)) + /** + * Additional information specific to the policy + * + * This arbitrary value can be deserialized into a custom type using the `convert` + * method: + * ```java + * MyClass myObject = lifeInsurancePolicy.additionalInfo().convert(MyClass.class); + * ``` + */ + @JsonProperty("additional_info") + @ExcludeMissing + fun _additionalInfo(): JsonValue = additionalInfo - /** - * Alias for [Builder.nav]. - * - * This unboxed primitive overload exists for backwards compatibility. - */ - fun nav(nav: Float) = nav(nav as Float?) + /** + * Name of the life assured + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun lifeAssured(): Optional = lifeAssured.getOptional("life_assured") - /** Alias for calling [Builder.nav] with `nav.orElse(null)`. */ - fun nav(nav: Optional) = nav(nav.getOrNull()) + /** + * Name of the insurance policy + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun policyName(): Optional = policyName.getOptional("policy_name") - /** - * Sets [Builder.nav] to an arbitrary JSON value. - * - * You should usually call [Builder.nav] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun nav(nav: JsonField) = apply { this.nav = nav } + /** + * Insurance policy number + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun policyNumber(): Optional = policyNumber.getOptional("policy_number") - /** - * Transaction type. Possible values are PURCHASE, PURCHASE_SIP, REDEMPTION, - * SWITCH_IN, SWITCH_IN_MERGER, SWITCH_OUT, SWITCH_OUT_MERGER, - * DIVIDEND_PAYOUT, DIVIDEND_REINVEST, SEGREGATION, STAMP_DUTY_TAX, TDS_TAX, - * STT_TAX, MISC, REVERSAL, UNKNOWN. - */ - fun type(type: Type) = type(JsonField.of(type)) + /** + * Premium amount + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun premiumAmount(): Optional = premiumAmount.getOptional("premium_amount") - /** - * Sets [Builder.type] to an arbitrary JSON value. - * - * You should usually call [Builder.type] with a well-typed [Type] value - * instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun type(type: JsonField) = apply { this.type = type } + /** + * Frequency of premium payment (e.g., Annual, Monthly) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun premiumFrequency(): Optional = + premiumFrequency.getOptional("premium_frequency") - /** Number of units involved in transaction */ - fun units(units: Float) = units(JsonField.of(units)) + /** + * Insurance company name + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun provider(): Optional = provider.getOptional("provider") - /** - * Sets [Builder.units] to an arbitrary JSON value. - * - * You should usually call [Builder.units] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun units(units: JsonField) = apply { this.units = units } + /** + * Status of the policy (e.g., Active, Lapsed) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun status(): Optional = status.getOptional("status") - fun additionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } + /** + * Sum assured amount + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun sumAssured(): Optional = sumAssured.getOptional("sum_assured") - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } + /** + * Returns the raw JSON value of [lifeAssured]. + * + * Unlike [lifeAssured], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("life_assured") + @ExcludeMissing + fun _lifeAssured(): JsonField = lifeAssured - fun putAllAdditionalProperties( - additionalProperties: Map - ) = apply { this.additionalProperties.putAll(additionalProperties) } - - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) - } + /** + * Returns the raw JSON value of [policyName]. + * + * Unlike [policyName], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("policy_name") + @ExcludeMissing + fun _policyName(): JsonField = policyName - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } + /** + * Returns the raw JSON value of [policyNumber]. + * + * Unlike [policyNumber], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("policy_number") + @ExcludeMissing + fun _policyNumber(): JsonField = policyNumber - /** - * Returns an immutable instance of [Transaction]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): Transaction = - Transaction( - additionalInfo, - amount, - balance, - date, - description, - dividendRate, - nav, - type, - units, - additionalProperties.toMutableMap(), - ) - } + /** + * Returns the raw JSON value of [premiumAmount]. + * + * Unlike [premiumAmount], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("premium_amount") + @ExcludeMissing + fun _premiumAmount(): JsonField = premiumAmount - private var validated: Boolean = false + /** + * Returns the raw JSON value of [premiumFrequency]. + * + * Unlike [premiumFrequency], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("premium_frequency") + @ExcludeMissing + fun _premiumFrequency(): JsonField = premiumFrequency - fun validate(): Transaction = apply { - if (validated) { - return@apply - } + /** + * Returns the raw JSON value of [provider]. + * + * Unlike [provider], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("provider") @ExcludeMissing fun _provider(): JsonField = provider - additionalInfo().ifPresent { it.validate() } - amount() - balance() - date() - description() - dividendRate() - nav() - type().ifPresent { it.validate() } - units() - validated = true - } + /** + * Returns the raw JSON value of [status]. + * + * Unlike [status], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("status") @ExcludeMissing fun _status(): JsonField = status - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - false - } + /** + * Returns the raw JSON value of [sumAssured]. + * + * Unlike [sumAssured], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("sum_assured") + @ExcludeMissing + fun _sumAssured(): JsonField = sumAssured - /** - * 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 = - (additionalInfo.asKnown().getOrNull()?.validity() ?: 0) + - (if (amount.asKnown().isPresent) 1 else 0) + - (if (balance.asKnown().isPresent) 1 else 0) + - (if (date.asKnown().isPresent) 1 else 0) + - (if (description.asKnown().isPresent) 1 else 0) + - (if (dividendRate.asKnown().isPresent) 1 else 0) + - (if (nav.asKnown().isPresent) 1 else 0) + - (type.asKnown().getOrNull()?.validity() ?: 0) + - (if (units.asKnown().isPresent) 1 else 0) - - /** Additional transaction-specific fields that vary by source */ - class AdditionalInfo - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val capitalWithdrawal: JsonField, - private val credit: JsonField, - private val debit: JsonField, - private val incomeDistribution: JsonField, - private val orderNo: JsonField, - private val price: JsonField, - private val stampDuty: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("capital_withdrawal") - @ExcludeMissing - capitalWithdrawal: JsonField = JsonMissing.of(), - @JsonProperty("credit") - @ExcludeMissing - credit: JsonField = JsonMissing.of(), - @JsonProperty("debit") - @ExcludeMissing - debit: JsonField = JsonMissing.of(), - @JsonProperty("income_distribution") - @ExcludeMissing - incomeDistribution: JsonField = JsonMissing.of(), - @JsonProperty("order_no") - @ExcludeMissing - orderNo: JsonField = JsonMissing.of(), - @JsonProperty("price") - @ExcludeMissing - price: JsonField = JsonMissing.of(), - @JsonProperty("stamp_duty") - @ExcludeMissing - stampDuty: JsonField = JsonMissing.of(), - ) : this( - capitalWithdrawal, - credit, - debit, - incomeDistribution, - orderNo, - price, - stampDuty, - mutableMapOf(), - ) + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } - /** - * Capital withdrawal amount (CDSL MF transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun capitalWithdrawal(): Optional = - capitalWithdrawal.getOptional("capital_withdrawal") + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) - /** - * Units credited (demat transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun credit(): Optional = credit.getOptional("credit") + fun toBuilder() = Builder().from(this) - /** - * Units debited (demat transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun debit(): Optional = debit.getOptional("debit") + companion object { - /** - * Income distribution amount (CDSL MF transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun incomeDistribution(): Optional = - incomeDistribution.getOptional("income_distribution") + /** + * Returns a mutable builder for constructing an instance of [LifeInsurancePolicy]. + */ + @JvmStatic fun builder() = Builder() + } - /** - * Order/transaction reference number (demat transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun orderNo(): Optional = orderNo.getOptional("order_no") + /** A builder for [LifeInsurancePolicy]. */ + class Builder internal constructor() { - /** - * Price per unit (NSDL/CDSL MF transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun price(): Optional = price.getOptional("price") + private var additionalInfo: JsonValue = JsonMissing.of() + private var lifeAssured: JsonField = JsonMissing.of() + private var policyName: JsonField = JsonMissing.of() + private var policyNumber: JsonField = JsonMissing.of() + private var premiumAmount: JsonField = JsonMissing.of() + private var premiumFrequency: JsonField = JsonMissing.of() + private var provider: JsonField = JsonMissing.of() + private var status: JsonField = JsonMissing.of() + private var sumAssured: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() - /** - * Stamp duty charged - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun stampDuty(): Optional = stampDuty.getOptional("stamp_duty") + @JvmSynthetic + internal fun from(lifeInsurancePolicy: LifeInsurancePolicy) = apply { + additionalInfo = lifeInsurancePolicy.additionalInfo + lifeAssured = lifeInsurancePolicy.lifeAssured + policyName = lifeInsurancePolicy.policyName + policyNumber = lifeInsurancePolicy.policyNumber + premiumAmount = lifeInsurancePolicy.premiumAmount + premiumFrequency = lifeInsurancePolicy.premiumFrequency + provider = lifeInsurancePolicy.provider + status = lifeInsurancePolicy.status + sumAssured = lifeInsurancePolicy.sumAssured + additionalProperties = lifeInsurancePolicy.additionalProperties.toMutableMap() + } - /** - * Returns the raw JSON value of [capitalWithdrawal]. - * - * Unlike [capitalWithdrawal], this method doesn't throw if the JSON field - * has an unexpected type. - */ - @JsonProperty("capital_withdrawal") - @ExcludeMissing - fun _capitalWithdrawal(): JsonField = capitalWithdrawal + /** Additional information specific to the policy */ + fun additionalInfo(additionalInfo: JsonValue) = apply { + this.additionalInfo = additionalInfo + } - /** - * Returns the raw JSON value of [credit]. - * - * Unlike [credit], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("credit") - @ExcludeMissing - fun _credit(): JsonField = credit + /** Name of the life assured */ + fun lifeAssured(lifeAssured: String) = lifeAssured(JsonField.of(lifeAssured)) - /** - * Returns the raw JSON value of [debit]. - * - * Unlike [debit], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("debit") - @ExcludeMissing - fun _debit(): JsonField = debit + /** + * Sets [Builder.lifeAssured] to an arbitrary JSON value. + * + * You should usually call [Builder.lifeAssured] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun lifeAssured(lifeAssured: JsonField) = apply { + this.lifeAssured = lifeAssured + } - /** - * Returns the raw JSON value of [incomeDistribution]. - * - * Unlike [incomeDistribution], this method doesn't throw if the JSON field - * has an unexpected type. - */ - @JsonProperty("income_distribution") - @ExcludeMissing - fun _incomeDistribution(): JsonField = incomeDistribution + /** Name of the insurance policy */ + fun policyName(policyName: String) = policyName(JsonField.of(policyName)) - /** - * Returns the raw JSON value of [orderNo]. - * - * Unlike [orderNo], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("order_no") - @ExcludeMissing - fun _orderNo(): JsonField = orderNo + /** + * Sets [Builder.policyName] to an arbitrary JSON value. + * + * You should usually call [Builder.policyName] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun policyName(policyName: JsonField) = apply { + this.policyName = policyName + } - /** - * Returns the raw JSON value of [price]. - * - * Unlike [price], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("price") - @ExcludeMissing - fun _price(): JsonField = price + /** Insurance policy number */ + fun policyNumber(policyNumber: String) = policyNumber(JsonField.of(policyNumber)) - /** - * Returns the raw JSON value of [stampDuty]. - * - * Unlike [stampDuty], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("stamp_duty") - @ExcludeMissing - fun _stampDuty(): JsonField = stampDuty + /** + * Sets [Builder.policyNumber] to an arbitrary JSON value. + * + * You should usually call [Builder.policyNumber] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun policyNumber(policyNumber: JsonField) = apply { + this.policyNumber = policyNumber + } - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } + /** Premium amount */ + fun premiumAmount(premiumAmount: Float) = premiumAmount(JsonField.of(premiumAmount)) - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) + /** + * Sets [Builder.premiumAmount] to an arbitrary JSON value. + * + * You should usually call [Builder.premiumAmount] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun premiumAmount(premiumAmount: JsonField) = apply { + this.premiumAmount = premiumAmount + } - fun toBuilder() = Builder().from(this) + /** Frequency of premium payment (e.g., Annual, Monthly) */ + fun premiumFrequency(premiumFrequency: String) = + premiumFrequency(JsonField.of(premiumFrequency)) - companion object { + /** + * Sets [Builder.premiumFrequency] to an arbitrary JSON value. + * + * You should usually call [Builder.premiumFrequency] with a well-typed [String] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun premiumFrequency(premiumFrequency: JsonField) = apply { + this.premiumFrequency = premiumFrequency + } - /** - * Returns a mutable builder for constructing an instance of - * [AdditionalInfo]. - */ - @JvmStatic fun builder() = Builder() - } + /** Insurance company name */ + fun provider(provider: String) = provider(JsonField.of(provider)) - /** A builder for [AdditionalInfo]. */ - class Builder internal constructor() { - - private var capitalWithdrawal: JsonField = JsonMissing.of() - private var credit: JsonField = JsonMissing.of() - private var debit: JsonField = JsonMissing.of() - private var incomeDistribution: JsonField = JsonMissing.of() - private var orderNo: JsonField = JsonMissing.of() - private var price: JsonField = JsonMissing.of() - private var stampDuty: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = - mutableMapOf() - - @JvmSynthetic - internal fun from(additionalInfo: AdditionalInfo) = apply { - capitalWithdrawal = additionalInfo.capitalWithdrawal - credit = additionalInfo.credit - debit = additionalInfo.debit - incomeDistribution = additionalInfo.incomeDistribution - orderNo = additionalInfo.orderNo - price = additionalInfo.price - stampDuty = additionalInfo.stampDuty - additionalProperties = - additionalInfo.additionalProperties.toMutableMap() - } - - /** Capital withdrawal amount (CDSL MF transactions) */ - fun capitalWithdrawal(capitalWithdrawal: Float) = - capitalWithdrawal(JsonField.of(capitalWithdrawal)) - - /** - * Sets [Builder.capitalWithdrawal] to an arbitrary JSON value. - * - * You should usually call [Builder.capitalWithdrawal] with a well-typed - * [Float] value instead. This method is primarily for setting the field - * to an undocumented or not yet supported value. - */ - fun capitalWithdrawal(capitalWithdrawal: JsonField) = apply { - this.capitalWithdrawal = capitalWithdrawal - } - - /** Units credited (demat transactions) */ - fun credit(credit: Float) = credit(JsonField.of(credit)) - - /** - * Sets [Builder.credit] to an arbitrary JSON value. - * - * You should usually call [Builder.credit] with a well-typed [Float] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun credit(credit: JsonField) = apply { this.credit = credit } - - /** Units debited (demat transactions) */ - fun debit(debit: Float) = debit(JsonField.of(debit)) - - /** - * Sets [Builder.debit] to an arbitrary JSON value. - * - * You should usually call [Builder.debit] with a well-typed [Float] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun debit(debit: JsonField) = apply { this.debit = debit } - - /** Income distribution amount (CDSL MF transactions) */ - fun incomeDistribution(incomeDistribution: Float) = - incomeDistribution(JsonField.of(incomeDistribution)) - - /** - * Sets [Builder.incomeDistribution] to an arbitrary JSON value. - * - * You should usually call [Builder.incomeDistribution] with a - * well-typed [Float] value instead. This method is primarily for - * setting the field to an undocumented or not yet supported value. - */ - fun incomeDistribution(incomeDistribution: JsonField) = apply { - this.incomeDistribution = incomeDistribution - } - - /** Order/transaction reference number (demat transactions) */ - fun orderNo(orderNo: String) = orderNo(JsonField.of(orderNo)) - - /** - * Sets [Builder.orderNo] to an arbitrary JSON value. - * - * You should usually call [Builder.orderNo] with a well-typed [String] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun orderNo(orderNo: JsonField) = apply { - this.orderNo = orderNo - } - - /** Price per unit (NSDL/CDSL MF transactions) */ - fun price(price: Float) = price(JsonField.of(price)) - - /** - * Sets [Builder.price] to an arbitrary JSON value. - * - * You should usually call [Builder.price] with a well-typed [Float] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun price(price: JsonField) = apply { this.price = price } - - /** Stamp duty charged */ - fun stampDuty(stampDuty: Float) = stampDuty(JsonField.of(stampDuty)) - - /** - * Sets [Builder.stampDuty] to an arbitrary JSON value. - * - * You should usually call [Builder.stampDuty] with a well-typed [Float] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun stampDuty(stampDuty: JsonField) = apply { - this.stampDuty = stampDuty - } + /** + * Sets [Builder.provider] to an arbitrary JSON value. + * + * You should usually call [Builder.provider] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun provider(provider: JsonField) = apply { this.provider = provider } - fun additionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } + /** Status of the policy (e.g., Active, Lapsed) */ + fun status(status: String) = status(JsonField.of(status)) - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } + /** + * Sets [Builder.status] to an arbitrary JSON value. + * + * You should usually call [Builder.status] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun status(status: JsonField) = apply { this.status = status } - fun putAllAdditionalProperties( - additionalProperties: Map - ) = apply { this.additionalProperties.putAll(additionalProperties) } + /** Sum assured amount */ + fun sumAssured(sumAssured: Float) = sumAssured(JsonField.of(sumAssured)) - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) - } + /** + * Sets [Builder.sumAssured] to an arbitrary JSON value. + * + * You should usually call [Builder.sumAssured] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun sumAssured(sumAssured: JsonField) = apply { + this.sumAssured = sumAssured + } - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } - /** - * Returns an immutable instance of [AdditionalInfo]. - * - * Further updates to this [Builder] will not mutate the returned - * instance. - */ - fun build(): AdditionalInfo = - AdditionalInfo( - capitalWithdrawal, - credit, - debit, - incomeDistribution, - orderNo, - price, - stampDuty, - additionalProperties.toMutableMap(), - ) - } + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } - private var validated: Boolean = false + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } - fun validate(): AdditionalInfo = apply { - if (validated) { - return@apply - } + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } - capitalWithdrawal() - credit() - debit() - incomeDistribution() - orderNo() - price() - stampDuty() - validated = true - } + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - false - } + /** + * Returns an immutable instance of [LifeInsurancePolicy]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): LifeInsurancePolicy = + LifeInsurancePolicy( + additionalInfo, + lifeAssured, + policyName, + policyNumber, + premiumAmount, + premiumFrequency, + provider, + status, + sumAssured, + additionalProperties.toMutableMap(), + ) + } - /** - * 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 (capitalWithdrawal.asKnown().isPresent) 1 else 0) + - (if (credit.asKnown().isPresent) 1 else 0) + - (if (debit.asKnown().isPresent) 1 else 0) + - (if (incomeDistribution.asKnown().isPresent) 1 else 0) + - (if (orderNo.asKnown().isPresent) 1 else 0) + - (if (price.asKnown().isPresent) 1 else 0) + - (if (stampDuty.asKnown().isPresent) 1 else 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + private var validated: Boolean = false - return other is AdditionalInfo && - capitalWithdrawal == other.capitalWithdrawal && - credit == other.credit && - debit == other.debit && - incomeDistribution == other.incomeDistribution && - orderNo == other.orderNo && - price == other.price && - stampDuty == other.stampDuty && - additionalProperties == other.additionalProperties - } + fun validate(): LifeInsurancePolicy = apply { + if (validated) { + return@apply + } - private val hashCode: Int by lazy { - Objects.hash( - capitalWithdrawal, - credit, - debit, - incomeDistribution, - orderNo, - price, - stampDuty, - additionalProperties, - ) - } + lifeAssured() + policyName() + policyNumber() + premiumAmount() + premiumFrequency() + provider() + status() + sumAssured() + validated = true + } - override fun hashCode(): Int = hashCode + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + false + } - override fun toString() = - "AdditionalInfo{capitalWithdrawal=$capitalWithdrawal, credit=$credit, debit=$debit, incomeDistribution=$incomeDistribution, orderNo=$orderNo, price=$price, stampDuty=$stampDuty, additionalProperties=$additionalProperties}" - } + /** + * 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 (lifeAssured.asKnown().isPresent) 1 else 0) + + (if (policyName.asKnown().isPresent) 1 else 0) + + (if (policyNumber.asKnown().isPresent) 1 else 0) + + (if (premiumAmount.asKnown().isPresent) 1 else 0) + + (if (premiumFrequency.asKnown().isPresent) 1 else 0) + + (if (provider.asKnown().isPresent) 1 else 0) + + (if (status.asKnown().isPresent) 1 else 0) + + (if (sumAssured.asKnown().isPresent) 1 else 0) - /** - * Transaction type. Possible values are PURCHASE, PURCHASE_SIP, REDEMPTION, - * SWITCH_IN, SWITCH_IN_MERGER, SWITCH_OUT, SWITCH_OUT_MERGER, DIVIDEND_PAYOUT, - * DIVIDEND_REINVEST, SEGREGATION, STAMP_DUTY_TAX, TDS_TAX, STT_TAX, MISC, - * REVERSAL, UNKNOWN. - */ - class Type - @JsonCreator - private constructor(private val value: JsonField) : Enum { + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data - * that doesn't match any known member, and you want to know that value. For - * example, if the SDK is on an older version than the API, then the API may - * respond with new members that the SDK is unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue - fun _value(): JsonField = value + return other is LifeInsurancePolicy && + additionalInfo == other.additionalInfo && + lifeAssured == other.lifeAssured && + policyName == other.policyName && + policyNumber == other.policyNumber && + premiumAmount == other.premiumAmount && + premiumFrequency == other.premiumFrequency && + provider == other.provider && + status == other.status && + sumAssured == other.sumAssured && + additionalProperties == other.additionalProperties + } - companion object { + private val hashCode: Int by lazy { + Objects.hash( + additionalInfo, + lifeAssured, + policyName, + policyNumber, + premiumAmount, + premiumFrequency, + provider, + status, + sumAssured, + additionalProperties, + ) + } - @JvmField val PURCHASE = of("PURCHASE") + override fun hashCode(): Int = hashCode - @JvmField val PURCHASE_SIP = of("PURCHASE_SIP") + override fun toString() = + "LifeInsurancePolicy{additionalInfo=$additionalInfo, lifeAssured=$lifeAssured, policyName=$policyName, policyNumber=$policyNumber, premiumAmount=$premiumAmount, premiumFrequency=$premiumFrequency, provider=$provider, status=$status, sumAssured=$sumAssured, additionalProperties=$additionalProperties}" + } - @JvmField val REDEMPTION = of("REDEMPTION") + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - @JvmField val SWITCH_IN = of("SWITCH_IN") + return other is Insurance && + lifeInsurancePolicies == other.lifeInsurancePolicies && + additionalProperties == other.additionalProperties + } - @JvmField val SWITCH_IN_MERGER = of("SWITCH_IN_MERGER") + private val hashCode: Int by lazy { + Objects.hash(lifeInsurancePolicies, additionalProperties) + } - @JvmField val SWITCH_OUT = of("SWITCH_OUT") + override fun hashCode(): Int = hashCode - @JvmField val SWITCH_OUT_MERGER = of("SWITCH_OUT_MERGER") + override fun toString() = + "Insurance{lifeInsurancePolicies=$lifeInsurancePolicies, additionalProperties=$additionalProperties}" + } - @JvmField val DIVIDEND_PAYOUT = of("DIVIDEND_PAYOUT") + class Investor + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val address: JsonField, + private val casId: JsonField, + private val email: JsonField, + private val mobile: JsonField, + private val name: JsonField, + private val pan: JsonField, + private val pincode: JsonField, + private val additionalProperties: MutableMap, + ) { - @JvmField val DIVIDEND_REINVEST = of("DIVIDEND_REINVEST") + @JsonCreator + private constructor( + @JsonProperty("address") @ExcludeMissing address: JsonField = JsonMissing.of(), + @JsonProperty("cas_id") @ExcludeMissing casId: JsonField = JsonMissing.of(), + @JsonProperty("email") @ExcludeMissing email: JsonField = JsonMissing.of(), + @JsonProperty("mobile") @ExcludeMissing mobile: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("pan") @ExcludeMissing pan: JsonField = JsonMissing.of(), + @JsonProperty("pincode") @ExcludeMissing pincode: JsonField = JsonMissing.of(), + ) : this(address, casId, email, mobile, name, pan, pincode, mutableMapOf()) - @JvmField val SEGREGATION = of("SEGREGATION") + /** + * Address of the investor + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun address(): Optional = address.getOptional("address") - @JvmField val STAMP_DUTY_TAX = of("STAMP_DUTY_TAX") + /** + * CAS ID of the investor (only for NSDL and CDSL) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun casId(): Optional = casId.getOptional("cas_id") - @JvmField val TDS_TAX = of("TDS_TAX") + /** + * Email address of the investor + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun email(): Optional = email.getOptional("email") - @JvmField val STT_TAX = of("STT_TAX") + /** + * Mobile number of the investor + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun mobile(): Optional = mobile.getOptional("mobile") - @JvmField val MISC = of("MISC") + /** + * Name of the investor + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun name(): Optional = name.getOptional("name") - @JvmField val REVERSAL = of("REVERSAL") + /** + * PAN (Permanent Account Number) of the investor + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun pan(): Optional = pan.getOptional("pan") - @JvmField val UNKNOWN = of("UNKNOWN") + /** + * Postal code of the investor's address + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun pincode(): Optional = pincode.getOptional("pincode") - @JvmStatic fun of(value: String) = Type(JsonField.of(value)) - } + /** + * Returns the raw JSON value of [address]. + * + * Unlike [address], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("address") @ExcludeMissing fun _address(): JsonField = address - /** An enum containing [Type]'s known values. */ - enum class Known { - PURCHASE, - PURCHASE_SIP, - REDEMPTION, - SWITCH_IN, - SWITCH_IN_MERGER, - SWITCH_OUT, - SWITCH_OUT_MERGER, - DIVIDEND_PAYOUT, - DIVIDEND_REINVEST, - SEGREGATION, - STAMP_DUTY_TAX, - TDS_TAX, - STT_TAX, - MISC, - REVERSAL, - UNKNOWN, - } + /** + * Returns the raw JSON value of [casId]. + * + * Unlike [casId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("cas_id") @ExcludeMissing fun _casId(): JsonField = casId - /** - * An enum containing [Type]'s known values, as well as an [_UNKNOWN] - * member. - * - * An instance of [Type] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For - * example, if the SDK is on an older version than the API, then the API - * may respond with new members that the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - PURCHASE, - PURCHASE_SIP, - REDEMPTION, - SWITCH_IN, - SWITCH_IN_MERGER, - SWITCH_OUT, - SWITCH_OUT_MERGER, - DIVIDEND_PAYOUT, - DIVIDEND_REINVEST, - SEGREGATION, - STAMP_DUTY_TAX, - TDS_TAX, - STT_TAX, - MISC, - REVERSAL, - UNKNOWN, - /** - * An enum member indicating that [Type] was instantiated with an - * unknown value. - */ - _UNKNOWN, - } + /** + * Returns the raw JSON value of [email]. + * + * Unlike [email], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("email") @ExcludeMissing fun _email(): JsonField = email - /** - * Returns an enum member corresponding to this class instance's value, or - * [Value._UNKNOWN] if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always - * known or if you want to throw for the unknown case. - */ - fun value(): Value = - when (this) { - PURCHASE -> Value.PURCHASE - PURCHASE_SIP -> Value.PURCHASE_SIP - REDEMPTION -> Value.REDEMPTION - SWITCH_IN -> Value.SWITCH_IN - SWITCH_IN_MERGER -> Value.SWITCH_IN_MERGER - SWITCH_OUT -> Value.SWITCH_OUT - SWITCH_OUT_MERGER -> Value.SWITCH_OUT_MERGER - DIVIDEND_PAYOUT -> Value.DIVIDEND_PAYOUT - DIVIDEND_REINVEST -> Value.DIVIDEND_REINVEST - SEGREGATION -> Value.SEGREGATION - STAMP_DUTY_TAX -> Value.STAMP_DUTY_TAX - TDS_TAX -> Value.TDS_TAX - STT_TAX -> Value.STT_TAX - MISC -> Value.MISC - REVERSAL -> Value.REVERSAL - UNKNOWN -> Value.UNKNOWN - else -> Value._UNKNOWN - } + /** + * Returns the raw JSON value of [mobile]. + * + * Unlike [mobile], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("mobile") @ExcludeMissing fun _mobile(): JsonField = mobile - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always - * known and don't want to throw for the unknown case. - * - * @throws CasParserInvalidDataException if this class instance's value is a - * not a known member. - */ - fun known(): Known = - when (this) { - PURCHASE -> Known.PURCHASE - PURCHASE_SIP -> Known.PURCHASE_SIP - REDEMPTION -> Known.REDEMPTION - SWITCH_IN -> Known.SWITCH_IN - SWITCH_IN_MERGER -> Known.SWITCH_IN_MERGER - SWITCH_OUT -> Known.SWITCH_OUT - SWITCH_OUT_MERGER -> Known.SWITCH_OUT_MERGER - DIVIDEND_PAYOUT -> Known.DIVIDEND_PAYOUT - DIVIDEND_REINVEST -> Known.DIVIDEND_REINVEST - SEGREGATION -> Known.SEGREGATION - STAMP_DUTY_TAX -> Known.STAMP_DUTY_TAX - TDS_TAX -> Known.TDS_TAX - STT_TAX -> Known.STT_TAX - MISC -> Known.MISC - REVERSAL -> Known.REVERSAL - UNKNOWN -> Known.UNKNOWN - else -> throw CasParserInvalidDataException("Unknown Type: $value") - } + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily - * for debugging and generally doesn't throw. - * - * @throws CasParserInvalidDataException if this class instance's value does - * not have the expected primitive type. - */ - fun asString(): String = - _value().asString().orElseThrow { - CasParserInvalidDataException("Value is not a String") - } + /** + * Returns the raw JSON value of [pan]. + * + * Unlike [pan], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("pan") @ExcludeMissing fun _pan(): JsonField = pan - private var validated: Boolean = false + /** + * Returns the raw JSON value of [pincode]. + * + * Unlike [pincode], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("pincode") @ExcludeMissing fun _pincode(): JsonField = pincode - fun validate(): Type = apply { - if (validated) { - return@apply - } + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } - known() - validated = true - } + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - false - } + fun toBuilder() = Builder().from(this) - /** - * 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 (value() == Value._UNKNOWN) 0 else 1 + companion object { - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + /** Returns a mutable builder for constructing an instance of [Investor]. */ + @JvmStatic fun builder() = Builder() + } - return other is Type && value == other.value - } + /** A builder for [Investor]. */ + class Builder internal constructor() { - override fun hashCode() = value.hashCode() + private var address: JsonField = JsonMissing.of() + private var casId: JsonField = JsonMissing.of() + private var email: JsonField = JsonMissing.of() + private var mobile: JsonField = JsonMissing.of() + private var name: JsonField = JsonMissing.of() + private var pan: JsonField = JsonMissing.of() + private var pincode: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() - override fun toString() = value.toString() - } + @JvmSynthetic + internal fun from(investor: Investor) = apply { + address = investor.address + casId = investor.casId + email = investor.email + mobile = investor.mobile + name = investor.name + pan = investor.pan + pincode = investor.pincode + additionalProperties = investor.additionalProperties.toMutableMap() + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + /** Address of the investor */ + fun address(address: String) = address(JsonField.of(address)) - return other is Transaction && - additionalInfo == other.additionalInfo && - amount == other.amount && - balance == other.balance && - date == other.date && - description == other.description && - dividendRate == other.dividendRate && - nav == other.nav && - type == other.type && - units == other.units && - additionalProperties == other.additionalProperties - } + /** + * Sets [Builder.address] to an arbitrary JSON value. + * + * You should usually call [Builder.address] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun address(address: JsonField) = apply { this.address = address } - private val hashCode: Int by lazy { - Objects.hash( - additionalInfo, - amount, - balance, - date, - description, - dividendRate, - nav, - type, - units, - additionalProperties, - ) - } + /** CAS ID of the investor (only for NSDL and CDSL) */ + fun casId(casId: String) = casId(JsonField.of(casId)) - override fun hashCode(): Int = hashCode + /** + * Sets [Builder.casId] to an arbitrary JSON value. + * + * You should usually call [Builder.casId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun casId(casId: JsonField) = apply { this.casId = casId } - override fun toString() = - "Transaction{additionalInfo=$additionalInfo, amount=$amount, balance=$balance, date=$date, description=$description, dividendRate=$dividendRate, nav=$nav, type=$type, units=$units, additionalProperties=$additionalProperties}" - } + /** Email address of the investor */ + fun email(email: String) = email(JsonField.of(email)) - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + /** + * Sets [Builder.email] to an arbitrary JSON value. + * + * You should usually call [Builder.email] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun email(email: JsonField) = apply { this.email = email } - return other is DematMutualFund && - additionalInfo == other.additionalInfo && - isin == other.isin && - name == other.name && - transactions == other.transactions && - units == other.units && - value == other.value && - additionalProperties == other.additionalProperties - } + /** Mobile number of the investor */ + fun mobile(mobile: String) = mobile(JsonField.of(mobile)) - private val hashCode: Int by lazy { - Objects.hash( - additionalInfo, - isin, - name, - transactions, - units, - value, - additionalProperties, - ) - } + /** + * Sets [Builder.mobile] to an arbitrary JSON value. + * + * You should usually call [Builder.mobile] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun mobile(mobile: JsonField) = apply { this.mobile = mobile } - override fun hashCode(): Int = hashCode + /** Name of the investor */ + fun name(name: String) = name(JsonField.of(name)) - override fun toString() = - "DematMutualFund{additionalInfo=$additionalInfo, isin=$isin, name=$name, transactions=$transactions, units=$units, value=$value, additionalProperties=$additionalProperties}" - } + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun name(name: JsonField) = apply { this.name = name } - class Equity - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val additionalInfo: JsonField, - private val isin: JsonField, - private val name: JsonField, - private val transactions: JsonField>, - private val units: JsonField, - private val value: JsonField, - private val additionalProperties: MutableMap, - ) { + /** PAN (Permanent Account Number) of the investor */ + fun pan(pan: String) = pan(JsonField.of(pan)) - @JsonCreator - private constructor( - @JsonProperty("additional_info") - @ExcludeMissing - additionalInfo: JsonField = JsonMissing.of(), - @JsonProperty("isin") - @ExcludeMissing - isin: JsonField = JsonMissing.of(), - @JsonProperty("name") - @ExcludeMissing - name: JsonField = JsonMissing.of(), - @JsonProperty("transactions") - @ExcludeMissing - transactions: JsonField> = JsonMissing.of(), - @JsonProperty("units") - @ExcludeMissing - units: JsonField = JsonMissing.of(), - @JsonProperty("value") - @ExcludeMissing - value: JsonField = JsonMissing.of(), - ) : this(additionalInfo, isin, name, transactions, units, value, mutableMapOf()) + /** + * Sets [Builder.pan] to an arbitrary JSON value. + * + * You should usually call [Builder.pan] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun pan(pan: JsonField) = apply { this.pan = pan } - /** - * Additional information specific to the equity - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun additionalInfo(): Optional = - additionalInfo.getOptional("additional_info") - - /** - * ISIN code of the equity - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun isin(): Optional = isin.getOptional("isin") - - /** - * Name of the equity - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun name(): Optional = name.getOptional("name") - - /** - * List of transactions for this holding (beta) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun transactions(): Optional> = - transactions.getOptional("transactions") - - /** - * Number of units held - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun units(): Optional = units.getOptional("units") - - /** - * Current market value of the holding - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun value(): Optional = value.getOptional("value") - - /** - * Returns the raw JSON value of [additionalInfo]. - * - * Unlike [additionalInfo], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("additional_info") - @ExcludeMissing - fun _additionalInfo(): JsonField = additionalInfo - - /** - * Returns the raw JSON value of [isin]. - * - * Unlike [isin], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("isin") @ExcludeMissing fun _isin(): JsonField = isin - - /** - * Returns the raw JSON value of [name]. - * - * Unlike [name], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name - - /** - * Returns the raw JSON value of [transactions]. - * - * Unlike [transactions], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("transactions") - @ExcludeMissing - fun _transactions(): JsonField> = transactions - - /** - * Returns the raw JSON value of [units]. - * - * Unlike [units], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("units") @ExcludeMissing fun _units(): JsonField = units - - /** - * Returns the raw JSON value of [value]. - * - * Unlike [value], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("value") @ExcludeMissing fun _value(): JsonField = value - - @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 [Equity]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Equity]. */ - class Builder internal constructor() { - - private var additionalInfo: JsonField = JsonMissing.of() - private var isin: JsonField = JsonMissing.of() - private var name: JsonField = JsonMissing.of() - private var transactions: JsonField>? = null - private var units: JsonField = JsonMissing.of() - private var value: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(equity: Equity) = apply { - additionalInfo = equity.additionalInfo - isin = equity.isin - name = equity.name - transactions = equity.transactions.map { it.toMutableList() } - units = equity.units - value = equity.value - additionalProperties = equity.additionalProperties.toMutableMap() - } - - /** Additional information specific to the equity */ - fun additionalInfo(additionalInfo: AdditionalInfo) = - additionalInfo(JsonField.of(additionalInfo)) - - /** - * Sets [Builder.additionalInfo] to an arbitrary JSON value. - * - * You should usually call [Builder.additionalInfo] with a well-typed - * [AdditionalInfo] value instead. This method is primarily for setting the - * field to an undocumented or not yet supported value. - */ - fun additionalInfo(additionalInfo: JsonField) = apply { - this.additionalInfo = additionalInfo - } - - /** ISIN code of the equity */ - fun isin(isin: String) = isin(JsonField.of(isin)) - - /** - * Sets [Builder.isin] to an arbitrary JSON value. - * - * You should usually call [Builder.isin] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun isin(isin: JsonField) = apply { this.isin = isin } - - /** Name of the equity */ - fun name(name: String) = name(JsonField.of(name)) - - /** - * Sets [Builder.name] to an arbitrary JSON value. - * - * You should usually call [Builder.name] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun name(name: JsonField) = apply { this.name = name } - - /** List of transactions for this holding (beta) */ - fun transactions(transactions: List) = - transactions(JsonField.of(transactions)) - - /** - * Sets [Builder.transactions] to an arbitrary JSON value. - * - * You should usually call [Builder.transactions] with a well-typed - * `List` value instead. This method is primarily for setting the - * field to an undocumented or not yet supported value. - */ - fun transactions(transactions: JsonField>) = apply { - this.transactions = transactions.map { it.toMutableList() } - } - - /** - * Adds a single [Transaction] to [transactions]. - * - * @throws IllegalStateException if the field was previously set to a non-list. - */ - fun addTransaction(transaction: Transaction) = apply { - transactions = - (transactions ?: JsonField.of(mutableListOf())).also { - checkKnown("transactions", it).add(transaction) - } - } - - /** Number of units held */ - fun units(units: Float) = units(JsonField.of(units)) - - /** - * Sets [Builder.units] to an arbitrary JSON value. - * - * You should usually call [Builder.units] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun units(units: JsonField) = apply { this.units = units } - - /** Current market value of the holding */ - fun value(value: Float) = value(JsonField.of(value)) - - /** - * Sets [Builder.value] to an arbitrary JSON value. - * - * You should usually call [Builder.value] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun value(value: JsonField) = apply { this.value = value } - - 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 [Equity]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): Equity = - Equity( - additionalInfo, - isin, - name, - (transactions ?: JsonMissing.of()).map { it.toImmutable() }, - units, - value, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): Equity = apply { - if (validated) { - return@apply - } - - additionalInfo().ifPresent { it.validate() } - isin() - name() - transactions().ifPresent { it.forEach { it.validate() } } - units() - value() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - 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 = - (additionalInfo.asKnown().getOrNull()?.validity() ?: 0) + - (if (isin.asKnown().isPresent) 1 else 0) + - (if (name.asKnown().isPresent) 1 else 0) + - (transactions.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + - (if (units.asKnown().isPresent) 1 else 0) + - (if (value.asKnown().isPresent) 1 else 0) - - /** Additional information specific to the equity */ - class AdditionalInfo - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val closeUnits: JsonField, - private val openUnits: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("close_units") - @ExcludeMissing - closeUnits: JsonField = JsonMissing.of(), - @JsonProperty("open_units") - @ExcludeMissing - openUnits: JsonField = JsonMissing.of(), - ) : this(closeUnits, openUnits, mutableMapOf()) - - /** - * Closing balance units for the statement period (beta) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun closeUnits(): Optional = closeUnits.getOptional("close_units") - - /** - * Opening balance units for the statement period (beta) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun openUnits(): Optional = openUnits.getOptional("open_units") - - /** - * Returns the raw JSON value of [closeUnits]. - * - * Unlike [closeUnits], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("close_units") - @ExcludeMissing - fun _closeUnits(): JsonField = closeUnits - - /** - * Returns the raw JSON value of [openUnits]. - * - * Unlike [openUnits], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("open_units") - @ExcludeMissing - fun _openUnits(): JsonField = openUnits - - @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 - * [AdditionalInfo]. - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [AdditionalInfo]. */ - class Builder internal constructor() { - - private var closeUnits: JsonField = JsonMissing.of() - private var openUnits: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = - mutableMapOf() - - @JvmSynthetic - internal fun from(additionalInfo: AdditionalInfo) = apply { - closeUnits = additionalInfo.closeUnits - openUnits = additionalInfo.openUnits - additionalProperties = - additionalInfo.additionalProperties.toMutableMap() - } - - /** Closing balance units for the statement period (beta) */ - fun closeUnits(closeUnits: Float?) = - closeUnits(JsonField.ofNullable(closeUnits)) - - /** - * Alias for [Builder.closeUnits]. - * - * This unboxed primitive overload exists for backwards compatibility. - */ - fun closeUnits(closeUnits: Float) = closeUnits(closeUnits as Float?) - - /** - * Alias for calling [Builder.closeUnits] with `closeUnits.orElse(null)`. - */ - fun closeUnits(closeUnits: Optional) = - closeUnits(closeUnits.getOrNull()) - - /** - * Sets [Builder.closeUnits] to an arbitrary JSON value. - * - * You should usually call [Builder.closeUnits] with a well-typed [Float] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun closeUnits(closeUnits: JsonField) = apply { - this.closeUnits = closeUnits - } - - /** Opening balance units for the statement period (beta) */ - fun openUnits(openUnits: Float?) = - openUnits(JsonField.ofNullable(openUnits)) - - /** - * Alias for [Builder.openUnits]. - * - * This unboxed primitive overload exists for backwards compatibility. - */ - fun openUnits(openUnits: Float) = openUnits(openUnits as Float?) - - /** Alias for calling [Builder.openUnits] with `openUnits.orElse(null)`. */ - fun openUnits(openUnits: Optional) = openUnits(openUnits.getOrNull()) - - /** - * Sets [Builder.openUnits] to an arbitrary JSON value. - * - * You should usually call [Builder.openUnits] with a well-typed [Float] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun openUnits(openUnits: JsonField) = apply { - this.openUnits = openUnits - } - - 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 [AdditionalInfo]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): AdditionalInfo = - AdditionalInfo( - closeUnits, - openUnits, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): AdditionalInfo = apply { - if (validated) { - return@apply - } - - closeUnits() - openUnits() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - 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 (closeUnits.asKnown().isPresent) 1 else 0) + - (if (openUnits.asKnown().isPresent) 1 else 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is AdditionalInfo && - closeUnits == other.closeUnits && - openUnits == other.openUnits && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash(closeUnits, openUnits, additionalProperties) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "AdditionalInfo{closeUnits=$closeUnits, openUnits=$openUnits, additionalProperties=$additionalProperties}" - } - - /** - * Unified transaction schema for all holding types (MF folios, equities, bonds, - * etc.) - */ - class Transaction - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val additionalInfo: JsonField, - private val amount: JsonField, - private val balance: JsonField, - private val date: JsonField, - private val description: JsonField, - private val dividendRate: JsonField, - private val nav: JsonField, - private val type: JsonField, - private val units: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("additional_info") - @ExcludeMissing - additionalInfo: JsonField = JsonMissing.of(), - @JsonProperty("amount") - @ExcludeMissing - amount: JsonField = JsonMissing.of(), - @JsonProperty("balance") - @ExcludeMissing - balance: JsonField = JsonMissing.of(), - @JsonProperty("date") - @ExcludeMissing - date: JsonField = JsonMissing.of(), - @JsonProperty("description") - @ExcludeMissing - description: JsonField = JsonMissing.of(), - @JsonProperty("dividend_rate") - @ExcludeMissing - dividendRate: JsonField = JsonMissing.of(), - @JsonProperty("nav") - @ExcludeMissing - nav: JsonField = JsonMissing.of(), - @JsonProperty("type") - @ExcludeMissing - type: JsonField = JsonMissing.of(), - @JsonProperty("units") - @ExcludeMissing - units: JsonField = JsonMissing.of(), - ) : this( - additionalInfo, - amount, - balance, - date, - description, - dividendRate, - nav, - type, - units, - mutableMapOf(), - ) - - /** - * Additional transaction-specific fields that vary by source - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun additionalInfo(): Optional = - additionalInfo.getOptional("additional_info") - - /** - * Transaction amount in currency (computed from units × price/NAV) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun amount(): Optional = amount.getOptional("amount") - - /** - * Balance units after transaction - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun balance(): Optional = balance.getOptional("balance") - - /** - * Transaction date (YYYY-MM-DD) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun date(): Optional = date.getOptional("date") - - /** - * Transaction description/particulars - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun description(): Optional = description.getOptional("description") - - /** - * Dividend rate (for DIVIDEND_PAYOUT transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun dividendRate(): Optional = dividendRate.getOptional("dividend_rate") - - /** - * NAV/price per unit on transaction date - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun nav(): Optional = nav.getOptional("nav") - - /** - * Transaction type. Possible values are PURCHASE, PURCHASE_SIP, REDEMPTION, - * SWITCH_IN, SWITCH_IN_MERGER, SWITCH_OUT, SWITCH_OUT_MERGER, DIVIDEND_PAYOUT, - * DIVIDEND_REINVEST, SEGREGATION, STAMP_DUTY_TAX, TDS_TAX, STT_TAX, MISC, - * REVERSAL, UNKNOWN. - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun type(): Optional = type.getOptional("type") - - /** - * Number of units involved in transaction - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun units(): Optional = units.getOptional("units") - - /** - * Returns the raw JSON value of [additionalInfo]. - * - * Unlike [additionalInfo], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("additional_info") - @ExcludeMissing - fun _additionalInfo(): JsonField = additionalInfo - - /** - * Returns the raw JSON value of [amount]. - * - * Unlike [amount], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("amount") @ExcludeMissing fun _amount(): JsonField = amount - - /** - * Returns the raw JSON value of [balance]. - * - * Unlike [balance], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("balance") - @ExcludeMissing - fun _balance(): JsonField = balance - - /** - * Returns the raw JSON value of [date]. - * - * Unlike [date], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("date") @ExcludeMissing fun _date(): JsonField = date - - /** - * Returns the raw JSON value of [description]. - * - * Unlike [description], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("description") - @ExcludeMissing - fun _description(): JsonField = description - - /** - * Returns the raw JSON value of [dividendRate]. - * - * Unlike [dividendRate], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("dividend_rate") - @ExcludeMissing - fun _dividendRate(): JsonField = dividendRate - - /** - * Returns the raw JSON value of [nav]. - * - * Unlike [nav], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("nav") @ExcludeMissing fun _nav(): JsonField = nav - - /** - * Returns the raw JSON value of [type]. - * - * Unlike [type], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type - - /** - * Returns the raw JSON value of [units]. - * - * Unlike [units], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("units") @ExcludeMissing fun _units(): JsonField = units - - @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 [Transaction]. - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Transaction]. */ - class Builder internal constructor() { - - private var additionalInfo: JsonField = JsonMissing.of() - private var amount: JsonField = JsonMissing.of() - private var balance: JsonField = JsonMissing.of() - private var date: JsonField = JsonMissing.of() - private var description: JsonField = JsonMissing.of() - private var dividendRate: JsonField = JsonMissing.of() - private var nav: JsonField = JsonMissing.of() - private var type: JsonField = JsonMissing.of() - private var units: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = - mutableMapOf() - - @JvmSynthetic - internal fun from(transaction: Transaction) = apply { - additionalInfo = transaction.additionalInfo - amount = transaction.amount - balance = transaction.balance - date = transaction.date - description = transaction.description - dividendRate = transaction.dividendRate - nav = transaction.nav - type = transaction.type - units = transaction.units - additionalProperties = transaction.additionalProperties.toMutableMap() - } - - /** Additional transaction-specific fields that vary by source */ - fun additionalInfo(additionalInfo: AdditionalInfo) = - additionalInfo(JsonField.of(additionalInfo)) - - /** - * Sets [Builder.additionalInfo] to an arbitrary JSON value. - * - * You should usually call [Builder.additionalInfo] with a well-typed - * [AdditionalInfo] value instead. This method is primarily for setting the - * field to an undocumented or not yet supported value. - */ - fun additionalInfo(additionalInfo: JsonField) = apply { - this.additionalInfo = additionalInfo - } - - /** Transaction amount in currency (computed from units × price/NAV) */ - fun amount(amount: Float?) = amount(JsonField.ofNullable(amount)) - - /** - * Alias for [Builder.amount]. - * - * This unboxed primitive overload exists for backwards compatibility. - */ - fun amount(amount: Float) = amount(amount as Float?) - - /** Alias for calling [Builder.amount] with `amount.orElse(null)`. */ - fun amount(amount: Optional) = amount(amount.getOrNull()) - - /** - * Sets [Builder.amount] to an arbitrary JSON value. - * - * You should usually call [Builder.amount] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun amount(amount: JsonField) = apply { this.amount = amount } - - /** Balance units after transaction */ - fun balance(balance: Float) = balance(JsonField.of(balance)) - - /** - * Sets [Builder.balance] to an arbitrary JSON value. - * - * You should usually call [Builder.balance] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun balance(balance: JsonField) = apply { this.balance = balance } - - /** Transaction date (YYYY-MM-DD) */ - fun date(date: LocalDate) = date(JsonField.of(date)) - - /** - * Sets [Builder.date] to an arbitrary JSON value. - * - * You should usually call [Builder.date] with a well-typed [LocalDate] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun date(date: JsonField) = apply { this.date = date } - - /** Transaction description/particulars */ - fun description(description: String) = - description(JsonField.of(description)) - - /** - * Sets [Builder.description] to an arbitrary JSON value. - * - * You should usually call [Builder.description] with a well-typed [String] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun description(description: JsonField) = apply { - this.description = description - } - - /** Dividend rate (for DIVIDEND_PAYOUT transactions) */ - fun dividendRate(dividendRate: Float?) = - dividendRate(JsonField.ofNullable(dividendRate)) - - /** - * Alias for [Builder.dividendRate]. - * - * This unboxed primitive overload exists for backwards compatibility. - */ - fun dividendRate(dividendRate: Float) = dividendRate(dividendRate as Float?) - - /** - * Alias for calling [Builder.dividendRate] with - * `dividendRate.orElse(null)`. - */ - fun dividendRate(dividendRate: Optional) = - dividendRate(dividendRate.getOrNull()) - - /** - * Sets [Builder.dividendRate] to an arbitrary JSON value. - * - * You should usually call [Builder.dividendRate] with a well-typed [Float] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun dividendRate(dividendRate: JsonField) = apply { - this.dividendRate = dividendRate - } - - /** NAV/price per unit on transaction date */ - fun nav(nav: Float?) = nav(JsonField.ofNullable(nav)) - - /** - * Alias for [Builder.nav]. - * - * This unboxed primitive overload exists for backwards compatibility. - */ - fun nav(nav: Float) = nav(nav as Float?) - - /** Alias for calling [Builder.nav] with `nav.orElse(null)`. */ - fun nav(nav: Optional) = nav(nav.getOrNull()) - - /** - * Sets [Builder.nav] to an arbitrary JSON value. - * - * You should usually call [Builder.nav] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun nav(nav: JsonField) = apply { this.nav = nav } - - /** - * Transaction type. Possible values are PURCHASE, PURCHASE_SIP, REDEMPTION, - * SWITCH_IN, SWITCH_IN_MERGER, SWITCH_OUT, SWITCH_OUT_MERGER, - * DIVIDEND_PAYOUT, DIVIDEND_REINVEST, SEGREGATION, STAMP_DUTY_TAX, TDS_TAX, - * STT_TAX, MISC, REVERSAL, UNKNOWN. - */ - fun type(type: Type) = type(JsonField.of(type)) - - /** - * Sets [Builder.type] to an arbitrary JSON value. - * - * You should usually call [Builder.type] with a well-typed [Type] value - * instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun type(type: JsonField) = apply { this.type = type } - - /** Number of units involved in transaction */ - fun units(units: Float) = units(JsonField.of(units)) - - /** - * Sets [Builder.units] to an arbitrary JSON value. - * - * You should usually call [Builder.units] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun units(units: JsonField) = apply { this.units = units } - - 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 [Transaction]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): Transaction = - Transaction( - additionalInfo, - amount, - balance, - date, - description, - dividendRate, - nav, - type, - units, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): Transaction = apply { - if (validated) { - return@apply - } - - additionalInfo().ifPresent { it.validate() } - amount() - balance() - date() - description() - dividendRate() - nav() - type().ifPresent { it.validate() } - units() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - 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 = - (additionalInfo.asKnown().getOrNull()?.validity() ?: 0) + - (if (amount.asKnown().isPresent) 1 else 0) + - (if (balance.asKnown().isPresent) 1 else 0) + - (if (date.asKnown().isPresent) 1 else 0) + - (if (description.asKnown().isPresent) 1 else 0) + - (if (dividendRate.asKnown().isPresent) 1 else 0) + - (if (nav.asKnown().isPresent) 1 else 0) + - (type.asKnown().getOrNull()?.validity() ?: 0) + - (if (units.asKnown().isPresent) 1 else 0) - - /** Additional transaction-specific fields that vary by source */ - class AdditionalInfo - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val capitalWithdrawal: JsonField, - private val credit: JsonField, - private val debit: JsonField, - private val incomeDistribution: JsonField, - private val orderNo: JsonField, - private val price: JsonField, - private val stampDuty: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("capital_withdrawal") - @ExcludeMissing - capitalWithdrawal: JsonField = JsonMissing.of(), - @JsonProperty("credit") - @ExcludeMissing - credit: JsonField = JsonMissing.of(), - @JsonProperty("debit") - @ExcludeMissing - debit: JsonField = JsonMissing.of(), - @JsonProperty("income_distribution") - @ExcludeMissing - incomeDistribution: JsonField = JsonMissing.of(), - @JsonProperty("order_no") - @ExcludeMissing - orderNo: JsonField = JsonMissing.of(), - @JsonProperty("price") - @ExcludeMissing - price: JsonField = JsonMissing.of(), - @JsonProperty("stamp_duty") - @ExcludeMissing - stampDuty: JsonField = JsonMissing.of(), - ) : this( - capitalWithdrawal, - credit, - debit, - incomeDistribution, - orderNo, - price, - stampDuty, - mutableMapOf(), - ) - - /** - * Capital withdrawal amount (CDSL MF transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun capitalWithdrawal(): Optional = - capitalWithdrawal.getOptional("capital_withdrawal") - - /** - * Units credited (demat transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun credit(): Optional = credit.getOptional("credit") - - /** - * Units debited (demat transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun debit(): Optional = debit.getOptional("debit") - - /** - * Income distribution amount (CDSL MF transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun incomeDistribution(): Optional = - incomeDistribution.getOptional("income_distribution") - - /** - * Order/transaction reference number (demat transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun orderNo(): Optional = orderNo.getOptional("order_no") - - /** - * Price per unit (NSDL/CDSL MF transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun price(): Optional = price.getOptional("price") - - /** - * Stamp duty charged - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun stampDuty(): Optional = stampDuty.getOptional("stamp_duty") - - /** - * Returns the raw JSON value of [capitalWithdrawal]. - * - * Unlike [capitalWithdrawal], this method doesn't throw if the JSON field - * has an unexpected type. - */ - @JsonProperty("capital_withdrawal") - @ExcludeMissing - fun _capitalWithdrawal(): JsonField = capitalWithdrawal - - /** - * Returns the raw JSON value of [credit]. - * - * Unlike [credit], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("credit") - @ExcludeMissing - fun _credit(): JsonField = credit - - /** - * Returns the raw JSON value of [debit]. - * - * Unlike [debit], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("debit") - @ExcludeMissing - fun _debit(): JsonField = debit - - /** - * Returns the raw JSON value of [incomeDistribution]. - * - * Unlike [incomeDistribution], this method doesn't throw if the JSON field - * has an unexpected type. - */ - @JsonProperty("income_distribution") - @ExcludeMissing - fun _incomeDistribution(): JsonField = incomeDistribution - - /** - * Returns the raw JSON value of [orderNo]. - * - * Unlike [orderNo], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("order_no") - @ExcludeMissing - fun _orderNo(): JsonField = orderNo - - /** - * Returns the raw JSON value of [price]. - * - * Unlike [price], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("price") - @ExcludeMissing - fun _price(): JsonField = price - - /** - * Returns the raw JSON value of [stampDuty]. - * - * Unlike [stampDuty], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("stamp_duty") - @ExcludeMissing - fun _stampDuty(): JsonField = stampDuty - - @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 - * [AdditionalInfo]. - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [AdditionalInfo]. */ - class Builder internal constructor() { - - private var capitalWithdrawal: JsonField = JsonMissing.of() - private var credit: JsonField = JsonMissing.of() - private var debit: JsonField = JsonMissing.of() - private var incomeDistribution: JsonField = JsonMissing.of() - private var orderNo: JsonField = JsonMissing.of() - private var price: JsonField = JsonMissing.of() - private var stampDuty: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = - mutableMapOf() - - @JvmSynthetic - internal fun from(additionalInfo: AdditionalInfo) = apply { - capitalWithdrawal = additionalInfo.capitalWithdrawal - credit = additionalInfo.credit - debit = additionalInfo.debit - incomeDistribution = additionalInfo.incomeDistribution - orderNo = additionalInfo.orderNo - price = additionalInfo.price - stampDuty = additionalInfo.stampDuty - additionalProperties = - additionalInfo.additionalProperties.toMutableMap() - } - - /** Capital withdrawal amount (CDSL MF transactions) */ - fun capitalWithdrawal(capitalWithdrawal: Float) = - capitalWithdrawal(JsonField.of(capitalWithdrawal)) - - /** - * Sets [Builder.capitalWithdrawal] to an arbitrary JSON value. - * - * You should usually call [Builder.capitalWithdrawal] with a well-typed - * [Float] value instead. This method is primarily for setting the field - * to an undocumented or not yet supported value. - */ - fun capitalWithdrawal(capitalWithdrawal: JsonField) = apply { - this.capitalWithdrawal = capitalWithdrawal - } - - /** Units credited (demat transactions) */ - fun credit(credit: Float) = credit(JsonField.of(credit)) - - /** - * Sets [Builder.credit] to an arbitrary JSON value. - * - * You should usually call [Builder.credit] with a well-typed [Float] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun credit(credit: JsonField) = apply { this.credit = credit } - - /** Units debited (demat transactions) */ - fun debit(debit: Float) = debit(JsonField.of(debit)) - - /** - * Sets [Builder.debit] to an arbitrary JSON value. - * - * You should usually call [Builder.debit] with a well-typed [Float] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun debit(debit: JsonField) = apply { this.debit = debit } - - /** Income distribution amount (CDSL MF transactions) */ - fun incomeDistribution(incomeDistribution: Float) = - incomeDistribution(JsonField.of(incomeDistribution)) - - /** - * Sets [Builder.incomeDistribution] to an arbitrary JSON value. - * - * You should usually call [Builder.incomeDistribution] with a - * well-typed [Float] value instead. This method is primarily for - * setting the field to an undocumented or not yet supported value. - */ - fun incomeDistribution(incomeDistribution: JsonField) = apply { - this.incomeDistribution = incomeDistribution - } - - /** Order/transaction reference number (demat transactions) */ - fun orderNo(orderNo: String) = orderNo(JsonField.of(orderNo)) - - /** - * Sets [Builder.orderNo] to an arbitrary JSON value. - * - * You should usually call [Builder.orderNo] with a well-typed [String] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun orderNo(orderNo: JsonField) = apply { - this.orderNo = orderNo - } - - /** Price per unit (NSDL/CDSL MF transactions) */ - fun price(price: Float) = price(JsonField.of(price)) - - /** - * Sets [Builder.price] to an arbitrary JSON value. - * - * You should usually call [Builder.price] with a well-typed [Float] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun price(price: JsonField) = apply { this.price = price } - - /** Stamp duty charged */ - fun stampDuty(stampDuty: Float) = stampDuty(JsonField.of(stampDuty)) - - /** - * Sets [Builder.stampDuty] to an arbitrary JSON value. - * - * You should usually call [Builder.stampDuty] with a well-typed [Float] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun stampDuty(stampDuty: JsonField) = apply { - this.stampDuty = stampDuty - } - - 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 [AdditionalInfo]. - * - * Further updates to this [Builder] will not mutate the returned - * instance. - */ - fun build(): AdditionalInfo = - AdditionalInfo( - capitalWithdrawal, - credit, - debit, - incomeDistribution, - orderNo, - price, - stampDuty, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): AdditionalInfo = apply { - if (validated) { - return@apply - } - - capitalWithdrawal() - credit() - debit() - incomeDistribution() - orderNo() - price() - stampDuty() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - 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 (capitalWithdrawal.asKnown().isPresent) 1 else 0) + - (if (credit.asKnown().isPresent) 1 else 0) + - (if (debit.asKnown().isPresent) 1 else 0) + - (if (incomeDistribution.asKnown().isPresent) 1 else 0) + - (if (orderNo.asKnown().isPresent) 1 else 0) + - (if (price.asKnown().isPresent) 1 else 0) + - (if (stampDuty.asKnown().isPresent) 1 else 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is AdditionalInfo && - capitalWithdrawal == other.capitalWithdrawal && - credit == other.credit && - debit == other.debit && - incomeDistribution == other.incomeDistribution && - orderNo == other.orderNo && - price == other.price && - stampDuty == other.stampDuty && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash( - capitalWithdrawal, - credit, - debit, - incomeDistribution, - orderNo, - price, - stampDuty, - additionalProperties, - ) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "AdditionalInfo{capitalWithdrawal=$capitalWithdrawal, credit=$credit, debit=$debit, incomeDistribution=$incomeDistribution, orderNo=$orderNo, price=$price, stampDuty=$stampDuty, additionalProperties=$additionalProperties}" - } - - /** - * Transaction type. Possible values are PURCHASE, PURCHASE_SIP, REDEMPTION, - * SWITCH_IN, SWITCH_IN_MERGER, SWITCH_OUT, SWITCH_OUT_MERGER, DIVIDEND_PAYOUT, - * DIVIDEND_REINVEST, SEGREGATION, STAMP_DUTY_TAX, TDS_TAX, STT_TAX, MISC, - * REVERSAL, UNKNOWN. - */ - class Type - @JsonCreator - private constructor(private val value: JsonField) : Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data - * that doesn't match any known member, and you want to know that value. For - * example, if the SDK is on an older version than the API, then the API may - * respond with new members that the SDK is unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue - fun _value(): JsonField = value - - companion object { - - @JvmField val PURCHASE = of("PURCHASE") - - @JvmField val PURCHASE_SIP = of("PURCHASE_SIP") - - @JvmField val REDEMPTION = of("REDEMPTION") - - @JvmField val SWITCH_IN = of("SWITCH_IN") - - @JvmField val SWITCH_IN_MERGER = of("SWITCH_IN_MERGER") - - @JvmField val SWITCH_OUT = of("SWITCH_OUT") - - @JvmField val SWITCH_OUT_MERGER = of("SWITCH_OUT_MERGER") - - @JvmField val DIVIDEND_PAYOUT = of("DIVIDEND_PAYOUT") - - @JvmField val DIVIDEND_REINVEST = of("DIVIDEND_REINVEST") - - @JvmField val SEGREGATION = of("SEGREGATION") - - @JvmField val STAMP_DUTY_TAX = of("STAMP_DUTY_TAX") - - @JvmField val TDS_TAX = of("TDS_TAX") - - @JvmField val STT_TAX = of("STT_TAX") - - @JvmField val MISC = of("MISC") - - @JvmField val REVERSAL = of("REVERSAL") - - @JvmField val UNKNOWN = of("UNKNOWN") - - @JvmStatic fun of(value: String) = Type(JsonField.of(value)) - } - - /** An enum containing [Type]'s known values. */ - enum class Known { - PURCHASE, - PURCHASE_SIP, - REDEMPTION, - SWITCH_IN, - SWITCH_IN_MERGER, - SWITCH_OUT, - SWITCH_OUT_MERGER, - DIVIDEND_PAYOUT, - DIVIDEND_REINVEST, - SEGREGATION, - STAMP_DUTY_TAX, - TDS_TAX, - STT_TAX, - MISC, - REVERSAL, - UNKNOWN, - } - - /** - * An enum containing [Type]'s known values, as well as an [_UNKNOWN] - * member. - * - * An instance of [Type] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For - * example, if the SDK is on an older version than the API, then the API - * may respond with new members that the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - PURCHASE, - PURCHASE_SIP, - REDEMPTION, - SWITCH_IN, - SWITCH_IN_MERGER, - SWITCH_OUT, - SWITCH_OUT_MERGER, - DIVIDEND_PAYOUT, - DIVIDEND_REINVEST, - SEGREGATION, - STAMP_DUTY_TAX, - TDS_TAX, - STT_TAX, - MISC, - REVERSAL, - UNKNOWN, - /** - * An enum member indicating that [Type] was instantiated with an - * unknown value. - */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or - * [Value._UNKNOWN] if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always - * known or if you want to throw for the unknown case. - */ - fun value(): Value = - when (this) { - PURCHASE -> Value.PURCHASE - PURCHASE_SIP -> Value.PURCHASE_SIP - REDEMPTION -> Value.REDEMPTION - SWITCH_IN -> Value.SWITCH_IN - SWITCH_IN_MERGER -> Value.SWITCH_IN_MERGER - SWITCH_OUT -> Value.SWITCH_OUT - SWITCH_OUT_MERGER -> Value.SWITCH_OUT_MERGER - DIVIDEND_PAYOUT -> Value.DIVIDEND_PAYOUT - DIVIDEND_REINVEST -> Value.DIVIDEND_REINVEST - SEGREGATION -> Value.SEGREGATION - STAMP_DUTY_TAX -> Value.STAMP_DUTY_TAX - TDS_TAX -> Value.TDS_TAX - STT_TAX -> Value.STT_TAX - MISC -> Value.MISC - REVERSAL -> Value.REVERSAL - UNKNOWN -> Value.UNKNOWN - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always - * known and don't want to throw for the unknown case. - * - * @throws CasParserInvalidDataException if this class instance's value is a - * not a known member. - */ - fun known(): Known = - when (this) { - PURCHASE -> Known.PURCHASE - PURCHASE_SIP -> Known.PURCHASE_SIP - REDEMPTION -> Known.REDEMPTION - SWITCH_IN -> Known.SWITCH_IN - SWITCH_IN_MERGER -> Known.SWITCH_IN_MERGER - SWITCH_OUT -> Known.SWITCH_OUT - SWITCH_OUT_MERGER -> Known.SWITCH_OUT_MERGER - DIVIDEND_PAYOUT -> Known.DIVIDEND_PAYOUT - DIVIDEND_REINVEST -> Known.DIVIDEND_REINVEST - SEGREGATION -> Known.SEGREGATION - STAMP_DUTY_TAX -> Known.STAMP_DUTY_TAX - TDS_TAX -> Known.TDS_TAX - STT_TAX -> Known.STT_TAX - MISC -> Known.MISC - REVERSAL -> Known.REVERSAL - UNKNOWN -> Known.UNKNOWN - else -> throw CasParserInvalidDataException("Unknown Type: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily - * for debugging and generally doesn't throw. - * - * @throws CasParserInvalidDataException if this class instance's value does - * not have the expected primitive type. - */ - fun asString(): String = - _value().asString().orElseThrow { - CasParserInvalidDataException("Value is not a String") - } - - private var validated: Boolean = false - - fun validate(): Type = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - 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 (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Type && value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Transaction && - additionalInfo == other.additionalInfo && - amount == other.amount && - balance == other.balance && - date == other.date && - description == other.description && - dividendRate == other.dividendRate && - nav == other.nav && - type == other.type && - units == other.units && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash( - additionalInfo, - amount, - balance, - date, - description, - dividendRate, - nav, - type, - units, - additionalProperties, - ) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Transaction{additionalInfo=$additionalInfo, amount=$amount, balance=$balance, date=$date, description=$description, dividendRate=$dividendRate, nav=$nav, type=$type, units=$units, additionalProperties=$additionalProperties}" - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Equity && - additionalInfo == other.additionalInfo && - isin == other.isin && - name == other.name && - transactions == other.transactions && - units == other.units && - value == other.value && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash( - additionalInfo, - isin, - name, - transactions, - units, - value, - additionalProperties, - ) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Equity{additionalInfo=$additionalInfo, isin=$isin, name=$name, transactions=$transactions, units=$units, value=$value, additionalProperties=$additionalProperties}" - } - - class GovernmentSecurity - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val additionalInfo: JsonField, - private val isin: JsonField, - private val name: JsonField, - private val transactions: JsonField>, - private val units: JsonField, - private val value: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("additional_info") - @ExcludeMissing - additionalInfo: JsonField = JsonMissing.of(), - @JsonProperty("isin") - @ExcludeMissing - isin: JsonField = JsonMissing.of(), - @JsonProperty("name") - @ExcludeMissing - name: JsonField = JsonMissing.of(), - @JsonProperty("transactions") - @ExcludeMissing - transactions: JsonField> = JsonMissing.of(), - @JsonProperty("units") - @ExcludeMissing - units: JsonField = JsonMissing.of(), - @JsonProperty("value") - @ExcludeMissing - value: JsonField = JsonMissing.of(), - ) : this(additionalInfo, isin, name, transactions, units, value, mutableMapOf()) - - /** - * Additional information specific to the government security - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun additionalInfo(): Optional = - additionalInfo.getOptional("additional_info") - - /** - * ISIN code of the government security - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun isin(): Optional = isin.getOptional("isin") - - /** - * Name of the government security - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun name(): Optional = name.getOptional("name") - - /** - * List of transactions for this holding (beta) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun transactions(): Optional> = - transactions.getOptional("transactions") - - /** - * Number of units held - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun units(): Optional = units.getOptional("units") - - /** - * Current market value of the holding - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun value(): Optional = value.getOptional("value") - - /** - * Returns the raw JSON value of [additionalInfo]. - * - * Unlike [additionalInfo], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("additional_info") - @ExcludeMissing - fun _additionalInfo(): JsonField = additionalInfo - - /** - * Returns the raw JSON value of [isin]. - * - * Unlike [isin], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("isin") @ExcludeMissing fun _isin(): JsonField = isin - - /** - * Returns the raw JSON value of [name]. - * - * Unlike [name], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name - - /** - * Returns the raw JSON value of [transactions]. - * - * Unlike [transactions], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("transactions") - @ExcludeMissing - fun _transactions(): JsonField> = transactions - - /** - * Returns the raw JSON value of [units]. - * - * Unlike [units], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("units") @ExcludeMissing fun _units(): JsonField = units - - /** - * Returns the raw JSON value of [value]. - * - * Unlike [value], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("value") @ExcludeMissing fun _value(): JsonField = value - - @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 - * [GovernmentSecurity]. - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [GovernmentSecurity]. */ - class Builder internal constructor() { - - private var additionalInfo: JsonField = JsonMissing.of() - private var isin: JsonField = JsonMissing.of() - private var name: JsonField = JsonMissing.of() - private var transactions: JsonField>? = null - private var units: JsonField = JsonMissing.of() - private var value: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(governmentSecurity: GovernmentSecurity) = apply { - additionalInfo = governmentSecurity.additionalInfo - isin = governmentSecurity.isin - name = governmentSecurity.name - transactions = governmentSecurity.transactions.map { it.toMutableList() } - units = governmentSecurity.units - value = governmentSecurity.value - additionalProperties = - governmentSecurity.additionalProperties.toMutableMap() - } - - /** Additional information specific to the government security */ - fun additionalInfo(additionalInfo: AdditionalInfo) = - additionalInfo(JsonField.of(additionalInfo)) - - /** - * Sets [Builder.additionalInfo] to an arbitrary JSON value. - * - * You should usually call [Builder.additionalInfo] with a well-typed - * [AdditionalInfo] value instead. This method is primarily for setting the - * field to an undocumented or not yet supported value. - */ - fun additionalInfo(additionalInfo: JsonField) = apply { - this.additionalInfo = additionalInfo - } - - /** ISIN code of the government security */ - fun isin(isin: String) = isin(JsonField.of(isin)) - - /** - * Sets [Builder.isin] to an arbitrary JSON value. - * - * You should usually call [Builder.isin] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun isin(isin: JsonField) = apply { this.isin = isin } - - /** Name of the government security */ - fun name(name: String) = name(JsonField.of(name)) - - /** - * Sets [Builder.name] to an arbitrary JSON value. - * - * You should usually call [Builder.name] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun name(name: JsonField) = apply { this.name = name } - - /** List of transactions for this holding (beta) */ - fun transactions(transactions: List) = - transactions(JsonField.of(transactions)) - - /** - * Sets [Builder.transactions] to an arbitrary JSON value. - * - * You should usually call [Builder.transactions] with a well-typed - * `List` value instead. This method is primarily for setting the - * field to an undocumented or not yet supported value. - */ - fun transactions(transactions: JsonField>) = apply { - this.transactions = transactions.map { it.toMutableList() } - } - - /** - * Adds a single [Transaction] to [transactions]. - * - * @throws IllegalStateException if the field was previously set to a non-list. - */ - fun addTransaction(transaction: Transaction) = apply { - transactions = - (transactions ?: JsonField.of(mutableListOf())).also { - checkKnown("transactions", it).add(transaction) - } - } - - /** Number of units held */ - fun units(units: Float) = units(JsonField.of(units)) - - /** - * Sets [Builder.units] to an arbitrary JSON value. - * - * You should usually call [Builder.units] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun units(units: JsonField) = apply { this.units = units } - - /** Current market value of the holding */ - fun value(value: Float) = value(JsonField.of(value)) - - /** - * Sets [Builder.value] to an arbitrary JSON value. - * - * You should usually call [Builder.value] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun value(value: JsonField) = apply { this.value = value } - - 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 [GovernmentSecurity]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): GovernmentSecurity = - GovernmentSecurity( - additionalInfo, - isin, - name, - (transactions ?: JsonMissing.of()).map { it.toImmutable() }, - units, - value, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): GovernmentSecurity = apply { - if (validated) { - return@apply - } - - additionalInfo().ifPresent { it.validate() } - isin() - name() - transactions().ifPresent { it.forEach { it.validate() } } - units() - value() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - 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 = - (additionalInfo.asKnown().getOrNull()?.validity() ?: 0) + - (if (isin.asKnown().isPresent) 1 else 0) + - (if (name.asKnown().isPresent) 1 else 0) + - (transactions.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + - (if (units.asKnown().isPresent) 1 else 0) + - (if (value.asKnown().isPresent) 1 else 0) - - /** Additional information specific to the government security */ - class AdditionalInfo - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val closeUnits: JsonField, - private val openUnits: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("close_units") - @ExcludeMissing - closeUnits: JsonField = JsonMissing.of(), - @JsonProperty("open_units") - @ExcludeMissing - openUnits: JsonField = JsonMissing.of(), - ) : this(closeUnits, openUnits, mutableMapOf()) - - /** - * Closing balance units for the statement period (beta) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun closeUnits(): Optional = closeUnits.getOptional("close_units") - - /** - * Opening balance units for the statement period (beta) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun openUnits(): Optional = openUnits.getOptional("open_units") - - /** - * Returns the raw JSON value of [closeUnits]. - * - * Unlike [closeUnits], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("close_units") - @ExcludeMissing - fun _closeUnits(): JsonField = closeUnits - - /** - * Returns the raw JSON value of [openUnits]. - * - * Unlike [openUnits], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("open_units") - @ExcludeMissing - fun _openUnits(): JsonField = openUnits - - @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 - * [AdditionalInfo]. - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [AdditionalInfo]. */ - class Builder internal constructor() { - - private var closeUnits: JsonField = JsonMissing.of() - private var openUnits: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = - mutableMapOf() - - @JvmSynthetic - internal fun from(additionalInfo: AdditionalInfo) = apply { - closeUnits = additionalInfo.closeUnits - openUnits = additionalInfo.openUnits - additionalProperties = - additionalInfo.additionalProperties.toMutableMap() - } - - /** Closing balance units for the statement period (beta) */ - fun closeUnits(closeUnits: Float?) = - closeUnits(JsonField.ofNullable(closeUnits)) - - /** - * Alias for [Builder.closeUnits]. - * - * This unboxed primitive overload exists for backwards compatibility. - */ - fun closeUnits(closeUnits: Float) = closeUnits(closeUnits as Float?) - - /** - * Alias for calling [Builder.closeUnits] with `closeUnits.orElse(null)`. - */ - fun closeUnits(closeUnits: Optional) = - closeUnits(closeUnits.getOrNull()) - - /** - * Sets [Builder.closeUnits] to an arbitrary JSON value. - * - * You should usually call [Builder.closeUnits] with a well-typed [Float] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun closeUnits(closeUnits: JsonField) = apply { - this.closeUnits = closeUnits - } - - /** Opening balance units for the statement period (beta) */ - fun openUnits(openUnits: Float?) = - openUnits(JsonField.ofNullable(openUnits)) - - /** - * Alias for [Builder.openUnits]. - * - * This unboxed primitive overload exists for backwards compatibility. - */ - fun openUnits(openUnits: Float) = openUnits(openUnits as Float?) - - /** Alias for calling [Builder.openUnits] with `openUnits.orElse(null)`. */ - fun openUnits(openUnits: Optional) = openUnits(openUnits.getOrNull()) - - /** - * Sets [Builder.openUnits] to an arbitrary JSON value. - * - * You should usually call [Builder.openUnits] with a well-typed [Float] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun openUnits(openUnits: JsonField) = apply { - this.openUnits = openUnits - } - - 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 [AdditionalInfo]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): AdditionalInfo = - AdditionalInfo( - closeUnits, - openUnits, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): AdditionalInfo = apply { - if (validated) { - return@apply - } - - closeUnits() - openUnits() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - 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 (closeUnits.asKnown().isPresent) 1 else 0) + - (if (openUnits.asKnown().isPresent) 1 else 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is AdditionalInfo && - closeUnits == other.closeUnits && - openUnits == other.openUnits && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash(closeUnits, openUnits, additionalProperties) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "AdditionalInfo{closeUnits=$closeUnits, openUnits=$openUnits, additionalProperties=$additionalProperties}" - } - - /** - * Unified transaction schema for all holding types (MF folios, equities, bonds, - * etc.) - */ - class Transaction - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val additionalInfo: JsonField, - private val amount: JsonField, - private val balance: JsonField, - private val date: JsonField, - private val description: JsonField, - private val dividendRate: JsonField, - private val nav: JsonField, - private val type: JsonField, - private val units: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("additional_info") - @ExcludeMissing - additionalInfo: JsonField = JsonMissing.of(), - @JsonProperty("amount") - @ExcludeMissing - amount: JsonField = JsonMissing.of(), - @JsonProperty("balance") - @ExcludeMissing - balance: JsonField = JsonMissing.of(), - @JsonProperty("date") - @ExcludeMissing - date: JsonField = JsonMissing.of(), - @JsonProperty("description") - @ExcludeMissing - description: JsonField = JsonMissing.of(), - @JsonProperty("dividend_rate") - @ExcludeMissing - dividendRate: JsonField = JsonMissing.of(), - @JsonProperty("nav") - @ExcludeMissing - nav: JsonField = JsonMissing.of(), - @JsonProperty("type") - @ExcludeMissing - type: JsonField = JsonMissing.of(), - @JsonProperty("units") - @ExcludeMissing - units: JsonField = JsonMissing.of(), - ) : this( - additionalInfo, - amount, - balance, - date, - description, - dividendRate, - nav, - type, - units, - mutableMapOf(), - ) - - /** - * Additional transaction-specific fields that vary by source - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun additionalInfo(): Optional = - additionalInfo.getOptional("additional_info") - - /** - * Transaction amount in currency (computed from units × price/NAV) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun amount(): Optional = amount.getOptional("amount") - - /** - * Balance units after transaction - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun balance(): Optional = balance.getOptional("balance") - - /** - * Transaction date (YYYY-MM-DD) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun date(): Optional = date.getOptional("date") - - /** - * Transaction description/particulars - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun description(): Optional = description.getOptional("description") - - /** - * Dividend rate (for DIVIDEND_PAYOUT transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun dividendRate(): Optional = dividendRate.getOptional("dividend_rate") - - /** - * NAV/price per unit on transaction date - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun nav(): Optional = nav.getOptional("nav") - - /** - * Transaction type. Possible values are PURCHASE, PURCHASE_SIP, REDEMPTION, - * SWITCH_IN, SWITCH_IN_MERGER, SWITCH_OUT, SWITCH_OUT_MERGER, DIVIDEND_PAYOUT, - * DIVIDEND_REINVEST, SEGREGATION, STAMP_DUTY_TAX, TDS_TAX, STT_TAX, MISC, - * REVERSAL, UNKNOWN. - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun type(): Optional = type.getOptional("type") - - /** - * Number of units involved in transaction - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun units(): Optional = units.getOptional("units") - - /** - * Returns the raw JSON value of [additionalInfo]. - * - * Unlike [additionalInfo], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("additional_info") - @ExcludeMissing - fun _additionalInfo(): JsonField = additionalInfo - - /** - * Returns the raw JSON value of [amount]. - * - * Unlike [amount], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("amount") @ExcludeMissing fun _amount(): JsonField = amount - - /** - * Returns the raw JSON value of [balance]. - * - * Unlike [balance], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("balance") - @ExcludeMissing - fun _balance(): JsonField = balance - - /** - * Returns the raw JSON value of [date]. - * - * Unlike [date], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("date") @ExcludeMissing fun _date(): JsonField = date - - /** - * Returns the raw JSON value of [description]. - * - * Unlike [description], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("description") - @ExcludeMissing - fun _description(): JsonField = description - - /** - * Returns the raw JSON value of [dividendRate]. - * - * Unlike [dividendRate], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("dividend_rate") - @ExcludeMissing - fun _dividendRate(): JsonField = dividendRate - - /** - * Returns the raw JSON value of [nav]. - * - * Unlike [nav], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("nav") @ExcludeMissing fun _nav(): JsonField = nav - - /** - * Returns the raw JSON value of [type]. - * - * Unlike [type], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type - - /** - * Returns the raw JSON value of [units]. - * - * Unlike [units], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("units") @ExcludeMissing fun _units(): JsonField = units - - @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 [Transaction]. - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Transaction]. */ - class Builder internal constructor() { - - private var additionalInfo: JsonField = JsonMissing.of() - private var amount: JsonField = JsonMissing.of() - private var balance: JsonField = JsonMissing.of() - private var date: JsonField = JsonMissing.of() - private var description: JsonField = JsonMissing.of() - private var dividendRate: JsonField = JsonMissing.of() - private var nav: JsonField = JsonMissing.of() - private var type: JsonField = JsonMissing.of() - private var units: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = - mutableMapOf() - - @JvmSynthetic - internal fun from(transaction: Transaction) = apply { - additionalInfo = transaction.additionalInfo - amount = transaction.amount - balance = transaction.balance - date = transaction.date - description = transaction.description - dividendRate = transaction.dividendRate - nav = transaction.nav - type = transaction.type - units = transaction.units - additionalProperties = transaction.additionalProperties.toMutableMap() - } - - /** Additional transaction-specific fields that vary by source */ - fun additionalInfo(additionalInfo: AdditionalInfo) = - additionalInfo(JsonField.of(additionalInfo)) - - /** - * Sets [Builder.additionalInfo] to an arbitrary JSON value. - * - * You should usually call [Builder.additionalInfo] with a well-typed - * [AdditionalInfo] value instead. This method is primarily for setting the - * field to an undocumented or not yet supported value. - */ - fun additionalInfo(additionalInfo: JsonField) = apply { - this.additionalInfo = additionalInfo - } - - /** Transaction amount in currency (computed from units × price/NAV) */ - fun amount(amount: Float?) = amount(JsonField.ofNullable(amount)) - - /** - * Alias for [Builder.amount]. - * - * This unboxed primitive overload exists for backwards compatibility. - */ - fun amount(amount: Float) = amount(amount as Float?) - - /** Alias for calling [Builder.amount] with `amount.orElse(null)`. */ - fun amount(amount: Optional) = amount(amount.getOrNull()) - - /** - * Sets [Builder.amount] to an arbitrary JSON value. - * - * You should usually call [Builder.amount] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun amount(amount: JsonField) = apply { this.amount = amount } - - /** Balance units after transaction */ - fun balance(balance: Float) = balance(JsonField.of(balance)) - - /** - * Sets [Builder.balance] to an arbitrary JSON value. - * - * You should usually call [Builder.balance] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun balance(balance: JsonField) = apply { this.balance = balance } - - /** Transaction date (YYYY-MM-DD) */ - fun date(date: LocalDate) = date(JsonField.of(date)) - - /** - * Sets [Builder.date] to an arbitrary JSON value. - * - * You should usually call [Builder.date] with a well-typed [LocalDate] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun date(date: JsonField) = apply { this.date = date } - - /** Transaction description/particulars */ - fun description(description: String) = - description(JsonField.of(description)) - - /** - * Sets [Builder.description] to an arbitrary JSON value. - * - * You should usually call [Builder.description] with a well-typed [String] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun description(description: JsonField) = apply { - this.description = description - } - - /** Dividend rate (for DIVIDEND_PAYOUT transactions) */ - fun dividendRate(dividendRate: Float?) = - dividendRate(JsonField.ofNullable(dividendRate)) - - /** - * Alias for [Builder.dividendRate]. - * - * This unboxed primitive overload exists for backwards compatibility. - */ - fun dividendRate(dividendRate: Float) = dividendRate(dividendRate as Float?) - - /** - * Alias for calling [Builder.dividendRate] with - * `dividendRate.orElse(null)`. - */ - fun dividendRate(dividendRate: Optional) = - dividendRate(dividendRate.getOrNull()) - - /** - * Sets [Builder.dividendRate] to an arbitrary JSON value. - * - * You should usually call [Builder.dividendRate] with a well-typed [Float] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun dividendRate(dividendRate: JsonField) = apply { - this.dividendRate = dividendRate - } - - /** NAV/price per unit on transaction date */ - fun nav(nav: Float?) = nav(JsonField.ofNullable(nav)) - - /** - * Alias for [Builder.nav]. - * - * This unboxed primitive overload exists for backwards compatibility. - */ - fun nav(nav: Float) = nav(nav as Float?) - - /** Alias for calling [Builder.nav] with `nav.orElse(null)`. */ - fun nav(nav: Optional) = nav(nav.getOrNull()) - - /** - * Sets [Builder.nav] to an arbitrary JSON value. - * - * You should usually call [Builder.nav] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun nav(nav: JsonField) = apply { this.nav = nav } - - /** - * Transaction type. Possible values are PURCHASE, PURCHASE_SIP, REDEMPTION, - * SWITCH_IN, SWITCH_IN_MERGER, SWITCH_OUT, SWITCH_OUT_MERGER, - * DIVIDEND_PAYOUT, DIVIDEND_REINVEST, SEGREGATION, STAMP_DUTY_TAX, TDS_TAX, - * STT_TAX, MISC, REVERSAL, UNKNOWN. - */ - fun type(type: Type) = type(JsonField.of(type)) - - /** - * Sets [Builder.type] to an arbitrary JSON value. - * - * You should usually call [Builder.type] with a well-typed [Type] value - * instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun type(type: JsonField) = apply { this.type = type } - - /** Number of units involved in transaction */ - fun units(units: Float) = units(JsonField.of(units)) - - /** - * Sets [Builder.units] to an arbitrary JSON value. - * - * You should usually call [Builder.units] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun units(units: JsonField) = apply { this.units = units } - - 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 [Transaction]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): Transaction = - Transaction( - additionalInfo, - amount, - balance, - date, - description, - dividendRate, - nav, - type, - units, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): Transaction = apply { - if (validated) { - return@apply - } - - additionalInfo().ifPresent { it.validate() } - amount() - balance() - date() - description() - dividendRate() - nav() - type().ifPresent { it.validate() } - units() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - 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 = - (additionalInfo.asKnown().getOrNull()?.validity() ?: 0) + - (if (amount.asKnown().isPresent) 1 else 0) + - (if (balance.asKnown().isPresent) 1 else 0) + - (if (date.asKnown().isPresent) 1 else 0) + - (if (description.asKnown().isPresent) 1 else 0) + - (if (dividendRate.asKnown().isPresent) 1 else 0) + - (if (nav.asKnown().isPresent) 1 else 0) + - (type.asKnown().getOrNull()?.validity() ?: 0) + - (if (units.asKnown().isPresent) 1 else 0) - - /** Additional transaction-specific fields that vary by source */ - class AdditionalInfo - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val capitalWithdrawal: JsonField, - private val credit: JsonField, - private val debit: JsonField, - private val incomeDistribution: JsonField, - private val orderNo: JsonField, - private val price: JsonField, - private val stampDuty: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("capital_withdrawal") - @ExcludeMissing - capitalWithdrawal: JsonField = JsonMissing.of(), - @JsonProperty("credit") - @ExcludeMissing - credit: JsonField = JsonMissing.of(), - @JsonProperty("debit") - @ExcludeMissing - debit: JsonField = JsonMissing.of(), - @JsonProperty("income_distribution") - @ExcludeMissing - incomeDistribution: JsonField = JsonMissing.of(), - @JsonProperty("order_no") - @ExcludeMissing - orderNo: JsonField = JsonMissing.of(), - @JsonProperty("price") - @ExcludeMissing - price: JsonField = JsonMissing.of(), - @JsonProperty("stamp_duty") - @ExcludeMissing - stampDuty: JsonField = JsonMissing.of(), - ) : this( - capitalWithdrawal, - credit, - debit, - incomeDistribution, - orderNo, - price, - stampDuty, - mutableMapOf(), - ) - - /** - * Capital withdrawal amount (CDSL MF transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun capitalWithdrawal(): Optional = - capitalWithdrawal.getOptional("capital_withdrawal") - - /** - * Units credited (demat transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun credit(): Optional = credit.getOptional("credit") - - /** - * Units debited (demat transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun debit(): Optional = debit.getOptional("debit") - - /** - * Income distribution amount (CDSL MF transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun incomeDistribution(): Optional = - incomeDistribution.getOptional("income_distribution") - - /** - * Order/transaction reference number (demat transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun orderNo(): Optional = orderNo.getOptional("order_no") - - /** - * Price per unit (NSDL/CDSL MF transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun price(): Optional = price.getOptional("price") - - /** - * Stamp duty charged - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun stampDuty(): Optional = stampDuty.getOptional("stamp_duty") - - /** - * Returns the raw JSON value of [capitalWithdrawal]. - * - * Unlike [capitalWithdrawal], this method doesn't throw if the JSON field - * has an unexpected type. - */ - @JsonProperty("capital_withdrawal") - @ExcludeMissing - fun _capitalWithdrawal(): JsonField = capitalWithdrawal - - /** - * Returns the raw JSON value of [credit]. - * - * Unlike [credit], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("credit") - @ExcludeMissing - fun _credit(): JsonField = credit - - /** - * Returns the raw JSON value of [debit]. - * - * Unlike [debit], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("debit") - @ExcludeMissing - fun _debit(): JsonField = debit - - /** - * Returns the raw JSON value of [incomeDistribution]. - * - * Unlike [incomeDistribution], this method doesn't throw if the JSON field - * has an unexpected type. - */ - @JsonProperty("income_distribution") - @ExcludeMissing - fun _incomeDistribution(): JsonField = incomeDistribution - - /** - * Returns the raw JSON value of [orderNo]. - * - * Unlike [orderNo], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("order_no") - @ExcludeMissing - fun _orderNo(): JsonField = orderNo - - /** - * Returns the raw JSON value of [price]. - * - * Unlike [price], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("price") - @ExcludeMissing - fun _price(): JsonField = price - - /** - * Returns the raw JSON value of [stampDuty]. - * - * Unlike [stampDuty], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("stamp_duty") - @ExcludeMissing - fun _stampDuty(): JsonField = stampDuty - - @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 - * [AdditionalInfo]. - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [AdditionalInfo]. */ - class Builder internal constructor() { - - private var capitalWithdrawal: JsonField = JsonMissing.of() - private var credit: JsonField = JsonMissing.of() - private var debit: JsonField = JsonMissing.of() - private var incomeDistribution: JsonField = JsonMissing.of() - private var orderNo: JsonField = JsonMissing.of() - private var price: JsonField = JsonMissing.of() - private var stampDuty: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = - mutableMapOf() - - @JvmSynthetic - internal fun from(additionalInfo: AdditionalInfo) = apply { - capitalWithdrawal = additionalInfo.capitalWithdrawal - credit = additionalInfo.credit - debit = additionalInfo.debit - incomeDistribution = additionalInfo.incomeDistribution - orderNo = additionalInfo.orderNo - price = additionalInfo.price - stampDuty = additionalInfo.stampDuty - additionalProperties = - additionalInfo.additionalProperties.toMutableMap() - } - - /** Capital withdrawal amount (CDSL MF transactions) */ - fun capitalWithdrawal(capitalWithdrawal: Float) = - capitalWithdrawal(JsonField.of(capitalWithdrawal)) - - /** - * Sets [Builder.capitalWithdrawal] to an arbitrary JSON value. - * - * You should usually call [Builder.capitalWithdrawal] with a well-typed - * [Float] value instead. This method is primarily for setting the field - * to an undocumented or not yet supported value. - */ - fun capitalWithdrawal(capitalWithdrawal: JsonField) = apply { - this.capitalWithdrawal = capitalWithdrawal - } - - /** Units credited (demat transactions) */ - fun credit(credit: Float) = credit(JsonField.of(credit)) - - /** - * Sets [Builder.credit] to an arbitrary JSON value. - * - * You should usually call [Builder.credit] with a well-typed [Float] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun credit(credit: JsonField) = apply { this.credit = credit } - - /** Units debited (demat transactions) */ - fun debit(debit: Float) = debit(JsonField.of(debit)) - - /** - * Sets [Builder.debit] to an arbitrary JSON value. - * - * You should usually call [Builder.debit] with a well-typed [Float] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun debit(debit: JsonField) = apply { this.debit = debit } - - /** Income distribution amount (CDSL MF transactions) */ - fun incomeDistribution(incomeDistribution: Float) = - incomeDistribution(JsonField.of(incomeDistribution)) - - /** - * Sets [Builder.incomeDistribution] to an arbitrary JSON value. - * - * You should usually call [Builder.incomeDistribution] with a - * well-typed [Float] value instead. This method is primarily for - * setting the field to an undocumented or not yet supported value. - */ - fun incomeDistribution(incomeDistribution: JsonField) = apply { - this.incomeDistribution = incomeDistribution - } - - /** Order/transaction reference number (demat transactions) */ - fun orderNo(orderNo: String) = orderNo(JsonField.of(orderNo)) - - /** - * Sets [Builder.orderNo] to an arbitrary JSON value. - * - * You should usually call [Builder.orderNo] with a well-typed [String] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun orderNo(orderNo: JsonField) = apply { - this.orderNo = orderNo - } - - /** Price per unit (NSDL/CDSL MF transactions) */ - fun price(price: Float) = price(JsonField.of(price)) - - /** - * Sets [Builder.price] to an arbitrary JSON value. - * - * You should usually call [Builder.price] with a well-typed [Float] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun price(price: JsonField) = apply { this.price = price } - - /** Stamp duty charged */ - fun stampDuty(stampDuty: Float) = stampDuty(JsonField.of(stampDuty)) - - /** - * Sets [Builder.stampDuty] to an arbitrary JSON value. - * - * You should usually call [Builder.stampDuty] with a well-typed [Float] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun stampDuty(stampDuty: JsonField) = apply { - this.stampDuty = stampDuty - } - - 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 [AdditionalInfo]. - * - * Further updates to this [Builder] will not mutate the returned - * instance. - */ - fun build(): AdditionalInfo = - AdditionalInfo( - capitalWithdrawal, - credit, - debit, - incomeDistribution, - orderNo, - price, - stampDuty, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): AdditionalInfo = apply { - if (validated) { - return@apply - } - - capitalWithdrawal() - credit() - debit() - incomeDistribution() - orderNo() - price() - stampDuty() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - 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 (capitalWithdrawal.asKnown().isPresent) 1 else 0) + - (if (credit.asKnown().isPresent) 1 else 0) + - (if (debit.asKnown().isPresent) 1 else 0) + - (if (incomeDistribution.asKnown().isPresent) 1 else 0) + - (if (orderNo.asKnown().isPresent) 1 else 0) + - (if (price.asKnown().isPresent) 1 else 0) + - (if (stampDuty.asKnown().isPresent) 1 else 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is AdditionalInfo && - capitalWithdrawal == other.capitalWithdrawal && - credit == other.credit && - debit == other.debit && - incomeDistribution == other.incomeDistribution && - orderNo == other.orderNo && - price == other.price && - stampDuty == other.stampDuty && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash( - capitalWithdrawal, - credit, - debit, - incomeDistribution, - orderNo, - price, - stampDuty, - additionalProperties, - ) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "AdditionalInfo{capitalWithdrawal=$capitalWithdrawal, credit=$credit, debit=$debit, incomeDistribution=$incomeDistribution, orderNo=$orderNo, price=$price, stampDuty=$stampDuty, additionalProperties=$additionalProperties}" - } - - /** - * Transaction type. Possible values are PURCHASE, PURCHASE_SIP, REDEMPTION, - * SWITCH_IN, SWITCH_IN_MERGER, SWITCH_OUT, SWITCH_OUT_MERGER, DIVIDEND_PAYOUT, - * DIVIDEND_REINVEST, SEGREGATION, STAMP_DUTY_TAX, TDS_TAX, STT_TAX, MISC, - * REVERSAL, UNKNOWN. - */ - class Type - @JsonCreator - private constructor(private val value: JsonField) : Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data - * that doesn't match any known member, and you want to know that value. For - * example, if the SDK is on an older version than the API, then the API may - * respond with new members that the SDK is unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue - fun _value(): JsonField = value - - companion object { - - @JvmField val PURCHASE = of("PURCHASE") - - @JvmField val PURCHASE_SIP = of("PURCHASE_SIP") - - @JvmField val REDEMPTION = of("REDEMPTION") - - @JvmField val SWITCH_IN = of("SWITCH_IN") - - @JvmField val SWITCH_IN_MERGER = of("SWITCH_IN_MERGER") - - @JvmField val SWITCH_OUT = of("SWITCH_OUT") - - @JvmField val SWITCH_OUT_MERGER = of("SWITCH_OUT_MERGER") - - @JvmField val DIVIDEND_PAYOUT = of("DIVIDEND_PAYOUT") - - @JvmField val DIVIDEND_REINVEST = of("DIVIDEND_REINVEST") - - @JvmField val SEGREGATION = of("SEGREGATION") - - @JvmField val STAMP_DUTY_TAX = of("STAMP_DUTY_TAX") - - @JvmField val TDS_TAX = of("TDS_TAX") - - @JvmField val STT_TAX = of("STT_TAX") - - @JvmField val MISC = of("MISC") - - @JvmField val REVERSAL = of("REVERSAL") - - @JvmField val UNKNOWN = of("UNKNOWN") - - @JvmStatic fun of(value: String) = Type(JsonField.of(value)) - } - - /** An enum containing [Type]'s known values. */ - enum class Known { - PURCHASE, - PURCHASE_SIP, - REDEMPTION, - SWITCH_IN, - SWITCH_IN_MERGER, - SWITCH_OUT, - SWITCH_OUT_MERGER, - DIVIDEND_PAYOUT, - DIVIDEND_REINVEST, - SEGREGATION, - STAMP_DUTY_TAX, - TDS_TAX, - STT_TAX, - MISC, - REVERSAL, - UNKNOWN, - } - - /** - * An enum containing [Type]'s known values, as well as an [_UNKNOWN] - * member. - * - * An instance of [Type] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For - * example, if the SDK is on an older version than the API, then the API - * may respond with new members that the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - PURCHASE, - PURCHASE_SIP, - REDEMPTION, - SWITCH_IN, - SWITCH_IN_MERGER, - SWITCH_OUT, - SWITCH_OUT_MERGER, - DIVIDEND_PAYOUT, - DIVIDEND_REINVEST, - SEGREGATION, - STAMP_DUTY_TAX, - TDS_TAX, - STT_TAX, - MISC, - REVERSAL, - UNKNOWN, - /** - * An enum member indicating that [Type] was instantiated with an - * unknown value. - */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or - * [Value._UNKNOWN] if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always - * known or if you want to throw for the unknown case. - */ - fun value(): Value = - when (this) { - PURCHASE -> Value.PURCHASE - PURCHASE_SIP -> Value.PURCHASE_SIP - REDEMPTION -> Value.REDEMPTION - SWITCH_IN -> Value.SWITCH_IN - SWITCH_IN_MERGER -> Value.SWITCH_IN_MERGER - SWITCH_OUT -> Value.SWITCH_OUT - SWITCH_OUT_MERGER -> Value.SWITCH_OUT_MERGER - DIVIDEND_PAYOUT -> Value.DIVIDEND_PAYOUT - DIVIDEND_REINVEST -> Value.DIVIDEND_REINVEST - SEGREGATION -> Value.SEGREGATION - STAMP_DUTY_TAX -> Value.STAMP_DUTY_TAX - TDS_TAX -> Value.TDS_TAX - STT_TAX -> Value.STT_TAX - MISC -> Value.MISC - REVERSAL -> Value.REVERSAL - UNKNOWN -> Value.UNKNOWN - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always - * known and don't want to throw for the unknown case. - * - * @throws CasParserInvalidDataException if this class instance's value is a - * not a known member. - */ - fun known(): Known = - when (this) { - PURCHASE -> Known.PURCHASE - PURCHASE_SIP -> Known.PURCHASE_SIP - REDEMPTION -> Known.REDEMPTION - SWITCH_IN -> Known.SWITCH_IN - SWITCH_IN_MERGER -> Known.SWITCH_IN_MERGER - SWITCH_OUT -> Known.SWITCH_OUT - SWITCH_OUT_MERGER -> Known.SWITCH_OUT_MERGER - DIVIDEND_PAYOUT -> Known.DIVIDEND_PAYOUT - DIVIDEND_REINVEST -> Known.DIVIDEND_REINVEST - SEGREGATION -> Known.SEGREGATION - STAMP_DUTY_TAX -> Known.STAMP_DUTY_TAX - TDS_TAX -> Known.TDS_TAX - STT_TAX -> Known.STT_TAX - MISC -> Known.MISC - REVERSAL -> Known.REVERSAL - UNKNOWN -> Known.UNKNOWN - else -> throw CasParserInvalidDataException("Unknown Type: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily - * for debugging and generally doesn't throw. - * - * @throws CasParserInvalidDataException if this class instance's value does - * not have the expected primitive type. - */ - fun asString(): String = - _value().asString().orElseThrow { - CasParserInvalidDataException("Value is not a String") - } - - private var validated: Boolean = false - - fun validate(): Type = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - 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 (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Type && value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Transaction && - additionalInfo == other.additionalInfo && - amount == other.amount && - balance == other.balance && - date == other.date && - description == other.description && - dividendRate == other.dividendRate && - nav == other.nav && - type == other.type && - units == other.units && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash( - additionalInfo, - amount, - balance, - date, - description, - dividendRate, - nav, - type, - units, - additionalProperties, - ) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Transaction{additionalInfo=$additionalInfo, amount=$amount, balance=$balance, date=$date, description=$description, dividendRate=$dividendRate, nav=$nav, type=$type, units=$units, additionalProperties=$additionalProperties}" - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is GovernmentSecurity && - additionalInfo == other.additionalInfo && - isin == other.isin && - name == other.name && - transactions == other.transactions && - units == other.units && - value == other.value && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash( - additionalInfo, - isin, - name, - transactions, - units, - value, - additionalProperties, - ) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "GovernmentSecurity{additionalInfo=$additionalInfo, isin=$isin, name=$name, transactions=$transactions, units=$units, value=$value, additionalProperties=$additionalProperties}" - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Holdings && - aifs == other.aifs && - corporateBonds == other.corporateBonds && - dematMutualFunds == other.dematMutualFunds && - equities == other.equities && - governmentSecurities == other.governmentSecurities && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash( - aifs, - corporateBonds, - dematMutualFunds, - equities, - governmentSecurities, - additionalProperties, - ) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Holdings{aifs=$aifs, corporateBonds=$corporateBonds, dematMutualFunds=$dematMutualFunds, equities=$equities, governmentSecurities=$governmentSecurities, additionalProperties=$additionalProperties}" - } - - class LinkedHolder - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val name: JsonField, - private val pan: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), - @JsonProperty("pan") @ExcludeMissing pan: JsonField = JsonMissing.of(), - ) : this(name, pan, mutableMapOf()) - - /** - * Name of the account holder - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun name(): Optional = name.getOptional("name") - - /** - * PAN of the account holder - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun pan(): Optional = pan.getOptional("pan") - - /** - * Returns the raw JSON value of [name]. - * - * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name - - /** - * Returns the raw JSON value of [pan]. - * - * Unlike [pan], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("pan") @ExcludeMissing fun _pan(): JsonField = pan - - @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 [LinkedHolder]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [LinkedHolder]. */ - class Builder internal constructor() { - - private var name: JsonField = JsonMissing.of() - private var pan: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(linkedHolder: LinkedHolder) = apply { - name = linkedHolder.name - pan = linkedHolder.pan - additionalProperties = linkedHolder.additionalProperties.toMutableMap() - } - - /** Name of the account holder */ - fun name(name: String) = name(JsonField.of(name)) - - /** - * Sets [Builder.name] to an arbitrary JSON value. - * - * You should usually call [Builder.name] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun name(name: JsonField) = apply { this.name = name } - - /** PAN of the account holder */ - fun pan(pan: String) = pan(JsonField.of(pan)) - - /** - * Sets [Builder.pan] to an arbitrary JSON value. - * - * You should usually call [Builder.pan] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun pan(pan: JsonField) = apply { this.pan = pan } - - 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 [LinkedHolder]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): LinkedHolder = - LinkedHolder(name, pan, additionalProperties.toMutableMap()) - } - - private var validated: Boolean = false - - fun validate(): LinkedHolder = apply { - if (validated) { - return@apply - } - - name() - pan() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - 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 (name.asKnown().isPresent) 1 else 0) + (if (pan.asKnown().isPresent) 1 else 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is LinkedHolder && - name == other.name && - pan == other.pan && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { Objects.hash(name, pan, additionalProperties) } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "LinkedHolder{name=$name, pan=$pan, additionalProperties=$additionalProperties}" - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is DematAccount && - additionalInfo == other.additionalInfo && - boId == other.boId && - clientId == other.clientId && - dematType == other.dematType && - dpId == other.dpId && - dpName == other.dpName && - holdings == other.holdings && - linkedHolders == other.linkedHolders && - value == other.value && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash( - additionalInfo, - boId, - clientId, - dematType, - dpId, - dpName, - holdings, - linkedHolders, - value, - additionalProperties, - ) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "DematAccount{additionalInfo=$additionalInfo, boId=$boId, clientId=$clientId, dematType=$dematType, dpId=$dpId, dpName=$dpName, holdings=$holdings, linkedHolders=$linkedHolders, value=$value, additionalProperties=$additionalProperties}" - } - - class Insurance - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val lifeInsurancePolicies: JsonField>, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("life_insurance_policies") - @ExcludeMissing - lifeInsurancePolicies: JsonField> = JsonMissing.of() - ) : this(lifeInsurancePolicies, mutableMapOf()) - - /** - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun lifeInsurancePolicies(): Optional> = - lifeInsurancePolicies.getOptional("life_insurance_policies") - - /** - * Returns the raw JSON value of [lifeInsurancePolicies]. - * - * Unlike [lifeInsurancePolicies], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("life_insurance_policies") - @ExcludeMissing - fun _lifeInsurancePolicies(): JsonField> = lifeInsurancePolicies - - @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 [Insurance]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Insurance]. */ - class Builder internal constructor() { - - private var lifeInsurancePolicies: JsonField>? = null - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(insurance: Insurance) = apply { - lifeInsurancePolicies = insurance.lifeInsurancePolicies.map { it.toMutableList() } - additionalProperties = insurance.additionalProperties.toMutableMap() - } - - fun lifeInsurancePolicies(lifeInsurancePolicies: List) = - lifeInsurancePolicies(JsonField.of(lifeInsurancePolicies)) - - /** - * Sets [Builder.lifeInsurancePolicies] to an arbitrary JSON value. - * - * You should usually call [Builder.lifeInsurancePolicies] with a well-typed - * `List` value instead. This method is primarily for setting the - * field to an undocumented or not yet supported value. - */ - fun lifeInsurancePolicies(lifeInsurancePolicies: JsonField>) = - apply { - this.lifeInsurancePolicies = lifeInsurancePolicies.map { it.toMutableList() } - } - - /** - * Adds a single [LifeInsurancePolicy] to [lifeInsurancePolicies]. - * - * @throws IllegalStateException if the field was previously set to a non-list. - */ - fun addLifeInsurancePolicy(lifeInsurancePolicy: LifeInsurancePolicy) = apply { - lifeInsurancePolicies = - (lifeInsurancePolicies ?: JsonField.of(mutableListOf())).also { - checkKnown("lifeInsurancePolicies", it).add(lifeInsurancePolicy) - } - } - - 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 [Insurance]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): Insurance = - Insurance( - (lifeInsurancePolicies ?: JsonMissing.of()).map { it.toImmutable() }, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): Insurance = apply { - if (validated) { - return@apply - } - - lifeInsurancePolicies().ifPresent { it.forEach { it.validate() } } - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - 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 = - (lifeInsurancePolicies.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) - - class LifeInsurancePolicy - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val additionalInfo: JsonValue, - private val lifeAssured: JsonField, - private val policyName: JsonField, - private val policyNumber: JsonField, - private val premiumAmount: JsonField, - private val premiumFrequency: JsonField, - private val provider: JsonField, - private val status: JsonField, - private val sumAssured: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("additional_info") - @ExcludeMissing - additionalInfo: JsonValue = JsonMissing.of(), - @JsonProperty("life_assured") - @ExcludeMissing - lifeAssured: JsonField = JsonMissing.of(), - @JsonProperty("policy_name") - @ExcludeMissing - policyName: JsonField = JsonMissing.of(), - @JsonProperty("policy_number") - @ExcludeMissing - policyNumber: JsonField = JsonMissing.of(), - @JsonProperty("premium_amount") - @ExcludeMissing - premiumAmount: JsonField = JsonMissing.of(), - @JsonProperty("premium_frequency") - @ExcludeMissing - premiumFrequency: JsonField = JsonMissing.of(), - @JsonProperty("provider") - @ExcludeMissing - provider: JsonField = JsonMissing.of(), - @JsonProperty("status") - @ExcludeMissing - status: JsonField = JsonMissing.of(), - @JsonProperty("sum_assured") - @ExcludeMissing - sumAssured: JsonField = JsonMissing.of(), - ) : this( - additionalInfo, - lifeAssured, - policyName, - policyNumber, - premiumAmount, - premiumFrequency, - provider, - status, - sumAssured, - mutableMapOf(), - ) - - /** - * Additional information specific to the policy - * - * This arbitrary value can be deserialized into a custom type using the `convert` - * method: - * ```java - * MyClass myObject = lifeInsurancePolicy.additionalInfo().convert(MyClass.class); - * ``` - */ - @JsonProperty("additional_info") - @ExcludeMissing - fun _additionalInfo(): JsonValue = additionalInfo - - /** - * Name of the life assured - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun lifeAssured(): Optional = lifeAssured.getOptional("life_assured") - - /** - * Name of the insurance policy - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun policyName(): Optional = policyName.getOptional("policy_name") - - /** - * Insurance policy number - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun policyNumber(): Optional = policyNumber.getOptional("policy_number") - - /** - * Premium amount - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun premiumAmount(): Optional = premiumAmount.getOptional("premium_amount") - - /** - * Frequency of premium payment (e.g., Annual, Monthly) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun premiumFrequency(): Optional = - premiumFrequency.getOptional("premium_frequency") - - /** - * Insurance company name - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun provider(): Optional = provider.getOptional("provider") - - /** - * Status of the policy (e.g., Active, Lapsed) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun status(): Optional = status.getOptional("status") - - /** - * Sum assured amount - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun sumAssured(): Optional = sumAssured.getOptional("sum_assured") - - /** - * Returns the raw JSON value of [lifeAssured]. - * - * Unlike [lifeAssured], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("life_assured") - @ExcludeMissing - fun _lifeAssured(): JsonField = lifeAssured - - /** - * Returns the raw JSON value of [policyName]. - * - * Unlike [policyName], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("policy_name") - @ExcludeMissing - fun _policyName(): JsonField = policyName - - /** - * Returns the raw JSON value of [policyNumber]. - * - * Unlike [policyNumber], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("policy_number") - @ExcludeMissing - fun _policyNumber(): JsonField = policyNumber - - /** - * Returns the raw JSON value of [premiumAmount]. - * - * Unlike [premiumAmount], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("premium_amount") - @ExcludeMissing - fun _premiumAmount(): JsonField = premiumAmount - - /** - * Returns the raw JSON value of [premiumFrequency]. - * - * Unlike [premiumFrequency], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("premium_frequency") - @ExcludeMissing - fun _premiumFrequency(): JsonField = premiumFrequency - - /** - * Returns the raw JSON value of [provider]. - * - * Unlike [provider], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("provider") @ExcludeMissing fun _provider(): JsonField = provider - - /** - * Returns the raw JSON value of [status]. - * - * Unlike [status], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("status") @ExcludeMissing fun _status(): JsonField = status - - /** - * Returns the raw JSON value of [sumAssured]. - * - * Unlike [sumAssured], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("sum_assured") - @ExcludeMissing - fun _sumAssured(): JsonField = sumAssured - - @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 [LifeInsurancePolicy]. - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [LifeInsurancePolicy]. */ - class Builder internal constructor() { - - private var additionalInfo: JsonValue = JsonMissing.of() - private var lifeAssured: JsonField = JsonMissing.of() - private var policyName: JsonField = JsonMissing.of() - private var policyNumber: JsonField = JsonMissing.of() - private var premiumAmount: JsonField = JsonMissing.of() - private var premiumFrequency: JsonField = JsonMissing.of() - private var provider: JsonField = JsonMissing.of() - private var status: JsonField = JsonMissing.of() - private var sumAssured: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(lifeInsurancePolicy: LifeInsurancePolicy) = apply { - additionalInfo = lifeInsurancePolicy.additionalInfo - lifeAssured = lifeInsurancePolicy.lifeAssured - policyName = lifeInsurancePolicy.policyName - policyNumber = lifeInsurancePolicy.policyNumber - premiumAmount = lifeInsurancePolicy.premiumAmount - premiumFrequency = lifeInsurancePolicy.premiumFrequency - provider = lifeInsurancePolicy.provider - status = lifeInsurancePolicy.status - sumAssured = lifeInsurancePolicy.sumAssured - additionalProperties = lifeInsurancePolicy.additionalProperties.toMutableMap() - } - - /** Additional information specific to the policy */ - fun additionalInfo(additionalInfo: JsonValue) = apply { - this.additionalInfo = additionalInfo - } - - /** Name of the life assured */ - fun lifeAssured(lifeAssured: String) = lifeAssured(JsonField.of(lifeAssured)) - - /** - * Sets [Builder.lifeAssured] to an arbitrary JSON value. - * - * You should usually call [Builder.lifeAssured] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. - */ - fun lifeAssured(lifeAssured: JsonField) = apply { - this.lifeAssured = lifeAssured - } - - /** Name of the insurance policy */ - fun policyName(policyName: String) = policyName(JsonField.of(policyName)) - - /** - * Sets [Builder.policyName] to an arbitrary JSON value. - * - * You should usually call [Builder.policyName] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. - */ - fun policyName(policyName: JsonField) = apply { - this.policyName = policyName - } - - /** Insurance policy number */ - fun policyNumber(policyNumber: String) = policyNumber(JsonField.of(policyNumber)) - - /** - * Sets [Builder.policyNumber] to an arbitrary JSON value. - * - * You should usually call [Builder.policyNumber] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. - */ - fun policyNumber(policyNumber: JsonField) = apply { - this.policyNumber = policyNumber - } - - /** Premium amount */ - fun premiumAmount(premiumAmount: Float) = premiumAmount(JsonField.of(premiumAmount)) - - /** - * Sets [Builder.premiumAmount] to an arbitrary JSON value. - * - * You should usually call [Builder.premiumAmount] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. - */ - fun premiumAmount(premiumAmount: JsonField) = apply { - this.premiumAmount = premiumAmount - } - - /** Frequency of premium payment (e.g., Annual, Monthly) */ - fun premiumFrequency(premiumFrequency: String) = - premiumFrequency(JsonField.of(premiumFrequency)) - - /** - * Sets [Builder.premiumFrequency] to an arbitrary JSON value. - * - * You should usually call [Builder.premiumFrequency] with a well-typed [String] - * value instead. This method is primarily for setting the field to an undocumented - * or not yet supported value. - */ - fun premiumFrequency(premiumFrequency: JsonField) = apply { - this.premiumFrequency = premiumFrequency - } - - /** Insurance company name */ - fun provider(provider: String) = provider(JsonField.of(provider)) - - /** - * Sets [Builder.provider] to an arbitrary JSON value. - * - * You should usually call [Builder.provider] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. - */ - fun provider(provider: JsonField) = apply { this.provider = provider } - - /** Status of the policy (e.g., Active, Lapsed) */ - fun status(status: String) = status(JsonField.of(status)) - - /** - * Sets [Builder.status] to an arbitrary JSON value. - * - * You should usually call [Builder.status] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. - */ - fun status(status: JsonField) = apply { this.status = status } - - /** Sum assured amount */ - fun sumAssured(sumAssured: Float) = sumAssured(JsonField.of(sumAssured)) - - /** - * Sets [Builder.sumAssured] to an arbitrary JSON value. - * - * You should usually call [Builder.sumAssured] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. - */ - fun sumAssured(sumAssured: JsonField) = apply { - this.sumAssured = sumAssured - } - - 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 [LifeInsurancePolicy]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): LifeInsurancePolicy = - LifeInsurancePolicy( - additionalInfo, - lifeAssured, - policyName, - policyNumber, - premiumAmount, - premiumFrequency, - provider, - status, - sumAssured, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): LifeInsurancePolicy = apply { - if (validated) { - return@apply - } - - lifeAssured() - policyName() - policyNumber() - premiumAmount() - premiumFrequency() - provider() - status() - sumAssured() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - 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 (lifeAssured.asKnown().isPresent) 1 else 0) + - (if (policyName.asKnown().isPresent) 1 else 0) + - (if (policyNumber.asKnown().isPresent) 1 else 0) + - (if (premiumAmount.asKnown().isPresent) 1 else 0) + - (if (premiumFrequency.asKnown().isPresent) 1 else 0) + - (if (provider.asKnown().isPresent) 1 else 0) + - (if (status.asKnown().isPresent) 1 else 0) + - (if (sumAssured.asKnown().isPresent) 1 else 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is LifeInsurancePolicy && - additionalInfo == other.additionalInfo && - lifeAssured == other.lifeAssured && - policyName == other.policyName && - policyNumber == other.policyNumber && - premiumAmount == other.premiumAmount && - premiumFrequency == other.premiumFrequency && - provider == other.provider && - status == other.status && - sumAssured == other.sumAssured && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash( - additionalInfo, - lifeAssured, - policyName, - policyNumber, - premiumAmount, - premiumFrequency, - provider, - status, - sumAssured, - additionalProperties, - ) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "LifeInsurancePolicy{additionalInfo=$additionalInfo, lifeAssured=$lifeAssured, policyName=$policyName, policyNumber=$policyNumber, premiumAmount=$premiumAmount, premiumFrequency=$premiumFrequency, provider=$provider, status=$status, sumAssured=$sumAssured, additionalProperties=$additionalProperties}" - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Insurance && - lifeInsurancePolicies == other.lifeInsurancePolicies && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash(lifeInsurancePolicies, additionalProperties) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Insurance{lifeInsurancePolicies=$lifeInsurancePolicies, additionalProperties=$additionalProperties}" - } - - class Investor - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val address: JsonField, - private val casId: JsonField, - private val email: JsonField, - private val mobile: JsonField, - private val name: JsonField, - private val pan: JsonField, - private val pincode: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("address") @ExcludeMissing address: JsonField = JsonMissing.of(), - @JsonProperty("cas_id") @ExcludeMissing casId: JsonField = JsonMissing.of(), - @JsonProperty("email") @ExcludeMissing email: JsonField = JsonMissing.of(), - @JsonProperty("mobile") @ExcludeMissing mobile: JsonField = JsonMissing.of(), - @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), - @JsonProperty("pan") @ExcludeMissing pan: JsonField = JsonMissing.of(), - @JsonProperty("pincode") @ExcludeMissing pincode: JsonField = JsonMissing.of(), - ) : this(address, casId, email, mobile, name, pan, pincode, mutableMapOf()) - - /** - * Address of the investor - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun address(): Optional = address.getOptional("address") - - /** - * CAS ID of the investor (only for NSDL and CDSL) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun casId(): Optional = casId.getOptional("cas_id") - - /** - * Email address of the investor - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun email(): Optional = email.getOptional("email") - - /** - * Mobile number of the investor - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun mobile(): Optional = mobile.getOptional("mobile") - - /** - * Name of the investor - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun name(): Optional = name.getOptional("name") - - /** - * PAN (Permanent Account Number) of the investor - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun pan(): Optional = pan.getOptional("pan") - - /** - * Postal code of the investor's address - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun pincode(): Optional = pincode.getOptional("pincode") - - /** - * Returns the raw JSON value of [address]. - * - * Unlike [address], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("address") @ExcludeMissing fun _address(): JsonField = address - - /** - * Returns the raw JSON value of [casId]. - * - * Unlike [casId], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("cas_id") @ExcludeMissing fun _casId(): JsonField = casId - - /** - * Returns the raw JSON value of [email]. - * - * Unlike [email], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("email") @ExcludeMissing fun _email(): JsonField = email - - /** - * Returns the raw JSON value of [mobile]. - * - * Unlike [mobile], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("mobile") @ExcludeMissing fun _mobile(): JsonField = mobile - - /** - * Returns the raw JSON value of [name]. - * - * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name - - /** - * Returns the raw JSON value of [pan]. - * - * Unlike [pan], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("pan") @ExcludeMissing fun _pan(): JsonField = pan - - /** - * Returns the raw JSON value of [pincode]. - * - * Unlike [pincode], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("pincode") @ExcludeMissing fun _pincode(): JsonField = pincode - - @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 [Investor]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Investor]. */ - class Builder internal constructor() { - - private var address: JsonField = JsonMissing.of() - private var casId: JsonField = JsonMissing.of() - private var email: JsonField = JsonMissing.of() - private var mobile: JsonField = JsonMissing.of() - private var name: JsonField = JsonMissing.of() - private var pan: JsonField = JsonMissing.of() - private var pincode: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(investor: Investor) = apply { - address = investor.address - casId = investor.casId - email = investor.email - mobile = investor.mobile - name = investor.name - pan = investor.pan - pincode = investor.pincode - additionalProperties = investor.additionalProperties.toMutableMap() - } - - /** Address of the investor */ - fun address(address: String) = address(JsonField.of(address)) - - /** - * Sets [Builder.address] to an arbitrary JSON value. - * - * You should usually call [Builder.address] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun address(address: JsonField) = apply { this.address = address } - - /** CAS ID of the investor (only for NSDL and CDSL) */ - fun casId(casId: String) = casId(JsonField.of(casId)) - - /** - * Sets [Builder.casId] to an arbitrary JSON value. - * - * You should usually call [Builder.casId] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun casId(casId: JsonField) = apply { this.casId = casId } - - /** Email address of the investor */ - fun email(email: String) = email(JsonField.of(email)) - - /** - * Sets [Builder.email] to an arbitrary JSON value. - * - * You should usually call [Builder.email] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun email(email: JsonField) = apply { this.email = email } - - /** Mobile number of the investor */ - fun mobile(mobile: String) = mobile(JsonField.of(mobile)) - - /** - * Sets [Builder.mobile] to an arbitrary JSON value. - * - * You should usually call [Builder.mobile] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun mobile(mobile: JsonField) = apply { this.mobile = mobile } - - /** Name of the investor */ - fun name(name: String) = name(JsonField.of(name)) - - /** - * Sets [Builder.name] to an arbitrary JSON value. - * - * You should usually call [Builder.name] with a well-typed [String] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported - * value. - */ - fun name(name: JsonField) = apply { this.name = name } - - /** PAN (Permanent Account Number) of the investor */ - fun pan(pan: String) = pan(JsonField.of(pan)) - - /** - * Sets [Builder.pan] to an arbitrary JSON value. - * - * You should usually call [Builder.pan] with a well-typed [String] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported - * value. - */ - fun pan(pan: JsonField) = apply { this.pan = pan } - - /** Postal code of the investor's address */ - fun pincode(pincode: String) = pincode(JsonField.of(pincode)) - - /** - * Sets [Builder.pincode] to an arbitrary JSON value. - * - * You should usually call [Builder.pincode] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun pincode(pincode: JsonField) = apply { this.pincode = pincode } - - 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 [Investor]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): Investor = - Investor( - address, - casId, - email, - mobile, - name, - pan, - pincode, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): Investor = apply { - if (validated) { - return@apply - } - - address() - casId() - email() - mobile() - name() - pan() - pincode() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - 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 (address.asKnown().isPresent) 1 else 0) + - (if (casId.asKnown().isPresent) 1 else 0) + - (if (email.asKnown().isPresent) 1 else 0) + - (if (mobile.asKnown().isPresent) 1 else 0) + - (if (name.asKnown().isPresent) 1 else 0) + - (if (pan.asKnown().isPresent) 1 else 0) + - (if (pincode.asKnown().isPresent) 1 else 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Investor && - address == other.address && - casId == other.casId && - email == other.email && - mobile == other.mobile && - name == other.name && - pan == other.pan && - pincode == other.pincode && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash(address, casId, email, mobile, name, pan, pincode, additionalProperties) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Investor{address=$address, casId=$casId, email=$email, mobile=$mobile, name=$name, pan=$pan, pincode=$pincode, additionalProperties=$additionalProperties}" - } - - class Meta - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val casType: JsonField, - private val generatedAt: JsonField, - private val statementPeriod: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("cas_type") - @ExcludeMissing - casType: JsonField = JsonMissing.of(), - @JsonProperty("generated_at") - @ExcludeMissing - generatedAt: JsonField = JsonMissing.of(), - @JsonProperty("statement_period") - @ExcludeMissing - statementPeriod: JsonField = JsonMissing.of(), - ) : this(casType, generatedAt, statementPeriod, mutableMapOf()) - - /** - * Type of CAS detected and processed - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun casType(): Optional = casType.getOptional("cas_type") - - /** - * Timestamp when the response was generated - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun generatedAt(): Optional = generatedAt.getOptional("generated_at") - - /** - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun statementPeriod(): Optional = - statementPeriod.getOptional("statement_period") - - /** - * Returns the raw JSON value of [casType]. - * - * Unlike [casType], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("cas_type") @ExcludeMissing fun _casType(): JsonField = casType - - /** - * Returns the raw JSON value of [generatedAt]. - * - * Unlike [generatedAt], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("generated_at") - @ExcludeMissing - fun _generatedAt(): JsonField = generatedAt - - /** - * Returns the raw JSON value of [statementPeriod]. - * - * Unlike [statementPeriod], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("statement_period") - @ExcludeMissing - fun _statementPeriod(): JsonField = statementPeriod - - @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 [Meta]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Meta]. */ - class Builder internal constructor() { - - private var casType: JsonField = JsonMissing.of() - private var generatedAt: JsonField = JsonMissing.of() - private var statementPeriod: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(meta: Meta) = apply { - casType = meta.casType - generatedAt = meta.generatedAt - statementPeriod = meta.statementPeriod - additionalProperties = meta.additionalProperties.toMutableMap() - } - - /** Type of CAS detected and processed */ - fun casType(casType: CasType) = casType(JsonField.of(casType)) - - /** - * Sets [Builder.casType] to an arbitrary JSON value. - * - * You should usually call [Builder.casType] with a well-typed [CasType] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun casType(casType: JsonField) = apply { this.casType = casType } - - /** Timestamp when the response was generated */ - fun generatedAt(generatedAt: OffsetDateTime) = generatedAt(JsonField.of(generatedAt)) - - /** - * Sets [Builder.generatedAt] to an arbitrary JSON value. - * - * You should usually call [Builder.generatedAt] with a well-typed [OffsetDateTime] - * value instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun generatedAt(generatedAt: JsonField) = apply { - this.generatedAt = generatedAt - } - - fun statementPeriod(statementPeriod: StatementPeriod) = - statementPeriod(JsonField.of(statementPeriod)) - - /** - * Sets [Builder.statementPeriod] to an arbitrary JSON value. - * - * You should usually call [Builder.statementPeriod] with a well-typed [StatementPeriod] - * value instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun statementPeriod(statementPeriod: JsonField) = apply { - this.statementPeriod = statementPeriod - } - - 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 [Meta]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): Meta = - Meta(casType, generatedAt, statementPeriod, additionalProperties.toMutableMap()) - } - - private var validated: Boolean = false - - fun validate(): Meta = apply { - if (validated) { - return@apply - } - - casType().ifPresent { it.validate() } - generatedAt() - statementPeriod().ifPresent { it.validate() } - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - 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 = - (casType.asKnown().getOrNull()?.validity() ?: 0) + - (if (generatedAt.asKnown().isPresent) 1 else 0) + - (statementPeriod.asKnown().getOrNull()?.validity() ?: 0) - - /** Type of CAS detected and processed */ - class CasType @JsonCreator private constructor(private val value: JsonField) : - Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that doesn't - * match any known member, and you want to know that value. For example, if the SDK is - * on an older version than the API, then the API may respond with new members that the - * SDK is unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - companion object { - - @JvmField val NSDL = of("NSDL") - - @JvmField val CDSL = of("CDSL") - - @JvmField val CAMS_KFINTECH = of("CAMS_KFINTECH") - - @JvmStatic fun of(value: String) = CasType(JsonField.of(value)) - } - - /** An enum containing [CasType]'s known values. */ - enum class Known { - NSDL, - CDSL, - CAMS_KFINTECH, - } - - /** - * An enum containing [CasType]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [CasType] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For example, if - * the SDK is on an older version than the API, then the API may respond with new - * members that the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - NSDL, - CDSL, - CAMS_KFINTECH, - /** - * An enum member indicating that [CasType] was instantiated with an unknown value. - */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or - * [Value._UNKNOWN] if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or if you - * want to throw for the unknown case. - */ - fun value(): Value = - when (this) { - NSDL -> Value.NSDL - CDSL -> Value.CDSL - CAMS_KFINTECH -> Value.CAMS_KFINTECH - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known and - * don't want to throw for the unknown case. - * - * @throws CasParserInvalidDataException if this class instance's value is a not a known - * member. - */ - fun known(): Known = - when (this) { - NSDL -> Known.NSDL - CDSL -> Known.CDSL - CAMS_KFINTECH -> Known.CAMS_KFINTECH - else -> throw CasParserInvalidDataException("Unknown CasType: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily for - * debugging and generally doesn't throw. - * - * @throws CasParserInvalidDataException if this class instance's value does not have - * the expected primitive type. - */ - fun asString(): String = - _value().asString().orElseThrow { - CasParserInvalidDataException("Value is not a String") - } - - private var validated: Boolean = false - - fun validate(): CasType = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - 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 (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is CasType && value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - - class StatementPeriod - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val from: JsonField, - private val to: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("from") @ExcludeMissing from: JsonField = JsonMissing.of(), - @JsonProperty("to") @ExcludeMissing to: JsonField = JsonMissing.of(), - ) : this(from, to, mutableMapOf()) - - /** - * Start date of the statement period - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun from(): Optional = from.getOptional("from") - - /** - * End date of the statement period - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun to(): Optional = to.getOptional("to") - - /** - * Returns the raw JSON value of [from]. - * - * Unlike [from], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("from") @ExcludeMissing fun _from(): JsonField = from - - /** - * Returns the raw JSON value of [to]. - * - * Unlike [to], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("to") @ExcludeMissing fun _to(): JsonField = to - - @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 [StatementPeriod]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [StatementPeriod]. */ - class Builder internal constructor() { - - private var from: JsonField = JsonMissing.of() - private var to: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(statementPeriod: StatementPeriod) = apply { - from = statementPeriod.from - to = statementPeriod.to - additionalProperties = statementPeriod.additionalProperties.toMutableMap() - } - - /** Start date of the statement period */ - fun from(from: LocalDate) = from(JsonField.of(from)) - - /** - * Sets [Builder.from] to an arbitrary JSON value. - * - * You should usually call [Builder.from] with a well-typed [LocalDate] value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. - */ - fun from(from: JsonField) = apply { this.from = from } - - /** End date of the statement period */ - fun to(to: LocalDate) = to(JsonField.of(to)) - - /** - * Sets [Builder.to] to an arbitrary JSON value. - * - * You should usually call [Builder.to] with a well-typed [LocalDate] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun to(to: JsonField) = apply { this.to = to } - - 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 [StatementPeriod]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): StatementPeriod = - StatementPeriod(from, to, additionalProperties.toMutableMap()) - } - - private var validated: Boolean = false - - fun validate(): StatementPeriod = apply { - if (validated) { - return@apply - } - - from() - to() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - 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 (from.asKnown().isPresent) 1 else 0) + (if (to.asKnown().isPresent) 1 else 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is StatementPeriod && - from == other.from && - to == other.to && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { Objects.hash(from, to, additionalProperties) } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "StatementPeriod{from=$from, to=$to, additionalProperties=$additionalProperties}" - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Meta && - casType == other.casType && - generatedAt == other.generatedAt && - statementPeriod == other.statementPeriod && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash(casType, generatedAt, statementPeriod, additionalProperties) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Meta{casType=$casType, generatedAt=$generatedAt, statementPeriod=$statementPeriod, additionalProperties=$additionalProperties}" - } - - class MutualFund - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val additionalInfo: JsonField, - private val amc: JsonField, - private val folioNumber: JsonField, - private val linkedHolders: JsonField>, - private val registrar: JsonField, - private val schemes: JsonField>, - private val value: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("additional_info") - @ExcludeMissing - additionalInfo: JsonField = JsonMissing.of(), - @JsonProperty("amc") @ExcludeMissing amc: JsonField = JsonMissing.of(), - @JsonProperty("folio_number") - @ExcludeMissing - folioNumber: JsonField = JsonMissing.of(), - @JsonProperty("linked_holders") - @ExcludeMissing - linkedHolders: JsonField> = JsonMissing.of(), - @JsonProperty("registrar") - @ExcludeMissing - registrar: JsonField = JsonMissing.of(), - @JsonProperty("schemes") - @ExcludeMissing - schemes: JsonField> = JsonMissing.of(), - @JsonProperty("value") @ExcludeMissing value: JsonField = JsonMissing.of(), - ) : this( - additionalInfo, - amc, - folioNumber, - linkedHolders, - registrar, - schemes, - value, - mutableMapOf(), - ) - - /** - * Additional folio information - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun additionalInfo(): Optional = - additionalInfo.getOptional("additional_info") - - /** - * Asset Management Company name - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun amc(): Optional = amc.getOptional("amc") - - /** - * Folio number - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun folioNumber(): Optional = folioNumber.getOptional("folio_number") - - /** - * List of account holders linked to this mutual fund folio - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun linkedHolders(): Optional> = - linkedHolders.getOptional("linked_holders") - - /** - * Registrar and Transfer Agent name - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun registrar(): Optional = registrar.getOptional("registrar") - - /** - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun schemes(): Optional> = schemes.getOptional("schemes") - - /** - * Total value of the folio - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun value(): Optional = value.getOptional("value") - - /** - * Returns the raw JSON value of [additionalInfo]. - * - * Unlike [additionalInfo], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("additional_info") - @ExcludeMissing - fun _additionalInfo(): JsonField = additionalInfo - - /** - * Returns the raw JSON value of [amc]. - * - * Unlike [amc], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("amc") @ExcludeMissing fun _amc(): JsonField = amc - - /** - * Returns the raw JSON value of [folioNumber]. - * - * Unlike [folioNumber], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("folio_number") - @ExcludeMissing - fun _folioNumber(): JsonField = folioNumber - - /** - * Returns the raw JSON value of [linkedHolders]. - * - * Unlike [linkedHolders], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("linked_holders") - @ExcludeMissing - fun _linkedHolders(): JsonField> = linkedHolders - - /** - * Returns the raw JSON value of [registrar]. - * - * Unlike [registrar], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("registrar") @ExcludeMissing fun _registrar(): JsonField = registrar - - /** - * Returns the raw JSON value of [schemes]. - * - * Unlike [schemes], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("schemes") @ExcludeMissing fun _schemes(): JsonField> = schemes - - /** - * Returns the raw JSON value of [value]. - * - * Unlike [value], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("value") @ExcludeMissing fun _value(): JsonField = value - - @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 [MutualFund]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [MutualFund]. */ - class Builder internal constructor() { - - private var additionalInfo: JsonField = JsonMissing.of() - private var amc: JsonField = JsonMissing.of() - private var folioNumber: JsonField = JsonMissing.of() - private var linkedHolders: JsonField>? = null - private var registrar: JsonField = JsonMissing.of() - private var schemes: JsonField>? = null - private var value: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(mutualFund: MutualFund) = apply { - additionalInfo = mutualFund.additionalInfo - amc = mutualFund.amc - folioNumber = mutualFund.folioNumber - linkedHolders = mutualFund.linkedHolders.map { it.toMutableList() } - registrar = mutualFund.registrar - schemes = mutualFund.schemes.map { it.toMutableList() } - value = mutualFund.value - additionalProperties = mutualFund.additionalProperties.toMutableMap() - } - - /** Additional folio information */ - fun additionalInfo(additionalInfo: AdditionalInfo) = - additionalInfo(JsonField.of(additionalInfo)) - - /** - * Sets [Builder.additionalInfo] to an arbitrary JSON value. - * - * You should usually call [Builder.additionalInfo] with a well-typed [AdditionalInfo] - * value instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun additionalInfo(additionalInfo: JsonField) = apply { - this.additionalInfo = additionalInfo - } - - /** Asset Management Company name */ - fun amc(amc: String) = amc(JsonField.of(amc)) - - /** - * Sets [Builder.amc] to an arbitrary JSON value. - * - * You should usually call [Builder.amc] with a well-typed [String] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported - * value. - */ - fun amc(amc: JsonField) = apply { this.amc = amc } - - /** Folio number */ - fun folioNumber(folioNumber: String) = folioNumber(JsonField.of(folioNumber)) - - /** - * Sets [Builder.folioNumber] to an arbitrary JSON value. - * - * You should usually call [Builder.folioNumber] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun folioNumber(folioNumber: JsonField) = apply { - this.folioNumber = folioNumber - } - - /** List of account holders linked to this mutual fund folio */ - fun linkedHolders(linkedHolders: List) = - linkedHolders(JsonField.of(linkedHolders)) - - /** - * Sets [Builder.linkedHolders] to an arbitrary JSON value. - * - * You should usually call [Builder.linkedHolders] with a well-typed - * `List` value instead. This method is primarily for setting the field to - * an undocumented or not yet supported value. - */ - fun linkedHolders(linkedHolders: JsonField>) = apply { - this.linkedHolders = linkedHolders.map { it.toMutableList() } - } - - /** - * Adds a single [LinkedHolder] to [linkedHolders]. - * - * @throws IllegalStateException if the field was previously set to a non-list. - */ - fun addLinkedHolder(linkedHolder: LinkedHolder) = apply { - linkedHolders = - (linkedHolders ?: JsonField.of(mutableListOf())).also { - checkKnown("linkedHolders", it).add(linkedHolder) - } - } - - /** Registrar and Transfer Agent name */ - fun registrar(registrar: String) = registrar(JsonField.of(registrar)) + /** Postal code of the investor's address */ + fun pincode(pincode: String) = pincode(JsonField.of(pincode)) /** - * Sets [Builder.registrar] to an arbitrary JSON value. + * Sets [Builder.pincode] to an arbitrary JSON value. * - * You should usually call [Builder.registrar] with a well-typed [String] value instead. + * You should usually call [Builder.pincode] with a well-typed [String] value instead. * This method is primarily for setting the field to an undocumented or not yet * supported value. */ - fun registrar(registrar: JsonField) = apply { this.registrar = registrar } - - fun schemes(schemes: List) = schemes(JsonField.of(schemes)) - - /** - * Sets [Builder.schemes] to an arbitrary JSON value. - * - * You should usually call [Builder.schemes] with a well-typed `List` value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun schemes(schemes: JsonField>) = apply { - this.schemes = schemes.map { it.toMutableList() } - } - - /** - * Adds a single [Scheme] to [schemes]. - * - * @throws IllegalStateException if the field was previously set to a non-list. - */ - fun addScheme(scheme: Scheme) = apply { - schemes = - (schemes ?: JsonField.of(mutableListOf())).also { - checkKnown("schemes", it).add(scheme) - } - } - - /** Total value of the folio */ - fun value(value: Float) = value(JsonField.of(value)) - - /** - * Sets [Builder.value] to an arbitrary JSON value. - * - * You should usually call [Builder.value] with a well-typed [Float] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported - * value. - */ - fun value(value: JsonField) = apply { this.value = value } + fun pincode(pincode: JsonField) = apply { this.pincode = pincode } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() @@ -13007,40 +5828,40 @@ private constructor( fun removeAllAdditionalProperties(keys: Set) = apply { keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [MutualFund]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): MutualFund = - MutualFund( - additionalInfo, - amc, - folioNumber, - (linkedHolders ?: JsonMissing.of()).map { it.toImmutable() }, - registrar, - (schemes ?: JsonMissing.of()).map { it.toImmutable() }, - value, + } + + /** + * Returns an immutable instance of [Investor]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Investor = + Investor( + address, + casId, + email, + mobile, + name, + pan, + pincode, additionalProperties.toMutableMap(), ) } private var validated: Boolean = false - fun validate(): MutualFund = apply { + fun validate(): Investor = apply { if (validated) { return@apply } - additionalInfo().ifPresent { it.validate() } - amc() - folioNumber() - linkedHolders().ifPresent { it.forEach { it.validate() } } - registrar() - schemes().ifPresent { it.forEach { it.validate() } } - value() + address() + casId() + email() + mobile() + name() + pan() + pincode() validated = true } @@ -13060,187 +5881,351 @@ private constructor( */ @JvmSynthetic internal fun validity(): Int = - (additionalInfo.asKnown().getOrNull()?.validity() ?: 0) + - (if (amc.asKnown().isPresent) 1 else 0) + - (if (folioNumber.asKnown().isPresent) 1 else 0) + - (linkedHolders.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + - (if (registrar.asKnown().isPresent) 1 else 0) + - (schemes.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + - (if (value.asKnown().isPresent) 1 else 0) + (if (address.asKnown().isPresent) 1 else 0) + + (if (casId.asKnown().isPresent) 1 else 0) + + (if (email.asKnown().isPresent) 1 else 0) + + (if (mobile.asKnown().isPresent) 1 else 0) + + (if (name.asKnown().isPresent) 1 else 0) + + (if (pan.asKnown().isPresent) 1 else 0) + + (if (pincode.asKnown().isPresent) 1 else 0) - /** Additional folio information */ - class AdditionalInfo - @JsonCreator(mode = JsonCreator.Mode.DISABLED) + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Investor && + address == other.address && + casId == other.casId && + email == other.email && + mobile == other.mobile && + name == other.name && + pan == other.pan && + pincode == other.pincode && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(address, casId, email, mobile, name, pan, pincode, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Investor{address=$address, casId=$casId, email=$email, mobile=$mobile, name=$name, pan=$pan, pincode=$pincode, additionalProperties=$additionalProperties}" + } + + class Meta + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val casType: JsonField, + private val generatedAt: JsonField, + private val statementPeriod: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator private constructor( - private val kyc: JsonField, - private val pan: JsonField, - private val pankyc: JsonField, - private val additionalProperties: MutableMap, - ) { + @JsonProperty("cas_type") + @ExcludeMissing + casType: JsonField = JsonMissing.of(), + @JsonProperty("generated_at") + @ExcludeMissing + generatedAt: JsonField = JsonMissing.of(), + @JsonProperty("statement_period") + @ExcludeMissing + statementPeriod: JsonField = JsonMissing.of(), + ) : this(casType, generatedAt, statementPeriod, mutableMapOf()) - @JsonCreator - private constructor( - @JsonProperty("kyc") @ExcludeMissing kyc: JsonField = JsonMissing.of(), - @JsonProperty("pan") @ExcludeMissing pan: JsonField = JsonMissing.of(), - @JsonProperty("pankyc") @ExcludeMissing pankyc: JsonField = JsonMissing.of(), - ) : this(kyc, pan, pankyc, mutableMapOf()) + /** + * Type of CAS detected and processed + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun casType(): Optional = casType.getOptional("cas_type") - /** - * KYC status of the folio - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun kyc(): Optional = kyc.getOptional("kyc") + /** + * Timestamp when the response was generated + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun generatedAt(): Optional = generatedAt.getOptional("generated_at") - /** - * PAN associated with the folio - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun pan(): Optional = pan.getOptional("pan") + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun statementPeriod(): Optional = + statementPeriod.getOptional("statement_period") + + /** + * Returns the raw JSON value of [casType]. + * + * Unlike [casType], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("cas_type") @ExcludeMissing fun _casType(): JsonField = casType + + /** + * Returns the raw JSON value of [generatedAt]. + * + * Unlike [generatedAt], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("generated_at") + @ExcludeMissing + fun _generatedAt(): JsonField = generatedAt + + /** + * Returns the raw JSON value of [statementPeriod]. + * + * Unlike [statementPeriod], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("statement_period") + @ExcludeMissing + fun _statementPeriod(): JsonField = statementPeriod + + @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 [Meta]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Meta]. */ + class Builder internal constructor() { + + private var casType: JsonField = JsonMissing.of() + private var generatedAt: JsonField = JsonMissing.of() + private var statementPeriod: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(meta: Meta) = apply { + casType = meta.casType + generatedAt = meta.generatedAt + statementPeriod = meta.statementPeriod + additionalProperties = meta.additionalProperties.toMutableMap() + } + + /** Type of CAS detected and processed */ + fun casType(casType: CasType) = casType(JsonField.of(casType)) /** - * PAN KYC status + * Sets [Builder.casType] to an arbitrary JSON value. * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). + * You should usually call [Builder.casType] with a well-typed [CasType] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - fun pankyc(): Optional = pankyc.getOptional("pankyc") + fun casType(casType: JsonField) = apply { this.casType = casType } + + /** Timestamp when the response was generated */ + fun generatedAt(generatedAt: OffsetDateTime) = generatedAt(JsonField.of(generatedAt)) /** - * Returns the raw JSON value of [kyc]. + * Sets [Builder.generatedAt] to an arbitrary JSON value. * - * Unlike [kyc], this method doesn't throw if the JSON field has an unexpected type. + * You should usually call [Builder.generatedAt] with a well-typed [OffsetDateTime] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. */ - @JsonProperty("kyc") @ExcludeMissing fun _kyc(): JsonField = kyc + fun generatedAt(generatedAt: JsonField) = apply { + this.generatedAt = generatedAt + } + + fun statementPeriod(statementPeriod: StatementPeriod) = + statementPeriod(JsonField.of(statementPeriod)) /** - * Returns the raw JSON value of [pan]. + * Sets [Builder.statementPeriod] to an arbitrary JSON value. * - * Unlike [pan], this method doesn't throw if the JSON field has an unexpected type. + * You should usually call [Builder.statementPeriod] with a well-typed [StatementPeriod] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. */ - @JsonProperty("pan") @ExcludeMissing fun _pan(): JsonField = pan + fun statementPeriod(statementPeriod: JsonField) = apply { + this.statementPeriod = statementPeriod + } + + 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 the raw JSON value of [pankyc]. + * Returns an immutable instance of [Meta]. * - * Unlike [pankyc], this method doesn't throw if the JSON field has an unexpected type. + * Further updates to this [Builder] will not mutate the returned instance. */ - @JsonProperty("pankyc") @ExcludeMissing fun _pankyc(): JsonField = pankyc - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } + fun build(): Meta = + Meta(casType, generatedAt, statementPeriod, additionalProperties.toMutableMap()) + } - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) + private var validated: Boolean = false - fun toBuilder() = Builder().from(this) + fun validate(): Meta = apply { + if (validated) { + return@apply + } - companion object { + casType().ifPresent { it.validate() } + generatedAt() + statementPeriod().ifPresent { it.validate() } + validated = true + } - /** Returns a mutable builder for constructing an instance of [AdditionalInfo]. */ - @JvmStatic fun builder() = Builder() + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + false } - /** A builder for [AdditionalInfo]. */ - class Builder internal constructor() { + /** + * 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 = + (casType.asKnown().getOrNull()?.validity() ?: 0) + + (if (generatedAt.asKnown().isPresent) 1 else 0) + + (statementPeriod.asKnown().getOrNull()?.validity() ?: 0) - private var kyc: JsonField = JsonMissing.of() - private var pan: JsonField = JsonMissing.of() - private var pankyc: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() + /** Type of CAS detected and processed */ + class CasType @JsonCreator private constructor(private val value: JsonField) : + Enum { - @JvmSynthetic - internal fun from(additionalInfo: AdditionalInfo) = apply { - kyc = additionalInfo.kyc - pan = additionalInfo.pan - pankyc = additionalInfo.pankyc - additionalProperties = additionalInfo.additionalProperties.toMutableMap() - } + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is + * on an older version than the API, then the API may respond with new members that the + * SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - /** KYC status of the folio */ - fun kyc(kyc: String) = kyc(JsonField.of(kyc)) + companion object { - /** - * Sets [Builder.kyc] to an arbitrary JSON value. - * - * You should usually call [Builder.kyc] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun kyc(kyc: JsonField) = apply { this.kyc = kyc } + @JvmField val NSDL = of("NSDL") - /** PAN associated with the folio */ - fun pan(pan: String) = pan(JsonField.of(pan)) + @JvmField val CDSL = of("CDSL") - /** - * Sets [Builder.pan] to an arbitrary JSON value. - * - * You should usually call [Builder.pan] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun pan(pan: JsonField) = apply { this.pan = pan } + @JvmField val CAMS_KFINTECH = of("CAMS_KFINTECH") - /** PAN KYC status */ - fun pankyc(pankyc: String) = pankyc(JsonField.of(pankyc)) + @JvmStatic fun of(value: String) = CasType(JsonField.of(value)) + } + + /** An enum containing [CasType]'s known values. */ + enum class Known { + NSDL, + CDSL, + CAMS_KFINTECH, + } + /** + * An enum containing [CasType]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [CasType] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if + * the SDK is on an older version than the API, then the API may respond with new + * members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + NSDL, + CDSL, + CAMS_KFINTECH, /** - * Sets [Builder.pankyc] to an arbitrary JSON value. - * - * You should usually call [Builder.pankyc] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. + * An enum member indicating that [CasType] was instantiated with an unknown value. */ - fun pankyc(pankyc: JsonField) = apply { this.pankyc = pankyc } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } + _UNKNOWN, + } - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you + * want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + NSDL -> Value.NSDL + CDSL -> Value.CDSL + CAMS_KFINTECH -> Value.CAMS_KFINTECH + else -> Value._UNKNOWN } - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and + * don't want to throw for the unknown case. + * + * @throws CasParserInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + NSDL -> Known.NSDL + CDSL -> Known.CDSL + CAMS_KFINTECH -> Known.CAMS_KFINTECH + else -> throw CasParserInvalidDataException("Unknown CasType: $value") } - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws CasParserInvalidDataException if this class instance's value does not have + * the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CasParserInvalidDataException("Value is not a String") } - /** - * Returns an immutable instance of [AdditionalInfo]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): AdditionalInfo = - AdditionalInfo(kyc, pan, pankyc, additionalProperties.toMutableMap()) - } - private var validated: Boolean = false - fun validate(): AdditionalInfo = apply { + fun validate(): CasType = apply { if (validated) { return@apply } - kyc() - pan() - pankyc() + known() validated = true } @@ -13258,77 +6243,64 @@ private constructor( * * Used for best match union deserialization. */ - @JvmSynthetic - internal fun validity(): Int = - (if (kyc.asKnown().isPresent) 1 else 0) + - (if (pan.asKnown().isPresent) 1 else 0) + - (if (pankyc.asKnown().isPresent) 1 else 0) + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is AdditionalInfo && - kyc == other.kyc && - pan == other.pan && - pankyc == other.pankyc && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash(kyc, pan, pankyc, additionalProperties) + return other is CasType && value == other.value } - override fun hashCode(): Int = hashCode + override fun hashCode() = value.hashCode() - override fun toString() = - "AdditionalInfo{kyc=$kyc, pan=$pan, pankyc=$pankyc, additionalProperties=$additionalProperties}" + override fun toString() = value.toString() } - class LinkedHolder + class StatementPeriod @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( - private val name: JsonField, - private val pan: JsonField, + private val from: JsonField, + private val to: JsonField, private val additionalProperties: MutableMap, ) { @JsonCreator private constructor( - @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), - @JsonProperty("pan") @ExcludeMissing pan: JsonField = JsonMissing.of(), - ) : this(name, pan, mutableMapOf()) + @JsonProperty("from") @ExcludeMissing from: JsonField = JsonMissing.of(), + @JsonProperty("to") @ExcludeMissing to: JsonField = JsonMissing.of(), + ) : this(from, to, mutableMapOf()) /** - * Name of the account holder + * Start date of the statement period * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. * if the server responded with an unexpected value). */ - fun name(): Optional = name.getOptional("name") + fun from(): Optional = from.getOptional("from") /** - * PAN of the account holder + * End date of the statement period * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. * if the server responded with an unexpected value). */ - fun pan(): Optional = pan.getOptional("pan") + fun to(): Optional = to.getOptional("to") /** - * Returns the raw JSON value of [name]. + * Returns the raw JSON value of [from]. * - * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [from], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + @JsonProperty("from") @ExcludeMissing fun _from(): JsonField = from /** - * Returns the raw JSON value of [pan]. + * Returns the raw JSON value of [to]. * - * Unlike [pan], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [to], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("pan") @ExcludeMissing fun _pan(): JsonField = pan + @JsonProperty("to") @ExcludeMissing fun _to(): JsonField = to @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { @@ -13344,47 +6316,47 @@ private constructor( companion object { - /** Returns a mutable builder for constructing an instance of [LinkedHolder]. */ + /** Returns a mutable builder for constructing an instance of [StatementPeriod]. */ @JvmStatic fun builder() = Builder() } - /** A builder for [LinkedHolder]. */ + /** A builder for [StatementPeriod]. */ class Builder internal constructor() { - - private var name: JsonField = JsonMissing.of() - private var pan: JsonField = JsonMissing.of() + + private var from: JsonField = JsonMissing.of() + private var to: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(linkedHolder: LinkedHolder) = apply { - name = linkedHolder.name - pan = linkedHolder.pan - additionalProperties = linkedHolder.additionalProperties.toMutableMap() + internal fun from(statementPeriod: StatementPeriod) = apply { + from = statementPeriod.from + to = statementPeriod.to + additionalProperties = statementPeriod.additionalProperties.toMutableMap() } - /** Name of the account holder */ - fun name(name: String) = name(JsonField.of(name)) + /** Start date of the statement period */ + fun from(from: LocalDate) = from(JsonField.of(from)) /** - * Sets [Builder.name] to an arbitrary JSON value. + * Sets [Builder.from] to an arbitrary JSON value. * - * You should usually call [Builder.name] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. + * You should usually call [Builder.from] with a well-typed [LocalDate] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. */ - fun name(name: JsonField) = apply { this.name = name } + fun from(from: JsonField) = apply { this.from = from } - /** PAN of the account holder */ - fun pan(pan: String) = pan(JsonField.of(pan)) + /** End date of the statement period */ + fun to(to: LocalDate) = to(JsonField.of(to)) /** - * Sets [Builder.pan] to an arbitrary JSON value. + * Sets [Builder.to] to an arbitrary JSON value. * - * You should usually call [Builder.pan] with a well-typed [String] value instead. + * You should usually call [Builder.to] with a well-typed [LocalDate] value instead. * This method is primarily for setting the field to an undocumented or not yet * supported value. */ - fun pan(pan: JsonField) = apply { this.pan = pan } + fun to(to: JsonField) = apply { this.to = to } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() @@ -13409,23 +6381,23 @@ private constructor( } /** - * Returns an immutable instance of [LinkedHolder]. + * Returns an immutable instance of [StatementPeriod]. * * Further updates to this [Builder] will not mutate the returned instance. */ - fun build(): LinkedHolder = - LinkedHolder(name, pan, additionalProperties.toMutableMap()) + fun build(): StatementPeriod = + StatementPeriod(from, to, additionalProperties.toMutableMap()) } private var validated: Boolean = false - fun validate(): LinkedHolder = apply { + fun validate(): StatementPeriod = apply { if (validated) { return@apply } - name() - pan() + from() + to() validated = true } @@ -13445,249 +6417,503 @@ private constructor( */ @JvmSynthetic internal fun validity(): Int = - (if (name.asKnown().isPresent) 1 else 0) + (if (pan.asKnown().isPresent) 1 else 0) + (if (from.asKnown().isPresent) 1 else 0) + (if (to.asKnown().isPresent) 1 else 0) override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is LinkedHolder && - name == other.name && - pan == other.pan && + return other is StatementPeriod && + from == other.from && + to == other.to && additionalProperties == other.additionalProperties } - private val hashCode: Int by lazy { Objects.hash(name, pan, additionalProperties) } + private val hashCode: Int by lazy { Objects.hash(from, to, additionalProperties) } override fun hashCode(): Int = hashCode override fun toString() = - "LinkedHolder{name=$name, pan=$pan, additionalProperties=$additionalProperties}" + "StatementPeriod{from=$from, to=$to, additionalProperties=$additionalProperties}" } - class Scheme - @JsonCreator(mode = JsonCreator.Mode.DISABLED) + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Meta && + casType == other.casType && + generatedAt == other.generatedAt && + statementPeriod == other.statementPeriod && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(casType, generatedAt, statementPeriod, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Meta{casType=$casType, generatedAt=$generatedAt, statementPeriod=$statementPeriod, additionalProperties=$additionalProperties}" + } + + class MutualFund + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val additionalInfo: JsonField, + private val amc: JsonField, + private val folioNumber: JsonField, + private val linkedHolders: JsonField>, + private val registrar: JsonField, + private val schemes: JsonField>, + private val value: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator private constructor( - private val additionalInfo: JsonField, - private val cost: JsonField, - private val gain: JsonField, - private val isin: JsonField, - private val name: JsonField, - private val nav: JsonField, - private val nominees: JsonField>, - private val transactions: JsonField>, - private val type: JsonField, - private val units: JsonField, - private val value: JsonField, - private val additionalProperties: MutableMap, - ) { + @JsonProperty("additional_info") + @ExcludeMissing + additionalInfo: JsonField = JsonMissing.of(), + @JsonProperty("amc") @ExcludeMissing amc: JsonField = JsonMissing.of(), + @JsonProperty("folio_number") + @ExcludeMissing + folioNumber: JsonField = JsonMissing.of(), + @JsonProperty("linked_holders") + @ExcludeMissing + linkedHolders: JsonField> = JsonMissing.of(), + @JsonProperty("registrar") + @ExcludeMissing + registrar: JsonField = JsonMissing.of(), + @JsonProperty("schemes") + @ExcludeMissing + schemes: JsonField> = JsonMissing.of(), + @JsonProperty("value") @ExcludeMissing value: JsonField = JsonMissing.of(), + ) : this( + additionalInfo, + amc, + folioNumber, + linkedHolders, + registrar, + schemes, + value, + mutableMapOf(), + ) + + /** + * Additional folio information + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun additionalInfo(): Optional = + additionalInfo.getOptional("additional_info") + + /** + * Asset Management Company name + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun amc(): Optional = amc.getOptional("amc") + + /** + * Folio number + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun folioNumber(): Optional = folioNumber.getOptional("folio_number") + + /** + * List of account holders linked to this mutual fund folio + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun linkedHolders(): Optional> = + linkedHolders.getOptional("linked_holders") + + /** + * Registrar and Transfer Agent name + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun registrar(): Optional = registrar.getOptional("registrar") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun schemes(): Optional> = schemes.getOptional("schemes") + + /** + * Total value of the folio + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun value(): Optional = value.getOptional("value") + + /** + * Returns the raw JSON value of [additionalInfo]. + * + * Unlike [additionalInfo], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("additional_info") + @ExcludeMissing + fun _additionalInfo(): JsonField = additionalInfo + + /** + * Returns the raw JSON value of [amc]. + * + * Unlike [amc], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("amc") @ExcludeMissing fun _amc(): JsonField = amc + + /** + * Returns the raw JSON value of [folioNumber]. + * + * Unlike [folioNumber], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("folio_number") + @ExcludeMissing + fun _folioNumber(): JsonField = folioNumber + + /** + * Returns the raw JSON value of [linkedHolders]. + * + * Unlike [linkedHolders], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("linked_holders") + @ExcludeMissing + fun _linkedHolders(): JsonField> = linkedHolders + + /** + * Returns the raw JSON value of [registrar]. + * + * Unlike [registrar], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("registrar") @ExcludeMissing fun _registrar(): JsonField = registrar + + /** + * Returns the raw JSON value of [schemes]. + * + * Unlike [schemes], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("schemes") @ExcludeMissing fun _schemes(): JsonField> = schemes + + /** + * Returns the raw JSON value of [value]. + * + * Unlike [value], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("value") @ExcludeMissing fun _value(): JsonField = value + + @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 [MutualFund]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [MutualFund]. */ + class Builder internal constructor() { - @JsonCreator - private constructor( - @JsonProperty("additional_info") - @ExcludeMissing - additionalInfo: JsonField = JsonMissing.of(), - @JsonProperty("cost") @ExcludeMissing cost: JsonField = JsonMissing.of(), - @JsonProperty("gain") @ExcludeMissing gain: JsonField = JsonMissing.of(), - @JsonProperty("isin") @ExcludeMissing isin: JsonField = JsonMissing.of(), - @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), - @JsonProperty("nav") @ExcludeMissing nav: JsonField = JsonMissing.of(), - @JsonProperty("nominees") - @ExcludeMissing - nominees: JsonField> = JsonMissing.of(), - @JsonProperty("transactions") - @ExcludeMissing - transactions: JsonField> = JsonMissing.of(), - @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), - @JsonProperty("units") @ExcludeMissing units: JsonField = JsonMissing.of(), - @JsonProperty("value") @ExcludeMissing value: JsonField = JsonMissing.of(), - ) : this( - additionalInfo, - cost, - gain, - isin, - name, - nav, - nominees, - transactions, - type, - units, - value, - mutableMapOf(), - ) + private var additionalInfo: JsonField = JsonMissing.of() + private var amc: JsonField = JsonMissing.of() + private var folioNumber: JsonField = JsonMissing.of() + private var linkedHolders: JsonField>? = null + private var registrar: JsonField = JsonMissing.of() + private var schemes: JsonField>? = null + private var value: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() - /** - * Additional information specific to the scheme - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun additionalInfo(): Optional = - additionalInfo.getOptional("additional_info") + @JvmSynthetic + internal fun from(mutualFund: MutualFund) = apply { + additionalInfo = mutualFund.additionalInfo + amc = mutualFund.amc + folioNumber = mutualFund.folioNumber + linkedHolders = mutualFund.linkedHolders.map { it.toMutableList() } + registrar = mutualFund.registrar + schemes = mutualFund.schemes.map { it.toMutableList() } + value = mutualFund.value + additionalProperties = mutualFund.additionalProperties.toMutableMap() + } + + /** Additional folio information */ + fun additionalInfo(additionalInfo: AdditionalInfo) = + additionalInfo(JsonField.of(additionalInfo)) /** - * Cost of investment + * Sets [Builder.additionalInfo] to an arbitrary JSON value. * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). + * You should usually call [Builder.additionalInfo] with a well-typed [AdditionalInfo] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. */ - fun cost(): Optional = cost.getOptional("cost") + fun additionalInfo(additionalInfo: JsonField) = apply { + this.additionalInfo = additionalInfo + } - /** - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun gain(): Optional = gain.getOptional("gain") + /** Asset Management Company name */ + fun amc(amc: String) = amc(JsonField.of(amc)) /** - * ISIN code of the scheme + * Sets [Builder.amc] to an arbitrary JSON value. * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). + * You should usually call [Builder.amc] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. */ - fun isin(): Optional = isin.getOptional("isin") + fun amc(amc: JsonField) = apply { this.amc = amc } + + /** Folio number */ + fun folioNumber(folioNumber: String) = folioNumber(JsonField.of(folioNumber)) /** - * Scheme name + * Sets [Builder.folioNumber] to an arbitrary JSON value. * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). + * You should usually call [Builder.folioNumber] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - fun name(): Optional = name.getOptional("name") + fun folioNumber(folioNumber: JsonField) = apply { + this.folioNumber = folioNumber + } + + /** List of account holders linked to this mutual fund folio */ + fun linkedHolders(linkedHolders: List) = + linkedHolders(JsonField.of(linkedHolders)) /** - * Net Asset Value per unit + * Sets [Builder.linkedHolders] to an arbitrary JSON value. * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). + * You should usually call [Builder.linkedHolders] with a well-typed + * `List` value instead. This method is primarily for setting the field to + * an undocumented or not yet supported value. */ - fun nav(): Optional = nav.getOptional("nav") + fun linkedHolders(linkedHolders: JsonField>) = apply { + this.linkedHolders = linkedHolders.map { it.toMutableList() } + } /** - * List of nominees + * Adds a single [LinkedHolder] to [linkedHolders]. * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). + * @throws IllegalStateException if the field was previously set to a non-list. */ - fun nominees(): Optional> = nominees.getOptional("nominees") + fun addLinkedHolder(linkedHolder: LinkedHolder) = apply { + linkedHolders = + (linkedHolders ?: JsonField.of(mutableListOf())).also { + checkKnown("linkedHolders", it).add(linkedHolder) + } + } - /** - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun transactions(): Optional> = - transactions.getOptional("transactions") + /** Registrar and Transfer Agent name */ + fun registrar(registrar: String) = registrar(JsonField.of(registrar)) /** - * Type of mutual fund scheme + * Sets [Builder.registrar] to an arbitrary JSON value. * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). + * You should usually call [Builder.registrar] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - fun type(): Optional = type.getOptional("type") + fun registrar(registrar: JsonField) = apply { this.registrar = registrar } - /** - * Number of units held - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun units(): Optional = units.getOptional("units") + fun schemes(schemes: List) = schemes(JsonField.of(schemes)) /** - * Current market value of the holding + * Sets [Builder.schemes] to an arbitrary JSON value. * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). + * You should usually call [Builder.schemes] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - fun value(): Optional = value.getOptional("value") + fun schemes(schemes: JsonField>) = apply { + this.schemes = schemes.map { it.toMutableList() } + } /** - * Returns the raw JSON value of [additionalInfo]. + * Adds a single [Scheme] to [schemes]. * - * Unlike [additionalInfo], this method doesn't throw if the JSON field has an - * unexpected type. + * @throws IllegalStateException if the field was previously set to a non-list. */ - @JsonProperty("additional_info") - @ExcludeMissing - fun _additionalInfo(): JsonField = additionalInfo + fun addScheme(scheme: Scheme) = apply { + schemes = + (schemes ?: JsonField.of(mutableListOf())).also { + checkKnown("schemes", it).add(scheme) + } + } + + /** Total value of the folio */ + fun value(value: Float) = value(JsonField.of(value)) /** - * Returns the raw JSON value of [cost]. + * Sets [Builder.value] to an arbitrary JSON value. * - * Unlike [cost], this method doesn't throw if the JSON field has an unexpected type. + * You should usually call [Builder.value] with a well-typed [Float] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. */ - @JsonProperty("cost") @ExcludeMissing fun _cost(): JsonField = cost + fun value(value: JsonField) = apply { this.value = value } + + 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 the raw JSON value of [gain]. + * Returns an immutable instance of [MutualFund]. * - * Unlike [gain], this method doesn't throw if the JSON field has an unexpected type. + * Further updates to this [Builder] will not mutate the returned instance. */ - @JsonProperty("gain") @ExcludeMissing fun _gain(): JsonField = gain + fun build(): MutualFund = + MutualFund( + additionalInfo, + amc, + folioNumber, + (linkedHolders ?: JsonMissing.of()).map { it.toImmutable() }, + registrar, + (schemes ?: JsonMissing.of()).map { it.toImmutable() }, + value, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): MutualFund = apply { + if (validated) { + return@apply + } + + additionalInfo().ifPresent { it.validate() } + amc() + folioNumber() + linkedHolders().ifPresent { it.forEach { it.validate() } } + registrar() + schemes().ifPresent { it.forEach { it.validate() } } + value() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 = + (additionalInfo.asKnown().getOrNull()?.validity() ?: 0) + + (if (amc.asKnown().isPresent) 1 else 0) + + (if (folioNumber.asKnown().isPresent) 1 else 0) + + (linkedHolders.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (registrar.asKnown().isPresent) 1 else 0) + + (schemes.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (value.asKnown().isPresent) 1 else 0) - /** - * Returns the raw JSON value of [isin]. - * - * Unlike [isin], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("isin") @ExcludeMissing fun _isin(): JsonField = isin + /** Additional folio information */ + class AdditionalInfo + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val kyc: JsonField, + private val pan: JsonField, + private val pankyc: JsonField, + private val additionalProperties: MutableMap, + ) { - /** - * Returns the raw JSON value of [name]. - * - * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + @JsonCreator + private constructor( + @JsonProperty("kyc") @ExcludeMissing kyc: JsonField = JsonMissing.of(), + @JsonProperty("pan") @ExcludeMissing pan: JsonField = JsonMissing.of(), + @JsonProperty("pankyc") @ExcludeMissing pankyc: JsonField = JsonMissing.of(), + ) : this(kyc, pan, pankyc, mutableMapOf()) /** - * Returns the raw JSON value of [nav]. + * KYC status of the folio * - * Unlike [nav], this method doesn't throw if the JSON field has an unexpected type. + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). */ - @JsonProperty("nav") @ExcludeMissing fun _nav(): JsonField = nav + fun kyc(): Optional = kyc.getOptional("kyc") /** - * Returns the raw JSON value of [nominees]. + * PAN associated with the folio * - * Unlike [nominees], this method doesn't throw if the JSON field has an unexpected - * type. + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). */ - @JsonProperty("nominees") - @ExcludeMissing - fun _nominees(): JsonField> = nominees + fun pan(): Optional = pan.getOptional("pan") /** - * Returns the raw JSON value of [transactions]. + * PAN KYC status * - * Unlike [transactions], this method doesn't throw if the JSON field has an unexpected - * type. + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). */ - @JsonProperty("transactions") - @ExcludeMissing - fun _transactions(): JsonField> = transactions + fun pankyc(): Optional = pankyc.getOptional("pankyc") /** - * Returns the raw JSON value of [type]. + * Returns the raw JSON value of [kyc]. * - * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [kyc], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + @JsonProperty("kyc") @ExcludeMissing fun _kyc(): JsonField = kyc /** - * Returns the raw JSON value of [units]. + * Returns the raw JSON value of [pan]. * - * Unlike [units], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [pan], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("units") @ExcludeMissing fun _units(): JsonField = units + @JsonProperty("pan") @ExcludeMissing fun _pan(): JsonField = pan /** - * Returns the raw JSON value of [value]. + * Returns the raw JSON value of [pankyc]. * - * Unlike [value], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [pankyc], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("value") @ExcludeMissing fun _value(): JsonField = value + @JsonProperty("pankyc") @ExcludeMissing fun _pankyc(): JsonField = pankyc @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { @@ -13703,203 +6929,61 @@ private constructor( companion object { - /** Returns a mutable builder for constructing an instance of [Scheme]. */ + /** Returns a mutable builder for constructing an instance of [AdditionalInfo]. */ @JvmStatic fun builder() = Builder() } - /** A builder for [Scheme]. */ + /** A builder for [AdditionalInfo]. */ class Builder internal constructor() { - private var additionalInfo: JsonField = JsonMissing.of() - private var cost: JsonField = JsonMissing.of() - private var gain: JsonField = JsonMissing.of() - private var isin: JsonField = JsonMissing.of() - private var name: JsonField = JsonMissing.of() - private var nav: JsonField = JsonMissing.of() - private var nominees: JsonField>? = null - private var transactions: JsonField>? = null - private var type: JsonField = JsonMissing.of() - private var units: JsonField = JsonMissing.of() - private var value: JsonField = JsonMissing.of() + private var kyc: JsonField = JsonMissing.of() + private var pan: JsonField = JsonMissing.of() + private var pankyc: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(scheme: Scheme) = apply { - additionalInfo = scheme.additionalInfo - cost = scheme.cost - gain = scheme.gain - isin = scheme.isin - name = scheme.name - nav = scheme.nav - nominees = scheme.nominees.map { it.toMutableList() } - transactions = scheme.transactions.map { it.toMutableList() } - type = scheme.type - units = scheme.units - value = scheme.value - additionalProperties = scheme.additionalProperties.toMutableMap() - } - - /** Additional information specific to the scheme */ - fun additionalInfo(additionalInfo: AdditionalInfo) = - additionalInfo(JsonField.of(additionalInfo)) - - /** - * Sets [Builder.additionalInfo] to an arbitrary JSON value. - * - * You should usually call [Builder.additionalInfo] with a well-typed - * [AdditionalInfo] value instead. This method is primarily for setting the field to - * an undocumented or not yet supported value. - */ - fun additionalInfo(additionalInfo: JsonField) = apply { - this.additionalInfo = additionalInfo - } - - /** Cost of investment */ - fun cost(cost: Float) = cost(JsonField.of(cost)) - - /** - * Sets [Builder.cost] to an arbitrary JSON value. - * - * You should usually call [Builder.cost] with a well-typed [Float] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun cost(cost: JsonField) = apply { this.cost = cost } - - fun gain(gain: Gain) = gain(JsonField.of(gain)) - - /** - * Sets [Builder.gain] to an arbitrary JSON value. - * - * You should usually call [Builder.gain] with a well-typed [Gain] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun gain(gain: JsonField) = apply { this.gain = gain } - - /** ISIN code of the scheme */ - fun isin(isin: String) = isin(JsonField.of(isin)) - - /** - * Sets [Builder.isin] to an arbitrary JSON value. - * - * You should usually call [Builder.isin] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun isin(isin: JsonField) = apply { this.isin = isin } - - /** Scheme name */ - fun name(name: String) = name(JsonField.of(name)) - - /** - * Sets [Builder.name] to an arbitrary JSON value. - * - * You should usually call [Builder.name] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun name(name: JsonField) = apply { this.name = name } - - /** Net Asset Value per unit */ - fun nav(nav: Float) = nav(JsonField.of(nav)) - - /** - * Sets [Builder.nav] to an arbitrary JSON value. - * - * You should usually call [Builder.nav] with a well-typed [Float] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun nav(nav: JsonField) = apply { this.nav = nav } - - /** List of nominees */ - fun nominees(nominees: List) = nominees(JsonField.of(nominees)) - - /** - * Sets [Builder.nominees] to an arbitrary JSON value. - * - * You should usually call [Builder.nominees] with a well-typed `List` value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. - */ - fun nominees(nominees: JsonField>) = apply { - this.nominees = nominees.map { it.toMutableList() } - } - - /** - * Adds a single [String] to [nominees]. - * - * @throws IllegalStateException if the field was previously set to a non-list. - */ - fun addNominee(nominee: String) = apply { - nominees = - (nominees ?: JsonField.of(mutableListOf())).also { - checkKnown("nominees", it).add(nominee) - } - } - - fun transactions(transactions: List) = - transactions(JsonField.of(transactions)) - - /** - * Sets [Builder.transactions] to an arbitrary JSON value. - * - * You should usually call [Builder.transactions] with a well-typed - * `List` value instead. This method is primarily for setting the field - * to an undocumented or not yet supported value. - */ - fun transactions(transactions: JsonField>) = apply { - this.transactions = transactions.map { it.toMutableList() } - } - - /** - * Adds a single [Transaction] to [transactions]. - * - * @throws IllegalStateException if the field was previously set to a non-list. - */ - fun addTransaction(transaction: Transaction) = apply { - transactions = - (transactions ?: JsonField.of(mutableListOf())).also { - checkKnown("transactions", it).add(transaction) - } + internal fun from(additionalInfo: AdditionalInfo) = apply { + kyc = additionalInfo.kyc + pan = additionalInfo.pan + pankyc = additionalInfo.pankyc + additionalProperties = additionalInfo.additionalProperties.toMutableMap() } - /** Type of mutual fund scheme */ - fun type(type: Type) = type(JsonField.of(type)) + /** KYC status of the folio */ + fun kyc(kyc: String) = kyc(JsonField.of(kyc)) /** - * Sets [Builder.type] to an arbitrary JSON value. + * Sets [Builder.kyc] to an arbitrary JSON value. * - * You should usually call [Builder.type] with a well-typed [Type] value instead. + * You should usually call [Builder.kyc] with a well-typed [String] value instead. * This method is primarily for setting the field to an undocumented or not yet * supported value. */ - fun type(type: JsonField) = apply { this.type = type } + fun kyc(kyc: JsonField) = apply { this.kyc = kyc } - /** Number of units held */ - fun units(units: Float) = units(JsonField.of(units)) + /** PAN associated with the folio */ + fun pan(pan: String) = pan(JsonField.of(pan)) /** - * Sets [Builder.units] to an arbitrary JSON value. + * Sets [Builder.pan] to an arbitrary JSON value. * - * You should usually call [Builder.units] with a well-typed [Float] value instead. + * You should usually call [Builder.pan] with a well-typed [String] value instead. * This method is primarily for setting the field to an undocumented or not yet * supported value. */ - fun units(units: JsonField) = apply { this.units = units } + fun pan(pan: JsonField) = apply { this.pan = pan } - /** Current market value of the holding */ - fun value(value: Float) = value(JsonField.of(value)) + /** PAN KYC status */ + fun pankyc(pankyc: String) = pankyc(JsonField.of(pankyc)) /** - * Sets [Builder.value] to an arbitrary JSON value. + * Sets [Builder.pankyc] to an arbitrary JSON value. * - * You should usually call [Builder.value] with a well-typed [Float] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. + * You should usually call [Builder.pankyc] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. */ - fun value(value: JsonField) = apply { this.value = value } + fun pankyc(pankyc: JsonField) = apply { this.pankyc = pankyc } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() @@ -13924,45 +7008,24 @@ private constructor( } /** - * Returns an immutable instance of [Scheme]. + * Returns an immutable instance of [AdditionalInfo]. * * Further updates to this [Builder] will not mutate the returned instance. */ - fun build(): Scheme = - Scheme( - additionalInfo, - cost, - gain, - isin, - name, - nav, - (nominees ?: JsonMissing.of()).map { it.toImmutable() }, - (transactions ?: JsonMissing.of()).map { it.toImmutable() }, - type, - units, - value, - additionalProperties.toMutableMap(), - ) + fun build(): AdditionalInfo = + AdditionalInfo(kyc, pan, pankyc, additionalProperties.toMutableMap()) } private var validated: Boolean = false - fun validate(): Scheme = apply { + fun validate(): AdditionalInfo = apply { if (validated) { return@apply } - additionalInfo().ifPresent { it.validate() } - cost() - gain().ifPresent { it.validate() } - isin() - name() - nav() - nominees() - transactions().ifPresent { it.forEach { it.validate() } } - type().ifPresent { it.validate() } - units() - value() + kyc() + pan() + pankyc() validated = true } @@ -13982,1742 +7045,1101 @@ private constructor( */ @JvmSynthetic internal fun validity(): Int = - (additionalInfo.asKnown().getOrNull()?.validity() ?: 0) + - (if (cost.asKnown().isPresent) 1 else 0) + - (gain.asKnown().getOrNull()?.validity() ?: 0) + - (if (isin.asKnown().isPresent) 1 else 0) + - (if (name.asKnown().isPresent) 1 else 0) + - (if (nav.asKnown().isPresent) 1 else 0) + - (nominees.asKnown().getOrNull()?.size ?: 0) + - (transactions.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + - (type.asKnown().getOrNull()?.validity() ?: 0) + - (if (units.asKnown().isPresent) 1 else 0) + - (if (value.asKnown().isPresent) 1 else 0) - - /** Additional information specific to the scheme */ - class AdditionalInfo - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val advisor: JsonField, - private val amfi: JsonField, - private val closeUnits: JsonField, - private val openUnits: JsonField, - private val rtaCode: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("advisor") - @ExcludeMissing - advisor: JsonField = JsonMissing.of(), - @JsonProperty("amfi") - @ExcludeMissing - amfi: JsonField = JsonMissing.of(), - @JsonProperty("close_units") - @ExcludeMissing - closeUnits: JsonField = JsonMissing.of(), - @JsonProperty("open_units") - @ExcludeMissing - openUnits: JsonField = JsonMissing.of(), - @JsonProperty("rta_code") - @ExcludeMissing - rtaCode: JsonField = JsonMissing.of(), - ) : this(advisor, amfi, closeUnits, openUnits, rtaCode, mutableMapOf()) - - /** - * Financial advisor name (CAMS/KFintech) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun advisor(): Optional = advisor.getOptional("advisor") - - /** - * AMFI code for the scheme (CAMS/KFintech) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun amfi(): Optional = amfi.getOptional("amfi") + (if (kyc.asKnown().isPresent) 1 else 0) + + (if (pan.asKnown().isPresent) 1 else 0) + + (if (pankyc.asKnown().isPresent) 1 else 0) - /** - * Closing balance units for the statement period - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun closeUnits(): Optional = closeUnits.getOptional("close_units") + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - /** - * Opening balance units for the statement period - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun openUnits(): Optional = openUnits.getOptional("open_units") + return other is AdditionalInfo && + kyc == other.kyc && + pan == other.pan && + pankyc == other.pankyc && + additionalProperties == other.additionalProperties + } - /** - * RTA code for the scheme (CAMS/KFintech) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun rtaCode(): Optional = rtaCode.getOptional("rta_code") + private val hashCode: Int by lazy { + Objects.hash(kyc, pan, pankyc, additionalProperties) + } - /** - * Returns the raw JSON value of [advisor]. - * - * Unlike [advisor], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("advisor") @ExcludeMissing fun _advisor(): JsonField = advisor + override fun hashCode(): Int = hashCode - /** - * Returns the raw JSON value of [amfi]. - * - * Unlike [amfi], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("amfi") @ExcludeMissing fun _amfi(): JsonField = amfi + override fun toString() = + "AdditionalInfo{kyc=$kyc, pan=$pan, pankyc=$pankyc, additionalProperties=$additionalProperties}" + } - /** - * Returns the raw JSON value of [closeUnits]. - * - * Unlike [closeUnits], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("close_units") - @ExcludeMissing - fun _closeUnits(): JsonField = closeUnits + class Scheme + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val additionalInfo: JsonField, + private val cost: JsonField, + private val gain: JsonField, + private val isin: JsonField, + private val name: JsonField, + private val nav: JsonField, + private val nominees: JsonField>, + private val transactions: JsonField>, + private val type: JsonField, + private val units: JsonField, + private val value: JsonField, + private val additionalProperties: MutableMap, + ) { - /** - * Returns the raw JSON value of [openUnits]. - * - * Unlike [openUnits], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("open_units") + @JsonCreator + private constructor( + @JsonProperty("additional_info") @ExcludeMissing - fun _openUnits(): JsonField = openUnits - - /** - * Returns the raw JSON value of [rtaCode]. - * - * Unlike [rtaCode], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("rta_code") + additionalInfo: JsonField = JsonMissing.of(), + @JsonProperty("cost") @ExcludeMissing cost: JsonField = JsonMissing.of(), + @JsonProperty("gain") @ExcludeMissing gain: JsonField = JsonMissing.of(), + @JsonProperty("isin") @ExcludeMissing isin: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("nav") @ExcludeMissing nav: JsonField = JsonMissing.of(), + @JsonProperty("nominees") @ExcludeMissing - fun _rtaCode(): JsonField = rtaCode - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter + nominees: JsonField> = JsonMissing.of(), + @JsonProperty("transactions") @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) + transactions: JsonField> = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), + @JsonProperty("units") @ExcludeMissing units: JsonField = JsonMissing.of(), + @JsonProperty("value") @ExcludeMissing value: JsonField = JsonMissing.of(), + ) : this( + additionalInfo, + cost, + gain, + isin, + name, + nav, + nominees, + transactions, + type, + units, + value, + mutableMapOf(), + ) - fun toBuilder() = Builder().from(this) + /** + * Additional information specific to the scheme + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun additionalInfo(): Optional = + additionalInfo.getOptional("additional_info") - companion object { + /** + * Cost of investment + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun cost(): Optional = cost.getOptional("cost") - /** - * Returns a mutable builder for constructing an instance of [AdditionalInfo]. - */ - @JvmStatic fun builder() = Builder() - } + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun gain(): Optional = gain.getOptional("gain") - /** A builder for [AdditionalInfo]. */ - class Builder internal constructor() { + /** + * ISIN code of the scheme + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun isin(): Optional = isin.getOptional("isin") - private var advisor: JsonField = JsonMissing.of() - private var amfi: JsonField = JsonMissing.of() - private var closeUnits: JsonField = JsonMissing.of() - private var openUnits: JsonField = JsonMissing.of() - private var rtaCode: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() + /** + * Scheme name + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun name(): Optional = name.getOptional("name") - @JvmSynthetic - internal fun from(additionalInfo: AdditionalInfo) = apply { - advisor = additionalInfo.advisor - amfi = additionalInfo.amfi - closeUnits = additionalInfo.closeUnits - openUnits = additionalInfo.openUnits - rtaCode = additionalInfo.rtaCode - additionalProperties = additionalInfo.additionalProperties.toMutableMap() - } + /** + * Net Asset Value per unit + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun nav(): Optional = nav.getOptional("nav") - /** Financial advisor name (CAMS/KFintech) */ - fun advisor(advisor: String) = advisor(JsonField.of(advisor)) + /** + * List of nominees + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun nominees(): Optional> = nominees.getOptional("nominees") - /** - * Sets [Builder.advisor] to an arbitrary JSON value. - * - * You should usually call [Builder.advisor] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun advisor(advisor: JsonField) = apply { this.advisor = advisor } + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun transactions(): Optional> = + transactions.getOptional("transactions") - /** AMFI code for the scheme (CAMS/KFintech) */ - fun amfi(amfi: String) = amfi(JsonField.of(amfi)) + /** + * Type of mutual fund scheme + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun type(): Optional = type.getOptional("type") - /** - * Sets [Builder.amfi] to an arbitrary JSON value. - * - * You should usually call [Builder.amfi] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun amfi(amfi: JsonField) = apply { this.amfi = amfi } + /** + * Number of units held + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun units(): Optional = units.getOptional("units") - /** Closing balance units for the statement period */ - fun closeUnits(closeUnits: Float?) = - closeUnits(JsonField.ofNullable(closeUnits)) + /** + * Current market value of the holding + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun value(): Optional = value.getOptional("value") - /** - * Alias for [Builder.closeUnits]. - * - * This unboxed primitive overload exists for backwards compatibility. - */ - fun closeUnits(closeUnits: Float) = closeUnits(closeUnits as Float?) + /** + * Returns the raw JSON value of [additionalInfo]. + * + * Unlike [additionalInfo], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("additional_info") + @ExcludeMissing + fun _additionalInfo(): JsonField = additionalInfo - /** Alias for calling [Builder.closeUnits] with `closeUnits.orElse(null)`. */ - fun closeUnits(closeUnits: Optional) = closeUnits(closeUnits.getOrNull()) + /** + * Returns the raw JSON value of [cost]. + * + * Unlike [cost], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("cost") @ExcludeMissing fun _cost(): JsonField = cost - /** - * Sets [Builder.closeUnits] to an arbitrary JSON value. - * - * You should usually call [Builder.closeUnits] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun closeUnits(closeUnits: JsonField) = apply { - this.closeUnits = closeUnits - } + /** + * Returns the raw JSON value of [gain]. + * + * Unlike [gain], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("gain") @ExcludeMissing fun _gain(): JsonField = gain - /** Opening balance units for the statement period */ - fun openUnits(openUnits: Float?) = openUnits(JsonField.ofNullable(openUnits)) + /** + * Returns the raw JSON value of [isin]. + * + * Unlike [isin], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("isin") @ExcludeMissing fun _isin(): JsonField = isin - /** - * Alias for [Builder.openUnits]. - * - * This unboxed primitive overload exists for backwards compatibility. - */ - fun openUnits(openUnits: Float) = openUnits(openUnits as Float?) + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name - /** Alias for calling [Builder.openUnits] with `openUnits.orElse(null)`. */ - fun openUnits(openUnits: Optional) = openUnits(openUnits.getOrNull()) + /** + * Returns the raw JSON value of [nav]. + * + * Unlike [nav], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("nav") @ExcludeMissing fun _nav(): JsonField = nav - /** - * Sets [Builder.openUnits] to an arbitrary JSON value. - * - * You should usually call [Builder.openUnits] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun openUnits(openUnits: JsonField) = apply { - this.openUnits = openUnits - } + /** + * Returns the raw JSON value of [nominees]. + * + * Unlike [nominees], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("nominees") + @ExcludeMissing + fun _nominees(): JsonField> = nominees - /** RTA code for the scheme (CAMS/KFintech) */ - fun rtaCode(rtaCode: String) = rtaCode(JsonField.of(rtaCode)) + /** + * Returns the raw JSON value of [transactions]. + * + * Unlike [transactions], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("transactions") + @ExcludeMissing + fun _transactions(): JsonField> = transactions - /** - * Sets [Builder.rtaCode] to an arbitrary JSON value. - * - * You should usually call [Builder.rtaCode] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun rtaCode(rtaCode: JsonField) = apply { this.rtaCode = rtaCode } + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } + /** + * Returns the raw JSON value of [units]. + * + * Unlike [units], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("units") @ExcludeMissing fun _units(): JsonField = units - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } + /** + * Returns the raw JSON value of [value]. + * + * Unlike [value], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("value") @ExcludeMissing fun _value(): JsonField = value + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) - } + fun toBuilder() = Builder().from(this) - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } + companion object { - /** - * Returns an immutable instance of [AdditionalInfo]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): AdditionalInfo = - AdditionalInfo( - advisor, - amfi, - closeUnits, - openUnits, - rtaCode, - additionalProperties.toMutableMap(), - ) - } + /** Returns a mutable builder for constructing an instance of [Scheme]. */ + @JvmStatic fun builder() = Builder() + } - private var validated: Boolean = false + /** A builder for [Scheme]. */ + class Builder internal constructor() { - fun validate(): AdditionalInfo = apply { - if (validated) { - return@apply - } + private var additionalInfo: JsonField = JsonMissing.of() + private var cost: JsonField = JsonMissing.of() + private var gain: JsonField = JsonMissing.of() + private var isin: JsonField = JsonMissing.of() + private var name: JsonField = JsonMissing.of() + private var nav: JsonField = JsonMissing.of() + private var nominees: JsonField>? = null + private var transactions: JsonField>? = null + private var type: JsonField = JsonMissing.of() + private var units: JsonField = JsonMissing.of() + private var value: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() - advisor() - amfi() - closeUnits() - openUnits() - rtaCode() - validated = true + @JvmSynthetic + internal fun from(scheme: Scheme) = apply { + additionalInfo = scheme.additionalInfo + cost = scheme.cost + gain = scheme.gain + isin = scheme.isin + name = scheme.name + nav = scheme.nav + nominees = scheme.nominees.map { it.toMutableList() } + transactions = scheme.transactions.map { it.toMutableList() } + type = scheme.type + units = scheme.units + value = scheme.value + additionalProperties = scheme.additionalProperties.toMutableMap() } - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - false - } + /** Additional information specific to the scheme */ + fun additionalInfo(additionalInfo: AdditionalInfo) = + additionalInfo(JsonField.of(additionalInfo)) /** - * Returns a score indicating how many valid values are contained in this object - * recursively. + * Sets [Builder.additionalInfo] to an arbitrary JSON value. * - * Used for best match union deserialization. + * You should usually call [Builder.additionalInfo] with a well-typed + * [AdditionalInfo] value instead. This method is primarily for setting the field to + * an undocumented or not yet supported value. */ - @JvmSynthetic - internal fun validity(): Int = - (if (advisor.asKnown().isPresent) 1 else 0) + - (if (amfi.asKnown().isPresent) 1 else 0) + - (if (closeUnits.asKnown().isPresent) 1 else 0) + - (if (openUnits.asKnown().isPresent) 1 else 0) + - (if (rtaCode.asKnown().isPresent) 1 else 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is AdditionalInfo && - advisor == other.advisor && - amfi == other.amfi && - closeUnits == other.closeUnits && - openUnits == other.openUnits && - rtaCode == other.rtaCode && - additionalProperties == other.additionalProperties + fun additionalInfo(additionalInfo: JsonField) = apply { + this.additionalInfo = additionalInfo } - private val hashCode: Int by lazy { - Objects.hash( - advisor, - amfi, - closeUnits, - openUnits, - rtaCode, - additionalProperties, - ) - } + /** Cost of investment */ + fun cost(cost: Float) = cost(JsonField.of(cost)) - override fun hashCode(): Int = hashCode + /** + * Sets [Builder.cost] to an arbitrary JSON value. + * + * You should usually call [Builder.cost] with a well-typed [Float] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun cost(cost: JsonField) = apply { this.cost = cost } - override fun toString() = - "AdditionalInfo{advisor=$advisor, amfi=$amfi, closeUnits=$closeUnits, openUnits=$openUnits, rtaCode=$rtaCode, additionalProperties=$additionalProperties}" - } + fun gain(gain: Gain) = gain(JsonField.of(gain)) - class Gain - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val absolute: JsonField, - private val percentage: JsonField, - private val additionalProperties: MutableMap, - ) { + /** + * Sets [Builder.gain] to an arbitrary JSON value. + * + * You should usually call [Builder.gain] with a well-typed [Gain] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun gain(gain: JsonField) = apply { this.gain = gain } - @JsonCreator - private constructor( - @JsonProperty("absolute") - @ExcludeMissing - absolute: JsonField = JsonMissing.of(), - @JsonProperty("percentage") - @ExcludeMissing - percentage: JsonField = JsonMissing.of(), - ) : this(absolute, percentage, mutableMapOf()) + /** ISIN code of the scheme */ + fun isin(isin: String) = isin(JsonField.of(isin)) /** - * Absolute gain or loss + * Sets [Builder.isin] to an arbitrary JSON value. * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). + * You should usually call [Builder.isin] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - fun absolute(): Optional = absolute.getOptional("absolute") + fun isin(isin: JsonField) = apply { this.isin = isin } + + /** Scheme name */ + fun name(name: String) = name(JsonField.of(name)) /** - * Percentage gain or loss + * Sets [Builder.name] to an arbitrary JSON value. * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). + * You should usually call [Builder.name] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - fun percentage(): Optional = percentage.getOptional("percentage") + fun name(name: JsonField) = apply { this.name = name } + + /** Net Asset Value per unit */ + fun nav(nav: Float) = nav(JsonField.of(nav)) /** - * Returns the raw JSON value of [absolute]. + * Sets [Builder.nav] to an arbitrary JSON value. * - * Unlike [absolute], this method doesn't throw if the JSON field has an unexpected - * type. + * You should usually call [Builder.nav] with a well-typed [Float] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - @JsonProperty("absolute") - @ExcludeMissing - fun _absolute(): JsonField = absolute + fun nav(nav: JsonField) = apply { this.nav = nav } + + /** List of nominees */ + fun nominees(nominees: List) = nominees(JsonField.of(nominees)) /** - * Returns the raw JSON value of [percentage]. + * Sets [Builder.nominees] to an arbitrary JSON value. * - * Unlike [percentage], this method doesn't throw if the JSON field has an - * unexpected type. + * You should usually call [Builder.nominees] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. */ - @JsonProperty("percentage") - @ExcludeMissing - fun _percentage(): JsonField = percentage - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) + fun nominees(nominees: JsonField>) = apply { + this.nominees = nominees.map { it.toMutableList() } } - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** Returns a mutable builder for constructing an instance of [Gain]. */ - @JvmStatic fun builder() = Builder() + /** + * Adds a single [String] to [nominees]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addNominee(nominee: String) = apply { + nominees = + (nominees ?: JsonField.of(mutableListOf())).also { + checkKnown("nominees", it).add(nominee) + } } - /** A builder for [Gain]. */ - class Builder internal constructor() { - - private var absolute: JsonField = JsonMissing.of() - private var percentage: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(gain: Gain) = apply { - absolute = gain.absolute - percentage = gain.percentage - additionalProperties = gain.additionalProperties.toMutableMap() - } - - /** Absolute gain or loss */ - fun absolute(absolute: Float) = absolute(JsonField.of(absolute)) - - /** - * Sets [Builder.absolute] to an arbitrary JSON value. - * - * You should usually call [Builder.absolute] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun absolute(absolute: JsonField) = apply { this.absolute = absolute } + fun transactions(transactions: List) = + transactions(JsonField.of(transactions)) - /** Percentage gain or loss */ - fun percentage(percentage: Float) = percentage(JsonField.of(percentage)) + /** + * Sets [Builder.transactions] to an arbitrary JSON value. + * + * You should usually call [Builder.transactions] with a well-typed + * `List` value instead. This method is primarily for setting the field + * to an undocumented or not yet supported value. + */ + fun transactions(transactions: JsonField>) = apply { + this.transactions = transactions.map { it.toMutableList() } + } - /** - * Sets [Builder.percentage] to an arbitrary JSON value. - * - * You should usually call [Builder.percentage] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun percentage(percentage: JsonField) = apply { - this.percentage = percentage - } + /** + * Adds a single [Transaction] to [transactions]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addTransaction(transaction: Transaction) = apply { + transactions = + (transactions ?: JsonField.of(mutableListOf())).also { + checkKnown("transactions", it).add(transaction) + } + } - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } + /** Type of mutual fund scheme */ + fun type(type: Type) = type(JsonField.of(type)) - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonField) = apply { this.type = type } - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } + /** Number of units held */ + fun units(units: Float) = units(JsonField.of(units)) - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) - } + /** + * Sets [Builder.units] to an arbitrary JSON value. + * + * You should usually call [Builder.units] with a well-typed [Float] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun units(units: JsonField) = apply { this.units = units } - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } + /** Current market value of the holding */ + fun value(value: Float) = value(JsonField.of(value)) - /** - * Returns an immutable instance of [Gain]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): Gain = - Gain(absolute, percentage, additionalProperties.toMutableMap()) + /** + * Sets [Builder.value] to an arbitrary JSON value. + * + * You should usually call [Builder.value] with a well-typed [Float] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun value(value: JsonField) = apply { this.value = value } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) } - private var validated: Boolean = false + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } - fun validate(): Gain = apply { - if (validated) { - return@apply + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) } - absolute() - percentage() - validated = true + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) } - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - false - } + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } /** - * Returns a score indicating how many valid values are contained in this object - * recursively. + * Returns an immutable instance of [Scheme]. * - * Used for best match union deserialization. + * Further updates to this [Builder] will not mutate the returned instance. */ - @JvmSynthetic - internal fun validity(): Int = - (if (absolute.asKnown().isPresent) 1 else 0) + - (if (percentage.asKnown().isPresent) 1 else 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + fun build(): Scheme = + Scheme( + additionalInfo, + cost, + gain, + isin, + name, + nav, + (nominees ?: JsonMissing.of()).map { it.toImmutable() }, + (transactions ?: JsonMissing.of()).map { it.toImmutable() }, + type, + units, + value, + additionalProperties.toMutableMap(), + ) + } - return other is Gain && - absolute == other.absolute && - percentage == other.percentage && - additionalProperties == other.additionalProperties - } + private var validated: Boolean = false - private val hashCode: Int by lazy { - Objects.hash(absolute, percentage, additionalProperties) + fun validate(): Scheme = apply { + if (validated) { + return@apply } - override fun hashCode(): Int = hashCode - - override fun toString() = - "Gain{absolute=$absolute, percentage=$percentage, additionalProperties=$additionalProperties}" + additionalInfo().ifPresent { it.validate() } + cost() + gain().ifPresent { it.validate() } + isin() + name() + nav() + nominees() + transactions().ifPresent { it.forEach { it.validate() } } + type().ifPresent { it.validate() } + units() + value() + validated = true } + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + false + } + /** - * Unified transaction schema for all holding types (MF folios, equities, bonds, etc.) + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. */ - class Transaction + @JvmSynthetic + internal fun validity(): Int = + (additionalInfo.asKnown().getOrNull()?.validity() ?: 0) + + (if (cost.asKnown().isPresent) 1 else 0) + + (gain.asKnown().getOrNull()?.validity() ?: 0) + + (if (isin.asKnown().isPresent) 1 else 0) + + (if (name.asKnown().isPresent) 1 else 0) + + (if (nav.asKnown().isPresent) 1 else 0) + + (nominees.asKnown().getOrNull()?.size ?: 0) + + (transactions.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (type.asKnown().getOrNull()?.validity() ?: 0) + + (if (units.asKnown().isPresent) 1 else 0) + + (if (value.asKnown().isPresent) 1 else 0) + + /** Additional information specific to the scheme */ + class AdditionalInfo @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( - private val additionalInfo: JsonField, - private val amount: JsonField, - private val balance: JsonField, - private val date: JsonField, - private val description: JsonField, - private val dividendRate: JsonField, - private val nav: JsonField, - private val type: JsonField, - private val units: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("additional_info") - @ExcludeMissing - additionalInfo: JsonField = JsonMissing.of(), - @JsonProperty("amount") - @ExcludeMissing - amount: JsonField = JsonMissing.of(), - @JsonProperty("balance") - @ExcludeMissing - balance: JsonField = JsonMissing.of(), - @JsonProperty("date") - @ExcludeMissing - date: JsonField = JsonMissing.of(), - @JsonProperty("description") - @ExcludeMissing - description: JsonField = JsonMissing.of(), - @JsonProperty("dividend_rate") - @ExcludeMissing - dividendRate: JsonField = JsonMissing.of(), - @JsonProperty("nav") @ExcludeMissing nav: JsonField = JsonMissing.of(), - @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), - @JsonProperty("units") - @ExcludeMissing - units: JsonField = JsonMissing.of(), - ) : this( - additionalInfo, - amount, - balance, - date, - description, - dividendRate, - nav, - type, - units, - mutableMapOf(), - ) - - /** - * Additional transaction-specific fields that vary by source - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun additionalInfo(): Optional = - additionalInfo.getOptional("additional_info") - - /** - * Transaction amount in currency (computed from units × price/NAV) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun amount(): Optional = amount.getOptional("amount") - - /** - * Balance units after transaction - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun balance(): Optional = balance.getOptional("balance") + private val advisor: JsonField, + private val amfi: JsonField, + private val closeUnits: JsonField, + private val openUnits: JsonField, + private val rtaCode: JsonField, + private val additionalProperties: MutableMap, + ) { - /** - * Transaction date (YYYY-MM-DD) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type - * (e.g. if the server responded with an unexpected value). - */ - fun date(): Optional = date.getOptional("date") + @JsonCreator + private constructor( + @JsonProperty("advisor") + @ExcludeMissing + advisor: JsonField = JsonMissing.of(), + @JsonProperty("amfi") + @ExcludeMissing + amfi: JsonField = JsonMissing.of(), + @JsonProperty("close_units") + @ExcludeMissing + closeUnits: JsonField = JsonMissing.of(), + @JsonProperty("open_units") + @ExcludeMissing + openUnits: JsonField = JsonMissing.of(), + @JsonProperty("rta_code") + @ExcludeMissing + rtaCode: JsonField = JsonMissing.of(), + ) : this(advisor, amfi, closeUnits, openUnits, rtaCode, mutableMapOf()) /** - * Transaction description/particulars + * Financial advisor name (CAMS/KFintech) * * @throws CasParserInvalidDataException if the JSON field has an unexpected type * (e.g. if the server responded with an unexpected value). */ - fun description(): Optional = description.getOptional("description") + fun advisor(): Optional = advisor.getOptional("advisor") /** - * Dividend rate (for DIVIDEND_PAYOUT transactions) + * AMFI code for the scheme (CAMS/KFintech) * * @throws CasParserInvalidDataException if the JSON field has an unexpected type * (e.g. if the server responded with an unexpected value). */ - fun dividendRate(): Optional = dividendRate.getOptional("dividend_rate") + fun amfi(): Optional = amfi.getOptional("amfi") /** - * NAV/price per unit on transaction date + * Closing balance units for the statement period * * @throws CasParserInvalidDataException if the JSON field has an unexpected type * (e.g. if the server responded with an unexpected value). */ - fun nav(): Optional = nav.getOptional("nav") + fun closeUnits(): Optional = closeUnits.getOptional("close_units") /** - * Transaction type. Possible values are PURCHASE, PURCHASE_SIP, REDEMPTION, - * SWITCH_IN, SWITCH_IN_MERGER, SWITCH_OUT, SWITCH_OUT_MERGER, DIVIDEND_PAYOUT, - * DIVIDEND_REINVEST, SEGREGATION, STAMP_DUTY_TAX, TDS_TAX, STT_TAX, MISC, REVERSAL, - * UNKNOWN. + * Opening balance units for the statement period * * @throws CasParserInvalidDataException if the JSON field has an unexpected type * (e.g. if the server responded with an unexpected value). */ - fun type(): Optional = type.getOptional("type") + fun openUnits(): Optional = openUnits.getOptional("open_units") /** - * Number of units involved in transaction + * RTA code for the scheme (CAMS/KFintech) * * @throws CasParserInvalidDataException if the JSON field has an unexpected type * (e.g. if the server responded with an unexpected value). */ - fun units(): Optional = units.getOptional("units") - - /** - * Returns the raw JSON value of [additionalInfo]. - * - * Unlike [additionalInfo], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("additional_info") - @ExcludeMissing - fun _additionalInfo(): JsonField = additionalInfo - - /** - * Returns the raw JSON value of [amount]. - * - * Unlike [amount], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("amount") @ExcludeMissing fun _amount(): JsonField = amount + fun rtaCode(): Optional = rtaCode.getOptional("rta_code") /** - * Returns the raw JSON value of [balance]. + * Returns the raw JSON value of [advisor]. * - * Unlike [balance], this method doesn't throw if the JSON field has an unexpected + * Unlike [advisor], this method doesn't throw if the JSON field has an unexpected * type. */ - @JsonProperty("balance") @ExcludeMissing fun _balance(): JsonField = balance + @JsonProperty("advisor") @ExcludeMissing fun _advisor(): JsonField = advisor /** - * Returns the raw JSON value of [date]. + * Returns the raw JSON value of [amfi]. * - * Unlike [date], this method doesn't throw if the JSON field has an unexpected + * Unlike [amfi], this method doesn't throw if the JSON field has an unexpected * type. */ - @JsonProperty("date") @ExcludeMissing fun _date(): JsonField = date - - /** - * Returns the raw JSON value of [description]. - * - * Unlike [description], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("description") - @ExcludeMissing - fun _description(): JsonField = description + @JsonProperty("amfi") @ExcludeMissing fun _amfi(): JsonField = amfi /** - * Returns the raw JSON value of [dividendRate]. + * Returns the raw JSON value of [closeUnits]. * - * Unlike [dividendRate], this method doesn't throw if the JSON field has an + * Unlike [closeUnits], this method doesn't throw if the JSON field has an * unexpected type. */ - @JsonProperty("dividend_rate") + @JsonProperty("close_units") @ExcludeMissing - fun _dividendRate(): JsonField = dividendRate - - /** - * Returns the raw JSON value of [nav]. - * - * Unlike [nav], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("nav") @ExcludeMissing fun _nav(): JsonField = nav - - /** - * Returns the raw JSON value of [type]. - * - * Unlike [type], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + fun _closeUnits(): JsonField = closeUnits /** - * Returns the raw JSON value of [units]. - * - * Unlike [units], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("units") @ExcludeMissing fun _units(): JsonField = units - - @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 [Transaction]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Transaction]. */ - class Builder internal constructor() { - - private var additionalInfo: JsonField = JsonMissing.of() - private var amount: JsonField = JsonMissing.of() - private var balance: JsonField = JsonMissing.of() - private var date: JsonField = JsonMissing.of() - private var description: JsonField = JsonMissing.of() - private var dividendRate: JsonField = JsonMissing.of() - private var nav: JsonField = JsonMissing.of() - private var type: JsonField = JsonMissing.of() - private var units: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(transaction: Transaction) = apply { - additionalInfo = transaction.additionalInfo - amount = transaction.amount - balance = transaction.balance - date = transaction.date - description = transaction.description - dividendRate = transaction.dividendRate - nav = transaction.nav - type = transaction.type - units = transaction.units - additionalProperties = transaction.additionalProperties.toMutableMap() - } - - /** Additional transaction-specific fields that vary by source */ - fun additionalInfo(additionalInfo: AdditionalInfo) = - additionalInfo(JsonField.of(additionalInfo)) - - /** - * Sets [Builder.additionalInfo] to an arbitrary JSON value. - * - * You should usually call [Builder.additionalInfo] with a well-typed - * [AdditionalInfo] value instead. This method is primarily for setting the - * field to an undocumented or not yet supported value. - */ - fun additionalInfo(additionalInfo: JsonField) = apply { - this.additionalInfo = additionalInfo - } - - /** Transaction amount in currency (computed from units × price/NAV) */ - fun amount(amount: Float?) = amount(JsonField.ofNullable(amount)) - - /** - * Alias for [Builder.amount]. - * - * This unboxed primitive overload exists for backwards compatibility. - */ - fun amount(amount: Float) = amount(amount as Float?) - - /** Alias for calling [Builder.amount] with `amount.orElse(null)`. */ - fun amount(amount: Optional) = amount(amount.getOrNull()) - - /** - * Sets [Builder.amount] to an arbitrary JSON value. - * - * You should usually call [Builder.amount] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun amount(amount: JsonField) = apply { this.amount = amount } - - /** Balance units after transaction */ - fun balance(balance: Float) = balance(JsonField.of(balance)) - - /** - * Sets [Builder.balance] to an arbitrary JSON value. - * - * You should usually call [Builder.balance] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun balance(balance: JsonField) = apply { this.balance = balance } - - /** Transaction date (YYYY-MM-DD) */ - fun date(date: LocalDate) = date(JsonField.of(date)) - - /** - * Sets [Builder.date] to an arbitrary JSON value. - * - * You should usually call [Builder.date] with a well-typed [LocalDate] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun date(date: JsonField) = apply { this.date = date } - - /** Transaction description/particulars */ - fun description(description: String) = description(JsonField.of(description)) - - /** - * Sets [Builder.description] to an arbitrary JSON value. - * - * You should usually call [Builder.description] with a well-typed [String] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun description(description: JsonField) = apply { - this.description = description - } - - /** Dividend rate (for DIVIDEND_PAYOUT transactions) */ - fun dividendRate(dividendRate: Float?) = - dividendRate(JsonField.ofNullable(dividendRate)) - - /** - * Alias for [Builder.dividendRate]. - * - * This unboxed primitive overload exists for backwards compatibility. - */ - fun dividendRate(dividendRate: Float) = dividendRate(dividendRate as Float?) - - /** - * Alias for calling [Builder.dividendRate] with `dividendRate.orElse(null)`. - */ - fun dividendRate(dividendRate: Optional) = - dividendRate(dividendRate.getOrNull()) - - /** - * Sets [Builder.dividendRate] to an arbitrary JSON value. - * - * You should usually call [Builder.dividendRate] with a well-typed [Float] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun dividendRate(dividendRate: JsonField) = apply { - this.dividendRate = dividendRate - } - - /** NAV/price per unit on transaction date */ - fun nav(nav: Float?) = nav(JsonField.ofNullable(nav)) - - /** - * Alias for [Builder.nav]. - * - * This unboxed primitive overload exists for backwards compatibility. - */ - fun nav(nav: Float) = nav(nav as Float?) - - /** Alias for calling [Builder.nav] with `nav.orElse(null)`. */ - fun nav(nav: Optional) = nav(nav.getOrNull()) - - /** - * Sets [Builder.nav] to an arbitrary JSON value. - * - * You should usually call [Builder.nav] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun nav(nav: JsonField) = apply { this.nav = nav } - - /** - * Transaction type. Possible values are PURCHASE, PURCHASE_SIP, REDEMPTION, - * SWITCH_IN, SWITCH_IN_MERGER, SWITCH_OUT, SWITCH_OUT_MERGER, DIVIDEND_PAYOUT, - * DIVIDEND_REINVEST, SEGREGATION, STAMP_DUTY_TAX, TDS_TAX, STT_TAX, MISC, - * REVERSAL, UNKNOWN. - */ - fun type(type: Type) = type(JsonField.of(type)) - - /** - * Sets [Builder.type] to an arbitrary JSON value. - * - * You should usually call [Builder.type] with a well-typed [Type] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun type(type: JsonField) = apply { this.type = type } - - /** Number of units involved in transaction */ - fun units(units: Float) = units(JsonField.of(units)) - - /** - * Sets [Builder.units] to an arbitrary JSON value. - * - * You should usually call [Builder.units] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun units(units: JsonField) = apply { this.units = units } - - 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 [Transaction]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): Transaction = - Transaction( - additionalInfo, - amount, - balance, - date, - description, - dividendRate, - nav, - type, - units, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): Transaction = apply { - if (validated) { - return@apply - } - - additionalInfo().ifPresent { it.validate() } - amount() - balance() - date() - description() - dividendRate() - nav() - type().ifPresent { it.validate() } - units() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - false - } + * Returns the raw JSON value of [openUnits]. + * + * Unlike [openUnits], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("open_units") + @ExcludeMissing + fun _openUnits(): JsonField = openUnits /** - * Returns a score indicating how many valid values are contained in this object - * recursively. + * Returns the raw JSON value of [rtaCode]. * - * Used for best match union deserialization. + * Unlike [rtaCode], this method doesn't throw if the JSON field has an unexpected + * type. */ - @JvmSynthetic - internal fun validity(): Int = - (additionalInfo.asKnown().getOrNull()?.validity() ?: 0) + - (if (amount.asKnown().isPresent) 1 else 0) + - (if (balance.asKnown().isPresent) 1 else 0) + - (if (date.asKnown().isPresent) 1 else 0) + - (if (description.asKnown().isPresent) 1 else 0) + - (if (dividendRate.asKnown().isPresent) 1 else 0) + - (if (nav.asKnown().isPresent) 1 else 0) + - (type.asKnown().getOrNull()?.validity() ?: 0) + - (if (units.asKnown().isPresent) 1 else 0) - - /** Additional transaction-specific fields that vary by source */ - class AdditionalInfo - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val capitalWithdrawal: JsonField, - private val credit: JsonField, - private val debit: JsonField, - private val incomeDistribution: JsonField, - private val orderNo: JsonField, - private val price: JsonField, - private val stampDuty: JsonField, - private val additionalProperties: MutableMap, - ) { + @JsonProperty("rta_code") + @ExcludeMissing + fun _rtaCode(): JsonField = rtaCode - @JsonCreator - private constructor( - @JsonProperty("capital_withdrawal") - @ExcludeMissing - capitalWithdrawal: JsonField = JsonMissing.of(), - @JsonProperty("credit") - @ExcludeMissing - credit: JsonField = JsonMissing.of(), - @JsonProperty("debit") - @ExcludeMissing - debit: JsonField = JsonMissing.of(), - @JsonProperty("income_distribution") - @ExcludeMissing - incomeDistribution: JsonField = JsonMissing.of(), - @JsonProperty("order_no") - @ExcludeMissing - orderNo: JsonField = JsonMissing.of(), - @JsonProperty("price") - @ExcludeMissing - price: JsonField = JsonMissing.of(), - @JsonProperty("stamp_duty") - @ExcludeMissing - stampDuty: JsonField = JsonMissing.of(), - ) : this( - capitalWithdrawal, - credit, - debit, - incomeDistribution, - orderNo, - price, - stampDuty, - mutableMapOf(), - ) + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } - /** - * Capital withdrawal amount (CDSL MF transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun capitalWithdrawal(): Optional = - capitalWithdrawal.getOptional("capital_withdrawal") + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) - /** - * Units credited (demat transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun credit(): Optional = credit.getOptional("credit") + fun toBuilder() = Builder().from(this) - /** - * Units debited (demat transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun debit(): Optional = debit.getOptional("debit") + companion object { /** - * Income distribution amount (CDSL MF transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). + * Returns a mutable builder for constructing an instance of [AdditionalInfo]. */ - fun incomeDistribution(): Optional = - incomeDistribution.getOptional("income_distribution") + @JvmStatic fun builder() = Builder() + } - /** - * Order/transaction reference number (demat transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun orderNo(): Optional = orderNo.getOptional("order_no") + /** A builder for [AdditionalInfo]. */ + class Builder internal constructor() { - /** - * Price per unit (NSDL/CDSL MF transactions) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun price(): Optional = price.getOptional("price") + private var advisor: JsonField = JsonMissing.of() + private var amfi: JsonField = JsonMissing.of() + private var closeUnits: JsonField = JsonMissing.of() + private var openUnits: JsonField = JsonMissing.of() + private var rtaCode: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() - /** - * Stamp duty charged - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected - * type (e.g. if the server responded with an unexpected value). - */ - fun stampDuty(): Optional = stampDuty.getOptional("stamp_duty") + @JvmSynthetic + internal fun from(additionalInfo: AdditionalInfo) = apply { + advisor = additionalInfo.advisor + amfi = additionalInfo.amfi + closeUnits = additionalInfo.closeUnits + openUnits = additionalInfo.openUnits + rtaCode = additionalInfo.rtaCode + additionalProperties = additionalInfo.additionalProperties.toMutableMap() + } - /** - * Returns the raw JSON value of [capitalWithdrawal]. - * - * Unlike [capitalWithdrawal], this method doesn't throw if the JSON field has - * an unexpected type. - */ - @JsonProperty("capital_withdrawal") - @ExcludeMissing - fun _capitalWithdrawal(): JsonField = capitalWithdrawal + /** Financial advisor name (CAMS/KFintech) */ + fun advisor(advisor: String) = advisor(JsonField.of(advisor)) /** - * Returns the raw JSON value of [credit]. + * Sets [Builder.advisor] to an arbitrary JSON value. * - * Unlike [credit], this method doesn't throw if the JSON field has an - * unexpected type. + * You should usually call [Builder.advisor] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. */ - @JsonProperty("credit") @ExcludeMissing fun _credit(): JsonField = credit + fun advisor(advisor: JsonField) = apply { this.advisor = advisor } + + /** AMFI code for the scheme (CAMS/KFintech) */ + fun amfi(amfi: String) = amfi(JsonField.of(amfi)) /** - * Returns the raw JSON value of [debit]. + * Sets [Builder.amfi] to an arbitrary JSON value. * - * Unlike [debit], this method doesn't throw if the JSON field has an unexpected - * type. + * You should usually call [Builder.amfi] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. */ - @JsonProperty("debit") @ExcludeMissing fun _debit(): JsonField = debit + fun amfi(amfi: JsonField) = apply { this.amfi = amfi } + + /** Closing balance units for the statement period */ + fun closeUnits(closeUnits: Float?) = + closeUnits(JsonField.ofNullable(closeUnits)) /** - * Returns the raw JSON value of [incomeDistribution]. + * Alias for [Builder.closeUnits]. * - * Unlike [incomeDistribution], this method doesn't throw if the JSON field has - * an unexpected type. + * This unboxed primitive overload exists for backwards compatibility. */ - @JsonProperty("income_distribution") - @ExcludeMissing - fun _incomeDistribution(): JsonField = incomeDistribution + fun closeUnits(closeUnits: Float) = closeUnits(closeUnits as Float?) + + /** Alias for calling [Builder.closeUnits] with `closeUnits.orElse(null)`. */ + fun closeUnits(closeUnits: Optional) = closeUnits(closeUnits.getOrNull()) /** - * Returns the raw JSON value of [orderNo]. + * Sets [Builder.closeUnits] to an arbitrary JSON value. * - * Unlike [orderNo], this method doesn't throw if the JSON field has an - * unexpected type. + * You should usually call [Builder.closeUnits] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. */ - @JsonProperty("order_no") - @ExcludeMissing - fun _orderNo(): JsonField = orderNo + fun closeUnits(closeUnits: JsonField) = apply { + this.closeUnits = closeUnits + } + + /** Opening balance units for the statement period */ + fun openUnits(openUnits: Float?) = openUnits(JsonField.ofNullable(openUnits)) /** - * Returns the raw JSON value of [price]. + * Alias for [Builder.openUnits]. * - * Unlike [price], this method doesn't throw if the JSON field has an unexpected - * type. + * This unboxed primitive overload exists for backwards compatibility. */ - @JsonProperty("price") @ExcludeMissing fun _price(): JsonField = price + fun openUnits(openUnits: Float) = openUnits(openUnits as Float?) + + /** Alias for calling [Builder.openUnits] with `openUnits.orElse(null)`. */ + fun openUnits(openUnits: Optional) = openUnits(openUnits.getOrNull()) /** - * Returns the raw JSON value of [stampDuty]. + * Sets [Builder.openUnits] to an arbitrary JSON value. * - * Unlike [stampDuty], this method doesn't throw if the JSON field has an - * unexpected type. + * You should usually call [Builder.openUnits] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. */ - @JsonProperty("stamp_duty") - @ExcludeMissing - fun _stampDuty(): JsonField = stampDuty - - @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 - * [AdditionalInfo]. - */ - @JvmStatic fun builder() = Builder() + fun openUnits(openUnits: JsonField) = apply { + this.openUnits = openUnits } - /** A builder for [AdditionalInfo]. */ - class Builder internal constructor() { - - private var capitalWithdrawal: JsonField = JsonMissing.of() - private var credit: JsonField = JsonMissing.of() - private var debit: JsonField = JsonMissing.of() - private var incomeDistribution: JsonField = JsonMissing.of() - private var orderNo: JsonField = JsonMissing.of() - private var price: JsonField = JsonMissing.of() - private var stampDuty: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = - mutableMapOf() - - @JvmSynthetic - internal fun from(additionalInfo: AdditionalInfo) = apply { - capitalWithdrawal = additionalInfo.capitalWithdrawal - credit = additionalInfo.credit - debit = additionalInfo.debit - incomeDistribution = additionalInfo.incomeDistribution - orderNo = additionalInfo.orderNo - price = additionalInfo.price - stampDuty = additionalInfo.stampDuty - additionalProperties = - additionalInfo.additionalProperties.toMutableMap() - } - - /** Capital withdrawal amount (CDSL MF transactions) */ - fun capitalWithdrawal(capitalWithdrawal: Float) = - capitalWithdrawal(JsonField.of(capitalWithdrawal)) - - /** - * Sets [Builder.capitalWithdrawal] to an arbitrary JSON value. - * - * You should usually call [Builder.capitalWithdrawal] with a well-typed - * [Float] value instead. This method is primarily for setting the field to - * an undocumented or not yet supported value. - */ - fun capitalWithdrawal(capitalWithdrawal: JsonField) = apply { - this.capitalWithdrawal = capitalWithdrawal - } - - /** Units credited (demat transactions) */ - fun credit(credit: Float) = credit(JsonField.of(credit)) - - /** - * Sets [Builder.credit] to an arbitrary JSON value. - * - * You should usually call [Builder.credit] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun credit(credit: JsonField) = apply { this.credit = credit } - - /** Units debited (demat transactions) */ - fun debit(debit: Float) = debit(JsonField.of(debit)) - - /** - * Sets [Builder.debit] to an arbitrary JSON value. - * - * You should usually call [Builder.debit] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun debit(debit: JsonField) = apply { this.debit = debit } - - /** Income distribution amount (CDSL MF transactions) */ - fun incomeDistribution(incomeDistribution: Float) = - incomeDistribution(JsonField.of(incomeDistribution)) - - /** - * Sets [Builder.incomeDistribution] to an arbitrary JSON value. - * - * You should usually call [Builder.incomeDistribution] with a well-typed - * [Float] value instead. This method is primarily for setting the field to - * an undocumented or not yet supported value. - */ - fun incomeDistribution(incomeDistribution: JsonField) = apply { - this.incomeDistribution = incomeDistribution - } - - /** Order/transaction reference number (demat transactions) */ - fun orderNo(orderNo: String) = orderNo(JsonField.of(orderNo)) - - /** - * Sets [Builder.orderNo] to an arbitrary JSON value. - * - * You should usually call [Builder.orderNo] with a well-typed [String] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun orderNo(orderNo: JsonField) = apply { this.orderNo = orderNo } - - /** Price per unit (NSDL/CDSL MF transactions) */ - fun price(price: Float) = price(JsonField.of(price)) - - /** - * Sets [Builder.price] to an arbitrary JSON value. - * - * You should usually call [Builder.price] with a well-typed [Float] value - * instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun price(price: JsonField) = apply { this.price = price } - - /** Stamp duty charged */ - fun stampDuty(stampDuty: Float) = stampDuty(JsonField.of(stampDuty)) - - /** - * Sets [Builder.stampDuty] to an arbitrary JSON value. - * - * You should usually call [Builder.stampDuty] with a well-typed [Float] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun stampDuty(stampDuty: JsonField) = apply { - this.stampDuty = stampDuty - } - - 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) - } + /** RTA code for the scheme (CAMS/KFintech) */ + fun rtaCode(rtaCode: String) = rtaCode(JsonField.of(rtaCode)) - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } + /** + * Sets [Builder.rtaCode] to an arbitrary JSON value. + * + * You should usually call [Builder.rtaCode] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun rtaCode(rtaCode: JsonField) = apply { this.rtaCode = rtaCode } - /** - * Returns an immutable instance of [AdditionalInfo]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): AdditionalInfo = - AdditionalInfo( - capitalWithdrawal, - credit, - debit, - incomeDistribution, - orderNo, - price, - stampDuty, - additionalProperties.toMutableMap(), - ) + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) } - private var validated: Boolean = false + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } - fun validate(): AdditionalInfo = apply { - if (validated) { - return@apply + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) } - capitalWithdrawal() - credit() - debit() - incomeDistribution() - orderNo() - price() - stampDuty() - validated = true + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) } - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - false - } + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } /** - * Returns a score indicating how many valid values are contained in this object - * recursively. + * Returns an immutable instance of [AdditionalInfo]. * - * Used for best match union deserialization. + * Further updates to this [Builder] will not mutate the returned instance. */ - @JvmSynthetic - internal fun validity(): Int = - (if (capitalWithdrawal.asKnown().isPresent) 1 else 0) + - (if (credit.asKnown().isPresent) 1 else 0) + - (if (debit.asKnown().isPresent) 1 else 0) + - (if (incomeDistribution.asKnown().isPresent) 1 else 0) + - (if (orderNo.asKnown().isPresent) 1 else 0) + - (if (price.asKnown().isPresent) 1 else 0) + - (if (stampDuty.asKnown().isPresent) 1 else 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + fun build(): AdditionalInfo = + AdditionalInfo( + advisor, + amfi, + closeUnits, + openUnits, + rtaCode, + additionalProperties.toMutableMap(), + ) + } - return other is AdditionalInfo && - capitalWithdrawal == other.capitalWithdrawal && - credit == other.credit && - debit == other.debit && - incomeDistribution == other.incomeDistribution && - orderNo == other.orderNo && - price == other.price && - stampDuty == other.stampDuty && - additionalProperties == other.additionalProperties - } + private var validated: Boolean = false - private val hashCode: Int by lazy { - Objects.hash( - capitalWithdrawal, - credit, - debit, - incomeDistribution, - orderNo, - price, - stampDuty, - additionalProperties, - ) + fun validate(): AdditionalInfo = apply { + if (validated) { + return@apply } - override fun hashCode(): Int = hashCode - - override fun toString() = - "AdditionalInfo{capitalWithdrawal=$capitalWithdrawal, credit=$credit, debit=$debit, incomeDistribution=$incomeDistribution, orderNo=$orderNo, price=$price, stampDuty=$stampDuty, additionalProperties=$additionalProperties}" + advisor() + amfi() + closeUnits() + openUnits() + rtaCode() + validated = true } + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + false + } + /** - * Transaction type. Possible values are PURCHASE, PURCHASE_SIP, REDEMPTION, - * SWITCH_IN, SWITCH_IN_MERGER, SWITCH_OUT, SWITCH_OUT_MERGER, DIVIDEND_PAYOUT, - * DIVIDEND_REINVEST, SEGREGATION, STAMP_DUTY_TAX, TDS_TAX, STT_TAX, MISC, REVERSAL, - * UNKNOWN. + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. */ - class Type @JsonCreator private constructor(private val value: JsonField) : - Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that - * doesn't match any known member, and you want to know that value. For example, - * if the SDK is on an older version than the API, then the API may respond with - * new members that the SDK is unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue - fun _value(): JsonField = value + @JvmSynthetic + internal fun validity(): Int = + (if (advisor.asKnown().isPresent) 1 else 0) + + (if (amfi.asKnown().isPresent) 1 else 0) + + (if (closeUnits.asKnown().isPresent) 1 else 0) + + (if (openUnits.asKnown().isPresent) 1 else 0) + + (if (rtaCode.asKnown().isPresent) 1 else 0) - companion object { + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - @JvmField val PURCHASE = of("PURCHASE") + return other is AdditionalInfo && + advisor == other.advisor && + amfi == other.amfi && + closeUnits == other.closeUnits && + openUnits == other.openUnits && + rtaCode == other.rtaCode && + additionalProperties == other.additionalProperties + } - @JvmField val PURCHASE_SIP = of("PURCHASE_SIP") + private val hashCode: Int by lazy { + Objects.hash( + advisor, + amfi, + closeUnits, + openUnits, + rtaCode, + additionalProperties, + ) + } - @JvmField val REDEMPTION = of("REDEMPTION") + override fun hashCode(): Int = hashCode - @JvmField val SWITCH_IN = of("SWITCH_IN") + override fun toString() = + "AdditionalInfo{advisor=$advisor, amfi=$amfi, closeUnits=$closeUnits, openUnits=$openUnits, rtaCode=$rtaCode, additionalProperties=$additionalProperties}" + } - @JvmField val SWITCH_IN_MERGER = of("SWITCH_IN_MERGER") + class Gain + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val absolute: JsonField, + private val percentage: JsonField, + private val additionalProperties: MutableMap, + ) { - @JvmField val SWITCH_OUT = of("SWITCH_OUT") + @JsonCreator + private constructor( + @JsonProperty("absolute") + @ExcludeMissing + absolute: JsonField = JsonMissing.of(), + @JsonProperty("percentage") + @ExcludeMissing + percentage: JsonField = JsonMissing.of(), + ) : this(absolute, percentage, mutableMapOf()) - @JvmField val SWITCH_OUT_MERGER = of("SWITCH_OUT_MERGER") + /** + * Absolute gain or loss + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun absolute(): Optional = absolute.getOptional("absolute") - @JvmField val DIVIDEND_PAYOUT = of("DIVIDEND_PAYOUT") + /** + * Percentage gain or loss + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun percentage(): Optional = percentage.getOptional("percentage") - @JvmField val DIVIDEND_REINVEST = of("DIVIDEND_REINVEST") + /** + * Returns the raw JSON value of [absolute]. + * + * Unlike [absolute], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("absolute") + @ExcludeMissing + fun _absolute(): JsonField = absolute - @JvmField val SEGREGATION = of("SEGREGATION") + /** + * Returns the raw JSON value of [percentage]. + * + * Unlike [percentage], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("percentage") + @ExcludeMissing + fun _percentage(): JsonField = percentage - @JvmField val STAMP_DUTY_TAX = of("STAMP_DUTY_TAX") + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } - @JvmField val TDS_TAX = of("TDS_TAX") + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) - @JvmField val STT_TAX = of("STT_TAX") + fun toBuilder() = Builder().from(this) - @JvmField val MISC = of("MISC") + companion object { - @JvmField val REVERSAL = of("REVERSAL") + /** Returns a mutable builder for constructing an instance of [Gain]. */ + @JvmStatic fun builder() = Builder() + } - @JvmField val UNKNOWN = of("UNKNOWN") + /** A builder for [Gain]. */ + class Builder internal constructor() { - @JvmStatic fun of(value: String) = Type(JsonField.of(value)) - } + private var absolute: JsonField = JsonMissing.of() + private var percentage: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() - /** An enum containing [Type]'s known values. */ - enum class Known { - PURCHASE, - PURCHASE_SIP, - REDEMPTION, - SWITCH_IN, - SWITCH_IN_MERGER, - SWITCH_OUT, - SWITCH_OUT_MERGER, - DIVIDEND_PAYOUT, - DIVIDEND_REINVEST, - SEGREGATION, - STAMP_DUTY_TAX, - TDS_TAX, - STT_TAX, - MISC, - REVERSAL, - UNKNOWN, + @JvmSynthetic + internal fun from(gain: Gain) = apply { + absolute = gain.absolute + percentage = gain.percentage + additionalProperties = gain.additionalProperties.toMutableMap() } - /** - * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [Type] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For - * example, if the SDK is on an older version than the API, then the API may - * respond with new members that the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - PURCHASE, - PURCHASE_SIP, - REDEMPTION, - SWITCH_IN, - SWITCH_IN_MERGER, - SWITCH_OUT, - SWITCH_OUT_MERGER, - DIVIDEND_PAYOUT, - DIVIDEND_REINVEST, - SEGREGATION, - STAMP_DUTY_TAX, - TDS_TAX, - STT_TAX, - MISC, - REVERSAL, - UNKNOWN, - /** - * An enum member indicating that [Type] was instantiated with an unknown - * value. - */ - _UNKNOWN, - } + /** Absolute gain or loss */ + fun absolute(absolute: Float) = absolute(JsonField.of(absolute)) /** - * Returns an enum member corresponding to this class instance's value, or - * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * Sets [Builder.absolute] to an arbitrary JSON value. * - * Use the [known] method instead if you're certain the value is always known or - * if you want to throw for the unknown case. + * You should usually call [Builder.absolute] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. */ - fun value(): Value = - when (this) { - PURCHASE -> Value.PURCHASE - PURCHASE_SIP -> Value.PURCHASE_SIP - REDEMPTION -> Value.REDEMPTION - SWITCH_IN -> Value.SWITCH_IN - SWITCH_IN_MERGER -> Value.SWITCH_IN_MERGER - SWITCH_OUT -> Value.SWITCH_OUT - SWITCH_OUT_MERGER -> Value.SWITCH_OUT_MERGER - DIVIDEND_PAYOUT -> Value.DIVIDEND_PAYOUT - DIVIDEND_REINVEST -> Value.DIVIDEND_REINVEST - SEGREGATION -> Value.SEGREGATION - STAMP_DUTY_TAX -> Value.STAMP_DUTY_TAX - TDS_TAX -> Value.TDS_TAX - STT_TAX -> Value.STT_TAX - MISC -> Value.MISC - REVERSAL -> Value.REVERSAL - UNKNOWN -> Value.UNKNOWN - else -> Value._UNKNOWN - } + fun absolute(absolute: JsonField) = apply { this.absolute = absolute } - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known - * and don't want to throw for the unknown case. - * - * @throws CasParserInvalidDataException if this class instance's value is a not - * a known member. - */ - fun known(): Known = - when (this) { - PURCHASE -> Known.PURCHASE - PURCHASE_SIP -> Known.PURCHASE_SIP - REDEMPTION -> Known.REDEMPTION - SWITCH_IN -> Known.SWITCH_IN - SWITCH_IN_MERGER -> Known.SWITCH_IN_MERGER - SWITCH_OUT -> Known.SWITCH_OUT - SWITCH_OUT_MERGER -> Known.SWITCH_OUT_MERGER - DIVIDEND_PAYOUT -> Known.DIVIDEND_PAYOUT - DIVIDEND_REINVEST -> Known.DIVIDEND_REINVEST - SEGREGATION -> Known.SEGREGATION - STAMP_DUTY_TAX -> Known.STAMP_DUTY_TAX - TDS_TAX -> Known.TDS_TAX - STT_TAX -> Known.STT_TAX - MISC -> Known.MISC - REVERSAL -> Known.REVERSAL - UNKNOWN -> Known.UNKNOWN - else -> throw CasParserInvalidDataException("Unknown Type: $value") - } + /** Percentage gain or loss */ + fun percentage(percentage: Float) = percentage(JsonField.of(percentage)) - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily for - * debugging and generally doesn't throw. + /** + * Sets [Builder.percentage] to an arbitrary JSON value. * - * @throws CasParserInvalidDataException if this class instance's value does not - * have the expected primitive type. + * You should usually call [Builder.percentage] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. */ - fun asString(): String = - _value().asString().orElseThrow { - CasParserInvalidDataException("Value is not a String") - } + fun percentage(percentage: JsonField) = apply { + this.percentage = percentage + } - private var validated: Boolean = false + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } - fun validate(): Type = apply { - if (validated) { - return@apply + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) } - known() - validated = true + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) } - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - false - } + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } /** - * Returns a score indicating how many valid values are contained in this object - * recursively. + * Returns an immutable instance of [Gain]. * - * Used for best match union deserialization. + * Further updates to this [Builder] will not mutate the returned instance. */ - @JvmSynthetic - internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + fun build(): Gain = + Gain(absolute, percentage, additionalProperties.toMutableMap()) + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + private var validated: Boolean = false - return other is Type && value == other.value + fun validate(): Gain = apply { + if (validated) { + return@apply } - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() + absolute() + percentage() + validated = true } + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (absolute.asKnown().isPresent) 1 else 0) + + (if (percentage.asKnown().isPresent) 1 else 0) + override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is Transaction && - additionalInfo == other.additionalInfo && - amount == other.amount && - balance == other.balance && - date == other.date && - description == other.description && - dividendRate == other.dividendRate && - nav == other.nav && - type == other.type && - units == other.units && + return other is Gain && + absolute == other.absolute && + percentage == other.percentage && additionalProperties == other.additionalProperties } private val hashCode: Int by lazy { - Objects.hash( - additionalInfo, - amount, - balance, - date, - description, - dividendRate, - nav, - type, - units, - additionalProperties, - ) + Objects.hash(absolute, percentage, additionalProperties) } override fun hashCode(): Int = hashCode override fun toString() = - "Transaction{additionalInfo=$additionalInfo, amount=$amount, balance=$balance, date=$date, description=$description, dividendRate=$dividendRate, nav=$nav, type=$type, units=$units, additionalProperties=$additionalProperties}" + "Gain{absolute=$absolute, percentage=$percentage, additionalProperties=$additionalProperties}" } /** Type of mutual fund scheme */ @@ -16921,186 +9343,6 @@ private constructor( "Fund{additionalInfo=$additionalInfo, cost=$cost, name=$name, nav=$nav, units=$units, value=$value, additionalProperties=$additionalProperties}" } - class LinkedHolder - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val name: JsonField, - private val pan: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), - @JsonProperty("pan") @ExcludeMissing pan: JsonField = JsonMissing.of(), - ) : this(name, pan, mutableMapOf()) - - /** - * Name of the account holder - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun name(): Optional = name.getOptional("name") - - /** - * PAN of the account holder - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun pan(): Optional = pan.getOptional("pan") - - /** - * Returns the raw JSON value of [name]. - * - * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name - - /** - * Returns the raw JSON value of [pan]. - * - * Unlike [pan], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("pan") @ExcludeMissing fun _pan(): JsonField = pan - - @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 [LinkedHolder]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [LinkedHolder]. */ - class Builder internal constructor() { - - private var name: JsonField = JsonMissing.of() - private var pan: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(linkedHolder: LinkedHolder) = apply { - name = linkedHolder.name - pan = linkedHolder.pan - additionalProperties = linkedHolder.additionalProperties.toMutableMap() - } - - /** Name of the account holder */ - fun name(name: String) = name(JsonField.of(name)) - - /** - * Sets [Builder.name] to an arbitrary JSON value. - * - * You should usually call [Builder.name] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun name(name: JsonField) = apply { this.name = name } - - /** PAN of the account holder */ - fun pan(pan: String) = pan(JsonField.of(pan)) - - /** - * Sets [Builder.pan] to an arbitrary JSON value. - * - * You should usually call [Builder.pan] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun pan(pan: JsonField) = apply { this.pan = pan } - - 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 [LinkedHolder]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): LinkedHolder = - LinkedHolder(name, pan, additionalProperties.toMutableMap()) - } - - private var validated: Boolean = false - - fun validate(): LinkedHolder = apply { - if (validated) { - return@apply - } - - name() - pan() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - 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 (name.asKnown().isPresent) 1 else 0) + (if (pan.asKnown().isPresent) 1 else 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is LinkedHolder && - name == other.name && - pan == other.pan && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { Objects.hash(name, pan, additionalProperties) } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "LinkedHolder{name=$name, pan=$pan, additionalProperties=$additionalProperties}" - } - override fun equals(other: Any?): Boolean { if (this === other) { return true diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserCdslParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/cdsl/CdslParsePdfParams.kt similarity index 95% rename from cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserCdslParams.kt rename to cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/cdsl/CdslParsePdfParams.kt index 8d90147..e9440f6 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserCdslParams.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/cdsl/CdslParsePdfParams.kt @@ -1,6 +1,6 @@ // File generated from our OpenAPI spec by Stainless. -package com.cas_parser.api.models.casparser +package com.cas_parser.api.models.cdsl import com.cas_parser.api.core.ExcludeMissing import com.cas_parser.api.core.JsonValue @@ -21,7 +21,7 @@ import java.util.Optional * This endpoint specifically parses CDSL CAS (Consolidated Account Statement) PDF files and returns * data in a unified format. Use this endpoint when you know the PDF is from CDSL. */ -class CasParserCdslParams +class CdslParsePdfParams private constructor( private val body: Body, private val additionalHeaders: Headers, @@ -85,13 +85,13 @@ private constructor( companion object { - @JvmStatic fun none(): CasParserCdslParams = builder().build() + @JvmStatic fun none(): CdslParsePdfParams = builder().build() - /** Returns a mutable builder for constructing an instance of [CasParserCdslParams]. */ + /** Returns a mutable builder for constructing an instance of [CdslParsePdfParams]. */ @JvmStatic fun builder() = Builder() } - /** A builder for [CasParserCdslParams]. */ + /** A builder for [CdslParsePdfParams]. */ class Builder internal constructor() { private var body: Body.Builder = Body.builder() @@ -99,10 +99,10 @@ private constructor( private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic - internal fun from(casParserCdslParams: CasParserCdslParams) = apply { - body = casParserCdslParams.body.toBuilder() - additionalHeaders = casParserCdslParams.additionalHeaders.toBuilder() - additionalQueryParams = casParserCdslParams.additionalQueryParams.toBuilder() + internal fun from(cdslParsePdfParams: CdslParsePdfParams) = apply { + body = cdslParsePdfParams.body.toBuilder() + additionalHeaders = cdslParsePdfParams.additionalHeaders.toBuilder() + additionalQueryParams = cdslParsePdfParams.additionalQueryParams.toBuilder() } /** @@ -267,12 +267,12 @@ private constructor( } /** - * Returns an immutable instance of [CasParserCdslParams]. + * Returns an immutable instance of [CdslParsePdfParams]. * * Further updates to this [Builder] will not mutate the returned instance. */ - fun build(): CasParserCdslParams = - CasParserCdslParams( + fun build(): CdslParsePdfParams = + CdslParsePdfParams( body.build(), additionalHeaders.build(), additionalQueryParams.build(), @@ -489,7 +489,7 @@ private constructor( return true } - return other is CasParserCdslParams && + return other is CdslParsePdfParams && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams @@ -498,5 +498,5 @@ private constructor( override fun hashCode(): Int = Objects.hash(body, additionalHeaders, additionalQueryParams) override fun toString() = - "CasParserCdslParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" + "CdslParsePdfParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchRequestOtpParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchRequestOtpParams.kt new file mode 100644 index 0000000..34b641d --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchRequestOtpParams.kt @@ -0,0 +1,561 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.cdsl.fetch + +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonField +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.Params +import com.cas_parser.api.core.checkRequired +import com.cas_parser.api.core.http.Headers +import com.cas_parser.api.core.http.QueryParams +import com.cas_parser.api.errors.CasParserInvalidDataException +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 + +/** + * **Step 1 of 2**: Request OTP for CDSL CAS fetch. + * + * This endpoint: + * 1. Solves reCAPTCHA automatically (~15-20 seconds) + * 2. Submits login credentials to CDSL portal + * 3. Triggers OTP to user's registered mobile number + * + * After user receives OTP, call `/v4/cdsl/fetch/{session_id}/verify` to complete. + */ +class FetchRequestOtpParams +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * CDSL BO ID (16 digits) + * + * @throws CasParserInvalidDataException 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 boId(): String = body.boId() + + /** + * Date of birth (YYYY-MM-DD) + * + * @throws CasParserInvalidDataException 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 dob(): String = body.dob() + + /** + * PAN number + * + * @throws CasParserInvalidDataException 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 pan(): String = body.pan() + + /** + * Returns the raw JSON value of [boId]. + * + * Unlike [boId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _boId(): JsonField = body._boId() + + /** + * Returns the raw JSON value of [dob]. + * + * Unlike [dob], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _dob(): JsonField = body._dob() + + /** + * Returns the raw JSON value of [pan]. + * + * Unlike [pan], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _pan(): JsonField = body._pan() + + fun _additionalBodyProperties(): Map = body._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 [FetchRequestOtpParams]. + * + * The following fields are required: + * ```java + * .boId() + * .dob() + * .pan() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [FetchRequestOtpParams]. */ + class Builder internal constructor() { + + private var body: Body.Builder = Body.builder() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(fetchRequestOtpParams: FetchRequestOtpParams) = apply { + body = fetchRequestOtpParams.body.toBuilder() + additionalHeaders = fetchRequestOtpParams.additionalHeaders.toBuilder() + additionalQueryParams = fetchRequestOtpParams.additionalQueryParams.toBuilder() + } + + /** + * Sets the entire request body. + * + * This is generally only useful if you are already constructing the body separately. + * Otherwise, it's more convenient to use the top-level setters instead: + * - [boId] + * - [dob] + * - [pan] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + /** CDSL BO ID (16 digits) */ + fun boId(boId: String) = apply { body.boId(boId) } + + /** + * Sets [Builder.boId] to an arbitrary JSON value. + * + * You should usually call [Builder.boId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun boId(boId: JsonField) = apply { body.boId(boId) } + + /** Date of birth (YYYY-MM-DD) */ + fun dob(dob: String) = apply { body.dob(dob) } + + /** + * Sets [Builder.dob] to an arbitrary JSON value. + * + * You should usually call [Builder.dob] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun dob(dob: JsonField) = apply { body.dob(dob) } + + /** PAN number */ + fun pan(pan: String) = apply { body.pan(pan) } + + /** + * Sets [Builder.pan] to an arbitrary JSON value. + * + * You should usually call [Builder.pan] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun pan(pan: JsonField) = apply { body.pan(pan) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) + } + + 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 [FetchRequestOtpParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .boId() + * .dob() + * .pan() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): FetchRequestOtpParams = + FetchRequestOtpParams( + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + class Body + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val boId: JsonField, + private val dob: JsonField, + private val pan: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("bo_id") @ExcludeMissing boId: JsonField = JsonMissing.of(), + @JsonProperty("dob") @ExcludeMissing dob: JsonField = JsonMissing.of(), + @JsonProperty("pan") @ExcludeMissing pan: JsonField = JsonMissing.of(), + ) : this(boId, dob, pan, mutableMapOf()) + + /** + * CDSL BO ID (16 digits) + * + * @throws CasParserInvalidDataException 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 boId(): String = boId.getRequired("bo_id") + + /** + * Date of birth (YYYY-MM-DD) + * + * @throws CasParserInvalidDataException 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 dob(): String = dob.getRequired("dob") + + /** + * PAN number + * + * @throws CasParserInvalidDataException 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 pan(): String = pan.getRequired("pan") + + /** + * Returns the raw JSON value of [boId]. + * + * Unlike [boId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("bo_id") @ExcludeMissing fun _boId(): JsonField = boId + + /** + * Returns the raw JSON value of [dob]. + * + * Unlike [dob], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("dob") @ExcludeMissing fun _dob(): JsonField = dob + + /** + * Returns the raw JSON value of [pan]. + * + * Unlike [pan], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("pan") @ExcludeMissing fun _pan(): JsonField = pan + + @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 [Body]. + * + * The following fields are required: + * ```java + * .boId() + * .dob() + * .pan() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var boId: JsonField? = null + private var dob: JsonField? = null + private var pan: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + boId = body.boId + dob = body.dob + pan = body.pan + additionalProperties = body.additionalProperties.toMutableMap() + } + + /** CDSL BO ID (16 digits) */ + fun boId(boId: String) = boId(JsonField.of(boId)) + + /** + * Sets [Builder.boId] to an arbitrary JSON value. + * + * You should usually call [Builder.boId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun boId(boId: JsonField) = apply { this.boId = boId } + + /** Date of birth (YYYY-MM-DD) */ + fun dob(dob: String) = dob(JsonField.of(dob)) + + /** + * Sets [Builder.dob] to an arbitrary JSON value. + * + * You should usually call [Builder.dob] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun dob(dob: JsonField) = apply { this.dob = dob } + + /** PAN number */ + fun pan(pan: String) = pan(JsonField.of(pan)) + + /** + * Sets [Builder.pan] to an arbitrary JSON value. + * + * You should usually call [Builder.pan] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun pan(pan: JsonField) = apply { this.pan = pan } + + 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 [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .boId() + * .dob() + * .pan() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("boId", boId), + checkRequired("dob", dob), + checkRequired("pan", pan), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + boId() + dob() + pan() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (boId.asKnown().isPresent) 1 else 0) + + (if (dob.asKnown().isPresent) 1 else 0) + + (if (pan.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + boId == other.boId && + dob == other.dob && + pan == other.pan && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(boId, dob, pan, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{boId=$boId, dob=$dob, pan=$pan, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is FetchRequestOtpParams && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = Objects.hash(body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "FetchRequestOtpParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchRequestOtpResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchRequestOtpResponse.kt new file mode 100644 index 0000000..cf0cf74 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchRequestOtpResponse.kt @@ -0,0 +1,219 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.cdsl.fetch + +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonField +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.errors.CasParserInvalidDataException +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 + +class FetchRequestOtpResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val msg: JsonField, + private val sessionId: JsonField, + private val status: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("msg") @ExcludeMissing msg: JsonField = JsonMissing.of(), + @JsonProperty("session_id") @ExcludeMissing sessionId: JsonField = JsonMissing.of(), + @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(), + ) : this(msg, sessionId, status, mutableMapOf()) + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun msg(): Optional = msg.getOptional("msg") + + /** + * Session ID for verify step + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun sessionId(): Optional = sessionId.getOptional("session_id") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun status(): Optional = status.getOptional("status") + + /** + * Returns the raw JSON value of [msg]. + * + * Unlike [msg], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("msg") @ExcludeMissing fun _msg(): JsonField = msg + + /** + * Returns the raw JSON value of [sessionId]. + * + * Unlike [sessionId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("session_id") @ExcludeMissing fun _sessionId(): JsonField = sessionId + + /** + * Returns the raw JSON value of [status]. + * + * Unlike [status], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("status") @ExcludeMissing fun _status(): JsonField = status + + @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 [FetchRequestOtpResponse]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [FetchRequestOtpResponse]. */ + class Builder internal constructor() { + + private var msg: JsonField = JsonMissing.of() + private var sessionId: JsonField = JsonMissing.of() + private var status: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(fetchRequestOtpResponse: FetchRequestOtpResponse) = apply { + msg = fetchRequestOtpResponse.msg + sessionId = fetchRequestOtpResponse.sessionId + status = fetchRequestOtpResponse.status + additionalProperties = fetchRequestOtpResponse.additionalProperties.toMutableMap() + } + + fun msg(msg: String) = msg(JsonField.of(msg)) + + /** + * Sets [Builder.msg] to an arbitrary JSON value. + * + * You should usually call [Builder.msg] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun msg(msg: JsonField) = apply { this.msg = msg } + + /** Session ID for verify step */ + fun sessionId(sessionId: String) = sessionId(JsonField.of(sessionId)) + + /** + * Sets [Builder.sessionId] to an arbitrary JSON value. + * + * You should usually call [Builder.sessionId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun sessionId(sessionId: JsonField) = apply { this.sessionId = sessionId } + + fun status(status: String) = status(JsonField.of(status)) + + /** + * Sets [Builder.status] to an arbitrary JSON value. + * + * You should usually call [Builder.status] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun status(status: JsonField) = apply { this.status = status } + + 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 [FetchRequestOtpResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): FetchRequestOtpResponse = + FetchRequestOtpResponse(msg, sessionId, status, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): FetchRequestOtpResponse = apply { + if (validated) { + return@apply + } + + msg() + sessionId() + status() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (msg.asKnown().isPresent) 1 else 0) + + (if (sessionId.asKnown().isPresent) 1 else 0) + + (if (status.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is FetchRequestOtpResponse && + msg == other.msg && + sessionId == other.sessionId && + status == other.status && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(msg, sessionId, status, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "FetchRequestOtpResponse{msg=$msg, sessionId=$sessionId, status=$status, additionalProperties=$additionalProperties}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchVerifyOtpParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchVerifyOtpParams.kt new file mode 100644 index 0000000..854f921 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchVerifyOtpParams.kt @@ -0,0 +1,505 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.cdsl.fetch + +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonField +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.Params +import com.cas_parser.api.core.checkRequired +import com.cas_parser.api.core.http.Headers +import com.cas_parser.api.core.http.QueryParams +import com.cas_parser.api.errors.CasParserInvalidDataException +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 + +/** + * **Step 2 of 2**: Verify OTP and retrieve CDSL CAS files. + * + * After successful verification, CAS PDFs are fetched from CDSL portal, uploaded to cloud storage, + * and returned as direct download URLs. + */ +class FetchVerifyOtpParams +private constructor( + private val sessionId: String?, + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun sessionId(): Optional = Optional.ofNullable(sessionId) + + /** + * OTP received on mobile + * + * @throws CasParserInvalidDataException 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 otp(): String = body.otp() + + /** + * Number of monthly statements to fetch (default 6) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun numPeriods(): Optional = body.numPeriods() + + /** + * Returns the raw JSON value of [otp]. + * + * Unlike [otp], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _otp(): JsonField = body._otp() + + /** + * Returns the raw JSON value of [numPeriods]. + * + * Unlike [numPeriods], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _numPeriods(): JsonField = body._numPeriods() + + fun _additionalBodyProperties(): Map = body._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 [FetchVerifyOtpParams]. + * + * The following fields are required: + * ```java + * .otp() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [FetchVerifyOtpParams]. */ + class Builder internal constructor() { + + private var sessionId: String? = null + private var body: Body.Builder = Body.builder() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(fetchVerifyOtpParams: FetchVerifyOtpParams) = apply { + sessionId = fetchVerifyOtpParams.sessionId + body = fetchVerifyOtpParams.body.toBuilder() + additionalHeaders = fetchVerifyOtpParams.additionalHeaders.toBuilder() + additionalQueryParams = fetchVerifyOtpParams.additionalQueryParams.toBuilder() + } + + fun sessionId(sessionId: String?) = apply { this.sessionId = sessionId } + + /** Alias for calling [Builder.sessionId] with `sessionId.orElse(null)`. */ + fun sessionId(sessionId: Optional) = sessionId(sessionId.getOrNull()) + + /** + * Sets the entire request body. + * + * This is generally only useful if you are already constructing the body separately. + * Otherwise, it's more convenient to use the top-level setters instead: + * - [otp] + * - [numPeriods] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + /** OTP received on mobile */ + fun otp(otp: String) = apply { body.otp(otp) } + + /** + * Sets [Builder.otp] to an arbitrary JSON value. + * + * You should usually call [Builder.otp] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun otp(otp: JsonField) = apply { body.otp(otp) } + + /** Number of monthly statements to fetch (default 6) */ + fun numPeriods(numPeriods: Long) = apply { body.numPeriods(numPeriods) } + + /** + * Sets [Builder.numPeriods] to an arbitrary JSON value. + * + * You should usually call [Builder.numPeriods] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun numPeriods(numPeriods: JsonField) = apply { body.numPeriods(numPeriods) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) + } + + 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 [FetchVerifyOtpParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .otp() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): FetchVerifyOtpParams = + FetchVerifyOtpParams( + sessionId, + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): Body = body + + fun _pathParam(index: Int): String = + when (index) { + 0 -> sessionId ?: "" + else -> "" + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + class Body + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val otp: JsonField, + private val numPeriods: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("otp") @ExcludeMissing otp: JsonField = JsonMissing.of(), + @JsonProperty("num_periods") + @ExcludeMissing + numPeriods: JsonField = JsonMissing.of(), + ) : this(otp, numPeriods, mutableMapOf()) + + /** + * OTP received on mobile + * + * @throws CasParserInvalidDataException 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 otp(): String = otp.getRequired("otp") + + /** + * Number of monthly statements to fetch (default 6) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun numPeriods(): Optional = numPeriods.getOptional("num_periods") + + /** + * Returns the raw JSON value of [otp]. + * + * Unlike [otp], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("otp") @ExcludeMissing fun _otp(): JsonField = otp + + /** + * Returns the raw JSON value of [numPeriods]. + * + * Unlike [numPeriods], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("num_periods") @ExcludeMissing fun _numPeriods(): JsonField = numPeriods + + @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 [Body]. + * + * The following fields are required: + * ```java + * .otp() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var otp: JsonField? = null + private var numPeriods: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + otp = body.otp + numPeriods = body.numPeriods + additionalProperties = body.additionalProperties.toMutableMap() + } + + /** OTP received on mobile */ + fun otp(otp: String) = otp(JsonField.of(otp)) + + /** + * Sets [Builder.otp] to an arbitrary JSON value. + * + * You should usually call [Builder.otp] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun otp(otp: JsonField) = apply { this.otp = otp } + + /** Number of monthly statements to fetch (default 6) */ + fun numPeriods(numPeriods: Long) = numPeriods(JsonField.of(numPeriods)) + + /** + * Sets [Builder.numPeriods] to an arbitrary JSON value. + * + * You should usually call [Builder.numPeriods] with a well-typed [Long] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun numPeriods(numPeriods: JsonField) = apply { this.numPeriods = numPeriods } + + 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 [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .otp() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body(checkRequired("otp", otp), numPeriods, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + otp() + numPeriods() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (otp.asKnown().isPresent) 1 else 0) + (if (numPeriods.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + otp == other.otp && + numPeriods == other.numPeriods && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(otp, numPeriods, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{otp=$otp, numPeriods=$numPeriods, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is FetchVerifyOtpParams && + sessionId == other.sessionId && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(sessionId, body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "FetchVerifyOtpParams{sessionId=$sessionId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchVerifyOtpResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchVerifyOtpResponse.kt new file mode 100644 index 0000000..2e72418 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchVerifyOtpResponse.kt @@ -0,0 +1,411 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.cdsl.fetch + +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonField +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.checkKnown +import com.cas_parser.api.core.toImmutable +import com.cas_parser.api.errors.CasParserInvalidDataException +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 + +class FetchVerifyOtpResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val files: JsonField>, + private val msg: JsonField, + private val status: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("files") @ExcludeMissing files: JsonField> = JsonMissing.of(), + @JsonProperty("msg") @ExcludeMissing msg: JsonField = JsonMissing.of(), + @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(), + ) : this(files, msg, status, mutableMapOf()) + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun files(): Optional> = files.getOptional("files") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun msg(): Optional = msg.getOptional("msg") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun status(): Optional = status.getOptional("status") + + /** + * Returns the raw JSON value of [files]. + * + * Unlike [files], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("files") @ExcludeMissing fun _files(): JsonField> = files + + /** + * Returns the raw JSON value of [msg]. + * + * Unlike [msg], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("msg") @ExcludeMissing fun _msg(): JsonField = msg + + /** + * Returns the raw JSON value of [status]. + * + * Unlike [status], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("status") @ExcludeMissing fun _status(): JsonField = status + + @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 [FetchVerifyOtpResponse]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [FetchVerifyOtpResponse]. */ + class Builder internal constructor() { + + private var files: JsonField>? = null + private var msg: JsonField = JsonMissing.of() + private var status: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(fetchVerifyOtpResponse: FetchVerifyOtpResponse) = apply { + files = fetchVerifyOtpResponse.files.map { it.toMutableList() } + msg = fetchVerifyOtpResponse.msg + status = fetchVerifyOtpResponse.status + additionalProperties = fetchVerifyOtpResponse.additionalProperties.toMutableMap() + } + + fun files(files: List) = files(JsonField.of(files)) + + /** + * Sets [Builder.files] to an arbitrary JSON value. + * + * You should usually call [Builder.files] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun files(files: JsonField>) = apply { + this.files = files.map { it.toMutableList() } + } + + /** + * Adds a single [File] to [files]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addFile(file: File) = apply { + files = + (files ?: JsonField.of(mutableListOf())).also { checkKnown("files", it).add(file) } + } + + fun msg(msg: String) = msg(JsonField.of(msg)) + + /** + * Sets [Builder.msg] to an arbitrary JSON value. + * + * You should usually call [Builder.msg] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun msg(msg: JsonField) = apply { this.msg = msg } + + fun status(status: String) = status(JsonField.of(status)) + + /** + * Sets [Builder.status] to an arbitrary JSON value. + * + * You should usually call [Builder.status] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun status(status: JsonField) = apply { this.status = status } + + 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 [FetchVerifyOtpResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): FetchVerifyOtpResponse = + FetchVerifyOtpResponse( + (files ?: JsonMissing.of()).map { it.toImmutable() }, + msg, + status, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): FetchVerifyOtpResponse = apply { + if (validated) { + return@apply + } + + files().ifPresent { it.forEach { it.validate() } } + msg() + status() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 = + (files.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (msg.asKnown().isPresent) 1 else 0) + + (if (status.asKnown().isPresent) 1 else 0) + + class File + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val filename: JsonField, + private val url: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("filename") + @ExcludeMissing + filename: JsonField = JsonMissing.of(), + @JsonProperty("url") @ExcludeMissing url: JsonField = JsonMissing.of(), + ) : this(filename, url, mutableMapOf()) + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun filename(): Optional = filename.getOptional("filename") + + /** + * Direct download URL (cloud storage) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun url(): Optional = url.getOptional("url") + + /** + * Returns the raw JSON value of [filename]. + * + * Unlike [filename], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("filename") @ExcludeMissing fun _filename(): JsonField = filename + + /** + * Returns the raw JSON value of [url]. + * + * Unlike [url], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("url") @ExcludeMissing fun _url(): JsonField = url + + @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 [File]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [File]. */ + class Builder internal constructor() { + + private var filename: JsonField = JsonMissing.of() + private var url: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(file: File) = apply { + filename = file.filename + url = file.url + additionalProperties = file.additionalProperties.toMutableMap() + } + + fun filename(filename: String) = filename(JsonField.of(filename)) + + /** + * Sets [Builder.filename] to an arbitrary JSON value. + * + * You should usually call [Builder.filename] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun filename(filename: JsonField) = apply { this.filename = filename } + + /** Direct download URL (cloud storage) */ + fun url(url: String) = url(JsonField.of(url)) + + /** + * Sets [Builder.url] to an arbitrary JSON value. + * + * You should usually call [Builder.url] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun url(url: JsonField) = apply { this.url = url } + + 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 [File]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): File = File(filename, url, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): File = apply { + if (validated) { + return@apply + } + + filename() + url() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (filename.asKnown().isPresent) 1 else 0) + (if (url.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is File && + filename == other.filename && + url == other.url && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(filename, url, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "File{filename=$filename, url=$url, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is FetchVerifyOtpResponse && + files == other.files && + msg == other.msg && + status == other.status && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(files, msg, status, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "FetchVerifyOtpResponse{files=$files, msg=$msg, status=$status, additionalProperties=$additionalProperties}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/contractnote/ContractNoteParseParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/contractnote/ContractNoteParseParams.kt new file mode 100644 index 0000000..6c6ee9e --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/contractnote/ContractNoteParseParams.kt @@ -0,0 +1,742 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.contractnote + +import com.cas_parser.api.core.Enum +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonField +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.MultipartField +import com.cas_parser.api.core.Params +import com.cas_parser.api.core.http.Headers +import com.cas_parser.api.core.http.QueryParams +import com.cas_parser.api.core.toImmutable +import com.cas_parser.api.errors.CasParserInvalidDataException +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 + +/** + * This endpoint parses Contract Note PDF files from various brokers including Zerodha, Groww, + * Upstox, ICICI Securities, and others. + * + * **What is a Contract Note?** A contract note is a legal document that provides details of all + * trades executed by an investor. It includes: + * - Trade details with timestamps, quantities, and prices + * - Brokerage and charges breakdown + * - Settlement information + * - Regulatory compliance details + * + * **Supported Brokers:** + * - Zerodha Broking Limited + * - Groww Invest Tech Private Limited + * - Upstox (RKSV Securities) + * - ICICI Securities Limited + * - Auto-detection for unknown brokers + * + * **Key Features:** + * - **Auto-detection**: Automatically identifies broker type from PDF content + * - **Comprehensive parsing**: Extracts equity transactions, derivatives transactions, detailed + * trades, and charges + * - **Flexible input**: Accepts both file upload and URL-based PDF input + * - **Password protection**: Supports password-protected PDFs + * + * The API returns structured data including contract note information, client details, transaction + * summaries, and detailed trade-by-trade breakdowns. + */ +class ContractNoteParseParams +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Optional broker type override. If not provided, system will auto-detect. + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun brokerType(): Optional = body.brokerType() + + /** + * Password for the PDF file (usually PAN number for Zerodha) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun password(): Optional = body.password() + + /** + * Base64 encoded contract note PDF file + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun pdfFile(): Optional = body.pdfFile() + + /** + * URL to the contract note PDF file + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun pdfUrl(): Optional = body.pdfUrl() + + /** + * Returns the raw multipart value of [brokerType]. + * + * Unlike [brokerType], this method doesn't throw if the multipart field has an unexpected type. + */ + fun _brokerType(): MultipartField = body._brokerType() + + /** + * Returns the raw multipart value of [password]. + * + * Unlike [password], this method doesn't throw if the multipart field has an unexpected type. + */ + fun _password(): MultipartField = body._password() + + /** + * Returns the raw multipart value of [pdfFile]. + * + * Unlike [pdfFile], this method doesn't throw if the multipart field has an unexpected type. + */ + fun _pdfFile(): MultipartField = body._pdfFile() + + /** + * Returns the raw multipart value of [pdfUrl]. + * + * Unlike [pdfUrl], this method doesn't throw if the multipart field has an unexpected type. + */ + fun _pdfUrl(): MultipartField = body._pdfUrl() + + fun _additionalBodyProperties(): Map = body._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 { + + @JvmStatic fun none(): ContractNoteParseParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [ContractNoteParseParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ContractNoteParseParams]. */ + class Builder internal constructor() { + + private var body: Body.Builder = Body.builder() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(contractNoteParseParams: ContractNoteParseParams) = apply { + body = contractNoteParseParams.body.toBuilder() + additionalHeaders = contractNoteParseParams.additionalHeaders.toBuilder() + additionalQueryParams = contractNoteParseParams.additionalQueryParams.toBuilder() + } + + /** + * Sets the entire request body. + * + * This is generally only useful if you are already constructing the body separately. + * Otherwise, it's more convenient to use the top-level setters instead: + * - [brokerType] + * - [password] + * - [pdfFile] + * - [pdfUrl] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + /** Optional broker type override. If not provided, system will auto-detect. */ + fun brokerType(brokerType: BrokerType) = apply { body.brokerType(brokerType) } + + /** + * Sets [Builder.brokerType] to an arbitrary multipart value. + * + * You should usually call [Builder.brokerType] with a well-typed [BrokerType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun brokerType(brokerType: MultipartField) = apply { + body.brokerType(brokerType) + } + + /** Password for the PDF file (usually PAN number for Zerodha) */ + fun password(password: String) = apply { body.password(password) } + + /** + * Sets [Builder.password] to an arbitrary multipart value. + * + * You should usually call [Builder.password] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun password(password: MultipartField) = apply { body.password(password) } + + /** Base64 encoded contract note PDF file */ + fun pdfFile(pdfFile: String) = apply { body.pdfFile(pdfFile) } + + /** + * Sets [Builder.pdfFile] to an arbitrary multipart value. + * + * You should usually call [Builder.pdfFile] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun pdfFile(pdfFile: MultipartField) = apply { body.pdfFile(pdfFile) } + + /** URL to the contract note PDF file */ + fun pdfUrl(pdfUrl: String) = apply { body.pdfUrl(pdfUrl) } + + /** + * Sets [Builder.pdfUrl] to an arbitrary multipart value. + * + * You should usually call [Builder.pdfUrl] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun pdfUrl(pdfUrl: MultipartField) = apply { body.pdfUrl(pdfUrl) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) + } + + 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 [ContractNoteParseParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): ContractNoteParseParams = + ContractNoteParseParams( + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): Map> = + (mapOf( + "broker_type" to _brokerType(), + "password" to _password(), + "pdf_file" to _pdfFile(), + "pdf_url" to _pdfUrl(), + ) + _additionalBodyProperties().mapValues { (_, value) -> MultipartField.of(value) }) + .toImmutable() + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + class Body + private constructor( + private val brokerType: MultipartField, + private val password: MultipartField, + private val pdfFile: MultipartField, + private val pdfUrl: MultipartField, + private val additionalProperties: MutableMap, + ) { + + /** + * Optional broker type override. If not provided, system will auto-detect. + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun brokerType(): Optional = brokerType.value.getOptional("broker_type") + + /** + * Password for the PDF file (usually PAN number for Zerodha) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun password(): Optional = password.value.getOptional("password") + + /** + * Base64 encoded contract note PDF file + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun pdfFile(): Optional = pdfFile.value.getOptional("pdf_file") + + /** + * URL to the contract note PDF file + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun pdfUrl(): Optional = pdfUrl.value.getOptional("pdf_url") + + /** + * Returns the raw multipart value of [brokerType]. + * + * Unlike [brokerType], this method doesn't throw if the multipart field has an unexpected + * type. + */ + @JsonProperty("broker_type") + @ExcludeMissing + fun _brokerType(): MultipartField = brokerType + + /** + * Returns the raw multipart value of [password]. + * + * Unlike [password], this method doesn't throw if the multipart field has an unexpected + * type. + */ + @JsonProperty("password") @ExcludeMissing fun _password(): MultipartField = password + + /** + * Returns the raw multipart value of [pdfFile]. + * + * Unlike [pdfFile], this method doesn't throw if the multipart field has an unexpected + * type. + */ + @JsonProperty("pdf_file") @ExcludeMissing fun _pdfFile(): MultipartField = pdfFile + + /** + * Returns the raw multipart value of [pdfUrl]. + * + * Unlike [pdfUrl], this method doesn't throw if the multipart field has an unexpected type. + */ + @JsonProperty("pdf_url") @ExcludeMissing fun _pdfUrl(): MultipartField = pdfUrl + + @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 [Body]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var brokerType: MultipartField = MultipartField.of(null) + private var password: MultipartField = MultipartField.of(null) + private var pdfFile: MultipartField = MultipartField.of(null) + private var pdfUrl: MultipartField = MultipartField.of(null) + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + brokerType = body.brokerType + password = body.password + pdfFile = body.pdfFile + pdfUrl = body.pdfUrl + additionalProperties = body.additionalProperties.toMutableMap() + } + + /** Optional broker type override. If not provided, system will auto-detect. */ + fun brokerType(brokerType: BrokerType) = brokerType(MultipartField.of(brokerType)) + + /** + * Sets [Builder.brokerType] to an arbitrary multipart value. + * + * You should usually call [Builder.brokerType] with a well-typed [BrokerType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun brokerType(brokerType: MultipartField) = apply { + this.brokerType = brokerType + } + + /** Password for the PDF file (usually PAN number for Zerodha) */ + fun password(password: String) = password(MultipartField.of(password)) + + /** + * Sets [Builder.password] to an arbitrary multipart value. + * + * You should usually call [Builder.password] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun password(password: MultipartField) = apply { this.password = password } + + /** Base64 encoded contract note PDF file */ + fun pdfFile(pdfFile: String) = pdfFile(MultipartField.of(pdfFile)) + + /** + * Sets [Builder.pdfFile] to an arbitrary multipart value. + * + * You should usually call [Builder.pdfFile] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun pdfFile(pdfFile: MultipartField) = apply { this.pdfFile = pdfFile } + + /** URL to the contract note PDF file */ + fun pdfUrl(pdfUrl: String) = pdfUrl(MultipartField.of(pdfUrl)) + + /** + * Sets [Builder.pdfUrl] to an arbitrary multipart value. + * + * You should usually call [Builder.pdfUrl] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun pdfUrl(pdfUrl: MultipartField) = apply { this.pdfUrl = pdfUrl } + + 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 [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Body = + Body(brokerType, password, pdfFile, pdfUrl, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + brokerType().ifPresent { it.validate() } + password() + pdfFile() + pdfUrl() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + false + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + brokerType == other.brokerType && + password == other.password && + pdfFile == other.pdfFile && + pdfUrl == other.pdfUrl && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(brokerType, password, pdfFile, pdfUrl, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{brokerType=$brokerType, password=$password, pdfFile=$pdfFile, pdfUrl=$pdfUrl, additionalProperties=$additionalProperties}" + } + + /** Optional broker type override. If not provided, system will auto-detect. */ + class BrokerType @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val ZERODHA = of("zerodha") + + @JvmField val GROWW = of("groww") + + @JvmField val UPSTOX = of("upstox") + + @JvmField val ICICI = of("icici") + + @JvmStatic fun of(value: String) = BrokerType(JsonField.of(value)) + } + + /** An enum containing [BrokerType]'s known values. */ + enum class Known { + ZERODHA, + GROWW, + UPSTOX, + ICICI, + } + + /** + * An enum containing [BrokerType]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [BrokerType] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + ZERODHA, + GROWW, + UPSTOX, + ICICI, + /** + * An enum member indicating that [BrokerType] was instantiated with an unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + ZERODHA -> Value.ZERODHA + GROWW -> Value.GROWW + UPSTOX -> Value.UPSTOX + ICICI -> Value.ICICI + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws CasParserInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + ZERODHA -> Known.ZERODHA + GROWW -> Known.GROWW + UPSTOX -> Known.UPSTOX + ICICI -> Known.ICICI + else -> throw CasParserInvalidDataException("Unknown BrokerType: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws CasParserInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CasParserInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): BrokerType = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is BrokerType && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ContractNoteParseParams && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = Objects.hash(body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "ContractNoteParseParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/contractnote/ContractNoteParseResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/contractnote/ContractNoteParseResponse.kt new file mode 100644 index 0000000..370d8b0 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/contractnote/ContractNoteParseResponse.kt @@ -0,0 +1,3934 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.contractnote + +import com.cas_parser.api.core.Enum +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonField +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.checkKnown +import com.cas_parser.api.core.toImmutable +import com.cas_parser.api.errors.CasParserInvalidDataException +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.time.LocalDate +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +class ContractNoteParseResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val data: JsonField, + private val msg: JsonField, + private val status: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("data") @ExcludeMissing data: JsonField = JsonMissing.of(), + @JsonProperty("msg") @ExcludeMissing msg: JsonField = JsonMissing.of(), + @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(), + ) : this(data, msg, status, mutableMapOf()) + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun data(): Optional = data.getOptional("data") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun msg(): Optional = msg.getOptional("msg") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun status(): Optional = status.getOptional("status") + + /** + * Returns the raw JSON value of [data]. + * + * Unlike [data], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("data") @ExcludeMissing fun _data(): JsonField = data + + /** + * Returns the raw JSON value of [msg]. + * + * Unlike [msg], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("msg") @ExcludeMissing fun _msg(): JsonField = msg + + /** + * Returns the raw JSON value of [status]. + * + * Unlike [status], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("status") @ExcludeMissing fun _status(): JsonField = status + + @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 [ContractNoteParseResponse]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ContractNoteParseResponse]. */ + class Builder internal constructor() { + + private var data: JsonField = JsonMissing.of() + private var msg: JsonField = JsonMissing.of() + private var status: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(contractNoteParseResponse: ContractNoteParseResponse) = apply { + data = contractNoteParseResponse.data + msg = contractNoteParseResponse.msg + status = contractNoteParseResponse.status + additionalProperties = contractNoteParseResponse.additionalProperties.toMutableMap() + } + + fun data(data: Data) = data(JsonField.of(data)) + + /** + * Sets [Builder.data] to an arbitrary JSON value. + * + * You should usually call [Builder.data] with a well-typed [Data] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun data(data: JsonField) = apply { this.data = data } + + fun msg(msg: String) = msg(JsonField.of(msg)) + + /** + * Sets [Builder.msg] to an arbitrary JSON value. + * + * You should usually call [Builder.msg] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun msg(msg: JsonField) = apply { this.msg = msg } + + fun status(status: String) = status(JsonField.of(status)) + + /** + * Sets [Builder.status] to an arbitrary JSON value. + * + * You should usually call [Builder.status] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun status(status: JsonField) = apply { this.status = status } + + 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 [ContractNoteParseResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): ContractNoteParseResponse = + ContractNoteParseResponse(data, msg, status, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): ContractNoteParseResponse = apply { + if (validated) { + return@apply + } + + data().ifPresent { it.validate() } + msg() + status() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 = + (data.asKnown().getOrNull()?.validity() ?: 0) + + (if (msg.asKnown().isPresent) 1 else 0) + + (if (status.asKnown().isPresent) 1 else 0) + + class Data + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val brokerInfo: JsonField, + private val chargesSummary: JsonField, + private val clientInfo: JsonField, + private val contractNoteInfo: JsonField, + private val derivativesTransactions: JsonField>, + private val detailedTrades: JsonField>, + private val equityTransactions: JsonField>, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("broker_info") + @ExcludeMissing + brokerInfo: JsonField = JsonMissing.of(), + @JsonProperty("charges_summary") + @ExcludeMissing + chargesSummary: JsonField = JsonMissing.of(), + @JsonProperty("client_info") + @ExcludeMissing + clientInfo: JsonField = JsonMissing.of(), + @JsonProperty("contract_note_info") + @ExcludeMissing + contractNoteInfo: JsonField = JsonMissing.of(), + @JsonProperty("derivatives_transactions") + @ExcludeMissing + derivativesTransactions: JsonField> = JsonMissing.of(), + @JsonProperty("detailed_trades") + @ExcludeMissing + detailedTrades: JsonField> = JsonMissing.of(), + @JsonProperty("equity_transactions") + @ExcludeMissing + equityTransactions: JsonField> = JsonMissing.of(), + ) : this( + brokerInfo, + chargesSummary, + clientInfo, + contractNoteInfo, + derivativesTransactions, + detailedTrades, + equityTransactions, + mutableMapOf(), + ) + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun brokerInfo(): Optional = brokerInfo.getOptional("broker_info") + + /** + * Breakdown of various charges and fees + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun chargesSummary(): Optional = + chargesSummary.getOptional("charges_summary") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun clientInfo(): Optional = clientInfo.getOptional("client_info") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun contractNoteInfo(): Optional = + contractNoteInfo.getOptional("contract_note_info") + + /** + * Summary of derivatives transactions + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun derivativesTransactions(): Optional> = + derivativesTransactions.getOptional("derivatives_transactions") + + /** + * Detailed breakdown of all individual trades + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun detailedTrades(): Optional> = + detailedTrades.getOptional("detailed_trades") + + /** + * Summary of equity transactions grouped by security + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun equityTransactions(): Optional> = + equityTransactions.getOptional("equity_transactions") + + /** + * Returns the raw JSON value of [brokerInfo]. + * + * Unlike [brokerInfo], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("broker_info") + @ExcludeMissing + fun _brokerInfo(): JsonField = brokerInfo + + /** + * Returns the raw JSON value of [chargesSummary]. + * + * Unlike [chargesSummary], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("charges_summary") + @ExcludeMissing + fun _chargesSummary(): JsonField = chargesSummary + + /** + * Returns the raw JSON value of [clientInfo]. + * + * Unlike [clientInfo], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("client_info") + @ExcludeMissing + fun _clientInfo(): JsonField = clientInfo + + /** + * Returns the raw JSON value of [contractNoteInfo]. + * + * Unlike [contractNoteInfo], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("contract_note_info") + @ExcludeMissing + fun _contractNoteInfo(): JsonField = contractNoteInfo + + /** + * Returns the raw JSON value of [derivativesTransactions]. + * + * Unlike [derivativesTransactions], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("derivatives_transactions") + @ExcludeMissing + fun _derivativesTransactions(): JsonField> = + derivativesTransactions + + /** + * Returns the raw JSON value of [detailedTrades]. + * + * Unlike [detailedTrades], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("detailed_trades") + @ExcludeMissing + fun _detailedTrades(): JsonField> = detailedTrades + + /** + * Returns the raw JSON value of [equityTransactions]. + * + * Unlike [equityTransactions], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("equity_transactions") + @ExcludeMissing + fun _equityTransactions(): JsonField> = equityTransactions + + @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 [Data]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Data]. */ + class Builder internal constructor() { + + private var brokerInfo: JsonField = JsonMissing.of() + private var chargesSummary: JsonField = JsonMissing.of() + private var clientInfo: JsonField = JsonMissing.of() + private var contractNoteInfo: JsonField = JsonMissing.of() + private var derivativesTransactions: JsonField>? = + null + private var detailedTrades: JsonField>? = null + private var equityTransactions: JsonField>? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(data: Data) = apply { + brokerInfo = data.brokerInfo + chargesSummary = data.chargesSummary + clientInfo = data.clientInfo + contractNoteInfo = data.contractNoteInfo + derivativesTransactions = data.derivativesTransactions.map { it.toMutableList() } + detailedTrades = data.detailedTrades.map { it.toMutableList() } + equityTransactions = data.equityTransactions.map { it.toMutableList() } + additionalProperties = data.additionalProperties.toMutableMap() + } + + fun brokerInfo(brokerInfo: BrokerInfo) = brokerInfo(JsonField.of(brokerInfo)) + + /** + * Sets [Builder.brokerInfo] to an arbitrary JSON value. + * + * You should usually call [Builder.brokerInfo] with a well-typed [BrokerInfo] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun brokerInfo(brokerInfo: JsonField) = apply { + this.brokerInfo = brokerInfo + } + + /** Breakdown of various charges and fees */ + fun chargesSummary(chargesSummary: ChargesSummary) = + chargesSummary(JsonField.of(chargesSummary)) + + /** + * Sets [Builder.chargesSummary] to an arbitrary JSON value. + * + * You should usually call [Builder.chargesSummary] with a well-typed [ChargesSummary] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun chargesSummary(chargesSummary: JsonField) = apply { + this.chargesSummary = chargesSummary + } + + fun clientInfo(clientInfo: ClientInfo) = clientInfo(JsonField.of(clientInfo)) + + /** + * Sets [Builder.clientInfo] to an arbitrary JSON value. + * + * You should usually call [Builder.clientInfo] with a well-typed [ClientInfo] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun clientInfo(clientInfo: JsonField) = apply { + this.clientInfo = clientInfo + } + + fun contractNoteInfo(contractNoteInfo: ContractNoteInfo) = + contractNoteInfo(JsonField.of(contractNoteInfo)) + + /** + * Sets [Builder.contractNoteInfo] to an arbitrary JSON value. + * + * You should usually call [Builder.contractNoteInfo] with a well-typed + * [ContractNoteInfo] value instead. This method is primarily for setting the field to + * an undocumented or not yet supported value. + */ + fun contractNoteInfo(contractNoteInfo: JsonField) = apply { + this.contractNoteInfo = contractNoteInfo + } + + /** Summary of derivatives transactions */ + fun derivativesTransactions(derivativesTransactions: List) = + derivativesTransactions(JsonField.of(derivativesTransactions)) + + /** + * Sets [Builder.derivativesTransactions] to an arbitrary JSON value. + * + * You should usually call [Builder.derivativesTransactions] with a well-typed + * `List` value instead. This method is primarily for setting + * the field to an undocumented or not yet supported value. + */ + fun derivativesTransactions( + derivativesTransactions: JsonField> + ) = apply { + this.derivativesTransactions = derivativesTransactions.map { it.toMutableList() } + } + + /** + * Adds a single [DerivativesTransaction] to [derivativesTransactions]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addDerivativesTransaction(derivativesTransaction: DerivativesTransaction) = apply { + derivativesTransactions = + (derivativesTransactions ?: JsonField.of(mutableListOf())).also { + checkKnown("derivativesTransactions", it).add(derivativesTransaction) + } + } + + /** Detailed breakdown of all individual trades */ + fun detailedTrades(detailedTrades: List) = + detailedTrades(JsonField.of(detailedTrades)) + + /** + * Sets [Builder.detailedTrades] to an arbitrary JSON value. + * + * You should usually call [Builder.detailedTrades] with a well-typed + * `List` value instead. This method is primarily for setting the field + * to an undocumented or not yet supported value. + */ + fun detailedTrades(detailedTrades: JsonField>) = apply { + this.detailedTrades = detailedTrades.map { it.toMutableList() } + } + + /** + * Adds a single [DetailedTrade] to [detailedTrades]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addDetailedTrade(detailedTrade: DetailedTrade) = apply { + detailedTrades = + (detailedTrades ?: JsonField.of(mutableListOf())).also { + checkKnown("detailedTrades", it).add(detailedTrade) + } + } + + /** Summary of equity transactions grouped by security */ + fun equityTransactions(equityTransactions: List) = + equityTransactions(JsonField.of(equityTransactions)) + + /** + * Sets [Builder.equityTransactions] to an arbitrary JSON value. + * + * You should usually call [Builder.equityTransactions] with a well-typed + * `List` value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun equityTransactions(equityTransactions: JsonField>) = apply { + this.equityTransactions = equityTransactions.map { it.toMutableList() } + } + + /** + * Adds a single [EquityTransaction] to [equityTransactions]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addEquityTransaction(equityTransaction: EquityTransaction) = apply { + equityTransactions = + (equityTransactions ?: JsonField.of(mutableListOf())).also { + checkKnown("equityTransactions", it).add(equityTransaction) + } + } + + 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 [Data]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Data = + Data( + brokerInfo, + chargesSummary, + clientInfo, + contractNoteInfo, + (derivativesTransactions ?: JsonMissing.of()).map { it.toImmutable() }, + (detailedTrades ?: JsonMissing.of()).map { it.toImmutable() }, + (equityTransactions ?: JsonMissing.of()).map { it.toImmutable() }, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Data = apply { + if (validated) { + return@apply + } + + brokerInfo().ifPresent { it.validate() } + chargesSummary().ifPresent { it.validate() } + clientInfo().ifPresent { it.validate() } + contractNoteInfo().ifPresent { it.validate() } + derivativesTransactions().ifPresent { it.forEach { it.validate() } } + detailedTrades().ifPresent { it.forEach { it.validate() } } + equityTransactions().ifPresent { it.forEach { it.validate() } } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 = + (brokerInfo.asKnown().getOrNull()?.validity() ?: 0) + + (chargesSummary.asKnown().getOrNull()?.validity() ?: 0) + + (clientInfo.asKnown().getOrNull()?.validity() ?: 0) + + (contractNoteInfo.asKnown().getOrNull()?.validity() ?: 0) + + (derivativesTransactions.asKnown().getOrNull()?.sumOf { it.validity().toInt() } + ?: 0) + + (detailedTrades.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (equityTransactions.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + class BrokerInfo + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val brokerType: JsonField, + private val name: JsonField, + private val sebiRegistration: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("broker_type") + @ExcludeMissing + brokerType: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("sebi_registration") + @ExcludeMissing + sebiRegistration: JsonField = JsonMissing.of(), + ) : this(brokerType, name, sebiRegistration, mutableMapOf()) + + /** + * Auto-detected or specified broker type + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun brokerType(): Optional = brokerType.getOptional("broker_type") + + /** + * Broker company name + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun name(): Optional = name.getOptional("name") + + /** + * SEBI registration number of the broker + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun sebiRegistration(): Optional = + sebiRegistration.getOptional("sebi_registration") + + /** + * Returns the raw JSON value of [brokerType]. + * + * Unlike [brokerType], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("broker_type") + @ExcludeMissing + fun _brokerType(): JsonField = brokerType + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + + /** + * Returns the raw JSON value of [sebiRegistration]. + * + * Unlike [sebiRegistration], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("sebi_registration") + @ExcludeMissing + fun _sebiRegistration(): JsonField = sebiRegistration + + @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 [BrokerInfo]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [BrokerInfo]. */ + class Builder internal constructor() { + + private var brokerType: JsonField = JsonMissing.of() + private var name: JsonField = JsonMissing.of() + private var sebiRegistration: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(brokerInfo: BrokerInfo) = apply { + brokerType = brokerInfo.brokerType + name = brokerInfo.name + sebiRegistration = brokerInfo.sebiRegistration + additionalProperties = brokerInfo.additionalProperties.toMutableMap() + } + + /** Auto-detected or specified broker type */ + fun brokerType(brokerType: BrokerType) = brokerType(JsonField.of(brokerType)) + + /** + * Sets [Builder.brokerType] to an arbitrary JSON value. + * + * You should usually call [Builder.brokerType] with a well-typed [BrokerType] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun brokerType(brokerType: JsonField) = apply { + this.brokerType = brokerType + } + + /** Broker company name */ + fun name(name: String) = name(JsonField.of(name)) + + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun name(name: JsonField) = apply { this.name = name } + + /** SEBI registration number of the broker */ + fun sebiRegistration(sebiRegistration: String) = + sebiRegistration(JsonField.of(sebiRegistration)) + + /** + * Sets [Builder.sebiRegistration] to an arbitrary JSON value. + * + * You should usually call [Builder.sebiRegistration] with a well-typed [String] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun sebiRegistration(sebiRegistration: JsonField) = apply { + this.sebiRegistration = sebiRegistration + } + + 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 [BrokerInfo]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): BrokerInfo = + BrokerInfo( + brokerType, + name, + sebiRegistration, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): BrokerInfo = apply { + if (validated) { + return@apply + } + + brokerType().ifPresent { it.validate() } + name() + sebiRegistration() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 = + (brokerType.asKnown().getOrNull()?.validity() ?: 0) + + (if (name.asKnown().isPresent) 1 else 0) + + (if (sebiRegistration.asKnown().isPresent) 1 else 0) + + /** Auto-detected or specified broker type */ + class BrokerType + @JsonCreator + private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that + * doesn't match any known member, and you want to know that value. For example, if + * the SDK is on an older version than the API, then the API may respond with new + * members that the SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val ZERODHA = of("zerodha") + + @JvmField val GROWW = of("groww") + + @JvmField val UPSTOX = of("upstox") + + @JvmField val ICICI = of("icici") + + @JvmField val UNKNOWN = of("unknown") + + @JvmStatic fun of(value: String) = BrokerType(JsonField.of(value)) + } + + /** An enum containing [BrokerType]'s known values. */ + enum class Known { + ZERODHA, + GROWW, + UPSTOX, + ICICI, + UNKNOWN, + } + + /** + * An enum containing [BrokerType]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [BrokerType] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, + * if the SDK is on an older version than the API, then the API may respond with + * new members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + ZERODHA, + GROWW, + UPSTOX, + ICICI, + UNKNOWN, + /** + * An enum member indicating that [BrokerType] was instantiated with an unknown + * value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if + * you want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + ZERODHA -> Value.ZERODHA + GROWW -> Value.GROWW + UPSTOX -> Value.UPSTOX + ICICI -> Value.ICICI + UNKNOWN -> Value.UNKNOWN + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and + * don't want to throw for the unknown case. + * + * @throws CasParserInvalidDataException if this class instance's value is a not a + * known member. + */ + fun known(): Known = + when (this) { + ZERODHA -> Known.ZERODHA + GROWW -> Known.GROWW + UPSTOX -> Known.UPSTOX + ICICI -> Known.ICICI + UNKNOWN -> Known.UNKNOWN + else -> throw CasParserInvalidDataException("Unknown BrokerType: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws CasParserInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CasParserInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): BrokerType = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is BrokerType && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is BrokerInfo && + brokerType == other.brokerType && + name == other.name && + sebiRegistration == other.sebiRegistration && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(brokerType, name, sebiRegistration, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "BrokerInfo{brokerType=$brokerType, name=$name, sebiRegistration=$sebiRegistration, additionalProperties=$additionalProperties}" + } + + /** Breakdown of various charges and fees */ + class ChargesSummary + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val cgst: JsonField, + private val exchangeTransactionCharges: JsonField, + private val igst: JsonField, + private val netAmountReceivablePayable: JsonField, + private val payInPayOutObligation: JsonField, + private val sebiTurnoverFees: JsonField, + private val securitiesTransactionTax: JsonField, + private val sgst: JsonField, + private val stampDuty: JsonField, + private val taxableValueBrokerage: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("cgst") @ExcludeMissing cgst: JsonField = JsonMissing.of(), + @JsonProperty("exchange_transaction_charges") + @ExcludeMissing + exchangeTransactionCharges: JsonField = JsonMissing.of(), + @JsonProperty("igst") @ExcludeMissing igst: JsonField = JsonMissing.of(), + @JsonProperty("net_amount_receivable_payable") + @ExcludeMissing + netAmountReceivablePayable: JsonField = JsonMissing.of(), + @JsonProperty("pay_in_pay_out_obligation") + @ExcludeMissing + payInPayOutObligation: JsonField = JsonMissing.of(), + @JsonProperty("sebi_turnover_fees") + @ExcludeMissing + sebiTurnoverFees: JsonField = JsonMissing.of(), + @JsonProperty("securities_transaction_tax") + @ExcludeMissing + securitiesTransactionTax: JsonField = JsonMissing.of(), + @JsonProperty("sgst") @ExcludeMissing sgst: JsonField = JsonMissing.of(), + @JsonProperty("stamp_duty") + @ExcludeMissing + stampDuty: JsonField = JsonMissing.of(), + @JsonProperty("taxable_value_brokerage") + @ExcludeMissing + taxableValueBrokerage: JsonField = JsonMissing.of(), + ) : this( + cgst, + exchangeTransactionCharges, + igst, + netAmountReceivablePayable, + payInPayOutObligation, + sebiTurnoverFees, + securitiesTransactionTax, + sgst, + stampDuty, + taxableValueBrokerage, + mutableMapOf(), + ) + + /** + * Central GST amount + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun cgst(): Optional = cgst.getOptional("cgst") + + /** + * Exchange transaction charges + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun exchangeTransactionCharges(): Optional = + exchangeTransactionCharges.getOptional("exchange_transaction_charges") + + /** + * Integrated GST amount + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun igst(): Optional = igst.getOptional("igst") + + /** + * Final net amount receivable or payable + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun netAmountReceivablePayable(): Optional = + netAmountReceivablePayable.getOptional("net_amount_receivable_payable") + + /** + * Net pay-in/pay-out obligation + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun payInPayOutObligation(): Optional = + payInPayOutObligation.getOptional("pay_in_pay_out_obligation") + + /** + * SEBI turnover fees + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun sebiTurnoverFees(): Optional = + sebiTurnoverFees.getOptional("sebi_turnover_fees") + + /** + * Securities Transaction Tax + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun securitiesTransactionTax(): Optional = + securitiesTransactionTax.getOptional("securities_transaction_tax") + + /** + * State GST amount + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun sgst(): Optional = sgst.getOptional("sgst") + + /** + * Stamp duty charges + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun stampDuty(): Optional = stampDuty.getOptional("stamp_duty") + + /** + * Taxable brokerage amount + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun taxableValueBrokerage(): Optional = + taxableValueBrokerage.getOptional("taxable_value_brokerage") + + /** + * Returns the raw JSON value of [cgst]. + * + * Unlike [cgst], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("cgst") @ExcludeMissing fun _cgst(): JsonField = cgst + + /** + * Returns the raw JSON value of [exchangeTransactionCharges]. + * + * Unlike [exchangeTransactionCharges], this method doesn't throw if the JSON field has + * an unexpected type. + */ + @JsonProperty("exchange_transaction_charges") + @ExcludeMissing + fun _exchangeTransactionCharges(): JsonField = exchangeTransactionCharges + + /** + * Returns the raw JSON value of [igst]. + * + * Unlike [igst], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("igst") @ExcludeMissing fun _igst(): JsonField = igst + + /** + * Returns the raw JSON value of [netAmountReceivablePayable]. + * + * Unlike [netAmountReceivablePayable], this method doesn't throw if the JSON field has + * an unexpected type. + */ + @JsonProperty("net_amount_receivable_payable") + @ExcludeMissing + fun _netAmountReceivablePayable(): JsonField = netAmountReceivablePayable + + /** + * Returns the raw JSON value of [payInPayOutObligation]. + * + * Unlike [payInPayOutObligation], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("pay_in_pay_out_obligation") + @ExcludeMissing + fun _payInPayOutObligation(): JsonField = payInPayOutObligation + + /** + * Returns the raw JSON value of [sebiTurnoverFees]. + * + * Unlike [sebiTurnoverFees], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("sebi_turnover_fees") + @ExcludeMissing + fun _sebiTurnoverFees(): JsonField = sebiTurnoverFees + + /** + * Returns the raw JSON value of [securitiesTransactionTax]. + * + * Unlike [securitiesTransactionTax], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("securities_transaction_tax") + @ExcludeMissing + fun _securitiesTransactionTax(): JsonField = securitiesTransactionTax + + /** + * Returns the raw JSON value of [sgst]. + * + * Unlike [sgst], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("sgst") @ExcludeMissing fun _sgst(): JsonField = sgst + + /** + * Returns the raw JSON value of [stampDuty]. + * + * Unlike [stampDuty], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("stamp_duty") + @ExcludeMissing + fun _stampDuty(): JsonField = stampDuty + + /** + * Returns the raw JSON value of [taxableValueBrokerage]. + * + * Unlike [taxableValueBrokerage], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("taxable_value_brokerage") + @ExcludeMissing + fun _taxableValueBrokerage(): JsonField = taxableValueBrokerage + + @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 [ChargesSummary]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ChargesSummary]. */ + class Builder internal constructor() { + + private var cgst: JsonField = JsonMissing.of() + private var exchangeTransactionCharges: JsonField = JsonMissing.of() + private var igst: JsonField = JsonMissing.of() + private var netAmountReceivablePayable: JsonField = JsonMissing.of() + private var payInPayOutObligation: JsonField = JsonMissing.of() + private var sebiTurnoverFees: JsonField = JsonMissing.of() + private var securitiesTransactionTax: JsonField = JsonMissing.of() + private var sgst: JsonField = JsonMissing.of() + private var stampDuty: JsonField = JsonMissing.of() + private var taxableValueBrokerage: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(chargesSummary: ChargesSummary) = apply { + cgst = chargesSummary.cgst + exchangeTransactionCharges = chargesSummary.exchangeTransactionCharges + igst = chargesSummary.igst + netAmountReceivablePayable = chargesSummary.netAmountReceivablePayable + payInPayOutObligation = chargesSummary.payInPayOutObligation + sebiTurnoverFees = chargesSummary.sebiTurnoverFees + securitiesTransactionTax = chargesSummary.securitiesTransactionTax + sgst = chargesSummary.sgst + stampDuty = chargesSummary.stampDuty + taxableValueBrokerage = chargesSummary.taxableValueBrokerage + additionalProperties = chargesSummary.additionalProperties.toMutableMap() + } + + /** Central GST amount */ + fun cgst(cgst: Float) = cgst(JsonField.of(cgst)) + + /** + * Sets [Builder.cgst] to an arbitrary JSON value. + * + * You should usually call [Builder.cgst] with a well-typed [Float] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun cgst(cgst: JsonField) = apply { this.cgst = cgst } + + /** Exchange transaction charges */ + fun exchangeTransactionCharges(exchangeTransactionCharges: Float) = + exchangeTransactionCharges(JsonField.of(exchangeTransactionCharges)) + + /** + * Sets [Builder.exchangeTransactionCharges] to an arbitrary JSON value. + * + * You should usually call [Builder.exchangeTransactionCharges] with a well-typed + * [Float] value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun exchangeTransactionCharges(exchangeTransactionCharges: JsonField) = + apply { + this.exchangeTransactionCharges = exchangeTransactionCharges + } + + /** Integrated GST amount */ + fun igst(igst: Float) = igst(JsonField.of(igst)) + + /** + * Sets [Builder.igst] to an arbitrary JSON value. + * + * You should usually call [Builder.igst] with a well-typed [Float] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun igst(igst: JsonField) = apply { this.igst = igst } + + /** Final net amount receivable or payable */ + fun netAmountReceivablePayable(netAmountReceivablePayable: Float) = + netAmountReceivablePayable(JsonField.of(netAmountReceivablePayable)) + + /** + * Sets [Builder.netAmountReceivablePayable] to an arbitrary JSON value. + * + * You should usually call [Builder.netAmountReceivablePayable] with a well-typed + * [Float] value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun netAmountReceivablePayable(netAmountReceivablePayable: JsonField) = + apply { + this.netAmountReceivablePayable = netAmountReceivablePayable + } + + /** Net pay-in/pay-out obligation */ + fun payInPayOutObligation(payInPayOutObligation: Float) = + payInPayOutObligation(JsonField.of(payInPayOutObligation)) + + /** + * Sets [Builder.payInPayOutObligation] to an arbitrary JSON value. + * + * You should usually call [Builder.payInPayOutObligation] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun payInPayOutObligation(payInPayOutObligation: JsonField) = apply { + this.payInPayOutObligation = payInPayOutObligation + } + + /** SEBI turnover fees */ + fun sebiTurnoverFees(sebiTurnoverFees: Float) = + sebiTurnoverFees(JsonField.of(sebiTurnoverFees)) + + /** + * Sets [Builder.sebiTurnoverFees] to an arbitrary JSON value. + * + * You should usually call [Builder.sebiTurnoverFees] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun sebiTurnoverFees(sebiTurnoverFees: JsonField) = apply { + this.sebiTurnoverFees = sebiTurnoverFees + } + + /** Securities Transaction Tax */ + fun securitiesTransactionTax(securitiesTransactionTax: Float) = + securitiesTransactionTax(JsonField.of(securitiesTransactionTax)) + + /** + * Sets [Builder.securitiesTransactionTax] to an arbitrary JSON value. + * + * You should usually call [Builder.securitiesTransactionTax] with a well-typed + * [Float] value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun securitiesTransactionTax(securitiesTransactionTax: JsonField) = apply { + this.securitiesTransactionTax = securitiesTransactionTax + } + + /** State GST amount */ + fun sgst(sgst: Float) = sgst(JsonField.of(sgst)) + + /** + * Sets [Builder.sgst] to an arbitrary JSON value. + * + * You should usually call [Builder.sgst] with a well-typed [Float] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun sgst(sgst: JsonField) = apply { this.sgst = sgst } + + /** Stamp duty charges */ + fun stampDuty(stampDuty: Float) = stampDuty(JsonField.of(stampDuty)) + + /** + * Sets [Builder.stampDuty] to an arbitrary JSON value. + * + * You should usually call [Builder.stampDuty] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun stampDuty(stampDuty: JsonField) = apply { this.stampDuty = stampDuty } + + /** Taxable brokerage amount */ + fun taxableValueBrokerage(taxableValueBrokerage: Float) = + taxableValueBrokerage(JsonField.of(taxableValueBrokerage)) + + /** + * Sets [Builder.taxableValueBrokerage] to an arbitrary JSON value. + * + * You should usually call [Builder.taxableValueBrokerage] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun taxableValueBrokerage(taxableValueBrokerage: JsonField) = apply { + this.taxableValueBrokerage = taxableValueBrokerage + } + + 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 [ChargesSummary]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): ChargesSummary = + ChargesSummary( + cgst, + exchangeTransactionCharges, + igst, + netAmountReceivablePayable, + payInPayOutObligation, + sebiTurnoverFees, + securitiesTransactionTax, + sgst, + stampDuty, + taxableValueBrokerage, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): ChargesSummary = apply { + if (validated) { + return@apply + } + + cgst() + exchangeTransactionCharges() + igst() + netAmountReceivablePayable() + payInPayOutObligation() + sebiTurnoverFees() + securitiesTransactionTax() + sgst() + stampDuty() + taxableValueBrokerage() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (cgst.asKnown().isPresent) 1 else 0) + + (if (exchangeTransactionCharges.asKnown().isPresent) 1 else 0) + + (if (igst.asKnown().isPresent) 1 else 0) + + (if (netAmountReceivablePayable.asKnown().isPresent) 1 else 0) + + (if (payInPayOutObligation.asKnown().isPresent) 1 else 0) + + (if (sebiTurnoverFees.asKnown().isPresent) 1 else 0) + + (if (securitiesTransactionTax.asKnown().isPresent) 1 else 0) + + (if (sgst.asKnown().isPresent) 1 else 0) + + (if (stampDuty.asKnown().isPresent) 1 else 0) + + (if (taxableValueBrokerage.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ChargesSummary && + cgst == other.cgst && + exchangeTransactionCharges == other.exchangeTransactionCharges && + igst == other.igst && + netAmountReceivablePayable == other.netAmountReceivablePayable && + payInPayOutObligation == other.payInPayOutObligation && + sebiTurnoverFees == other.sebiTurnoverFees && + securitiesTransactionTax == other.securitiesTransactionTax && + sgst == other.sgst && + stampDuty == other.stampDuty && + taxableValueBrokerage == other.taxableValueBrokerage && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + cgst, + exchangeTransactionCharges, + igst, + netAmountReceivablePayable, + payInPayOutObligation, + sebiTurnoverFees, + securitiesTransactionTax, + sgst, + stampDuty, + taxableValueBrokerage, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ChargesSummary{cgst=$cgst, exchangeTransactionCharges=$exchangeTransactionCharges, igst=$igst, netAmountReceivablePayable=$netAmountReceivablePayable, payInPayOutObligation=$payInPayOutObligation, sebiTurnoverFees=$sebiTurnoverFees, securitiesTransactionTax=$securitiesTransactionTax, sgst=$sgst, stampDuty=$stampDuty, taxableValueBrokerage=$taxableValueBrokerage, additionalProperties=$additionalProperties}" + } + + class ClientInfo + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val address: JsonField, + private val gstStateCode: JsonField, + private val name: JsonField, + private val pan: JsonField, + private val placeOfSupply: JsonField, + private val ucc: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("address") + @ExcludeMissing + address: JsonField = JsonMissing.of(), + @JsonProperty("gst_state_code") + @ExcludeMissing + gstStateCode: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("pan") @ExcludeMissing pan: JsonField = JsonMissing.of(), + @JsonProperty("place_of_supply") + @ExcludeMissing + placeOfSupply: JsonField = JsonMissing.of(), + @JsonProperty("ucc") @ExcludeMissing ucc: JsonField = JsonMissing.of(), + ) : this(address, gstStateCode, name, pan, placeOfSupply, ucc, mutableMapOf()) + + /** + * Client address + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun address(): Optional = address.getOptional("address") + + /** + * GST state code + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun gstStateCode(): Optional = gstStateCode.getOptional("gst_state_code") + + /** + * Client name + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun name(): Optional = name.getOptional("name") + + /** + * Client PAN number + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun pan(): Optional = pan.getOptional("pan") + + /** + * GST place of supply + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun placeOfSupply(): Optional = placeOfSupply.getOptional("place_of_supply") + + /** + * Unique Client Code + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun ucc(): Optional = ucc.getOptional("ucc") + + /** + * Returns the raw JSON value of [address]. + * + * Unlike [address], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("address") @ExcludeMissing fun _address(): JsonField = address + + /** + * Returns the raw JSON value of [gstStateCode]. + * + * Unlike [gstStateCode], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("gst_state_code") + @ExcludeMissing + fun _gstStateCode(): JsonField = gstStateCode + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + + /** + * Returns the raw JSON value of [pan]. + * + * Unlike [pan], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("pan") @ExcludeMissing fun _pan(): JsonField = pan + + /** + * Returns the raw JSON value of [placeOfSupply]. + * + * Unlike [placeOfSupply], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("place_of_supply") + @ExcludeMissing + fun _placeOfSupply(): JsonField = placeOfSupply + + /** + * Returns the raw JSON value of [ucc]. + * + * Unlike [ucc], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("ucc") @ExcludeMissing fun _ucc(): JsonField = ucc + + @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 [ClientInfo]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ClientInfo]. */ + class Builder internal constructor() { + + private var address: JsonField = JsonMissing.of() + private var gstStateCode: JsonField = JsonMissing.of() + private var name: JsonField = JsonMissing.of() + private var pan: JsonField = JsonMissing.of() + private var placeOfSupply: JsonField = JsonMissing.of() + private var ucc: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(clientInfo: ClientInfo) = apply { + address = clientInfo.address + gstStateCode = clientInfo.gstStateCode + name = clientInfo.name + pan = clientInfo.pan + placeOfSupply = clientInfo.placeOfSupply + ucc = clientInfo.ucc + additionalProperties = clientInfo.additionalProperties.toMutableMap() + } + + /** Client address */ + fun address(address: String) = address(JsonField.of(address)) + + /** + * Sets [Builder.address] to an arbitrary JSON value. + * + * You should usually call [Builder.address] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun address(address: JsonField) = apply { this.address = address } + + /** GST state code */ + fun gstStateCode(gstStateCode: String) = gstStateCode(JsonField.of(gstStateCode)) + + /** + * Sets [Builder.gstStateCode] to an arbitrary JSON value. + * + * You should usually call [Builder.gstStateCode] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun gstStateCode(gstStateCode: JsonField) = apply { + this.gstStateCode = gstStateCode + } + + /** Client name */ + fun name(name: String) = name(JsonField.of(name)) + + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun name(name: JsonField) = apply { this.name = name } + + /** Client PAN number */ + fun pan(pan: String) = pan(JsonField.of(pan)) + + /** + * Sets [Builder.pan] to an arbitrary JSON value. + * + * You should usually call [Builder.pan] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun pan(pan: JsonField) = apply { this.pan = pan } + + /** GST place of supply */ + fun placeOfSupply(placeOfSupply: String) = + placeOfSupply(JsonField.of(placeOfSupply)) + + /** + * Sets [Builder.placeOfSupply] to an arbitrary JSON value. + * + * You should usually call [Builder.placeOfSupply] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun placeOfSupply(placeOfSupply: JsonField) = apply { + this.placeOfSupply = placeOfSupply + } + + /** Unique Client Code */ + fun ucc(ucc: String) = ucc(JsonField.of(ucc)) + + /** + * Sets [Builder.ucc] to an arbitrary JSON value. + * + * You should usually call [Builder.ucc] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun ucc(ucc: JsonField) = apply { this.ucc = ucc } + + 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 [ClientInfo]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): ClientInfo = + ClientInfo( + address, + gstStateCode, + name, + pan, + placeOfSupply, + ucc, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): ClientInfo = apply { + if (validated) { + return@apply + } + + address() + gstStateCode() + name() + pan() + placeOfSupply() + ucc() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (address.asKnown().isPresent) 1 else 0) + + (if (gstStateCode.asKnown().isPresent) 1 else 0) + + (if (name.asKnown().isPresent) 1 else 0) + + (if (pan.asKnown().isPresent) 1 else 0) + + (if (placeOfSupply.asKnown().isPresent) 1 else 0) + + (if (ucc.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ClientInfo && + address == other.address && + gstStateCode == other.gstStateCode && + name == other.name && + pan == other.pan && + placeOfSupply == other.placeOfSupply && + ucc == other.ucc && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + address, + gstStateCode, + name, + pan, + placeOfSupply, + ucc, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ClientInfo{address=$address, gstStateCode=$gstStateCode, name=$name, pan=$pan, placeOfSupply=$placeOfSupply, ucc=$ucc, additionalProperties=$additionalProperties}" + } + + class ContractNoteInfo + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val contractNoteNumber: JsonField, + private val settlementDate: JsonField, + private val settlementNumber: JsonField, + private val tradeDate: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("contract_note_number") + @ExcludeMissing + contractNoteNumber: JsonField = JsonMissing.of(), + @JsonProperty("settlement_date") + @ExcludeMissing + settlementDate: JsonField = JsonMissing.of(), + @JsonProperty("settlement_number") + @ExcludeMissing + settlementNumber: JsonField = JsonMissing.of(), + @JsonProperty("trade_date") + @ExcludeMissing + tradeDate: JsonField = JsonMissing.of(), + ) : this( + contractNoteNumber, + settlementDate, + settlementNumber, + tradeDate, + mutableMapOf(), + ) + + /** + * Contract note reference number + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun contractNoteNumber(): Optional = + contractNoteNumber.getOptional("contract_note_number") + + /** + * Settlement date for the trades + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun settlementDate(): Optional = + settlementDate.getOptional("settlement_date") + + /** + * Settlement reference number + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun settlementNumber(): Optional = + settlementNumber.getOptional("settlement_number") + + /** + * Date when trades were executed + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun tradeDate(): Optional = tradeDate.getOptional("trade_date") + + /** + * Returns the raw JSON value of [contractNoteNumber]. + * + * Unlike [contractNoteNumber], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("contract_note_number") + @ExcludeMissing + fun _contractNoteNumber(): JsonField = contractNoteNumber + + /** + * Returns the raw JSON value of [settlementDate]. + * + * Unlike [settlementDate], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("settlement_date") + @ExcludeMissing + fun _settlementDate(): JsonField = settlementDate + + /** + * Returns the raw JSON value of [settlementNumber]. + * + * Unlike [settlementNumber], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("settlement_number") + @ExcludeMissing + fun _settlementNumber(): JsonField = settlementNumber + + /** + * Returns the raw JSON value of [tradeDate]. + * + * Unlike [tradeDate], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("trade_date") + @ExcludeMissing + fun _tradeDate(): JsonField = tradeDate + + @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 [ContractNoteInfo]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ContractNoteInfo]. */ + class Builder internal constructor() { + + private var contractNoteNumber: JsonField = JsonMissing.of() + private var settlementDate: JsonField = JsonMissing.of() + private var settlementNumber: JsonField = JsonMissing.of() + private var tradeDate: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(contractNoteInfo: ContractNoteInfo) = apply { + contractNoteNumber = contractNoteInfo.contractNoteNumber + settlementDate = contractNoteInfo.settlementDate + settlementNumber = contractNoteInfo.settlementNumber + tradeDate = contractNoteInfo.tradeDate + additionalProperties = contractNoteInfo.additionalProperties.toMutableMap() + } + + /** Contract note reference number */ + fun contractNoteNumber(contractNoteNumber: String) = + contractNoteNumber(JsonField.of(contractNoteNumber)) + + /** + * Sets [Builder.contractNoteNumber] to an arbitrary JSON value. + * + * You should usually call [Builder.contractNoteNumber] with a well-typed [String] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun contractNoteNumber(contractNoteNumber: JsonField) = apply { + this.contractNoteNumber = contractNoteNumber + } + + /** Settlement date for the trades */ + fun settlementDate(settlementDate: LocalDate) = + settlementDate(JsonField.of(settlementDate)) + + /** + * Sets [Builder.settlementDate] to an arbitrary JSON value. + * + * You should usually call [Builder.settlementDate] with a well-typed [LocalDate] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun settlementDate(settlementDate: JsonField) = apply { + this.settlementDate = settlementDate + } + + /** Settlement reference number */ + fun settlementNumber(settlementNumber: String) = + settlementNumber(JsonField.of(settlementNumber)) + + /** + * Sets [Builder.settlementNumber] to an arbitrary JSON value. + * + * You should usually call [Builder.settlementNumber] with a well-typed [String] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun settlementNumber(settlementNumber: JsonField) = apply { + this.settlementNumber = settlementNumber + } + + /** Date when trades were executed */ + fun tradeDate(tradeDate: LocalDate) = tradeDate(JsonField.of(tradeDate)) + + /** + * Sets [Builder.tradeDate] to an arbitrary JSON value. + * + * You should usually call [Builder.tradeDate] with a well-typed [LocalDate] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun tradeDate(tradeDate: JsonField) = apply { + this.tradeDate = tradeDate + } + + 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 [ContractNoteInfo]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): ContractNoteInfo = + ContractNoteInfo( + contractNoteNumber, + settlementDate, + settlementNumber, + tradeDate, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): ContractNoteInfo = apply { + if (validated) { + return@apply + } + + contractNoteNumber() + settlementDate() + settlementNumber() + tradeDate() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (contractNoteNumber.asKnown().isPresent) 1 else 0) + + (if (settlementDate.asKnown().isPresent) 1 else 0) + + (if (settlementNumber.asKnown().isPresent) 1 else 0) + + (if (tradeDate.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ContractNoteInfo && + contractNoteNumber == other.contractNoteNumber && + settlementDate == other.settlementDate && + settlementNumber == other.settlementNumber && + tradeDate == other.tradeDate && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + contractNoteNumber, + settlementDate, + settlementNumber, + tradeDate, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ContractNoteInfo{contractNoteNumber=$contractNoteNumber, settlementDate=$settlementDate, settlementNumber=$settlementNumber, tradeDate=$tradeDate, additionalProperties=$additionalProperties}" + } + + class DerivativesTransaction + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val brokeragePerUnit: JsonField, + private val buySellBfCf: JsonField, + private val closingRatePerUnit: JsonField, + private val contractDescription: JsonField, + private val netTotal: JsonField, + private val quantity: JsonField, + private val wapPerUnit: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("brokerage_per_unit") + @ExcludeMissing + brokeragePerUnit: JsonField = JsonMissing.of(), + @JsonProperty("buy_sell_bf_cf") + @ExcludeMissing + buySellBfCf: JsonField = JsonMissing.of(), + @JsonProperty("closing_rate_per_unit") + @ExcludeMissing + closingRatePerUnit: JsonField = JsonMissing.of(), + @JsonProperty("contract_description") + @ExcludeMissing + contractDescription: JsonField = JsonMissing.of(), + @JsonProperty("net_total") + @ExcludeMissing + netTotal: JsonField = JsonMissing.of(), + @JsonProperty("quantity") + @ExcludeMissing + quantity: JsonField = JsonMissing.of(), + @JsonProperty("wap_per_unit") + @ExcludeMissing + wapPerUnit: JsonField = JsonMissing.of(), + ) : this( + brokeragePerUnit, + buySellBfCf, + closingRatePerUnit, + contractDescription, + netTotal, + quantity, + wapPerUnit, + mutableMapOf(), + ) + + /** + * Brokerage charged per unit + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun brokeragePerUnit(): Optional = + brokeragePerUnit.getOptional("brokerage_per_unit") + + /** + * Transaction type (Buy/Sell/Bring Forward/Carry Forward) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun buySellBfCf(): Optional = buySellBfCf.getOptional("buy_sell_bf_cf") + + /** + * Closing rate per unit + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun closingRatePerUnit(): Optional = + closingRatePerUnit.getOptional("closing_rate_per_unit") + + /** + * Derivatives contract description + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun contractDescription(): Optional = + contractDescription.getOptional("contract_description") + + /** + * Net total amount + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun netTotal(): Optional = netTotal.getOptional("net_total") + + /** + * Quantity traded + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun quantity(): Optional = quantity.getOptional("quantity") + + /** + * Weighted Average Price per unit + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun wapPerUnit(): Optional = wapPerUnit.getOptional("wap_per_unit") + + /** + * Returns the raw JSON value of [brokeragePerUnit]. + * + * Unlike [brokeragePerUnit], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("brokerage_per_unit") + @ExcludeMissing + fun _brokeragePerUnit(): JsonField = brokeragePerUnit + + /** + * Returns the raw JSON value of [buySellBfCf]. + * + * Unlike [buySellBfCf], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("buy_sell_bf_cf") + @ExcludeMissing + fun _buySellBfCf(): JsonField = buySellBfCf + + /** + * Returns the raw JSON value of [closingRatePerUnit]. + * + * Unlike [closingRatePerUnit], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("closing_rate_per_unit") + @ExcludeMissing + fun _closingRatePerUnit(): JsonField = closingRatePerUnit + + /** + * Returns the raw JSON value of [contractDescription]. + * + * Unlike [contractDescription], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("contract_description") + @ExcludeMissing + fun _contractDescription(): JsonField = contractDescription + + /** + * Returns the raw JSON value of [netTotal]. + * + * Unlike [netTotal], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("net_total") @ExcludeMissing fun _netTotal(): JsonField = netTotal + + /** + * Returns the raw JSON value of [quantity]. + * + * Unlike [quantity], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("quantity") @ExcludeMissing fun _quantity(): JsonField = quantity + + /** + * Returns the raw JSON value of [wapPerUnit]. + * + * Unlike [wapPerUnit], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("wap_per_unit") + @ExcludeMissing + fun _wapPerUnit(): JsonField = wapPerUnit + + @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 + * [DerivativesTransaction]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [DerivativesTransaction]. */ + class Builder internal constructor() { + + private var brokeragePerUnit: JsonField = JsonMissing.of() + private var buySellBfCf: JsonField = JsonMissing.of() + private var closingRatePerUnit: JsonField = JsonMissing.of() + private var contractDescription: JsonField = JsonMissing.of() + private var netTotal: JsonField = JsonMissing.of() + private var quantity: JsonField = JsonMissing.of() + private var wapPerUnit: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(derivativesTransaction: DerivativesTransaction) = apply { + brokeragePerUnit = derivativesTransaction.brokeragePerUnit + buySellBfCf = derivativesTransaction.buySellBfCf + closingRatePerUnit = derivativesTransaction.closingRatePerUnit + contractDescription = derivativesTransaction.contractDescription + netTotal = derivativesTransaction.netTotal + quantity = derivativesTransaction.quantity + wapPerUnit = derivativesTransaction.wapPerUnit + additionalProperties = + derivativesTransaction.additionalProperties.toMutableMap() + } + + /** Brokerage charged per unit */ + fun brokeragePerUnit(brokeragePerUnit: Float) = + brokeragePerUnit(JsonField.of(brokeragePerUnit)) + + /** + * Sets [Builder.brokeragePerUnit] to an arbitrary JSON value. + * + * You should usually call [Builder.brokeragePerUnit] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun brokeragePerUnit(brokeragePerUnit: JsonField) = apply { + this.brokeragePerUnit = brokeragePerUnit + } + + /** Transaction type (Buy/Sell/Bring Forward/Carry Forward) */ + fun buySellBfCf(buySellBfCf: String) = buySellBfCf(JsonField.of(buySellBfCf)) + + /** + * Sets [Builder.buySellBfCf] to an arbitrary JSON value. + * + * You should usually call [Builder.buySellBfCf] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun buySellBfCf(buySellBfCf: JsonField) = apply { + this.buySellBfCf = buySellBfCf + } + + /** Closing rate per unit */ + fun closingRatePerUnit(closingRatePerUnit: Float) = + closingRatePerUnit(JsonField.of(closingRatePerUnit)) + + /** + * Sets [Builder.closingRatePerUnit] to an arbitrary JSON value. + * + * You should usually call [Builder.closingRatePerUnit] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun closingRatePerUnit(closingRatePerUnit: JsonField) = apply { + this.closingRatePerUnit = closingRatePerUnit + } + + /** Derivatives contract description */ + fun contractDescription(contractDescription: String) = + contractDescription(JsonField.of(contractDescription)) + + /** + * Sets [Builder.contractDescription] to an arbitrary JSON value. + * + * You should usually call [Builder.contractDescription] with a well-typed [String] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun contractDescription(contractDescription: JsonField) = apply { + this.contractDescription = contractDescription + } + + /** Net total amount */ + fun netTotal(netTotal: Float) = netTotal(JsonField.of(netTotal)) + + /** + * Sets [Builder.netTotal] to an arbitrary JSON value. + * + * You should usually call [Builder.netTotal] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun netTotal(netTotal: JsonField) = apply { this.netTotal = netTotal } + + /** Quantity traded */ + fun quantity(quantity: Float) = quantity(JsonField.of(quantity)) + + /** + * Sets [Builder.quantity] to an arbitrary JSON value. + * + * You should usually call [Builder.quantity] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun quantity(quantity: JsonField) = apply { this.quantity = quantity } + + /** Weighted Average Price per unit */ + fun wapPerUnit(wapPerUnit: Float) = wapPerUnit(JsonField.of(wapPerUnit)) + + /** + * Sets [Builder.wapPerUnit] to an arbitrary JSON value. + * + * You should usually call [Builder.wapPerUnit] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun wapPerUnit(wapPerUnit: JsonField) = apply { + this.wapPerUnit = wapPerUnit + } + + 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 [DerivativesTransaction]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): DerivativesTransaction = + DerivativesTransaction( + brokeragePerUnit, + buySellBfCf, + closingRatePerUnit, + contractDescription, + netTotal, + quantity, + wapPerUnit, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): DerivativesTransaction = apply { + if (validated) { + return@apply + } + + brokeragePerUnit() + buySellBfCf() + closingRatePerUnit() + contractDescription() + netTotal() + quantity() + wapPerUnit() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (brokeragePerUnit.asKnown().isPresent) 1 else 0) + + (if (buySellBfCf.asKnown().isPresent) 1 else 0) + + (if (closingRatePerUnit.asKnown().isPresent) 1 else 0) + + (if (contractDescription.asKnown().isPresent) 1 else 0) + + (if (netTotal.asKnown().isPresent) 1 else 0) + + (if (quantity.asKnown().isPresent) 1 else 0) + + (if (wapPerUnit.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is DerivativesTransaction && + brokeragePerUnit == other.brokeragePerUnit && + buySellBfCf == other.buySellBfCf && + closingRatePerUnit == other.closingRatePerUnit && + contractDescription == other.contractDescription && + netTotal == other.netTotal && + quantity == other.quantity && + wapPerUnit == other.wapPerUnit && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + brokeragePerUnit, + buySellBfCf, + closingRatePerUnit, + contractDescription, + netTotal, + quantity, + wapPerUnit, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "DerivativesTransaction{brokeragePerUnit=$brokeragePerUnit, buySellBfCf=$buySellBfCf, closingRatePerUnit=$closingRatePerUnit, contractDescription=$contractDescription, netTotal=$netTotal, quantity=$quantity, wapPerUnit=$wapPerUnit, additionalProperties=$additionalProperties}" + } + + class DetailedTrade + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val brokerage: JsonField, + private val buySell: JsonField, + private val closingRatePerUnit: JsonField, + private val exchange: JsonField, + private val netRatePerUnit: JsonField, + private val netTotal: JsonField, + private val orderNumber: JsonField, + private val orderTime: JsonField, + private val quantity: JsonField, + private val remarks: JsonField, + private val securityDescription: JsonField, + private val tradeNumber: JsonField, + private val tradeTime: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("brokerage") + @ExcludeMissing + brokerage: JsonField = JsonMissing.of(), + @JsonProperty("buy_sell") + @ExcludeMissing + buySell: JsonField = JsonMissing.of(), + @JsonProperty("closing_rate_per_unit") + @ExcludeMissing + closingRatePerUnit: JsonField = JsonMissing.of(), + @JsonProperty("exchange") + @ExcludeMissing + exchange: JsonField = JsonMissing.of(), + @JsonProperty("net_rate_per_unit") + @ExcludeMissing + netRatePerUnit: JsonField = JsonMissing.of(), + @JsonProperty("net_total") + @ExcludeMissing + netTotal: JsonField = JsonMissing.of(), + @JsonProperty("order_number") + @ExcludeMissing + orderNumber: JsonField = JsonMissing.of(), + @JsonProperty("order_time") + @ExcludeMissing + orderTime: JsonField = JsonMissing.of(), + @JsonProperty("quantity") + @ExcludeMissing + quantity: JsonField = JsonMissing.of(), + @JsonProperty("remarks") + @ExcludeMissing + remarks: JsonField = JsonMissing.of(), + @JsonProperty("security_description") + @ExcludeMissing + securityDescription: JsonField = JsonMissing.of(), + @JsonProperty("trade_number") + @ExcludeMissing + tradeNumber: JsonField = JsonMissing.of(), + @JsonProperty("trade_time") + @ExcludeMissing + tradeTime: JsonField = JsonMissing.of(), + ) : this( + brokerage, + buySell, + closingRatePerUnit, + exchange, + netRatePerUnit, + netTotal, + orderNumber, + orderTime, + quantity, + remarks, + securityDescription, + tradeNumber, + tradeTime, + mutableMapOf(), + ) + + /** + * Brokerage charged for this trade + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun brokerage(): Optional = brokerage.getOptional("brokerage") + + /** + * Transaction type (B for Buy, S for Sell) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun buySell(): Optional = buySell.getOptional("buy_sell") + + /** + * Closing rate per unit + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun closingRatePerUnit(): Optional = + closingRatePerUnit.getOptional("closing_rate_per_unit") + + /** + * Exchange name + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun exchange(): Optional = exchange.getOptional("exchange") + + /** + * Net rate per unit + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun netRatePerUnit(): Optional = netRatePerUnit.getOptional("net_rate_per_unit") + + /** + * Net total for this trade + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun netTotal(): Optional = netTotal.getOptional("net_total") + + /** + * Order reference number + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun orderNumber(): Optional = orderNumber.getOptional("order_number") + + /** + * Time when order was placed + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun orderTime(): Optional = orderTime.getOptional("order_time") + + /** + * Quantity traded + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun quantity(): Optional = quantity.getOptional("quantity") + + /** + * Additional remarks or notes + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun remarks(): Optional = remarks.getOptional("remarks") + + /** + * Security name with exchange and ISIN + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun securityDescription(): Optional = + securityDescription.getOptional("security_description") + + /** + * Trade reference number + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun tradeNumber(): Optional = tradeNumber.getOptional("trade_number") + + /** + * Time when trade was executed + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun tradeTime(): Optional = tradeTime.getOptional("trade_time") + + /** + * Returns the raw JSON value of [brokerage]. + * + * Unlike [brokerage], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("brokerage") + @ExcludeMissing + fun _brokerage(): JsonField = brokerage + + /** + * Returns the raw JSON value of [buySell]. + * + * Unlike [buySell], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("buy_sell") @ExcludeMissing fun _buySell(): JsonField = buySell + + /** + * Returns the raw JSON value of [closingRatePerUnit]. + * + * Unlike [closingRatePerUnit], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("closing_rate_per_unit") + @ExcludeMissing + fun _closingRatePerUnit(): JsonField = closingRatePerUnit + + /** + * Returns the raw JSON value of [exchange]. + * + * Unlike [exchange], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("exchange") @ExcludeMissing fun _exchange(): JsonField = exchange + + /** + * Returns the raw JSON value of [netRatePerUnit]. + * + * Unlike [netRatePerUnit], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("net_rate_per_unit") + @ExcludeMissing + fun _netRatePerUnit(): JsonField = netRatePerUnit + + /** + * Returns the raw JSON value of [netTotal]. + * + * Unlike [netTotal], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("net_total") @ExcludeMissing fun _netTotal(): JsonField = netTotal + + /** + * Returns the raw JSON value of [orderNumber]. + * + * Unlike [orderNumber], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("order_number") + @ExcludeMissing + fun _orderNumber(): JsonField = orderNumber + + /** + * Returns the raw JSON value of [orderTime]. + * + * Unlike [orderTime], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("order_time") + @ExcludeMissing + fun _orderTime(): JsonField = orderTime + + /** + * Returns the raw JSON value of [quantity]. + * + * Unlike [quantity], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("quantity") @ExcludeMissing fun _quantity(): JsonField = quantity + + /** + * Returns the raw JSON value of [remarks]. + * + * Unlike [remarks], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("remarks") @ExcludeMissing fun _remarks(): JsonField = remarks + + /** + * Returns the raw JSON value of [securityDescription]. + * + * Unlike [securityDescription], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("security_description") + @ExcludeMissing + fun _securityDescription(): JsonField = securityDescription + + /** + * Returns the raw JSON value of [tradeNumber]. + * + * Unlike [tradeNumber], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("trade_number") + @ExcludeMissing + fun _tradeNumber(): JsonField = tradeNumber + + /** + * Returns the raw JSON value of [tradeTime]. + * + * Unlike [tradeTime], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("trade_time") + @ExcludeMissing + fun _tradeTime(): JsonField = tradeTime + + @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 [DetailedTrade]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [DetailedTrade]. */ + class Builder internal constructor() { + + private var brokerage: JsonField = JsonMissing.of() + private var buySell: JsonField = JsonMissing.of() + private var closingRatePerUnit: JsonField = JsonMissing.of() + private var exchange: JsonField = JsonMissing.of() + private var netRatePerUnit: JsonField = JsonMissing.of() + private var netTotal: JsonField = JsonMissing.of() + private var orderNumber: JsonField = JsonMissing.of() + private var orderTime: JsonField = JsonMissing.of() + private var quantity: JsonField = JsonMissing.of() + private var remarks: JsonField = JsonMissing.of() + private var securityDescription: JsonField = JsonMissing.of() + private var tradeNumber: JsonField = JsonMissing.of() + private var tradeTime: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(detailedTrade: DetailedTrade) = apply { + brokerage = detailedTrade.brokerage + buySell = detailedTrade.buySell + closingRatePerUnit = detailedTrade.closingRatePerUnit + exchange = detailedTrade.exchange + netRatePerUnit = detailedTrade.netRatePerUnit + netTotal = detailedTrade.netTotal + orderNumber = detailedTrade.orderNumber + orderTime = detailedTrade.orderTime + quantity = detailedTrade.quantity + remarks = detailedTrade.remarks + securityDescription = detailedTrade.securityDescription + tradeNumber = detailedTrade.tradeNumber + tradeTime = detailedTrade.tradeTime + additionalProperties = detailedTrade.additionalProperties.toMutableMap() + } + + /** Brokerage charged for this trade */ + fun brokerage(brokerage: Float) = brokerage(JsonField.of(brokerage)) + + /** + * Sets [Builder.brokerage] to an arbitrary JSON value. + * + * You should usually call [Builder.brokerage] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun brokerage(brokerage: JsonField) = apply { this.brokerage = brokerage } + + /** Transaction type (B for Buy, S for Sell) */ + fun buySell(buySell: String) = buySell(JsonField.of(buySell)) + + /** + * Sets [Builder.buySell] to an arbitrary JSON value. + * + * You should usually call [Builder.buySell] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun buySell(buySell: JsonField) = apply { this.buySell = buySell } + + /** Closing rate per unit */ + fun closingRatePerUnit(closingRatePerUnit: Float) = + closingRatePerUnit(JsonField.of(closingRatePerUnit)) + + /** + * Sets [Builder.closingRatePerUnit] to an arbitrary JSON value. + * + * You should usually call [Builder.closingRatePerUnit] with a well-typed [Float] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun closingRatePerUnit(closingRatePerUnit: JsonField) = apply { + this.closingRatePerUnit = closingRatePerUnit + } + + /** Exchange name */ + fun exchange(exchange: String) = exchange(JsonField.of(exchange)) + + /** + * Sets [Builder.exchange] to an arbitrary JSON value. + * + * You should usually call [Builder.exchange] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun exchange(exchange: JsonField) = apply { this.exchange = exchange } + + /** Net rate per unit */ + fun netRatePerUnit(netRatePerUnit: Float) = + netRatePerUnit(JsonField.of(netRatePerUnit)) + + /** + * Sets [Builder.netRatePerUnit] to an arbitrary JSON value. + * + * You should usually call [Builder.netRatePerUnit] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun netRatePerUnit(netRatePerUnit: JsonField) = apply { + this.netRatePerUnit = netRatePerUnit + } + + /** Net total for this trade */ + fun netTotal(netTotal: Float) = netTotal(JsonField.of(netTotal)) + + /** + * Sets [Builder.netTotal] to an arbitrary JSON value. + * + * You should usually call [Builder.netTotal] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun netTotal(netTotal: JsonField) = apply { this.netTotal = netTotal } + + /** Order reference number */ + fun orderNumber(orderNumber: String) = orderNumber(JsonField.of(orderNumber)) + + /** + * Sets [Builder.orderNumber] to an arbitrary JSON value. + * + * You should usually call [Builder.orderNumber] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun orderNumber(orderNumber: JsonField) = apply { + this.orderNumber = orderNumber + } + + /** Time when order was placed */ + fun orderTime(orderTime: String) = orderTime(JsonField.of(orderTime)) + + /** + * Sets [Builder.orderTime] to an arbitrary JSON value. + * + * You should usually call [Builder.orderTime] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun orderTime(orderTime: JsonField) = apply { this.orderTime = orderTime } + + /** Quantity traded */ + fun quantity(quantity: Float) = quantity(JsonField.of(quantity)) + + /** + * Sets [Builder.quantity] to an arbitrary JSON value. + * + * You should usually call [Builder.quantity] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun quantity(quantity: JsonField) = apply { this.quantity = quantity } + + /** Additional remarks or notes */ + fun remarks(remarks: String) = remarks(JsonField.of(remarks)) + + /** + * Sets [Builder.remarks] to an arbitrary JSON value. + * + * You should usually call [Builder.remarks] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun remarks(remarks: JsonField) = apply { this.remarks = remarks } + + /** Security name with exchange and ISIN */ + fun securityDescription(securityDescription: String) = + securityDescription(JsonField.of(securityDescription)) + + /** + * Sets [Builder.securityDescription] to an arbitrary JSON value. + * + * You should usually call [Builder.securityDescription] with a well-typed [String] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun securityDescription(securityDescription: JsonField) = apply { + this.securityDescription = securityDescription + } + + /** Trade reference number */ + fun tradeNumber(tradeNumber: String) = tradeNumber(JsonField.of(tradeNumber)) + + /** + * Sets [Builder.tradeNumber] to an arbitrary JSON value. + * + * You should usually call [Builder.tradeNumber] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun tradeNumber(tradeNumber: JsonField) = apply { + this.tradeNumber = tradeNumber + } + + /** Time when trade was executed */ + fun tradeTime(tradeTime: String) = tradeTime(JsonField.of(tradeTime)) + + /** + * Sets [Builder.tradeTime] to an arbitrary JSON value. + * + * You should usually call [Builder.tradeTime] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun tradeTime(tradeTime: JsonField) = apply { this.tradeTime = tradeTime } + + 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 [DetailedTrade]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): DetailedTrade = + DetailedTrade( + brokerage, + buySell, + closingRatePerUnit, + exchange, + netRatePerUnit, + netTotal, + orderNumber, + orderTime, + quantity, + remarks, + securityDescription, + tradeNumber, + tradeTime, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): DetailedTrade = apply { + if (validated) { + return@apply + } + + brokerage() + buySell() + closingRatePerUnit() + exchange() + netRatePerUnit() + netTotal() + orderNumber() + orderTime() + quantity() + remarks() + securityDescription() + tradeNumber() + tradeTime() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (brokerage.asKnown().isPresent) 1 else 0) + + (if (buySell.asKnown().isPresent) 1 else 0) + + (if (closingRatePerUnit.asKnown().isPresent) 1 else 0) + + (if (exchange.asKnown().isPresent) 1 else 0) + + (if (netRatePerUnit.asKnown().isPresent) 1 else 0) + + (if (netTotal.asKnown().isPresent) 1 else 0) + + (if (orderNumber.asKnown().isPresent) 1 else 0) + + (if (orderTime.asKnown().isPresent) 1 else 0) + + (if (quantity.asKnown().isPresent) 1 else 0) + + (if (remarks.asKnown().isPresent) 1 else 0) + + (if (securityDescription.asKnown().isPresent) 1 else 0) + + (if (tradeNumber.asKnown().isPresent) 1 else 0) + + (if (tradeTime.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is DetailedTrade && + brokerage == other.brokerage && + buySell == other.buySell && + closingRatePerUnit == other.closingRatePerUnit && + exchange == other.exchange && + netRatePerUnit == other.netRatePerUnit && + netTotal == other.netTotal && + orderNumber == other.orderNumber && + orderTime == other.orderTime && + quantity == other.quantity && + remarks == other.remarks && + securityDescription == other.securityDescription && + tradeNumber == other.tradeNumber && + tradeTime == other.tradeTime && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + brokerage, + buySell, + closingRatePerUnit, + exchange, + netRatePerUnit, + netTotal, + orderNumber, + orderTime, + quantity, + remarks, + securityDescription, + tradeNumber, + tradeTime, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "DetailedTrade{brokerage=$brokerage, buySell=$buySell, closingRatePerUnit=$closingRatePerUnit, exchange=$exchange, netRatePerUnit=$netRatePerUnit, netTotal=$netTotal, orderNumber=$orderNumber, orderTime=$orderTime, quantity=$quantity, remarks=$remarks, securityDescription=$securityDescription, tradeNumber=$tradeNumber, tradeTime=$tradeTime, additionalProperties=$additionalProperties}" + } + + class EquityTransaction + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val buyQuantity: JsonField, + private val buyTotalValue: JsonField, + private val buyWap: JsonField, + private val isin: JsonField, + private val netObligation: JsonField, + private val securityName: JsonField, + private val securitySymbol: JsonField, + private val sellQuantity: JsonField, + private val sellTotalValue: JsonField, + private val sellWap: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("buy_quantity") + @ExcludeMissing + buyQuantity: JsonField = JsonMissing.of(), + @JsonProperty("buy_total_value") + @ExcludeMissing + buyTotalValue: JsonField = JsonMissing.of(), + @JsonProperty("buy_wap") + @ExcludeMissing + buyWap: JsonField = JsonMissing.of(), + @JsonProperty("isin") @ExcludeMissing isin: JsonField = JsonMissing.of(), + @JsonProperty("net_obligation") + @ExcludeMissing + netObligation: JsonField = JsonMissing.of(), + @JsonProperty("security_name") + @ExcludeMissing + securityName: JsonField = JsonMissing.of(), + @JsonProperty("security_symbol") + @ExcludeMissing + securitySymbol: JsonField = JsonMissing.of(), + @JsonProperty("sell_quantity") + @ExcludeMissing + sellQuantity: JsonField = JsonMissing.of(), + @JsonProperty("sell_total_value") + @ExcludeMissing + sellTotalValue: JsonField = JsonMissing.of(), + @JsonProperty("sell_wap") + @ExcludeMissing + sellWap: JsonField = JsonMissing.of(), + ) : this( + buyQuantity, + buyTotalValue, + buyWap, + isin, + netObligation, + securityName, + securitySymbol, + sellQuantity, + sellTotalValue, + sellWap, + mutableMapOf(), + ) + + /** + * Total quantity purchased + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun buyQuantity(): Optional = buyQuantity.getOptional("buy_quantity") + + /** + * Total value of buy transactions + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun buyTotalValue(): Optional = buyTotalValue.getOptional("buy_total_value") + + /** + * Weighted Average Price for buy transactions + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun buyWap(): Optional = buyWap.getOptional("buy_wap") + + /** + * ISIN code of the security + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun isin(): Optional = isin.getOptional("isin") + + /** + * Net amount payable/receivable for this security + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun netObligation(): Optional = netObligation.getOptional("net_obligation") + + /** + * Name of the security + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun securityName(): Optional = securityName.getOptional("security_name") + + /** + * Trading symbol + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun securitySymbol(): Optional = securitySymbol.getOptional("security_symbol") + + /** + * Total quantity sold + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun sellQuantity(): Optional = sellQuantity.getOptional("sell_quantity") + + /** + * Total value of sell transactions + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun sellTotalValue(): Optional = sellTotalValue.getOptional("sell_total_value") + + /** + * Weighted Average Price for sell transactions + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun sellWap(): Optional = sellWap.getOptional("sell_wap") + + /** + * Returns the raw JSON value of [buyQuantity]. + * + * Unlike [buyQuantity], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("buy_quantity") + @ExcludeMissing + fun _buyQuantity(): JsonField = buyQuantity + + /** + * Returns the raw JSON value of [buyTotalValue]. + * + * Unlike [buyTotalValue], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("buy_total_value") + @ExcludeMissing + fun _buyTotalValue(): JsonField = buyTotalValue + + /** + * Returns the raw JSON value of [buyWap]. + * + * Unlike [buyWap], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("buy_wap") @ExcludeMissing fun _buyWap(): JsonField = buyWap + + /** + * Returns the raw JSON value of [isin]. + * + * Unlike [isin], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("isin") @ExcludeMissing fun _isin(): JsonField = isin + + /** + * Returns the raw JSON value of [netObligation]. + * + * Unlike [netObligation], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("net_obligation") + @ExcludeMissing + fun _netObligation(): JsonField = netObligation + + /** + * Returns the raw JSON value of [securityName]. + * + * Unlike [securityName], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("security_name") + @ExcludeMissing + fun _securityName(): JsonField = securityName + + /** + * Returns the raw JSON value of [securitySymbol]. + * + * Unlike [securitySymbol], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("security_symbol") + @ExcludeMissing + fun _securitySymbol(): JsonField = securitySymbol + + /** + * Returns the raw JSON value of [sellQuantity]. + * + * Unlike [sellQuantity], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("sell_quantity") + @ExcludeMissing + fun _sellQuantity(): JsonField = sellQuantity + + /** + * Returns the raw JSON value of [sellTotalValue]. + * + * Unlike [sellTotalValue], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("sell_total_value") + @ExcludeMissing + fun _sellTotalValue(): JsonField = sellTotalValue + + /** + * Returns the raw JSON value of [sellWap]. + * + * Unlike [sellWap], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("sell_wap") @ExcludeMissing fun _sellWap(): JsonField = sellWap + + @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 [EquityTransaction]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [EquityTransaction]. */ + class Builder internal constructor() { + + private var buyQuantity: JsonField = JsonMissing.of() + private var buyTotalValue: JsonField = JsonMissing.of() + private var buyWap: JsonField = JsonMissing.of() + private var isin: JsonField = JsonMissing.of() + private var netObligation: JsonField = JsonMissing.of() + private var securityName: JsonField = JsonMissing.of() + private var securitySymbol: JsonField = JsonMissing.of() + private var sellQuantity: JsonField = JsonMissing.of() + private var sellTotalValue: JsonField = JsonMissing.of() + private var sellWap: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(equityTransaction: EquityTransaction) = apply { + buyQuantity = equityTransaction.buyQuantity + buyTotalValue = equityTransaction.buyTotalValue + buyWap = equityTransaction.buyWap + isin = equityTransaction.isin + netObligation = equityTransaction.netObligation + securityName = equityTransaction.securityName + securitySymbol = equityTransaction.securitySymbol + sellQuantity = equityTransaction.sellQuantity + sellTotalValue = equityTransaction.sellTotalValue + sellWap = equityTransaction.sellWap + additionalProperties = equityTransaction.additionalProperties.toMutableMap() + } + + /** Total quantity purchased */ + fun buyQuantity(buyQuantity: Float) = buyQuantity(JsonField.of(buyQuantity)) + + /** + * Sets [Builder.buyQuantity] to an arbitrary JSON value. + * + * You should usually call [Builder.buyQuantity] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun buyQuantity(buyQuantity: JsonField) = apply { + this.buyQuantity = buyQuantity + } + + /** Total value of buy transactions */ + fun buyTotalValue(buyTotalValue: Float) = buyTotalValue(JsonField.of(buyTotalValue)) + + /** + * Sets [Builder.buyTotalValue] to an arbitrary JSON value. + * + * You should usually call [Builder.buyTotalValue] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun buyTotalValue(buyTotalValue: JsonField) = apply { + this.buyTotalValue = buyTotalValue + } + + /** Weighted Average Price for buy transactions */ + fun buyWap(buyWap: Float) = buyWap(JsonField.of(buyWap)) + + /** + * Sets [Builder.buyWap] to an arbitrary JSON value. + * + * You should usually call [Builder.buyWap] with a well-typed [Float] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun buyWap(buyWap: JsonField) = apply { this.buyWap = buyWap } + + /** ISIN code of the security */ + fun isin(isin: String) = isin(JsonField.of(isin)) + + /** + * Sets [Builder.isin] to an arbitrary JSON value. + * + * You should usually call [Builder.isin] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun isin(isin: JsonField) = apply { this.isin = isin } + + /** Net amount payable/receivable for this security */ + fun netObligation(netObligation: Float) = netObligation(JsonField.of(netObligation)) + + /** + * Sets [Builder.netObligation] to an arbitrary JSON value. + * + * You should usually call [Builder.netObligation] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun netObligation(netObligation: JsonField) = apply { + this.netObligation = netObligation + } + + /** Name of the security */ + fun securityName(securityName: String) = securityName(JsonField.of(securityName)) + + /** + * Sets [Builder.securityName] to an arbitrary JSON value. + * + * You should usually call [Builder.securityName] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun securityName(securityName: JsonField) = apply { + this.securityName = securityName + } + + /** Trading symbol */ + fun securitySymbol(securitySymbol: String) = + securitySymbol(JsonField.of(securitySymbol)) + + /** + * Sets [Builder.securitySymbol] to an arbitrary JSON value. + * + * You should usually call [Builder.securitySymbol] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun securitySymbol(securitySymbol: JsonField) = apply { + this.securitySymbol = securitySymbol + } + + /** Total quantity sold */ + fun sellQuantity(sellQuantity: Float) = sellQuantity(JsonField.of(sellQuantity)) + + /** + * Sets [Builder.sellQuantity] to an arbitrary JSON value. + * + * You should usually call [Builder.sellQuantity] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun sellQuantity(sellQuantity: JsonField) = apply { + this.sellQuantity = sellQuantity + } + + /** Total value of sell transactions */ + fun sellTotalValue(sellTotalValue: Float) = + sellTotalValue(JsonField.of(sellTotalValue)) + + /** + * Sets [Builder.sellTotalValue] to an arbitrary JSON value. + * + * You should usually call [Builder.sellTotalValue] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun sellTotalValue(sellTotalValue: JsonField) = apply { + this.sellTotalValue = sellTotalValue + } + + /** Weighted Average Price for sell transactions */ + fun sellWap(sellWap: Float) = sellWap(JsonField.of(sellWap)) + + /** + * Sets [Builder.sellWap] to an arbitrary JSON value. + * + * You should usually call [Builder.sellWap] with a well-typed [Float] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun sellWap(sellWap: JsonField) = apply { this.sellWap = sellWap } + + 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 [EquityTransaction]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): EquityTransaction = + EquityTransaction( + buyQuantity, + buyTotalValue, + buyWap, + isin, + netObligation, + securityName, + securitySymbol, + sellQuantity, + sellTotalValue, + sellWap, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): EquityTransaction = apply { + if (validated) { + return@apply + } + + buyQuantity() + buyTotalValue() + buyWap() + isin() + netObligation() + securityName() + securitySymbol() + sellQuantity() + sellTotalValue() + sellWap() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (buyQuantity.asKnown().isPresent) 1 else 0) + + (if (buyTotalValue.asKnown().isPresent) 1 else 0) + + (if (buyWap.asKnown().isPresent) 1 else 0) + + (if (isin.asKnown().isPresent) 1 else 0) + + (if (netObligation.asKnown().isPresent) 1 else 0) + + (if (securityName.asKnown().isPresent) 1 else 0) + + (if (securitySymbol.asKnown().isPresent) 1 else 0) + + (if (sellQuantity.asKnown().isPresent) 1 else 0) + + (if (sellTotalValue.asKnown().isPresent) 1 else 0) + + (if (sellWap.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is EquityTransaction && + buyQuantity == other.buyQuantity && + buyTotalValue == other.buyTotalValue && + buyWap == other.buyWap && + isin == other.isin && + netObligation == other.netObligation && + securityName == other.securityName && + securitySymbol == other.securitySymbol && + sellQuantity == other.sellQuantity && + sellTotalValue == other.sellTotalValue && + sellWap == other.sellWap && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + buyQuantity, + buyTotalValue, + buyWap, + isin, + netObligation, + securityName, + securitySymbol, + sellQuantity, + sellTotalValue, + sellWap, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "EquityTransaction{buyQuantity=$buyQuantity, buyTotalValue=$buyTotalValue, buyWap=$buyWap, isin=$isin, netObligation=$netObligation, securityName=$securityName, securitySymbol=$securitySymbol, sellQuantity=$sellQuantity, sellTotalValue=$sellTotalValue, sellWap=$sellWap, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Data && + brokerInfo == other.brokerInfo && + chargesSummary == other.chargesSummary && + clientInfo == other.clientInfo && + contractNoteInfo == other.contractNoteInfo && + derivativesTransactions == other.derivativesTransactions && + detailedTrades == other.detailedTrades && + equityTransactions == other.equityTransactions && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + brokerInfo, + chargesSummary, + clientInfo, + contractNoteInfo, + derivativesTransactions, + detailedTrades, + equityTransactions, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Data{brokerInfo=$brokerInfo, chargesSummary=$chargesSummary, clientInfo=$clientInfo, contractNoteInfo=$contractNoteInfo, derivativesTransactions=$derivativesTransactions, detailedTrades=$detailedTrades, equityTransactions=$equityTransactions, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ContractNoteParseResponse && + data == other.data && + msg == other.msg && + status == other.status && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(data, msg, status, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ContractNoteParseResponse{data=$data, msg=$msg, status=$status, additionalProperties=$additionalProperties}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/credits/CreditCheckParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/credits/CreditCheckParams.kt new file mode 100644 index 0000000..aa45ce8 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/credits/CreditCheckParams.kt @@ -0,0 +1,219 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.credits + +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.Params +import com.cas_parser.api.core.http.Headers +import com.cas_parser.api.core.http.QueryParams +import com.cas_parser.api.core.toImmutable +import java.util.Objects +import java.util.Optional + +/** + * Check your remaining API credits and usage for the current billing period. + * + * Returns: + * - Number of API calls used and remaining credits + * - Credit limit and reset date + * - List of enabled features for your plan + * + * Credits reset at the start of each billing period. + */ +class CreditCheckParams +private constructor( + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, + private val additionalBodyProperties: Map, +) : Params { + + /** Additional body properties to send with the request. */ + fun _additionalBodyProperties(): Map = additionalBodyProperties + + /** 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 { + + @JvmStatic fun none(): CreditCheckParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [CreditCheckParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [CreditCheckParams]. */ + class Builder internal constructor() { + + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + private var additionalBodyProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(creditCheckParams: CreditCheckParams) = apply { + additionalHeaders = creditCheckParams.additionalHeaders.toBuilder() + additionalQueryParams = creditCheckParams.additionalQueryParams.toBuilder() + additionalBodyProperties = creditCheckParams.additionalBodyProperties.toMutableMap() + } + + 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) + } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + this.additionalBodyProperties.clear() + putAllAdditionalBodyProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + additionalBodyProperties.put(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + this.additionalBodyProperties.putAll(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { + additionalBodyProperties.remove(key) + } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalBodyProperty) + } + + /** + * Returns an immutable instance of [CreditCheckParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): CreditCheckParams = + CreditCheckParams( + additionalHeaders.build(), + additionalQueryParams.build(), + additionalBodyProperties.toImmutable(), + ) + } + + fun _body(): Optional> = + Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is CreditCheckParams && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams && + additionalBodyProperties == other.additionalBodyProperties + } + + override fun hashCode(): Int = + Objects.hash(additionalHeaders, additionalQueryParams, additionalBodyProperties) + + override fun toString() = + "CreditCheckParams{additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/credits/CreditCheckResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/credits/CreditCheckResponse.kt new file mode 100644 index 0000000..6a3f1a3 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/credits/CreditCheckResponse.kt @@ -0,0 +1,387 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.credits + +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonField +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.checkKnown +import com.cas_parser.api.core.toImmutable +import com.cas_parser.api.errors.CasParserInvalidDataException +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.time.OffsetDateTime +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +class CreditCheckResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val enabledFeatures: JsonField>, + private val isUnlimited: JsonField, + private val limit: JsonField, + private val remaining: JsonField, + private val resetsAt: JsonField, + private val used: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("enabled_features") + @ExcludeMissing + enabledFeatures: JsonField> = JsonMissing.of(), + @JsonProperty("is_unlimited") + @ExcludeMissing + isUnlimited: JsonField = JsonMissing.of(), + @JsonProperty("limit") @ExcludeMissing limit: JsonField = JsonMissing.of(), + @JsonProperty("remaining") @ExcludeMissing remaining: JsonField = JsonMissing.of(), + @JsonProperty("resets_at") + @ExcludeMissing + resetsAt: JsonField = JsonMissing.of(), + @JsonProperty("used") @ExcludeMissing used: JsonField = JsonMissing.of(), + ) : this(enabledFeatures, isUnlimited, limit, remaining, resetsAt, used, mutableMapOf()) + + /** + * List of API features enabled for your plan + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun enabledFeatures(): Optional> = enabledFeatures.getOptional("enabled_features") + + /** + * Whether the account has unlimited credits + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun isUnlimited(): Optional = isUnlimited.getOptional("is_unlimited") + + /** + * Total credit limit for billing period + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun limit(): Optional = limit.getOptional("limit") + + /** + * Remaining credits (null if unlimited) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun remaining(): Optional = remaining.getOptional("remaining") + + /** + * When credits reset (ISO 8601) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun resetsAt(): Optional = resetsAt.getOptional("resets_at") + + /** + * Number of credits used this billing period + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun used(): Optional = used.getOptional("used") + + /** + * Returns the raw JSON value of [enabledFeatures]. + * + * Unlike [enabledFeatures], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("enabled_features") + @ExcludeMissing + fun _enabledFeatures(): JsonField> = enabledFeatures + + /** + * Returns the raw JSON value of [isUnlimited]. + * + * Unlike [isUnlimited], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("is_unlimited") + @ExcludeMissing + fun _isUnlimited(): JsonField = isUnlimited + + /** + * Returns the raw JSON value of [limit]. + * + * Unlike [limit], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("limit") @ExcludeMissing fun _limit(): JsonField = limit + + /** + * Returns the raw JSON value of [remaining]. + * + * Unlike [remaining], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("remaining") @ExcludeMissing fun _remaining(): JsonField = remaining + + /** + * Returns the raw JSON value of [resetsAt]. + * + * Unlike [resetsAt], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("resets_at") @ExcludeMissing fun _resetsAt(): JsonField = resetsAt + + /** + * Returns the raw JSON value of [used]. + * + * Unlike [used], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("used") @ExcludeMissing fun _used(): JsonField = used + + @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 [CreditCheckResponse]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [CreditCheckResponse]. */ + class Builder internal constructor() { + + private var enabledFeatures: JsonField>? = null + private var isUnlimited: JsonField = JsonMissing.of() + private var limit: JsonField = JsonMissing.of() + private var remaining: JsonField = JsonMissing.of() + private var resetsAt: JsonField = JsonMissing.of() + private var used: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(creditCheckResponse: CreditCheckResponse) = apply { + enabledFeatures = creditCheckResponse.enabledFeatures.map { it.toMutableList() } + isUnlimited = creditCheckResponse.isUnlimited + limit = creditCheckResponse.limit + remaining = creditCheckResponse.remaining + resetsAt = creditCheckResponse.resetsAt + used = creditCheckResponse.used + additionalProperties = creditCheckResponse.additionalProperties.toMutableMap() + } + + /** List of API features enabled for your plan */ + fun enabledFeatures(enabledFeatures: List) = + enabledFeatures(JsonField.of(enabledFeatures)) + + /** + * Sets [Builder.enabledFeatures] to an arbitrary JSON value. + * + * You should usually call [Builder.enabledFeatures] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun enabledFeatures(enabledFeatures: JsonField>) = apply { + this.enabledFeatures = enabledFeatures.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [enabledFeatures]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addEnabledFeature(enabledFeature: String) = apply { + enabledFeatures = + (enabledFeatures ?: JsonField.of(mutableListOf())).also { + checkKnown("enabledFeatures", it).add(enabledFeature) + } + } + + /** Whether the account has unlimited credits */ + fun isUnlimited(isUnlimited: Boolean) = isUnlimited(JsonField.of(isUnlimited)) + + /** + * Sets [Builder.isUnlimited] to an arbitrary JSON value. + * + * You should usually call [Builder.isUnlimited] with a well-typed [Boolean] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun isUnlimited(isUnlimited: JsonField) = apply { this.isUnlimited = isUnlimited } + + /** Total credit limit for billing period */ + fun limit(limit: Long) = limit(JsonField.of(limit)) + + /** + * Sets [Builder.limit] to an arbitrary JSON value. + * + * You should usually call [Builder.limit] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun limit(limit: JsonField) = apply { this.limit = limit } + + /** Remaining credits (null if unlimited) */ + fun remaining(remaining: Double?) = remaining(JsonField.ofNullable(remaining)) + + /** + * Alias for [Builder.remaining]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun remaining(remaining: Double) = remaining(remaining as Double?) + + /** Alias for calling [Builder.remaining] with `remaining.orElse(null)`. */ + fun remaining(remaining: Optional) = remaining(remaining.getOrNull()) + + /** + * Sets [Builder.remaining] to an arbitrary JSON value. + * + * You should usually call [Builder.remaining] with a well-typed [Double] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun remaining(remaining: JsonField) = apply { this.remaining = remaining } + + /** When credits reset (ISO 8601) */ + fun resetsAt(resetsAt: OffsetDateTime?) = resetsAt(JsonField.ofNullable(resetsAt)) + + /** Alias for calling [Builder.resetsAt] with `resetsAt.orElse(null)`. */ + fun resetsAt(resetsAt: Optional) = resetsAt(resetsAt.getOrNull()) + + /** + * Sets [Builder.resetsAt] to an arbitrary JSON value. + * + * You should usually call [Builder.resetsAt] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun resetsAt(resetsAt: JsonField) = apply { this.resetsAt = resetsAt } + + /** Number of credits used this billing period */ + fun used(used: Double) = used(JsonField.of(used)) + + /** + * Sets [Builder.used] to an arbitrary JSON value. + * + * You should usually call [Builder.used] with a well-typed [Double] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun used(used: JsonField) = apply { this.used = used } + + 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 [CreditCheckResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): CreditCheckResponse = + CreditCheckResponse( + (enabledFeatures ?: JsonMissing.of()).map { it.toImmutable() }, + isUnlimited, + limit, + remaining, + resetsAt, + used, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): CreditCheckResponse = apply { + if (validated) { + return@apply + } + + enabledFeatures() + isUnlimited() + limit() + remaining() + resetsAt() + used() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 = + (enabledFeatures.asKnown().getOrNull()?.size ?: 0) + + (if (isUnlimited.asKnown().isPresent) 1 else 0) + + (if (limit.asKnown().isPresent) 1 else 0) + + (if (remaining.asKnown().isPresent) 1 else 0) + + (if (resetsAt.asKnown().isPresent) 1 else 0) + + (if (used.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is CreditCheckResponse && + enabledFeatures == other.enabledFeatures && + isUnlimited == other.isUnlimited && + limit == other.limit && + remaining == other.remaining && + resetsAt == other.resetsAt && + used == other.used && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + enabledFeatures, + isUnlimited, + limit, + remaining, + resetsAt, + used, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "CreditCheckResponse{enabledFeatures=$enabledFeatures, isUnlimited=$isUnlimited, limit=$limit, remaining=$remaining, resetsAt=$resetsAt, used=$used, additionalProperties=$additionalProperties}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxCheckConnectionStatusParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxCheckConnectionStatusParams.kt new file mode 100644 index 0000000..96b1fab --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxCheckConnectionStatusParams.kt @@ -0,0 +1,252 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.inbox + +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.Params +import com.cas_parser.api.core.checkRequired +import com.cas_parser.api.core.http.Headers +import com.cas_parser.api.core.http.QueryParams +import com.cas_parser.api.core.toImmutable +import java.util.Objects +import java.util.Optional + +/** + * Verify if an `inbox_token` is still valid and check connection status. + * + * Use this to check if the user needs to re-authenticate (e.g., if they revoked access in their + * email provider settings). + */ +class InboxCheckConnectionStatusParams +private constructor( + private val xInboxToken: String, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, + private val additionalBodyProperties: Map, +) : Params { + + fun xInboxToken(): String = xInboxToken + + /** Additional body properties to send with the request. */ + fun _additionalBodyProperties(): Map = additionalBodyProperties + + /** 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 + * [InboxCheckConnectionStatusParams]. + * + * The following fields are required: + * ```java + * .xInboxToken() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [InboxCheckConnectionStatusParams]. */ + class Builder internal constructor() { + + private var xInboxToken: String? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + private var additionalBodyProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(inboxCheckConnectionStatusParams: InboxCheckConnectionStatusParams) = + apply { + xInboxToken = inboxCheckConnectionStatusParams.xInboxToken + additionalHeaders = inboxCheckConnectionStatusParams.additionalHeaders.toBuilder() + additionalQueryParams = + inboxCheckConnectionStatusParams.additionalQueryParams.toBuilder() + additionalBodyProperties = + inboxCheckConnectionStatusParams.additionalBodyProperties.toMutableMap() + } + + fun xInboxToken(xInboxToken: String) = apply { this.xInboxToken = xInboxToken } + + 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) + } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + this.additionalBodyProperties.clear() + putAllAdditionalBodyProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + additionalBodyProperties.put(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + this.additionalBodyProperties.putAll(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { + additionalBodyProperties.remove(key) + } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalBodyProperty) + } + + /** + * Returns an immutable instance of [InboxCheckConnectionStatusParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .xInboxToken() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): InboxCheckConnectionStatusParams = + InboxCheckConnectionStatusParams( + checkRequired("xInboxToken", xInboxToken), + additionalHeaders.build(), + additionalQueryParams.build(), + additionalBodyProperties.toImmutable(), + ) + } + + fun _body(): Optional> = + Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) + + override fun _headers(): Headers = + Headers.builder() + .apply { + put("x-inbox-token", xInboxToken) + putAll(additionalHeaders) + } + .build() + + override fun _queryParams(): QueryParams = additionalQueryParams + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is InboxCheckConnectionStatusParams && + xInboxToken == other.xInboxToken && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams && + additionalBodyProperties == other.additionalBodyProperties + } + + override fun hashCode(): Int = + Objects.hash( + xInboxToken, + additionalHeaders, + additionalQueryParams, + additionalBodyProperties, + ) + + override fun toString() = + "InboxCheckConnectionStatusParams{xInboxToken=$xInboxToken, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxCheckConnectionStatusResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxCheckConnectionStatusResponse.kt new file mode 100644 index 0000000..dad4ab0 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxCheckConnectionStatusResponse.kt @@ -0,0 +1,265 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.inbox + +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonField +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.errors.CasParserInvalidDataException +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 + +class InboxCheckConnectionStatusResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val connected: JsonField, + private val email: JsonField, + private val provider: JsonField, + private val status: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("connected") @ExcludeMissing connected: JsonField = JsonMissing.of(), + @JsonProperty("email") @ExcludeMissing email: JsonField = JsonMissing.of(), + @JsonProperty("provider") @ExcludeMissing provider: JsonField = JsonMissing.of(), + @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(), + ) : this(connected, email, provider, status, mutableMapOf()) + + /** + * Whether the token is valid and usable + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun connected(): Optional = connected.getOptional("connected") + + /** + * Email address of the connected account + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun email(): Optional = email.getOptional("email") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun provider(): Optional = provider.getOptional("provider") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun status(): Optional = status.getOptional("status") + + /** + * Returns the raw JSON value of [connected]. + * + * Unlike [connected], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("connected") @ExcludeMissing fun _connected(): JsonField = connected + + /** + * Returns the raw JSON value of [email]. + * + * Unlike [email], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("email") @ExcludeMissing fun _email(): JsonField = email + + /** + * Returns the raw JSON value of [provider]. + * + * Unlike [provider], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("provider") @ExcludeMissing fun _provider(): JsonField = provider + + /** + * Returns the raw JSON value of [status]. + * + * Unlike [status], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("status") @ExcludeMissing fun _status(): JsonField = status + + @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 + * [InboxCheckConnectionStatusResponse]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [InboxCheckConnectionStatusResponse]. */ + class Builder internal constructor() { + + private var connected: JsonField = JsonMissing.of() + private var email: JsonField = JsonMissing.of() + private var provider: JsonField = JsonMissing.of() + private var status: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(inboxCheckConnectionStatusResponse: InboxCheckConnectionStatusResponse) = + apply { + connected = inboxCheckConnectionStatusResponse.connected + email = inboxCheckConnectionStatusResponse.email + provider = inboxCheckConnectionStatusResponse.provider + status = inboxCheckConnectionStatusResponse.status + additionalProperties = + inboxCheckConnectionStatusResponse.additionalProperties.toMutableMap() + } + + /** Whether the token is valid and usable */ + fun connected(connected: Boolean) = connected(JsonField.of(connected)) + + /** + * Sets [Builder.connected] to an arbitrary JSON value. + * + * You should usually call [Builder.connected] with a well-typed [Boolean] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun connected(connected: JsonField) = apply { this.connected = connected } + + /** Email address of the connected account */ + fun email(email: String) = email(JsonField.of(email)) + + /** + * Sets [Builder.email] to an arbitrary JSON value. + * + * You should usually call [Builder.email] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun email(email: JsonField) = apply { this.email = email } + + fun provider(provider: String) = provider(JsonField.of(provider)) + + /** + * Sets [Builder.provider] to an arbitrary JSON value. + * + * You should usually call [Builder.provider] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun provider(provider: JsonField) = apply { this.provider = provider } + + fun status(status: String) = status(JsonField.of(status)) + + /** + * Sets [Builder.status] to an arbitrary JSON value. + * + * You should usually call [Builder.status] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun status(status: JsonField) = apply { this.status = status } + + 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 [InboxCheckConnectionStatusResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): InboxCheckConnectionStatusResponse = + InboxCheckConnectionStatusResponse( + connected, + email, + provider, + status, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): InboxCheckConnectionStatusResponse = apply { + if (validated) { + return@apply + } + + connected() + email() + provider() + status() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (connected.asKnown().isPresent) 1 else 0) + + (if (email.asKnown().isPresent) 1 else 0) + + (if (provider.asKnown().isPresent) 1 else 0) + + (if (status.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is InboxCheckConnectionStatusResponse && + connected == other.connected && + email == other.email && + provider == other.provider && + status == other.status && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(connected, email, provider, status, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "InboxCheckConnectionStatusResponse{connected=$connected, email=$email, provider=$provider, status=$status, additionalProperties=$additionalProperties}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxConnectEmailParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxConnectEmailParams.kt new file mode 100644 index 0000000..dc2c277 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxConnectEmailParams.kt @@ -0,0 +1,506 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.inbox + +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonField +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.Params +import com.cas_parser.api.core.checkRequired +import com.cas_parser.api.core.http.Headers +import com.cas_parser.api.core.http.QueryParams +import com.cas_parser.api.errors.CasParserInvalidDataException +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 + +/** + * Initiate OAuth flow to connect user's email inbox. + * + * Returns an `oauth_url` that you should redirect the user to. After authorization, they are + * redirected back to your `redirect_uri` with the following query parameters: + * + * **On success:** + * - `inbox_token` - Encrypted token to store client-side + * - `email` - Email address of the connected account + * - `state` - Your original state parameter (for CSRF verification) + * + * **On error:** + * - `error` - Error code (e.g., `access_denied`, `token_exchange_failed`) + * - `state` - Your original state parameter + * + * **Store the `inbox_token` client-side** and use it for all subsequent inbox API calls. + */ +class InboxConnectEmailParams +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Your callback URL to receive the inbox_token (must be http or https) + * + * @throws CasParserInvalidDataException 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 redirectUri(): String = body.redirectUri() + + /** + * State parameter for CSRF protection (returned in redirect) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun state(): Optional = body.state() + + /** + * Returns the raw JSON value of [redirectUri]. + * + * Unlike [redirectUri], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _redirectUri(): JsonField = body._redirectUri() + + /** + * Returns the raw JSON value of [state]. + * + * Unlike [state], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _state(): JsonField = body._state() + + fun _additionalBodyProperties(): Map = body._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 [InboxConnectEmailParams]. + * + * The following fields are required: + * ```java + * .redirectUri() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [InboxConnectEmailParams]. */ + class Builder internal constructor() { + + private var body: Body.Builder = Body.builder() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(inboxConnectEmailParams: InboxConnectEmailParams) = apply { + body = inboxConnectEmailParams.body.toBuilder() + additionalHeaders = inboxConnectEmailParams.additionalHeaders.toBuilder() + additionalQueryParams = inboxConnectEmailParams.additionalQueryParams.toBuilder() + } + + /** + * Sets the entire request body. + * + * This is generally only useful if you are already constructing the body separately. + * Otherwise, it's more convenient to use the top-level setters instead: + * - [redirectUri] + * - [state] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + /** Your callback URL to receive the inbox_token (must be http or https) */ + fun redirectUri(redirectUri: String) = apply { body.redirectUri(redirectUri) } + + /** + * Sets [Builder.redirectUri] to an arbitrary JSON value. + * + * You should usually call [Builder.redirectUri] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun redirectUri(redirectUri: JsonField) = apply { body.redirectUri(redirectUri) } + + /** State parameter for CSRF protection (returned in redirect) */ + fun state(state: String) = apply { body.state(state) } + + /** + * Sets [Builder.state] to an arbitrary JSON value. + * + * You should usually call [Builder.state] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun state(state: JsonField) = apply { body.state(state) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) + } + + 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 [InboxConnectEmailParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .redirectUri() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): InboxConnectEmailParams = + InboxConnectEmailParams( + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + class Body + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val redirectUri: JsonField, + private val state: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("redirect_uri") + @ExcludeMissing + redirectUri: JsonField = JsonMissing.of(), + @JsonProperty("state") @ExcludeMissing state: JsonField = JsonMissing.of(), + ) : this(redirectUri, state, mutableMapOf()) + + /** + * Your callback URL to receive the inbox_token (must be http or https) + * + * @throws CasParserInvalidDataException 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 redirectUri(): String = redirectUri.getRequired("redirect_uri") + + /** + * State parameter for CSRF protection (returned in redirect) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun state(): Optional = state.getOptional("state") + + /** + * Returns the raw JSON value of [redirectUri]. + * + * Unlike [redirectUri], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("redirect_uri") + @ExcludeMissing + fun _redirectUri(): JsonField = redirectUri + + /** + * Returns the raw JSON value of [state]. + * + * Unlike [state], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("state") @ExcludeMissing fun _state(): JsonField = state + + @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 [Body]. + * + * The following fields are required: + * ```java + * .redirectUri() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var redirectUri: JsonField? = null + private var state: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + redirectUri = body.redirectUri + state = body.state + additionalProperties = body.additionalProperties.toMutableMap() + } + + /** Your callback URL to receive the inbox_token (must be http or https) */ + fun redirectUri(redirectUri: String) = redirectUri(JsonField.of(redirectUri)) + + /** + * Sets [Builder.redirectUri] to an arbitrary JSON value. + * + * You should usually call [Builder.redirectUri] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun redirectUri(redirectUri: JsonField) = apply { + this.redirectUri = redirectUri + } + + /** State parameter for CSRF protection (returned in redirect) */ + fun state(state: String) = state(JsonField.of(state)) + + /** + * Sets [Builder.state] to an arbitrary JSON value. + * + * You should usually call [Builder.state] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun state(state: JsonField) = apply { this.state = state } + + 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 [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .redirectUri() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("redirectUri", redirectUri), + state, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + redirectUri() + state() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (redirectUri.asKnown().isPresent) 1 else 0) + + (if (state.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + redirectUri == other.redirectUri && + state == other.state && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(redirectUri, state, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{redirectUri=$redirectUri, state=$state, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is InboxConnectEmailParams && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = Objects.hash(body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "InboxConnectEmailParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxConnectEmailResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxConnectEmailResponse.kt new file mode 100644 index 0000000..4511a59 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxConnectEmailResponse.kt @@ -0,0 +1,230 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.inbox + +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonField +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.errors.CasParserInvalidDataException +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 + +class InboxConnectEmailResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val expiresIn: JsonField, + private val oauthUrl: JsonField, + private val status: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("expires_in") @ExcludeMissing expiresIn: JsonField = JsonMissing.of(), + @JsonProperty("oauth_url") @ExcludeMissing oauthUrl: JsonField = JsonMissing.of(), + @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(), + ) : this(expiresIn, oauthUrl, status, mutableMapOf()) + + /** + * Seconds until the OAuth URL expires (typically 10 minutes) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun expiresIn(): Optional = expiresIn.getOptional("expires_in") + + /** + * Redirect user to this URL to start OAuth flow + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun oauthUrl(): Optional = oauthUrl.getOptional("oauth_url") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun status(): Optional = status.getOptional("status") + + /** + * Returns the raw JSON value of [expiresIn]. + * + * Unlike [expiresIn], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("expires_in") @ExcludeMissing fun _expiresIn(): JsonField = expiresIn + + /** + * Returns the raw JSON value of [oauthUrl]. + * + * Unlike [oauthUrl], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("oauth_url") @ExcludeMissing fun _oauthUrl(): JsonField = oauthUrl + + /** + * Returns the raw JSON value of [status]. + * + * Unlike [status], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("status") @ExcludeMissing fun _status(): JsonField = status + + @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 [InboxConnectEmailResponse]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [InboxConnectEmailResponse]. */ + class Builder internal constructor() { + + private var expiresIn: JsonField = JsonMissing.of() + private var oauthUrl: JsonField = JsonMissing.of() + private var status: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(inboxConnectEmailResponse: InboxConnectEmailResponse) = apply { + expiresIn = inboxConnectEmailResponse.expiresIn + oauthUrl = inboxConnectEmailResponse.oauthUrl + status = inboxConnectEmailResponse.status + additionalProperties = inboxConnectEmailResponse.additionalProperties.toMutableMap() + } + + /** Seconds until the OAuth URL expires (typically 10 minutes) */ + fun expiresIn(expiresIn: Long) = expiresIn(JsonField.of(expiresIn)) + + /** + * Sets [Builder.expiresIn] to an arbitrary JSON value. + * + * You should usually call [Builder.expiresIn] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun expiresIn(expiresIn: JsonField) = apply { this.expiresIn = expiresIn } + + /** Redirect user to this URL to start OAuth flow */ + fun oauthUrl(oauthUrl: String) = oauthUrl(JsonField.of(oauthUrl)) + + /** + * Sets [Builder.oauthUrl] to an arbitrary JSON value. + * + * You should usually call [Builder.oauthUrl] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun oauthUrl(oauthUrl: JsonField) = apply { this.oauthUrl = oauthUrl } + + fun status(status: String) = status(JsonField.of(status)) + + /** + * Sets [Builder.status] to an arbitrary JSON value. + * + * You should usually call [Builder.status] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun status(status: JsonField) = apply { this.status = status } + + 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 [InboxConnectEmailResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): InboxConnectEmailResponse = + InboxConnectEmailResponse( + expiresIn, + oauthUrl, + status, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): InboxConnectEmailResponse = apply { + if (validated) { + return@apply + } + + expiresIn() + oauthUrl() + status() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (expiresIn.asKnown().isPresent) 1 else 0) + + (if (oauthUrl.asKnown().isPresent) 1 else 0) + + (if (status.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is InboxConnectEmailResponse && + expiresIn == other.expiresIn && + oauthUrl == other.oauthUrl && + status == other.status && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(expiresIn, oauthUrl, status, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "InboxConnectEmailResponse{expiresIn=$expiresIn, oauthUrl=$oauthUrl, status=$status, additionalProperties=$additionalProperties}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxDisconnectEmailParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxDisconnectEmailParams.kt new file mode 100644 index 0000000..6caa88e --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxDisconnectEmailParams.kt @@ -0,0 +1,251 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.inbox + +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.Params +import com.cas_parser.api.core.checkRequired +import com.cas_parser.api.core.http.Headers +import com.cas_parser.api.core.http.QueryParams +import com.cas_parser.api.core.toImmutable +import java.util.Objects +import java.util.Optional + +/** + * Revoke email access and invalidate the token. + * + * This calls the provider's token revocation API (e.g., Google's revoke endpoint) to ensure the + * user's consent is properly removed. + * + * After calling this, the `inbox_token` becomes unusable. + */ +class InboxDisconnectEmailParams +private constructor( + private val xInboxToken: String, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, + private val additionalBodyProperties: Map, +) : Params { + + fun xInboxToken(): String = xInboxToken + + /** Additional body properties to send with the request. */ + fun _additionalBodyProperties(): Map = additionalBodyProperties + + /** 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 [InboxDisconnectEmailParams]. + * + * The following fields are required: + * ```java + * .xInboxToken() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [InboxDisconnectEmailParams]. */ + class Builder internal constructor() { + + private var xInboxToken: String? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + private var additionalBodyProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(inboxDisconnectEmailParams: InboxDisconnectEmailParams) = apply { + xInboxToken = inboxDisconnectEmailParams.xInboxToken + additionalHeaders = inboxDisconnectEmailParams.additionalHeaders.toBuilder() + additionalQueryParams = inboxDisconnectEmailParams.additionalQueryParams.toBuilder() + additionalBodyProperties = + inboxDisconnectEmailParams.additionalBodyProperties.toMutableMap() + } + + fun xInboxToken(xInboxToken: String) = apply { this.xInboxToken = xInboxToken } + + 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) + } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + this.additionalBodyProperties.clear() + putAllAdditionalBodyProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + additionalBodyProperties.put(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + this.additionalBodyProperties.putAll(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { + additionalBodyProperties.remove(key) + } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalBodyProperty) + } + + /** + * Returns an immutable instance of [InboxDisconnectEmailParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .xInboxToken() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): InboxDisconnectEmailParams = + InboxDisconnectEmailParams( + checkRequired("xInboxToken", xInboxToken), + additionalHeaders.build(), + additionalQueryParams.build(), + additionalBodyProperties.toImmutable(), + ) + } + + fun _body(): Optional> = + Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) + + override fun _headers(): Headers = + Headers.builder() + .apply { + put("x-inbox-token", xInboxToken) + putAll(additionalHeaders) + } + .build() + + override fun _queryParams(): QueryParams = additionalQueryParams + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is InboxDisconnectEmailParams && + xInboxToken == other.xInboxToken && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams && + additionalBodyProperties == other.additionalBodyProperties + } + + override fun hashCode(): Int = + Objects.hash( + xInboxToken, + additionalHeaders, + additionalQueryParams, + additionalBodyProperties, + ) + + override fun toString() = + "InboxDisconnectEmailParams{xInboxToken=$xInboxToken, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxDisconnectEmailResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxDisconnectEmailResponse.kt new file mode 100644 index 0000000..0214edc --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxDisconnectEmailResponse.kt @@ -0,0 +1,186 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.inbox + +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonField +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.errors.CasParserInvalidDataException +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 + +class InboxDisconnectEmailResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val msg: JsonField, + private val status: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("msg") @ExcludeMissing msg: JsonField = JsonMissing.of(), + @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(), + ) : this(msg, status, mutableMapOf()) + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun msg(): Optional = msg.getOptional("msg") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun status(): Optional = status.getOptional("status") + + /** + * Returns the raw JSON value of [msg]. + * + * Unlike [msg], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("msg") @ExcludeMissing fun _msg(): JsonField = msg + + /** + * Returns the raw JSON value of [status]. + * + * Unlike [status], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("status") @ExcludeMissing fun _status(): JsonField = status + + @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 [InboxDisconnectEmailResponse]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [InboxDisconnectEmailResponse]. */ + class Builder internal constructor() { + + private var msg: JsonField = JsonMissing.of() + private var status: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(inboxDisconnectEmailResponse: InboxDisconnectEmailResponse) = apply { + msg = inboxDisconnectEmailResponse.msg + status = inboxDisconnectEmailResponse.status + additionalProperties = inboxDisconnectEmailResponse.additionalProperties.toMutableMap() + } + + fun msg(msg: String) = msg(JsonField.of(msg)) + + /** + * Sets [Builder.msg] to an arbitrary JSON value. + * + * You should usually call [Builder.msg] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun msg(msg: JsonField) = apply { this.msg = msg } + + fun status(status: String) = status(JsonField.of(status)) + + /** + * Sets [Builder.status] to an arbitrary JSON value. + * + * You should usually call [Builder.status] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun status(status: JsonField) = apply { this.status = status } + + 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 [InboxDisconnectEmailResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): InboxDisconnectEmailResponse = + InboxDisconnectEmailResponse(msg, status, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): InboxDisconnectEmailResponse = apply { + if (validated) { + return@apply + } + + msg() + status() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (msg.asKnown().isPresent) 1 else 0) + (if (status.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is InboxDisconnectEmailResponse && + msg == other.msg && + status == other.status && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(msg, status, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "InboxDisconnectEmailResponse{msg=$msg, status=$status, additionalProperties=$additionalProperties}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesParams.kt new file mode 100644 index 0000000..b3c976d --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesParams.kt @@ -0,0 +1,755 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.inbox + +import com.cas_parser.api.core.Enum +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonField +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.Params +import com.cas_parser.api.core.checkKnown +import com.cas_parser.api.core.checkRequired +import com.cas_parser.api.core.http.Headers +import com.cas_parser.api.core.http.QueryParams +import com.cas_parser.api.core.toImmutable +import com.cas_parser.api.errors.CasParserInvalidDataException +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.time.LocalDate +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * Search the user's email inbox for CAS files from known senders (CAMS, KFintech, CDSL, NSDL). + * + * Files are uploaded to temporary cloud storage. **URLs expire in 24 hours.** + * + * Optionally filter by CAS provider and date range. + * + * **Billing:** 0.2 credits per request (charged regardless of success or number of files found). + */ +class InboxListCasFilesParams +private constructor( + private val xInboxToken: String, + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun xInboxToken(): String = xInboxToken + + /** + * Filter by CAS provider(s): + * - `cdsl` → eCAS@cdslstatement.com + * - `nsdl` → NSDL-CAS@nsdl.co.in + * - `cams` → donotreply@camsonline.com + * - `kfintech` → samfS@kfintech.com + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun casTypes(): Optional> = body.casTypes() + + /** + * End date in ISO format (YYYY-MM-DD). Defaults to today. + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun endDate(): Optional = body.endDate() + + /** + * Start date in ISO format (YYYY-MM-DD). Defaults to 30 days ago. + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun startDate(): Optional = body.startDate() + + /** + * Returns the raw JSON value of [casTypes]. + * + * Unlike [casTypes], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _casTypes(): JsonField> = body._casTypes() + + /** + * Returns the raw JSON value of [endDate]. + * + * Unlike [endDate], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _endDate(): JsonField = body._endDate() + + /** + * Returns the raw JSON value of [startDate]. + * + * Unlike [startDate], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _startDate(): JsonField = body._startDate() + + fun _additionalBodyProperties(): Map = body._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 [InboxListCasFilesParams]. + * + * The following fields are required: + * ```java + * .xInboxToken() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [InboxListCasFilesParams]. */ + class Builder internal constructor() { + + private var xInboxToken: String? = null + private var body: Body.Builder = Body.builder() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(inboxListCasFilesParams: InboxListCasFilesParams) = apply { + xInboxToken = inboxListCasFilesParams.xInboxToken + body = inboxListCasFilesParams.body.toBuilder() + additionalHeaders = inboxListCasFilesParams.additionalHeaders.toBuilder() + additionalQueryParams = inboxListCasFilesParams.additionalQueryParams.toBuilder() + } + + fun xInboxToken(xInboxToken: String) = apply { this.xInboxToken = xInboxToken } + + /** + * Sets the entire request body. + * + * This is generally only useful if you are already constructing the body separately. + * Otherwise, it's more convenient to use the top-level setters instead: + * - [casTypes] + * - [endDate] + * - [startDate] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + /** + * Filter by CAS provider(s): + * - `cdsl` → eCAS@cdslstatement.com + * - `nsdl` → NSDL-CAS@nsdl.co.in + * - `cams` → donotreply@camsonline.com + * - `kfintech` → samfS@kfintech.com + */ + fun casTypes(casTypes: List) = apply { body.casTypes(casTypes) } + + /** + * Sets [Builder.casTypes] to an arbitrary JSON value. + * + * You should usually call [Builder.casTypes] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun casTypes(casTypes: JsonField>) = apply { body.casTypes(casTypes) } + + /** + * Adds a single [CasType] to [casTypes]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addCasType(casType: CasType) = apply { body.addCasType(casType) } + + /** End date in ISO format (YYYY-MM-DD). Defaults to today. */ + fun endDate(endDate: LocalDate) = apply { body.endDate(endDate) } + + /** + * Sets [Builder.endDate] to an arbitrary JSON value. + * + * You should usually call [Builder.endDate] with a well-typed [LocalDate] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun endDate(endDate: JsonField) = apply { body.endDate(endDate) } + + /** Start date in ISO format (YYYY-MM-DD). Defaults to 30 days ago. */ + fun startDate(startDate: LocalDate) = apply { body.startDate(startDate) } + + /** + * Sets [Builder.startDate] to an arbitrary JSON value. + * + * You should usually call [Builder.startDate] with a well-typed [LocalDate] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun startDate(startDate: JsonField) = apply { body.startDate(startDate) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) + } + + 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 [InboxListCasFilesParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .xInboxToken() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): InboxListCasFilesParams = + InboxListCasFilesParams( + checkRequired("xInboxToken", xInboxToken), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): Body = body + + override fun _headers(): Headers = + Headers.builder() + .apply { + put("x-inbox-token", xInboxToken) + putAll(additionalHeaders) + } + .build() + + override fun _queryParams(): QueryParams = additionalQueryParams + + class Body + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val casTypes: JsonField>, + private val endDate: JsonField, + private val startDate: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("cas_types") + @ExcludeMissing + casTypes: JsonField> = JsonMissing.of(), + @JsonProperty("end_date") + @ExcludeMissing + endDate: JsonField = JsonMissing.of(), + @JsonProperty("start_date") + @ExcludeMissing + startDate: JsonField = JsonMissing.of(), + ) : this(casTypes, endDate, startDate, mutableMapOf()) + + /** + * Filter by CAS provider(s): + * - `cdsl` → eCAS@cdslstatement.com + * - `nsdl` → NSDL-CAS@nsdl.co.in + * - `cams` → donotreply@camsonline.com + * - `kfintech` → samfS@kfintech.com + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun casTypes(): Optional> = casTypes.getOptional("cas_types") + + /** + * End date in ISO format (YYYY-MM-DD). Defaults to today. + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun endDate(): Optional = endDate.getOptional("end_date") + + /** + * Start date in ISO format (YYYY-MM-DD). Defaults to 30 days ago. + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun startDate(): Optional = startDate.getOptional("start_date") + + /** + * Returns the raw JSON value of [casTypes]. + * + * Unlike [casTypes], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("cas_types") + @ExcludeMissing + fun _casTypes(): JsonField> = casTypes + + /** + * Returns the raw JSON value of [endDate]. + * + * Unlike [endDate], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("end_date") @ExcludeMissing fun _endDate(): JsonField = endDate + + /** + * Returns the raw JSON value of [startDate]. + * + * Unlike [startDate], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("start_date") + @ExcludeMissing + fun _startDate(): JsonField = startDate + + @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 [Body]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var casTypes: JsonField>? = null + private var endDate: JsonField = JsonMissing.of() + private var startDate: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + casTypes = body.casTypes.map { it.toMutableList() } + endDate = body.endDate + startDate = body.startDate + additionalProperties = body.additionalProperties.toMutableMap() + } + + /** + * Filter by CAS provider(s): + * - `cdsl` → eCAS@cdslstatement.com + * - `nsdl` → NSDL-CAS@nsdl.co.in + * - `cams` → donotreply@camsonline.com + * - `kfintech` → samfS@kfintech.com + */ + fun casTypes(casTypes: List) = casTypes(JsonField.of(casTypes)) + + /** + * Sets [Builder.casTypes] to an arbitrary JSON value. + * + * You should usually call [Builder.casTypes] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun casTypes(casTypes: JsonField>) = apply { + this.casTypes = casTypes.map { it.toMutableList() } + } + + /** + * Adds a single [CasType] to [casTypes]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addCasType(casType: CasType) = apply { + casTypes = + (casTypes ?: JsonField.of(mutableListOf())).also { + checkKnown("casTypes", it).add(casType) + } + } + + /** End date in ISO format (YYYY-MM-DD). Defaults to today. */ + fun endDate(endDate: LocalDate) = endDate(JsonField.of(endDate)) + + /** + * Sets [Builder.endDate] to an arbitrary JSON value. + * + * You should usually call [Builder.endDate] with a well-typed [LocalDate] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun endDate(endDate: JsonField) = apply { this.endDate = endDate } + + /** Start date in ISO format (YYYY-MM-DD). Defaults to 30 days ago. */ + fun startDate(startDate: LocalDate) = startDate(JsonField.of(startDate)) + + /** + * Sets [Builder.startDate] to an arbitrary JSON value. + * + * You should usually call [Builder.startDate] with a well-typed [LocalDate] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun startDate(startDate: JsonField) = apply { this.startDate = startDate } + + 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 [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Body = + Body( + (casTypes ?: JsonMissing.of()).map { it.toImmutable() }, + endDate, + startDate, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + casTypes().ifPresent { it.forEach { it.validate() } } + endDate() + startDate() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 = + (casTypes.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (endDate.asKnown().isPresent) 1 else 0) + + (if (startDate.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + casTypes == other.casTypes && + endDate == other.endDate && + startDate == other.startDate && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(casTypes, endDate, startDate, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{casTypes=$casTypes, endDate=$endDate, startDate=$startDate, additionalProperties=$additionalProperties}" + } + + class CasType @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val CDSL = of("cdsl") + + @JvmField val NSDL = of("nsdl") + + @JvmField val CAMS = of("cams") + + @JvmField val KFINTECH = of("kfintech") + + @JvmStatic fun of(value: String) = CasType(JsonField.of(value)) + } + + /** An enum containing [CasType]'s known values. */ + enum class Known { + CDSL, + NSDL, + CAMS, + KFINTECH, + } + + /** + * An enum containing [CasType]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [CasType] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + CDSL, + NSDL, + CAMS, + KFINTECH, + /** An enum member indicating that [CasType] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + CDSL -> Value.CDSL + NSDL -> Value.NSDL + CAMS -> Value.CAMS + KFINTECH -> Value.KFINTECH + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws CasParserInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + CDSL -> Known.CDSL + NSDL -> Known.NSDL + CAMS -> Known.CAMS + KFINTECH -> Known.KFINTECH + else -> throw CasParserInvalidDataException("Unknown CasType: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws CasParserInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CasParserInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): CasType = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is CasType && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is InboxListCasFilesParams && + xInboxToken == other.xInboxToken && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(xInboxToken, body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "InboxListCasFilesParams{xInboxToken=$xInboxToken, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesResponse.kt new file mode 100644 index 0000000..84d490e --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesResponse.kt @@ -0,0 +1,823 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.inbox + +import com.cas_parser.api.core.Enum +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonField +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.checkKnown +import com.cas_parser.api.core.toImmutable +import com.cas_parser.api.errors.CasParserInvalidDataException +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.time.LocalDate +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +class InboxListCasFilesResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val count: JsonField, + private val files: JsonField>, + private val status: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("count") @ExcludeMissing count: JsonField = JsonMissing.of(), + @JsonProperty("files") @ExcludeMissing files: JsonField> = JsonMissing.of(), + @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(), + ) : this(count, files, status, mutableMapOf()) + + /** + * Number of CAS files found + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun count(): Optional = count.getOptional("count") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun files(): Optional> = files.getOptional("files") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun status(): Optional = status.getOptional("status") + + /** + * Returns the raw JSON value of [count]. + * + * Unlike [count], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("count") @ExcludeMissing fun _count(): JsonField = count + + /** + * Returns the raw JSON value of [files]. + * + * Unlike [files], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("files") @ExcludeMissing fun _files(): JsonField> = files + + /** + * Returns the raw JSON value of [status]. + * + * Unlike [status], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("status") @ExcludeMissing fun _status(): JsonField = status + + @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 [InboxListCasFilesResponse]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [InboxListCasFilesResponse]. */ + class Builder internal constructor() { + + private var count: JsonField = JsonMissing.of() + private var files: JsonField>? = null + private var status: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(inboxListCasFilesResponse: InboxListCasFilesResponse) = apply { + count = inboxListCasFilesResponse.count + files = inboxListCasFilesResponse.files.map { it.toMutableList() } + status = inboxListCasFilesResponse.status + additionalProperties = inboxListCasFilesResponse.additionalProperties.toMutableMap() + } + + /** Number of CAS files found */ + fun count(count: Long) = count(JsonField.of(count)) + + /** + * Sets [Builder.count] to an arbitrary JSON value. + * + * You should usually call [Builder.count] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun count(count: JsonField) = apply { this.count = count } + + fun files(files: List) = files(JsonField.of(files)) + + /** + * Sets [Builder.files] to an arbitrary JSON value. + * + * You should usually call [Builder.files] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun files(files: JsonField>) = apply { + this.files = files.map { it.toMutableList() } + } + + /** + * Adds a single [File] to [files]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addFile(file: File) = apply { + files = + (files ?: JsonField.of(mutableListOf())).also { checkKnown("files", it).add(file) } + } + + fun status(status: String) = status(JsonField.of(status)) + + /** + * Sets [Builder.status] to an arbitrary JSON value. + * + * You should usually call [Builder.status] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun status(status: JsonField) = apply { this.status = status } + + 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 [InboxListCasFilesResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): InboxListCasFilesResponse = + InboxListCasFilesResponse( + count, + (files ?: JsonMissing.of()).map { it.toImmutable() }, + status, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): InboxListCasFilesResponse = apply { + if (validated) { + return@apply + } + + count() + files().ifPresent { it.forEach { it.validate() } } + status() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (count.asKnown().isPresent) 1 else 0) + + (files.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (status.asKnown().isPresent) 1 else 0) + + /** A CAS file found in the user's email inbox */ + class File + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val casType: JsonField, + private val expiresIn: JsonField, + private val filename: JsonField, + private val messageDate: JsonField, + private val messageId: JsonField, + private val originalFilename: JsonField, + private val size: JsonField, + private val url: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("cas_type") + @ExcludeMissing + casType: JsonField = JsonMissing.of(), + @JsonProperty("expires_in") + @ExcludeMissing + expiresIn: JsonField = JsonMissing.of(), + @JsonProperty("filename") + @ExcludeMissing + filename: JsonField = JsonMissing.of(), + @JsonProperty("message_date") + @ExcludeMissing + messageDate: JsonField = JsonMissing.of(), + @JsonProperty("message_id") + @ExcludeMissing + messageId: JsonField = JsonMissing.of(), + @JsonProperty("original_filename") + @ExcludeMissing + originalFilename: JsonField = JsonMissing.of(), + @JsonProperty("size") @ExcludeMissing size: JsonField = JsonMissing.of(), + @JsonProperty("url") @ExcludeMissing url: JsonField = JsonMissing.of(), + ) : this( + casType, + expiresIn, + filename, + messageDate, + messageId, + originalFilename, + size, + url, + mutableMapOf(), + ) + + /** + * Detected CAS provider based on sender email + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun casType(): Optional = casType.getOptional("cas_type") + + /** + * URL expiration time in seconds (default 86400 = 24 hours) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun expiresIn(): Optional = expiresIn.getOptional("expires_in") + + /** + * Standardized filename (provider_YYYYMMDD_uniqueid.pdf) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun filename(): Optional = filename.getOptional("filename") + + /** + * Date the email was received + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun messageDate(): Optional = messageDate.getOptional("message_date") + + /** + * Unique identifier for the email message (use for subsequent API calls) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun messageId(): Optional = messageId.getOptional("message_id") + + /** + * Original attachment filename from the email + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun originalFilename(): Optional = originalFilename.getOptional("original_filename") + + /** + * File size in bytes + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun size(): Optional = size.getOptional("size") + + /** + * Direct download URL (presigned, expires based on expires_in) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun url(): Optional = url.getOptional("url") + + /** + * Returns the raw JSON value of [casType]. + * + * Unlike [casType], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("cas_type") @ExcludeMissing fun _casType(): JsonField = casType + + /** + * Returns the raw JSON value of [expiresIn]. + * + * Unlike [expiresIn], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("expires_in") @ExcludeMissing fun _expiresIn(): JsonField = expiresIn + + /** + * Returns the raw JSON value of [filename]. + * + * Unlike [filename], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("filename") @ExcludeMissing fun _filename(): JsonField = filename + + /** + * Returns the raw JSON value of [messageDate]. + * + * Unlike [messageDate], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("message_date") + @ExcludeMissing + fun _messageDate(): JsonField = messageDate + + /** + * Returns the raw JSON value of [messageId]. + * + * Unlike [messageId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("message_id") @ExcludeMissing fun _messageId(): JsonField = messageId + + /** + * Returns the raw JSON value of [originalFilename]. + * + * Unlike [originalFilename], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("original_filename") + @ExcludeMissing + fun _originalFilename(): JsonField = originalFilename + + /** + * Returns the raw JSON value of [size]. + * + * Unlike [size], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("size") @ExcludeMissing fun _size(): JsonField = size + + /** + * Returns the raw JSON value of [url]. + * + * Unlike [url], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("url") @ExcludeMissing fun _url(): JsonField = url + + @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 [File]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [File]. */ + class Builder internal constructor() { + + private var casType: JsonField = JsonMissing.of() + private var expiresIn: JsonField = JsonMissing.of() + private var filename: JsonField = JsonMissing.of() + private var messageDate: JsonField = JsonMissing.of() + private var messageId: JsonField = JsonMissing.of() + private var originalFilename: JsonField = JsonMissing.of() + private var size: JsonField = JsonMissing.of() + private var url: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(file: File) = apply { + casType = file.casType + expiresIn = file.expiresIn + filename = file.filename + messageDate = file.messageDate + messageId = file.messageId + originalFilename = file.originalFilename + size = file.size + url = file.url + additionalProperties = file.additionalProperties.toMutableMap() + } + + /** Detected CAS provider based on sender email */ + fun casType(casType: CasType) = casType(JsonField.of(casType)) + + /** + * Sets [Builder.casType] to an arbitrary JSON value. + * + * You should usually call [Builder.casType] with a well-typed [CasType] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun casType(casType: JsonField) = apply { this.casType = casType } + + /** URL expiration time in seconds (default 86400 = 24 hours) */ + fun expiresIn(expiresIn: Long) = expiresIn(JsonField.of(expiresIn)) + + /** + * Sets [Builder.expiresIn] to an arbitrary JSON value. + * + * You should usually call [Builder.expiresIn] with a well-typed [Long] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun expiresIn(expiresIn: JsonField) = apply { this.expiresIn = expiresIn } + + /** Standardized filename (provider_YYYYMMDD_uniqueid.pdf) */ + fun filename(filename: String) = filename(JsonField.of(filename)) + + /** + * Sets [Builder.filename] to an arbitrary JSON value. + * + * You should usually call [Builder.filename] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun filename(filename: JsonField) = apply { this.filename = filename } + + /** Date the email was received */ + fun messageDate(messageDate: LocalDate) = messageDate(JsonField.of(messageDate)) + + /** + * Sets [Builder.messageDate] to an arbitrary JSON value. + * + * You should usually call [Builder.messageDate] with a well-typed [LocalDate] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun messageDate(messageDate: JsonField) = apply { + this.messageDate = messageDate + } + + /** Unique identifier for the email message (use for subsequent API calls) */ + fun messageId(messageId: String) = messageId(JsonField.of(messageId)) + + /** + * Sets [Builder.messageId] to an arbitrary JSON value. + * + * You should usually call [Builder.messageId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun messageId(messageId: JsonField) = apply { this.messageId = messageId } + + /** Original attachment filename from the email */ + fun originalFilename(originalFilename: String) = + originalFilename(JsonField.of(originalFilename)) + + /** + * Sets [Builder.originalFilename] to an arbitrary JSON value. + * + * You should usually call [Builder.originalFilename] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun originalFilename(originalFilename: JsonField) = apply { + this.originalFilename = originalFilename + } + + /** File size in bytes */ + fun size(size: Long) = size(JsonField.of(size)) + + /** + * Sets [Builder.size] to an arbitrary JSON value. + * + * You should usually call [Builder.size] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun size(size: JsonField) = apply { this.size = size } + + /** Direct download URL (presigned, expires based on expires_in) */ + fun url(url: String) = url(JsonField.of(url)) + + /** + * Sets [Builder.url] to an arbitrary JSON value. + * + * You should usually call [Builder.url] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun url(url: JsonField) = apply { this.url = url } + + 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 [File]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): File = + File( + casType, + expiresIn, + filename, + messageDate, + messageId, + originalFilename, + size, + url, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): File = apply { + if (validated) { + return@apply + } + + casType().ifPresent { it.validate() } + expiresIn() + filename() + messageDate() + messageId() + originalFilename() + size() + url() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 = + (casType.asKnown().getOrNull()?.validity() ?: 0) + + (if (expiresIn.asKnown().isPresent) 1 else 0) + + (if (filename.asKnown().isPresent) 1 else 0) + + (if (messageDate.asKnown().isPresent) 1 else 0) + + (if (messageId.asKnown().isPresent) 1 else 0) + + (if (originalFilename.asKnown().isPresent) 1 else 0) + + (if (size.asKnown().isPresent) 1 else 0) + + (if (url.asKnown().isPresent) 1 else 0) + + /** Detected CAS provider based on sender email */ + class CasType @JsonCreator private constructor(private val value: JsonField) : + Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is + * on an older version than the API, then the API may respond with new members that the + * SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val CDSL = of("cdsl") + + @JvmField val NSDL = of("nsdl") + + @JvmField val CAMS = of("cams") + + @JvmField val KFINTECH = of("kfintech") + + @JvmStatic fun of(value: String) = CasType(JsonField.of(value)) + } + + /** An enum containing [CasType]'s known values. */ + enum class Known { + CDSL, + NSDL, + CAMS, + KFINTECH, + } + + /** + * An enum containing [CasType]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [CasType] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if + * the SDK is on an older version than the API, then the API may respond with new + * members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + CDSL, + NSDL, + CAMS, + KFINTECH, + /** + * An enum member indicating that [CasType] was instantiated with an unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you + * want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + CDSL -> Value.CDSL + NSDL -> Value.NSDL + CAMS -> Value.CAMS + KFINTECH -> Value.KFINTECH + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and + * don't want to throw for the unknown case. + * + * @throws CasParserInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + CDSL -> Known.CDSL + NSDL -> Known.NSDL + CAMS -> Known.CAMS + KFINTECH -> Known.KFINTECH + else -> throw CasParserInvalidDataException("Unknown CasType: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws CasParserInvalidDataException if this class instance's value does not have + * the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CasParserInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): CasType = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is CasType && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is File && + casType == other.casType && + expiresIn == other.expiresIn && + filename == other.filename && + messageDate == other.messageDate && + messageId == other.messageId && + originalFilename == other.originalFilename && + size == other.size && + url == other.url && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + casType, + expiresIn, + filename, + messageDate, + messageId, + originalFilename, + size, + url, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "File{casType=$casType, expiresIn=$expiresIn, filename=$filename, messageDate=$messageDate, messageId=$messageId, originalFilename=$originalFilename, size=$size, url=$url, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is InboxListCasFilesResponse && + count == other.count && + files == other.files && + status == other.status && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(count, files, status, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "InboxListCasFilesResponse{count=$count, files=$files, status=$status, additionalProperties=$additionalProperties}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/kfintech/KfintechGenerateCasParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/kfintech/KfintechGenerateCasParams.kt new file mode 100644 index 0000000..87b8b15 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/kfintech/KfintechGenerateCasParams.kt @@ -0,0 +1,693 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.kfintech + +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonField +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.Params +import com.cas_parser.api.core.checkRequired +import com.cas_parser.api.core.http.Headers +import com.cas_parser.api.core.http.QueryParams +import com.cas_parser.api.errors.CasParserInvalidDataException +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 + +/** + * Generate CAS via KFintech mailback. The CAS PDF will be sent to the investor's email. + * + * This is an async operation - the investor receives the CAS via email within a few minutes. For + * instant CAS retrieval, use CDSL Fetch (`/v4/cdsl/fetch`). + */ +class KfintechGenerateCasParams +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Email address to receive the CAS document + * + * @throws CasParserInvalidDataException 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 email(): String = body.email() + + /** + * Start date (YYYY-MM-DD) + * + * @throws CasParserInvalidDataException 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 fromDate(): String = body.fromDate() + + /** + * Password for the PDF + * + * @throws CasParserInvalidDataException 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 password(): String = body.password() + + /** + * End date (YYYY-MM-DD) + * + * @throws CasParserInvalidDataException 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 toDate(): String = body.toDate() + + /** + * PAN number (optional) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun panNo(): Optional = body.panNo() + + /** + * Returns the raw JSON value of [email]. + * + * Unlike [email], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _email(): JsonField = body._email() + + /** + * Returns the raw JSON value of [fromDate]. + * + * Unlike [fromDate], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _fromDate(): JsonField = body._fromDate() + + /** + * Returns the raw JSON value of [password]. + * + * Unlike [password], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _password(): JsonField = body._password() + + /** + * Returns the raw JSON value of [toDate]. + * + * Unlike [toDate], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _toDate(): JsonField = body._toDate() + + /** + * Returns the raw JSON value of [panNo]. + * + * Unlike [panNo], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _panNo(): JsonField = body._panNo() + + fun _additionalBodyProperties(): Map = body._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 [KfintechGenerateCasParams]. + * + * The following fields are required: + * ```java + * .email() + * .fromDate() + * .password() + * .toDate() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [KfintechGenerateCasParams]. */ + class Builder internal constructor() { + + private var body: Body.Builder = Body.builder() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(kfintechGenerateCasParams: KfintechGenerateCasParams) = apply { + body = kfintechGenerateCasParams.body.toBuilder() + additionalHeaders = kfintechGenerateCasParams.additionalHeaders.toBuilder() + additionalQueryParams = kfintechGenerateCasParams.additionalQueryParams.toBuilder() + } + + /** + * Sets the entire request body. + * + * This is generally only useful if you are already constructing the body separately. + * Otherwise, it's more convenient to use the top-level setters instead: + * - [email] + * - [fromDate] + * - [password] + * - [toDate] + * - [panNo] + * - etc. + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + /** Email address to receive the CAS document */ + fun email(email: String) = apply { body.email(email) } + + /** + * Sets [Builder.email] to an arbitrary JSON value. + * + * You should usually call [Builder.email] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun email(email: JsonField) = apply { body.email(email) } + + /** Start date (YYYY-MM-DD) */ + fun fromDate(fromDate: String) = apply { body.fromDate(fromDate) } + + /** + * Sets [Builder.fromDate] to an arbitrary JSON value. + * + * You should usually call [Builder.fromDate] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun fromDate(fromDate: JsonField) = apply { body.fromDate(fromDate) } + + /** Password for the PDF */ + fun password(password: String) = apply { body.password(password) } + + /** + * Sets [Builder.password] to an arbitrary JSON value. + * + * You should usually call [Builder.password] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun password(password: JsonField) = apply { body.password(password) } + + /** End date (YYYY-MM-DD) */ + fun toDate(toDate: String) = apply { body.toDate(toDate) } + + /** + * Sets [Builder.toDate] to an arbitrary JSON value. + * + * You should usually call [Builder.toDate] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun toDate(toDate: JsonField) = apply { body.toDate(toDate) } + + /** PAN number (optional) */ + fun panNo(panNo: String) = apply { body.panNo(panNo) } + + /** + * Sets [Builder.panNo] to an arbitrary JSON value. + * + * You should usually call [Builder.panNo] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun panNo(panNo: JsonField) = apply { body.panNo(panNo) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) + } + + 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 [KfintechGenerateCasParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .email() + * .fromDate() + * .password() + * .toDate() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): KfintechGenerateCasParams = + KfintechGenerateCasParams( + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + class Body + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val email: JsonField, + private val fromDate: JsonField, + private val password: JsonField, + private val toDate: JsonField, + private val panNo: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("email") @ExcludeMissing email: JsonField = JsonMissing.of(), + @JsonProperty("from_date") + @ExcludeMissing + fromDate: JsonField = JsonMissing.of(), + @JsonProperty("password") + @ExcludeMissing + password: JsonField = JsonMissing.of(), + @JsonProperty("to_date") @ExcludeMissing toDate: JsonField = JsonMissing.of(), + @JsonProperty("pan_no") @ExcludeMissing panNo: JsonField = JsonMissing.of(), + ) : this(email, fromDate, password, toDate, panNo, mutableMapOf()) + + /** + * Email address to receive the CAS document + * + * @throws CasParserInvalidDataException 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 email(): String = email.getRequired("email") + + /** + * Start date (YYYY-MM-DD) + * + * @throws CasParserInvalidDataException 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 fromDate(): String = fromDate.getRequired("from_date") + + /** + * Password for the PDF + * + * @throws CasParserInvalidDataException 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 password(): String = password.getRequired("password") + + /** + * End date (YYYY-MM-DD) + * + * @throws CasParserInvalidDataException 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 toDate(): String = toDate.getRequired("to_date") + + /** + * PAN number (optional) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun panNo(): Optional = panNo.getOptional("pan_no") + + /** + * Returns the raw JSON value of [email]. + * + * Unlike [email], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("email") @ExcludeMissing fun _email(): JsonField = email + + /** + * Returns the raw JSON value of [fromDate]. + * + * Unlike [fromDate], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("from_date") @ExcludeMissing fun _fromDate(): JsonField = fromDate + + /** + * Returns the raw JSON value of [password]. + * + * Unlike [password], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("password") @ExcludeMissing fun _password(): JsonField = password + + /** + * Returns the raw JSON value of [toDate]. + * + * Unlike [toDate], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("to_date") @ExcludeMissing fun _toDate(): JsonField = toDate + + /** + * Returns the raw JSON value of [panNo]. + * + * Unlike [panNo], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("pan_no") @ExcludeMissing fun _panNo(): JsonField = panNo + + @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 [Body]. + * + * The following fields are required: + * ```java + * .email() + * .fromDate() + * .password() + * .toDate() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var email: JsonField? = null + private var fromDate: JsonField? = null + private var password: JsonField? = null + private var toDate: JsonField? = null + private var panNo: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + email = body.email + fromDate = body.fromDate + password = body.password + toDate = body.toDate + panNo = body.panNo + additionalProperties = body.additionalProperties.toMutableMap() + } + + /** Email address to receive the CAS document */ + fun email(email: String) = email(JsonField.of(email)) + + /** + * Sets [Builder.email] to an arbitrary JSON value. + * + * You should usually call [Builder.email] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun email(email: JsonField) = apply { this.email = email } + + /** Start date (YYYY-MM-DD) */ + fun fromDate(fromDate: String) = fromDate(JsonField.of(fromDate)) + + /** + * Sets [Builder.fromDate] to an arbitrary JSON value. + * + * You should usually call [Builder.fromDate] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun fromDate(fromDate: JsonField) = apply { this.fromDate = fromDate } + + /** Password for the PDF */ + fun password(password: String) = password(JsonField.of(password)) + + /** + * Sets [Builder.password] to an arbitrary JSON value. + * + * You should usually call [Builder.password] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun password(password: JsonField) = apply { this.password = password } + + /** End date (YYYY-MM-DD) */ + fun toDate(toDate: String) = toDate(JsonField.of(toDate)) + + /** + * Sets [Builder.toDate] to an arbitrary JSON value. + * + * You should usually call [Builder.toDate] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun toDate(toDate: JsonField) = apply { this.toDate = toDate } + + /** PAN number (optional) */ + fun panNo(panNo: String) = panNo(JsonField.of(panNo)) + + /** + * Sets [Builder.panNo] to an arbitrary JSON value. + * + * You should usually call [Builder.panNo] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun panNo(panNo: JsonField) = apply { this.panNo = panNo } + + 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 [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .email() + * .fromDate() + * .password() + * .toDate() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("email", email), + checkRequired("fromDate", fromDate), + checkRequired("password", password), + checkRequired("toDate", toDate), + panNo, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + email() + fromDate() + password() + toDate() + panNo() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (email.asKnown().isPresent) 1 else 0) + + (if (fromDate.asKnown().isPresent) 1 else 0) + + (if (password.asKnown().isPresent) 1 else 0) + + (if (toDate.asKnown().isPresent) 1 else 0) + + (if (panNo.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + email == other.email && + fromDate == other.fromDate && + password == other.password && + toDate == other.toDate && + panNo == other.panNo && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(email, fromDate, password, toDate, panNo, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{email=$email, fromDate=$fromDate, password=$password, toDate=$toDate, panNo=$panNo, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is KfintechGenerateCasParams && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = Objects.hash(body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "KfintechGenerateCasParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/kfintech/KfintechGenerateCasResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/kfintech/KfintechGenerateCasResponse.kt new file mode 100644 index 0000000..40e0359 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/kfintech/KfintechGenerateCasResponse.kt @@ -0,0 +1,186 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.kfintech + +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonField +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.errors.CasParserInvalidDataException +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 + +class KfintechGenerateCasResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val msg: JsonField, + private val status: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("msg") @ExcludeMissing msg: JsonField = JsonMissing.of(), + @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(), + ) : this(msg, status, mutableMapOf()) + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun msg(): Optional = msg.getOptional("msg") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun status(): Optional = status.getOptional("status") + + /** + * Returns the raw JSON value of [msg]. + * + * Unlike [msg], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("msg") @ExcludeMissing fun _msg(): JsonField = msg + + /** + * Returns the raw JSON value of [status]. + * + * Unlike [status], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("status") @ExcludeMissing fun _status(): JsonField = status + + @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 [KfintechGenerateCasResponse]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [KfintechGenerateCasResponse]. */ + class Builder internal constructor() { + + private var msg: JsonField = JsonMissing.of() + private var status: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(kfintechGenerateCasResponse: KfintechGenerateCasResponse) = apply { + msg = kfintechGenerateCasResponse.msg + status = kfintechGenerateCasResponse.status + additionalProperties = kfintechGenerateCasResponse.additionalProperties.toMutableMap() + } + + fun msg(msg: String) = msg(JsonField.of(msg)) + + /** + * Sets [Builder.msg] to an arbitrary JSON value. + * + * You should usually call [Builder.msg] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun msg(msg: JsonField) = apply { this.msg = msg } + + fun status(status: String) = status(JsonField.of(status)) + + /** + * Sets [Builder.status] to an arbitrary JSON value. + * + * You should usually call [Builder.status] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun status(status: JsonField) = apply { this.status = status } + + 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 [KfintechGenerateCasResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): KfintechGenerateCasResponse = + KfintechGenerateCasResponse(msg, status, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): KfintechGenerateCasResponse = apply { + if (validated) { + return@apply + } + + msg() + status() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (msg.asKnown().isPresent) 1 else 0) + (if (status.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is KfintechGenerateCasResponse && + msg == other.msg && + status == other.status && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(msg, status, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "KfintechGenerateCasResponse{msg=$msg, status=$status, additionalProperties=$additionalProperties}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogCreateParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogCreateParams.kt new file mode 100644 index 0000000..c46a795 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogCreateParams.kt @@ -0,0 +1,528 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.logs + +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonField +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.Params +import com.cas_parser.api.core.http.Headers +import com.cas_parser.api.core.http.QueryParams +import com.cas_parser.api.errors.CasParserInvalidDataException +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.time.OffsetDateTime +import java.util.Collections +import java.util.Objects +import java.util.Optional + +/** + * Retrieve detailed API usage logs for your account. + * + * Returns a list of API calls with timestamps, features used, status codes, and credits consumed. + * Useful for monitoring usage patterns and debugging. + */ +class LogCreateParams +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * End time filter (ISO 8601). Defaults to now. + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun endTime(): Optional = body.endTime() + + /** + * Maximum number of logs to return + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun limit(): Optional = body.limit() + + /** + * Start time filter (ISO 8601). Defaults to 30 days ago. + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun startTime(): Optional = body.startTime() + + /** + * Returns the raw JSON value of [endTime]. + * + * Unlike [endTime], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _endTime(): JsonField = body._endTime() + + /** + * Returns the raw JSON value of [limit]. + * + * Unlike [limit], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _limit(): JsonField = body._limit() + + /** + * Returns the raw JSON value of [startTime]. + * + * Unlike [startTime], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _startTime(): JsonField = body._startTime() + + fun _additionalBodyProperties(): Map = body._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 { + + @JvmStatic fun none(): LogCreateParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [LogCreateParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [LogCreateParams]. */ + class Builder internal constructor() { + + private var body: Body.Builder = Body.builder() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(logCreateParams: LogCreateParams) = apply { + body = logCreateParams.body.toBuilder() + additionalHeaders = logCreateParams.additionalHeaders.toBuilder() + additionalQueryParams = logCreateParams.additionalQueryParams.toBuilder() + } + + /** + * Sets the entire request body. + * + * This is generally only useful if you are already constructing the body separately. + * Otherwise, it's more convenient to use the top-level setters instead: + * - [endTime] + * - [limit] + * - [startTime] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + /** End time filter (ISO 8601). Defaults to now. */ + fun endTime(endTime: OffsetDateTime) = apply { body.endTime(endTime) } + + /** + * Sets [Builder.endTime] to an arbitrary JSON value. + * + * You should usually call [Builder.endTime] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun endTime(endTime: JsonField) = apply { body.endTime(endTime) } + + /** Maximum number of logs to return */ + fun limit(limit: Long) = apply { body.limit(limit) } + + /** + * Sets [Builder.limit] to an arbitrary JSON value. + * + * You should usually call [Builder.limit] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun limit(limit: JsonField) = apply { body.limit(limit) } + + /** Start time filter (ISO 8601). Defaults to 30 days ago. */ + fun startTime(startTime: OffsetDateTime) = apply { body.startTime(startTime) } + + /** + * Sets [Builder.startTime] to an arbitrary JSON value. + * + * You should usually call [Builder.startTime] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun startTime(startTime: JsonField) = apply { body.startTime(startTime) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) + } + + 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 [LogCreateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): LogCreateParams = + LogCreateParams(body.build(), additionalHeaders.build(), additionalQueryParams.build()) + } + + fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + class Body + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val endTime: JsonField, + private val limit: JsonField, + private val startTime: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("end_time") + @ExcludeMissing + endTime: JsonField = JsonMissing.of(), + @JsonProperty("limit") @ExcludeMissing limit: JsonField = JsonMissing.of(), + @JsonProperty("start_time") + @ExcludeMissing + startTime: JsonField = JsonMissing.of(), + ) : this(endTime, limit, startTime, mutableMapOf()) + + /** + * End time filter (ISO 8601). Defaults to now. + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun endTime(): Optional = endTime.getOptional("end_time") + + /** + * Maximum number of logs to return + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun limit(): Optional = limit.getOptional("limit") + + /** + * Start time filter (ISO 8601). Defaults to 30 days ago. + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun startTime(): Optional = startTime.getOptional("start_time") + + /** + * Returns the raw JSON value of [endTime]. + * + * Unlike [endTime], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("end_time") + @ExcludeMissing + fun _endTime(): JsonField = endTime + + /** + * Returns the raw JSON value of [limit]. + * + * Unlike [limit], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("limit") @ExcludeMissing fun _limit(): JsonField = limit + + /** + * Returns the raw JSON value of [startTime]. + * + * Unlike [startTime], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("start_time") + @ExcludeMissing + fun _startTime(): JsonField = startTime + + @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 [Body]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var endTime: JsonField = JsonMissing.of() + private var limit: JsonField = JsonMissing.of() + private var startTime: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + endTime = body.endTime + limit = body.limit + startTime = body.startTime + additionalProperties = body.additionalProperties.toMutableMap() + } + + /** End time filter (ISO 8601). Defaults to now. */ + fun endTime(endTime: OffsetDateTime) = endTime(JsonField.of(endTime)) + + /** + * Sets [Builder.endTime] to an arbitrary JSON value. + * + * You should usually call [Builder.endTime] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun endTime(endTime: JsonField) = apply { this.endTime = endTime } + + /** Maximum number of logs to return */ + fun limit(limit: Long) = limit(JsonField.of(limit)) + + /** + * Sets [Builder.limit] to an arbitrary JSON value. + * + * You should usually call [Builder.limit] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun limit(limit: JsonField) = apply { this.limit = limit } + + /** Start time filter (ISO 8601). Defaults to 30 days ago. */ + fun startTime(startTime: OffsetDateTime) = startTime(JsonField.of(startTime)) + + /** + * Sets [Builder.startTime] to an arbitrary JSON value. + * + * You should usually call [Builder.startTime] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun startTime(startTime: JsonField) = apply { + this.startTime = startTime + } + + 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 [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Body = Body(endTime, limit, startTime, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + endTime() + limit() + startTime() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (endTime.asKnown().isPresent) 1 else 0) + + (if (limit.asKnown().isPresent) 1 else 0) + + (if (startTime.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + endTime == other.endTime && + limit == other.limit && + startTime == other.startTime && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(endTime, limit, startTime, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{endTime=$endTime, limit=$limit, startTime=$startTime, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is LogCreateParams && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = Objects.hash(body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "LogCreateParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogCreateResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogCreateResponse.kt new file mode 100644 index 0000000..b77a776 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogCreateResponse.kt @@ -0,0 +1,578 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.logs + +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonField +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.checkKnown +import com.cas_parser.api.core.toImmutable +import com.cas_parser.api.errors.CasParserInvalidDataException +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.time.OffsetDateTime +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +class LogCreateResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val count: JsonField, + private val logs: JsonField>, + private val status: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("count") @ExcludeMissing count: JsonField = JsonMissing.of(), + @JsonProperty("logs") @ExcludeMissing logs: JsonField> = JsonMissing.of(), + @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(), + ) : this(count, logs, status, mutableMapOf()) + + /** + * Number of logs returned + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun count(): Optional = count.getOptional("count") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun logs(): Optional> = logs.getOptional("logs") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun status(): Optional = status.getOptional("status") + + /** + * Returns the raw JSON value of [count]. + * + * Unlike [count], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("count") @ExcludeMissing fun _count(): JsonField = count + + /** + * Returns the raw JSON value of [logs]. + * + * Unlike [logs], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("logs") @ExcludeMissing fun _logs(): JsonField> = logs + + /** + * Returns the raw JSON value of [status]. + * + * Unlike [status], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("status") @ExcludeMissing fun _status(): JsonField = status + + @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 [LogCreateResponse]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [LogCreateResponse]. */ + class Builder internal constructor() { + + private var count: JsonField = JsonMissing.of() + private var logs: JsonField>? = null + private var status: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(logCreateResponse: LogCreateResponse) = apply { + count = logCreateResponse.count + logs = logCreateResponse.logs.map { it.toMutableList() } + status = logCreateResponse.status + additionalProperties = logCreateResponse.additionalProperties.toMutableMap() + } + + /** Number of logs returned */ + fun count(count: Long) = count(JsonField.of(count)) + + /** + * Sets [Builder.count] to an arbitrary JSON value. + * + * You should usually call [Builder.count] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun count(count: JsonField) = apply { this.count = count } + + fun logs(logs: List) = logs(JsonField.of(logs)) + + /** + * Sets [Builder.logs] to an arbitrary JSON value. + * + * You should usually call [Builder.logs] with a well-typed `List` value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun logs(logs: JsonField>) = apply { this.logs = logs.map { it.toMutableList() } } + + /** + * Adds a single [Log] to [logs]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addLog(log: Log) = apply { + logs = (logs ?: JsonField.of(mutableListOf())).also { checkKnown("logs", it).add(log) } + } + + fun status(status: String) = status(JsonField.of(status)) + + /** + * Sets [Builder.status] to an arbitrary JSON value. + * + * You should usually call [Builder.status] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun status(status: JsonField) = apply { this.status = status } + + 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 [LogCreateResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): LogCreateResponse = + LogCreateResponse( + count, + (logs ?: JsonMissing.of()).map { it.toImmutable() }, + status, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): LogCreateResponse = apply { + if (validated) { + return@apply + } + + count() + logs().ifPresent { it.forEach { it.validate() } } + status() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (count.asKnown().isPresent) 1 else 0) + + (logs.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (status.asKnown().isPresent) 1 else 0) + + class Log + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val credits: JsonField, + private val feature: JsonField, + private val path: JsonField, + private val requestId: JsonField, + private val statusCode: JsonField, + private val timestamp: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("credits") @ExcludeMissing credits: JsonField = JsonMissing.of(), + @JsonProperty("feature") @ExcludeMissing feature: JsonField = JsonMissing.of(), + @JsonProperty("path") @ExcludeMissing path: JsonField = JsonMissing.of(), + @JsonProperty("request_id") + @ExcludeMissing + requestId: JsonField = JsonMissing.of(), + @JsonProperty("status_code") + @ExcludeMissing + statusCode: JsonField = JsonMissing.of(), + @JsonProperty("timestamp") + @ExcludeMissing + timestamp: JsonField = JsonMissing.of(), + ) : this(credits, feature, path, requestId, statusCode, timestamp, mutableMapOf()) + + /** + * Credits consumed for this request + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun credits(): Optional = credits.getOptional("credits") + + /** + * API feature used + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun feature(): Optional = feature.getOptional("feature") + + /** + * API endpoint path + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun path(): Optional = path.getOptional("path") + + /** + * Unique request identifier + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun requestId(): Optional = requestId.getOptional("request_id") + + /** + * HTTP response status code + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun statusCode(): Optional = statusCode.getOptional("status_code") + + /** + * When the request was made + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun timestamp(): Optional = timestamp.getOptional("timestamp") + + /** + * Returns the raw JSON value of [credits]. + * + * Unlike [credits], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("credits") @ExcludeMissing fun _credits(): JsonField = credits + + /** + * Returns the raw JSON value of [feature]. + * + * Unlike [feature], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("feature") @ExcludeMissing fun _feature(): JsonField = feature + + /** + * Returns the raw JSON value of [path]. + * + * Unlike [path], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("path") @ExcludeMissing fun _path(): JsonField = path + + /** + * Returns the raw JSON value of [requestId]. + * + * Unlike [requestId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("request_id") @ExcludeMissing fun _requestId(): JsonField = requestId + + /** + * Returns the raw JSON value of [statusCode]. + * + * Unlike [statusCode], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("status_code") @ExcludeMissing fun _statusCode(): JsonField = statusCode + + /** + * Returns the raw JSON value of [timestamp]. + * + * Unlike [timestamp], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("timestamp") + @ExcludeMissing + fun _timestamp(): JsonField = timestamp + + @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 [Log]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Log]. */ + class Builder internal constructor() { + + private var credits: JsonField = JsonMissing.of() + private var feature: JsonField = JsonMissing.of() + private var path: JsonField = JsonMissing.of() + private var requestId: JsonField = JsonMissing.of() + private var statusCode: JsonField = JsonMissing.of() + private var timestamp: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(log: Log) = apply { + credits = log.credits + feature = log.feature + path = log.path + requestId = log.requestId + statusCode = log.statusCode + timestamp = log.timestamp + additionalProperties = log.additionalProperties.toMutableMap() + } + + /** Credits consumed for this request */ + fun credits(credits: Double) = credits(JsonField.of(credits)) + + /** + * Sets [Builder.credits] to an arbitrary JSON value. + * + * You should usually call [Builder.credits] with a well-typed [Double] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun credits(credits: JsonField) = apply { this.credits = credits } + + /** API feature used */ + fun feature(feature: String) = feature(JsonField.of(feature)) + + /** + * Sets [Builder.feature] to an arbitrary JSON value. + * + * You should usually call [Builder.feature] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun feature(feature: JsonField) = apply { this.feature = feature } + + /** API endpoint path */ + fun path(path: String) = path(JsonField.of(path)) + + /** + * Sets [Builder.path] to an arbitrary JSON value. + * + * You should usually call [Builder.path] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun path(path: JsonField) = apply { this.path = path } + + /** Unique request identifier */ + fun requestId(requestId: String) = requestId(JsonField.of(requestId)) + + /** + * Sets [Builder.requestId] to an arbitrary JSON value. + * + * You should usually call [Builder.requestId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun requestId(requestId: JsonField) = apply { this.requestId = requestId } + + /** HTTP response status code */ + fun statusCode(statusCode: Long) = statusCode(JsonField.of(statusCode)) + + /** + * Sets [Builder.statusCode] to an arbitrary JSON value. + * + * You should usually call [Builder.statusCode] with a well-typed [Long] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun statusCode(statusCode: JsonField) = apply { this.statusCode = statusCode } + + /** When the request was made */ + fun timestamp(timestamp: OffsetDateTime) = timestamp(JsonField.of(timestamp)) + + /** + * Sets [Builder.timestamp] to an arbitrary JSON value. + * + * You should usually call [Builder.timestamp] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun timestamp(timestamp: JsonField) = apply { + this.timestamp = timestamp + } + + 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 [Log]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Log = + Log( + credits, + feature, + path, + requestId, + statusCode, + timestamp, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Log = apply { + if (validated) { + return@apply + } + + credits() + feature() + path() + requestId() + statusCode() + timestamp() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (credits.asKnown().isPresent) 1 else 0) + + (if (feature.asKnown().isPresent) 1 else 0) + + (if (path.asKnown().isPresent) 1 else 0) + + (if (requestId.asKnown().isPresent) 1 else 0) + + (if (statusCode.asKnown().isPresent) 1 else 0) + + (if (timestamp.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Log && + credits == other.credits && + feature == other.feature && + path == other.path && + requestId == other.requestId && + statusCode == other.statusCode && + timestamp == other.timestamp && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + credits, + feature, + path, + requestId, + statusCode, + timestamp, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Log{credits=$credits, feature=$feature, path=$path, requestId=$requestId, statusCode=$statusCode, timestamp=$timestamp, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is LogCreateResponse && + count == other.count && + logs == other.logs && + status == other.status && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(count, logs, status, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "LogCreateResponse{count=$count, logs=$logs, status=$status, additionalProperties=$additionalProperties}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogGetSummaryParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogGetSummaryParams.kt new file mode 100644 index 0000000..f14f253 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogGetSummaryParams.kt @@ -0,0 +1,468 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.logs + +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonField +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.Params +import com.cas_parser.api.core.http.Headers +import com.cas_parser.api.core.http.QueryParams +import com.cas_parser.api.errors.CasParserInvalidDataException +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.time.OffsetDateTime +import java.util.Collections +import java.util.Objects +import java.util.Optional + +/** + * Get aggregated usage statistics grouped by feature. + * + * Useful for understanding which API features are being used most and tracking usage trends. + */ +class LogGetSummaryParams +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * End time filter (ISO 8601). Defaults to now. + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun endTime(): Optional = body.endTime() + + /** + * Start time filter (ISO 8601). Defaults to start of current month. + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun startTime(): Optional = body.startTime() + + /** + * Returns the raw JSON value of [endTime]. + * + * Unlike [endTime], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _endTime(): JsonField = body._endTime() + + /** + * Returns the raw JSON value of [startTime]. + * + * Unlike [startTime], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _startTime(): JsonField = body._startTime() + + fun _additionalBodyProperties(): Map = body._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 { + + @JvmStatic fun none(): LogGetSummaryParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [LogGetSummaryParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [LogGetSummaryParams]. */ + class Builder internal constructor() { + + private var body: Body.Builder = Body.builder() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(logGetSummaryParams: LogGetSummaryParams) = apply { + body = logGetSummaryParams.body.toBuilder() + additionalHeaders = logGetSummaryParams.additionalHeaders.toBuilder() + additionalQueryParams = logGetSummaryParams.additionalQueryParams.toBuilder() + } + + /** + * Sets the entire request body. + * + * This is generally only useful if you are already constructing the body separately. + * Otherwise, it's more convenient to use the top-level setters instead: + * - [endTime] + * - [startTime] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + /** End time filter (ISO 8601). Defaults to now. */ + fun endTime(endTime: OffsetDateTime) = apply { body.endTime(endTime) } + + /** + * Sets [Builder.endTime] to an arbitrary JSON value. + * + * You should usually call [Builder.endTime] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun endTime(endTime: JsonField) = apply { body.endTime(endTime) } + + /** Start time filter (ISO 8601). Defaults to start of current month. */ + fun startTime(startTime: OffsetDateTime) = apply { body.startTime(startTime) } + + /** + * Sets [Builder.startTime] to an arbitrary JSON value. + * + * You should usually call [Builder.startTime] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun startTime(startTime: JsonField) = apply { body.startTime(startTime) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) + } + + 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 [LogGetSummaryParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): LogGetSummaryParams = + LogGetSummaryParams( + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + class Body + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val endTime: JsonField, + private val startTime: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("end_time") + @ExcludeMissing + endTime: JsonField = JsonMissing.of(), + @JsonProperty("start_time") + @ExcludeMissing + startTime: JsonField = JsonMissing.of(), + ) : this(endTime, startTime, mutableMapOf()) + + /** + * End time filter (ISO 8601). Defaults to now. + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun endTime(): Optional = endTime.getOptional("end_time") + + /** + * Start time filter (ISO 8601). Defaults to start of current month. + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun startTime(): Optional = startTime.getOptional("start_time") + + /** + * Returns the raw JSON value of [endTime]. + * + * Unlike [endTime], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("end_time") + @ExcludeMissing + fun _endTime(): JsonField = endTime + + /** + * Returns the raw JSON value of [startTime]. + * + * Unlike [startTime], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("start_time") + @ExcludeMissing + fun _startTime(): JsonField = startTime + + @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 [Body]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var endTime: JsonField = JsonMissing.of() + private var startTime: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + endTime = body.endTime + startTime = body.startTime + additionalProperties = body.additionalProperties.toMutableMap() + } + + /** End time filter (ISO 8601). Defaults to now. */ + fun endTime(endTime: OffsetDateTime) = endTime(JsonField.of(endTime)) + + /** + * Sets [Builder.endTime] to an arbitrary JSON value. + * + * You should usually call [Builder.endTime] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun endTime(endTime: JsonField) = apply { this.endTime = endTime } + + /** Start time filter (ISO 8601). Defaults to start of current month. */ + fun startTime(startTime: OffsetDateTime) = startTime(JsonField.of(startTime)) + + /** + * Sets [Builder.startTime] to an arbitrary JSON value. + * + * You should usually call [Builder.startTime] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun startTime(startTime: JsonField) = apply { + this.startTime = startTime + } + + 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 [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Body = Body(endTime, startTime, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + endTime() + startTime() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (endTime.asKnown().isPresent) 1 else 0) + + (if (startTime.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + endTime == other.endTime && + startTime == other.startTime && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(endTime, startTime, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{endTime=$endTime, startTime=$startTime, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is LogGetSummaryParams && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = Objects.hash(body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "LogGetSummaryParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogGetSummaryResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogGetSummaryResponse.kt new file mode 100644 index 0000000..a78d1ba --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogGetSummaryResponse.kt @@ -0,0 +1,663 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.logs + +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonField +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.checkKnown +import com.cas_parser.api.core.toImmutable +import com.cas_parser.api.errors.CasParserInvalidDataException +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 + +class LogGetSummaryResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val status: JsonField, + private val summary: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(), + @JsonProperty("summary") @ExcludeMissing summary: JsonField = JsonMissing.of(), + ) : this(status, summary, mutableMapOf()) + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun status(): Optional = status.getOptional("status") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun summary(): Optional = summary.getOptional("summary") + + /** + * Returns the raw JSON value of [status]. + * + * Unlike [status], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("status") @ExcludeMissing fun _status(): JsonField = status + + /** + * Returns the raw JSON value of [summary]. + * + * Unlike [summary], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("summary") @ExcludeMissing fun _summary(): JsonField = summary + + @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 [LogGetSummaryResponse]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [LogGetSummaryResponse]. */ + class Builder internal constructor() { + + private var status: JsonField = JsonMissing.of() + private var summary: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(logGetSummaryResponse: LogGetSummaryResponse) = apply { + status = logGetSummaryResponse.status + summary = logGetSummaryResponse.summary + additionalProperties = logGetSummaryResponse.additionalProperties.toMutableMap() + } + + fun status(status: String) = status(JsonField.of(status)) + + /** + * Sets [Builder.status] to an arbitrary JSON value. + * + * You should usually call [Builder.status] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun status(status: JsonField) = apply { this.status = status } + + fun summary(summary: Summary) = summary(JsonField.of(summary)) + + /** + * Sets [Builder.summary] to an arbitrary JSON value. + * + * You should usually call [Builder.summary] with a well-typed [Summary] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun summary(summary: JsonField) = apply { this.summary = summary } + + 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 [LogGetSummaryResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): LogGetSummaryResponse = + LogGetSummaryResponse(status, summary, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): LogGetSummaryResponse = apply { + if (validated) { + return@apply + } + + status() + summary().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (status.asKnown().isPresent) 1 else 0) + + (summary.asKnown().getOrNull()?.validity() ?: 0) + + class Summary + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val byFeature: JsonField>, + private val totalCredits: JsonField, + private val totalRequests: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("by_feature") + @ExcludeMissing + byFeature: JsonField> = JsonMissing.of(), + @JsonProperty("total_credits") + @ExcludeMissing + totalCredits: JsonField = JsonMissing.of(), + @JsonProperty("total_requests") + @ExcludeMissing + totalRequests: JsonField = JsonMissing.of(), + ) : this(byFeature, totalCredits, totalRequests, mutableMapOf()) + + /** + * Usage breakdown by feature + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun byFeature(): Optional> = byFeature.getOptional("by_feature") + + /** + * Total credits consumed in the period + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun totalCredits(): Optional = totalCredits.getOptional("total_credits") + + /** + * Total API requests made in the period + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun totalRequests(): Optional = totalRequests.getOptional("total_requests") + + /** + * Returns the raw JSON value of [byFeature]. + * + * Unlike [byFeature], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("by_feature") + @ExcludeMissing + fun _byFeature(): JsonField> = byFeature + + /** + * Returns the raw JSON value of [totalCredits]. + * + * Unlike [totalCredits], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("total_credits") + @ExcludeMissing + fun _totalCredits(): JsonField = totalCredits + + /** + * Returns the raw JSON value of [totalRequests]. + * + * Unlike [totalRequests], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("total_requests") + @ExcludeMissing + fun _totalRequests(): JsonField = totalRequests + + @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 [Summary]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Summary]. */ + class Builder internal constructor() { + + private var byFeature: JsonField>? = null + private var totalCredits: JsonField = JsonMissing.of() + private var totalRequests: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(summary: Summary) = apply { + byFeature = summary.byFeature.map { it.toMutableList() } + totalCredits = summary.totalCredits + totalRequests = summary.totalRequests + additionalProperties = summary.additionalProperties.toMutableMap() + } + + /** Usage breakdown by feature */ + fun byFeature(byFeature: List) = byFeature(JsonField.of(byFeature)) + + /** + * Sets [Builder.byFeature] to an arbitrary JSON value. + * + * You should usually call [Builder.byFeature] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun byFeature(byFeature: JsonField>) = apply { + this.byFeature = byFeature.map { it.toMutableList() } + } + + /** + * Adds a single [ByFeature] to [Builder.byFeature]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addByFeature(byFeature: ByFeature) = apply { + this.byFeature = + (this.byFeature ?: JsonField.of(mutableListOf())).also { + checkKnown("byFeature", it).add(byFeature) + } + } + + /** Total credits consumed in the period */ + fun totalCredits(totalCredits: Double) = totalCredits(JsonField.of(totalCredits)) + + /** + * Sets [Builder.totalCredits] to an arbitrary JSON value. + * + * You should usually call [Builder.totalCredits] with a well-typed [Double] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun totalCredits(totalCredits: JsonField) = apply { + this.totalCredits = totalCredits + } + + /** Total API requests made in the period */ + fun totalRequests(totalRequests: Long) = totalRequests(JsonField.of(totalRequests)) + + /** + * Sets [Builder.totalRequests] to an arbitrary JSON value. + * + * You should usually call [Builder.totalRequests] with a well-typed [Long] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun totalRequests(totalRequests: JsonField) = apply { + this.totalRequests = totalRequests + } + + 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 [Summary]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Summary = + Summary( + (byFeature ?: JsonMissing.of()).map { it.toImmutable() }, + totalCredits, + totalRequests, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Summary = apply { + if (validated) { + return@apply + } + + byFeature().ifPresent { it.forEach { it.validate() } } + totalCredits() + totalRequests() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 = + (byFeature.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (totalCredits.asKnown().isPresent) 1 else 0) + + (if (totalRequests.asKnown().isPresent) 1 else 0) + + class ByFeature + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val credits: JsonField, + private val feature: JsonField, + private val requests: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("credits") + @ExcludeMissing + credits: JsonField = JsonMissing.of(), + @JsonProperty("feature") + @ExcludeMissing + feature: JsonField = JsonMissing.of(), + @JsonProperty("requests") + @ExcludeMissing + requests: JsonField = JsonMissing.of(), + ) : this(credits, feature, requests, mutableMapOf()) + + /** + * Credits consumed by this feature + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun credits(): Optional = credits.getOptional("credits") + + /** + * API feature name + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun feature(): Optional = feature.getOptional("feature") + + /** + * Number of requests for this feature + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun requests(): Optional = requests.getOptional("requests") + + /** + * Returns the raw JSON value of [credits]. + * + * Unlike [credits], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("credits") @ExcludeMissing fun _credits(): JsonField = credits + + /** + * Returns the raw JSON value of [feature]. + * + * Unlike [feature], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("feature") @ExcludeMissing fun _feature(): JsonField = feature + + /** + * Returns the raw JSON value of [requests]. + * + * Unlike [requests], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("requests") @ExcludeMissing fun _requests(): JsonField = requests + + @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 [ByFeature]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ByFeature]. */ + class Builder internal constructor() { + + private var credits: JsonField = JsonMissing.of() + private var feature: JsonField = JsonMissing.of() + private var requests: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(byFeature: ByFeature) = apply { + credits = byFeature.credits + feature = byFeature.feature + requests = byFeature.requests + additionalProperties = byFeature.additionalProperties.toMutableMap() + } + + /** Credits consumed by this feature */ + fun credits(credits: Double) = credits(JsonField.of(credits)) + + /** + * Sets [Builder.credits] to an arbitrary JSON value. + * + * You should usually call [Builder.credits] with a well-typed [Double] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun credits(credits: JsonField) = apply { this.credits = credits } + + /** API feature name */ + fun feature(feature: String) = feature(JsonField.of(feature)) + + /** + * Sets [Builder.feature] to an arbitrary JSON value. + * + * You should usually call [Builder.feature] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun feature(feature: JsonField) = apply { this.feature = feature } + + /** Number of requests for this feature */ + fun requests(requests: Long) = requests(JsonField.of(requests)) + + /** + * Sets [Builder.requests] to an arbitrary JSON value. + * + * You should usually call [Builder.requests] with a well-typed [Long] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun requests(requests: JsonField) = apply { this.requests = requests } + + 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 [ByFeature]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): ByFeature = + ByFeature(credits, feature, requests, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): ByFeature = apply { + if (validated) { + return@apply + } + + credits() + feature() + requests() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (credits.asKnown().isPresent) 1 else 0) + + (if (feature.asKnown().isPresent) 1 else 0) + + (if (requests.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ByFeature && + credits == other.credits && + feature == other.feature && + requests == other.requests && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(credits, feature, requests, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ByFeature{credits=$credits, feature=$feature, requests=$requests, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Summary && + byFeature == other.byFeature && + totalCredits == other.totalCredits && + totalRequests == other.totalRequests && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(byFeature, totalCredits, totalRequests, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Summary{byFeature=$byFeature, totalCredits=$totalCredits, totalRequests=$totalRequests, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is LogGetSummaryResponse && + status == other.status && + summary == other.summary && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(status, summary, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "LogGetSummaryResponse{status=$status, summary=$summary, additionalProperties=$additionalProperties}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserNsdlParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/nsdl/NsdlParseParams.kt similarity index 94% rename from cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserNsdlParams.kt rename to cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/nsdl/NsdlParseParams.kt index 87cec06..240f71c 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserNsdlParams.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/nsdl/NsdlParseParams.kt @@ -1,6 +1,6 @@ // File generated from our OpenAPI spec by Stainless. -package com.cas_parser.api.models.casparser +package com.cas_parser.api.models.nsdl import com.cas_parser.api.core.ExcludeMissing import com.cas_parser.api.core.JsonValue @@ -21,7 +21,7 @@ import java.util.Optional * This endpoint specifically parses NSDL CAS (Consolidated Account Statement) PDF files and returns * data in a unified format. Use this endpoint when you know the PDF is from NSDL. */ -class CasParserNsdlParams +class NsdlParseParams private constructor( private val body: Body, private val additionalHeaders: Headers, @@ -85,13 +85,13 @@ private constructor( companion object { - @JvmStatic fun none(): CasParserNsdlParams = builder().build() + @JvmStatic fun none(): NsdlParseParams = builder().build() - /** Returns a mutable builder for constructing an instance of [CasParserNsdlParams]. */ + /** Returns a mutable builder for constructing an instance of [NsdlParseParams]. */ @JvmStatic fun builder() = Builder() } - /** A builder for [CasParserNsdlParams]. */ + /** A builder for [NsdlParseParams]. */ class Builder internal constructor() { private var body: Body.Builder = Body.builder() @@ -99,10 +99,10 @@ private constructor( private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic - internal fun from(casParserNsdlParams: CasParserNsdlParams) = apply { - body = casParserNsdlParams.body.toBuilder() - additionalHeaders = casParserNsdlParams.additionalHeaders.toBuilder() - additionalQueryParams = casParserNsdlParams.additionalQueryParams.toBuilder() + internal fun from(nsdlParseParams: NsdlParseParams) = apply { + body = nsdlParseParams.body.toBuilder() + additionalHeaders = nsdlParseParams.additionalHeaders.toBuilder() + additionalQueryParams = nsdlParseParams.additionalQueryParams.toBuilder() } /** @@ -267,16 +267,12 @@ private constructor( } /** - * Returns an immutable instance of [CasParserNsdlParams]. + * Returns an immutable instance of [NsdlParseParams]. * * Further updates to this [Builder] will not mutate the returned instance. */ - fun build(): CasParserNsdlParams = - CasParserNsdlParams( - body.build(), - additionalHeaders.build(), - additionalQueryParams.build(), - ) + fun build(): NsdlParseParams = + NsdlParseParams(body.build(), additionalHeaders.build(), additionalQueryParams.build()) } fun _body(): Map> = @@ -489,7 +485,7 @@ private constructor( return true } - return other is CasParserNsdlParams && + return other is NsdlParseParams && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams @@ -498,5 +494,5 @@ private constructor( override fun hashCode(): Int = Objects.hash(body, additionalHeaders, additionalQueryParams) override fun toString() = - "CasParserNsdlParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" + "NsdlParseParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserSmartParseParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/smart/SmartParseCasPdfParams.kt similarity index 94% rename from cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserSmartParseParams.kt rename to cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/smart/SmartParseCasPdfParams.kt index 99ecd8a..cbfbeb1 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/casparser/CasParserSmartParseParams.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/smart/SmartParseCasPdfParams.kt @@ -1,6 +1,6 @@ // File generated from our OpenAPI spec by Stainless. -package com.cas_parser.api.models.casparser +package com.cas_parser.api.models.smart import com.cas_parser.api.core.ExcludeMissing import com.cas_parser.api.core.JsonValue @@ -22,7 +22,7 @@ import java.util.Optional * CAMS/KFintech and returns data in a unified format. It auto-detects the CAS type and transforms * the data into a consistent structure regardless of the source. */ -class CasParserSmartParseParams +class SmartParseCasPdfParams private constructor( private val body: Body, private val additionalHeaders: Headers, @@ -86,15 +86,13 @@ private constructor( companion object { - @JvmStatic fun none(): CasParserSmartParseParams = builder().build() + @JvmStatic fun none(): SmartParseCasPdfParams = builder().build() - /** - * Returns a mutable builder for constructing an instance of [CasParserSmartParseParams]. - */ + /** Returns a mutable builder for constructing an instance of [SmartParseCasPdfParams]. */ @JvmStatic fun builder() = Builder() } - /** A builder for [CasParserSmartParseParams]. */ + /** A builder for [SmartParseCasPdfParams]. */ class Builder internal constructor() { private var body: Body.Builder = Body.builder() @@ -102,10 +100,10 @@ private constructor( private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic - internal fun from(casParserSmartParseParams: CasParserSmartParseParams) = apply { - body = casParserSmartParseParams.body.toBuilder() - additionalHeaders = casParserSmartParseParams.additionalHeaders.toBuilder() - additionalQueryParams = casParserSmartParseParams.additionalQueryParams.toBuilder() + internal fun from(smartParseCasPdfParams: SmartParseCasPdfParams) = apply { + body = smartParseCasPdfParams.body.toBuilder() + additionalHeaders = smartParseCasPdfParams.additionalHeaders.toBuilder() + additionalQueryParams = smartParseCasPdfParams.additionalQueryParams.toBuilder() } /** @@ -270,12 +268,12 @@ private constructor( } /** - * Returns an immutable instance of [CasParserSmartParseParams]. + * Returns an immutable instance of [SmartParseCasPdfParams]. * * Further updates to this [Builder] will not mutate the returned instance. */ - fun build(): CasParserSmartParseParams = - CasParserSmartParseParams( + fun build(): SmartParseCasPdfParams = + SmartParseCasPdfParams( body.build(), additionalHeaders.build(), additionalQueryParams.build(), @@ -492,7 +490,7 @@ private constructor( return true } - return other is CasParserSmartParseParams && + return other is SmartParseCasPdfParams && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams @@ -501,5 +499,5 @@ private constructor( override fun hashCode(): Int = Objects.hash(body, additionalHeaders, additionalQueryParams) override fun toString() = - "CasParserSmartParseParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" + "SmartParseCasPdfParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyParams.kt new file mode 100644 index 0000000..aac1a81 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyParams.kt @@ -0,0 +1,211 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.verifytoken + +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.Params +import com.cas_parser.api.core.http.Headers +import com.cas_parser.api.core.http.QueryParams +import com.cas_parser.api.core.toImmutable +import java.util.Objects +import java.util.Optional + +/** Verify an access token and check if it's still valid. Useful for debugging token issues. */ +class VerifyTokenVerifyParams +private constructor( + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, + private val additionalBodyProperties: Map, +) : Params { + + /** Additional body properties to send with the request. */ + fun _additionalBodyProperties(): Map = additionalBodyProperties + + /** 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 { + + @JvmStatic fun none(): VerifyTokenVerifyParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [VerifyTokenVerifyParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [VerifyTokenVerifyParams]. */ + class Builder internal constructor() { + + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + private var additionalBodyProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(verifyTokenVerifyParams: VerifyTokenVerifyParams) = apply { + additionalHeaders = verifyTokenVerifyParams.additionalHeaders.toBuilder() + additionalQueryParams = verifyTokenVerifyParams.additionalQueryParams.toBuilder() + additionalBodyProperties = + verifyTokenVerifyParams.additionalBodyProperties.toMutableMap() + } + + 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) + } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + this.additionalBodyProperties.clear() + putAllAdditionalBodyProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + additionalBodyProperties.put(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + this.additionalBodyProperties.putAll(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { + additionalBodyProperties.remove(key) + } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalBodyProperty) + } + + /** + * Returns an immutable instance of [VerifyTokenVerifyParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): VerifyTokenVerifyParams = + VerifyTokenVerifyParams( + additionalHeaders.build(), + additionalQueryParams.build(), + additionalBodyProperties.toImmutable(), + ) + } + + fun _body(): Optional> = + Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is VerifyTokenVerifyParams && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams && + additionalBodyProperties == other.additionalBodyProperties + } + + override fun hashCode(): Int = + Objects.hash(additionalHeaders, additionalQueryParams, additionalBodyProperties) + + override fun toString() = + "VerifyTokenVerifyParams{additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyResponse.kt new file mode 100644 index 0000000..b8859a0 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyResponse.kt @@ -0,0 +1,240 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.verifytoken + +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonField +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.errors.CasParserInvalidDataException +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 + +class VerifyTokenVerifyResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val error: JsonField, + private val maskedApiKey: JsonField, + private val valid: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("error") @ExcludeMissing error: JsonField = JsonMissing.of(), + @JsonProperty("masked_api_key") + @ExcludeMissing + maskedApiKey: JsonField = JsonMissing.of(), + @JsonProperty("valid") @ExcludeMissing valid: JsonField = JsonMissing.of(), + ) : this(error, maskedApiKey, valid, mutableMapOf()) + + /** + * Error message (only shown if invalid) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun error(): Optional = error.getOptional("error") + + /** + * Masked API key (only shown if valid) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun maskedApiKey(): Optional = maskedApiKey.getOptional("masked_api_key") + + /** + * Whether the token is valid + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun valid(): Optional = valid.getOptional("valid") + + /** + * Returns the raw JSON value of [error]. + * + * Unlike [error], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("error") @ExcludeMissing fun _error(): JsonField = error + + /** + * Returns the raw JSON value of [maskedApiKey]. + * + * Unlike [maskedApiKey], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("masked_api_key") + @ExcludeMissing + fun _maskedApiKey(): JsonField = maskedApiKey + + /** + * Returns the raw JSON value of [valid]. + * + * Unlike [valid], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("valid") @ExcludeMissing fun _valid(): JsonField = valid + + @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 [VerifyTokenVerifyResponse]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [VerifyTokenVerifyResponse]. */ + class Builder internal constructor() { + + private var error: JsonField = JsonMissing.of() + private var maskedApiKey: JsonField = JsonMissing.of() + private var valid: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(verifyTokenVerifyResponse: VerifyTokenVerifyResponse) = apply { + error = verifyTokenVerifyResponse.error + maskedApiKey = verifyTokenVerifyResponse.maskedApiKey + valid = verifyTokenVerifyResponse.valid + additionalProperties = verifyTokenVerifyResponse.additionalProperties.toMutableMap() + } + + /** Error message (only shown if invalid) */ + fun error(error: String) = error(JsonField.of(error)) + + /** + * Sets [Builder.error] to an arbitrary JSON value. + * + * You should usually call [Builder.error] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun error(error: JsonField) = apply { this.error = error } + + /** Masked API key (only shown if valid) */ + fun maskedApiKey(maskedApiKey: String) = maskedApiKey(JsonField.of(maskedApiKey)) + + /** + * Sets [Builder.maskedApiKey] to an arbitrary JSON value. + * + * You should usually call [Builder.maskedApiKey] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun maskedApiKey(maskedApiKey: JsonField) = apply { + this.maskedApiKey = maskedApiKey + } + + /** Whether the token is valid */ + fun valid(valid: Boolean) = valid(JsonField.of(valid)) + + /** + * Sets [Builder.valid] to an arbitrary JSON value. + * + * You should usually call [Builder.valid] with a well-typed [Boolean] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun valid(valid: JsonField) = apply { this.valid = valid } + + 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 [VerifyTokenVerifyResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): VerifyTokenVerifyResponse = + VerifyTokenVerifyResponse( + error, + maskedApiKey, + valid, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): VerifyTokenVerifyResponse = apply { + if (validated) { + return@apply + } + + error() + maskedApiKey() + valid() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (error.asKnown().isPresent) 1 else 0) + + (if (maskedApiKey.asKnown().isPresent) 1 else 0) + + (if (valid.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is VerifyTokenVerifyResponse && + error == other.error && + maskedApiKey == other.maskedApiKey && + valid == other.valid && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(error, maskedApiKey, valid, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "VerifyTokenVerifyResponse{error=$error, maskedApiKey=$maskedApiKey, valid=$valid, additionalProperties=$additionalProperties}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsync.kt new file mode 100644 index 0000000..0948924 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsync.kt @@ -0,0 +1,97 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.models.accesstoken.AccessTokenCreateParams +import com.cas_parser.api.models.accesstoken.AccessTokenCreateResponse +import java.util.concurrent.CompletableFuture +import java.util.function.Consumer + +interface AccessTokenServiceAsync { + + /** + * 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): AccessTokenServiceAsync + + /** + * Generate a short-lived access token from your API key. + * + * **Use this endpoint from your backend** to create tokens that can be safely passed to + * frontend/SDK. + * + * Access tokens: + * - Are prefixed with `at_` for easy identification + * - Valid for up to 60 minutes + * - Can be used in place of API keys on all v4 endpoints + * - Cannot be used to generate other access tokens + */ + fun create(): CompletableFuture = + create(AccessTokenCreateParams.none()) + + /** @see create */ + fun create( + params: AccessTokenCreateParams = AccessTokenCreateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see create */ + fun create( + params: AccessTokenCreateParams = AccessTokenCreateParams.none() + ): CompletableFuture = create(params, RequestOptions.none()) + + /** @see create */ + fun create(requestOptions: RequestOptions): CompletableFuture = + create(AccessTokenCreateParams.none(), requestOptions) + + /** + * A view of [AccessTokenServiceAsync] 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 + ): AccessTokenServiceAsync.WithRawResponse + + /** + * Returns a raw HTTP response for `post /v1/access-token`, but is otherwise the same as + * [AccessTokenServiceAsync.create]. + */ + fun create(): CompletableFuture> = + create(AccessTokenCreateParams.none()) + + /** @see create */ + fun create( + params: AccessTokenCreateParams = AccessTokenCreateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see create */ + fun create( + params: AccessTokenCreateParams = AccessTokenCreateParams.none() + ): CompletableFuture> = + create(params, RequestOptions.none()) + + /** @see create */ + fun create( + requestOptions: RequestOptions + ): CompletableFuture> = + create(AccessTokenCreateParams.none(), requestOptions) + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsyncImpl.kt new file mode 100644 index 0000000..e71b99c --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsyncImpl.kt @@ -0,0 +1,86 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.handlers.errorBodyHandler +import com.cas_parser.api.core.handlers.errorHandler +import com.cas_parser.api.core.handlers.jsonHandler +import com.cas_parser.api.core.http.HttpMethod +import com.cas_parser.api.core.http.HttpRequest +import com.cas_parser.api.core.http.HttpResponse +import com.cas_parser.api.core.http.HttpResponse.Handler +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.core.http.json +import com.cas_parser.api.core.http.parseable +import com.cas_parser.api.core.prepareAsync +import com.cas_parser.api.models.accesstoken.AccessTokenCreateParams +import com.cas_parser.api.models.accesstoken.AccessTokenCreateResponse +import java.util.concurrent.CompletableFuture +import java.util.function.Consumer + +class AccessTokenServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + AccessTokenServiceAsync { + + private val withRawResponse: AccessTokenServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): AccessTokenServiceAsync.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): AccessTokenServiceAsync = + AccessTokenServiceAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun create( + params: AccessTokenCreateParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v1/access-token + withRawResponse().create(params, requestOptions).thenApply { it.parse() } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + AccessTokenServiceAsync.WithRawResponse { + + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + + override fun withOptions( + modifier: Consumer + ): AccessTokenServiceAsync.WithRawResponse = + AccessTokenServiceAsyncImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun create( + params: AccessTokenCreateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v1", "access-token") + .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 { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CamsKfintechServiceAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CamsKfintechServiceAsync.kt new file mode 100644 index 0000000..c7651f1 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CamsKfintechServiceAsync.kt @@ -0,0 +1,89 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.models.camskfintech.CamsKfintechParseParams +import com.cas_parser.api.models.camskfintech.UnifiedResponse +import java.util.concurrent.CompletableFuture +import java.util.function.Consumer + +interface CamsKfintechServiceAsync { + + /** + * 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): CamsKfintechServiceAsync + + /** + * This endpoint specifically parses CAMS/KFintech CAS (Consolidated Account Statement) PDF + * files and returns data in a unified format. Use this endpoint when you know the PDF is from + * CAMS or KFintech. + */ + fun parse(): CompletableFuture = parse(CamsKfintechParseParams.none()) + + /** @see parse */ + fun parse( + params: CamsKfintechParseParams = CamsKfintechParseParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see parse */ + fun parse( + params: CamsKfintechParseParams = CamsKfintechParseParams.none() + ): CompletableFuture = parse(params, RequestOptions.none()) + + /** @see parse */ + fun parse(requestOptions: RequestOptions): CompletableFuture = + parse(CamsKfintechParseParams.none(), requestOptions) + + /** + * A view of [CamsKfintechServiceAsync] 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 + ): CamsKfintechServiceAsync.WithRawResponse + + /** + * Returns a raw HTTP response for `post /v4/cams_kfintech/parse`, but is otherwise the same + * as [CamsKfintechServiceAsync.parse]. + */ + fun parse(): CompletableFuture> = + parse(CamsKfintechParseParams.none()) + + /** @see parse */ + fun parse( + params: CamsKfintechParseParams = CamsKfintechParseParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see parse */ + fun parse( + params: CamsKfintechParseParams = CamsKfintechParseParams.none() + ): CompletableFuture> = + parse(params, RequestOptions.none()) + + /** @see parse */ + fun parse( + requestOptions: RequestOptions + ): CompletableFuture> = + parse(CamsKfintechParseParams.none(), requestOptions) + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CamsKfintechServiceAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CamsKfintechServiceAsyncImpl.kt new file mode 100644 index 0000000..ef05059 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CamsKfintechServiceAsyncImpl.kt @@ -0,0 +1,86 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.handlers.errorBodyHandler +import com.cas_parser.api.core.handlers.errorHandler +import com.cas_parser.api.core.handlers.jsonHandler +import com.cas_parser.api.core.http.HttpMethod +import com.cas_parser.api.core.http.HttpRequest +import com.cas_parser.api.core.http.HttpResponse +import com.cas_parser.api.core.http.HttpResponse.Handler +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.core.http.multipartFormData +import com.cas_parser.api.core.http.parseable +import com.cas_parser.api.core.prepareAsync +import com.cas_parser.api.models.camskfintech.CamsKfintechParseParams +import com.cas_parser.api.models.camskfintech.UnifiedResponse +import java.util.concurrent.CompletableFuture +import java.util.function.Consumer + +class CamsKfintechServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + CamsKfintechServiceAsync { + + private val withRawResponse: CamsKfintechServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): CamsKfintechServiceAsync.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): CamsKfintechServiceAsync = + CamsKfintechServiceAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun parse( + params: CamsKfintechParseParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v4/cams_kfintech/parse + withRawResponse().parse(params, requestOptions).thenApply { it.parse() } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + CamsKfintechServiceAsync.WithRawResponse { + + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + + override fun withOptions( + modifier: Consumer + ): CamsKfintechServiceAsync.WithRawResponse = + CamsKfintechServiceAsyncImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + private val parseHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun parse( + params: CamsKfintechParseParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v4", "cams_kfintech", "parse") + .body(multipartFormData(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 { parseHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CasGeneratorServiceAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CasGeneratorServiceAsync.kt deleted file mode 100644 index 0e6995d..0000000 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CasGeneratorServiceAsync.kt +++ /dev/null @@ -1,37 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.services.async - -import com.cas_parser.api.core.ClientOptions -import java.util.function.Consumer - -interface CasGeneratorServiceAsync { - - /** - * 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): CasGeneratorServiceAsync - - /** - * A view of [CasGeneratorServiceAsync] 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 - ): CasGeneratorServiceAsync.WithRawResponse - } -} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CasGeneratorServiceAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CasGeneratorServiceAsyncImpl.kt deleted file mode 100644 index 0bbd145..0000000 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CasGeneratorServiceAsyncImpl.kt +++ /dev/null @@ -1,30 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.services.async - -import com.cas_parser.api.core.ClientOptions -import java.util.function.Consumer - -class CasGeneratorServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : - CasGeneratorServiceAsync { - - private val withRawResponse: CasGeneratorServiceAsync.WithRawResponse by lazy { - WithRawResponseImpl(clientOptions) - } - - override fun withRawResponse(): CasGeneratorServiceAsync.WithRawResponse = withRawResponse - - override fun withOptions(modifier: Consumer): CasGeneratorServiceAsync = - CasGeneratorServiceAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build()) - - class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : - CasGeneratorServiceAsync.WithRawResponse { - - override fun withOptions( - modifier: Consumer - ): CasGeneratorServiceAsync.WithRawResponse = - CasGeneratorServiceAsyncImpl.WithRawResponseImpl( - clientOptions.toBuilder().apply(modifier::accept).build() - ) - } -} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CasParserServiceAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CasParserServiceAsync.kt deleted file mode 100644 index 319748a..0000000 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CasParserServiceAsync.kt +++ /dev/null @@ -1,230 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.services.async - -import com.cas_parser.api.core.ClientOptions -import com.cas_parser.api.core.RequestOptions -import com.cas_parser.api.core.http.HttpResponseFor -import com.cas_parser.api.models.casparser.CasParserCamsKfintechParams -import com.cas_parser.api.models.casparser.CasParserCdslParams -import com.cas_parser.api.models.casparser.CasParserNsdlParams -import com.cas_parser.api.models.casparser.CasParserSmartParseParams -import com.cas_parser.api.models.casparser.UnifiedResponse -import java.util.concurrent.CompletableFuture -import java.util.function.Consumer - -interface CasParserServiceAsync { - - /** - * 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): CasParserServiceAsync - - /** - * This endpoint specifically parses CAMS/KFintech CAS (Consolidated Account Statement) PDF - * files and returns data in a unified format. Use this endpoint when you know the PDF is from - * CAMS or KFintech. - */ - fun camsKfintech(): CompletableFuture = - camsKfintech(CasParserCamsKfintechParams.none()) - - /** @see camsKfintech */ - fun camsKfintech( - params: CasParserCamsKfintechParams = CasParserCamsKfintechParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture - - /** @see camsKfintech */ - fun camsKfintech( - params: CasParserCamsKfintechParams = CasParserCamsKfintechParams.none() - ): CompletableFuture = camsKfintech(params, RequestOptions.none()) - - /** @see camsKfintech */ - fun camsKfintech(requestOptions: RequestOptions): CompletableFuture = - camsKfintech(CasParserCamsKfintechParams.none(), requestOptions) - - /** - * This endpoint specifically parses CDSL CAS (Consolidated Account Statement) PDF files and - * returns data in a unified format. Use this endpoint when you know the PDF is from CDSL. - */ - fun cdsl(): CompletableFuture = cdsl(CasParserCdslParams.none()) - - /** @see cdsl */ - fun cdsl( - params: CasParserCdslParams = CasParserCdslParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture - - /** @see cdsl */ - fun cdsl( - params: CasParserCdslParams = CasParserCdslParams.none() - ): CompletableFuture = cdsl(params, RequestOptions.none()) - - /** @see cdsl */ - fun cdsl(requestOptions: RequestOptions): CompletableFuture = - cdsl(CasParserCdslParams.none(), requestOptions) - - /** - * This endpoint specifically parses NSDL CAS (Consolidated Account Statement) PDF files and - * returns data in a unified format. Use this endpoint when you know the PDF is from NSDL. - */ - fun nsdl(): CompletableFuture = nsdl(CasParserNsdlParams.none()) - - /** @see nsdl */ - fun nsdl( - params: CasParserNsdlParams = CasParserNsdlParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture - - /** @see nsdl */ - fun nsdl( - params: CasParserNsdlParams = CasParserNsdlParams.none() - ): CompletableFuture = nsdl(params, RequestOptions.none()) - - /** @see nsdl */ - fun nsdl(requestOptions: RequestOptions): CompletableFuture = - nsdl(CasParserNsdlParams.none(), requestOptions) - - /** - * This endpoint parses CAS (Consolidated Account Statement) PDF files from NSDL, CDSL, or - * CAMS/KFintech and returns data in a unified format. It auto-detects the CAS type and - * transforms the data into a consistent structure regardless of the source. - */ - fun smartParse(): CompletableFuture = - smartParse(CasParserSmartParseParams.none()) - - /** @see smartParse */ - fun smartParse( - params: CasParserSmartParseParams = CasParserSmartParseParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture - - /** @see smartParse */ - fun smartParse( - params: CasParserSmartParseParams = CasParserSmartParseParams.none() - ): CompletableFuture = smartParse(params, RequestOptions.none()) - - /** @see smartParse */ - fun smartParse(requestOptions: RequestOptions): CompletableFuture = - smartParse(CasParserSmartParseParams.none(), requestOptions) - - /** - * A view of [CasParserServiceAsync] 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 - ): CasParserServiceAsync.WithRawResponse - - /** - * Returns a raw HTTP response for `post /v4/cams_kfintech/parse`, but is otherwise the same - * as [CasParserServiceAsync.camsKfintech]. - */ - fun camsKfintech(): CompletableFuture> = - camsKfintech(CasParserCamsKfintechParams.none()) - - /** @see camsKfintech */ - fun camsKfintech( - params: CasParserCamsKfintechParams = CasParserCamsKfintechParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture> - - /** @see camsKfintech */ - fun camsKfintech( - params: CasParserCamsKfintechParams = CasParserCamsKfintechParams.none() - ): CompletableFuture> = - camsKfintech(params, RequestOptions.none()) - - /** @see camsKfintech */ - fun camsKfintech( - requestOptions: RequestOptions - ): CompletableFuture> = - camsKfintech(CasParserCamsKfintechParams.none(), requestOptions) - - /** - * Returns a raw HTTP response for `post /v4/cdsl/parse`, but is otherwise the same as - * [CasParserServiceAsync.cdsl]. - */ - fun cdsl(): CompletableFuture> = - cdsl(CasParserCdslParams.none()) - - /** @see cdsl */ - fun cdsl( - params: CasParserCdslParams = CasParserCdslParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture> - - /** @see cdsl */ - fun cdsl( - params: CasParserCdslParams = CasParserCdslParams.none() - ): CompletableFuture> = cdsl(params, RequestOptions.none()) - - /** @see cdsl */ - fun cdsl( - requestOptions: RequestOptions - ): CompletableFuture> = - cdsl(CasParserCdslParams.none(), requestOptions) - - /** - * Returns a raw HTTP response for `post /v4/nsdl/parse`, but is otherwise the same as - * [CasParserServiceAsync.nsdl]. - */ - fun nsdl(): CompletableFuture> = - nsdl(CasParserNsdlParams.none()) - - /** @see nsdl */ - fun nsdl( - params: CasParserNsdlParams = CasParserNsdlParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture> - - /** @see nsdl */ - fun nsdl( - params: CasParserNsdlParams = CasParserNsdlParams.none() - ): CompletableFuture> = nsdl(params, RequestOptions.none()) - - /** @see nsdl */ - fun nsdl( - requestOptions: RequestOptions - ): CompletableFuture> = - nsdl(CasParserNsdlParams.none(), requestOptions) - - /** - * Returns a raw HTTP response for `post /v4/smart/parse`, but is otherwise the same as - * [CasParserServiceAsync.smartParse]. - */ - fun smartParse(): CompletableFuture> = - smartParse(CasParserSmartParseParams.none()) - - /** @see smartParse */ - fun smartParse( - params: CasParserSmartParseParams = CasParserSmartParseParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture> - - /** @see smartParse */ - fun smartParse( - params: CasParserSmartParseParams = CasParserSmartParseParams.none() - ): CompletableFuture> = - smartParse(params, RequestOptions.none()) - - /** @see smartParse */ - fun smartParse( - requestOptions: RequestOptions - ): CompletableFuture> = - smartParse(CasParserSmartParseParams.none(), requestOptions) - } -} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CdslServiceAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CdslServiceAsync.kt new file mode 100644 index 0000000..b00e28d --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CdslServiceAsync.kt @@ -0,0 +1,88 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.models.camskfintech.UnifiedResponse +import com.cas_parser.api.models.cdsl.CdslParsePdfParams +import com.cas_parser.api.services.async.cdsl.FetchServiceAsync +import java.util.concurrent.CompletableFuture +import java.util.function.Consumer + +interface CdslServiceAsync { + + /** + * 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): CdslServiceAsync + + fun fetch(): FetchServiceAsync + + /** + * This endpoint specifically parses CDSL CAS (Consolidated Account Statement) PDF files and + * returns data in a unified format. Use this endpoint when you know the PDF is from CDSL. + */ + fun parsePdf(): CompletableFuture = parsePdf(CdslParsePdfParams.none()) + + /** @see parsePdf */ + fun parsePdf( + params: CdslParsePdfParams = CdslParsePdfParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see parsePdf */ + fun parsePdf( + params: CdslParsePdfParams = CdslParsePdfParams.none() + ): CompletableFuture = parsePdf(params, RequestOptions.none()) + + /** @see parsePdf */ + fun parsePdf(requestOptions: RequestOptions): CompletableFuture = + parsePdf(CdslParsePdfParams.none(), requestOptions) + + /** A view of [CdslServiceAsync] 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): CdslServiceAsync.WithRawResponse + + fun fetch(): FetchServiceAsync.WithRawResponse + + /** + * Returns a raw HTTP response for `post /v4/cdsl/parse`, but is otherwise the same as + * [CdslServiceAsync.parsePdf]. + */ + fun parsePdf(): CompletableFuture> = + parsePdf(CdslParsePdfParams.none()) + + /** @see parsePdf */ + fun parsePdf( + params: CdslParsePdfParams = CdslParsePdfParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see parsePdf */ + fun parsePdf( + params: CdslParsePdfParams = CdslParsePdfParams.none() + ): CompletableFuture> = + parsePdf(params, RequestOptions.none()) + + /** @see parsePdf */ + fun parsePdf( + requestOptions: RequestOptions + ): CompletableFuture> = + parsePdf(CdslParsePdfParams.none(), requestOptions) + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CdslServiceAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CdslServiceAsyncImpl.kt new file mode 100644 index 0000000..2531112 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CdslServiceAsyncImpl.kt @@ -0,0 +1,98 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.handlers.errorBodyHandler +import com.cas_parser.api.core.handlers.errorHandler +import com.cas_parser.api.core.handlers.jsonHandler +import com.cas_parser.api.core.http.HttpMethod +import com.cas_parser.api.core.http.HttpRequest +import com.cas_parser.api.core.http.HttpResponse +import com.cas_parser.api.core.http.HttpResponse.Handler +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.core.http.multipartFormData +import com.cas_parser.api.core.http.parseable +import com.cas_parser.api.core.prepareAsync +import com.cas_parser.api.models.camskfintech.UnifiedResponse +import com.cas_parser.api.models.cdsl.CdslParsePdfParams +import com.cas_parser.api.services.async.cdsl.FetchServiceAsync +import com.cas_parser.api.services.async.cdsl.FetchServiceAsyncImpl +import java.util.concurrent.CompletableFuture +import java.util.function.Consumer + +class CdslServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + CdslServiceAsync { + + private val withRawResponse: CdslServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + private val fetch: FetchServiceAsync by lazy { FetchServiceAsyncImpl(clientOptions) } + + override fun withRawResponse(): CdslServiceAsync.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): CdslServiceAsync = + CdslServiceAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun fetch(): FetchServiceAsync = fetch + + override fun parsePdf( + params: CdslParsePdfParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v4/cdsl/parse + withRawResponse().parsePdf(params, requestOptions).thenApply { it.parse() } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + CdslServiceAsync.WithRawResponse { + + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + + private val fetch: FetchServiceAsync.WithRawResponse by lazy { + FetchServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + override fun withOptions( + modifier: Consumer + ): CdslServiceAsync.WithRawResponse = + CdslServiceAsyncImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + override fun fetch(): FetchServiceAsync.WithRawResponse = fetch + + private val parsePdfHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun parsePdf( + params: CdslParsePdfParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v4", "cdsl", "parse") + .body(multipartFormData(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 { parsePdfHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/ContractNoteServiceAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/ContractNoteServiceAsync.kt new file mode 100644 index 0000000..6168665 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/ContractNoteServiceAsync.kt @@ -0,0 +1,113 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.models.contractnote.ContractNoteParseParams +import com.cas_parser.api.models.contractnote.ContractNoteParseResponse +import java.util.concurrent.CompletableFuture +import java.util.function.Consumer + +interface ContractNoteServiceAsync { + + /** + * 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): ContractNoteServiceAsync + + /** + * This endpoint parses Contract Note PDF files from various brokers including Zerodha, Groww, + * Upstox, ICICI Securities, and others. + * + * **What is a Contract Note?** A contract note is a legal document that provides details of all + * trades executed by an investor. It includes: + * - Trade details with timestamps, quantities, and prices + * - Brokerage and charges breakdown + * - Settlement information + * - Regulatory compliance details + * + * **Supported Brokers:** + * - Zerodha Broking Limited + * - Groww Invest Tech Private Limited + * - Upstox (RKSV Securities) + * - ICICI Securities Limited + * - Auto-detection for unknown brokers + * + * **Key Features:** + * - **Auto-detection**: Automatically identifies broker type from PDF content + * - **Comprehensive parsing**: Extracts equity transactions, derivatives transactions, detailed + * trades, and charges + * - **Flexible input**: Accepts both file upload and URL-based PDF input + * - **Password protection**: Supports password-protected PDFs + * + * The API returns structured data including contract note information, client details, + * transaction summaries, and detailed trade-by-trade breakdowns. + */ + fun parse(): CompletableFuture = + parse(ContractNoteParseParams.none()) + + /** @see parse */ + fun parse( + params: ContractNoteParseParams = ContractNoteParseParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see parse */ + fun parse( + params: ContractNoteParseParams = ContractNoteParseParams.none() + ): CompletableFuture = parse(params, RequestOptions.none()) + + /** @see parse */ + fun parse(requestOptions: RequestOptions): CompletableFuture = + parse(ContractNoteParseParams.none(), requestOptions) + + /** + * A view of [ContractNoteServiceAsync] 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 + ): ContractNoteServiceAsync.WithRawResponse + + /** + * Returns a raw HTTP response for `post /v4/contract_note/parse`, but is otherwise the same + * as [ContractNoteServiceAsync.parse]. + */ + fun parse(): CompletableFuture> = + parse(ContractNoteParseParams.none()) + + /** @see parse */ + fun parse( + params: ContractNoteParseParams = ContractNoteParseParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see parse */ + fun parse( + params: ContractNoteParseParams = ContractNoteParseParams.none() + ): CompletableFuture> = + parse(params, RequestOptions.none()) + + /** @see parse */ + fun parse( + requestOptions: RequestOptions + ): CompletableFuture> = + parse(ContractNoteParseParams.none(), requestOptions) + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/ContractNoteServiceAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/ContractNoteServiceAsyncImpl.kt new file mode 100644 index 0000000..7b8d062 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/ContractNoteServiceAsyncImpl.kt @@ -0,0 +1,86 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.handlers.errorBodyHandler +import com.cas_parser.api.core.handlers.errorHandler +import com.cas_parser.api.core.handlers.jsonHandler +import com.cas_parser.api.core.http.HttpMethod +import com.cas_parser.api.core.http.HttpRequest +import com.cas_parser.api.core.http.HttpResponse +import com.cas_parser.api.core.http.HttpResponse.Handler +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.core.http.multipartFormData +import com.cas_parser.api.core.http.parseable +import com.cas_parser.api.core.prepareAsync +import com.cas_parser.api.models.contractnote.ContractNoteParseParams +import com.cas_parser.api.models.contractnote.ContractNoteParseResponse +import java.util.concurrent.CompletableFuture +import java.util.function.Consumer + +class ContractNoteServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + ContractNoteServiceAsync { + + private val withRawResponse: ContractNoteServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): ContractNoteServiceAsync.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): ContractNoteServiceAsync = + ContractNoteServiceAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun parse( + params: ContractNoteParseParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v4/contract_note/parse + withRawResponse().parse(params, requestOptions).thenApply { it.parse() } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + ContractNoteServiceAsync.WithRawResponse { + + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + + override fun withOptions( + modifier: Consumer + ): ContractNoteServiceAsync.WithRawResponse = + ContractNoteServiceAsyncImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + private val parseHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun parse( + params: ContractNoteParseParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v4", "contract_note", "parse") + .body(multipartFormData(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 { parseHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CreditServiceAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CreditServiceAsync.kt new file mode 100644 index 0000000..05290f8 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CreditServiceAsync.kt @@ -0,0 +1,93 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.models.credits.CreditCheckParams +import com.cas_parser.api.models.credits.CreditCheckResponse +import java.util.concurrent.CompletableFuture +import java.util.function.Consumer + +interface CreditServiceAsync { + + /** + * 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): CreditServiceAsync + + /** + * Check your remaining API credits and usage for the current billing period. + * + * Returns: + * - Number of API calls used and remaining credits + * - Credit limit and reset date + * - List of enabled features for your plan + * + * Credits reset at the start of each billing period. + */ + fun check(): CompletableFuture = check(CreditCheckParams.none()) + + /** @see check */ + fun check( + params: CreditCheckParams = CreditCheckParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see check */ + fun check( + params: CreditCheckParams = CreditCheckParams.none() + ): CompletableFuture = check(params, RequestOptions.none()) + + /** @see check */ + fun check(requestOptions: RequestOptions): CompletableFuture = + check(CreditCheckParams.none(), requestOptions) + + /** + * A view of [CreditServiceAsync] 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 + ): CreditServiceAsync.WithRawResponse + + /** + * Returns a raw HTTP response for `post /credits`, but is otherwise the same as + * [CreditServiceAsync.check]. + */ + fun check(): CompletableFuture> = + check(CreditCheckParams.none()) + + /** @see check */ + fun check( + params: CreditCheckParams = CreditCheckParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see check */ + fun check( + params: CreditCheckParams = CreditCheckParams.none() + ): CompletableFuture> = + check(params, RequestOptions.none()) + + /** @see check */ + fun check( + requestOptions: RequestOptions + ): CompletableFuture> = + check(CreditCheckParams.none(), requestOptions) + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CreditServiceAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CreditServiceAsyncImpl.kt new file mode 100644 index 0000000..6f2806c --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CreditServiceAsyncImpl.kt @@ -0,0 +1,86 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.handlers.errorBodyHandler +import com.cas_parser.api.core.handlers.errorHandler +import com.cas_parser.api.core.handlers.jsonHandler +import com.cas_parser.api.core.http.HttpMethod +import com.cas_parser.api.core.http.HttpRequest +import com.cas_parser.api.core.http.HttpResponse +import com.cas_parser.api.core.http.HttpResponse.Handler +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.core.http.json +import com.cas_parser.api.core.http.parseable +import com.cas_parser.api.core.prepareAsync +import com.cas_parser.api.models.credits.CreditCheckParams +import com.cas_parser.api.models.credits.CreditCheckResponse +import java.util.concurrent.CompletableFuture +import java.util.function.Consumer + +class CreditServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + CreditServiceAsync { + + private val withRawResponse: CreditServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): CreditServiceAsync.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): CreditServiceAsync = + CreditServiceAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun check( + params: CreditCheckParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /credits + withRawResponse().check(params, requestOptions).thenApply { it.parse() } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + CreditServiceAsync.WithRawResponse { + + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + + override fun withOptions( + modifier: Consumer + ): CreditServiceAsync.WithRawResponse = + CreditServiceAsyncImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + private val checkHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun check( + params: CreditCheckParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("credits") + .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 { checkHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/InboxServiceAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/InboxServiceAsync.kt new file mode 100644 index 0000000..b488405 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/InboxServiceAsync.kt @@ -0,0 +1,188 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.models.inbox.InboxCheckConnectionStatusParams +import com.cas_parser.api.models.inbox.InboxCheckConnectionStatusResponse +import com.cas_parser.api.models.inbox.InboxConnectEmailParams +import com.cas_parser.api.models.inbox.InboxConnectEmailResponse +import com.cas_parser.api.models.inbox.InboxDisconnectEmailParams +import com.cas_parser.api.models.inbox.InboxDisconnectEmailResponse +import com.cas_parser.api.models.inbox.InboxListCasFilesParams +import com.cas_parser.api.models.inbox.InboxListCasFilesResponse +import java.util.concurrent.CompletableFuture +import java.util.function.Consumer + +interface InboxServiceAsync { + + /** + * 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): InboxServiceAsync + + /** + * Verify if an `inbox_token` is still valid and check connection status. + * + * Use this to check if the user needs to re-authenticate (e.g., if they revoked access in their + * email provider settings). + */ + fun checkConnectionStatus( + params: InboxCheckConnectionStatusParams + ): CompletableFuture = + checkConnectionStatus(params, RequestOptions.none()) + + /** @see checkConnectionStatus */ + fun checkConnectionStatus( + params: InboxCheckConnectionStatusParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** + * Initiate OAuth flow to connect user's email inbox. + * + * Returns an `oauth_url` that you should redirect the user to. After authorization, they are + * redirected back to your `redirect_uri` with the following query parameters: + * + * **On success:** + * - `inbox_token` - Encrypted token to store client-side + * - `email` - Email address of the connected account + * - `state` - Your original state parameter (for CSRF verification) + * + * **On error:** + * - `error` - Error code (e.g., `access_denied`, `token_exchange_failed`) + * - `state` - Your original state parameter + * + * **Store the `inbox_token` client-side** and use it for all subsequent inbox API calls. + */ + fun connectEmail( + params: InboxConnectEmailParams + ): CompletableFuture = connectEmail(params, RequestOptions.none()) + + /** @see connectEmail */ + fun connectEmail( + params: InboxConnectEmailParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** + * Revoke email access and invalidate the token. + * + * This calls the provider's token revocation API (e.g., Google's revoke endpoint) to ensure the + * user's consent is properly removed. + * + * After calling this, the `inbox_token` becomes unusable. + */ + fun disconnectEmail( + params: InboxDisconnectEmailParams + ): CompletableFuture = + disconnectEmail(params, RequestOptions.none()) + + /** @see disconnectEmail */ + fun disconnectEmail( + params: InboxDisconnectEmailParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** + * Search the user's email inbox for CAS files from known senders (CAMS, KFintech, CDSL, NSDL). + * + * Files are uploaded to temporary cloud storage. **URLs expire in 24 hours.** + * + * Optionally filter by CAS provider and date range. + * + * **Billing:** 0.2 credits per request (charged regardless of success or number of files + * found). + */ + fun listCasFiles( + params: InboxListCasFilesParams + ): CompletableFuture = listCasFiles(params, RequestOptions.none()) + + /** @see listCasFiles */ + fun listCasFiles( + params: InboxListCasFilesParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** A view of [InboxServiceAsync] 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 + ): InboxServiceAsync.WithRawResponse + + /** + * Returns a raw HTTP response for `post /v4/inbox/status`, but is otherwise the same as + * [InboxServiceAsync.checkConnectionStatus]. + */ + fun checkConnectionStatus( + params: InboxCheckConnectionStatusParams + ): CompletableFuture> = + checkConnectionStatus(params, RequestOptions.none()) + + /** @see checkConnectionStatus */ + fun checkConnectionStatus( + params: InboxCheckConnectionStatusParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `post /v4/inbox/connect`, but is otherwise the same as + * [InboxServiceAsync.connectEmail]. + */ + fun connectEmail( + params: InboxConnectEmailParams + ): CompletableFuture> = + connectEmail(params, RequestOptions.none()) + + /** @see connectEmail */ + fun connectEmail( + params: InboxConnectEmailParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `post /v4/inbox/disconnect`, but is otherwise the same as + * [InboxServiceAsync.disconnectEmail]. + */ + fun disconnectEmail( + params: InboxDisconnectEmailParams + ): CompletableFuture> = + disconnectEmail(params, RequestOptions.none()) + + /** @see disconnectEmail */ + fun disconnectEmail( + params: InboxDisconnectEmailParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `post /v4/inbox/cas`, but is otherwise the same as + * [InboxServiceAsync.listCasFiles]. + */ + fun listCasFiles( + params: InboxListCasFilesParams + ): CompletableFuture> = + listCasFiles(params, RequestOptions.none()) + + /** @see listCasFiles */ + fun listCasFiles( + params: InboxListCasFilesParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CasParserServiceAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/InboxServiceAsyncImpl.kt similarity index 54% rename from cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CasParserServiceAsyncImpl.kt rename to cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/InboxServiceAsyncImpl.kt index 747e8ed..29c7d03 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CasParserServiceAsyncImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/InboxServiceAsyncImpl.kt @@ -12,83 +12,86 @@ import com.cas_parser.api.core.http.HttpRequest import com.cas_parser.api.core.http.HttpResponse import com.cas_parser.api.core.http.HttpResponse.Handler import com.cas_parser.api.core.http.HttpResponseFor -import com.cas_parser.api.core.http.multipartFormData +import com.cas_parser.api.core.http.json import com.cas_parser.api.core.http.parseable import com.cas_parser.api.core.prepareAsync -import com.cas_parser.api.models.casparser.CasParserCamsKfintechParams -import com.cas_parser.api.models.casparser.CasParserCdslParams -import com.cas_parser.api.models.casparser.CasParserNsdlParams -import com.cas_parser.api.models.casparser.CasParserSmartParseParams -import com.cas_parser.api.models.casparser.UnifiedResponse +import com.cas_parser.api.models.inbox.InboxCheckConnectionStatusParams +import com.cas_parser.api.models.inbox.InboxCheckConnectionStatusResponse +import com.cas_parser.api.models.inbox.InboxConnectEmailParams +import com.cas_parser.api.models.inbox.InboxConnectEmailResponse +import com.cas_parser.api.models.inbox.InboxDisconnectEmailParams +import com.cas_parser.api.models.inbox.InboxDisconnectEmailResponse +import com.cas_parser.api.models.inbox.InboxListCasFilesParams +import com.cas_parser.api.models.inbox.InboxListCasFilesResponse import java.util.concurrent.CompletableFuture import java.util.function.Consumer -class CasParserServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : - CasParserServiceAsync { +class InboxServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + InboxServiceAsync { - private val withRawResponse: CasParserServiceAsync.WithRawResponse by lazy { + private val withRawResponse: InboxServiceAsync.WithRawResponse by lazy { WithRawResponseImpl(clientOptions) } - override fun withRawResponse(): CasParserServiceAsync.WithRawResponse = withRawResponse + override fun withRawResponse(): InboxServiceAsync.WithRawResponse = withRawResponse - override fun withOptions(modifier: Consumer): CasParserServiceAsync = - CasParserServiceAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + override fun withOptions(modifier: Consumer): InboxServiceAsync = + InboxServiceAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build()) - override fun camsKfintech( - params: CasParserCamsKfintechParams, + override fun checkConnectionStatus( + params: InboxCheckConnectionStatusParams, requestOptions: RequestOptions, - ): CompletableFuture = - // post /v4/cams_kfintech/parse - withRawResponse().camsKfintech(params, requestOptions).thenApply { it.parse() } + ): CompletableFuture = + // post /v4/inbox/status + withRawResponse().checkConnectionStatus(params, requestOptions).thenApply { it.parse() } - override fun cdsl( - params: CasParserCdslParams, + override fun connectEmail( + params: InboxConnectEmailParams, requestOptions: RequestOptions, - ): CompletableFuture = - // post /v4/cdsl/parse - withRawResponse().cdsl(params, requestOptions).thenApply { it.parse() } + ): CompletableFuture = + // post /v4/inbox/connect + withRawResponse().connectEmail(params, requestOptions).thenApply { it.parse() } - override fun nsdl( - params: CasParserNsdlParams, + override fun disconnectEmail( + params: InboxDisconnectEmailParams, requestOptions: RequestOptions, - ): CompletableFuture = - // post /v4/nsdl/parse - withRawResponse().nsdl(params, requestOptions).thenApply { it.parse() } + ): CompletableFuture = + // post /v4/inbox/disconnect + withRawResponse().disconnectEmail(params, requestOptions).thenApply { it.parse() } - override fun smartParse( - params: CasParserSmartParseParams, + override fun listCasFiles( + params: InboxListCasFilesParams, requestOptions: RequestOptions, - ): CompletableFuture = - // post /v4/smart/parse - withRawResponse().smartParse(params, requestOptions).thenApply { it.parse() } + ): CompletableFuture = + // post /v4/inbox/cas + withRawResponse().listCasFiles(params, requestOptions).thenApply { it.parse() } class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : - CasParserServiceAsync.WithRawResponse { + InboxServiceAsync.WithRawResponse { private val errorHandler: Handler = errorHandler(errorBodyHandler(clientOptions.jsonMapper)) override fun withOptions( modifier: Consumer - ): CasParserServiceAsync.WithRawResponse = - CasParserServiceAsyncImpl.WithRawResponseImpl( + ): InboxServiceAsync.WithRawResponse = + InboxServiceAsyncImpl.WithRawResponseImpl( clientOptions.toBuilder().apply(modifier::accept).build() ) - private val camsKfintechHandler: Handler = - jsonHandler(clientOptions.jsonMapper) + private val checkConnectionStatusHandler: Handler = + jsonHandler(clientOptions.jsonMapper) - override fun camsKfintech( - params: CasParserCamsKfintechParams, + override fun checkConnectionStatus( + params: InboxCheckConnectionStatusParams, requestOptions: RequestOptions, - ): CompletableFuture> { + ): CompletableFuture> { val request = HttpRequest.builder() .method(HttpMethod.POST) .baseUrl(clientOptions.baseUrl()) - .addPathSegments("v4", "cams_kfintech", "parse") - .body(multipartFormData(clientOptions.jsonMapper, params._body())) + .addPathSegments("v4", "inbox", "status") + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } .build() .prepareAsync(clientOptions, params) val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) @@ -97,7 +100,7 @@ class CasParserServiceAsyncImpl internal constructor(private val clientOptions: .thenApply { response -> errorHandler.handle(response).parseable { response - .use { camsKfintechHandler.handle(it) } + .use { checkConnectionStatusHandler.handle(it) } .also { if (requestOptions.responseValidation!!) { it.validate() @@ -107,19 +110,19 @@ class CasParserServiceAsyncImpl internal constructor(private val clientOptions: } } - private val cdslHandler: Handler = - jsonHandler(clientOptions.jsonMapper) + private val connectEmailHandler: Handler = + jsonHandler(clientOptions.jsonMapper) - override fun cdsl( - params: CasParserCdslParams, + override fun connectEmail( + params: InboxConnectEmailParams, requestOptions: RequestOptions, - ): CompletableFuture> { + ): CompletableFuture> { val request = HttpRequest.builder() .method(HttpMethod.POST) .baseUrl(clientOptions.baseUrl()) - .addPathSegments("v4", "cdsl", "parse") - .body(multipartFormData(clientOptions.jsonMapper, params._body())) + .addPathSegments("v4", "inbox", "connect") + .body(json(clientOptions.jsonMapper, params._body())) .build() .prepareAsync(clientOptions, params) val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) @@ -128,7 +131,7 @@ class CasParserServiceAsyncImpl internal constructor(private val clientOptions: .thenApply { response -> errorHandler.handle(response).parseable { response - .use { cdslHandler.handle(it) } + .use { connectEmailHandler.handle(it) } .also { if (requestOptions.responseValidation!!) { it.validate() @@ -138,19 +141,19 @@ class CasParserServiceAsyncImpl internal constructor(private val clientOptions: } } - private val nsdlHandler: Handler = - jsonHandler(clientOptions.jsonMapper) + private val disconnectEmailHandler: Handler = + jsonHandler(clientOptions.jsonMapper) - override fun nsdl( - params: CasParserNsdlParams, + override fun disconnectEmail( + params: InboxDisconnectEmailParams, requestOptions: RequestOptions, - ): CompletableFuture> { + ): CompletableFuture> { val request = HttpRequest.builder() .method(HttpMethod.POST) .baseUrl(clientOptions.baseUrl()) - .addPathSegments("v4", "nsdl", "parse") - .body(multipartFormData(clientOptions.jsonMapper, params._body())) + .addPathSegments("v4", "inbox", "disconnect") + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } .build() .prepareAsync(clientOptions, params) val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) @@ -159,7 +162,7 @@ class CasParserServiceAsyncImpl internal constructor(private val clientOptions: .thenApply { response -> errorHandler.handle(response).parseable { response - .use { nsdlHandler.handle(it) } + .use { disconnectEmailHandler.handle(it) } .also { if (requestOptions.responseValidation!!) { it.validate() @@ -169,19 +172,19 @@ class CasParserServiceAsyncImpl internal constructor(private val clientOptions: } } - private val smartParseHandler: Handler = - jsonHandler(clientOptions.jsonMapper) + private val listCasFilesHandler: Handler = + jsonHandler(clientOptions.jsonMapper) - override fun smartParse( - params: CasParserSmartParseParams, + override fun listCasFiles( + params: InboxListCasFilesParams, requestOptions: RequestOptions, - ): CompletableFuture> { + ): CompletableFuture> { val request = HttpRequest.builder() .method(HttpMethod.POST) .baseUrl(clientOptions.baseUrl()) - .addPathSegments("v4", "smart", "parse") - .body(multipartFormData(clientOptions.jsonMapper, params._body())) + .addPathSegments("v4", "inbox", "cas") + .body(json(clientOptions.jsonMapper, params._body())) .build() .prepareAsync(clientOptions, params) val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) @@ -190,7 +193,7 @@ class CasParserServiceAsyncImpl internal constructor(private val clientOptions: .thenApply { response -> errorHandler.handle(response).parseable { response - .use { smartParseHandler.handle(it) } + .use { listCasFilesHandler.handle(it) } .also { if (requestOptions.responseValidation!!) { it.validate() diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/KfintechServiceAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/KfintechServiceAsync.kt new file mode 100644 index 0000000..fa22355 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/KfintechServiceAsync.kt @@ -0,0 +1,72 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.models.kfintech.KfintechGenerateCasParams +import com.cas_parser.api.models.kfintech.KfintechGenerateCasResponse +import java.util.concurrent.CompletableFuture +import java.util.function.Consumer + +interface KfintechServiceAsync { + + /** + * 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): KfintechServiceAsync + + /** + * Generate CAS via KFintech mailback. The CAS PDF will be sent to the investor's email. + * + * This is an async operation - the investor receives the CAS via email within a few minutes. + * For instant CAS retrieval, use CDSL Fetch (`/v4/cdsl/fetch`). + */ + fun generateCas( + params: KfintechGenerateCasParams + ): CompletableFuture = generateCas(params, RequestOptions.none()) + + /** @see generateCas */ + fun generateCas( + params: KfintechGenerateCasParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** + * A view of [KfintechServiceAsync] 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 + ): KfintechServiceAsync.WithRawResponse + + /** + * Returns a raw HTTP response for `post /v4/kfintech/generate`, but is otherwise the same + * as [KfintechServiceAsync.generateCas]. + */ + fun generateCas( + params: KfintechGenerateCasParams + ): CompletableFuture> = + generateCas(params, RequestOptions.none()) + + /** @see generateCas */ + fun generateCas( + params: KfintechGenerateCasParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/KfintechServiceAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/KfintechServiceAsyncImpl.kt new file mode 100644 index 0000000..2445261 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/KfintechServiceAsyncImpl.kt @@ -0,0 +1,86 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.handlers.errorBodyHandler +import com.cas_parser.api.core.handlers.errorHandler +import com.cas_parser.api.core.handlers.jsonHandler +import com.cas_parser.api.core.http.HttpMethod +import com.cas_parser.api.core.http.HttpRequest +import com.cas_parser.api.core.http.HttpResponse +import com.cas_parser.api.core.http.HttpResponse.Handler +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.core.http.json +import com.cas_parser.api.core.http.parseable +import com.cas_parser.api.core.prepareAsync +import com.cas_parser.api.models.kfintech.KfintechGenerateCasParams +import com.cas_parser.api.models.kfintech.KfintechGenerateCasResponse +import java.util.concurrent.CompletableFuture +import java.util.function.Consumer + +class KfintechServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + KfintechServiceAsync { + + private val withRawResponse: KfintechServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): KfintechServiceAsync.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): KfintechServiceAsync = + KfintechServiceAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun generateCas( + params: KfintechGenerateCasParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v4/kfintech/generate + withRawResponse().generateCas(params, requestOptions).thenApply { it.parse() } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + KfintechServiceAsync.WithRawResponse { + + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + + override fun withOptions( + modifier: Consumer + ): KfintechServiceAsync.WithRawResponse = + KfintechServiceAsyncImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + private val generateCasHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun generateCas( + params: KfintechGenerateCasParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v4", "kfintech", "generate") + .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 { generateCasHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/LogServiceAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/LogServiceAsync.kt new file mode 100644 index 0000000..641ee6a --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/LogServiceAsync.kt @@ -0,0 +1,135 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.models.logs.LogCreateParams +import com.cas_parser.api.models.logs.LogCreateResponse +import com.cas_parser.api.models.logs.LogGetSummaryParams +import com.cas_parser.api.models.logs.LogGetSummaryResponse +import java.util.concurrent.CompletableFuture +import java.util.function.Consumer + +interface LogServiceAsync { + + /** + * 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): LogServiceAsync + + /** + * Retrieve detailed API usage logs for your account. + * + * Returns a list of API calls with timestamps, features used, status codes, and credits + * consumed. Useful for monitoring usage patterns and debugging. + */ + fun create(): CompletableFuture = create(LogCreateParams.none()) + + /** @see create */ + fun create( + params: LogCreateParams = LogCreateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see create */ + fun create( + params: LogCreateParams = LogCreateParams.none() + ): CompletableFuture = create(params, RequestOptions.none()) + + /** @see create */ + fun create(requestOptions: RequestOptions): CompletableFuture = + create(LogCreateParams.none(), requestOptions) + + /** + * Get aggregated usage statistics grouped by feature. + * + * Useful for understanding which API features are being used most and tracking usage trends. + */ + fun getSummary(): CompletableFuture = + getSummary(LogGetSummaryParams.none()) + + /** @see getSummary */ + fun getSummary( + params: LogGetSummaryParams = LogGetSummaryParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see getSummary */ + fun getSummary( + params: LogGetSummaryParams = LogGetSummaryParams.none() + ): CompletableFuture = getSummary(params, RequestOptions.none()) + + /** @see getSummary */ + fun getSummary(requestOptions: RequestOptions): CompletableFuture = + getSummary(LogGetSummaryParams.none(), requestOptions) + + /** A view of [LogServiceAsync] 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): LogServiceAsync.WithRawResponse + + /** + * Returns a raw HTTP response for `post /logs`, but is otherwise the same as + * [LogServiceAsync.create]. + */ + fun create(): CompletableFuture> = + create(LogCreateParams.none()) + + /** @see create */ + fun create( + params: LogCreateParams = LogCreateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see create */ + fun create( + params: LogCreateParams = LogCreateParams.none() + ): CompletableFuture> = + create(params, RequestOptions.none()) + + /** @see create */ + fun create( + requestOptions: RequestOptions + ): CompletableFuture> = + create(LogCreateParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `post /logs/summary`, but is otherwise the same as + * [LogServiceAsync.getSummary]. + */ + fun getSummary(): CompletableFuture> = + getSummary(LogGetSummaryParams.none()) + + /** @see getSummary */ + fun getSummary( + params: LogGetSummaryParams = LogGetSummaryParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see getSummary */ + fun getSummary( + params: LogGetSummaryParams = LogGetSummaryParams.none() + ): CompletableFuture> = + getSummary(params, RequestOptions.none()) + + /** @see getSummary */ + fun getSummary( + requestOptions: RequestOptions + ): CompletableFuture> = + getSummary(LogGetSummaryParams.none(), requestOptions) + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/LogServiceAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/LogServiceAsyncImpl.kt new file mode 100644 index 0000000..1dd0192 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/LogServiceAsyncImpl.kt @@ -0,0 +1,126 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.handlers.errorBodyHandler +import com.cas_parser.api.core.handlers.errorHandler +import com.cas_parser.api.core.handlers.jsonHandler +import com.cas_parser.api.core.http.HttpMethod +import com.cas_parser.api.core.http.HttpRequest +import com.cas_parser.api.core.http.HttpResponse +import com.cas_parser.api.core.http.HttpResponse.Handler +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.core.http.json +import com.cas_parser.api.core.http.parseable +import com.cas_parser.api.core.prepareAsync +import com.cas_parser.api.models.logs.LogCreateParams +import com.cas_parser.api.models.logs.LogCreateResponse +import com.cas_parser.api.models.logs.LogGetSummaryParams +import com.cas_parser.api.models.logs.LogGetSummaryResponse +import java.util.concurrent.CompletableFuture +import java.util.function.Consumer + +class LogServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + LogServiceAsync { + + private val withRawResponse: LogServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): LogServiceAsync.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): LogServiceAsync = + LogServiceAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun create( + params: LogCreateParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /logs + withRawResponse().create(params, requestOptions).thenApply { it.parse() } + + override fun getSummary( + params: LogGetSummaryParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /logs/summary + withRawResponse().getSummary(params, requestOptions).thenApply { it.parse() } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + LogServiceAsync.WithRawResponse { + + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + + override fun withOptions( + modifier: Consumer + ): LogServiceAsync.WithRawResponse = + LogServiceAsyncImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun create( + params: LogCreateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("logs") + .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 { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + + private val getSummaryHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun getSummary( + params: LogGetSummaryParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("logs", "summary") + .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 { getSummaryHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/NsdlServiceAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/NsdlServiceAsync.kt new file mode 100644 index 0000000..d9571cb --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/NsdlServiceAsync.kt @@ -0,0 +1,83 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.models.camskfintech.UnifiedResponse +import com.cas_parser.api.models.nsdl.NsdlParseParams +import java.util.concurrent.CompletableFuture +import java.util.function.Consumer + +interface NsdlServiceAsync { + + /** + * 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): NsdlServiceAsync + + /** + * This endpoint specifically parses NSDL CAS (Consolidated Account Statement) PDF files and + * returns data in a unified format. Use this endpoint when you know the PDF is from NSDL. + */ + fun parse(): CompletableFuture = parse(NsdlParseParams.none()) + + /** @see parse */ + fun parse( + params: NsdlParseParams = NsdlParseParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see parse */ + fun parse( + params: NsdlParseParams = NsdlParseParams.none() + ): CompletableFuture = parse(params, RequestOptions.none()) + + /** @see parse */ + fun parse(requestOptions: RequestOptions): CompletableFuture = + parse(NsdlParseParams.none(), requestOptions) + + /** A view of [NsdlServiceAsync] 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): NsdlServiceAsync.WithRawResponse + + /** + * Returns a raw HTTP response for `post /v4/nsdl/parse`, but is otherwise the same as + * [NsdlServiceAsync.parse]. + */ + fun parse(): CompletableFuture> = + parse(NsdlParseParams.none()) + + /** @see parse */ + fun parse( + params: NsdlParseParams = NsdlParseParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see parse */ + fun parse( + params: NsdlParseParams = NsdlParseParams.none() + ): CompletableFuture> = + parse(params, RequestOptions.none()) + + /** @see parse */ + fun parse( + requestOptions: RequestOptions + ): CompletableFuture> = + parse(NsdlParseParams.none(), requestOptions) + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/NsdlServiceAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/NsdlServiceAsyncImpl.kt new file mode 100644 index 0000000..8fd0b0c --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/NsdlServiceAsyncImpl.kt @@ -0,0 +1,86 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.handlers.errorBodyHandler +import com.cas_parser.api.core.handlers.errorHandler +import com.cas_parser.api.core.handlers.jsonHandler +import com.cas_parser.api.core.http.HttpMethod +import com.cas_parser.api.core.http.HttpRequest +import com.cas_parser.api.core.http.HttpResponse +import com.cas_parser.api.core.http.HttpResponse.Handler +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.core.http.multipartFormData +import com.cas_parser.api.core.http.parseable +import com.cas_parser.api.core.prepareAsync +import com.cas_parser.api.models.camskfintech.UnifiedResponse +import com.cas_parser.api.models.nsdl.NsdlParseParams +import java.util.concurrent.CompletableFuture +import java.util.function.Consumer + +class NsdlServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + NsdlServiceAsync { + + private val withRawResponse: NsdlServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): NsdlServiceAsync.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): NsdlServiceAsync = + NsdlServiceAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun parse( + params: NsdlParseParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v4/nsdl/parse + withRawResponse().parse(params, requestOptions).thenApply { it.parse() } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + NsdlServiceAsync.WithRawResponse { + + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + + override fun withOptions( + modifier: Consumer + ): NsdlServiceAsync.WithRawResponse = + NsdlServiceAsyncImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + private val parseHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun parse( + params: NsdlParseParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v4", "nsdl", "parse") + .body(multipartFormData(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 { parseHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/SmartServiceAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/SmartServiceAsync.kt new file mode 100644 index 0000000..9fb8951 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/SmartServiceAsync.kt @@ -0,0 +1,87 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.models.camskfintech.UnifiedResponse +import com.cas_parser.api.models.smart.SmartParseCasPdfParams +import java.util.concurrent.CompletableFuture +import java.util.function.Consumer + +interface SmartServiceAsync { + + /** + * 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): SmartServiceAsync + + /** + * This endpoint parses CAS (Consolidated Account Statement) PDF files from NSDL, CDSL, or + * CAMS/KFintech and returns data in a unified format. It auto-detects the CAS type and + * transforms the data into a consistent structure regardless of the source. + */ + fun parseCasPdf(): CompletableFuture = + parseCasPdf(SmartParseCasPdfParams.none()) + + /** @see parseCasPdf */ + fun parseCasPdf( + params: SmartParseCasPdfParams = SmartParseCasPdfParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see parseCasPdf */ + fun parseCasPdf( + params: SmartParseCasPdfParams = SmartParseCasPdfParams.none() + ): CompletableFuture = parseCasPdf(params, RequestOptions.none()) + + /** @see parseCasPdf */ + fun parseCasPdf(requestOptions: RequestOptions): CompletableFuture = + parseCasPdf(SmartParseCasPdfParams.none(), requestOptions) + + /** A view of [SmartServiceAsync] 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 + ): SmartServiceAsync.WithRawResponse + + /** + * Returns a raw HTTP response for `post /v4/smart/parse`, but is otherwise the same as + * [SmartServiceAsync.parseCasPdf]. + */ + fun parseCasPdf(): CompletableFuture> = + parseCasPdf(SmartParseCasPdfParams.none()) + + /** @see parseCasPdf */ + fun parseCasPdf( + params: SmartParseCasPdfParams = SmartParseCasPdfParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see parseCasPdf */ + fun parseCasPdf( + params: SmartParseCasPdfParams = SmartParseCasPdfParams.none() + ): CompletableFuture> = + parseCasPdf(params, RequestOptions.none()) + + /** @see parseCasPdf */ + fun parseCasPdf( + requestOptions: RequestOptions + ): CompletableFuture> = + parseCasPdf(SmartParseCasPdfParams.none(), requestOptions) + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/SmartServiceAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/SmartServiceAsyncImpl.kt new file mode 100644 index 0000000..618e4fc --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/SmartServiceAsyncImpl.kt @@ -0,0 +1,86 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.handlers.errorBodyHandler +import com.cas_parser.api.core.handlers.errorHandler +import com.cas_parser.api.core.handlers.jsonHandler +import com.cas_parser.api.core.http.HttpMethod +import com.cas_parser.api.core.http.HttpRequest +import com.cas_parser.api.core.http.HttpResponse +import com.cas_parser.api.core.http.HttpResponse.Handler +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.core.http.multipartFormData +import com.cas_parser.api.core.http.parseable +import com.cas_parser.api.core.prepareAsync +import com.cas_parser.api.models.camskfintech.UnifiedResponse +import com.cas_parser.api.models.smart.SmartParseCasPdfParams +import java.util.concurrent.CompletableFuture +import java.util.function.Consumer + +class SmartServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + SmartServiceAsync { + + private val withRawResponse: SmartServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): SmartServiceAsync.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): SmartServiceAsync = + SmartServiceAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun parseCasPdf( + params: SmartParseCasPdfParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v4/smart/parse + withRawResponse().parseCasPdf(params, requestOptions).thenApply { it.parse() } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + SmartServiceAsync.WithRawResponse { + + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + + override fun withOptions( + modifier: Consumer + ): SmartServiceAsync.WithRawResponse = + SmartServiceAsyncImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + private val parseCasPdfHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun parseCasPdf( + params: SmartParseCasPdfParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v4", "smart", "parse") + .body(multipartFormData(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 { parseCasPdfHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsync.kt new file mode 100644 index 0000000..2a7125e --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsync.kt @@ -0,0 +1,86 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.models.verifytoken.VerifyTokenVerifyParams +import com.cas_parser.api.models.verifytoken.VerifyTokenVerifyResponse +import java.util.concurrent.CompletableFuture +import java.util.function.Consumer + +interface VerifyTokenServiceAsync { + + /** + * 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): VerifyTokenServiceAsync + + /** Verify an access token and check if it's still valid. Useful for debugging token issues. */ + fun verify(): CompletableFuture = + verify(VerifyTokenVerifyParams.none()) + + /** @see verify */ + fun verify( + params: VerifyTokenVerifyParams = VerifyTokenVerifyParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see verify */ + fun verify( + params: VerifyTokenVerifyParams = VerifyTokenVerifyParams.none() + ): CompletableFuture = verify(params, RequestOptions.none()) + + /** @see verify */ + fun verify(requestOptions: RequestOptions): CompletableFuture = + verify(VerifyTokenVerifyParams.none(), requestOptions) + + /** + * A view of [VerifyTokenServiceAsync] 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 + ): VerifyTokenServiceAsync.WithRawResponse + + /** + * Returns a raw HTTP response for `post /v1/verify-token`, but is otherwise the same as + * [VerifyTokenServiceAsync.verify]. + */ + fun verify(): CompletableFuture> = + verify(VerifyTokenVerifyParams.none()) + + /** @see verify */ + fun verify( + params: VerifyTokenVerifyParams = VerifyTokenVerifyParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see verify */ + fun verify( + params: VerifyTokenVerifyParams = VerifyTokenVerifyParams.none() + ): CompletableFuture> = + verify(params, RequestOptions.none()) + + /** @see verify */ + fun verify( + requestOptions: RequestOptions + ): CompletableFuture> = + verify(VerifyTokenVerifyParams.none(), requestOptions) + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsyncImpl.kt new file mode 100644 index 0000000..ba12f1b --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsyncImpl.kt @@ -0,0 +1,86 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.handlers.errorBodyHandler +import com.cas_parser.api.core.handlers.errorHandler +import com.cas_parser.api.core.handlers.jsonHandler +import com.cas_parser.api.core.http.HttpMethod +import com.cas_parser.api.core.http.HttpRequest +import com.cas_parser.api.core.http.HttpResponse +import com.cas_parser.api.core.http.HttpResponse.Handler +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.core.http.json +import com.cas_parser.api.core.http.parseable +import com.cas_parser.api.core.prepareAsync +import com.cas_parser.api.models.verifytoken.VerifyTokenVerifyParams +import com.cas_parser.api.models.verifytoken.VerifyTokenVerifyResponse +import java.util.concurrent.CompletableFuture +import java.util.function.Consumer + +class VerifyTokenServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + VerifyTokenServiceAsync { + + private val withRawResponse: VerifyTokenServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): VerifyTokenServiceAsync.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): VerifyTokenServiceAsync = + VerifyTokenServiceAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun verify( + params: VerifyTokenVerifyParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v1/verify-token + withRawResponse().verify(params, requestOptions).thenApply { it.parse() } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + VerifyTokenServiceAsync.WithRawResponse { + + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + + override fun withOptions( + modifier: Consumer + ): VerifyTokenServiceAsync.WithRawResponse = + VerifyTokenServiceAsyncImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + private val verifyHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun verify( + params: VerifyTokenVerifyParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v1", "verify-token") + .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 { verifyHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/cdsl/FetchServiceAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/cdsl/FetchServiceAsync.kt new file mode 100644 index 0000000..83b8d52 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/cdsl/FetchServiceAsync.kt @@ -0,0 +1,135 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async.cdsl + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.models.cdsl.fetch.FetchRequestOtpParams +import com.cas_parser.api.models.cdsl.fetch.FetchRequestOtpResponse +import com.cas_parser.api.models.cdsl.fetch.FetchVerifyOtpParams +import com.cas_parser.api.models.cdsl.fetch.FetchVerifyOtpResponse +import java.util.concurrent.CompletableFuture +import java.util.function.Consumer + +interface FetchServiceAsync { + + /** + * 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): FetchServiceAsync + + /** + * **Step 1 of 2**: Request OTP for CDSL CAS fetch. + * + * This endpoint: + * 1. Solves reCAPTCHA automatically (~15-20 seconds) + * 2. Submits login credentials to CDSL portal + * 3. Triggers OTP to user's registered mobile number + * + * After user receives OTP, call `/v4/cdsl/fetch/{session_id}/verify` to complete. + */ + fun requestOtp(params: FetchRequestOtpParams): CompletableFuture = + requestOtp(params, RequestOptions.none()) + + /** @see requestOtp */ + fun requestOtp( + params: FetchRequestOtpParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** + * **Step 2 of 2**: Verify OTP and retrieve CDSL CAS files. + * + * After successful verification, CAS PDFs are fetched from CDSL portal, uploaded to cloud + * storage, and returned as direct download URLs. + */ + fun verifyOtp( + sessionId: String, + params: FetchVerifyOtpParams, + ): CompletableFuture = + verifyOtp(sessionId, params, RequestOptions.none()) + + /** @see verifyOtp */ + fun verifyOtp( + sessionId: String, + params: FetchVerifyOtpParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + verifyOtp(params.toBuilder().sessionId(sessionId).build(), requestOptions) + + /** @see verifyOtp */ + fun verifyOtp(params: FetchVerifyOtpParams): CompletableFuture = + verifyOtp(params, RequestOptions.none()) + + /** @see verifyOtp */ + fun verifyOtp( + params: FetchVerifyOtpParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** A view of [FetchServiceAsync] 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 + ): FetchServiceAsync.WithRawResponse + + /** + * Returns a raw HTTP response for `post /v4/cdsl/fetch`, but is otherwise the same as + * [FetchServiceAsync.requestOtp]. + */ + fun requestOtp( + params: FetchRequestOtpParams + ): CompletableFuture> = + requestOtp(params, RequestOptions.none()) + + /** @see requestOtp */ + fun requestOtp( + params: FetchRequestOtpParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `post /v4/cdsl/fetch/{session_id}/verify`, but is + * otherwise the same as [FetchServiceAsync.verifyOtp]. + */ + fun verifyOtp( + sessionId: String, + params: FetchVerifyOtpParams, + ): CompletableFuture> = + verifyOtp(sessionId, params, RequestOptions.none()) + + /** @see verifyOtp */ + fun verifyOtp( + sessionId: String, + params: FetchVerifyOtpParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + verifyOtp(params.toBuilder().sessionId(sessionId).build(), requestOptions) + + /** @see verifyOtp */ + fun verifyOtp( + params: FetchVerifyOtpParams + ): CompletableFuture> = + verifyOtp(params, RequestOptions.none()) + + /** @see verifyOtp */ + fun verifyOtp( + params: FetchVerifyOtpParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/cdsl/FetchServiceAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/cdsl/FetchServiceAsyncImpl.kt new file mode 100644 index 0000000..fb97ea9 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/cdsl/FetchServiceAsyncImpl.kt @@ -0,0 +1,131 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async.cdsl + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.checkRequired +import com.cas_parser.api.core.handlers.errorBodyHandler +import com.cas_parser.api.core.handlers.errorHandler +import com.cas_parser.api.core.handlers.jsonHandler +import com.cas_parser.api.core.http.HttpMethod +import com.cas_parser.api.core.http.HttpRequest +import com.cas_parser.api.core.http.HttpResponse +import com.cas_parser.api.core.http.HttpResponse.Handler +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.core.http.json +import com.cas_parser.api.core.http.parseable +import com.cas_parser.api.core.prepareAsync +import com.cas_parser.api.models.cdsl.fetch.FetchRequestOtpParams +import com.cas_parser.api.models.cdsl.fetch.FetchRequestOtpResponse +import com.cas_parser.api.models.cdsl.fetch.FetchVerifyOtpParams +import com.cas_parser.api.models.cdsl.fetch.FetchVerifyOtpResponse +import java.util.concurrent.CompletableFuture +import java.util.function.Consumer +import kotlin.jvm.optionals.getOrNull + +class FetchServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + FetchServiceAsync { + + private val withRawResponse: FetchServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): FetchServiceAsync.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): FetchServiceAsync = + FetchServiceAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun requestOtp( + params: FetchRequestOtpParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v4/cdsl/fetch + withRawResponse().requestOtp(params, requestOptions).thenApply { it.parse() } + + override fun verifyOtp( + params: FetchVerifyOtpParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v4/cdsl/fetch/{session_id}/verify + withRawResponse().verifyOtp(params, requestOptions).thenApply { it.parse() } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + FetchServiceAsync.WithRawResponse { + + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + + override fun withOptions( + modifier: Consumer + ): FetchServiceAsync.WithRawResponse = + FetchServiceAsyncImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + private val requestOtpHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun requestOtp( + params: FetchRequestOtpParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v4", "cdsl", "fetch") + .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 { requestOtpHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + + private val verifyOtpHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun verifyOtp( + params: FetchVerifyOtpParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("sessionId", params.sessionId().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v4", "cdsl", "fetch", params._pathParam(0), "verify") + .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 { verifyOtpHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/AccessTokenService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/AccessTokenService.kt new file mode 100644 index 0000000..3414d2a --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/AccessTokenService.kt @@ -0,0 +1,96 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.models.accesstoken.AccessTokenCreateParams +import com.cas_parser.api.models.accesstoken.AccessTokenCreateResponse +import com.google.errorprone.annotations.MustBeClosed +import java.util.function.Consumer + +interface AccessTokenService { + + /** + * 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): AccessTokenService + + /** + * Generate a short-lived access token from your API key. + * + * **Use this endpoint from your backend** to create tokens that can be safely passed to + * frontend/SDK. + * + * Access tokens: + * - Are prefixed with `at_` for easy identification + * - Valid for up to 60 minutes + * - Can be used in place of API keys on all v4 endpoints + * - Cannot be used to generate other access tokens + */ + fun create(): AccessTokenCreateResponse = create(AccessTokenCreateParams.none()) + + /** @see create */ + fun create( + params: AccessTokenCreateParams = AccessTokenCreateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): AccessTokenCreateResponse + + /** @see create */ + fun create( + params: AccessTokenCreateParams = AccessTokenCreateParams.none() + ): AccessTokenCreateResponse = create(params, RequestOptions.none()) + + /** @see create */ + fun create(requestOptions: RequestOptions): AccessTokenCreateResponse = + create(AccessTokenCreateParams.none(), requestOptions) + + /** + * A view of [AccessTokenService] 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 + ): AccessTokenService.WithRawResponse + + /** + * Returns a raw HTTP response for `post /v1/access-token`, but is otherwise the same as + * [AccessTokenService.create]. + */ + @MustBeClosed + fun create(): HttpResponseFor = + create(AccessTokenCreateParams.none()) + + /** @see create */ + @MustBeClosed + fun create( + params: AccessTokenCreateParams = AccessTokenCreateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see create */ + @MustBeClosed + fun create( + params: AccessTokenCreateParams = AccessTokenCreateParams.none() + ): HttpResponseFor = create(params, RequestOptions.none()) + + /** @see create */ + @MustBeClosed + fun create(requestOptions: RequestOptions): HttpResponseFor = + create(AccessTokenCreateParams.none(), requestOptions) + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/AccessTokenServiceImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/AccessTokenServiceImpl.kt new file mode 100644 index 0000000..9906e2d --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/AccessTokenServiceImpl.kt @@ -0,0 +1,82 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.handlers.errorBodyHandler +import com.cas_parser.api.core.handlers.errorHandler +import com.cas_parser.api.core.handlers.jsonHandler +import com.cas_parser.api.core.http.HttpMethod +import com.cas_parser.api.core.http.HttpRequest +import com.cas_parser.api.core.http.HttpResponse +import com.cas_parser.api.core.http.HttpResponse.Handler +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.core.http.json +import com.cas_parser.api.core.http.parseable +import com.cas_parser.api.core.prepare +import com.cas_parser.api.models.accesstoken.AccessTokenCreateParams +import com.cas_parser.api.models.accesstoken.AccessTokenCreateResponse +import java.util.function.Consumer + +class AccessTokenServiceImpl internal constructor(private val clientOptions: ClientOptions) : + AccessTokenService { + + private val withRawResponse: AccessTokenService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): AccessTokenService.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): AccessTokenService = + AccessTokenServiceImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun create( + params: AccessTokenCreateParams, + requestOptions: RequestOptions, + ): AccessTokenCreateResponse = + // post /v1/access-token + withRawResponse().create(params, requestOptions).parse() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + AccessTokenService.WithRawResponse { + + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + + override fun withOptions( + modifier: Consumer + ): AccessTokenService.WithRawResponse = + AccessTokenServiceImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun create( + params: AccessTokenCreateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v1", "access-token") + .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 { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CamsKfintechService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CamsKfintechService.kt new file mode 100644 index 0000000..294210c --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CamsKfintechService.kt @@ -0,0 +1,87 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.models.camskfintech.CamsKfintechParseParams +import com.cas_parser.api.models.camskfintech.UnifiedResponse +import com.google.errorprone.annotations.MustBeClosed +import java.util.function.Consumer + +interface CamsKfintechService { + + /** + * 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): CamsKfintechService + + /** + * This endpoint specifically parses CAMS/KFintech CAS (Consolidated Account Statement) PDF + * files and returns data in a unified format. Use this endpoint when you know the PDF is from + * CAMS or KFintech. + */ + fun parse(): UnifiedResponse = parse(CamsKfintechParseParams.none()) + + /** @see parse */ + fun parse( + params: CamsKfintechParseParams = CamsKfintechParseParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): UnifiedResponse + + /** @see parse */ + fun parse(params: CamsKfintechParseParams = CamsKfintechParseParams.none()): UnifiedResponse = + parse(params, RequestOptions.none()) + + /** @see parse */ + fun parse(requestOptions: RequestOptions): UnifiedResponse = + parse(CamsKfintechParseParams.none(), requestOptions) + + /** + * A view of [CamsKfintechService] 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 + ): CamsKfintechService.WithRawResponse + + /** + * Returns a raw HTTP response for `post /v4/cams_kfintech/parse`, but is otherwise the same + * as [CamsKfintechService.parse]. + */ + @MustBeClosed + fun parse(): HttpResponseFor = parse(CamsKfintechParseParams.none()) + + /** @see parse */ + @MustBeClosed + fun parse( + params: CamsKfintechParseParams = CamsKfintechParseParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see parse */ + @MustBeClosed + fun parse( + params: CamsKfintechParseParams = CamsKfintechParseParams.none() + ): HttpResponseFor = parse(params, RequestOptions.none()) + + /** @see parse */ + @MustBeClosed + fun parse(requestOptions: RequestOptions): HttpResponseFor = + parse(CamsKfintechParseParams.none(), requestOptions) + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CamsKfintechServiceImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CamsKfintechServiceImpl.kt new file mode 100644 index 0000000..867c1c6 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CamsKfintechServiceImpl.kt @@ -0,0 +1,82 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.handlers.errorBodyHandler +import com.cas_parser.api.core.handlers.errorHandler +import com.cas_parser.api.core.handlers.jsonHandler +import com.cas_parser.api.core.http.HttpMethod +import com.cas_parser.api.core.http.HttpRequest +import com.cas_parser.api.core.http.HttpResponse +import com.cas_parser.api.core.http.HttpResponse.Handler +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.core.http.multipartFormData +import com.cas_parser.api.core.http.parseable +import com.cas_parser.api.core.prepare +import com.cas_parser.api.models.camskfintech.CamsKfintechParseParams +import com.cas_parser.api.models.camskfintech.UnifiedResponse +import java.util.function.Consumer + +class CamsKfintechServiceImpl internal constructor(private val clientOptions: ClientOptions) : + CamsKfintechService { + + private val withRawResponse: CamsKfintechService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): CamsKfintechService.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): CamsKfintechService = + CamsKfintechServiceImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun parse( + params: CamsKfintechParseParams, + requestOptions: RequestOptions, + ): UnifiedResponse = + // post /v4/cams_kfintech/parse + withRawResponse().parse(params, requestOptions).parse() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + CamsKfintechService.WithRawResponse { + + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + + override fun withOptions( + modifier: Consumer + ): CamsKfintechService.WithRawResponse = + CamsKfintechServiceImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + private val parseHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun parse( + params: CamsKfintechParseParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v4", "cams_kfintech", "parse") + .body(multipartFormData(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 { parseHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CasGeneratorService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CasGeneratorService.kt deleted file mode 100644 index f0ad062..0000000 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CasGeneratorService.kt +++ /dev/null @@ -1,36 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.services.blocking - -import com.cas_parser.api.core.ClientOptions -import java.util.function.Consumer - -interface CasGeneratorService { - - /** - * 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): CasGeneratorService - - /** - * A view of [CasGeneratorService] 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 - ): CasGeneratorService.WithRawResponse - } -} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CasGeneratorServiceImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CasGeneratorServiceImpl.kt deleted file mode 100644 index 1d0054b..0000000 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CasGeneratorServiceImpl.kt +++ /dev/null @@ -1,30 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.services.blocking - -import com.cas_parser.api.core.ClientOptions -import java.util.function.Consumer - -class CasGeneratorServiceImpl internal constructor(private val clientOptions: ClientOptions) : - CasGeneratorService { - - private val withRawResponse: CasGeneratorService.WithRawResponse by lazy { - WithRawResponseImpl(clientOptions) - } - - override fun withRawResponse(): CasGeneratorService.WithRawResponse = withRawResponse - - override fun withOptions(modifier: Consumer): CasGeneratorService = - CasGeneratorServiceImpl(clientOptions.toBuilder().apply(modifier::accept).build()) - - class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : - CasGeneratorService.WithRawResponse { - - override fun withOptions( - modifier: Consumer - ): CasGeneratorService.WithRawResponse = - CasGeneratorServiceImpl.WithRawResponseImpl( - clientOptions.toBuilder().apply(modifier::accept).build() - ) - } -} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CasParserService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CasParserService.kt deleted file mode 100644 index f526f80..0000000 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CasParserService.kt +++ /dev/null @@ -1,226 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.services.blocking - -import com.cas_parser.api.core.ClientOptions -import com.cas_parser.api.core.RequestOptions -import com.cas_parser.api.core.http.HttpResponseFor -import com.cas_parser.api.models.casparser.CasParserCamsKfintechParams -import com.cas_parser.api.models.casparser.CasParserCdslParams -import com.cas_parser.api.models.casparser.CasParserNsdlParams -import com.cas_parser.api.models.casparser.CasParserSmartParseParams -import com.cas_parser.api.models.casparser.UnifiedResponse -import com.google.errorprone.annotations.MustBeClosed -import java.util.function.Consumer - -interface CasParserService { - - /** - * 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): CasParserService - - /** - * This endpoint specifically parses CAMS/KFintech CAS (Consolidated Account Statement) PDF - * files and returns data in a unified format. Use this endpoint when you know the PDF is from - * CAMS or KFintech. - */ - fun camsKfintech(): UnifiedResponse = camsKfintech(CasParserCamsKfintechParams.none()) - - /** @see camsKfintech */ - fun camsKfintech( - params: CasParserCamsKfintechParams = CasParserCamsKfintechParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): UnifiedResponse - - /** @see camsKfintech */ - fun camsKfintech( - params: CasParserCamsKfintechParams = CasParserCamsKfintechParams.none() - ): UnifiedResponse = camsKfintech(params, RequestOptions.none()) - - /** @see camsKfintech */ - fun camsKfintech(requestOptions: RequestOptions): UnifiedResponse = - camsKfintech(CasParserCamsKfintechParams.none(), requestOptions) - - /** - * This endpoint specifically parses CDSL CAS (Consolidated Account Statement) PDF files and - * returns data in a unified format. Use this endpoint when you know the PDF is from CDSL. - */ - fun cdsl(): UnifiedResponse = cdsl(CasParserCdslParams.none()) - - /** @see cdsl */ - fun cdsl( - params: CasParserCdslParams = CasParserCdslParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): UnifiedResponse - - /** @see cdsl */ - fun cdsl(params: CasParserCdslParams = CasParserCdslParams.none()): UnifiedResponse = - cdsl(params, RequestOptions.none()) - - /** @see cdsl */ - fun cdsl(requestOptions: RequestOptions): UnifiedResponse = - cdsl(CasParserCdslParams.none(), requestOptions) - - /** - * This endpoint specifically parses NSDL CAS (Consolidated Account Statement) PDF files and - * returns data in a unified format. Use this endpoint when you know the PDF is from NSDL. - */ - fun nsdl(): UnifiedResponse = nsdl(CasParserNsdlParams.none()) - - /** @see nsdl */ - fun nsdl( - params: CasParserNsdlParams = CasParserNsdlParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): UnifiedResponse - - /** @see nsdl */ - fun nsdl(params: CasParserNsdlParams = CasParserNsdlParams.none()): UnifiedResponse = - nsdl(params, RequestOptions.none()) - - /** @see nsdl */ - fun nsdl(requestOptions: RequestOptions): UnifiedResponse = - nsdl(CasParserNsdlParams.none(), requestOptions) - - /** - * This endpoint parses CAS (Consolidated Account Statement) PDF files from NSDL, CDSL, or - * CAMS/KFintech and returns data in a unified format. It auto-detects the CAS type and - * transforms the data into a consistent structure regardless of the source. - */ - fun smartParse(): UnifiedResponse = smartParse(CasParserSmartParseParams.none()) - - /** @see smartParse */ - fun smartParse( - params: CasParserSmartParseParams = CasParserSmartParseParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): UnifiedResponse - - /** @see smartParse */ - fun smartParse( - params: CasParserSmartParseParams = CasParserSmartParseParams.none() - ): UnifiedResponse = smartParse(params, RequestOptions.none()) - - /** @see smartParse */ - fun smartParse(requestOptions: RequestOptions): UnifiedResponse = - smartParse(CasParserSmartParseParams.none(), requestOptions) - - /** A view of [CasParserService] 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): CasParserService.WithRawResponse - - /** - * Returns a raw HTTP response for `post /v4/cams_kfintech/parse`, but is otherwise the same - * as [CasParserService.camsKfintech]. - */ - @MustBeClosed - fun camsKfintech(): HttpResponseFor = - camsKfintech(CasParserCamsKfintechParams.none()) - - /** @see camsKfintech */ - @MustBeClosed - fun camsKfintech( - params: CasParserCamsKfintechParams = CasParserCamsKfintechParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): HttpResponseFor - - /** @see camsKfintech */ - @MustBeClosed - fun camsKfintech( - params: CasParserCamsKfintechParams = CasParserCamsKfintechParams.none() - ): HttpResponseFor = camsKfintech(params, RequestOptions.none()) - - /** @see camsKfintech */ - @MustBeClosed - fun camsKfintech(requestOptions: RequestOptions): HttpResponseFor = - camsKfintech(CasParserCamsKfintechParams.none(), requestOptions) - - /** - * Returns a raw HTTP response for `post /v4/cdsl/parse`, but is otherwise the same as - * [CasParserService.cdsl]. - */ - @MustBeClosed - fun cdsl(): HttpResponseFor = cdsl(CasParserCdslParams.none()) - - /** @see cdsl */ - @MustBeClosed - fun cdsl( - params: CasParserCdslParams = CasParserCdslParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): HttpResponseFor - - /** @see cdsl */ - @MustBeClosed - fun cdsl( - params: CasParserCdslParams = CasParserCdslParams.none() - ): HttpResponseFor = cdsl(params, RequestOptions.none()) - - /** @see cdsl */ - @MustBeClosed - fun cdsl(requestOptions: RequestOptions): HttpResponseFor = - cdsl(CasParserCdslParams.none(), requestOptions) - - /** - * Returns a raw HTTP response for `post /v4/nsdl/parse`, but is otherwise the same as - * [CasParserService.nsdl]. - */ - @MustBeClosed - fun nsdl(): HttpResponseFor = nsdl(CasParserNsdlParams.none()) - - /** @see nsdl */ - @MustBeClosed - fun nsdl( - params: CasParserNsdlParams = CasParserNsdlParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): HttpResponseFor - - /** @see nsdl */ - @MustBeClosed - fun nsdl( - params: CasParserNsdlParams = CasParserNsdlParams.none() - ): HttpResponseFor = nsdl(params, RequestOptions.none()) - - /** @see nsdl */ - @MustBeClosed - fun nsdl(requestOptions: RequestOptions): HttpResponseFor = - nsdl(CasParserNsdlParams.none(), requestOptions) - - /** - * Returns a raw HTTP response for `post /v4/smart/parse`, but is otherwise the same as - * [CasParserService.smartParse]. - */ - @MustBeClosed - fun smartParse(): HttpResponseFor = - smartParse(CasParserSmartParseParams.none()) - - /** @see smartParse */ - @MustBeClosed - fun smartParse( - params: CasParserSmartParseParams = CasParserSmartParseParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): HttpResponseFor - - /** @see smartParse */ - @MustBeClosed - fun smartParse( - params: CasParserSmartParseParams = CasParserSmartParseParams.none() - ): HttpResponseFor = smartParse(params, RequestOptions.none()) - - /** @see smartParse */ - @MustBeClosed - fun smartParse(requestOptions: RequestOptions): HttpResponseFor = - smartParse(CasParserSmartParseParams.none(), requestOptions) - } -} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CdslService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CdslService.kt new file mode 100644 index 0000000..a8241be --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CdslService.kt @@ -0,0 +1,87 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.models.camskfintech.UnifiedResponse +import com.cas_parser.api.models.cdsl.CdslParsePdfParams +import com.cas_parser.api.services.blocking.cdsl.FetchService +import com.google.errorprone.annotations.MustBeClosed +import java.util.function.Consumer + +interface CdslService { + + /** + * 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): CdslService + + fun fetch(): FetchService + + /** + * This endpoint specifically parses CDSL CAS (Consolidated Account Statement) PDF files and + * returns data in a unified format. Use this endpoint when you know the PDF is from CDSL. + */ + fun parsePdf(): UnifiedResponse = parsePdf(CdslParsePdfParams.none()) + + /** @see parsePdf */ + fun parsePdf( + params: CdslParsePdfParams = CdslParsePdfParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): UnifiedResponse + + /** @see parsePdf */ + fun parsePdf(params: CdslParsePdfParams = CdslParsePdfParams.none()): UnifiedResponse = + parsePdf(params, RequestOptions.none()) + + /** @see parsePdf */ + fun parsePdf(requestOptions: RequestOptions): UnifiedResponse = + parsePdf(CdslParsePdfParams.none(), requestOptions) + + /** A view of [CdslService] 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): CdslService.WithRawResponse + + fun fetch(): FetchService.WithRawResponse + + /** + * Returns a raw HTTP response for `post /v4/cdsl/parse`, but is otherwise the same as + * [CdslService.parsePdf]. + */ + @MustBeClosed + fun parsePdf(): HttpResponseFor = parsePdf(CdslParsePdfParams.none()) + + /** @see parsePdf */ + @MustBeClosed + fun parsePdf( + params: CdslParsePdfParams = CdslParsePdfParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see parsePdf */ + @MustBeClosed + fun parsePdf( + params: CdslParsePdfParams = CdslParsePdfParams.none() + ): HttpResponseFor = parsePdf(params, RequestOptions.none()) + + /** @see parsePdf */ + @MustBeClosed + fun parsePdf(requestOptions: RequestOptions): HttpResponseFor = + parsePdf(CdslParsePdfParams.none(), requestOptions) + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CdslServiceImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CdslServiceImpl.kt new file mode 100644 index 0000000..0155aa6 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CdslServiceImpl.kt @@ -0,0 +1,93 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.handlers.errorBodyHandler +import com.cas_parser.api.core.handlers.errorHandler +import com.cas_parser.api.core.handlers.jsonHandler +import com.cas_parser.api.core.http.HttpMethod +import com.cas_parser.api.core.http.HttpRequest +import com.cas_parser.api.core.http.HttpResponse +import com.cas_parser.api.core.http.HttpResponse.Handler +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.core.http.multipartFormData +import com.cas_parser.api.core.http.parseable +import com.cas_parser.api.core.prepare +import com.cas_parser.api.models.camskfintech.UnifiedResponse +import com.cas_parser.api.models.cdsl.CdslParsePdfParams +import com.cas_parser.api.services.blocking.cdsl.FetchService +import com.cas_parser.api.services.blocking.cdsl.FetchServiceImpl +import java.util.function.Consumer + +class CdslServiceImpl internal constructor(private val clientOptions: ClientOptions) : CdslService { + + private val withRawResponse: CdslService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + private val fetch: FetchService by lazy { FetchServiceImpl(clientOptions) } + + override fun withRawResponse(): CdslService.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): CdslService = + CdslServiceImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun fetch(): FetchService = fetch + + override fun parsePdf( + params: CdslParsePdfParams, + requestOptions: RequestOptions, + ): UnifiedResponse = + // post /v4/cdsl/parse + withRawResponse().parsePdf(params, requestOptions).parse() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + CdslService.WithRawResponse { + + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + + private val fetch: FetchService.WithRawResponse by lazy { + FetchServiceImpl.WithRawResponseImpl(clientOptions) + } + + override fun withOptions( + modifier: Consumer + ): CdslService.WithRawResponse = + CdslServiceImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + override fun fetch(): FetchService.WithRawResponse = fetch + + private val parsePdfHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun parsePdf( + params: CdslParsePdfParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v4", "cdsl", "parse") + .body(multipartFormData(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 { parsePdfHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/ContractNoteService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/ContractNoteService.kt new file mode 100644 index 0000000..d7a1b64 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/ContractNoteService.kt @@ -0,0 +1,112 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.models.contractnote.ContractNoteParseParams +import com.cas_parser.api.models.contractnote.ContractNoteParseResponse +import com.google.errorprone.annotations.MustBeClosed +import java.util.function.Consumer + +interface ContractNoteService { + + /** + * 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): ContractNoteService + + /** + * This endpoint parses Contract Note PDF files from various brokers including Zerodha, Groww, + * Upstox, ICICI Securities, and others. + * + * **What is a Contract Note?** A contract note is a legal document that provides details of all + * trades executed by an investor. It includes: + * - Trade details with timestamps, quantities, and prices + * - Brokerage and charges breakdown + * - Settlement information + * - Regulatory compliance details + * + * **Supported Brokers:** + * - Zerodha Broking Limited + * - Groww Invest Tech Private Limited + * - Upstox (RKSV Securities) + * - ICICI Securities Limited + * - Auto-detection for unknown brokers + * + * **Key Features:** + * - **Auto-detection**: Automatically identifies broker type from PDF content + * - **Comprehensive parsing**: Extracts equity transactions, derivatives transactions, detailed + * trades, and charges + * - **Flexible input**: Accepts both file upload and URL-based PDF input + * - **Password protection**: Supports password-protected PDFs + * + * The API returns structured data including contract note information, client details, + * transaction summaries, and detailed trade-by-trade breakdowns. + */ + fun parse(): ContractNoteParseResponse = parse(ContractNoteParseParams.none()) + + /** @see parse */ + fun parse( + params: ContractNoteParseParams = ContractNoteParseParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): ContractNoteParseResponse + + /** @see parse */ + fun parse( + params: ContractNoteParseParams = ContractNoteParseParams.none() + ): ContractNoteParseResponse = parse(params, RequestOptions.none()) + + /** @see parse */ + fun parse(requestOptions: RequestOptions): ContractNoteParseResponse = + parse(ContractNoteParseParams.none(), requestOptions) + + /** + * A view of [ContractNoteService] 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 + ): ContractNoteService.WithRawResponse + + /** + * Returns a raw HTTP response for `post /v4/contract_note/parse`, but is otherwise the same + * as [ContractNoteService.parse]. + */ + @MustBeClosed + fun parse(): HttpResponseFor = + parse(ContractNoteParseParams.none()) + + /** @see parse */ + @MustBeClosed + fun parse( + params: ContractNoteParseParams = ContractNoteParseParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see parse */ + @MustBeClosed + fun parse( + params: ContractNoteParseParams = ContractNoteParseParams.none() + ): HttpResponseFor = parse(params, RequestOptions.none()) + + /** @see parse */ + @MustBeClosed + fun parse(requestOptions: RequestOptions): HttpResponseFor = + parse(ContractNoteParseParams.none(), requestOptions) + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/ContractNoteServiceImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/ContractNoteServiceImpl.kt new file mode 100644 index 0000000..978c42b --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/ContractNoteServiceImpl.kt @@ -0,0 +1,82 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.handlers.errorBodyHandler +import com.cas_parser.api.core.handlers.errorHandler +import com.cas_parser.api.core.handlers.jsonHandler +import com.cas_parser.api.core.http.HttpMethod +import com.cas_parser.api.core.http.HttpRequest +import com.cas_parser.api.core.http.HttpResponse +import com.cas_parser.api.core.http.HttpResponse.Handler +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.core.http.multipartFormData +import com.cas_parser.api.core.http.parseable +import com.cas_parser.api.core.prepare +import com.cas_parser.api.models.contractnote.ContractNoteParseParams +import com.cas_parser.api.models.contractnote.ContractNoteParseResponse +import java.util.function.Consumer + +class ContractNoteServiceImpl internal constructor(private val clientOptions: ClientOptions) : + ContractNoteService { + + private val withRawResponse: ContractNoteService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): ContractNoteService.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): ContractNoteService = + ContractNoteServiceImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun parse( + params: ContractNoteParseParams, + requestOptions: RequestOptions, + ): ContractNoteParseResponse = + // post /v4/contract_note/parse + withRawResponse().parse(params, requestOptions).parse() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + ContractNoteService.WithRawResponse { + + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + + override fun withOptions( + modifier: Consumer + ): ContractNoteService.WithRawResponse = + ContractNoteServiceImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + private val parseHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun parse( + params: ContractNoteParseParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v4", "contract_note", "parse") + .body(multipartFormData(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 { parseHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CreditService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CreditService.kt new file mode 100644 index 0000000..5d22d46 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CreditService.kt @@ -0,0 +1,88 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.models.credits.CreditCheckParams +import com.cas_parser.api.models.credits.CreditCheckResponse +import com.google.errorprone.annotations.MustBeClosed +import java.util.function.Consumer + +interface CreditService { + + /** + * 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): CreditService + + /** + * Check your remaining API credits and usage for the current billing period. + * + * Returns: + * - Number of API calls used and remaining credits + * - Credit limit and reset date + * - List of enabled features for your plan + * + * Credits reset at the start of each billing period. + */ + fun check(): CreditCheckResponse = check(CreditCheckParams.none()) + + /** @see check */ + fun check( + params: CreditCheckParams = CreditCheckParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CreditCheckResponse + + /** @see check */ + fun check(params: CreditCheckParams = CreditCheckParams.none()): CreditCheckResponse = + check(params, RequestOptions.none()) + + /** @see check */ + fun check(requestOptions: RequestOptions): CreditCheckResponse = + check(CreditCheckParams.none(), requestOptions) + + /** A view of [CreditService] 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): CreditService.WithRawResponse + + /** + * Returns a raw HTTP response for `post /credits`, but is otherwise the same as + * [CreditService.check]. + */ + @MustBeClosed + fun check(): HttpResponseFor = check(CreditCheckParams.none()) + + /** @see check */ + @MustBeClosed + fun check( + params: CreditCheckParams = CreditCheckParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see check */ + @MustBeClosed + fun check( + params: CreditCheckParams = CreditCheckParams.none() + ): HttpResponseFor = check(params, RequestOptions.none()) + + /** @see check */ + @MustBeClosed + fun check(requestOptions: RequestOptions): HttpResponseFor = + check(CreditCheckParams.none(), requestOptions) + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CreditServiceImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CreditServiceImpl.kt new file mode 100644 index 0000000..549e113 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CreditServiceImpl.kt @@ -0,0 +1,82 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.handlers.errorBodyHandler +import com.cas_parser.api.core.handlers.errorHandler +import com.cas_parser.api.core.handlers.jsonHandler +import com.cas_parser.api.core.http.HttpMethod +import com.cas_parser.api.core.http.HttpRequest +import com.cas_parser.api.core.http.HttpResponse +import com.cas_parser.api.core.http.HttpResponse.Handler +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.core.http.json +import com.cas_parser.api.core.http.parseable +import com.cas_parser.api.core.prepare +import com.cas_parser.api.models.credits.CreditCheckParams +import com.cas_parser.api.models.credits.CreditCheckResponse +import java.util.function.Consumer + +class CreditServiceImpl internal constructor(private val clientOptions: ClientOptions) : + CreditService { + + private val withRawResponse: CreditService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): CreditService.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): CreditService = + CreditServiceImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun check( + params: CreditCheckParams, + requestOptions: RequestOptions, + ): CreditCheckResponse = + // post /credits + withRawResponse().check(params, requestOptions).parse() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + CreditService.WithRawResponse { + + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + + override fun withOptions( + modifier: Consumer + ): CreditService.WithRawResponse = + CreditServiceImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + private val checkHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun check( + params: CreditCheckParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("credits") + .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 { checkHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/InboxService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/InboxService.kt new file mode 100644 index 0000000..e2b5ce0 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/InboxService.kt @@ -0,0 +1,187 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.models.inbox.InboxCheckConnectionStatusParams +import com.cas_parser.api.models.inbox.InboxCheckConnectionStatusResponse +import com.cas_parser.api.models.inbox.InboxConnectEmailParams +import com.cas_parser.api.models.inbox.InboxConnectEmailResponse +import com.cas_parser.api.models.inbox.InboxDisconnectEmailParams +import com.cas_parser.api.models.inbox.InboxDisconnectEmailResponse +import com.cas_parser.api.models.inbox.InboxListCasFilesParams +import com.cas_parser.api.models.inbox.InboxListCasFilesResponse +import com.google.errorprone.annotations.MustBeClosed +import java.util.function.Consumer + +interface InboxService { + + /** + * 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): InboxService + + /** + * Verify if an `inbox_token` is still valid and check connection status. + * + * Use this to check if the user needs to re-authenticate (e.g., if they revoked access in their + * email provider settings). + */ + fun checkConnectionStatus( + params: InboxCheckConnectionStatusParams + ): InboxCheckConnectionStatusResponse = checkConnectionStatus(params, RequestOptions.none()) + + /** @see checkConnectionStatus */ + fun checkConnectionStatus( + params: InboxCheckConnectionStatusParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): InboxCheckConnectionStatusResponse + + /** + * Initiate OAuth flow to connect user's email inbox. + * + * Returns an `oauth_url` that you should redirect the user to. After authorization, they are + * redirected back to your `redirect_uri` with the following query parameters: + * + * **On success:** + * - `inbox_token` - Encrypted token to store client-side + * - `email` - Email address of the connected account + * - `state` - Your original state parameter (for CSRF verification) + * + * **On error:** + * - `error` - Error code (e.g., `access_denied`, `token_exchange_failed`) + * - `state` - Your original state parameter + * + * **Store the `inbox_token` client-side** and use it for all subsequent inbox API calls. + */ + fun connectEmail(params: InboxConnectEmailParams): InboxConnectEmailResponse = + connectEmail(params, RequestOptions.none()) + + /** @see connectEmail */ + fun connectEmail( + params: InboxConnectEmailParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): InboxConnectEmailResponse + + /** + * Revoke email access and invalidate the token. + * + * This calls the provider's token revocation API (e.g., Google's revoke endpoint) to ensure the + * user's consent is properly removed. + * + * After calling this, the `inbox_token` becomes unusable. + */ + fun disconnectEmail(params: InboxDisconnectEmailParams): InboxDisconnectEmailResponse = + disconnectEmail(params, RequestOptions.none()) + + /** @see disconnectEmail */ + fun disconnectEmail( + params: InboxDisconnectEmailParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): InboxDisconnectEmailResponse + + /** + * Search the user's email inbox for CAS files from known senders (CAMS, KFintech, CDSL, NSDL). + * + * Files are uploaded to temporary cloud storage. **URLs expire in 24 hours.** + * + * Optionally filter by CAS provider and date range. + * + * **Billing:** 0.2 credits per request (charged regardless of success or number of files + * found). + */ + fun listCasFiles(params: InboxListCasFilesParams): InboxListCasFilesResponse = + listCasFiles(params, RequestOptions.none()) + + /** @see listCasFiles */ + fun listCasFiles( + params: InboxListCasFilesParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): InboxListCasFilesResponse + + /** A view of [InboxService] 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): InboxService.WithRawResponse + + /** + * Returns a raw HTTP response for `post /v4/inbox/status`, but is otherwise the same as + * [InboxService.checkConnectionStatus]. + */ + @MustBeClosed + fun checkConnectionStatus( + params: InboxCheckConnectionStatusParams + ): HttpResponseFor = + checkConnectionStatus(params, RequestOptions.none()) + + /** @see checkConnectionStatus */ + @MustBeClosed + fun checkConnectionStatus( + params: InboxCheckConnectionStatusParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `post /v4/inbox/connect`, but is otherwise the same as + * [InboxService.connectEmail]. + */ + @MustBeClosed + fun connectEmail( + params: InboxConnectEmailParams + ): HttpResponseFor = connectEmail(params, RequestOptions.none()) + + /** @see connectEmail */ + @MustBeClosed + fun connectEmail( + params: InboxConnectEmailParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `post /v4/inbox/disconnect`, but is otherwise the same as + * [InboxService.disconnectEmail]. + */ + @MustBeClosed + fun disconnectEmail( + params: InboxDisconnectEmailParams + ): HttpResponseFor = + disconnectEmail(params, RequestOptions.none()) + + /** @see disconnectEmail */ + @MustBeClosed + fun disconnectEmail( + params: InboxDisconnectEmailParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `post /v4/inbox/cas`, but is otherwise the same as + * [InboxService.listCasFiles]. + */ + @MustBeClosed + fun listCasFiles( + params: InboxListCasFilesParams + ): HttpResponseFor = listCasFiles(params, RequestOptions.none()) + + /** @see listCasFiles */ + @MustBeClosed + fun listCasFiles( + params: InboxListCasFilesParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CasParserServiceImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/InboxServiceImpl.kt similarity index 52% rename from cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CasParserServiceImpl.kt rename to cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/InboxServiceImpl.kt index 8826c88..27ebb03 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CasParserServiceImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/InboxServiceImpl.kt @@ -12,89 +12,92 @@ import com.cas_parser.api.core.http.HttpRequest import com.cas_parser.api.core.http.HttpResponse import com.cas_parser.api.core.http.HttpResponse.Handler import com.cas_parser.api.core.http.HttpResponseFor -import com.cas_parser.api.core.http.multipartFormData +import com.cas_parser.api.core.http.json import com.cas_parser.api.core.http.parseable import com.cas_parser.api.core.prepare -import com.cas_parser.api.models.casparser.CasParserCamsKfintechParams -import com.cas_parser.api.models.casparser.CasParserCdslParams -import com.cas_parser.api.models.casparser.CasParserNsdlParams -import com.cas_parser.api.models.casparser.CasParserSmartParseParams -import com.cas_parser.api.models.casparser.UnifiedResponse +import com.cas_parser.api.models.inbox.InboxCheckConnectionStatusParams +import com.cas_parser.api.models.inbox.InboxCheckConnectionStatusResponse +import com.cas_parser.api.models.inbox.InboxConnectEmailParams +import com.cas_parser.api.models.inbox.InboxConnectEmailResponse +import com.cas_parser.api.models.inbox.InboxDisconnectEmailParams +import com.cas_parser.api.models.inbox.InboxDisconnectEmailResponse +import com.cas_parser.api.models.inbox.InboxListCasFilesParams +import com.cas_parser.api.models.inbox.InboxListCasFilesResponse import java.util.function.Consumer -class CasParserServiceImpl internal constructor(private val clientOptions: ClientOptions) : - CasParserService { +class InboxServiceImpl internal constructor(private val clientOptions: ClientOptions) : + InboxService { - private val withRawResponse: CasParserService.WithRawResponse by lazy { + private val withRawResponse: InboxService.WithRawResponse by lazy { WithRawResponseImpl(clientOptions) } - override fun withRawResponse(): CasParserService.WithRawResponse = withRawResponse + override fun withRawResponse(): InboxService.WithRawResponse = withRawResponse - override fun withOptions(modifier: Consumer): CasParserService = - CasParserServiceImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + override fun withOptions(modifier: Consumer): InboxService = + InboxServiceImpl(clientOptions.toBuilder().apply(modifier::accept).build()) - override fun camsKfintech( - params: CasParserCamsKfintechParams, + override fun checkConnectionStatus( + params: InboxCheckConnectionStatusParams, requestOptions: RequestOptions, - ): UnifiedResponse = - // post /v4/cams_kfintech/parse - withRawResponse().camsKfintech(params, requestOptions).parse() + ): InboxCheckConnectionStatusResponse = + // post /v4/inbox/status + withRawResponse().checkConnectionStatus(params, requestOptions).parse() - override fun cdsl( - params: CasParserCdslParams, + override fun connectEmail( + params: InboxConnectEmailParams, requestOptions: RequestOptions, - ): UnifiedResponse = - // post /v4/cdsl/parse - withRawResponse().cdsl(params, requestOptions).parse() + ): InboxConnectEmailResponse = + // post /v4/inbox/connect + withRawResponse().connectEmail(params, requestOptions).parse() - override fun nsdl( - params: CasParserNsdlParams, + override fun disconnectEmail( + params: InboxDisconnectEmailParams, requestOptions: RequestOptions, - ): UnifiedResponse = - // post /v4/nsdl/parse - withRawResponse().nsdl(params, requestOptions).parse() + ): InboxDisconnectEmailResponse = + // post /v4/inbox/disconnect + withRawResponse().disconnectEmail(params, requestOptions).parse() - override fun smartParse( - params: CasParserSmartParseParams, + override fun listCasFiles( + params: InboxListCasFilesParams, requestOptions: RequestOptions, - ): UnifiedResponse = - // post /v4/smart/parse - withRawResponse().smartParse(params, requestOptions).parse() + ): InboxListCasFilesResponse = + // post /v4/inbox/cas + withRawResponse().listCasFiles(params, requestOptions).parse() class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : - CasParserService.WithRawResponse { + InboxService.WithRawResponse { private val errorHandler: Handler = errorHandler(errorBodyHandler(clientOptions.jsonMapper)) override fun withOptions( modifier: Consumer - ): CasParserService.WithRawResponse = - CasParserServiceImpl.WithRawResponseImpl( + ): InboxService.WithRawResponse = + InboxServiceImpl.WithRawResponseImpl( clientOptions.toBuilder().apply(modifier::accept).build() ) - private val camsKfintechHandler: Handler = - jsonHandler(clientOptions.jsonMapper) + private val checkConnectionStatusHandler: Handler = + jsonHandler(clientOptions.jsonMapper) - override fun camsKfintech( - params: CasParserCamsKfintechParams, + override fun checkConnectionStatus( + params: InboxCheckConnectionStatusParams, requestOptions: RequestOptions, - ): HttpResponseFor { + ): HttpResponseFor { val request = HttpRequest.builder() .method(HttpMethod.POST) .baseUrl(clientOptions.baseUrl()) - .addPathSegments("v4", "cams_kfintech", "parse") - .body(multipartFormData(clientOptions.jsonMapper, params._body())) + .addPathSegments("v4", "inbox", "status") + .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 { camsKfintechHandler.handle(it) } + .use { checkConnectionStatusHandler.handle(it) } .also { if (requestOptions.responseValidation!!) { it.validate() @@ -103,26 +106,26 @@ class CasParserServiceImpl internal constructor(private val clientOptions: Clien } } - private val cdslHandler: Handler = - jsonHandler(clientOptions.jsonMapper) + private val connectEmailHandler: Handler = + jsonHandler(clientOptions.jsonMapper) - override fun cdsl( - params: CasParserCdslParams, + override fun connectEmail( + params: InboxConnectEmailParams, requestOptions: RequestOptions, - ): HttpResponseFor { + ): HttpResponseFor { val request = HttpRequest.builder() .method(HttpMethod.POST) .baseUrl(clientOptions.baseUrl()) - .addPathSegments("v4", "cdsl", "parse") - .body(multipartFormData(clientOptions.jsonMapper, params._body())) + .addPathSegments("v4", "inbox", "connect") + .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 { cdslHandler.handle(it) } + .use { connectEmailHandler.handle(it) } .also { if (requestOptions.responseValidation!!) { it.validate() @@ -131,26 +134,26 @@ class CasParserServiceImpl internal constructor(private val clientOptions: Clien } } - private val nsdlHandler: Handler = - jsonHandler(clientOptions.jsonMapper) + private val disconnectEmailHandler: Handler = + jsonHandler(clientOptions.jsonMapper) - override fun nsdl( - params: CasParserNsdlParams, + override fun disconnectEmail( + params: InboxDisconnectEmailParams, requestOptions: RequestOptions, - ): HttpResponseFor { + ): HttpResponseFor { val request = HttpRequest.builder() .method(HttpMethod.POST) .baseUrl(clientOptions.baseUrl()) - .addPathSegments("v4", "nsdl", "parse") - .body(multipartFormData(clientOptions.jsonMapper, params._body())) + .addPathSegments("v4", "inbox", "disconnect") + .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 { nsdlHandler.handle(it) } + .use { disconnectEmailHandler.handle(it) } .also { if (requestOptions.responseValidation!!) { it.validate() @@ -159,26 +162,26 @@ class CasParserServiceImpl internal constructor(private val clientOptions: Clien } } - private val smartParseHandler: Handler = - jsonHandler(clientOptions.jsonMapper) + private val listCasFilesHandler: Handler = + jsonHandler(clientOptions.jsonMapper) - override fun smartParse( - params: CasParserSmartParseParams, + override fun listCasFiles( + params: InboxListCasFilesParams, requestOptions: RequestOptions, - ): HttpResponseFor { + ): HttpResponseFor { val request = HttpRequest.builder() .method(HttpMethod.POST) .baseUrl(clientOptions.baseUrl()) - .addPathSegments("v4", "smart", "parse") - .body(multipartFormData(clientOptions.jsonMapper, params._body())) + .addPathSegments("v4", "inbox", "cas") + .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 { smartParseHandler.handle(it) } + .use { listCasFilesHandler.handle(it) } .also { if (requestOptions.responseValidation!!) { it.validate() diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/KfintechService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/KfintechService.kt new file mode 100644 index 0000000..0bc26c9 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/KfintechService.kt @@ -0,0 +1,68 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.models.kfintech.KfintechGenerateCasParams +import com.cas_parser.api.models.kfintech.KfintechGenerateCasResponse +import com.google.errorprone.annotations.MustBeClosed +import java.util.function.Consumer + +interface KfintechService { + + /** + * 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): KfintechService + + /** + * Generate CAS via KFintech mailback. The CAS PDF will be sent to the investor's email. + * + * This is an async operation - the investor receives the CAS via email within a few minutes. + * For instant CAS retrieval, use CDSL Fetch (`/v4/cdsl/fetch`). + */ + fun generateCas(params: KfintechGenerateCasParams): KfintechGenerateCasResponse = + generateCas(params, RequestOptions.none()) + + /** @see generateCas */ + fun generateCas( + params: KfintechGenerateCasParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): KfintechGenerateCasResponse + + /** A view of [KfintechService] 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): KfintechService.WithRawResponse + + /** + * Returns a raw HTTP response for `post /v4/kfintech/generate`, but is otherwise the same + * as [KfintechService.generateCas]. + */ + @MustBeClosed + fun generateCas( + params: KfintechGenerateCasParams + ): HttpResponseFor = generateCas(params, RequestOptions.none()) + + /** @see generateCas */ + @MustBeClosed + fun generateCas( + params: KfintechGenerateCasParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/KfintechServiceImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/KfintechServiceImpl.kt new file mode 100644 index 0000000..679e4d8 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/KfintechServiceImpl.kt @@ -0,0 +1,82 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.handlers.errorBodyHandler +import com.cas_parser.api.core.handlers.errorHandler +import com.cas_parser.api.core.handlers.jsonHandler +import com.cas_parser.api.core.http.HttpMethod +import com.cas_parser.api.core.http.HttpRequest +import com.cas_parser.api.core.http.HttpResponse +import com.cas_parser.api.core.http.HttpResponse.Handler +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.core.http.json +import com.cas_parser.api.core.http.parseable +import com.cas_parser.api.core.prepare +import com.cas_parser.api.models.kfintech.KfintechGenerateCasParams +import com.cas_parser.api.models.kfintech.KfintechGenerateCasResponse +import java.util.function.Consumer + +class KfintechServiceImpl internal constructor(private val clientOptions: ClientOptions) : + KfintechService { + + private val withRawResponse: KfintechService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): KfintechService.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): KfintechService = + KfintechServiceImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun generateCas( + params: KfintechGenerateCasParams, + requestOptions: RequestOptions, + ): KfintechGenerateCasResponse = + // post /v4/kfintech/generate + withRawResponse().generateCas(params, requestOptions).parse() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + KfintechService.WithRawResponse { + + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + + override fun withOptions( + modifier: Consumer + ): KfintechService.WithRawResponse = + KfintechServiceImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + private val generateCasHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun generateCas( + params: KfintechGenerateCasParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v4", "kfintech", "generate") + .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 { generateCasHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/LogService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/LogService.kt new file mode 100644 index 0000000..ce35cba --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/LogService.kt @@ -0,0 +1,134 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.models.logs.LogCreateParams +import com.cas_parser.api.models.logs.LogCreateResponse +import com.cas_parser.api.models.logs.LogGetSummaryParams +import com.cas_parser.api.models.logs.LogGetSummaryResponse +import com.google.errorprone.annotations.MustBeClosed +import java.util.function.Consumer + +interface LogService { + + /** + * 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): LogService + + /** + * Retrieve detailed API usage logs for your account. + * + * Returns a list of API calls with timestamps, features used, status codes, and credits + * consumed. Useful for monitoring usage patterns and debugging. + */ + fun create(): LogCreateResponse = create(LogCreateParams.none()) + + /** @see create */ + fun create( + params: LogCreateParams = LogCreateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): LogCreateResponse + + /** @see create */ + fun create(params: LogCreateParams = LogCreateParams.none()): LogCreateResponse = + create(params, RequestOptions.none()) + + /** @see create */ + fun create(requestOptions: RequestOptions): LogCreateResponse = + create(LogCreateParams.none(), requestOptions) + + /** + * Get aggregated usage statistics grouped by feature. + * + * Useful for understanding which API features are being used most and tracking usage trends. + */ + fun getSummary(): LogGetSummaryResponse = getSummary(LogGetSummaryParams.none()) + + /** @see getSummary */ + fun getSummary( + params: LogGetSummaryParams = LogGetSummaryParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): LogGetSummaryResponse + + /** @see getSummary */ + fun getSummary( + params: LogGetSummaryParams = LogGetSummaryParams.none() + ): LogGetSummaryResponse = getSummary(params, RequestOptions.none()) + + /** @see getSummary */ + fun getSummary(requestOptions: RequestOptions): LogGetSummaryResponse = + getSummary(LogGetSummaryParams.none(), requestOptions) + + /** A view of [LogService] 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): LogService.WithRawResponse + + /** + * Returns a raw HTTP response for `post /logs`, but is otherwise the same as + * [LogService.create]. + */ + @MustBeClosed + fun create(): HttpResponseFor = create(LogCreateParams.none()) + + /** @see create */ + @MustBeClosed + fun create( + params: LogCreateParams = LogCreateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see create */ + @MustBeClosed + fun create( + params: LogCreateParams = LogCreateParams.none() + ): HttpResponseFor = create(params, RequestOptions.none()) + + /** @see create */ + @MustBeClosed + fun create(requestOptions: RequestOptions): HttpResponseFor = + create(LogCreateParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `post /logs/summary`, but is otherwise the same as + * [LogService.getSummary]. + */ + @MustBeClosed + fun getSummary(): HttpResponseFor = + getSummary(LogGetSummaryParams.none()) + + /** @see getSummary */ + @MustBeClosed + fun getSummary( + params: LogGetSummaryParams = LogGetSummaryParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see getSummary */ + @MustBeClosed + fun getSummary( + params: LogGetSummaryParams = LogGetSummaryParams.none() + ): HttpResponseFor = getSummary(params, RequestOptions.none()) + + /** @see getSummary */ + @MustBeClosed + fun getSummary(requestOptions: RequestOptions): HttpResponseFor = + getSummary(LogGetSummaryParams.none(), requestOptions) + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/LogServiceImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/LogServiceImpl.kt new file mode 100644 index 0000000..fb303d1 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/LogServiceImpl.kt @@ -0,0 +1,118 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.handlers.errorBodyHandler +import com.cas_parser.api.core.handlers.errorHandler +import com.cas_parser.api.core.handlers.jsonHandler +import com.cas_parser.api.core.http.HttpMethod +import com.cas_parser.api.core.http.HttpRequest +import com.cas_parser.api.core.http.HttpResponse +import com.cas_parser.api.core.http.HttpResponse.Handler +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.core.http.json +import com.cas_parser.api.core.http.parseable +import com.cas_parser.api.core.prepare +import com.cas_parser.api.models.logs.LogCreateParams +import com.cas_parser.api.models.logs.LogCreateResponse +import com.cas_parser.api.models.logs.LogGetSummaryParams +import com.cas_parser.api.models.logs.LogGetSummaryResponse +import java.util.function.Consumer + +class LogServiceImpl internal constructor(private val clientOptions: ClientOptions) : LogService { + + private val withRawResponse: LogService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): LogService.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): LogService = + LogServiceImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun create( + params: LogCreateParams, + requestOptions: RequestOptions, + ): LogCreateResponse = + // post /logs + withRawResponse().create(params, requestOptions).parse() + + override fun getSummary( + params: LogGetSummaryParams, + requestOptions: RequestOptions, + ): LogGetSummaryResponse = + // post /logs/summary + withRawResponse().getSummary(params, requestOptions).parse() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + LogService.WithRawResponse { + + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + + override fun withOptions( + modifier: Consumer + ): LogService.WithRawResponse = + LogServiceImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun create( + params: LogCreateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("logs") + .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 { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + + private val getSummaryHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun getSummary( + params: LogGetSummaryParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("logs", "summary") + .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 { getSummaryHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/NsdlService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/NsdlService.kt new file mode 100644 index 0000000..8ca3b7c --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/NsdlService.kt @@ -0,0 +1,81 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.models.camskfintech.UnifiedResponse +import com.cas_parser.api.models.nsdl.NsdlParseParams +import com.google.errorprone.annotations.MustBeClosed +import java.util.function.Consumer + +interface NsdlService { + + /** + * 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): NsdlService + + /** + * This endpoint specifically parses NSDL CAS (Consolidated Account Statement) PDF files and + * returns data in a unified format. Use this endpoint when you know the PDF is from NSDL. + */ + fun parse(): UnifiedResponse = parse(NsdlParseParams.none()) + + /** @see parse */ + fun parse( + params: NsdlParseParams = NsdlParseParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): UnifiedResponse + + /** @see parse */ + fun parse(params: NsdlParseParams = NsdlParseParams.none()): UnifiedResponse = + parse(params, RequestOptions.none()) + + /** @see parse */ + fun parse(requestOptions: RequestOptions): UnifiedResponse = + parse(NsdlParseParams.none(), requestOptions) + + /** A view of [NsdlService] 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): NsdlService.WithRawResponse + + /** + * Returns a raw HTTP response for `post /v4/nsdl/parse`, but is otherwise the same as + * [NsdlService.parse]. + */ + @MustBeClosed fun parse(): HttpResponseFor = parse(NsdlParseParams.none()) + + /** @see parse */ + @MustBeClosed + fun parse( + params: NsdlParseParams = NsdlParseParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see parse */ + @MustBeClosed + fun parse( + params: NsdlParseParams = NsdlParseParams.none() + ): HttpResponseFor = parse(params, RequestOptions.none()) + + /** @see parse */ + @MustBeClosed + fun parse(requestOptions: RequestOptions): HttpResponseFor = + parse(NsdlParseParams.none(), requestOptions) + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/NsdlServiceImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/NsdlServiceImpl.kt new file mode 100644 index 0000000..a887773 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/NsdlServiceImpl.kt @@ -0,0 +1,78 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.handlers.errorBodyHandler +import com.cas_parser.api.core.handlers.errorHandler +import com.cas_parser.api.core.handlers.jsonHandler +import com.cas_parser.api.core.http.HttpMethod +import com.cas_parser.api.core.http.HttpRequest +import com.cas_parser.api.core.http.HttpResponse +import com.cas_parser.api.core.http.HttpResponse.Handler +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.core.http.multipartFormData +import com.cas_parser.api.core.http.parseable +import com.cas_parser.api.core.prepare +import com.cas_parser.api.models.camskfintech.UnifiedResponse +import com.cas_parser.api.models.nsdl.NsdlParseParams +import java.util.function.Consumer + +class NsdlServiceImpl internal constructor(private val clientOptions: ClientOptions) : NsdlService { + + private val withRawResponse: NsdlService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): NsdlService.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): NsdlService = + NsdlServiceImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun parse(params: NsdlParseParams, requestOptions: RequestOptions): UnifiedResponse = + // post /v4/nsdl/parse + withRawResponse().parse(params, requestOptions).parse() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + NsdlService.WithRawResponse { + + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + + override fun withOptions( + modifier: Consumer + ): NsdlService.WithRawResponse = + NsdlServiceImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + private val parseHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun parse( + params: NsdlParseParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v4", "nsdl", "parse") + .body(multipartFormData(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 { parseHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/SmartService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/SmartService.kt new file mode 100644 index 0000000..fce30ed --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/SmartService.kt @@ -0,0 +1,85 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.models.camskfintech.UnifiedResponse +import com.cas_parser.api.models.smart.SmartParseCasPdfParams +import com.google.errorprone.annotations.MustBeClosed +import java.util.function.Consumer + +interface SmartService { + + /** + * 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): SmartService + + /** + * This endpoint parses CAS (Consolidated Account Statement) PDF files from NSDL, CDSL, or + * CAMS/KFintech and returns data in a unified format. It auto-detects the CAS type and + * transforms the data into a consistent structure regardless of the source. + */ + fun parseCasPdf(): UnifiedResponse = parseCasPdf(SmartParseCasPdfParams.none()) + + /** @see parseCasPdf */ + fun parseCasPdf( + params: SmartParseCasPdfParams = SmartParseCasPdfParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): UnifiedResponse + + /** @see parseCasPdf */ + fun parseCasPdf( + params: SmartParseCasPdfParams = SmartParseCasPdfParams.none() + ): UnifiedResponse = parseCasPdf(params, RequestOptions.none()) + + /** @see parseCasPdf */ + fun parseCasPdf(requestOptions: RequestOptions): UnifiedResponse = + parseCasPdf(SmartParseCasPdfParams.none(), requestOptions) + + /** A view of [SmartService] 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): SmartService.WithRawResponse + + /** + * Returns a raw HTTP response for `post /v4/smart/parse`, but is otherwise the same as + * [SmartService.parseCasPdf]. + */ + @MustBeClosed + fun parseCasPdf(): HttpResponseFor = + parseCasPdf(SmartParseCasPdfParams.none()) + + /** @see parseCasPdf */ + @MustBeClosed + fun parseCasPdf( + params: SmartParseCasPdfParams = SmartParseCasPdfParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see parseCasPdf */ + @MustBeClosed + fun parseCasPdf( + params: SmartParseCasPdfParams = SmartParseCasPdfParams.none() + ): HttpResponseFor = parseCasPdf(params, RequestOptions.none()) + + /** @see parseCasPdf */ + @MustBeClosed + fun parseCasPdf(requestOptions: RequestOptions): HttpResponseFor = + parseCasPdf(SmartParseCasPdfParams.none(), requestOptions) + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/SmartServiceImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/SmartServiceImpl.kt new file mode 100644 index 0000000..6808cd7 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/SmartServiceImpl.kt @@ -0,0 +1,82 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.handlers.errorBodyHandler +import com.cas_parser.api.core.handlers.errorHandler +import com.cas_parser.api.core.handlers.jsonHandler +import com.cas_parser.api.core.http.HttpMethod +import com.cas_parser.api.core.http.HttpRequest +import com.cas_parser.api.core.http.HttpResponse +import com.cas_parser.api.core.http.HttpResponse.Handler +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.core.http.multipartFormData +import com.cas_parser.api.core.http.parseable +import com.cas_parser.api.core.prepare +import com.cas_parser.api.models.camskfintech.UnifiedResponse +import com.cas_parser.api.models.smart.SmartParseCasPdfParams +import java.util.function.Consumer + +class SmartServiceImpl internal constructor(private val clientOptions: ClientOptions) : + SmartService { + + private val withRawResponse: SmartService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): SmartService.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): SmartService = + SmartServiceImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun parseCasPdf( + params: SmartParseCasPdfParams, + requestOptions: RequestOptions, + ): UnifiedResponse = + // post /v4/smart/parse + withRawResponse().parseCasPdf(params, requestOptions).parse() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + SmartService.WithRawResponse { + + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + + override fun withOptions( + modifier: Consumer + ): SmartService.WithRawResponse = + SmartServiceImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + private val parseCasPdfHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun parseCasPdf( + params: SmartParseCasPdfParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v4", "smart", "parse") + .body(multipartFormData(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 { parseCasPdfHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/VerifyTokenService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/VerifyTokenService.kt new file mode 100644 index 0000000..6596370 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/VerifyTokenService.kt @@ -0,0 +1,85 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.models.verifytoken.VerifyTokenVerifyParams +import com.cas_parser.api.models.verifytoken.VerifyTokenVerifyResponse +import com.google.errorprone.annotations.MustBeClosed +import java.util.function.Consumer + +interface VerifyTokenService { + + /** + * 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): VerifyTokenService + + /** Verify an access token and check if it's still valid. Useful for debugging token issues. */ + fun verify(): VerifyTokenVerifyResponse = verify(VerifyTokenVerifyParams.none()) + + /** @see verify */ + fun verify( + params: VerifyTokenVerifyParams = VerifyTokenVerifyParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): VerifyTokenVerifyResponse + + /** @see verify */ + fun verify( + params: VerifyTokenVerifyParams = VerifyTokenVerifyParams.none() + ): VerifyTokenVerifyResponse = verify(params, RequestOptions.none()) + + /** @see verify */ + fun verify(requestOptions: RequestOptions): VerifyTokenVerifyResponse = + verify(VerifyTokenVerifyParams.none(), requestOptions) + + /** + * A view of [VerifyTokenService] 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 + ): VerifyTokenService.WithRawResponse + + /** + * Returns a raw HTTP response for `post /v1/verify-token`, but is otherwise the same as + * [VerifyTokenService.verify]. + */ + @MustBeClosed + fun verify(): HttpResponseFor = + verify(VerifyTokenVerifyParams.none()) + + /** @see verify */ + @MustBeClosed + fun verify( + params: VerifyTokenVerifyParams = VerifyTokenVerifyParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see verify */ + @MustBeClosed + fun verify( + params: VerifyTokenVerifyParams = VerifyTokenVerifyParams.none() + ): HttpResponseFor = verify(params, RequestOptions.none()) + + /** @see verify */ + @MustBeClosed + fun verify(requestOptions: RequestOptions): HttpResponseFor = + verify(VerifyTokenVerifyParams.none(), requestOptions) + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/VerifyTokenServiceImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/VerifyTokenServiceImpl.kt new file mode 100644 index 0000000..6780bb3 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/VerifyTokenServiceImpl.kt @@ -0,0 +1,82 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.handlers.errorBodyHandler +import com.cas_parser.api.core.handlers.errorHandler +import com.cas_parser.api.core.handlers.jsonHandler +import com.cas_parser.api.core.http.HttpMethod +import com.cas_parser.api.core.http.HttpRequest +import com.cas_parser.api.core.http.HttpResponse +import com.cas_parser.api.core.http.HttpResponse.Handler +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.core.http.json +import com.cas_parser.api.core.http.parseable +import com.cas_parser.api.core.prepare +import com.cas_parser.api.models.verifytoken.VerifyTokenVerifyParams +import com.cas_parser.api.models.verifytoken.VerifyTokenVerifyResponse +import java.util.function.Consumer + +class VerifyTokenServiceImpl internal constructor(private val clientOptions: ClientOptions) : + VerifyTokenService { + + private val withRawResponse: VerifyTokenService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): VerifyTokenService.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): VerifyTokenService = + VerifyTokenServiceImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun verify( + params: VerifyTokenVerifyParams, + requestOptions: RequestOptions, + ): VerifyTokenVerifyResponse = + // post /v1/verify-token + withRawResponse().verify(params, requestOptions).parse() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + VerifyTokenService.WithRawResponse { + + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + + override fun withOptions( + modifier: Consumer + ): VerifyTokenService.WithRawResponse = + VerifyTokenServiceImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + private val verifyHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun verify( + params: VerifyTokenVerifyParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v1", "verify-token") + .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 { verifyHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/cdsl/FetchService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/cdsl/FetchService.kt new file mode 100644 index 0000000..81f2bc3 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/cdsl/FetchService.kt @@ -0,0 +1,132 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking.cdsl + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.models.cdsl.fetch.FetchRequestOtpParams +import com.cas_parser.api.models.cdsl.fetch.FetchRequestOtpResponse +import com.cas_parser.api.models.cdsl.fetch.FetchVerifyOtpParams +import com.cas_parser.api.models.cdsl.fetch.FetchVerifyOtpResponse +import com.google.errorprone.annotations.MustBeClosed +import java.util.function.Consumer + +interface FetchService { + + /** + * 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): FetchService + + /** + * **Step 1 of 2**: Request OTP for CDSL CAS fetch. + * + * This endpoint: + * 1. Solves reCAPTCHA automatically (~15-20 seconds) + * 2. Submits login credentials to CDSL portal + * 3. Triggers OTP to user's registered mobile number + * + * After user receives OTP, call `/v4/cdsl/fetch/{session_id}/verify` to complete. + */ + fun requestOtp(params: FetchRequestOtpParams): FetchRequestOtpResponse = + requestOtp(params, RequestOptions.none()) + + /** @see requestOtp */ + fun requestOtp( + params: FetchRequestOtpParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): FetchRequestOtpResponse + + /** + * **Step 2 of 2**: Verify OTP and retrieve CDSL CAS files. + * + * After successful verification, CAS PDFs are fetched from CDSL portal, uploaded to cloud + * storage, and returned as direct download URLs. + */ + fun verifyOtp(sessionId: String, params: FetchVerifyOtpParams): FetchVerifyOtpResponse = + verifyOtp(sessionId, params, RequestOptions.none()) + + /** @see verifyOtp */ + fun verifyOtp( + sessionId: String, + params: FetchVerifyOtpParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): FetchVerifyOtpResponse = + verifyOtp(params.toBuilder().sessionId(sessionId).build(), requestOptions) + + /** @see verifyOtp */ + fun verifyOtp(params: FetchVerifyOtpParams): FetchVerifyOtpResponse = + verifyOtp(params, RequestOptions.none()) + + /** @see verifyOtp */ + fun verifyOtp( + params: FetchVerifyOtpParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): FetchVerifyOtpResponse + + /** A view of [FetchService] 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): FetchService.WithRawResponse + + /** + * Returns a raw HTTP response for `post /v4/cdsl/fetch`, but is otherwise the same as + * [FetchService.requestOtp]. + */ + @MustBeClosed + fun requestOtp(params: FetchRequestOtpParams): HttpResponseFor = + requestOtp(params, RequestOptions.none()) + + /** @see requestOtp */ + @MustBeClosed + fun requestOtp( + params: FetchRequestOtpParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `post /v4/cdsl/fetch/{session_id}/verify`, but is + * otherwise the same as [FetchService.verifyOtp]. + */ + @MustBeClosed + fun verifyOtp( + sessionId: String, + params: FetchVerifyOtpParams, + ): HttpResponseFor = + verifyOtp(sessionId, params, RequestOptions.none()) + + /** @see verifyOtp */ + @MustBeClosed + fun verifyOtp( + sessionId: String, + params: FetchVerifyOtpParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + verifyOtp(params.toBuilder().sessionId(sessionId).build(), requestOptions) + + /** @see verifyOtp */ + @MustBeClosed + fun verifyOtp(params: FetchVerifyOtpParams): HttpResponseFor = + verifyOtp(params, RequestOptions.none()) + + /** @see verifyOtp */ + @MustBeClosed + fun verifyOtp( + params: FetchVerifyOtpParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/cdsl/FetchServiceImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/cdsl/FetchServiceImpl.kt new file mode 100644 index 0000000..e9a3246 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/cdsl/FetchServiceImpl.kt @@ -0,0 +1,124 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking.cdsl + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.checkRequired +import com.cas_parser.api.core.handlers.errorBodyHandler +import com.cas_parser.api.core.handlers.errorHandler +import com.cas_parser.api.core.handlers.jsonHandler +import com.cas_parser.api.core.http.HttpMethod +import com.cas_parser.api.core.http.HttpRequest +import com.cas_parser.api.core.http.HttpResponse +import com.cas_parser.api.core.http.HttpResponse.Handler +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.core.http.json +import com.cas_parser.api.core.http.parseable +import com.cas_parser.api.core.prepare +import com.cas_parser.api.models.cdsl.fetch.FetchRequestOtpParams +import com.cas_parser.api.models.cdsl.fetch.FetchRequestOtpResponse +import com.cas_parser.api.models.cdsl.fetch.FetchVerifyOtpParams +import com.cas_parser.api.models.cdsl.fetch.FetchVerifyOtpResponse +import java.util.function.Consumer +import kotlin.jvm.optionals.getOrNull + +class FetchServiceImpl internal constructor(private val clientOptions: ClientOptions) : + FetchService { + + private val withRawResponse: FetchService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): FetchService.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): FetchService = + FetchServiceImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun requestOtp( + params: FetchRequestOtpParams, + requestOptions: RequestOptions, + ): FetchRequestOtpResponse = + // post /v4/cdsl/fetch + withRawResponse().requestOtp(params, requestOptions).parse() + + override fun verifyOtp( + params: FetchVerifyOtpParams, + requestOptions: RequestOptions, + ): FetchVerifyOtpResponse = + // post /v4/cdsl/fetch/{session_id}/verify + withRawResponse().verifyOtp(params, requestOptions).parse() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + FetchService.WithRawResponse { + + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + + override fun withOptions( + modifier: Consumer + ): FetchService.WithRawResponse = + FetchServiceImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + private val requestOtpHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun requestOtp( + params: FetchRequestOtpParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v4", "cdsl", "fetch") + .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 { requestOtpHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + + private val verifyOtpHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun verifyOtp( + params: FetchVerifyOtpParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("sessionId", params.sessionId().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v4", "cdsl", "fetch", params._pathParam(0), "verify") + .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 { verifyOtpHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateParamsTest.kt new file mode 100644 index 0000000..a6a696b --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateParamsTest.kt @@ -0,0 +1,30 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.accesstoken + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class AccessTokenCreateParamsTest { + + @Test + fun create() { + AccessTokenCreateParams.builder().expiryMinutes(60L).build() + } + + @Test + fun body() { + val params = AccessTokenCreateParams.builder().expiryMinutes(60L).build() + + val body = params._body() + + assertThat(body.expiryMinutes()).contains(60L) + } + + @Test + fun bodyWithoutOptionalFields() { + val params = AccessTokenCreateParams.builder().build() + + val body = params._body() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateResponseTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateResponseTest.kt new file mode 100644 index 0000000..09382b7 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateResponseTest.kt @@ -0,0 +1,45 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.accesstoken + +import com.cas_parser.api.core.jsonMapper +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class AccessTokenCreateResponseTest { + + @Test + fun create() { + val accessTokenCreateResponse = + AccessTokenCreateResponse.builder() + .accessToken("at_eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...") + .expiresIn(3600L) + .tokenType("api_key") + .build() + + assertThat(accessTokenCreateResponse.accessToken()) + .contains("at_eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...") + assertThat(accessTokenCreateResponse.expiresIn()).contains(3600L) + assertThat(accessTokenCreateResponse.tokenType()).contains("api_key") + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val accessTokenCreateResponse = + AccessTokenCreateResponse.builder() + .accessToken("at_eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...") + .expiresIn(3600L) + .tokenType("api_key") + .build() + + val roundtrippedAccessTokenCreateResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(accessTokenCreateResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedAccessTokenCreateResponse).isEqualTo(accessTokenCreateResponse) + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserSmartParseParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/camskfintech/CamsKfintechParseParamsTest.kt similarity index 86% rename from cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserSmartParseParamsTest.kt rename to cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/camskfintech/CamsKfintechParseParamsTest.kt index 795fbfd..4cf0889 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserSmartParseParamsTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/camskfintech/CamsKfintechParseParamsTest.kt @@ -1,17 +1,17 @@ // File generated from our OpenAPI spec by Stainless. -package com.cas_parser.api.models.casparser +package com.cas_parser.api.models.camskfintech import com.cas_parser.api.core.MultipartField import java.io.InputStream import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -internal class CasParserSmartParseParamsTest { +internal class CamsKfintechParseParamsTest { @Test fun create() { - CasParserSmartParseParams.builder() + CamsKfintechParseParams.builder() .password("password") .pdfFile("pdf_file") .pdfUrl("https://example.com") @@ -21,7 +21,7 @@ internal class CasParserSmartParseParamsTest { @Test fun body() { val params = - CasParserSmartParseParams.builder() + CamsKfintechParseParams.builder() .password("password") .pdfFile("pdf_file") .pdfUrl("https://example.com") @@ -51,7 +51,7 @@ internal class CasParserSmartParseParamsTest { @Test fun bodyWithoutOptionalFields() { - val params = CasParserSmartParseParams.builder().build() + val params = CamsKfintechParseParams.builder().build() val body = params._body() diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/camskfintech/LinkedHolderTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/camskfintech/LinkedHolderTest.kt new file mode 100644 index 0000000..7382244 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/camskfintech/LinkedHolderTest.kt @@ -0,0 +1,33 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.camskfintech + +import com.cas_parser.api.core.jsonMapper +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class LinkedHolderTest { + + @Test + fun create() { + val linkedHolder = LinkedHolder.builder().name("name").pan("pan").build() + + assertThat(linkedHolder.name()).contains("name") + assertThat(linkedHolder.pan()).contains("pan") + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val linkedHolder = LinkedHolder.builder().name("name").pan("pan").build() + + val roundtrippedLinkedHolder = + jsonMapper.readValue( + jsonMapper.writeValueAsString(linkedHolder), + jacksonTypeRef(), + ) + + assertThat(roundtrippedLinkedHolder).isEqualTo(linkedHolder) + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/camskfintech/TransactionTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/camskfintech/TransactionTest.kt new file mode 100644 index 0000000..e133f0c --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/camskfintech/TransactionTest.kt @@ -0,0 +1,94 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.camskfintech + +import com.cas_parser.api.core.jsonMapper +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import java.time.LocalDate +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class TransactionTest { + + @Test + fun create() { + val transaction = + Transaction.builder() + .additionalInfo( + Transaction.AdditionalInfo.builder() + .capitalWithdrawal(0.0f) + .credit(0.0f) + .debit(0.0f) + .incomeDistribution(0.0f) + .orderNo("order_no") + .price(0.0f) + .stampDuty(0.0f) + .build() + ) + .amount(0.0f) + .balance(0.0f) + .date(LocalDate.parse("2019-12-27")) + .description("description") + .dividendRate(0.0f) + .nav(0.0f) + .type(Transaction.Type.PURCHASE) + .units(0.0f) + .build() + + assertThat(transaction.additionalInfo()) + .contains( + Transaction.AdditionalInfo.builder() + .capitalWithdrawal(0.0f) + .credit(0.0f) + .debit(0.0f) + .incomeDistribution(0.0f) + .orderNo("order_no") + .price(0.0f) + .stampDuty(0.0f) + .build() + ) + assertThat(transaction.amount()).contains(0.0f) + assertThat(transaction.balance()).contains(0.0f) + assertThat(transaction.date()).contains(LocalDate.parse("2019-12-27")) + assertThat(transaction.description()).contains("description") + assertThat(transaction.dividendRate()).contains(0.0f) + assertThat(transaction.nav()).contains(0.0f) + assertThat(transaction.type()).contains(Transaction.Type.PURCHASE) + assertThat(transaction.units()).contains(0.0f) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val transaction = + Transaction.builder() + .additionalInfo( + Transaction.AdditionalInfo.builder() + .capitalWithdrawal(0.0f) + .credit(0.0f) + .debit(0.0f) + .incomeDistribution(0.0f) + .orderNo("order_no") + .price(0.0f) + .stampDuty(0.0f) + .build() + ) + .amount(0.0f) + .balance(0.0f) + .date(LocalDate.parse("2019-12-27")) + .description("description") + .dividendRate(0.0f) + .nav(0.0f) + .type(Transaction.Type.PURCHASE) + .units(0.0f) + .build() + + val roundtrippedTransaction = + jsonMapper.readValue( + jsonMapper.writeValueAsString(transaction), + jacksonTypeRef(), + ) + + assertThat(roundtrippedTransaction).isEqualTo(transaction) + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/UnifiedResponseTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/camskfintech/UnifiedResponseTest.kt similarity index 77% rename from cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/UnifiedResponseTest.kt rename to cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/camskfintech/UnifiedResponseTest.kt index f0fa2ca..ab37900 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/UnifiedResponseTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/camskfintech/UnifiedResponseTest.kt @@ -1,6 +1,6 @@ // File generated from our OpenAPI spec by Stainless. -package com.cas_parser.api.models.casparser +package com.cas_parser.api.models.camskfintech import com.cas_parser.api.core.JsonValue import com.cas_parser.api.core.jsonMapper @@ -50,13 +50,9 @@ internal class UnifiedResponseTest { .isin("isin") .name("name") .addTransaction( - UnifiedResponse.DematAccount.Holdings.Aif.Transaction - .builder() + Transaction.builder() .additionalInfo( - UnifiedResponse.DematAccount.Holdings.Aif - .Transaction - .AdditionalInfo - .builder() + Transaction.AdditionalInfo.builder() .capitalWithdrawal(0.0f) .credit(0.0f) .debit(0.0f) @@ -72,12 +68,7 @@ internal class UnifiedResponseTest { .description("description") .dividendRate(0.0f) .nav(0.0f) - .type( - UnifiedResponse.DematAccount.Holdings.Aif - .Transaction - .Type - .PURCHASE - ) + .type(Transaction.Type.PURCHASE) .units(0.0f) .build() ) @@ -98,15 +89,9 @@ internal class UnifiedResponseTest { .isin("isin") .name("name") .addTransaction( - UnifiedResponse.DematAccount.Holdings.CorporateBond - .Transaction - .builder() + Transaction.builder() .additionalInfo( - UnifiedResponse.DematAccount.Holdings - .CorporateBond - .Transaction - .AdditionalInfo - .builder() + Transaction.AdditionalInfo.builder() .capitalWithdrawal(0.0f) .credit(0.0f) .debit(0.0f) @@ -122,13 +107,7 @@ internal class UnifiedResponseTest { .description("description") .dividendRate(0.0f) .nav(0.0f) - .type( - UnifiedResponse.DematAccount.Holdings - .CorporateBond - .Transaction - .Type - .PURCHASE - ) + .type(Transaction.Type.PURCHASE) .units(0.0f) .build() ) @@ -149,15 +128,9 @@ internal class UnifiedResponseTest { .isin("isin") .name("name") .addTransaction( - UnifiedResponse.DematAccount.Holdings.DematMutualFund - .Transaction - .builder() + Transaction.builder() .additionalInfo( - UnifiedResponse.DematAccount.Holdings - .DematMutualFund - .Transaction - .AdditionalInfo - .builder() + Transaction.AdditionalInfo.builder() .capitalWithdrawal(0.0f) .credit(0.0f) .debit(0.0f) @@ -173,13 +146,7 @@ internal class UnifiedResponseTest { .description("description") .dividendRate(0.0f) .nav(0.0f) - .type( - UnifiedResponse.DematAccount.Holdings - .DematMutualFund - .Transaction - .Type - .PURCHASE - ) + .type(Transaction.Type.PURCHASE) .units(0.0f) .build() ) @@ -200,13 +167,9 @@ internal class UnifiedResponseTest { .isin("isin") .name("name") .addTransaction( - UnifiedResponse.DematAccount.Holdings.Equity.Transaction - .builder() + Transaction.builder() .additionalInfo( - UnifiedResponse.DematAccount.Holdings.Equity - .Transaction - .AdditionalInfo - .builder() + Transaction.AdditionalInfo.builder() .capitalWithdrawal(0.0f) .credit(0.0f) .debit(0.0f) @@ -222,12 +185,7 @@ internal class UnifiedResponseTest { .description("description") .dividendRate(0.0f) .nav(0.0f) - .type( - UnifiedResponse.DematAccount.Holdings.Equity - .Transaction - .Type - .PURCHASE - ) + .type(Transaction.Type.PURCHASE) .units(0.0f) .build() ) @@ -249,15 +207,9 @@ internal class UnifiedResponseTest { .isin("isin") .name("name") .addTransaction( - UnifiedResponse.DematAccount.Holdings.GovernmentSecurity - .Transaction - .builder() + Transaction.builder() .additionalInfo( - UnifiedResponse.DematAccount.Holdings - .GovernmentSecurity - .Transaction - .AdditionalInfo - .builder() + Transaction.AdditionalInfo.builder() .capitalWithdrawal(0.0f) .credit(0.0f) .debit(0.0f) @@ -273,13 +225,7 @@ internal class UnifiedResponseTest { .description("description") .dividendRate(0.0f) .nav(0.0f) - .type( - UnifiedResponse.DematAccount.Holdings - .GovernmentSecurity - .Transaction - .Type - .PURCHASE - ) + .type(Transaction.Type.PURCHASE) .units(0.0f) .build() ) @@ -289,12 +235,7 @@ internal class UnifiedResponseTest { ) .build() ) - .addLinkedHolder( - UnifiedResponse.DematAccount.LinkedHolder.builder() - .name("name") - .pan("pan") - .build() - ) + .addLinkedHolder(LinkedHolder.builder().name("name").pan("pan").build()) .value(0.0f) .build() ) @@ -349,12 +290,7 @@ internal class UnifiedResponseTest { ) .amc("amc") .folioNumber("folio_number") - .addLinkedHolder( - UnifiedResponse.MutualFund.LinkedHolder.builder() - .name("name") - .pan("pan") - .build() - ) + .addLinkedHolder(LinkedHolder.builder().name("name").pan("pan").build()) .registrar("registrar") .addScheme( UnifiedResponse.MutualFund.Scheme.builder() @@ -379,11 +315,9 @@ internal class UnifiedResponseTest { .nav(0.0f) .addNominee("string") .addTransaction( - UnifiedResponse.MutualFund.Scheme.Transaction.builder() + Transaction.builder() .additionalInfo( - UnifiedResponse.MutualFund.Scheme.Transaction - .AdditionalInfo - .builder() + Transaction.AdditionalInfo.builder() .capitalWithdrawal(0.0f) .credit(0.0f) .debit(0.0f) @@ -399,10 +333,7 @@ internal class UnifiedResponseTest { .description("description") .dividendRate(0.0f) .nav(0.0f) - .type( - UnifiedResponse.MutualFund.Scheme.Transaction.Type - .PURCHASE - ) + .type(Transaction.Type.PURCHASE) .units(0.0f) .build() ) @@ -433,12 +364,7 @@ internal class UnifiedResponseTest { .value(0.0f) .build() ) - .addLinkedHolder( - UnifiedResponse.Np.LinkedHolder.builder() - .name("name") - .pan("pan") - .build() - ) + .addLinkedHolder(LinkedHolder.builder().name("name").pan("pan").build()) .pran("pran") .value(0.0f) .build() @@ -512,13 +438,9 @@ internal class UnifiedResponseTest { .isin("isin") .name("name") .addTransaction( - UnifiedResponse.DematAccount.Holdings.Aif.Transaction - .builder() + Transaction.builder() .additionalInfo( - UnifiedResponse.DematAccount.Holdings.Aif - .Transaction - .AdditionalInfo - .builder() + Transaction.AdditionalInfo.builder() .capitalWithdrawal(0.0f) .credit(0.0f) .debit(0.0f) @@ -534,12 +456,7 @@ internal class UnifiedResponseTest { .description("description") .dividendRate(0.0f) .nav(0.0f) - .type( - UnifiedResponse.DematAccount.Holdings.Aif - .Transaction - .Type - .PURCHASE - ) + .type(Transaction.Type.PURCHASE) .units(0.0f) .build() ) @@ -560,14 +477,9 @@ internal class UnifiedResponseTest { .isin("isin") .name("name") .addTransaction( - UnifiedResponse.DematAccount.Holdings.CorporateBond - .Transaction - .builder() + Transaction.builder() .additionalInfo( - UnifiedResponse.DematAccount.Holdings.CorporateBond - .Transaction - .AdditionalInfo - .builder() + Transaction.AdditionalInfo.builder() .capitalWithdrawal(0.0f) .credit(0.0f) .debit(0.0f) @@ -583,12 +495,7 @@ internal class UnifiedResponseTest { .description("description") .dividendRate(0.0f) .nav(0.0f) - .type( - UnifiedResponse.DematAccount.Holdings.CorporateBond - .Transaction - .Type - .PURCHASE - ) + .type(Transaction.Type.PURCHASE) .units(0.0f) .build() ) @@ -609,15 +516,9 @@ internal class UnifiedResponseTest { .isin("isin") .name("name") .addTransaction( - UnifiedResponse.DematAccount.Holdings.DematMutualFund - .Transaction - .builder() + Transaction.builder() .additionalInfo( - UnifiedResponse.DematAccount.Holdings - .DematMutualFund - .Transaction - .AdditionalInfo - .builder() + Transaction.AdditionalInfo.builder() .capitalWithdrawal(0.0f) .credit(0.0f) .debit(0.0f) @@ -633,13 +534,7 @@ internal class UnifiedResponseTest { .description("description") .dividendRate(0.0f) .nav(0.0f) - .type( - UnifiedResponse.DematAccount.Holdings - .DematMutualFund - .Transaction - .Type - .PURCHASE - ) + .type(Transaction.Type.PURCHASE) .units(0.0f) .build() ) @@ -659,13 +554,9 @@ internal class UnifiedResponseTest { .isin("isin") .name("name") .addTransaction( - UnifiedResponse.DematAccount.Holdings.Equity.Transaction - .builder() + Transaction.builder() .additionalInfo( - UnifiedResponse.DematAccount.Holdings.Equity - .Transaction - .AdditionalInfo - .builder() + Transaction.AdditionalInfo.builder() .capitalWithdrawal(0.0f) .credit(0.0f) .debit(0.0f) @@ -681,12 +572,7 @@ internal class UnifiedResponseTest { .description("description") .dividendRate(0.0f) .nav(0.0f) - .type( - UnifiedResponse.DematAccount.Holdings.Equity - .Transaction - .Type - .PURCHASE - ) + .type(Transaction.Type.PURCHASE) .units(0.0f) .build() ) @@ -707,15 +593,9 @@ internal class UnifiedResponseTest { .isin("isin") .name("name") .addTransaction( - UnifiedResponse.DematAccount.Holdings.GovernmentSecurity - .Transaction - .builder() + Transaction.builder() .additionalInfo( - UnifiedResponse.DematAccount.Holdings - .GovernmentSecurity - .Transaction - .AdditionalInfo - .builder() + Transaction.AdditionalInfo.builder() .capitalWithdrawal(0.0f) .credit(0.0f) .debit(0.0f) @@ -731,13 +611,7 @@ internal class UnifiedResponseTest { .description("description") .dividendRate(0.0f) .nav(0.0f) - .type( - UnifiedResponse.DematAccount.Holdings - .GovernmentSecurity - .Transaction - .Type - .PURCHASE - ) + .type(Transaction.Type.PURCHASE) .units(0.0f) .build() ) @@ -747,12 +621,7 @@ internal class UnifiedResponseTest { ) .build() ) - .addLinkedHolder( - UnifiedResponse.DematAccount.LinkedHolder.builder() - .name("name") - .pan("pan") - .build() - ) + .addLinkedHolder(LinkedHolder.builder().name("name").pan("pan").build()) .value(0.0f) .build() ) @@ -811,12 +680,7 @@ internal class UnifiedResponseTest { ) .amc("amc") .folioNumber("folio_number") - .addLinkedHolder( - UnifiedResponse.MutualFund.LinkedHolder.builder() - .name("name") - .pan("pan") - .build() - ) + .addLinkedHolder(LinkedHolder.builder().name("name").pan("pan").build()) .registrar("registrar") .addScheme( UnifiedResponse.MutualFund.Scheme.builder() @@ -841,10 +705,9 @@ internal class UnifiedResponseTest { .nav(0.0f) .addNominee("string") .addTransaction( - UnifiedResponse.MutualFund.Scheme.Transaction.builder() + Transaction.builder() .additionalInfo( - UnifiedResponse.MutualFund.Scheme.Transaction.AdditionalInfo - .builder() + Transaction.AdditionalInfo.builder() .capitalWithdrawal(0.0f) .credit(0.0f) .debit(0.0f) @@ -860,9 +723,7 @@ internal class UnifiedResponseTest { .description("description") .dividendRate(0.0f) .nav(0.0f) - .type( - UnifiedResponse.MutualFund.Scheme.Transaction.Type.PURCHASE - ) + .type(Transaction.Type.PURCHASE) .units(0.0f) .build() ) @@ -894,9 +755,7 @@ internal class UnifiedResponseTest { .value(0.0f) .build() ) - .addLinkedHolder( - UnifiedResponse.Np.LinkedHolder.builder().name("name").pan("pan").build() - ) + .addLinkedHolder(LinkedHolder.builder().name("name").pan("pan").build()) .pran("pran") .value(0.0f) .build() @@ -975,13 +834,9 @@ internal class UnifiedResponseTest { .isin("isin") .name("name") .addTransaction( - UnifiedResponse.DematAccount.Holdings.Aif.Transaction - .builder() + Transaction.builder() .additionalInfo( - UnifiedResponse.DematAccount.Holdings.Aif - .Transaction - .AdditionalInfo - .builder() + Transaction.AdditionalInfo.builder() .capitalWithdrawal(0.0f) .credit(0.0f) .debit(0.0f) @@ -997,12 +852,7 @@ internal class UnifiedResponseTest { .description("description") .dividendRate(0.0f) .nav(0.0f) - .type( - UnifiedResponse.DematAccount.Holdings.Aif - .Transaction - .Type - .PURCHASE - ) + .type(Transaction.Type.PURCHASE) .units(0.0f) .build() ) @@ -1023,15 +873,9 @@ internal class UnifiedResponseTest { .isin("isin") .name("name") .addTransaction( - UnifiedResponse.DematAccount.Holdings.CorporateBond - .Transaction - .builder() + Transaction.builder() .additionalInfo( - UnifiedResponse.DematAccount.Holdings - .CorporateBond - .Transaction - .AdditionalInfo - .builder() + Transaction.AdditionalInfo.builder() .capitalWithdrawal(0.0f) .credit(0.0f) .debit(0.0f) @@ -1047,13 +891,7 @@ internal class UnifiedResponseTest { .description("description") .dividendRate(0.0f) .nav(0.0f) - .type( - UnifiedResponse.DematAccount.Holdings - .CorporateBond - .Transaction - .Type - .PURCHASE - ) + .type(Transaction.Type.PURCHASE) .units(0.0f) .build() ) @@ -1074,15 +912,9 @@ internal class UnifiedResponseTest { .isin("isin") .name("name") .addTransaction( - UnifiedResponse.DematAccount.Holdings.DematMutualFund - .Transaction - .builder() + Transaction.builder() .additionalInfo( - UnifiedResponse.DematAccount.Holdings - .DematMutualFund - .Transaction - .AdditionalInfo - .builder() + Transaction.AdditionalInfo.builder() .capitalWithdrawal(0.0f) .credit(0.0f) .debit(0.0f) @@ -1098,13 +930,7 @@ internal class UnifiedResponseTest { .description("description") .dividendRate(0.0f) .nav(0.0f) - .type( - UnifiedResponse.DematAccount.Holdings - .DematMutualFund - .Transaction - .Type - .PURCHASE - ) + .type(Transaction.Type.PURCHASE) .units(0.0f) .build() ) @@ -1125,13 +951,9 @@ internal class UnifiedResponseTest { .isin("isin") .name("name") .addTransaction( - UnifiedResponse.DematAccount.Holdings.Equity.Transaction - .builder() + Transaction.builder() .additionalInfo( - UnifiedResponse.DematAccount.Holdings.Equity - .Transaction - .AdditionalInfo - .builder() + Transaction.AdditionalInfo.builder() .capitalWithdrawal(0.0f) .credit(0.0f) .debit(0.0f) @@ -1147,12 +969,7 @@ internal class UnifiedResponseTest { .description("description") .dividendRate(0.0f) .nav(0.0f) - .type( - UnifiedResponse.DematAccount.Holdings.Equity - .Transaction - .Type - .PURCHASE - ) + .type(Transaction.Type.PURCHASE) .units(0.0f) .build() ) @@ -1174,15 +991,9 @@ internal class UnifiedResponseTest { .isin("isin") .name("name") .addTransaction( - UnifiedResponse.DematAccount.Holdings.GovernmentSecurity - .Transaction - .builder() + Transaction.builder() .additionalInfo( - UnifiedResponse.DematAccount.Holdings - .GovernmentSecurity - .Transaction - .AdditionalInfo - .builder() + Transaction.AdditionalInfo.builder() .capitalWithdrawal(0.0f) .credit(0.0f) .debit(0.0f) @@ -1198,13 +1009,7 @@ internal class UnifiedResponseTest { .description("description") .dividendRate(0.0f) .nav(0.0f) - .type( - UnifiedResponse.DematAccount.Holdings - .GovernmentSecurity - .Transaction - .Type - .PURCHASE - ) + .type(Transaction.Type.PURCHASE) .units(0.0f) .build() ) @@ -1214,12 +1019,7 @@ internal class UnifiedResponseTest { ) .build() ) - .addLinkedHolder( - UnifiedResponse.DematAccount.LinkedHolder.builder() - .name("name") - .pan("pan") - .build() - ) + .addLinkedHolder(LinkedHolder.builder().name("name").pan("pan").build()) .value(0.0f) .build() ) @@ -1274,12 +1074,7 @@ internal class UnifiedResponseTest { ) .amc("amc") .folioNumber("folio_number") - .addLinkedHolder( - UnifiedResponse.MutualFund.LinkedHolder.builder() - .name("name") - .pan("pan") - .build() - ) + .addLinkedHolder(LinkedHolder.builder().name("name").pan("pan").build()) .registrar("registrar") .addScheme( UnifiedResponse.MutualFund.Scheme.builder() @@ -1304,11 +1099,9 @@ internal class UnifiedResponseTest { .nav(0.0f) .addNominee("string") .addTransaction( - UnifiedResponse.MutualFund.Scheme.Transaction.builder() + Transaction.builder() .additionalInfo( - UnifiedResponse.MutualFund.Scheme.Transaction - .AdditionalInfo - .builder() + Transaction.AdditionalInfo.builder() .capitalWithdrawal(0.0f) .credit(0.0f) .debit(0.0f) @@ -1324,10 +1117,7 @@ internal class UnifiedResponseTest { .description("description") .dividendRate(0.0f) .nav(0.0f) - .type( - UnifiedResponse.MutualFund.Scheme.Transaction.Type - .PURCHASE - ) + .type(Transaction.Type.PURCHASE) .units(0.0f) .build() ) @@ -1358,12 +1148,7 @@ internal class UnifiedResponseTest { .value(0.0f) .build() ) - .addLinkedHolder( - UnifiedResponse.Np.LinkedHolder.builder() - .name("name") - .pan("pan") - .build() - ) + .addLinkedHolder(LinkedHolder.builder().name("name").pan("pan").build()) .pran("pran") .value(0.0f) .build() diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserNsdlParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/cdsl/CdslParsePdfParamsTest.kt similarity index 87% rename from cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserNsdlParamsTest.kt rename to cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/cdsl/CdslParsePdfParamsTest.kt index fba23f6..d848d88 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserNsdlParamsTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/cdsl/CdslParsePdfParamsTest.kt @@ -1,17 +1,17 @@ // File generated from our OpenAPI spec by Stainless. -package com.cas_parser.api.models.casparser +package com.cas_parser.api.models.cdsl import com.cas_parser.api.core.MultipartField import java.io.InputStream import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -internal class CasParserNsdlParamsTest { +internal class CdslParsePdfParamsTest { @Test fun create() { - CasParserNsdlParams.builder() + CdslParsePdfParams.builder() .password("password") .pdfFile("pdf_file") .pdfUrl("https://example.com") @@ -21,7 +21,7 @@ internal class CasParserNsdlParamsTest { @Test fun body() { val params = - CasParserNsdlParams.builder() + CdslParsePdfParams.builder() .password("password") .pdfFile("pdf_file") .pdfUrl("https://example.com") @@ -51,7 +51,7 @@ internal class CasParserNsdlParamsTest { @Test fun bodyWithoutOptionalFields() { - val params = CasParserNsdlParams.builder().build() + val params = CdslParsePdfParams.builder().build() val body = params._body() diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchRequestOtpParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchRequestOtpParamsTest.kt new file mode 100644 index 0000000..3f56894 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchRequestOtpParamsTest.kt @@ -0,0 +1,34 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.cdsl.fetch + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class FetchRequestOtpParamsTest { + + @Test + fun create() { + FetchRequestOtpParams.builder() + .boId("1234567890123456") + .dob("1990-01-15") + .pan("ABCDE1234F") + .build() + } + + @Test + fun body() { + val params = + FetchRequestOtpParams.builder() + .boId("1234567890123456") + .dob("1990-01-15") + .pan("ABCDE1234F") + .build() + + val body = params._body() + + assertThat(body.boId()).isEqualTo("1234567890123456") + assertThat(body.dob()).isEqualTo("1990-01-15") + assertThat(body.pan()).isEqualTo("ABCDE1234F") + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchRequestOtpResponseTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchRequestOtpResponseTest.kt new file mode 100644 index 0000000..a63b5e2 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchRequestOtpResponseTest.kt @@ -0,0 +1,45 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.cdsl.fetch + +import com.cas_parser.api.core.jsonMapper +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class FetchRequestOtpResponseTest { + + @Test + fun create() { + val fetchRequestOtpResponse = + FetchRequestOtpResponse.builder() + .msg("OTP sent to registered mobile") + .sessionId("550e8400-e29b-41d4-a716-446655440000") + .status("success") + .build() + + assertThat(fetchRequestOtpResponse.msg()).contains("OTP sent to registered mobile") + assertThat(fetchRequestOtpResponse.sessionId()) + .contains("550e8400-e29b-41d4-a716-446655440000") + assertThat(fetchRequestOtpResponse.status()).contains("success") + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val fetchRequestOtpResponse = + FetchRequestOtpResponse.builder() + .msg("OTP sent to registered mobile") + .sessionId("550e8400-e29b-41d4-a716-446655440000") + .status("success") + .build() + + val roundtrippedFetchRequestOtpResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(fetchRequestOtpResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedFetchRequestOtpResponse).isEqualTo(fetchRequestOtpResponse) + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchVerifyOtpParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchVerifyOtpParamsTest.kt new file mode 100644 index 0000000..5b4f38d --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchVerifyOtpParamsTest.kt @@ -0,0 +1,47 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.cdsl.fetch + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class FetchVerifyOtpParamsTest { + + @Test + fun create() { + FetchVerifyOtpParams.builder().sessionId("session_id").otp("123456").numPeriods(6L).build() + } + + @Test + fun pathParams() { + val params = FetchVerifyOtpParams.builder().sessionId("session_id").otp("123456").build() + + assertThat(params._pathParam(0)).isEqualTo("session_id") + // out-of-bound path param + assertThat(params._pathParam(1)).isEqualTo("") + } + + @Test + fun body() { + val params = + FetchVerifyOtpParams.builder() + .sessionId("session_id") + .otp("123456") + .numPeriods(6L) + .build() + + val body = params._body() + + assertThat(body.otp()).isEqualTo("123456") + assertThat(body.numPeriods()).contains(6L) + } + + @Test + fun bodyWithoutOptionalFields() { + val params = FetchVerifyOtpParams.builder().sessionId("session_id").otp("123456").build() + + val body = params._body() + + assertThat(body.otp()).isEqualTo("123456") + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchVerifyOtpResponseTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchVerifyOtpResponseTest.kt new file mode 100644 index 0000000..fbad184 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchVerifyOtpResponseTest.kt @@ -0,0 +1,67 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.cdsl.fetch + +import com.cas_parser.api.core.jsonMapper +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import kotlin.jvm.optionals.getOrNull +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class FetchVerifyOtpResponseTest { + + @Test + fun create() { + val fetchVerifyOtpResponse = + FetchVerifyOtpResponse.builder() + .addFile( + FetchVerifyOtpResponse.File.builder() + .filename("CDSL_CAS_1234567890123456_NOV2025.pdf") + .url( + "https://cdn.casparser.in/cdsl-cas/session-id/CDSL_CAS_1234567890123456_NOV2025.pdf" + ) + .build() + ) + .msg("Fetched 6 CAS files") + .status("success") + .build() + + assertThat(fetchVerifyOtpResponse.files().getOrNull()) + .containsExactly( + FetchVerifyOtpResponse.File.builder() + .filename("CDSL_CAS_1234567890123456_NOV2025.pdf") + .url( + "https://cdn.casparser.in/cdsl-cas/session-id/CDSL_CAS_1234567890123456_NOV2025.pdf" + ) + .build() + ) + assertThat(fetchVerifyOtpResponse.msg()).contains("Fetched 6 CAS files") + assertThat(fetchVerifyOtpResponse.status()).contains("success") + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val fetchVerifyOtpResponse = + FetchVerifyOtpResponse.builder() + .addFile( + FetchVerifyOtpResponse.File.builder() + .filename("CDSL_CAS_1234567890123456_NOV2025.pdf") + .url( + "https://cdn.casparser.in/cdsl-cas/session-id/CDSL_CAS_1234567890123456_NOV2025.pdf" + ) + .build() + ) + .msg("Fetched 6 CAS files") + .status("success") + .build() + + val roundtrippedFetchVerifyOtpResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(fetchVerifyOtpResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedFetchVerifyOtpResponse).isEqualTo(fetchVerifyOtpResponse) + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/contractnote/ContractNoteParseParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/contractnote/ContractNoteParseParamsTest.kt new file mode 100644 index 0000000..71e01fd --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/contractnote/ContractNoteParseParamsTest.kt @@ -0,0 +1,65 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.contractnote + +import com.cas_parser.api.core.MultipartField +import java.io.InputStream +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class ContractNoteParseParamsTest { + + @Test + fun create() { + ContractNoteParseParams.builder() + .brokerType(ContractNoteParseParams.BrokerType.ZERODHA) + .password("FAXAK2545F") + .pdfFile("JVBERi0xLjQKMSAwIG9iago8PAovVHlwZSAvQ2F0YWxvZwo...") + .pdfUrl("https://example.com/contract_note.pdf") + .build() + } + + @Test + fun body() { + val params = + ContractNoteParseParams.builder() + .brokerType(ContractNoteParseParams.BrokerType.ZERODHA) + .password("FAXAK2545F") + .pdfFile("JVBERi0xLjQKMSAwIG9iago8PAovVHlwZSAvQ2F0YWxvZwo...") + .pdfUrl("https://example.com/contract_note.pdf") + .build() + + val body = params._body() + + assertThat(body.filterValues { !it.value.isNull() }) + .usingRecursiveComparison() + // TODO(AssertJ): Replace this and the `mapValues` below with: + // https://github.com/assertj/assertj/issues/3165 + .withEqualsForType( + { a, b -> a.readBytes() contentEquals b.readBytes() }, + InputStream::class.java, + ) + .isEqualTo( + mapOf( + "broker_type" to + MultipartField.of(ContractNoteParseParams.BrokerType.ZERODHA), + "password" to MultipartField.of("FAXAK2545F"), + "pdf_file" to + MultipartField.of("JVBERi0xLjQKMSAwIG9iago8PAovVHlwZSAvQ2F0YWxvZwo..."), + "pdf_url" to MultipartField.of("https://example.com/contract_note.pdf"), + ) + .mapValues { (_, field) -> + field.map { (it as? ByteArray)?.inputStream() ?: it } + } + ) + } + + @Test + fun bodyWithoutOptionalFields() { + val params = ContractNoteParseParams.builder().build() + + val body = params._body() + + assertThat(body.filterValues { !it.value.isNull() }).isEmpty() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/contractnote/ContractNoteParseResponseTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/contractnote/ContractNoteParseResponseTest.kt new file mode 100644 index 0000000..9d524f4 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/contractnote/ContractNoteParseResponseTest.kt @@ -0,0 +1,304 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.contractnote + +import com.cas_parser.api.core.jsonMapper +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import java.time.LocalDate +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class ContractNoteParseResponseTest { + + @Test + fun create() { + val contractNoteParseResponse = + ContractNoteParseResponse.builder() + .data( + ContractNoteParseResponse.Data.builder() + .brokerInfo( + ContractNoteParseResponse.Data.BrokerInfo.builder() + .brokerType( + ContractNoteParseResponse.Data.BrokerInfo.BrokerType.ZERODHA + ) + .name("Zerodha Broking Limited") + .sebiRegistration("INZ000031633") + .build() + ) + .chargesSummary( + ContractNoteParseResponse.Data.ChargesSummary.builder() + .cgst(0.0f) + .exchangeTransactionCharges(0.0f) + .igst(0.0f) + .netAmountReceivablePayable(0.0f) + .payInPayOutObligation(0.0f) + .sebiTurnoverFees(0.0f) + .securitiesTransactionTax(0.0f) + .sgst(0.0f) + .stampDuty(0.0f) + .taxableValueBrokerage(0.0f) + .build() + ) + .clientInfo( + ContractNoteParseResponse.Data.ClientInfo.builder() + .address("address") + .gstStateCode("7") + .name("VIRENDER KUMAR") + .pan("FAXAK2545F") + .placeOfSupply("DELHI") + .ucc("YS3654") + .build() + ) + .contractNoteInfo( + ContractNoteParseResponse.Data.ContractNoteInfo.builder() + .contractNoteNumber("CNT-25/26-73436720") + .settlementDate(LocalDate.parse("2025-08-06")) + .settlementNumber("2025149") + .tradeDate(LocalDate.parse("2025-08-05")) + .build() + ) + .addDerivativesTransaction( + ContractNoteParseResponse.Data.DerivativesTransaction.builder() + .brokeragePerUnit(0.0f) + .buySellBfCf("B") + .closingRatePerUnit(0.0f) + .contractDescription("NIFTY24802410DPE") + .netTotal(0.0f) + .quantity(0.0f) + .wapPerUnit(0.0f) + .build() + ) + .addDetailedTrade( + ContractNoteParseResponse.Data.DetailedTrade.builder() + .brokerage(0.0f) + .buySell("B") + .closingRatePerUnit(0.0f) + .exchange("NSE") + .netRatePerUnit(0.0f) + .netTotal(0.0f) + .orderNumber("1000000042939390") + .orderTime("13:13:13") + .quantity(0.0f) + .remarks("remarks") + .securityDescription("CASTROLIND-EQ/INE172A01027") + .tradeNumber("4006567") + .tradeTime("13:13:13") + .build() + ) + .addEquityTransaction( + ContractNoteParseResponse.Data.EquityTransaction.builder() + .buyQuantity(0.0f) + .buyTotalValue(0.0f) + .buyWap(0.0f) + .isin("INE172A01027") + .netObligation(0.0f) + .securityName("CASTROLIND") + .securitySymbol("CASTROLIND") + .sellQuantity(0.0f) + .sellTotalValue(0.0f) + .sellWap(0.0f) + .build() + ) + .build() + ) + .msg("success") + .status("success") + .build() + + assertThat(contractNoteParseResponse.data()) + .contains( + ContractNoteParseResponse.Data.builder() + .brokerInfo( + ContractNoteParseResponse.Data.BrokerInfo.builder() + .brokerType( + ContractNoteParseResponse.Data.BrokerInfo.BrokerType.ZERODHA + ) + .name("Zerodha Broking Limited") + .sebiRegistration("INZ000031633") + .build() + ) + .chargesSummary( + ContractNoteParseResponse.Data.ChargesSummary.builder() + .cgst(0.0f) + .exchangeTransactionCharges(0.0f) + .igst(0.0f) + .netAmountReceivablePayable(0.0f) + .payInPayOutObligation(0.0f) + .sebiTurnoverFees(0.0f) + .securitiesTransactionTax(0.0f) + .sgst(0.0f) + .stampDuty(0.0f) + .taxableValueBrokerage(0.0f) + .build() + ) + .clientInfo( + ContractNoteParseResponse.Data.ClientInfo.builder() + .address("address") + .gstStateCode("7") + .name("VIRENDER KUMAR") + .pan("FAXAK2545F") + .placeOfSupply("DELHI") + .ucc("YS3654") + .build() + ) + .contractNoteInfo( + ContractNoteParseResponse.Data.ContractNoteInfo.builder() + .contractNoteNumber("CNT-25/26-73436720") + .settlementDate(LocalDate.parse("2025-08-06")) + .settlementNumber("2025149") + .tradeDate(LocalDate.parse("2025-08-05")) + .build() + ) + .addDerivativesTransaction( + ContractNoteParseResponse.Data.DerivativesTransaction.builder() + .brokeragePerUnit(0.0f) + .buySellBfCf("B") + .closingRatePerUnit(0.0f) + .contractDescription("NIFTY24802410DPE") + .netTotal(0.0f) + .quantity(0.0f) + .wapPerUnit(0.0f) + .build() + ) + .addDetailedTrade( + ContractNoteParseResponse.Data.DetailedTrade.builder() + .brokerage(0.0f) + .buySell("B") + .closingRatePerUnit(0.0f) + .exchange("NSE") + .netRatePerUnit(0.0f) + .netTotal(0.0f) + .orderNumber("1000000042939390") + .orderTime("13:13:13") + .quantity(0.0f) + .remarks("remarks") + .securityDescription("CASTROLIND-EQ/INE172A01027") + .tradeNumber("4006567") + .tradeTime("13:13:13") + .build() + ) + .addEquityTransaction( + ContractNoteParseResponse.Data.EquityTransaction.builder() + .buyQuantity(0.0f) + .buyTotalValue(0.0f) + .buyWap(0.0f) + .isin("INE172A01027") + .netObligation(0.0f) + .securityName("CASTROLIND") + .securitySymbol("CASTROLIND") + .sellQuantity(0.0f) + .sellTotalValue(0.0f) + .sellWap(0.0f) + .build() + ) + .build() + ) + assertThat(contractNoteParseResponse.msg()).contains("success") + assertThat(contractNoteParseResponse.status()).contains("success") + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val contractNoteParseResponse = + ContractNoteParseResponse.builder() + .data( + ContractNoteParseResponse.Data.builder() + .brokerInfo( + ContractNoteParseResponse.Data.BrokerInfo.builder() + .brokerType( + ContractNoteParseResponse.Data.BrokerInfo.BrokerType.ZERODHA + ) + .name("Zerodha Broking Limited") + .sebiRegistration("INZ000031633") + .build() + ) + .chargesSummary( + ContractNoteParseResponse.Data.ChargesSummary.builder() + .cgst(0.0f) + .exchangeTransactionCharges(0.0f) + .igst(0.0f) + .netAmountReceivablePayable(0.0f) + .payInPayOutObligation(0.0f) + .sebiTurnoverFees(0.0f) + .securitiesTransactionTax(0.0f) + .sgst(0.0f) + .stampDuty(0.0f) + .taxableValueBrokerage(0.0f) + .build() + ) + .clientInfo( + ContractNoteParseResponse.Data.ClientInfo.builder() + .address("address") + .gstStateCode("7") + .name("VIRENDER KUMAR") + .pan("FAXAK2545F") + .placeOfSupply("DELHI") + .ucc("YS3654") + .build() + ) + .contractNoteInfo( + ContractNoteParseResponse.Data.ContractNoteInfo.builder() + .contractNoteNumber("CNT-25/26-73436720") + .settlementDate(LocalDate.parse("2025-08-06")) + .settlementNumber("2025149") + .tradeDate(LocalDate.parse("2025-08-05")) + .build() + ) + .addDerivativesTransaction( + ContractNoteParseResponse.Data.DerivativesTransaction.builder() + .brokeragePerUnit(0.0f) + .buySellBfCf("B") + .closingRatePerUnit(0.0f) + .contractDescription("NIFTY24802410DPE") + .netTotal(0.0f) + .quantity(0.0f) + .wapPerUnit(0.0f) + .build() + ) + .addDetailedTrade( + ContractNoteParseResponse.Data.DetailedTrade.builder() + .brokerage(0.0f) + .buySell("B") + .closingRatePerUnit(0.0f) + .exchange("NSE") + .netRatePerUnit(0.0f) + .netTotal(0.0f) + .orderNumber("1000000042939390") + .orderTime("13:13:13") + .quantity(0.0f) + .remarks("remarks") + .securityDescription("CASTROLIND-EQ/INE172A01027") + .tradeNumber("4006567") + .tradeTime("13:13:13") + .build() + ) + .addEquityTransaction( + ContractNoteParseResponse.Data.EquityTransaction.builder() + .buyQuantity(0.0f) + .buyTotalValue(0.0f) + .buyWap(0.0f) + .isin("INE172A01027") + .netObligation(0.0f) + .securityName("CASTROLIND") + .securitySymbol("CASTROLIND") + .sellQuantity(0.0f) + .sellTotalValue(0.0f) + .sellWap(0.0f) + .build() + ) + .build() + ) + .msg("success") + .status("success") + .build() + + val roundtrippedContractNoteParseResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(contractNoteParseResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedContractNoteParseResponse).isEqualTo(contractNoteParseResponse) + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/credits/CreditCheckParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/credits/CreditCheckParamsTest.kt new file mode 100644 index 0000000..b26664b --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/credits/CreditCheckParamsTest.kt @@ -0,0 +1,13 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.credits + +import org.junit.jupiter.api.Test + +internal class CreditCheckParamsTest { + + @Test + fun create() { + CreditCheckParams.builder().build() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/credits/CreditCheckResponseTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/credits/CreditCheckResponseTest.kt new file mode 100644 index 0000000..17d52f9 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/credits/CreditCheckResponseTest.kt @@ -0,0 +1,61 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.credits + +import com.cas_parser.api.core.jsonMapper +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import java.time.OffsetDateTime +import kotlin.jvm.optionals.getOrNull +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class CreditCheckResponseTest { + + @Test + fun create() { + val creditCheckResponse = + CreditCheckResponse.builder() + .enabledFeatures( + listOf("cams_kfintech_cas_parser", "cdsl_cas_parser", "nsdl_cas_parser") + ) + .isUnlimited(false) + .limit(50L) + .remaining(35.0) + .resetsAt(OffsetDateTime.parse("2026-02-15T00:00:00Z")) + .used(15.0) + .build() + + assertThat(creditCheckResponse.enabledFeatures().getOrNull()) + .containsExactly("cams_kfintech_cas_parser", "cdsl_cas_parser", "nsdl_cas_parser") + assertThat(creditCheckResponse.isUnlimited()).contains(false) + assertThat(creditCheckResponse.limit()).contains(50L) + assertThat(creditCheckResponse.remaining()).contains(35.0) + assertThat(creditCheckResponse.resetsAt()) + .contains(OffsetDateTime.parse("2026-02-15T00:00:00Z")) + assertThat(creditCheckResponse.used()).contains(15.0) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val creditCheckResponse = + CreditCheckResponse.builder() + .enabledFeatures( + listOf("cams_kfintech_cas_parser", "cdsl_cas_parser", "nsdl_cas_parser") + ) + .isUnlimited(false) + .limit(50L) + .remaining(35.0) + .resetsAt(OffsetDateTime.parse("2026-02-15T00:00:00Z")) + .used(15.0) + .build() + + val roundtrippedCreditCheckResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(creditCheckResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedCreditCheckResponse).isEqualTo(creditCheckResponse) + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inbox/InboxCheckConnectionStatusParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inbox/InboxCheckConnectionStatusParamsTest.kt new file mode 100644 index 0000000..082807a --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inbox/InboxCheckConnectionStatusParamsTest.kt @@ -0,0 +1,25 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.inbox + +import com.cas_parser.api.core.http.Headers +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class InboxCheckConnectionStatusParamsTest { + + @Test + fun create() { + InboxCheckConnectionStatusParams.builder().xInboxToken("x-inbox-token").build() + } + + @Test + fun headers() { + val params = InboxCheckConnectionStatusParams.builder().xInboxToken("x-inbox-token").build() + + val headers = params._headers() + + assertThat(headers) + .isEqualTo(Headers.builder().put("x-inbox-token", "x-inbox-token").build()) + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inbox/InboxCheckConnectionStatusResponseTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inbox/InboxCheckConnectionStatusResponseTest.kt new file mode 100644 index 0000000..1c78969 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inbox/InboxCheckConnectionStatusResponseTest.kt @@ -0,0 +1,48 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.inbox + +import com.cas_parser.api.core.jsonMapper +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class InboxCheckConnectionStatusResponseTest { + + @Test + fun create() { + val inboxCheckConnectionStatusResponse = + InboxCheckConnectionStatusResponse.builder() + .connected(true) + .email("user@gmail.com") + .provider("gmail") + .status("success") + .build() + + assertThat(inboxCheckConnectionStatusResponse.connected()).contains(true) + assertThat(inboxCheckConnectionStatusResponse.email()).contains("user@gmail.com") + assertThat(inboxCheckConnectionStatusResponse.provider()).contains("gmail") + assertThat(inboxCheckConnectionStatusResponse.status()).contains("success") + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val inboxCheckConnectionStatusResponse = + InboxCheckConnectionStatusResponse.builder() + .connected(true) + .email("user@gmail.com") + .provider("gmail") + .status("success") + .build() + + val roundtrippedInboxCheckConnectionStatusResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(inboxCheckConnectionStatusResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedInboxCheckConnectionStatusResponse) + .isEqualTo(inboxCheckConnectionStatusResponse) + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inbox/InboxConnectEmailParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inbox/InboxConnectEmailParamsTest.kt new file mode 100644 index 0000000..568051f --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inbox/InboxConnectEmailParamsTest.kt @@ -0,0 +1,43 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.inbox + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class InboxConnectEmailParamsTest { + + @Test + fun create() { + InboxConnectEmailParams.builder() + .redirectUri("https://yourapp.com/oauth-callback") + .state("abc123") + .build() + } + + @Test + fun body() { + val params = + InboxConnectEmailParams.builder() + .redirectUri("https://yourapp.com/oauth-callback") + .state("abc123") + .build() + + val body = params._body() + + assertThat(body.redirectUri()).isEqualTo("https://yourapp.com/oauth-callback") + assertThat(body.state()).contains("abc123") + } + + @Test + fun bodyWithoutOptionalFields() { + val params = + InboxConnectEmailParams.builder() + .redirectUri("https://yourapp.com/oauth-callback") + .build() + + val body = params._body() + + assertThat(body.redirectUri()).isEqualTo("https://yourapp.com/oauth-callback") + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inbox/InboxConnectEmailResponseTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inbox/InboxConnectEmailResponseTest.kt new file mode 100644 index 0000000..2a2f511 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inbox/InboxConnectEmailResponseTest.kt @@ -0,0 +1,45 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.inbox + +import com.cas_parser.api.core.jsonMapper +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class InboxConnectEmailResponseTest { + + @Test + fun create() { + val inboxConnectEmailResponse = + InboxConnectEmailResponse.builder() + .expiresIn(600L) + .oauthUrl("https://accounts.google.com/o/oauth2/v2/auth?client_id=...") + .status("success") + .build() + + assertThat(inboxConnectEmailResponse.expiresIn()).contains(600L) + assertThat(inboxConnectEmailResponse.oauthUrl()) + .contains("https://accounts.google.com/o/oauth2/v2/auth?client_id=...") + assertThat(inboxConnectEmailResponse.status()).contains("success") + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val inboxConnectEmailResponse = + InboxConnectEmailResponse.builder() + .expiresIn(600L) + .oauthUrl("https://accounts.google.com/o/oauth2/v2/auth?client_id=...") + .status("success") + .build() + + val roundtrippedInboxConnectEmailResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(inboxConnectEmailResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedInboxConnectEmailResponse).isEqualTo(inboxConnectEmailResponse) + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inbox/InboxDisconnectEmailParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inbox/InboxDisconnectEmailParamsTest.kt new file mode 100644 index 0000000..90269ad --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inbox/InboxDisconnectEmailParamsTest.kt @@ -0,0 +1,25 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.inbox + +import com.cas_parser.api.core.http.Headers +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class InboxDisconnectEmailParamsTest { + + @Test + fun create() { + InboxDisconnectEmailParams.builder().xInboxToken("x-inbox-token").build() + } + + @Test + fun headers() { + val params = InboxDisconnectEmailParams.builder().xInboxToken("x-inbox-token").build() + + val headers = params._headers() + + assertThat(headers) + .isEqualTo(Headers.builder().put("x-inbox-token", "x-inbox-token").build()) + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inbox/InboxDisconnectEmailResponseTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inbox/InboxDisconnectEmailResponseTest.kt new file mode 100644 index 0000000..ea186c6 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inbox/InboxDisconnectEmailResponseTest.kt @@ -0,0 +1,41 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.inbox + +import com.cas_parser.api.core.jsonMapper +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class InboxDisconnectEmailResponseTest { + + @Test + fun create() { + val inboxDisconnectEmailResponse = + InboxDisconnectEmailResponse.builder() + .msg("Email disconnected successfully") + .status("success") + .build() + + assertThat(inboxDisconnectEmailResponse.msg()).contains("Email disconnected successfully") + assertThat(inboxDisconnectEmailResponse.status()).contains("success") + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val inboxDisconnectEmailResponse = + InboxDisconnectEmailResponse.builder() + .msg("Email disconnected successfully") + .status("success") + .build() + + val roundtrippedInboxDisconnectEmailResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(inboxDisconnectEmailResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedInboxDisconnectEmailResponse).isEqualTo(inboxDisconnectEmailResponse) + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesParamsTest.kt new file mode 100644 index 0000000..1d56f77 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesParamsTest.kt @@ -0,0 +1,79 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.inbox + +import com.cas_parser.api.core.http.Headers +import java.time.LocalDate +import kotlin.jvm.optionals.getOrNull +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class InboxListCasFilesParamsTest { + + @Test + fun create() { + InboxListCasFilesParams.builder() + .xInboxToken("x-inbox-token") + .addCasType(InboxListCasFilesParams.CasType.CDSL) + .addCasType(InboxListCasFilesParams.CasType.NSDL) + .endDate(LocalDate.parse("2025-12-31")) + .startDate(LocalDate.parse("2025-12-01")) + .build() + } + + @Test + fun headers() { + val params = + InboxListCasFilesParams.builder() + .xInboxToken("x-inbox-token") + .addCasType(InboxListCasFilesParams.CasType.CDSL) + .addCasType(InboxListCasFilesParams.CasType.NSDL) + .endDate(LocalDate.parse("2025-12-31")) + .startDate(LocalDate.parse("2025-12-01")) + .build() + + val headers = params._headers() + + assertThat(headers) + .isEqualTo(Headers.builder().put("x-inbox-token", "x-inbox-token").build()) + } + + @Test + fun headersWithoutOptionalFields() { + val params = InboxListCasFilesParams.builder().xInboxToken("x-inbox-token").build() + + val headers = params._headers() + + assertThat(headers) + .isEqualTo(Headers.builder().put("x-inbox-token", "x-inbox-token").build()) + } + + @Test + fun body() { + val params = + InboxListCasFilesParams.builder() + .xInboxToken("x-inbox-token") + .addCasType(InboxListCasFilesParams.CasType.CDSL) + .addCasType(InboxListCasFilesParams.CasType.NSDL) + .endDate(LocalDate.parse("2025-12-31")) + .startDate(LocalDate.parse("2025-12-01")) + .build() + + val body = params._body() + + assertThat(body.casTypes().getOrNull()) + .containsExactly( + InboxListCasFilesParams.CasType.CDSL, + InboxListCasFilesParams.CasType.NSDL, + ) + assertThat(body.endDate()).contains(LocalDate.parse("2025-12-31")) + assertThat(body.startDate()).contains(LocalDate.parse("2025-12-01")) + } + + @Test + fun bodyWithoutOptionalFields() { + val params = InboxListCasFilesParams.builder().xInboxToken("x-inbox-token").build() + + val body = params._body() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesResponseTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesResponseTest.kt new file mode 100644 index 0000000..1f710cb --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesResponseTest.kt @@ -0,0 +1,84 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.inbox + +import com.cas_parser.api.core.jsonMapper +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import java.time.LocalDate +import kotlin.jvm.optionals.getOrNull +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class InboxListCasFilesResponseTest { + + @Test + fun create() { + val inboxListCasFilesResponse = + InboxListCasFilesResponse.builder() + .count(5L) + .addFile( + InboxListCasFilesResponse.File.builder() + .casType(InboxListCasFilesResponse.File.CasType.CDSL) + .expiresIn(86400L) + .filename("cdsl_20250115_a1b2c3d4.pdf") + .messageDate(LocalDate.parse("2025-01-15")) + .messageId("18d4a2b3c4d5e6f7") + .originalFilename("CDSL_CAS_Statement.pdf") + .size(245000L) + .url( + "https://cdn.casparser.in/email-cas/user123/cdsl_20250115_a1b2c3d4.pdf" + ) + .build() + ) + .status("success") + .build() + + assertThat(inboxListCasFilesResponse.count()).contains(5L) + assertThat(inboxListCasFilesResponse.files().getOrNull()) + .containsExactly( + InboxListCasFilesResponse.File.builder() + .casType(InboxListCasFilesResponse.File.CasType.CDSL) + .expiresIn(86400L) + .filename("cdsl_20250115_a1b2c3d4.pdf") + .messageDate(LocalDate.parse("2025-01-15")) + .messageId("18d4a2b3c4d5e6f7") + .originalFilename("CDSL_CAS_Statement.pdf") + .size(245000L) + .url("https://cdn.casparser.in/email-cas/user123/cdsl_20250115_a1b2c3d4.pdf") + .build() + ) + assertThat(inboxListCasFilesResponse.status()).contains("success") + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val inboxListCasFilesResponse = + InboxListCasFilesResponse.builder() + .count(5L) + .addFile( + InboxListCasFilesResponse.File.builder() + .casType(InboxListCasFilesResponse.File.CasType.CDSL) + .expiresIn(86400L) + .filename("cdsl_20250115_a1b2c3d4.pdf") + .messageDate(LocalDate.parse("2025-01-15")) + .messageId("18d4a2b3c4d5e6f7") + .originalFilename("CDSL_CAS_Statement.pdf") + .size(245000L) + .url( + "https://cdn.casparser.in/email-cas/user123/cdsl_20250115_a1b2c3d4.pdf" + ) + .build() + ) + .status("success") + .build() + + val roundtrippedInboxListCasFilesResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(inboxListCasFilesResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedInboxListCasFilesResponse).isEqualTo(inboxListCasFilesResponse) + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/kfintech/KfintechGenerateCasParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/kfintech/KfintechGenerateCasParamsTest.kt new file mode 100644 index 0000000..bed6b13 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/kfintech/KfintechGenerateCasParamsTest.kt @@ -0,0 +1,58 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.kfintech + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class KfintechGenerateCasParamsTest { + + @Test + fun create() { + KfintechGenerateCasParams.builder() + .email("user@example.com") + .fromDate("2023-01-01") + .password("Abcdefghi12\$") + .toDate("2023-12-31") + .panNo("ABCDE1234F") + .build() + } + + @Test + fun body() { + val params = + KfintechGenerateCasParams.builder() + .email("user@example.com") + .fromDate("2023-01-01") + .password("Abcdefghi12\$") + .toDate("2023-12-31") + .panNo("ABCDE1234F") + .build() + + val body = params._body() + + assertThat(body.email()).isEqualTo("user@example.com") + assertThat(body.fromDate()).isEqualTo("2023-01-01") + assertThat(body.password()).isEqualTo("Abcdefghi12\$") + assertThat(body.toDate()).isEqualTo("2023-12-31") + assertThat(body.panNo()).contains("ABCDE1234F") + } + + @Test + fun bodyWithoutOptionalFields() { + val params = + KfintechGenerateCasParams.builder() + .email("user@example.com") + .fromDate("2023-01-01") + .password("Abcdefghi12\$") + .toDate("2023-12-31") + .build() + + val body = params._body() + + assertThat(body.email()).isEqualTo("user@example.com") + assertThat(body.fromDate()).isEqualTo("2023-01-01") + assertThat(body.password()).isEqualTo("Abcdefghi12\$") + assertThat(body.toDate()).isEqualTo("2023-12-31") + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/kfintech/KfintechGenerateCasResponseTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/kfintech/KfintechGenerateCasResponseTest.kt new file mode 100644 index 0000000..57b2d09 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/kfintech/KfintechGenerateCasResponseTest.kt @@ -0,0 +1,42 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.kfintech + +import com.cas_parser.api.core.jsonMapper +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class KfintechGenerateCasResponseTest { + + @Test + fun create() { + val kfintechGenerateCasResponse = + KfintechGenerateCasResponse.builder() + .msg("CAS request submitted. Check email shortly.") + .status("success") + .build() + + assertThat(kfintechGenerateCasResponse.msg()) + .contains("CAS request submitted. Check email shortly.") + assertThat(kfintechGenerateCasResponse.status()).contains("success") + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val kfintechGenerateCasResponse = + KfintechGenerateCasResponse.builder() + .msg("CAS request submitted. Check email shortly.") + .status("success") + .build() + + val roundtrippedKfintechGenerateCasResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(kfintechGenerateCasResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedKfintechGenerateCasResponse).isEqualTo(kfintechGenerateCasResponse) + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogCreateParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogCreateParamsTest.kt new file mode 100644 index 0000000..e7212ba --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogCreateParamsTest.kt @@ -0,0 +1,42 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.logs + +import java.time.OffsetDateTime +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class LogCreateParamsTest { + + @Test + fun create() { + LogCreateParams.builder() + .endTime(OffsetDateTime.parse("2026-01-31T23:59:59Z")) + .limit(1L) + .startTime(OffsetDateTime.parse("2026-01-01T00:00:00Z")) + .build() + } + + @Test + fun body() { + val params = + LogCreateParams.builder() + .endTime(OffsetDateTime.parse("2026-01-31T23:59:59Z")) + .limit(1L) + .startTime(OffsetDateTime.parse("2026-01-01T00:00:00Z")) + .build() + + val body = params._body() + + assertThat(body.endTime()).contains(OffsetDateTime.parse("2026-01-31T23:59:59Z")) + assertThat(body.limit()).contains(1L) + assertThat(body.startTime()).contains(OffsetDateTime.parse("2026-01-01T00:00:00Z")) + } + + @Test + fun bodyWithoutOptionalFields() { + val params = LogCreateParams.builder().build() + + val body = params._body() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogCreateResponseTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogCreateResponseTest.kt new file mode 100644 index 0000000..0f24a21 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogCreateResponseTest.kt @@ -0,0 +1,74 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.logs + +import com.cas_parser.api.core.jsonMapper +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import java.time.OffsetDateTime +import kotlin.jvm.optionals.getOrNull +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class LogCreateResponseTest { + + @Test + fun create() { + val logCreateResponse = + LogCreateResponse.builder() + .count(25L) + .addLog( + LogCreateResponse.Log.builder() + .credits(1.0) + .feature("cdsl_cas_parser") + .path("/v4/cdsl/parse") + .requestId("req_2xYz7KpL8mN3Ab") + .statusCode(200L) + .timestamp(OffsetDateTime.parse("2026-01-15T14:30:00Z")) + .build() + ) + .status("success") + .build() + + assertThat(logCreateResponse.count()).contains(25L) + assertThat(logCreateResponse.logs().getOrNull()) + .containsExactly( + LogCreateResponse.Log.builder() + .credits(1.0) + .feature("cdsl_cas_parser") + .path("/v4/cdsl/parse") + .requestId("req_2xYz7KpL8mN3Ab") + .statusCode(200L) + .timestamp(OffsetDateTime.parse("2026-01-15T14:30:00Z")) + .build() + ) + assertThat(logCreateResponse.status()).contains("success") + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val logCreateResponse = + LogCreateResponse.builder() + .count(25L) + .addLog( + LogCreateResponse.Log.builder() + .credits(1.0) + .feature("cdsl_cas_parser") + .path("/v4/cdsl/parse") + .requestId("req_2xYz7KpL8mN3Ab") + .statusCode(200L) + .timestamp(OffsetDateTime.parse("2026-01-15T14:30:00Z")) + .build() + ) + .status("success") + .build() + + val roundtrippedLogCreateResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(logCreateResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedLogCreateResponse).isEqualTo(logCreateResponse) + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogGetSummaryParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogGetSummaryParamsTest.kt new file mode 100644 index 0000000..a2cfd4a --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogGetSummaryParamsTest.kt @@ -0,0 +1,39 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.logs + +import java.time.OffsetDateTime +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class LogGetSummaryParamsTest { + + @Test + fun create() { + LogGetSummaryParams.builder() + .endTime(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .startTime(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .build() + } + + @Test + fun body() { + val params = + LogGetSummaryParams.builder() + .endTime(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .startTime(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .build() + + val body = params._body() + + assertThat(body.endTime()).contains(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + assertThat(body.startTime()).contains(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + } + + @Test + fun bodyWithoutOptionalFields() { + val params = LogGetSummaryParams.builder().build() + + val body = params._body() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogGetSummaryResponseTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogGetSummaryResponseTest.kt new file mode 100644 index 0000000..94e8bc7 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogGetSummaryResponseTest.kt @@ -0,0 +1,78 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.logs + +import com.cas_parser.api.core.jsonMapper +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class LogGetSummaryResponseTest { + + @Test + fun create() { + val logGetSummaryResponse = + LogGetSummaryResponse.builder() + .status("success") + .summary( + LogGetSummaryResponse.Summary.builder() + .addByFeature( + LogGetSummaryResponse.Summary.ByFeature.builder() + .credits(15.0) + .feature("cdsl_cas_parser") + .requests(15L) + .build() + ) + .totalCredits(45.5) + .totalRequests(42L) + .build() + ) + .build() + + assertThat(logGetSummaryResponse.status()).contains("success") + assertThat(logGetSummaryResponse.summary()) + .contains( + LogGetSummaryResponse.Summary.builder() + .addByFeature( + LogGetSummaryResponse.Summary.ByFeature.builder() + .credits(15.0) + .feature("cdsl_cas_parser") + .requests(15L) + .build() + ) + .totalCredits(45.5) + .totalRequests(42L) + .build() + ) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val logGetSummaryResponse = + LogGetSummaryResponse.builder() + .status("success") + .summary( + LogGetSummaryResponse.Summary.builder() + .addByFeature( + LogGetSummaryResponse.Summary.ByFeature.builder() + .credits(15.0) + .feature("cdsl_cas_parser") + .requests(15L) + .build() + ) + .totalCredits(45.5) + .totalRequests(42L) + .build() + ) + .build() + + val roundtrippedLogGetSummaryResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(logGetSummaryResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedLogGetSummaryResponse).isEqualTo(logGetSummaryResponse) + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserCdslParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/nsdl/NsdlParseParamsTest.kt similarity index 87% rename from cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserCdslParamsTest.kt rename to cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/nsdl/NsdlParseParamsTest.kt index 6293280..a7631d5 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserCdslParamsTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/nsdl/NsdlParseParamsTest.kt @@ -1,17 +1,17 @@ // File generated from our OpenAPI spec by Stainless. -package com.cas_parser.api.models.casparser +package com.cas_parser.api.models.nsdl import com.cas_parser.api.core.MultipartField import java.io.InputStream import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -internal class CasParserCdslParamsTest { +internal class NsdlParseParamsTest { @Test fun create() { - CasParserCdslParams.builder() + NsdlParseParams.builder() .password("password") .pdfFile("pdf_file") .pdfUrl("https://example.com") @@ -21,7 +21,7 @@ internal class CasParserCdslParamsTest { @Test fun body() { val params = - CasParserCdslParams.builder() + NsdlParseParams.builder() .password("password") .pdfFile("pdf_file") .pdfUrl("https://example.com") @@ -51,7 +51,7 @@ internal class CasParserCdslParamsTest { @Test fun bodyWithoutOptionalFields() { - val params = CasParserCdslParams.builder().build() + val params = NsdlParseParams.builder().build() val body = params._body() diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserCamsKfintechParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/smart/SmartParseCasPdfParamsTest.kt similarity index 86% rename from cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserCamsKfintechParamsTest.kt rename to cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/smart/SmartParseCasPdfParamsTest.kt index 7fd81ef..1c1b2c2 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/casparser/CasParserCamsKfintechParamsTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/smart/SmartParseCasPdfParamsTest.kt @@ -1,17 +1,17 @@ // File generated from our OpenAPI spec by Stainless. -package com.cas_parser.api.models.casparser +package com.cas_parser.api.models.smart import com.cas_parser.api.core.MultipartField import java.io.InputStream import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -internal class CasParserCamsKfintechParamsTest { +internal class SmartParseCasPdfParamsTest { @Test fun create() { - CasParserCamsKfintechParams.builder() + SmartParseCasPdfParams.builder() .password("password") .pdfFile("pdf_file") .pdfUrl("https://example.com") @@ -21,7 +21,7 @@ internal class CasParserCamsKfintechParamsTest { @Test fun body() { val params = - CasParserCamsKfintechParams.builder() + SmartParseCasPdfParams.builder() .password("password") .pdfFile("pdf_file") .pdfUrl("https://example.com") @@ -51,7 +51,7 @@ internal class CasParserCamsKfintechParamsTest { @Test fun bodyWithoutOptionalFields() { - val params = CasParserCamsKfintechParams.builder().build() + val params = SmartParseCasPdfParams.builder().build() val body = params._body() diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyParamsTest.kt new file mode 100644 index 0000000..6e75d40 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyParamsTest.kt @@ -0,0 +1,13 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.verifytoken + +import org.junit.jupiter.api.Test + +internal class VerifyTokenVerifyParamsTest { + + @Test + fun create() { + VerifyTokenVerifyParams.builder().build() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyResponseTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyResponseTest.kt new file mode 100644 index 0000000..813bc45 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyResponseTest.kt @@ -0,0 +1,44 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.verifytoken + +import com.cas_parser.api.core.jsonMapper +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class VerifyTokenVerifyResponseTest { + + @Test + fun create() { + val verifyTokenVerifyResponse = + VerifyTokenVerifyResponse.builder() + .error("Token has expired") + .maskedApiKey("abc1****ef23") + .valid(true) + .build() + + assertThat(verifyTokenVerifyResponse.error()).contains("Token has expired") + assertThat(verifyTokenVerifyResponse.maskedApiKey()).contains("abc1****ef23") + assertThat(verifyTokenVerifyResponse.valid()).contains(true) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val verifyTokenVerifyResponse = + VerifyTokenVerifyResponse.builder() + .error("Token has expired") + .maskedApiKey("abc1****ef23") + .valid(true) + .build() + + val roundtrippedVerifyTokenVerifyResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(verifyTokenVerifyResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedVerifyTokenVerifyResponse).isEqualTo(verifyTokenVerifyResponse) + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/ErrorHandlingTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/ErrorHandlingTest.kt index 71fb9b3..f58190a 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/ErrorHandlingTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/ErrorHandlingTest.kt @@ -16,7 +16,6 @@ import com.cas_parser.api.errors.RateLimitException import com.cas_parser.api.errors.UnauthorizedException import com.cas_parser.api.errors.UnexpectedStatusCodeException import com.cas_parser.api.errors.UnprocessableEntityException -import com.cas_parser.api.models.casparser.CasParserSmartParseParams import com.github.tomakehurst.wiremock.client.WireMock.anyUrl import com.github.tomakehurst.wiremock.client.WireMock.post import com.github.tomakehurst.wiremock.client.WireMock.status @@ -59,8 +58,8 @@ internal class ErrorHandlingTest { } @Test - fun casParserSmartParse400() { - val casParserService = client.casParser() + fun creditsCheck400() { + val creditService = client.credits() stubFor( post(anyUrl()) .willReturn( @@ -68,16 +67,7 @@ internal class ErrorHandlingTest { ) ) - val e = - assertThrows { - casParserService.smartParse( - CasParserSmartParseParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - } + val e = assertThrows { creditService.check() } assertThat(e.statusCode()).isEqualTo(400) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -85,8 +75,8 @@ internal class ErrorHandlingTest { } @Test - fun casParserSmartParse400WithRawResponse() { - val casParserService = client.casParser().withRawResponse() + fun creditsCheck400WithRawResponse() { + val creditService = client.credits().withRawResponse() stubFor( post(anyUrl()) .willReturn( @@ -94,16 +84,7 @@ internal class ErrorHandlingTest { ) ) - val e = - assertThrows { - casParserService.smartParse( - CasParserSmartParseParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - } + val e = assertThrows { creditService.check() } assertThat(e.statusCode()).isEqualTo(400) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -111,8 +92,8 @@ internal class ErrorHandlingTest { } @Test - fun casParserSmartParse401() { - val casParserService = client.casParser() + fun creditsCheck401() { + val creditService = client.credits() stubFor( post(anyUrl()) .willReturn( @@ -120,16 +101,7 @@ internal class ErrorHandlingTest { ) ) - val e = - assertThrows { - casParserService.smartParse( - CasParserSmartParseParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - } + val e = assertThrows { creditService.check() } assertThat(e.statusCode()).isEqualTo(401) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -137,8 +109,8 @@ internal class ErrorHandlingTest { } @Test - fun casParserSmartParse401WithRawResponse() { - val casParserService = client.casParser().withRawResponse() + fun creditsCheck401WithRawResponse() { + val creditService = client.credits().withRawResponse() stubFor( post(anyUrl()) .willReturn( @@ -146,16 +118,7 @@ internal class ErrorHandlingTest { ) ) - val e = - assertThrows { - casParserService.smartParse( - CasParserSmartParseParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - } + val e = assertThrows { creditService.check() } assertThat(e.statusCode()).isEqualTo(401) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -163,8 +126,8 @@ internal class ErrorHandlingTest { } @Test - fun casParserSmartParse403() { - val casParserService = client.casParser() + fun creditsCheck403() { + val creditService = client.credits() stubFor( post(anyUrl()) .willReturn( @@ -172,16 +135,7 @@ internal class ErrorHandlingTest { ) ) - val e = - assertThrows { - casParserService.smartParse( - CasParserSmartParseParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - } + val e = assertThrows { creditService.check() } assertThat(e.statusCode()).isEqualTo(403) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -189,8 +143,8 @@ internal class ErrorHandlingTest { } @Test - fun casParserSmartParse403WithRawResponse() { - val casParserService = client.casParser().withRawResponse() + fun creditsCheck403WithRawResponse() { + val creditService = client.credits().withRawResponse() stubFor( post(anyUrl()) .willReturn( @@ -198,16 +152,7 @@ internal class ErrorHandlingTest { ) ) - val e = - assertThrows { - casParserService.smartParse( - CasParserSmartParseParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - } + val e = assertThrows { creditService.check() } assertThat(e.statusCode()).isEqualTo(403) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -215,8 +160,8 @@ internal class ErrorHandlingTest { } @Test - fun casParserSmartParse404() { - val casParserService = client.casParser() + fun creditsCheck404() { + val creditService = client.credits() stubFor( post(anyUrl()) .willReturn( @@ -224,16 +169,7 @@ internal class ErrorHandlingTest { ) ) - val e = - assertThrows { - casParserService.smartParse( - CasParserSmartParseParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - } + val e = assertThrows { creditService.check() } assertThat(e.statusCode()).isEqualTo(404) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -241,8 +177,8 @@ internal class ErrorHandlingTest { } @Test - fun casParserSmartParse404WithRawResponse() { - val casParserService = client.casParser().withRawResponse() + fun creditsCheck404WithRawResponse() { + val creditService = client.credits().withRawResponse() stubFor( post(anyUrl()) .willReturn( @@ -250,16 +186,7 @@ internal class ErrorHandlingTest { ) ) - val e = - assertThrows { - casParserService.smartParse( - CasParserSmartParseParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - } + val e = assertThrows { creditService.check() } assertThat(e.statusCode()).isEqualTo(404) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -267,8 +194,8 @@ internal class ErrorHandlingTest { } @Test - fun casParserSmartParse422() { - val casParserService = client.casParser() + fun creditsCheck422() { + val creditService = client.credits() stubFor( post(anyUrl()) .willReturn( @@ -276,16 +203,7 @@ internal class ErrorHandlingTest { ) ) - val e = - assertThrows { - casParserService.smartParse( - CasParserSmartParseParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - } + val e = assertThrows { creditService.check() } assertThat(e.statusCode()).isEqualTo(422) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -293,8 +211,8 @@ internal class ErrorHandlingTest { } @Test - fun casParserSmartParse422WithRawResponse() { - val casParserService = client.casParser().withRawResponse() + fun creditsCheck422WithRawResponse() { + val creditService = client.credits().withRawResponse() stubFor( post(anyUrl()) .willReturn( @@ -302,16 +220,7 @@ internal class ErrorHandlingTest { ) ) - val e = - assertThrows { - casParserService.smartParse( - CasParserSmartParseParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - } + val e = assertThrows { creditService.check() } assertThat(e.statusCode()).isEqualTo(422) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -319,8 +228,8 @@ internal class ErrorHandlingTest { } @Test - fun casParserSmartParse429() { - val casParserService = client.casParser() + fun creditsCheck429() { + val creditService = client.credits() stubFor( post(anyUrl()) .willReturn( @@ -328,16 +237,7 @@ internal class ErrorHandlingTest { ) ) - val e = - assertThrows { - casParserService.smartParse( - CasParserSmartParseParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - } + val e = assertThrows { creditService.check() } assertThat(e.statusCode()).isEqualTo(429) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -345,8 +245,8 @@ internal class ErrorHandlingTest { } @Test - fun casParserSmartParse429WithRawResponse() { - val casParserService = client.casParser().withRawResponse() + fun creditsCheck429WithRawResponse() { + val creditService = client.credits().withRawResponse() stubFor( post(anyUrl()) .willReturn( @@ -354,16 +254,7 @@ internal class ErrorHandlingTest { ) ) - val e = - assertThrows { - casParserService.smartParse( - CasParserSmartParseParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - } + val e = assertThrows { creditService.check() } assertThat(e.statusCode()).isEqualTo(429) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -371,8 +262,8 @@ internal class ErrorHandlingTest { } @Test - fun casParserSmartParse500() { - val casParserService = client.casParser() + fun creditsCheck500() { + val creditService = client.credits() stubFor( post(anyUrl()) .willReturn( @@ -380,16 +271,7 @@ internal class ErrorHandlingTest { ) ) - val e = - assertThrows { - casParserService.smartParse( - CasParserSmartParseParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - } + val e = assertThrows { creditService.check() } assertThat(e.statusCode()).isEqualTo(500) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -397,8 +279,8 @@ internal class ErrorHandlingTest { } @Test - fun casParserSmartParse500WithRawResponse() { - val casParserService = client.casParser().withRawResponse() + fun creditsCheck500WithRawResponse() { + val creditService = client.credits().withRawResponse() stubFor( post(anyUrl()) .willReturn( @@ -406,16 +288,7 @@ internal class ErrorHandlingTest { ) ) - val e = - assertThrows { - casParserService.smartParse( - CasParserSmartParseParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - } + val e = assertThrows { creditService.check() } assertThat(e.statusCode()).isEqualTo(500) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -423,8 +296,8 @@ internal class ErrorHandlingTest { } @Test - fun casParserSmartParse999() { - val casParserService = client.casParser() + fun creditsCheck999() { + val creditService = client.credits() stubFor( post(anyUrl()) .willReturn( @@ -432,16 +305,7 @@ internal class ErrorHandlingTest { ) ) - val e = - assertThrows { - casParserService.smartParse( - CasParserSmartParseParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - } + val e = assertThrows { creditService.check() } assertThat(e.statusCode()).isEqualTo(999) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -449,8 +313,8 @@ internal class ErrorHandlingTest { } @Test - fun casParserSmartParse999WithRawResponse() { - val casParserService = client.casParser().withRawResponse() + fun creditsCheck999WithRawResponse() { + val creditService = client.credits().withRawResponse() stubFor( post(anyUrl()) .willReturn( @@ -458,16 +322,7 @@ internal class ErrorHandlingTest { ) ) - val e = - assertThrows { - casParserService.smartParse( - CasParserSmartParseParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - } + val e = assertThrows { creditService.check() } assertThat(e.statusCode()).isEqualTo(999) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -475,23 +330,14 @@ internal class ErrorHandlingTest { } @Test - fun casParserSmartParseInvalidJsonBody() { - val casParserService = client.casParser() + fun creditsCheckInvalidJsonBody() { + val creditService = client.credits() stubFor( post(anyUrl()) .willReturn(status(200).withHeader(HEADER_NAME, HEADER_VALUE).withBody(NOT_JSON)) ) - val e = - assertThrows { - casParserService.smartParse( - CasParserSmartParseParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - } + val e = assertThrows { creditService.check() } assertThat(e).hasMessage("Error reading response") } diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/ServiceParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/ServiceParamsTest.kt index 5454df2..2d2074d 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/ServiceParamsTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/ServiceParamsTest.kt @@ -5,7 +5,7 @@ package com.cas_parser.api.services import com.cas_parser.api.client.CasParserClient import com.cas_parser.api.client.okhttp.CasParserOkHttpClient import com.cas_parser.api.core.JsonValue -import com.cas_parser.api.models.casparser.CasParserSmartParseParams +import com.cas_parser.api.models.credits.CreditCheckParams import com.github.tomakehurst.wiremock.client.WireMock.anyUrl import com.github.tomakehurst.wiremock.client.WireMock.equalTo import com.github.tomakehurst.wiremock.client.WireMock.matchingJsonPath @@ -38,15 +38,12 @@ internal class ServiceParamsTest { @Disabled("Prism tests are disabled") @Test - fun smartParse() { - val casParserService = client.casParser() + fun check() { + val creditService = client.credits() stubFor(post(anyUrl()).willReturn(ok("{}"))) - casParserService.smartParse( - CasParserSmartParseParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") + creditService.check( + CreditCheckParams.builder() .putAdditionalHeader("Secret-Header", "42") .putAdditionalQueryParam("secret_query_param", "42") .putAdditionalBodyProperty("secretProperty", JsonValue.from("42")) diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsyncTest.kt new file mode 100644 index 0000000..d1a2caa --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsyncTest.kt @@ -0,0 +1,33 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.TestServerExtension +import com.cas_parser.api.client.okhttp.CasParserOkHttpClientAsync +import com.cas_parser.api.models.accesstoken.AccessTokenCreateParams +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class AccessTokenServiceAsyncTest { + + @Disabled("Prism tests are disabled") + @Test + fun create() { + val client = + CasParserOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val accessTokenServiceAsync = client.accessToken() + + val accessTokenFuture = + accessTokenServiceAsync.create( + AccessTokenCreateParams.builder().expiryMinutes(60L).build() + ) + + val accessToken = accessTokenFuture.get() + accessToken.validate() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CamsKfintechServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CamsKfintechServiceAsyncTest.kt new file mode 100644 index 0000000..2f14e4a --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CamsKfintechServiceAsyncTest.kt @@ -0,0 +1,37 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.TestServerExtension +import com.cas_parser.api.client.okhttp.CasParserOkHttpClientAsync +import com.cas_parser.api.models.camskfintech.CamsKfintechParseParams +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class CamsKfintechServiceAsyncTest { + + @Disabled("Prism tests are disabled") + @Test + fun parse() { + val client = + CasParserOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val camsKfintechServiceAsync = client.camsKfintech() + + val unifiedResponseFuture = + camsKfintechServiceAsync.parse( + CamsKfintechParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + + val unifiedResponse = unifiedResponseFuture.get() + unifiedResponse.validate() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CasParserServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CasParserServiceAsyncTest.kt deleted file mode 100644 index 363c5eb..0000000 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CasParserServiceAsyncTest.kt +++ /dev/null @@ -1,109 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.services.async - -import com.cas_parser.api.TestServerExtension -import com.cas_parser.api.client.okhttp.CasParserOkHttpClientAsync -import com.cas_parser.api.models.casparser.CasParserCamsKfintechParams -import com.cas_parser.api.models.casparser.CasParserCdslParams -import com.cas_parser.api.models.casparser.CasParserNsdlParams -import com.cas_parser.api.models.casparser.CasParserSmartParseParams -import org.junit.jupiter.api.Disabled -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith - -@ExtendWith(TestServerExtension::class) -internal class CasParserServiceAsyncTest { - - @Disabled("Prism tests are disabled") - @Test - fun camsKfintech() { - val client = - CasParserOkHttpClientAsync.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() - val casParserServiceAsync = client.casParser() - - val unifiedResponseFuture = - casParserServiceAsync.camsKfintech( - CasParserCamsKfintechParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - - val unifiedResponse = unifiedResponseFuture.get() - unifiedResponse.validate() - } - - @Disabled("Prism tests are disabled") - @Test - fun cdsl() { - val client = - CasParserOkHttpClientAsync.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() - val casParserServiceAsync = client.casParser() - - val unifiedResponseFuture = - casParserServiceAsync.cdsl( - CasParserCdslParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - - val unifiedResponse = unifiedResponseFuture.get() - unifiedResponse.validate() - } - - @Disabled("Prism tests are disabled") - @Test - fun nsdl() { - val client = - CasParserOkHttpClientAsync.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() - val casParserServiceAsync = client.casParser() - - val unifiedResponseFuture = - casParserServiceAsync.nsdl( - CasParserNsdlParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - - val unifiedResponse = unifiedResponseFuture.get() - unifiedResponse.validate() - } - - @Disabled("Prism tests are disabled") - @Test - fun smartParse() { - val client = - CasParserOkHttpClientAsync.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() - val casParserServiceAsync = client.casParser() - - val unifiedResponseFuture = - casParserServiceAsync.smartParse( - CasParserSmartParseParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - - val unifiedResponse = unifiedResponseFuture.get() - unifiedResponse.validate() - } -} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CdslServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CdslServiceAsyncTest.kt new file mode 100644 index 0000000..36a9797 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CdslServiceAsyncTest.kt @@ -0,0 +1,37 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.TestServerExtension +import com.cas_parser.api.client.okhttp.CasParserOkHttpClientAsync +import com.cas_parser.api.models.cdsl.CdslParsePdfParams +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class CdslServiceAsyncTest { + + @Disabled("Prism tests are disabled") + @Test + fun parsePdf() { + val client = + CasParserOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val cdslServiceAsync = client.cdsl() + + val unifiedResponseFuture = + cdslServiceAsync.parsePdf( + CdslParsePdfParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + + val unifiedResponse = unifiedResponseFuture.get() + unifiedResponse.validate() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/ContractNoteServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/ContractNoteServiceAsyncTest.kt new file mode 100644 index 0000000..8e7907e --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/ContractNoteServiceAsyncTest.kt @@ -0,0 +1,38 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.TestServerExtension +import com.cas_parser.api.client.okhttp.CasParserOkHttpClientAsync +import com.cas_parser.api.models.contractnote.ContractNoteParseParams +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class ContractNoteServiceAsyncTest { + + @Disabled("Prism tests are disabled") + @Test + fun parse() { + val client = + CasParserOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val contractNoteServiceAsync = client.contractNote() + + val responseFuture = + contractNoteServiceAsync.parse( + ContractNoteParseParams.builder() + .brokerType(ContractNoteParseParams.BrokerType.ZERODHA) + .password("FAXAK2545F") + .pdfFile("JVBERi0xLjQKMSAwIG9iago8PAovVHlwZSAvQ2F0YWxvZwo...") + .pdfUrl("https://example.com/contract_note.pdf") + .build() + ) + + val response = responseFuture.get() + response.validate() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CreditServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CreditServiceAsyncTest.kt new file mode 100644 index 0000000..bedb74b --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CreditServiceAsyncTest.kt @@ -0,0 +1,29 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.TestServerExtension +import com.cas_parser.api.client.okhttp.CasParserOkHttpClientAsync +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class CreditServiceAsyncTest { + + @Disabled("Prism tests are disabled") + @Test + fun check() { + val client = + CasParserOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val creditServiceAsync = client.credits() + + val responseFuture = creditServiceAsync.check() + + val response = responseFuture.get() + response.validate() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/InboxServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/InboxServiceAsyncTest.kt new file mode 100644 index 0000000..45759bf --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/InboxServiceAsyncTest.kt @@ -0,0 +1,103 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.TestServerExtension +import com.cas_parser.api.client.okhttp.CasParserOkHttpClientAsync +import com.cas_parser.api.models.inbox.InboxCheckConnectionStatusParams +import com.cas_parser.api.models.inbox.InboxConnectEmailParams +import com.cas_parser.api.models.inbox.InboxDisconnectEmailParams +import com.cas_parser.api.models.inbox.InboxListCasFilesParams +import java.time.LocalDate +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class InboxServiceAsyncTest { + + @Disabled("Prism tests are disabled") + @Test + fun checkConnectionStatus() { + val client = + CasParserOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val inboxServiceAsync = client.inbox() + + val responseFuture = + inboxServiceAsync.checkConnectionStatus( + InboxCheckConnectionStatusParams.builder().xInboxToken("x-inbox-token").build() + ) + + val response = responseFuture.get() + response.validate() + } + + @Disabled("Prism tests are disabled") + @Test + fun connectEmail() { + val client = + CasParserOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val inboxServiceAsync = client.inbox() + + val responseFuture = + inboxServiceAsync.connectEmail( + InboxConnectEmailParams.builder() + .redirectUri("https://yourapp.com/oauth-callback") + .state("abc123") + .build() + ) + + val response = responseFuture.get() + response.validate() + } + + @Disabled("Prism tests are disabled") + @Test + fun disconnectEmail() { + val client = + CasParserOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val inboxServiceAsync = client.inbox() + + val responseFuture = + inboxServiceAsync.disconnectEmail( + InboxDisconnectEmailParams.builder().xInboxToken("x-inbox-token").build() + ) + + val response = responseFuture.get() + response.validate() + } + + @Disabled("Prism tests are disabled") + @Test + fun listCasFiles() { + val client = + CasParserOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val inboxServiceAsync = client.inbox() + + val responseFuture = + inboxServiceAsync.listCasFiles( + InboxListCasFilesParams.builder() + .xInboxToken("x-inbox-token") + .addCasType(InboxListCasFilesParams.CasType.CDSL) + .addCasType(InboxListCasFilesParams.CasType.NSDL) + .endDate(LocalDate.parse("2025-12-31")) + .startDate(LocalDate.parse("2025-12-01")) + .build() + ) + + val response = responseFuture.get() + response.validate() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/KfintechServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/KfintechServiceAsyncTest.kt new file mode 100644 index 0000000..8409abc --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/KfintechServiceAsyncTest.kt @@ -0,0 +1,39 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.TestServerExtension +import com.cas_parser.api.client.okhttp.CasParserOkHttpClientAsync +import com.cas_parser.api.models.kfintech.KfintechGenerateCasParams +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class KfintechServiceAsyncTest { + + @Disabled("Prism tests are disabled") + @Test + fun generateCas() { + val client = + CasParserOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val kfintechServiceAsync = client.kfintech() + + val responseFuture = + kfintechServiceAsync.generateCas( + KfintechGenerateCasParams.builder() + .email("user@example.com") + .fromDate("2023-01-01") + .password("Abcdefghi12\$") + .toDate("2023-12-31") + .panNo("ABCDE1234F") + .build() + ) + + val response = responseFuture.get() + response.validate() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/LogServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/LogServiceAsyncTest.kt new file mode 100644 index 0000000..bcb12c3 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/LogServiceAsyncTest.kt @@ -0,0 +1,61 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.TestServerExtension +import com.cas_parser.api.client.okhttp.CasParserOkHttpClientAsync +import com.cas_parser.api.models.logs.LogCreateParams +import com.cas_parser.api.models.logs.LogGetSummaryParams +import java.time.OffsetDateTime +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class LogServiceAsyncTest { + + @Disabled("Prism tests are disabled") + @Test + fun create() { + val client = + CasParserOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val logServiceAsync = client.logs() + + val logFuture = + logServiceAsync.create( + LogCreateParams.builder() + .endTime(OffsetDateTime.parse("2026-01-31T23:59:59Z")) + .limit(1L) + .startTime(OffsetDateTime.parse("2026-01-01T00:00:00Z")) + .build() + ) + + val log = logFuture.get() + log.validate() + } + + @Disabled("Prism tests are disabled") + @Test + fun getSummary() { + val client = + CasParserOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val logServiceAsync = client.logs() + + val responseFuture = + logServiceAsync.getSummary( + LogGetSummaryParams.builder() + .endTime(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .startTime(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .build() + ) + + val response = responseFuture.get() + response.validate() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/NsdlServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/NsdlServiceAsyncTest.kt new file mode 100644 index 0000000..b8db02d --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/NsdlServiceAsyncTest.kt @@ -0,0 +1,37 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.TestServerExtension +import com.cas_parser.api.client.okhttp.CasParserOkHttpClientAsync +import com.cas_parser.api.models.nsdl.NsdlParseParams +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class NsdlServiceAsyncTest { + + @Disabled("Prism tests are disabled") + @Test + fun parse() { + val client = + CasParserOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val nsdlServiceAsync = client.nsdl() + + val unifiedResponseFuture = + nsdlServiceAsync.parse( + NsdlParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + + val unifiedResponse = unifiedResponseFuture.get() + unifiedResponse.validate() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/SmartServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/SmartServiceAsyncTest.kt new file mode 100644 index 0000000..9cc398a --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/SmartServiceAsyncTest.kt @@ -0,0 +1,37 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.TestServerExtension +import com.cas_parser.api.client.okhttp.CasParserOkHttpClientAsync +import com.cas_parser.api.models.smart.SmartParseCasPdfParams +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class SmartServiceAsyncTest { + + @Disabled("Prism tests are disabled") + @Test + fun parseCasPdf() { + val client = + CasParserOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val smartServiceAsync = client.smart() + + val unifiedResponseFuture = + smartServiceAsync.parseCasPdf( + SmartParseCasPdfParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + + val unifiedResponse = unifiedResponseFuture.get() + unifiedResponse.validate() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsyncTest.kt new file mode 100644 index 0000000..c521605 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsyncTest.kt @@ -0,0 +1,29 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.TestServerExtension +import com.cas_parser.api.client.okhttp.CasParserOkHttpClientAsync +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class VerifyTokenServiceAsyncTest { + + @Disabled("Prism tests are disabled") + @Test + fun verify() { + val client = + CasParserOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val verifyTokenServiceAsync = client.verifyToken() + + val responseFuture = verifyTokenServiceAsync.verify() + + val response = responseFuture.get() + response.validate() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/cdsl/FetchServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/cdsl/FetchServiceAsyncTest.kt new file mode 100644 index 0000000..7cc38ca --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/cdsl/FetchServiceAsyncTest.kt @@ -0,0 +1,61 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async.cdsl + +import com.cas_parser.api.TestServerExtension +import com.cas_parser.api.client.okhttp.CasParserOkHttpClientAsync +import com.cas_parser.api.models.cdsl.fetch.FetchRequestOtpParams +import com.cas_parser.api.models.cdsl.fetch.FetchVerifyOtpParams +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class FetchServiceAsyncTest { + + @Disabled("Prism tests are disabled") + @Test + fun requestOtp() { + val client = + CasParserOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val fetchServiceAsync = client.cdsl().fetch() + + val responseFuture = + fetchServiceAsync.requestOtp( + FetchRequestOtpParams.builder() + .boId("1234567890123456") + .dob("1990-01-15") + .pan("ABCDE1234F") + .build() + ) + + val response = responseFuture.get() + response.validate() + } + + @Disabled("Prism tests are disabled") + @Test + fun verifyOtp() { + val client = + CasParserOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val fetchServiceAsync = client.cdsl().fetch() + + val responseFuture = + fetchServiceAsync.verifyOtp( + FetchVerifyOtpParams.builder() + .sessionId("session_id") + .otp("123456") + .numPeriods(6L) + .build() + ) + + val response = responseFuture.get() + response.validate() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/AccessTokenServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/AccessTokenServiceTest.kt new file mode 100644 index 0000000..278e2a8 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/AccessTokenServiceTest.kt @@ -0,0 +1,30 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.TestServerExtension +import com.cas_parser.api.client.okhttp.CasParserOkHttpClient +import com.cas_parser.api.models.accesstoken.AccessTokenCreateParams +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class AccessTokenServiceTest { + + @Disabled("Prism tests are disabled") + @Test + fun create() { + val client = + CasParserOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val accessTokenService = client.accessToken() + + val accessToken = + accessTokenService.create(AccessTokenCreateParams.builder().expiryMinutes(60L).build()) + + accessToken.validate() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CamsKfintechServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CamsKfintechServiceTest.kt new file mode 100644 index 0000000..86de188 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CamsKfintechServiceTest.kt @@ -0,0 +1,36 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.TestServerExtension +import com.cas_parser.api.client.okhttp.CasParserOkHttpClient +import com.cas_parser.api.models.camskfintech.CamsKfintechParseParams +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class CamsKfintechServiceTest { + + @Disabled("Prism tests are disabled") + @Test + fun parse() { + val client = + CasParserOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val camsKfintechService = client.camsKfintech() + + val unifiedResponse = + camsKfintechService.parse( + CamsKfintechParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + + unifiedResponse.validate() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CasParserServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CasParserServiceTest.kt deleted file mode 100644 index 9724ba1..0000000 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CasParserServiceTest.kt +++ /dev/null @@ -1,105 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.services.blocking - -import com.cas_parser.api.TestServerExtension -import com.cas_parser.api.client.okhttp.CasParserOkHttpClient -import com.cas_parser.api.models.casparser.CasParserCamsKfintechParams -import com.cas_parser.api.models.casparser.CasParserCdslParams -import com.cas_parser.api.models.casparser.CasParserNsdlParams -import com.cas_parser.api.models.casparser.CasParserSmartParseParams -import org.junit.jupiter.api.Disabled -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith - -@ExtendWith(TestServerExtension::class) -internal class CasParserServiceTest { - - @Disabled("Prism tests are disabled") - @Test - fun camsKfintech() { - val client = - CasParserOkHttpClient.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() - val casParserService = client.casParser() - - val unifiedResponse = - casParserService.camsKfintech( - CasParserCamsKfintechParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - - unifiedResponse.validate() - } - - @Disabled("Prism tests are disabled") - @Test - fun cdsl() { - val client = - CasParserOkHttpClient.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() - val casParserService = client.casParser() - - val unifiedResponse = - casParserService.cdsl( - CasParserCdslParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - - unifiedResponse.validate() - } - - @Disabled("Prism tests are disabled") - @Test - fun nsdl() { - val client = - CasParserOkHttpClient.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() - val casParserService = client.casParser() - - val unifiedResponse = - casParserService.nsdl( - CasParserNsdlParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - - unifiedResponse.validate() - } - - @Disabled("Prism tests are disabled") - @Test - fun smartParse() { - val client = - CasParserOkHttpClient.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() - val casParserService = client.casParser() - - val unifiedResponse = - casParserService.smartParse( - CasParserSmartParseParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - - unifiedResponse.validate() - } -} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CdslServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CdslServiceTest.kt new file mode 100644 index 0000000..492dd5c --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CdslServiceTest.kt @@ -0,0 +1,36 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.TestServerExtension +import com.cas_parser.api.client.okhttp.CasParserOkHttpClient +import com.cas_parser.api.models.cdsl.CdslParsePdfParams +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class CdslServiceTest { + + @Disabled("Prism tests are disabled") + @Test + fun parsePdf() { + val client = + CasParserOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val cdslService = client.cdsl() + + val unifiedResponse = + cdslService.parsePdf( + CdslParsePdfParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + + unifiedResponse.validate() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/ContractNoteServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/ContractNoteServiceTest.kt new file mode 100644 index 0000000..07164ca --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/ContractNoteServiceTest.kt @@ -0,0 +1,37 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.TestServerExtension +import com.cas_parser.api.client.okhttp.CasParserOkHttpClient +import com.cas_parser.api.models.contractnote.ContractNoteParseParams +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class ContractNoteServiceTest { + + @Disabled("Prism tests are disabled") + @Test + fun parse() { + val client = + CasParserOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val contractNoteService = client.contractNote() + + val response = + contractNoteService.parse( + ContractNoteParseParams.builder() + .brokerType(ContractNoteParseParams.BrokerType.ZERODHA) + .password("FAXAK2545F") + .pdfFile("JVBERi0xLjQKMSAwIG9iago8PAovVHlwZSAvQ2F0YWxvZwo...") + .pdfUrl("https://example.com/contract_note.pdf") + .build() + ) + + response.validate() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CreditServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CreditServiceTest.kt new file mode 100644 index 0000000..750948f --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CreditServiceTest.kt @@ -0,0 +1,28 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.TestServerExtension +import com.cas_parser.api.client.okhttp.CasParserOkHttpClient +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class CreditServiceTest { + + @Disabled("Prism tests are disabled") + @Test + fun check() { + val client = + CasParserOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val creditService = client.credits() + + val response = creditService.check() + + response.validate() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/InboxServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/InboxServiceTest.kt new file mode 100644 index 0000000..8b62e2d --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/InboxServiceTest.kt @@ -0,0 +1,99 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.TestServerExtension +import com.cas_parser.api.client.okhttp.CasParserOkHttpClient +import com.cas_parser.api.models.inbox.InboxCheckConnectionStatusParams +import com.cas_parser.api.models.inbox.InboxConnectEmailParams +import com.cas_parser.api.models.inbox.InboxDisconnectEmailParams +import com.cas_parser.api.models.inbox.InboxListCasFilesParams +import java.time.LocalDate +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class InboxServiceTest { + + @Disabled("Prism tests are disabled") + @Test + fun checkConnectionStatus() { + val client = + CasParserOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val inboxService = client.inbox() + + val response = + inboxService.checkConnectionStatus( + InboxCheckConnectionStatusParams.builder().xInboxToken("x-inbox-token").build() + ) + + response.validate() + } + + @Disabled("Prism tests are disabled") + @Test + fun connectEmail() { + val client = + CasParserOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val inboxService = client.inbox() + + val response = + inboxService.connectEmail( + InboxConnectEmailParams.builder() + .redirectUri("https://yourapp.com/oauth-callback") + .state("abc123") + .build() + ) + + response.validate() + } + + @Disabled("Prism tests are disabled") + @Test + fun disconnectEmail() { + val client = + CasParserOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val inboxService = client.inbox() + + val response = + inboxService.disconnectEmail( + InboxDisconnectEmailParams.builder().xInboxToken("x-inbox-token").build() + ) + + response.validate() + } + + @Disabled("Prism tests are disabled") + @Test + fun listCasFiles() { + val client = + CasParserOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val inboxService = client.inbox() + + val response = + inboxService.listCasFiles( + InboxListCasFilesParams.builder() + .xInboxToken("x-inbox-token") + .addCasType(InboxListCasFilesParams.CasType.CDSL) + .addCasType(InboxListCasFilesParams.CasType.NSDL) + .endDate(LocalDate.parse("2025-12-31")) + .startDate(LocalDate.parse("2025-12-01")) + .build() + ) + + response.validate() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/KfintechServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/KfintechServiceTest.kt new file mode 100644 index 0000000..963c6f6 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/KfintechServiceTest.kt @@ -0,0 +1,38 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.TestServerExtension +import com.cas_parser.api.client.okhttp.CasParserOkHttpClient +import com.cas_parser.api.models.kfintech.KfintechGenerateCasParams +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class KfintechServiceTest { + + @Disabled("Prism tests are disabled") + @Test + fun generateCas() { + val client = + CasParserOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val kfintechService = client.kfintech() + + val response = + kfintechService.generateCas( + KfintechGenerateCasParams.builder() + .email("user@example.com") + .fromDate("2023-01-01") + .password("Abcdefghi12\$") + .toDate("2023-12-31") + .panNo("ABCDE1234F") + .build() + ) + + response.validate() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/LogServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/LogServiceTest.kt new file mode 100644 index 0000000..20549fa --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/LogServiceTest.kt @@ -0,0 +1,59 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.TestServerExtension +import com.cas_parser.api.client.okhttp.CasParserOkHttpClient +import com.cas_parser.api.models.logs.LogCreateParams +import com.cas_parser.api.models.logs.LogGetSummaryParams +import java.time.OffsetDateTime +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class LogServiceTest { + + @Disabled("Prism tests are disabled") + @Test + fun create() { + val client = + CasParserOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val logService = client.logs() + + val log = + logService.create( + LogCreateParams.builder() + .endTime(OffsetDateTime.parse("2026-01-31T23:59:59Z")) + .limit(1L) + .startTime(OffsetDateTime.parse("2026-01-01T00:00:00Z")) + .build() + ) + + log.validate() + } + + @Disabled("Prism tests are disabled") + @Test + fun getSummary() { + val client = + CasParserOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val logService = client.logs() + + val response = + logService.getSummary( + LogGetSummaryParams.builder() + .endTime(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .startTime(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .build() + ) + + response.validate() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/NsdlServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/NsdlServiceTest.kt new file mode 100644 index 0000000..44b520c --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/NsdlServiceTest.kt @@ -0,0 +1,36 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.TestServerExtension +import com.cas_parser.api.client.okhttp.CasParserOkHttpClient +import com.cas_parser.api.models.nsdl.NsdlParseParams +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class NsdlServiceTest { + + @Disabled("Prism tests are disabled") + @Test + fun parse() { + val client = + CasParserOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val nsdlService = client.nsdl() + + val unifiedResponse = + nsdlService.parse( + NsdlParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + + unifiedResponse.validate() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/SmartServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/SmartServiceTest.kt new file mode 100644 index 0000000..0f96eb7 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/SmartServiceTest.kt @@ -0,0 +1,36 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.TestServerExtension +import com.cas_parser.api.client.okhttp.CasParserOkHttpClient +import com.cas_parser.api.models.smart.SmartParseCasPdfParams +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class SmartServiceTest { + + @Disabled("Prism tests are disabled") + @Test + fun parseCasPdf() { + val client = + CasParserOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val smartService = client.smart() + + val unifiedResponse = + smartService.parseCasPdf( + SmartParseCasPdfParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + + unifiedResponse.validate() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/VerifyTokenServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/VerifyTokenServiceTest.kt new file mode 100644 index 0000000..05a1f9f --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/VerifyTokenServiceTest.kt @@ -0,0 +1,28 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.TestServerExtension +import com.cas_parser.api.client.okhttp.CasParserOkHttpClient +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class VerifyTokenServiceTest { + + @Disabled("Prism tests are disabled") + @Test + fun verify() { + val client = + CasParserOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val verifyTokenService = client.verifyToken() + + val response = verifyTokenService.verify() + + response.validate() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/cdsl/FetchServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/cdsl/FetchServiceTest.kt new file mode 100644 index 0000000..eedc3dd --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/cdsl/FetchServiceTest.kt @@ -0,0 +1,59 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking.cdsl + +import com.cas_parser.api.TestServerExtension +import com.cas_parser.api.client.okhttp.CasParserOkHttpClient +import com.cas_parser.api.models.cdsl.fetch.FetchRequestOtpParams +import com.cas_parser.api.models.cdsl.fetch.FetchVerifyOtpParams +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class FetchServiceTest { + + @Disabled("Prism tests are disabled") + @Test + fun requestOtp() { + val client = + CasParserOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val fetchService = client.cdsl().fetch() + + val response = + fetchService.requestOtp( + FetchRequestOtpParams.builder() + .boId("1234567890123456") + .dob("1990-01-15") + .pan("ABCDE1234F") + .build() + ) + + response.validate() + } + + @Disabled("Prism tests are disabled") + @Test + fun verifyOtp() { + val client = + CasParserOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val fetchService = client.cdsl().fetch() + + val response = + fetchService.verifyOtp( + FetchVerifyOtpParams.builder() + .sessionId("session_id") + .otp("123456") + .numPeriods(6L) + .build() + ) + + response.validate() + } +} diff --git a/cas-parser-java-proguard-test/src/test/kotlin/com/cas_parser/api/proguard/ProGuardCompatibilityTest.kt b/cas-parser-java-proguard-test/src/test/kotlin/com/cas_parser/api/proguard/ProGuardCompatibilityTest.kt index a975237..bdbc9b7 100644 --- a/cas-parser-java-proguard-test/src/test/kotlin/com/cas_parser/api/proguard/ProGuardCompatibilityTest.kt +++ b/cas-parser-java-proguard-test/src/test/kotlin/com/cas_parser/api/proguard/ProGuardCompatibilityTest.kt @@ -3,11 +3,9 @@ package com.cas_parser.api.proguard import com.cas_parser.api.client.okhttp.CasParserOkHttpClient -import com.cas_parser.api.core.JsonValue import com.cas_parser.api.core.jsonMapper -import com.cas_parser.api.models.casparser.UnifiedResponse +import com.cas_parser.api.models.credits.CreditCheckResponse import com.fasterxml.jackson.module.kotlin.jacksonTypeRef -import java.time.LocalDate import java.time.OffsetDateTime import kotlin.reflect.full.memberFunctions import kotlin.reflect.jvm.javaMethod @@ -50,482 +48,40 @@ internal class ProGuardCompatibilityTest { val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() assertThat(client).isNotNull() - assertThat(client.casParser()).isNotNull() - assertThat(client.casGenerator()).isNotNull() + assertThat(client.credits()).isNotNull() + assertThat(client.logs()).isNotNull() + assertThat(client.accessToken()).isNotNull() + assertThat(client.verifyToken()).isNotNull() + assertThat(client.camsKfintech()).isNotNull() + assertThat(client.cdsl()).isNotNull() + assertThat(client.contractNote()).isNotNull() + assertThat(client.inbox()).isNotNull() + assertThat(client.kfintech()).isNotNull() + assertThat(client.nsdl()).isNotNull() + assertThat(client.smart()).isNotNull() } @Test - fun unifiedResponseRoundtrip() { + fun creditCheckResponseRoundtrip() { val jsonMapper = jsonMapper() - val unifiedResponse = - UnifiedResponse.builder() - .addDematAccount( - UnifiedResponse.DematAccount.builder() - .additionalInfo( - UnifiedResponse.DematAccount.AdditionalInfo.builder() - .boStatus("bo_status") - .boSubStatus("bo_sub_status") - .boType("bo_type") - .bsda("bsda") - .email("dev@stainless.com") - .addLinkedPan("string") - .nominee("nominee") - .status("status") - .build() - ) - .boId("bo_id") - .clientId("client_id") - .dematType(UnifiedResponse.DematAccount.DematType.NSDL) - .dpId("dp_id") - .dpName("dp_name") - .holdings( - UnifiedResponse.DematAccount.Holdings.builder() - .addAif( - UnifiedResponse.DematAccount.Holdings.Aif.builder() - .additionalInfo( - UnifiedResponse.DematAccount.Holdings.Aif.AdditionalInfo - .builder() - .closeUnits(0.0f) - .openUnits(0.0f) - .build() - ) - .isin("isin") - .name("name") - .addTransaction( - UnifiedResponse.DematAccount.Holdings.Aif.Transaction - .builder() - .additionalInfo( - UnifiedResponse.DematAccount.Holdings.Aif - .Transaction - .AdditionalInfo - .builder() - .capitalWithdrawal(0.0f) - .credit(0.0f) - .debit(0.0f) - .incomeDistribution(0.0f) - .orderNo("order_no") - .price(0.0f) - .stampDuty(0.0f) - .build() - ) - .amount(0.0f) - .balance(0.0f) - .date(LocalDate.parse("2019-12-27")) - .description("description") - .dividendRate(0.0f) - .nav(0.0f) - .type( - UnifiedResponse.DematAccount.Holdings.Aif - .Transaction - .Type - .PURCHASE - ) - .units(0.0f) - .build() - ) - .units(0.0f) - .value(0.0f) - .build() - ) - .addCorporateBond( - UnifiedResponse.DematAccount.Holdings.CorporateBond.builder() - .additionalInfo( - UnifiedResponse.DematAccount.Holdings.CorporateBond - .AdditionalInfo - .builder() - .closeUnits(0.0f) - .openUnits(0.0f) - .build() - ) - .isin("isin") - .name("name") - .addTransaction( - UnifiedResponse.DematAccount.Holdings.CorporateBond - .Transaction - .builder() - .additionalInfo( - UnifiedResponse.DematAccount.Holdings - .CorporateBond - .Transaction - .AdditionalInfo - .builder() - .capitalWithdrawal(0.0f) - .credit(0.0f) - .debit(0.0f) - .incomeDistribution(0.0f) - .orderNo("order_no") - .price(0.0f) - .stampDuty(0.0f) - .build() - ) - .amount(0.0f) - .balance(0.0f) - .date(LocalDate.parse("2019-12-27")) - .description("description") - .dividendRate(0.0f) - .nav(0.0f) - .type( - UnifiedResponse.DematAccount.Holdings - .CorporateBond - .Transaction - .Type - .PURCHASE - ) - .units(0.0f) - .build() - ) - .units(0.0f) - .value(0.0f) - .build() - ) - .addDematMutualFund( - UnifiedResponse.DematAccount.Holdings.DematMutualFund.builder() - .additionalInfo( - UnifiedResponse.DematAccount.Holdings.DematMutualFund - .AdditionalInfo - .builder() - .closeUnits(0.0f) - .openUnits(0.0f) - .build() - ) - .isin("isin") - .name("name") - .addTransaction( - UnifiedResponse.DematAccount.Holdings.DematMutualFund - .Transaction - .builder() - .additionalInfo( - UnifiedResponse.DematAccount.Holdings - .DematMutualFund - .Transaction - .AdditionalInfo - .builder() - .capitalWithdrawal(0.0f) - .credit(0.0f) - .debit(0.0f) - .incomeDistribution(0.0f) - .orderNo("order_no") - .price(0.0f) - .stampDuty(0.0f) - .build() - ) - .amount(0.0f) - .balance(0.0f) - .date(LocalDate.parse("2019-12-27")) - .description("description") - .dividendRate(0.0f) - .nav(0.0f) - .type( - UnifiedResponse.DematAccount.Holdings - .DematMutualFund - .Transaction - .Type - .PURCHASE - ) - .units(0.0f) - .build() - ) - .units(0.0f) - .value(0.0f) - .build() - ) - .addEquity( - UnifiedResponse.DematAccount.Holdings.Equity.builder() - .additionalInfo( - UnifiedResponse.DematAccount.Holdings.Equity - .AdditionalInfo - .builder() - .closeUnits(0.0f) - .openUnits(0.0f) - .build() - ) - .isin("isin") - .name("name") - .addTransaction( - UnifiedResponse.DematAccount.Holdings.Equity.Transaction - .builder() - .additionalInfo( - UnifiedResponse.DematAccount.Holdings.Equity - .Transaction - .AdditionalInfo - .builder() - .capitalWithdrawal(0.0f) - .credit(0.0f) - .debit(0.0f) - .incomeDistribution(0.0f) - .orderNo("order_no") - .price(0.0f) - .stampDuty(0.0f) - .build() - ) - .amount(0.0f) - .balance(0.0f) - .date(LocalDate.parse("2019-12-27")) - .description("description") - .dividendRate(0.0f) - .nav(0.0f) - .type( - UnifiedResponse.DematAccount.Holdings.Equity - .Transaction - .Type - .PURCHASE - ) - .units(0.0f) - .build() - ) - .units(0.0f) - .value(0.0f) - .build() - ) - .addGovernmentSecurity( - UnifiedResponse.DematAccount.Holdings.GovernmentSecurity - .builder() - .additionalInfo( - UnifiedResponse.DematAccount.Holdings.GovernmentSecurity - .AdditionalInfo - .builder() - .closeUnits(0.0f) - .openUnits(0.0f) - .build() - ) - .isin("isin") - .name("name") - .addTransaction( - UnifiedResponse.DematAccount.Holdings.GovernmentSecurity - .Transaction - .builder() - .additionalInfo( - UnifiedResponse.DematAccount.Holdings - .GovernmentSecurity - .Transaction - .AdditionalInfo - .builder() - .capitalWithdrawal(0.0f) - .credit(0.0f) - .debit(0.0f) - .incomeDistribution(0.0f) - .orderNo("order_no") - .price(0.0f) - .stampDuty(0.0f) - .build() - ) - .amount(0.0f) - .balance(0.0f) - .date(LocalDate.parse("2019-12-27")) - .description("description") - .dividendRate(0.0f) - .nav(0.0f) - .type( - UnifiedResponse.DematAccount.Holdings - .GovernmentSecurity - .Transaction - .Type - .PURCHASE - ) - .units(0.0f) - .build() - ) - .units(0.0f) - .value(0.0f) - .build() - ) - .build() - ) - .addLinkedHolder( - UnifiedResponse.DematAccount.LinkedHolder.builder() - .name("name") - .pan("pan") - .build() - ) - .value(0.0f) - .build() - ) - .insurance( - UnifiedResponse.Insurance.builder() - .addLifeInsurancePolicy( - UnifiedResponse.Insurance.LifeInsurancePolicy.builder() - .additionalInfo(JsonValue.from(mapOf())) - .lifeAssured("life_assured") - .policyName("policy_name") - .policyNumber("policy_number") - .premiumAmount(0.0f) - .premiumFrequency("premium_frequency") - .provider("provider") - .status("status") - .sumAssured(0.0f) - .build() - ) - .build() - ) - .investor( - UnifiedResponse.Investor.builder() - .address("address") - .casId("cas_id") - .email("dev@stainless.com") - .mobile("mobile") - .name("name") - .pan("pan") - .pincode("pincode") - .build() - ) - .meta( - UnifiedResponse.Meta.builder() - .casType(UnifiedResponse.Meta.CasType.NSDL) - .generatedAt(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .statementPeriod( - UnifiedResponse.Meta.StatementPeriod.builder() - .from(LocalDate.parse("2019-12-27")) - .to(LocalDate.parse("2019-12-27")) - .build() - ) - .build() - ) - .addMutualFund( - UnifiedResponse.MutualFund.builder() - .additionalInfo( - UnifiedResponse.MutualFund.AdditionalInfo.builder() - .kyc("kyc") - .pan("pan") - .pankyc("pankyc") - .build() - ) - .amc("amc") - .folioNumber("folio_number") - .addLinkedHolder( - UnifiedResponse.MutualFund.LinkedHolder.builder() - .name("name") - .pan("pan") - .build() - ) - .registrar("registrar") - .addScheme( - UnifiedResponse.MutualFund.Scheme.builder() - .additionalInfo( - UnifiedResponse.MutualFund.Scheme.AdditionalInfo.builder() - .advisor("advisor") - .amfi("amfi") - .closeUnits(0.0f) - .openUnits(0.0f) - .rtaCode("rta_code") - .build() - ) - .cost(0.0f) - .gain( - UnifiedResponse.MutualFund.Scheme.Gain.builder() - .absolute(0.0f) - .percentage(0.0f) - .build() - ) - .isin("isin") - .name("name") - .nav(0.0f) - .addNominee("string") - .addTransaction( - UnifiedResponse.MutualFund.Scheme.Transaction.builder() - .additionalInfo( - UnifiedResponse.MutualFund.Scheme.Transaction - .AdditionalInfo - .builder() - .capitalWithdrawal(0.0f) - .credit(0.0f) - .debit(0.0f) - .incomeDistribution(0.0f) - .orderNo("order_no") - .price(0.0f) - .stampDuty(0.0f) - .build() - ) - .amount(0.0f) - .balance(0.0f) - .date(LocalDate.parse("2019-12-27")) - .description("description") - .dividendRate(0.0f) - .nav(0.0f) - .type( - UnifiedResponse.MutualFund.Scheme.Transaction.Type - .PURCHASE - ) - .units(0.0f) - .build() - ) - .type(UnifiedResponse.MutualFund.Scheme.Type.EQUITY) - .units(0.0f) - .value(0.0f) - .build() - ) - .value(0.0f) - .build() - ) - .addNp( - UnifiedResponse.Np.builder() - .additionalInfo(JsonValue.from(mapOf())) - .cra("cra") - .addFund( - UnifiedResponse.Np.Fund.builder() - .additionalInfo( - UnifiedResponse.Np.Fund.AdditionalInfo.builder() - .manager("manager") - .tier(UnifiedResponse.Np.Fund.AdditionalInfo.Tier._1) - .build() - ) - .cost(0.0f) - .name("name") - .nav(0.0f) - .units(0.0f) - .value(0.0f) - .build() - ) - .addLinkedHolder( - UnifiedResponse.Np.LinkedHolder.builder() - .name("name") - .pan("pan") - .build() - ) - .pran("pran") - .value(0.0f) - .build() - ) - .summary( - UnifiedResponse.Summary.builder() - .accounts( - UnifiedResponse.Summary.Accounts.builder() - .demat( - UnifiedResponse.Summary.Accounts.Demat.builder() - .count(0L) - .totalValue(0.0f) - .build() - ) - .insurance( - UnifiedResponse.Summary.Accounts.Insurance.builder() - .count(0L) - .totalValue(0.0f) - .build() - ) - .mutualFunds( - UnifiedResponse.Summary.Accounts.MutualFunds.builder() - .count(0L) - .totalValue(0.0f) - .build() - ) - .nps( - UnifiedResponse.Summary.Accounts.Nps.builder() - .count(0L) - .totalValue(0.0f) - .build() - ) - .build() - ) - .totalValue(0.0f) - .build() + val creditCheckResponse = + CreditCheckResponse.builder() + .enabledFeatures( + listOf("cams_kfintech_cas_parser", "cdsl_cas_parser", "nsdl_cas_parser") ) + .isUnlimited(false) + .limit(50L) + .remaining(35.0) + .resetsAt(OffsetDateTime.parse("2026-02-15T00:00:00Z")) + .used(15.0) .build() - val roundtrippedUnifiedResponse = + val roundtrippedCreditCheckResponse = jsonMapper.readValue( - jsonMapper.writeValueAsString(unifiedResponse), - jacksonTypeRef(), + jsonMapper.writeValueAsString(creditCheckResponse), + jacksonTypeRef(), ) - assertThat(roundtrippedUnifiedResponse).isEqualTo(unifiedResponse) + assertThat(roundtrippedCreditCheckResponse).isEqualTo(creditCheckResponse) } } diff --git a/release-please-config.json b/release-please-config.json deleted file mode 100644 index 8f98719..0000000 --- a/release-please-config.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "packages": { - ".": {} - }, - "$schema": "https://raw.githubusercontent.com/stainless-api/release-please/main/schemas/config.json", - "include-v-in-tag": true, - "include-component-in-tag": false, - "versioning": "prerelease", - "prerelease": true, - "bump-minor-pre-major": true, - "bump-patch-for-minor-pre-major": false, - "pull-request-header": "Automated Release PR", - "pull-request-title-pattern": "release: ${version}", - "changelog-sections": [ - { - "type": "feat", - "section": "Features" - }, - { - "type": "fix", - "section": "Bug Fixes" - }, - { - "type": "perf", - "section": "Performance Improvements" - }, - { - "type": "revert", - "section": "Reverts" - }, - { - "type": "chore", - "section": "Chores" - }, - { - "type": "docs", - "section": "Documentation" - }, - { - "type": "style", - "section": "Styles" - }, - { - "type": "refactor", - "section": "Refactors" - }, - { - "type": "test", - "section": "Tests", - "hidden": true - }, - { - "type": "build", - "section": "Build System" - }, - { - "type": "ci", - "section": "Continuous Integration", - "hidden": true - } - ], - "release-type": "simple", - "extra-files": [ - "README.md", - "build.gradle.kts" - ] -} \ No newline at end of file From 8e512368104f383e510aad33a5f8f5ee6352dfa8 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 14 Feb 2026 00:31:59 +0000 Subject: [PATCH 30/99] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index ff35822..881eb9d 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 17 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-56b0f699c5437d9e5326626d35dfc972c17d01f12cb416c7f4854c8ea6d0e95e.yml openapi_spec_hash: 158f405c1880706266d83e6ff16b9d2f -config_hash: 267be54ae6400ea329b16189da51ee06 +config_hash: 0147789978cfd5a389e3a322f947cc77 From 226b2e6b29102bf6d8432ec7909eedca19132670 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 14 Feb 2026 00:32:06 +0000 Subject: [PATCH 31/99] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index 881eb9d..ceaa88c 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 17 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-56b0f699c5437d9e5326626d35dfc972c17d01f12cb416c7f4854c8ea6d0e95e.yml openapi_spec_hash: 158f405c1880706266d83e6ff16b9d2f -config_hash: 0147789978cfd5a389e3a322f947cc77 +config_hash: d809302a8fbd68d89e2f340990780406 From 27d1e51f2cc2a2141ce405a352fdc711c00e14bc Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 14 Feb 2026 00:32:19 +0000 Subject: [PATCH 32/99] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index ceaa88c..0d67332 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 17 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-56b0f699c5437d9e5326626d35dfc972c17d01f12cb416c7f4854c8ea6d0e95e.yml openapi_spec_hash: 158f405c1880706266d83e6ff16b9d2f -config_hash: d809302a8fbd68d89e2f340990780406 +config_hash: b829eba996751b6279970de4dcc343a1 From acde54f1be656af2ad81f2a4054db10fbdb25591 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 14 Feb 2026 00:32:28 +0000 Subject: [PATCH 33/99] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index 0d67332..59965f2 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 17 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-56b0f699c5437d9e5326626d35dfc972c17d01f12cb416c7f4854c8ea6d0e95e.yml openapi_spec_hash: 158f405c1880706266d83e6ff16b9d2f -config_hash: b829eba996751b6279970de4dcc343a1 +config_hash: ba177c0fa552925abac02f860f0aba70 From 70f1dc66c3104a01b932b3700b40b4da6a5f9de5 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 14 Feb 2026 00:32:53 +0000 Subject: [PATCH 34/99] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index 59965f2..92a06be 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 17 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-56b0f699c5437d9e5326626d35dfc972c17d01f12cb416c7f4854c8ea6d0e95e.yml openapi_spec_hash: 158f405c1880706266d83e6ff16b9d2f -config_hash: ba177c0fa552925abac02f860f0aba70 +config_hash: c9c82d7a2437cc99fc06dd1f92cf76ab From fd064c32d84602e8b5569b4332bafd4841101866 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 14 Feb 2026 00:43:08 +0000 Subject: [PATCH 35/99] chore: update SDK settings --- .github/workflows/publish-sonatype.yml | 41 ++++++++++++ .github/workflows/release-doctor.yml | 24 +++++++ .release-please-manifest.json | 3 + .stats.yml | 2 +- README.md | 14 +++- bin/check-release-environment | 33 +++++++++ build.gradle.kts | 2 +- .../main/kotlin/cas-parser.publish.gradle.kts | 8 +-- .../kotlin/com/cas_parser/api/core/Check.kt | 2 +- release-please-config.json | 67 +++++++++++++++++++ 10 files changed, 188 insertions(+), 8 deletions(-) create mode 100644 .github/workflows/publish-sonatype.yml create mode 100644 .github/workflows/release-doctor.yml create mode 100644 .release-please-manifest.json create mode 100644 bin/check-release-environment create mode 100644 release-please-config.json diff --git a/.github/workflows/publish-sonatype.yml b/.github/workflows/publish-sonatype.yml new file mode 100644 index 0000000..2bfe3c5 --- /dev/null +++ b/.github/workflows/publish-sonatype.yml @@ -0,0 +1,41 @@ +# This workflow is triggered when a GitHub release is created. +# It can also be run manually to re-publish to Sonatype in case it failed for some reason. +# You can run this workflow by navigating to https://www.github.com/CASParser/cas-parser-java/actions/workflows/publish-sonatype.yml +name: Publish Sonatype +on: + workflow_dispatch: + + release: + types: [published] + +jobs: + publish: + name: publish + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v6 + + - name: Set up Java + uses: actions/setup-java@v5 + with: + distribution: temurin + java-version: | + 8 + 21 + cache: gradle + + - name: Set up Gradle + uses: gradle/gradle-build-action@v2 + + - name: Publish to Sonatype + run: |- + export -- GPG_SIGNING_KEY_ID + printenv -- GPG_SIGNING_KEY | gpg --batch --passphrase-fd 3 --import 3<<< "$GPG_SIGNING_PASSWORD" + GPG_SIGNING_KEY_ID="$(gpg --with-colons --list-keys | awk -F : -- '/^pub:/ { getline; print "0x" substr($10, length($10) - 7) }')" + ./gradlew publish --no-configuration-cache + env: + SONATYPE_USERNAME: ${{ secrets.CAS_PARSER_SONATYPE_USERNAME || secrets.SONATYPE_USERNAME }} + SONATYPE_PASSWORD: ${{ secrets.CAS_PARSER_SONATYPE_PASSWORD || secrets.SONATYPE_PASSWORD }} + GPG_SIGNING_KEY: ${{ secrets.CAS_PARSER_SONATYPE_GPG_SIGNING_KEY || secrets.GPG_SIGNING_KEY }} + GPG_SIGNING_PASSWORD: ${{ secrets.CAS_PARSER_SONATYPE_GPG_SIGNING_PASSWORD || secrets.GPG_SIGNING_PASSWORD }} \ No newline at end of file diff --git a/.github/workflows/release-doctor.yml b/.github/workflows/release-doctor.yml new file mode 100644 index 0000000..a636804 --- /dev/null +++ b/.github/workflows/release-doctor.yml @@ -0,0 +1,24 @@ +name: Release Doctor +on: + pull_request: + branches: + - main + workflow_dispatch: + +jobs: + release_doctor: + name: release doctor + runs-on: ubuntu-latest + if: github.repository == 'CASParser/cas-parser-java' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || startsWith(github.head_ref, 'release-please') || github.head_ref == 'next') + + steps: + - uses: actions/checkout@v6 + + - name: Check release environment + run: | + bash ./bin/check-release-environment + env: + SONATYPE_USERNAME: ${{ secrets.CAS_PARSER_SONATYPE_USERNAME || secrets.SONATYPE_USERNAME }} + SONATYPE_PASSWORD: ${{ secrets.CAS_PARSER_SONATYPE_PASSWORD || secrets.SONATYPE_PASSWORD }} + GPG_SIGNING_KEY: ${{ secrets.CAS_PARSER_SONATYPE_GPG_SIGNING_KEY || secrets.GPG_SIGNING_KEY }} + GPG_SIGNING_PASSWORD: ${{ secrets.CAS_PARSER_SONATYPE_GPG_SIGNING_PASSWORD || secrets.GPG_SIGNING_PASSWORD }} diff --git a/.release-please-manifest.json b/.release-please-manifest.json new file mode 100644 index 0000000..3d2ac0b --- /dev/null +++ b/.release-please-manifest.json @@ -0,0 +1,3 @@ +{ + ".": "0.1.0" +} \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 92a06be..5089578 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 17 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-56b0f699c5437d9e5326626d35dfc972c17d01f12cb416c7f4854c8ea6d0e95e.yml openapi_spec_hash: 158f405c1880706266d83e6ff16b9d2f -config_hash: c9c82d7a2437cc99fc06dd1f92cf76ab +config_hash: 45c71ec3a79a4740623d68b2319ff2bd diff --git a/README.md b/README.md index f63b8d7..eeedf84 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,26 @@ # Cas Parser Java API Library + + [![Maven Central](https://img.shields.io/maven-central/v/com.cas_parser.api/cas-parser-java)](https://central.sonatype.com/artifact/com.cas_parser.api/cas-parser-java/0.1.0) [![javadoc](https://javadoc.io/badge2/com.cas_parser.api/cas-parser-java/0.1.0/javadoc.svg)](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.1.0) + + The Cas Parser Java SDK provides convenient access to the Cas Parser REST API from applications written in Java. It is generated with [Stainless](https://www.stainless.com/). + + Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.1.0). + + ## Installation + + ### Gradle ```kotlin @@ -27,6 +37,8 @@ implementation("com.cas_parser.api:cas-parser-java:0.1.0") ``` + + ## Requirements This library requires Java 8 or later. @@ -603,4 +615,4 @@ This package generally follows [SemVer](https://semver.org/spec/v2.0.0.html) con We take backwards-compatibility seriously and work hard to ensure you can rely on a smooth upgrade experience. -We are keen for your feedback; please open an [issue](https://www.github.com/stainless-sdks/cas-parser-java/issues) with questions, bugs, or suggestions. +We are keen for your feedback; please open an [issue](https://www.github.com/CASParser/cas-parser-java/issues) with questions, bugs, or suggestions. diff --git a/bin/check-release-environment b/bin/check-release-environment new file mode 100644 index 0000000..3a6a7b4 --- /dev/null +++ b/bin/check-release-environment @@ -0,0 +1,33 @@ +#!/usr/bin/env bash + +errors=() + +if [ -z "${SONATYPE_USERNAME}" ]; then + errors+=("The SONATYPE_USERNAME secret has not been set. Please set it in either this repository's secrets or your organization secrets") +fi + +if [ -z "${SONATYPE_PASSWORD}" ]; then + errors+=("The SONATYPE_PASSWORD secret has not been set. Please set it in either this repository's secrets or your organization secrets") +fi + +if [ -z "${GPG_SIGNING_KEY}" ]; then + errors+=("The GPG_SIGNING_KEY secret has not been set. Please set it in either this repository's secrets or your organization secrets") +fi + +if [ -z "${GPG_SIGNING_PASSWORD}" ]; then + errors+=("The GPG_SIGNING_PASSWORD secret has not been set. Please set it in either this repository's secrets or your organization secrets") +fi + +lenErrors=${#errors[@]} + +if [[ lenErrors -gt 0 ]]; then + echo -e "Found the following errors in the release environment:\n" + + for error in "${errors[@]}"; do + echo -e "- $error\n" + done + + exit 1 +fi + +echo "The environment is ready to push releases!" diff --git a/build.gradle.kts b/build.gradle.kts index abbbc45..30b3cae 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -9,7 +9,7 @@ repositories { allprojects { group = "com.cas_parser.api" - version = "0.1.0" + version = "0.1.0" // x-release-please-version } subprojects { diff --git a/buildSrc/src/main/kotlin/cas-parser.publish.gradle.kts b/buildSrc/src/main/kotlin/cas-parser.publish.gradle.kts index d4958ec..56f585c 100644 --- a/buildSrc/src/main/kotlin/cas-parser.publish.gradle.kts +++ b/buildSrc/src/main/kotlin/cas-parser.publish.gradle.kts @@ -11,7 +11,7 @@ configure { pom { name.set("CAS Parser - Track Portfolios from CDSL, NSDL, CAMS, KFintech") description.set("API for parsing and analyzing CAS (Consolidated Account Statement) PDF files\nfrom NSDL, CDSL, and CAMS/KFintech, with a unified response format") - url.set("https://www.github.com/stainless-sdks/cas-parser-java") + url.set("https://www.github.com/CASParser/cas-parser-java") licenses { license { @@ -27,9 +27,9 @@ configure { } scm { - connection.set("scm:git:git://github.com/stainless-sdks/cas-parser-java.git") - developerConnection.set("scm:git:git://github.com/stainless-sdks/cas-parser-java.git") - url.set("https://github.com/stainless-sdks/cas-parser-java") + connection.set("scm:git:git://github.com/CASParser/cas-parser-java.git") + developerConnection.set("scm:git:git://github.com/CASParser/cas-parser-java.git") + url.set("https://github.com/CASParser/cas-parser-java") } versionMapping { diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Check.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Check.kt index 2e4c6e8..c0b5e80 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Check.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Check.kt @@ -77,7 +77,7 @@ This can happen if you are either: Double-check that you are depending on compatible Jackson versions. -See https://www.github.com/stainless-sdks/cas-parser-java#jackson for more information. +See https://www.github.com/CASParser/cas-parser-java#jackson for more information. """ .trimIndent() } diff --git a/release-please-config.json b/release-please-config.json new file mode 100644 index 0000000..8f98719 --- /dev/null +++ b/release-please-config.json @@ -0,0 +1,67 @@ +{ + "packages": { + ".": {} + }, + "$schema": "https://raw.githubusercontent.com/stainless-api/release-please/main/schemas/config.json", + "include-v-in-tag": true, + "include-component-in-tag": false, + "versioning": "prerelease", + "prerelease": true, + "bump-minor-pre-major": true, + "bump-patch-for-minor-pre-major": false, + "pull-request-header": "Automated Release PR", + "pull-request-title-pattern": "release: ${version}", + "changelog-sections": [ + { + "type": "feat", + "section": "Features" + }, + { + "type": "fix", + "section": "Bug Fixes" + }, + { + "type": "perf", + "section": "Performance Improvements" + }, + { + "type": "revert", + "section": "Reverts" + }, + { + "type": "chore", + "section": "Chores" + }, + { + "type": "docs", + "section": "Documentation" + }, + { + "type": "style", + "section": "Styles" + }, + { + "type": "refactor", + "section": "Refactors" + }, + { + "type": "test", + "section": "Tests", + "hidden": true + }, + { + "type": "build", + "section": "Build System" + }, + { + "type": "ci", + "section": "Continuous Integration", + "hidden": true + } + ], + "release-type": "simple", + "extra-files": [ + "README.md", + "build.gradle.kts" + ] +} \ No newline at end of file From 696bef31700b93d9bcc51ac77b809ddeb373fad2 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 14 Feb 2026 00:43:36 +0000 Subject: [PATCH 36/99] chore: configure new SDK language --- .stats.yml | 2 +- README.md | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index 5089578..4d62cd0 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 17 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-56b0f699c5437d9e5326626d35dfc972c17d01f12cb416c7f4854c8ea6d0e95e.yml openapi_spec_hash: 158f405c1880706266d83e6ff16b9d2f -config_hash: 45c71ec3a79a4740623d68b2319ff2bd +config_hash: 1af2e938c93ea4ec25fc633469072c43 diff --git a/README.md b/README.md index eeedf84..160a9c5 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,15 @@ The Cas Parser Java SDK provides convenient access to the Cas Parser REST API fr It is generated with [Stainless](https://www.stainless.com/). +## MCP Server + +Use the Cas Parser MCP Server to enable AI assistants to interact with this API, allowing them to explore endpoints, make test requests, and use documentation to help integrate this SDK into your application. + +[![Add to Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en-US/install-mcp?name=cas-parser-mcp&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsImNhcy1wYXJzZXItbWNwIl0sImVudiI6eyJDQVNfUEFSU0VSX0FQSV9LRVkiOiJNeSBBUEkgS2V5In19) +[![Install in VS Code](https://img.shields.io/badge/_-Add_to_VS_Code-blue?style=for-the-badge&logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9Im5vbmUiIHZpZXdCb3g9IjAgMCA0MCA0MCI+PHBhdGggZmlsbD0iI0VFRSIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMzAuMjM1IDM5Ljg4NGEyLjQ5MSAyLjQ5MSAwIDAgMS0xLjc4MS0uNzNMMTIuNyAyNC43OGwtMy40NiAyLjYyNC0zLjQwNiAyLjU4MmExLjY2NSAxLjY2NSAwIDAgMS0xLjA4Mi4zMzggMS42NjQgMS42NjQgMCAwIDEtMS4wNDYtLjQzMWwtMi4yLTJhMS42NjYgMS42NjYgMCAwIDEgMC0yLjQ2M0w3LjQ1OCAyMCA0LjY3IDE3LjQ1MyAxLjUwNyAxNC41N2ExLjY2NSAxLjY2NSAwIDAgMSAwLTIuNDYzbDIuMi0yYTEuNjY1IDEuNjY1IDAgMCAxIDIuMTMtLjA5N2w2Ljg2MyA1LjIwOUwyOC40NTIuODQ0YTIuNDg4IDIuNDg4IDAgMCAxIDEuODQxLS43MjljLjM1MS4wMDkuNjk5LjA5MSAxLjAxOS4yNDVsOC4yMzYgMy45NjFhMi41IDIuNSAwIDAgMSAxLjQxNSAyLjI1M3YuMDk5LS4wNDVWMzMuMzd2LS4wNDUuMDk1YTIuNTAxIDIuNTAxIDAgMCAxLTEuNDE2IDIuMjU3bC04LjIzNSAzLjk2MWEyLjQ5MiAyLjQ5MiAwIDAgMS0xLjA3Ny4yNDZabS43MTYtMjguOTQ3LTExLjk0OCA5LjA2MiAxMS45NTIgOS4wNjUtLjAwNC0xOC4xMjdaIi8+PC9zdmc+)](https://vscode.stainless.com/mcp/%7B%22name%22%3A%22cas-parser-mcp%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22cas-parser-mcp%22%5D%2C%22env%22%3A%7B%22CAS_PARSER_API_KEY%22%3A%22My%20API%20Key%22%7D%7D) + +> Note: You may need to set environment variables in your MCP client. + Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.1.0). From dd87fcd53c764406dbb7c0cbabd3931f3755a539 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 14 Feb 2026 00:49:48 +0000 Subject: [PATCH 37/99] chore(internal): version bump --- .release-please-manifest.json | 2 +- README.md | 10 +++++----- build.gradle.kts | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 3d2ac0b..10f3091 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.1.0" + ".": "0.2.0" } \ No newline at end of file diff --git a/README.md b/README.md index 160a9c5..3d0bf3f 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ -[![Maven Central](https://img.shields.io/maven-central/v/com.cas_parser.api/cas-parser-java)](https://central.sonatype.com/artifact/com.cas_parser.api/cas-parser-java/0.1.0) -[![javadoc](https://javadoc.io/badge2/com.cas_parser.api/cas-parser-java/0.1.0/javadoc.svg)](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.1.0) +[![Maven Central](https://img.shields.io/maven-central/v/com.cas_parser.api/cas-parser-java)](https://central.sonatype.com/artifact/com.cas_parser.api/cas-parser-java/0.2.0) +[![javadoc](https://javadoc.io/badge2/com.cas_parser.api/cas-parser-java/0.2.0/javadoc.svg)](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.2.0) @@ -22,7 +22,7 @@ Use the Cas Parser MCP Server to enable AI assistants to interact with this API, -Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.1.0). +Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.2.0). @@ -33,7 +33,7 @@ Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.cas_parser.api ### Gradle ```kotlin -implementation("com.cas_parser.api:cas-parser-java:0.1.0") +implementation("com.cas_parser.api:cas-parser-java:0.2.0") ``` ### Maven @@ -42,7 +42,7 @@ implementation("com.cas_parser.api:cas-parser-java:0.1.0") com.cas_parser.api cas-parser-java - 0.1.0 + 0.2.0 ``` diff --git a/build.gradle.kts b/build.gradle.kts index 30b3cae..55b241b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -9,7 +9,7 @@ repositories { allprojects { group = "com.cas_parser.api" - version = "0.1.0" // x-release-please-version + version = "0.2.0" // x-release-please-version } subprojects { From 6f6ad46ec22abeb8ae2561f51987c42e8212e7e7 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 14 Feb 2026 00:57:03 +0000 Subject: [PATCH 38/99] chore: update SDK settings --- .stats.yml | 2 +- README.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.stats.yml b/.stats.yml index 4d62cd0..8281628 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 17 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-56b0f699c5437d9e5326626d35dfc972c17d01f12cb416c7f4854c8ea6d0e95e.yml openapi_spec_hash: 158f405c1880706266d83e6ff16b9d2f -config_hash: 1af2e938c93ea4ec25fc633469072c43 +config_hash: bb1b61e2661a7ef2d197a0d4012e9e8a diff --git a/README.md b/README.md index 3d0bf3f..7d7a635 100644 --- a/README.md +++ b/README.md @@ -15,8 +15,8 @@ It is generated with [Stainless](https://www.stainless.com/). Use the Cas Parser MCP Server to enable AI assistants to interact with this API, allowing them to explore endpoints, make test requests, and use documentation to help integrate this SDK into your application. -[![Add to Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en-US/install-mcp?name=cas-parser-mcp&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsImNhcy1wYXJzZXItbWNwIl0sImVudiI6eyJDQVNfUEFSU0VSX0FQSV9LRVkiOiJNeSBBUEkgS2V5In19) -[![Install in VS Code](https://img.shields.io/badge/_-Add_to_VS_Code-blue?style=for-the-badge&logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9Im5vbmUiIHZpZXdCb3g9IjAgMCA0MCA0MCI+PHBhdGggZmlsbD0iI0VFRSIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMzAuMjM1IDM5Ljg4NGEyLjQ5MSAyLjQ5MSAwIDAgMS0xLjc4MS0uNzNMMTIuNyAyNC43OGwtMy40NiAyLjYyNC0zLjQwNiAyLjU4MmExLjY2NSAxLjY2NSAwIDAgMS0xLjA4Mi4zMzggMS42NjQgMS42NjQgMCAwIDEtMS4wNDYtLjQzMWwtMi4yLTJhMS42NjYgMS42NjYgMCAwIDEgMC0yLjQ2M0w3LjQ1OCAyMCA0LjY3IDE3LjQ1MyAxLjUwNyAxNC41N2ExLjY2NSAxLjY2NSAwIDAgMSAwLTIuNDYzbDIuMi0yYTEuNjY1IDEuNjY1IDAgMCAxIDIuMTMtLjA5N2w2Ljg2MyA1LjIwOUwyOC40NTIuODQ0YTIuNDg4IDIuNDg4IDAgMCAxIDEuODQxLS43MjljLjM1MS4wMDkuNjk5LjA5MSAxLjAxOS4yNDVsOC4yMzYgMy45NjFhMi41IDIuNSAwIDAgMSAxLjQxNSAyLjI1M3YuMDk5LS4wNDVWMzMuMzd2LS4wNDUuMDk1YTIuNTAxIDIuNTAxIDAgMCAxLTEuNDE2IDIuMjU3bC04LjIzNSAzLjk2MWEyLjQ5MiAyLjQ5MiAwIDAgMS0xLjA3Ny4yNDZabS43MTYtMjguOTQ3LTExLjk0OCA5LjA2MiAxMS45NTIgOS4wNjUtLjAwNC0xOC4xMjdaIi8+PC9zdmc+)](https://vscode.stainless.com/mcp/%7B%22name%22%3A%22cas-parser-mcp%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22cas-parser-mcp%22%5D%2C%22env%22%3A%7B%22CAS_PARSER_API_KEY%22%3A%22My%20API%20Key%22%7D%7D) +[![Add to Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en-US/install-mcp?name=cas-parser-mcp&config=eyJuYW1lIjoiY2FzLXBhcnNlci1tY3AiLCJ0cmFuc3BvcnQiOiJodHRwIiwidXJsIjoiaHR0cHM6Ly9jYXMtcGFyc2VyLnN0bG1jcC5jb20iLCJoZWFkZXJzIjp7IngtYXBpLWtleSI6Ik15IEFQSSBLZXkifX0) +[![Install in VS Code](https://img.shields.io/badge/_-Add_to_VS_Code-blue?style=for-the-badge&logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9Im5vbmUiIHZpZXdCb3g9IjAgMCA0MCA0MCI+PHBhdGggZmlsbD0iI0VFRSIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMzAuMjM1IDM5Ljg4NGEyLjQ5MSAyLjQ5MSAwIDAgMS0xLjc4MS0uNzNMMTIuNyAyNC43OGwtMy40NiAyLjYyNC0zLjQwNiAyLjU4MmExLjY2NSAxLjY2NSAwIDAgMS0xLjA4Mi4zMzggMS42NjQgMS42NjQgMCAwIDEtMS4wNDYtLjQzMWwtMi4yLTJhMS42NjYgMS42NjYgMCAwIDEgMC0yLjQ2M0w3LjQ1OCAyMCA0LjY3IDE3LjQ1MyAxLjUwNyAxNC41N2ExLjY2NSAxLjY2NSAwIDAgMSAwLTIuNDYzbDIuMi0yYTEuNjY1IDEuNjY1IDAgMCAxIDIuMTMtLjA5N2w2Ljg2MyA1LjIwOUwyOC40NTIuODQ0YTIuNDg4IDIuNDg4IDAgMCAxIDEuODQxLS43MjljLjM1MS4wMDkuNjk5LjA5MSAxLjAxOS4yNDVsOC4yMzYgMy45NjFhMi41IDIuNSAwIDAgMSAxLjQxNSAyLjI1M3YuMDk5LS4wNDVWMzMuMzd2LS4wNDUuMDk1YTIuNTAxIDIuNTAxIDAgMCAxLTEuNDE2IDIuMjU3bC04LjIzNSAzLjk2MWEyLjQ5MiAyLjQ5MiAwIDAgMS0xLjA3Ny4yNDZabS43MTYtMjguOTQ3LTExLjk0OCA5LjA2MiAxMS45NTIgOS4wNjUtLjAwNC0xOC4xMjdaIi8+PC9zdmc+)](https://vscode.stainless.com/mcp/%7B%22name%22%3A%22cas-parser-mcp%22%2C%22type%22%3A%22http%22%2C%22url%22%3A%22https%3A%2F%2Fcas-parser.stlmcp.com%22%2C%22headers%22%3A%7B%22x-api-key%22%3A%22My%20API%20Key%22%7D%7D) > Note: You may need to set environment variables in your MCP client. From 210682c284aa279e35263b9e26f74736397ebe6a Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 14 Feb 2026 00:57:12 +0000 Subject: [PATCH 39/99] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index 8281628..415d8d1 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 17 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-56b0f699c5437d9e5326626d35dfc972c17d01f12cb416c7f4854c8ea6d0e95e.yml openapi_spec_hash: 158f405c1880706266d83e6ff16b9d2f -config_hash: bb1b61e2661a7ef2d197a0d4012e9e8a +config_hash: 97b6c66e88343f85b8b173ee4457919f From 476dbd1a688c8f218a7ea8cdedef28ac27d9f00b Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 14 Feb 2026 00:58:34 +0000 Subject: [PATCH 40/99] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index 415d8d1..a41a618 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 17 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-56b0f699c5437d9e5326626d35dfc972c17d01f12cb416c7f4854c8ea6d0e95e.yml openapi_spec_hash: 158f405c1880706266d83e6ff16b9d2f -config_hash: 97b6c66e88343f85b8b173ee4457919f +config_hash: 11ccfc363acca397f243709a8a097bb7 From 7c94d7acf7f7e3d0d0769379b4f5b234a1bc91a8 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 14 Feb 2026 00:58:43 +0000 Subject: [PATCH 41/99] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index a41a618..e7c969a 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 17 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-56b0f699c5437d9e5326626d35dfc972c17d01f12cb416c7f4854c8ea6d0e95e.yml openapi_spec_hash: 158f405c1880706266d83e6ff16b9d2f -config_hash: 11ccfc363acca397f243709a8a097bb7 +config_hash: e78bb30ba7c06b2a6d20092a5872aec2 From 71f2babfaa20c5732822ff7ef7ba8504e98c72c1 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 14 Feb 2026 01:05:40 +0000 Subject: [PATCH 42/99] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index e7c969a..917f8d3 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 17 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-56b0f699c5437d9e5326626d35dfc972c17d01f12cb416c7f4854c8ea6d0e95e.yml openapi_spec_hash: 158f405c1880706266d83e6ff16b9d2f -config_hash: e78bb30ba7c06b2a6d20092a5872aec2 +config_hash: 3984d901dd3643875b212ecb24263a9d From fb59b40e16717d3db8d1906acb193048d1e8181f Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 14 Feb 2026 01:29:40 +0000 Subject: [PATCH 43/99] chore(internal): version bump --- .release-please-manifest.json | 2 +- README.md | 10 +++++----- build.gradle.kts | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 10f3091..b06ba91 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.2.0" + ".": "0.2.1" } \ No newline at end of file diff --git a/README.md b/README.md index 7d7a635..d659d06 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ -[![Maven Central](https://img.shields.io/maven-central/v/com.cas_parser.api/cas-parser-java)](https://central.sonatype.com/artifact/com.cas_parser.api/cas-parser-java/0.2.0) -[![javadoc](https://javadoc.io/badge2/com.cas_parser.api/cas-parser-java/0.2.0/javadoc.svg)](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.2.0) +[![Maven Central](https://img.shields.io/maven-central/v/com.cas_parser.api/cas-parser-java)](https://central.sonatype.com/artifact/com.cas_parser.api/cas-parser-java/0.2.1) +[![javadoc](https://javadoc.io/badge2/com.cas_parser.api/cas-parser-java/0.2.1/javadoc.svg)](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.2.1) @@ -22,7 +22,7 @@ Use the Cas Parser MCP Server to enable AI assistants to interact with this API, -Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.2.0). +Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.2.1). @@ -33,7 +33,7 @@ Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.cas_parser.api ### Gradle ```kotlin -implementation("com.cas_parser.api:cas-parser-java:0.2.0") +implementation("com.cas_parser.api:cas-parser-java:0.2.1") ``` ### Maven @@ -42,7 +42,7 @@ implementation("com.cas_parser.api:cas-parser-java:0.2.0") com.cas_parser.api cas-parser-java - 0.2.0 + 0.2.1 ``` diff --git a/build.gradle.kts b/build.gradle.kts index 55b241b..a705ba2 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -9,7 +9,7 @@ repositories { allprojects { group = "com.cas_parser.api" - version = "0.2.0" // x-release-please-version + version = "0.2.1" // x-release-please-version } subprojects { From 16736eb1f9a8bd3a071496a83dfe42f6ad96cce8 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 14 Feb 2026 01:31:16 +0000 Subject: [PATCH 44/99] feat(api): manual updates --- .stats.yml | 2 +- README.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.stats.yml b/.stats.yml index 917f8d3..9dc7546 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 17 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-56b0f699c5437d9e5326626d35dfc972c17d01f12cb416c7f4854c8ea6d0e95e.yml openapi_spec_hash: 158f405c1880706266d83e6ff16b9d2f -config_hash: 3984d901dd3643875b212ecb24263a9d +config_hash: 71b56825479262e2a16b9a2fe978c174 diff --git a/README.md b/README.md index d659d06..fa81071 100644 --- a/README.md +++ b/README.md @@ -15,8 +15,8 @@ It is generated with [Stainless](https://www.stainless.com/). Use the Cas Parser MCP Server to enable AI assistants to interact with this API, allowing them to explore endpoints, make test requests, and use documentation to help integrate this SDK into your application. -[![Add to Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en-US/install-mcp?name=cas-parser-mcp&config=eyJuYW1lIjoiY2FzLXBhcnNlci1tY3AiLCJ0cmFuc3BvcnQiOiJodHRwIiwidXJsIjoiaHR0cHM6Ly9jYXMtcGFyc2VyLnN0bG1jcC5jb20iLCJoZWFkZXJzIjp7IngtYXBpLWtleSI6Ik15IEFQSSBLZXkifX0) -[![Install in VS Code](https://img.shields.io/badge/_-Add_to_VS_Code-blue?style=for-the-badge&logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9Im5vbmUiIHZpZXdCb3g9IjAgMCA0MCA0MCI+PHBhdGggZmlsbD0iI0VFRSIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMzAuMjM1IDM5Ljg4NGEyLjQ5MSAyLjQ5MSAwIDAgMS0xLjc4MS0uNzNMMTIuNyAyNC43OGwtMy40NiAyLjYyNC0zLjQwNiAyLjU4MmExLjY2NSAxLjY2NSAwIDAgMS0xLjA4Mi4zMzggMS42NjQgMS42NjQgMCAwIDEtMS4wNDYtLjQzMWwtMi4yLTJhMS42NjYgMS42NjYgMCAwIDEgMC0yLjQ2M0w3LjQ1OCAyMCA0LjY3IDE3LjQ1MyAxLjUwNyAxNC41N2ExLjY2NSAxLjY2NSAwIDAgMSAwLTIuNDYzbDIuMi0yYTEuNjY1IDEuNjY1IDAgMCAxIDIuMTMtLjA5N2w2Ljg2MyA1LjIwOUwyOC40NTIuODQ0YTIuNDg4IDIuNDg4IDAgMCAxIDEuODQxLS43MjljLjM1MS4wMDkuNjk5LjA5MSAxLjAxOS4yNDVsOC4yMzYgMy45NjFhMi41IDIuNSAwIDAgMSAxLjQxNSAyLjI1M3YuMDk5LS4wNDVWMzMuMzd2LS4wNDUuMDk1YTIuNTAxIDIuNTAxIDAgMCAxLTEuNDE2IDIuMjU3bC04LjIzNSAzLjk2MWEyLjQ5MiAyLjQ5MiAwIDAgMS0xLjA3Ny4yNDZabS43MTYtMjguOTQ3LTExLjk0OCA5LjA2MiAxMS45NTIgOS4wNjUtLjAwNC0xOC4xMjdaIi8+PC9zdmc+)](https://vscode.stainless.com/mcp/%7B%22name%22%3A%22cas-parser-mcp%22%2C%22type%22%3A%22http%22%2C%22url%22%3A%22https%3A%2F%2Fcas-parser.stlmcp.com%22%2C%22headers%22%3A%7B%22x-api-key%22%3A%22My%20API%20Key%22%7D%7D) +[![Add to Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en-US/install-mcp?name=cas-parser-node-mcp&config=eyJuYW1lIjoiY2FzLXBhcnNlci1ub2RlLW1jcCIsInRyYW5zcG9ydCI6Imh0dHAiLCJ1cmwiOiJodHRwczovL2Nhcy1wYXJzZXIuc3RsbWNwLmNvbSIsImhlYWRlcnMiOnsieC1hcGkta2V5IjoiTXkgQVBJIEtleSJ9fQ) +[![Install in VS Code](https://img.shields.io/badge/_-Add_to_VS_Code-blue?style=for-the-badge&logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9Im5vbmUiIHZpZXdCb3g9IjAgMCA0MCA0MCI+PHBhdGggZmlsbD0iI0VFRSIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMzAuMjM1IDM5Ljg4NGEyLjQ5MSAyLjQ5MSAwIDAgMS0xLjc4MS0uNzNMMTIuNyAyNC43OGwtMy40NiAyLjYyNC0zLjQwNiAyLjU4MmExLjY2NSAxLjY2NSAwIDAgMS0xLjA4Mi4zMzggMS42NjQgMS42NjQgMCAwIDEtMS4wNDYtLjQzMWwtMi4yLTJhMS42NjYgMS42NjYgMCAwIDEgMC0yLjQ2M0w3LjQ1OCAyMCA0LjY3IDE3LjQ1MyAxLjUwNyAxNC41N2ExLjY2NSAxLjY2NSAwIDAgMSAwLTIuNDYzbDIuMi0yYTEuNjY1IDEuNjY1IDAgMCAxIDIuMTMtLjA5N2w2Ljg2MyA1LjIwOUwyOC40NTIuODQ0YTIuNDg4IDIuNDg4IDAgMCAxIDEuODQxLS43MjljLjM1MS4wMDkuNjk5LjA5MSAxLjAxOS4yNDVsOC4yMzYgMy45NjFhMi41IDIuNSAwIDAgMSAxLjQxNSAyLjI1M3YuMDk5LS4wNDVWMzMuMzd2LS4wNDUuMDk1YTIuNTAxIDIuNTAxIDAgMCAxLTEuNDE2IDIuMjU3bC04LjIzNSAzLjk2MWEyLjQ5MiAyLjQ5MiAwIDAgMS0xLjA3Ny4yNDZabS43MTYtMjguOTQ3LTExLjk0OCA5LjA2MiAxMS45NTIgOS4wNjUtLjAwNC0xOC4xMjdaIi8+PC9zdmc+)](https://vscode.stainless.com/mcp/%7B%22name%22%3A%22cas-parser-node-mcp%22%2C%22type%22%3A%22http%22%2C%22url%22%3A%22https%3A%2F%2Fcas-parser.stlmcp.com%22%2C%22headers%22%3A%7B%22x-api-key%22%3A%22My%20API%20Key%22%7D%7D) > Note: You may need to set environment variables in your MCP client. From 34e1e4413c06cf2034f36c61cae751558bed041b Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 14 Feb 2026 01:31:34 +0000 Subject: [PATCH 45/99] feat(api): manual updates --- .stats.yml | 2 +- README.md | 4 ++-- buildSrc/src/main/kotlin/cas-parser.publish.gradle.kts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.stats.yml b/.stats.yml index 9dc7546..32808d2 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 17 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-56b0f699c5437d9e5326626d35dfc972c17d01f12cb416c7f4854c8ea6d0e95e.yml openapi_spec_hash: 158f405c1880706266d83e6ff16b9d2f -config_hash: 71b56825479262e2a16b9a2fe978c174 +config_hash: ab495a165f0919b37cbf9efbd0f0e6ef diff --git a/README.md b/README.md index fa81071..02cd334 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ -The Cas Parser Java SDK provides convenient access to the Cas Parser REST API from applications written in Java. +The Cas Parser Java SDK provides convenient access to the [Cas Parser REST API](https://docs.casparser.in) from applications written in Java. It is generated with [Stainless](https://www.stainless.com/). @@ -22,7 +22,7 @@ Use the Cas Parser MCP Server to enable AI assistants to interact with this API, -Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.2.1). +The REST API documentation can be found on [docs.casparser.in](https://docs.casparser.in). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.2.1). diff --git a/buildSrc/src/main/kotlin/cas-parser.publish.gradle.kts b/buildSrc/src/main/kotlin/cas-parser.publish.gradle.kts index 56f585c..e7683ee 100644 --- a/buildSrc/src/main/kotlin/cas-parser.publish.gradle.kts +++ b/buildSrc/src/main/kotlin/cas-parser.publish.gradle.kts @@ -11,7 +11,7 @@ configure { pom { name.set("CAS Parser - Track Portfolios from CDSL, NSDL, CAMS, KFintech") description.set("API for parsing and analyzing CAS (Consolidated Account Statement) PDF files\nfrom NSDL, CDSL, and CAMS/KFintech, with a unified response format") - url.set("https://www.github.com/CASParser/cas-parser-java") + url.set("https://docs.casparser.in") licenses { license { From eebd8b50f4385b4dec3ad51cd2797c55b832eaef Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 14 Feb 2026 01:33:43 +0000 Subject: [PATCH 46/99] chore(internal): version bump --- .release-please-manifest.json | 2 +- README.md | 10 +++++----- build.gradle.kts | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index b06ba91..6b7b74c 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.2.1" + ".": "0.3.0" } \ No newline at end of file diff --git a/README.md b/README.md index 02cd334..c55a4ea 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ -[![Maven Central](https://img.shields.io/maven-central/v/com.cas_parser.api/cas-parser-java)](https://central.sonatype.com/artifact/com.cas_parser.api/cas-parser-java/0.2.1) -[![javadoc](https://javadoc.io/badge2/com.cas_parser.api/cas-parser-java/0.2.1/javadoc.svg)](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.2.1) +[![Maven Central](https://img.shields.io/maven-central/v/com.cas_parser.api/cas-parser-java)](https://central.sonatype.com/artifact/com.cas_parser.api/cas-parser-java/0.3.0) +[![javadoc](https://javadoc.io/badge2/com.cas_parser.api/cas-parser-java/0.3.0/javadoc.svg)](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.3.0) @@ -22,7 +22,7 @@ Use the Cas Parser MCP Server to enable AI assistants to interact with this API, -The REST API documentation can be found on [docs.casparser.in](https://docs.casparser.in). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.2.1). +The REST API documentation can be found on [docs.casparser.in](https://docs.casparser.in). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.3.0). @@ -33,7 +33,7 @@ The REST API documentation can be found on [docs.casparser.in](https://docs.casp ### Gradle ```kotlin -implementation("com.cas_parser.api:cas-parser-java:0.2.1") +implementation("com.cas_parser.api:cas-parser-java:0.3.0") ``` ### Maven @@ -42,7 +42,7 @@ implementation("com.cas_parser.api:cas-parser-java:0.2.1") com.cas_parser.api cas-parser-java - 0.2.1 + 0.3.0 ``` diff --git a/build.gradle.kts b/build.gradle.kts index a705ba2..90d29ec 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -9,7 +9,7 @@ repositories { allprojects { group = "com.cas_parser.api" - version = "0.2.1" // x-release-please-version + version = "0.3.0" // x-release-please-version } subprojects { From 00915b86d63138ce083e14329cca5daa4fbcc003 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 14 Feb 2026 01:43:46 +0000 Subject: [PATCH 47/99] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index 32808d2..56f5a81 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 17 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-56b0f699c5437d9e5326626d35dfc972c17d01f12cb416c7f4854c8ea6d0e95e.yml openapi_spec_hash: 158f405c1880706266d83e6ff16b9d2f -config_hash: ab495a165f0919b37cbf9efbd0f0e6ef +config_hash: 41c337f5cda03b13880617490f82bad0 From e1435a789b9db76831864f5695b35ef874a99664 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 14 Feb 2026 01:43:55 +0000 Subject: [PATCH 48/99] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index 56f5a81..32808d2 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 17 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-56b0f699c5437d9e5326626d35dfc972c17d01f12cb416c7f4854c8ea6d0e95e.yml openapi_spec_hash: 158f405c1880706266d83e6ff16b9d2f -config_hash: 41c337f5cda03b13880617490f82bad0 +config_hash: ab495a165f0919b37cbf9efbd0f0e6ef From 78f54d9d26cc93f0f0908fff0ad23164d0a3025c Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 14 Feb 2026 01:44:22 +0000 Subject: [PATCH 49/99] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index 32808d2..56f5a81 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 17 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-56b0f699c5437d9e5326626d35dfc972c17d01f12cb416c7f4854c8ea6d0e95e.yml openapi_spec_hash: 158f405c1880706266d83e6ff16b9d2f -config_hash: ab495a165f0919b37cbf9efbd0f0e6ef +config_hash: 41c337f5cda03b13880617490f82bad0 From 5365f42fd61ef402d19984b1e3ac512317f09f47 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 18 Feb 2026 04:40:05 +0000 Subject: [PATCH 50/99] chore(internal): update `TestServerExtension` comment --- .../com/cas_parser/api/TestServerExtension.kt | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/TestServerExtension.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/TestServerExtension.kt index a567645..7b684c2 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/TestServerExtension.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/TestServerExtension.kt @@ -15,25 +15,12 @@ class TestServerExtension : BeforeAllCallback, ExecutionCondition { } catch (e: Exception) { throw RuntimeException( """ - The test suite will not run without a mock Prism server running against your OpenAPI spec. + The test suite will not run without a mock server running against your OpenAPI spec. You can set the environment variable `SKIP_MOCK_TESTS` to `true` to skip running any tests that require the mock server. - To fix: - - 1. Install Prism (requires Node 16+): - - With npm: - $ npm install -g @stoplight/prism-cli - - With yarn: - $ yarn global add @stoplight/prism-cli - - 2. Run the mock server - - To run the server, pass in the path of your OpenAPI spec to the prism command: - $ prism mock path/to/your.openapi.yml + To fix run `./scripts/mock` in a separate terminal. """ .trimIndent(), e, From c7bf5c16faaae45b2f74a9da6f01b65b363e6f10 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 19 Feb 2026 04:32:12 +0000 Subject: [PATCH 51/99] chore(internal): make `OkHttp` constructor internal --- .../kotlin/com/cas_parser/api/client/okhttp/OkHttpClient.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/OkHttpClient.kt b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/OkHttpClient.kt index 7079d3c..9cfdd63 100644 --- a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/OkHttpClient.kt +++ b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/OkHttpClient.kt @@ -33,7 +33,7 @@ import okhttp3.logging.HttpLoggingInterceptor import okio.BufferedSink class OkHttpClient -private constructor(@JvmSynthetic internal val okHttpClient: okhttp3.OkHttpClient) : HttpClient { +internal constructor(@JvmSynthetic internal val okHttpClient: okhttp3.OkHttpClient) : HttpClient { override fun execute(request: HttpRequest, requestOptions: RequestOptions): HttpResponse { val call = newCall(request, requestOptions) From ed1530b635cac83e866c6c303ac097de0015f334 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 19 Feb 2026 04:35:40 +0000 Subject: [PATCH 52/99] feat(client): add connection pooling option --- README.md | 19 ++++++++ .../client/okhttp/CasParserOkHttpClient.kt | 44 +++++++++++++++++++ .../okhttp/CasParserOkHttpClientAsync.kt | 44 +++++++++++++++++++ .../api/client/okhttp/OkHttpClient.kt | 42 ++++++++++++++++++ 4 files changed, 149 insertions(+) diff --git a/README.md b/README.md index c55a4ea..212151b 100644 --- a/README.md +++ b/README.md @@ -342,6 +342,25 @@ CasParserClient client = CasParserOkHttpClient.builder() .build(); ``` +### Connection pooling + +To customize the underlying OkHttp connection pool, configure the client using the `maxIdleConnections` and `keepAliveDuration` methods: + +```java +import com.cas_parser.api.client.CasParserClient; +import com.cas_parser.api.client.okhttp.CasParserOkHttpClient; +import java.time.Duration; + +CasParserClient client = CasParserOkHttpClient.builder() + .fromEnv() + // If `maxIdleConnections` is set, then `keepAliveDuration` must be set, and vice versa. + .maxIdleConnections(10) + .keepAliveDuration(Duration.ofMinutes(2)) + .build(); +``` + +If both options are unset, OkHttp's default connection pool settings are used. + ### HTTPS > [!NOTE] diff --git a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClient.kt b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClient.kt index dc713f6..417682f 100644 --- a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClient.kt +++ b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClient.kt @@ -47,6 +47,8 @@ class CasParserOkHttpClient private constructor() { private var clientOptions: ClientOptions.Builder = ClientOptions.builder() private var dispatcherExecutorService: ExecutorService? = null private var proxy: Proxy? = null + private var maxIdleConnections: Int? = null + private var keepAliveDuration: Duration? = null private var sslSocketFactory: SSLSocketFactory? = null private var trustManager: X509TrustManager? = null private var hostnameVerifier: HostnameVerifier? = null @@ -75,6 +77,46 @@ class CasParserOkHttpClient private constructor() { /** Alias for calling [Builder.proxy] with `proxy.orElse(null)`. */ fun proxy(proxy: Optional) = proxy(proxy.getOrNull()) + /** + * The maximum number of idle connections kept by the underlying OkHttp connection pool. + * + * If this is set, then [keepAliveDuration] must also be set. + * + * If unset, then OkHttp's default is used. + */ + fun maxIdleConnections(maxIdleConnections: Int?) = apply { + this.maxIdleConnections = maxIdleConnections + } + + /** + * Alias for [Builder.maxIdleConnections]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun maxIdleConnections(maxIdleConnections: Int) = + maxIdleConnections(maxIdleConnections as Int?) + + /** + * Alias for calling [Builder.maxIdleConnections] with `maxIdleConnections.orElse(null)`. + */ + fun maxIdleConnections(maxIdleConnections: Optional) = + maxIdleConnections(maxIdleConnections.getOrNull()) + + /** + * The keep-alive duration for idle connections in the underlying OkHttp connection pool. + * + * If this is set, then [maxIdleConnections] must also be set. + * + * If unset, then OkHttp's default is used. + */ + fun keepAliveDuration(keepAliveDuration: Duration?) = apply { + this.keepAliveDuration = keepAliveDuration + } + + /** Alias for calling [Builder.keepAliveDuration] with `keepAliveDuration.orElse(null)`. */ + fun keepAliveDuration(keepAliveDuration: Optional) = + keepAliveDuration(keepAliveDuration.getOrNull()) + /** * The socket factory used to secure HTTPS connections. * @@ -328,6 +370,8 @@ class CasParserOkHttpClient private constructor() { OkHttpClient.builder() .timeout(clientOptions.timeout()) .proxy(proxy) + .maxIdleConnections(maxIdleConnections) + .keepAliveDuration(keepAliveDuration) .dispatcherExecutorService(dispatcherExecutorService) .sslSocketFactory(sslSocketFactory) .trustManager(trustManager) diff --git a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClientAsync.kt b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClientAsync.kt index 5d4beab..e83fa10 100644 --- a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClientAsync.kt +++ b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClientAsync.kt @@ -47,6 +47,8 @@ class CasParserOkHttpClientAsync private constructor() { private var clientOptions: ClientOptions.Builder = ClientOptions.builder() private var dispatcherExecutorService: ExecutorService? = null private var proxy: Proxy? = null + private var maxIdleConnections: Int? = null + private var keepAliveDuration: Duration? = null private var sslSocketFactory: SSLSocketFactory? = null private var trustManager: X509TrustManager? = null private var hostnameVerifier: HostnameVerifier? = null @@ -75,6 +77,46 @@ class CasParserOkHttpClientAsync private constructor() { /** Alias for calling [Builder.proxy] with `proxy.orElse(null)`. */ fun proxy(proxy: Optional) = proxy(proxy.getOrNull()) + /** + * The maximum number of idle connections kept by the underlying OkHttp connection pool. + * + * If this is set, then [keepAliveDuration] must also be set. + * + * If unset, then OkHttp's default is used. + */ + fun maxIdleConnections(maxIdleConnections: Int?) = apply { + this.maxIdleConnections = maxIdleConnections + } + + /** + * Alias for [Builder.maxIdleConnections]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun maxIdleConnections(maxIdleConnections: Int) = + maxIdleConnections(maxIdleConnections as Int?) + + /** + * Alias for calling [Builder.maxIdleConnections] with `maxIdleConnections.orElse(null)`. + */ + fun maxIdleConnections(maxIdleConnections: Optional) = + maxIdleConnections(maxIdleConnections.getOrNull()) + + /** + * The keep-alive duration for idle connections in the underlying OkHttp connection pool. + * + * If this is set, then [maxIdleConnections] must also be set. + * + * If unset, then OkHttp's default is used. + */ + fun keepAliveDuration(keepAliveDuration: Duration?) = apply { + this.keepAliveDuration = keepAliveDuration + } + + /** Alias for calling [Builder.keepAliveDuration] with `keepAliveDuration.orElse(null)`. */ + fun keepAliveDuration(keepAliveDuration: Optional) = + keepAliveDuration(keepAliveDuration.getOrNull()) + /** * The socket factory used to secure HTTPS connections. * @@ -328,6 +370,8 @@ class CasParserOkHttpClientAsync private constructor() { OkHttpClient.builder() .timeout(clientOptions.timeout()) .proxy(proxy) + .maxIdleConnections(maxIdleConnections) + .keepAliveDuration(keepAliveDuration) .dispatcherExecutorService(dispatcherExecutorService) .sslSocketFactory(sslSocketFactory) .trustManager(trustManager) diff --git a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/OkHttpClient.kt b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/OkHttpClient.kt index 9cfdd63..7bc37ab 100644 --- a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/OkHttpClient.kt +++ b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/OkHttpClient.kt @@ -16,11 +16,13 @@ import java.time.Duration import java.util.concurrent.CancellationException import java.util.concurrent.CompletableFuture import java.util.concurrent.ExecutorService +import java.util.concurrent.TimeUnit import javax.net.ssl.HostnameVerifier import javax.net.ssl.SSLSocketFactory import javax.net.ssl.X509TrustManager import okhttp3.Call import okhttp3.Callback +import okhttp3.ConnectionPool import okhttp3.Dispatcher import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.MediaType @@ -200,6 +202,8 @@ internal constructor(@JvmSynthetic internal val okHttpClient: okhttp3.OkHttpClie private var timeout: Timeout = Timeout.default() private var proxy: Proxy? = null + private var maxIdleConnections: Int? = null + private var keepAliveDuration: Duration? = null private var dispatcherExecutorService: ExecutorService? = null private var sslSocketFactory: SSLSocketFactory? = null private var trustManager: X509TrustManager? = null @@ -211,6 +215,28 @@ internal constructor(@JvmSynthetic internal val okHttpClient: okhttp3.OkHttpClie fun proxy(proxy: Proxy?) = apply { this.proxy = proxy } + /** + * Sets the maximum number of idle connections kept by the underlying [ConnectionPool]. + * + * If this is set, then [keepAliveDuration] must also be set. + * + * If unset, then OkHttp's default is used. + */ + fun maxIdleConnections(maxIdleConnections: Int?) = apply { + this.maxIdleConnections = maxIdleConnections + } + + /** + * Sets the keep-alive duration for idle connections in the underlying [ConnectionPool]. + * + * If this is set, then [maxIdleConnections] must also be set. + * + * If unset, then OkHttp's default is used. + */ + fun keepAliveDuration(keepAliveDuration: Duration?) = apply { + this.keepAliveDuration = keepAliveDuration + } + fun dispatcherExecutorService(dispatcherExecutorService: ExecutorService?) = apply { this.dispatcherExecutorService = dispatcherExecutorService } @@ -240,6 +266,22 @@ internal constructor(@JvmSynthetic internal val okHttpClient: okhttp3.OkHttpClie .apply { dispatcherExecutorService?.let { dispatcher(Dispatcher(it)) } + val maxIdleConnections = maxIdleConnections + val keepAliveDuration = keepAliveDuration + if (maxIdleConnections != null && keepAliveDuration != null) { + connectionPool( + ConnectionPool( + maxIdleConnections, + keepAliveDuration.toNanos(), + TimeUnit.NANOSECONDS, + ) + ) + } else { + check((maxIdleConnections != null) == (keepAliveDuration != null)) { + "Both or none of `maxIdleConnections` and `keepAliveDuration` must be set, but only one was set" + } + } + val sslSocketFactory = sslSocketFactory val trustManager = trustManager if (sslSocketFactory != null && trustManager != null) { From 6081f46c1ce970584fbef526cccba6fb1be42efb Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 20 Feb 2026 05:23:00 +0000 Subject: [PATCH 53/99] chore(internal): remove mock server code --- .../com/cas_parser/api/TestServerExtension.kt | 49 ------------------- .../async/AccessTokenServiceAsyncTest.kt | 9 +--- .../async/CamsKfintechServiceAsyncTest.kt | 9 +--- .../services/async/CdslServiceAsyncTest.kt | 9 +--- .../async/ContractNoteServiceAsyncTest.kt | 9 +--- .../services/async/CreditServiceAsyncTest.kt | 9 +--- .../services/async/InboxServiceAsyncTest.kt | 27 ++-------- .../async/KfintechServiceAsyncTest.kt | 9 +--- .../api/services/async/LogServiceAsyncTest.kt | 15 +----- .../services/async/NsdlServiceAsyncTest.kt | 9 +--- .../services/async/SmartServiceAsyncTest.kt | 9 +--- .../async/VerifyTokenServiceAsyncTest.kt | 9 +--- .../async/cdsl/FetchServiceAsyncTest.kt | 15 +----- .../blocking/AccessTokenServiceTest.kt | 9 +--- .../blocking/CamsKfintechServiceTest.kt | 9 +--- .../api/services/blocking/CdslServiceTest.kt | 9 +--- .../blocking/ContractNoteServiceTest.kt | 9 +--- .../services/blocking/CreditServiceTest.kt | 9 +--- .../api/services/blocking/InboxServiceTest.kt | 27 ++-------- .../services/blocking/KfintechServiceTest.kt | 9 +--- .../api/services/blocking/LogServiceTest.kt | 15 +----- .../api/services/blocking/NsdlServiceTest.kt | 9 +--- .../api/services/blocking/SmartServiceTest.kt | 9 +--- .../blocking/VerifyTokenServiceTest.kt | 9 +--- .../blocking/cdsl/FetchServiceTest.kt | 15 +----- scripts/mock | 41 ---------------- scripts/test | 46 ----------------- 27 files changed, 34 insertions(+), 378 deletions(-) delete mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/TestServerExtension.kt delete mode 100755 scripts/mock diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/TestServerExtension.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/TestServerExtension.kt deleted file mode 100644 index 7b684c2..0000000 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/TestServerExtension.kt +++ /dev/null @@ -1,49 +0,0 @@ -package com.cas_parser.api - -import java.lang.RuntimeException -import java.net.URL -import org.junit.jupiter.api.extension.BeforeAllCallback -import org.junit.jupiter.api.extension.ConditionEvaluationResult -import org.junit.jupiter.api.extension.ExecutionCondition -import org.junit.jupiter.api.extension.ExtensionContext - -class TestServerExtension : BeforeAllCallback, ExecutionCondition { - - override fun beforeAll(context: ExtensionContext?) { - try { - URL(BASE_URL).openConnection().connect() - } catch (e: Exception) { - throw RuntimeException( - """ - The test suite will not run without a mock server running against your OpenAPI spec. - - You can set the environment variable `SKIP_MOCK_TESTS` to `true` to skip running any tests - that require the mock server. - - To fix run `./scripts/mock` in a separate terminal. - """ - .trimIndent(), - e, - ) - } - } - - override fun evaluateExecutionCondition(context: ExtensionContext): ConditionEvaluationResult { - return if (System.getenv(SKIP_TESTS_ENV).toBoolean()) { - ConditionEvaluationResult.disabled( - "Environment variable $SKIP_TESTS_ENV is set to true" - ) - } else { - ConditionEvaluationResult.enabled( - "Environment variable $SKIP_TESTS_ENV is not set to true" - ) - } - } - - companion object { - - val BASE_URL = System.getenv("TEST_API_BASE_URL") ?: "http://localhost:4010" - - const val SKIP_TESTS_ENV: String = "SKIP_MOCK_TESTS" - } -} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsyncTest.kt index d1a2caa..bb9558e 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsyncTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsyncTest.kt @@ -2,24 +2,17 @@ package com.cas_parser.api.services.async -import com.cas_parser.api.TestServerExtension import com.cas_parser.api.client.okhttp.CasParserOkHttpClientAsync import com.cas_parser.api.models.accesstoken.AccessTokenCreateParams import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith -@ExtendWith(TestServerExtension::class) internal class AccessTokenServiceAsyncTest { @Disabled("Prism tests are disabled") @Test fun create() { - val client = - CasParserOkHttpClientAsync.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() + val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() val accessTokenServiceAsync = client.accessToken() val accessTokenFuture = diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CamsKfintechServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CamsKfintechServiceAsyncTest.kt index 2f14e4a..5597a2e 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CamsKfintechServiceAsyncTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CamsKfintechServiceAsyncTest.kt @@ -2,24 +2,17 @@ package com.cas_parser.api.services.async -import com.cas_parser.api.TestServerExtension import com.cas_parser.api.client.okhttp.CasParserOkHttpClientAsync import com.cas_parser.api.models.camskfintech.CamsKfintechParseParams import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith -@ExtendWith(TestServerExtension::class) internal class CamsKfintechServiceAsyncTest { @Disabled("Prism tests are disabled") @Test fun parse() { - val client = - CasParserOkHttpClientAsync.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() + val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() val camsKfintechServiceAsync = client.camsKfintech() val unifiedResponseFuture = diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CdslServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CdslServiceAsyncTest.kt index 36a9797..33d3092 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CdslServiceAsyncTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CdslServiceAsyncTest.kt @@ -2,24 +2,17 @@ package com.cas_parser.api.services.async -import com.cas_parser.api.TestServerExtension import com.cas_parser.api.client.okhttp.CasParserOkHttpClientAsync import com.cas_parser.api.models.cdsl.CdslParsePdfParams import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith -@ExtendWith(TestServerExtension::class) internal class CdslServiceAsyncTest { @Disabled("Prism tests are disabled") @Test fun parsePdf() { - val client = - CasParserOkHttpClientAsync.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() + val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() val cdslServiceAsync = client.cdsl() val unifiedResponseFuture = diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/ContractNoteServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/ContractNoteServiceAsyncTest.kt index 8e7907e..02dc255 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/ContractNoteServiceAsyncTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/ContractNoteServiceAsyncTest.kt @@ -2,24 +2,17 @@ package com.cas_parser.api.services.async -import com.cas_parser.api.TestServerExtension import com.cas_parser.api.client.okhttp.CasParserOkHttpClientAsync import com.cas_parser.api.models.contractnote.ContractNoteParseParams import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith -@ExtendWith(TestServerExtension::class) internal class ContractNoteServiceAsyncTest { @Disabled("Prism tests are disabled") @Test fun parse() { - val client = - CasParserOkHttpClientAsync.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() + val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() val contractNoteServiceAsync = client.contractNote() val responseFuture = diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CreditServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CreditServiceAsyncTest.kt index bedb74b..c831f4e 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CreditServiceAsyncTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CreditServiceAsyncTest.kt @@ -2,23 +2,16 @@ package com.cas_parser.api.services.async -import com.cas_parser.api.TestServerExtension import com.cas_parser.api.client.okhttp.CasParserOkHttpClientAsync import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith -@ExtendWith(TestServerExtension::class) internal class CreditServiceAsyncTest { @Disabled("Prism tests are disabled") @Test fun check() { - val client = - CasParserOkHttpClientAsync.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() + val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() val creditServiceAsync = client.credits() val responseFuture = creditServiceAsync.check() diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/InboxServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/InboxServiceAsyncTest.kt index 45759bf..f80c8f1 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/InboxServiceAsyncTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/InboxServiceAsyncTest.kt @@ -2,7 +2,6 @@ package com.cas_parser.api.services.async -import com.cas_parser.api.TestServerExtension import com.cas_parser.api.client.okhttp.CasParserOkHttpClientAsync import com.cas_parser.api.models.inbox.InboxCheckConnectionStatusParams import com.cas_parser.api.models.inbox.InboxConnectEmailParams @@ -11,19 +10,13 @@ import com.cas_parser.api.models.inbox.InboxListCasFilesParams import java.time.LocalDate import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith -@ExtendWith(TestServerExtension::class) internal class InboxServiceAsyncTest { @Disabled("Prism tests are disabled") @Test fun checkConnectionStatus() { - val client = - CasParserOkHttpClientAsync.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() + val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() val inboxServiceAsync = client.inbox() val responseFuture = @@ -38,11 +31,7 @@ internal class InboxServiceAsyncTest { @Disabled("Prism tests are disabled") @Test fun connectEmail() { - val client = - CasParserOkHttpClientAsync.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() + val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() val inboxServiceAsync = client.inbox() val responseFuture = @@ -60,11 +49,7 @@ internal class InboxServiceAsyncTest { @Disabled("Prism tests are disabled") @Test fun disconnectEmail() { - val client = - CasParserOkHttpClientAsync.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() + val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() val inboxServiceAsync = client.inbox() val responseFuture = @@ -79,11 +64,7 @@ internal class InboxServiceAsyncTest { @Disabled("Prism tests are disabled") @Test fun listCasFiles() { - val client = - CasParserOkHttpClientAsync.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() + val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() val inboxServiceAsync = client.inbox() val responseFuture = diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/KfintechServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/KfintechServiceAsyncTest.kt index 8409abc..3e8ebf1 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/KfintechServiceAsyncTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/KfintechServiceAsyncTest.kt @@ -2,24 +2,17 @@ package com.cas_parser.api.services.async -import com.cas_parser.api.TestServerExtension import com.cas_parser.api.client.okhttp.CasParserOkHttpClientAsync import com.cas_parser.api.models.kfintech.KfintechGenerateCasParams import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith -@ExtendWith(TestServerExtension::class) internal class KfintechServiceAsyncTest { @Disabled("Prism tests are disabled") @Test fun generateCas() { - val client = - CasParserOkHttpClientAsync.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() + val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() val kfintechServiceAsync = client.kfintech() val responseFuture = diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/LogServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/LogServiceAsyncTest.kt index bcb12c3..7779a3c 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/LogServiceAsyncTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/LogServiceAsyncTest.kt @@ -2,26 +2,19 @@ package com.cas_parser.api.services.async -import com.cas_parser.api.TestServerExtension import com.cas_parser.api.client.okhttp.CasParserOkHttpClientAsync import com.cas_parser.api.models.logs.LogCreateParams import com.cas_parser.api.models.logs.LogGetSummaryParams import java.time.OffsetDateTime import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith -@ExtendWith(TestServerExtension::class) internal class LogServiceAsyncTest { @Disabled("Prism tests are disabled") @Test fun create() { - val client = - CasParserOkHttpClientAsync.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() + val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() val logServiceAsync = client.logs() val logFuture = @@ -40,11 +33,7 @@ internal class LogServiceAsyncTest { @Disabled("Prism tests are disabled") @Test fun getSummary() { - val client = - CasParserOkHttpClientAsync.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() + val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() val logServiceAsync = client.logs() val responseFuture = diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/NsdlServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/NsdlServiceAsyncTest.kt index b8db02d..4b569bc 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/NsdlServiceAsyncTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/NsdlServiceAsyncTest.kt @@ -2,24 +2,17 @@ package com.cas_parser.api.services.async -import com.cas_parser.api.TestServerExtension import com.cas_parser.api.client.okhttp.CasParserOkHttpClientAsync import com.cas_parser.api.models.nsdl.NsdlParseParams import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith -@ExtendWith(TestServerExtension::class) internal class NsdlServiceAsyncTest { @Disabled("Prism tests are disabled") @Test fun parse() { - val client = - CasParserOkHttpClientAsync.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() + val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() val nsdlServiceAsync = client.nsdl() val unifiedResponseFuture = diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/SmartServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/SmartServiceAsyncTest.kt index 9cc398a..c574f20 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/SmartServiceAsyncTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/SmartServiceAsyncTest.kt @@ -2,24 +2,17 @@ package com.cas_parser.api.services.async -import com.cas_parser.api.TestServerExtension import com.cas_parser.api.client.okhttp.CasParserOkHttpClientAsync import com.cas_parser.api.models.smart.SmartParseCasPdfParams import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith -@ExtendWith(TestServerExtension::class) internal class SmartServiceAsyncTest { @Disabled("Prism tests are disabled") @Test fun parseCasPdf() { - val client = - CasParserOkHttpClientAsync.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() + val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() val smartServiceAsync = client.smart() val unifiedResponseFuture = diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsyncTest.kt index c521605..028abdd 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsyncTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsyncTest.kt @@ -2,23 +2,16 @@ package com.cas_parser.api.services.async -import com.cas_parser.api.TestServerExtension import com.cas_parser.api.client.okhttp.CasParserOkHttpClientAsync import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith -@ExtendWith(TestServerExtension::class) internal class VerifyTokenServiceAsyncTest { @Disabled("Prism tests are disabled") @Test fun verify() { - val client = - CasParserOkHttpClientAsync.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() + val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() val verifyTokenServiceAsync = client.verifyToken() val responseFuture = verifyTokenServiceAsync.verify() diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/cdsl/FetchServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/cdsl/FetchServiceAsyncTest.kt index 7cc38ca..aee0987 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/cdsl/FetchServiceAsyncTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/cdsl/FetchServiceAsyncTest.kt @@ -2,25 +2,18 @@ package com.cas_parser.api.services.async.cdsl -import com.cas_parser.api.TestServerExtension import com.cas_parser.api.client.okhttp.CasParserOkHttpClientAsync import com.cas_parser.api.models.cdsl.fetch.FetchRequestOtpParams import com.cas_parser.api.models.cdsl.fetch.FetchVerifyOtpParams import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith -@ExtendWith(TestServerExtension::class) internal class FetchServiceAsyncTest { @Disabled("Prism tests are disabled") @Test fun requestOtp() { - val client = - CasParserOkHttpClientAsync.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() + val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() val fetchServiceAsync = client.cdsl().fetch() val responseFuture = @@ -39,11 +32,7 @@ internal class FetchServiceAsyncTest { @Disabled("Prism tests are disabled") @Test fun verifyOtp() { - val client = - CasParserOkHttpClientAsync.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() + val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() val fetchServiceAsync = client.cdsl().fetch() val responseFuture = diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/AccessTokenServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/AccessTokenServiceTest.kt index 278e2a8..b236856 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/AccessTokenServiceTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/AccessTokenServiceTest.kt @@ -2,24 +2,17 @@ package com.cas_parser.api.services.blocking -import com.cas_parser.api.TestServerExtension import com.cas_parser.api.client.okhttp.CasParserOkHttpClient import com.cas_parser.api.models.accesstoken.AccessTokenCreateParams import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith -@ExtendWith(TestServerExtension::class) internal class AccessTokenServiceTest { @Disabled("Prism tests are disabled") @Test fun create() { - val client = - CasParserOkHttpClient.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() + val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() val accessTokenService = client.accessToken() val accessToken = diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CamsKfintechServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CamsKfintechServiceTest.kt index 86de188..fc27735 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CamsKfintechServiceTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CamsKfintechServiceTest.kt @@ -2,24 +2,17 @@ package com.cas_parser.api.services.blocking -import com.cas_parser.api.TestServerExtension import com.cas_parser.api.client.okhttp.CasParserOkHttpClient import com.cas_parser.api.models.camskfintech.CamsKfintechParseParams import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith -@ExtendWith(TestServerExtension::class) internal class CamsKfintechServiceTest { @Disabled("Prism tests are disabled") @Test fun parse() { - val client = - CasParserOkHttpClient.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() + val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() val camsKfintechService = client.camsKfintech() val unifiedResponse = diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CdslServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CdslServiceTest.kt index 492dd5c..7529333 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CdslServiceTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CdslServiceTest.kt @@ -2,24 +2,17 @@ package com.cas_parser.api.services.blocking -import com.cas_parser.api.TestServerExtension import com.cas_parser.api.client.okhttp.CasParserOkHttpClient import com.cas_parser.api.models.cdsl.CdslParsePdfParams import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith -@ExtendWith(TestServerExtension::class) internal class CdslServiceTest { @Disabled("Prism tests are disabled") @Test fun parsePdf() { - val client = - CasParserOkHttpClient.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() + val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() val cdslService = client.cdsl() val unifiedResponse = diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/ContractNoteServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/ContractNoteServiceTest.kt index 07164ca..93bf156 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/ContractNoteServiceTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/ContractNoteServiceTest.kt @@ -2,24 +2,17 @@ package com.cas_parser.api.services.blocking -import com.cas_parser.api.TestServerExtension import com.cas_parser.api.client.okhttp.CasParserOkHttpClient import com.cas_parser.api.models.contractnote.ContractNoteParseParams import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith -@ExtendWith(TestServerExtension::class) internal class ContractNoteServiceTest { @Disabled("Prism tests are disabled") @Test fun parse() { - val client = - CasParserOkHttpClient.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() + val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() val contractNoteService = client.contractNote() val response = diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CreditServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CreditServiceTest.kt index 750948f..faff248 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CreditServiceTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CreditServiceTest.kt @@ -2,23 +2,16 @@ package com.cas_parser.api.services.blocking -import com.cas_parser.api.TestServerExtension import com.cas_parser.api.client.okhttp.CasParserOkHttpClient import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith -@ExtendWith(TestServerExtension::class) internal class CreditServiceTest { @Disabled("Prism tests are disabled") @Test fun check() { - val client = - CasParserOkHttpClient.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() + val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() val creditService = client.credits() val response = creditService.check() diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/InboxServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/InboxServiceTest.kt index 8b62e2d..177e27d 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/InboxServiceTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/InboxServiceTest.kt @@ -2,7 +2,6 @@ package com.cas_parser.api.services.blocking -import com.cas_parser.api.TestServerExtension import com.cas_parser.api.client.okhttp.CasParserOkHttpClient import com.cas_parser.api.models.inbox.InboxCheckConnectionStatusParams import com.cas_parser.api.models.inbox.InboxConnectEmailParams @@ -11,19 +10,13 @@ import com.cas_parser.api.models.inbox.InboxListCasFilesParams import java.time.LocalDate import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith -@ExtendWith(TestServerExtension::class) internal class InboxServiceTest { @Disabled("Prism tests are disabled") @Test fun checkConnectionStatus() { - val client = - CasParserOkHttpClient.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() + val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() val inboxService = client.inbox() val response = @@ -37,11 +30,7 @@ internal class InboxServiceTest { @Disabled("Prism tests are disabled") @Test fun connectEmail() { - val client = - CasParserOkHttpClient.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() + val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() val inboxService = client.inbox() val response = @@ -58,11 +47,7 @@ internal class InboxServiceTest { @Disabled("Prism tests are disabled") @Test fun disconnectEmail() { - val client = - CasParserOkHttpClient.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() + val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() val inboxService = client.inbox() val response = @@ -76,11 +61,7 @@ internal class InboxServiceTest { @Disabled("Prism tests are disabled") @Test fun listCasFiles() { - val client = - CasParserOkHttpClient.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() + val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() val inboxService = client.inbox() val response = diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/KfintechServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/KfintechServiceTest.kt index 963c6f6..15b7879 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/KfintechServiceTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/KfintechServiceTest.kt @@ -2,24 +2,17 @@ package com.cas_parser.api.services.blocking -import com.cas_parser.api.TestServerExtension import com.cas_parser.api.client.okhttp.CasParserOkHttpClient import com.cas_parser.api.models.kfintech.KfintechGenerateCasParams import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith -@ExtendWith(TestServerExtension::class) internal class KfintechServiceTest { @Disabled("Prism tests are disabled") @Test fun generateCas() { - val client = - CasParserOkHttpClient.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() + val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() val kfintechService = client.kfintech() val response = diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/LogServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/LogServiceTest.kt index 20549fa..fe5349c 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/LogServiceTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/LogServiceTest.kt @@ -2,26 +2,19 @@ package com.cas_parser.api.services.blocking -import com.cas_parser.api.TestServerExtension import com.cas_parser.api.client.okhttp.CasParserOkHttpClient import com.cas_parser.api.models.logs.LogCreateParams import com.cas_parser.api.models.logs.LogGetSummaryParams import java.time.OffsetDateTime import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith -@ExtendWith(TestServerExtension::class) internal class LogServiceTest { @Disabled("Prism tests are disabled") @Test fun create() { - val client = - CasParserOkHttpClient.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() + val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() val logService = client.logs() val log = @@ -39,11 +32,7 @@ internal class LogServiceTest { @Disabled("Prism tests are disabled") @Test fun getSummary() { - val client = - CasParserOkHttpClient.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() + val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() val logService = client.logs() val response = diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/NsdlServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/NsdlServiceTest.kt index 44b520c..8ae0dc3 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/NsdlServiceTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/NsdlServiceTest.kt @@ -2,24 +2,17 @@ package com.cas_parser.api.services.blocking -import com.cas_parser.api.TestServerExtension import com.cas_parser.api.client.okhttp.CasParserOkHttpClient import com.cas_parser.api.models.nsdl.NsdlParseParams import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith -@ExtendWith(TestServerExtension::class) internal class NsdlServiceTest { @Disabled("Prism tests are disabled") @Test fun parse() { - val client = - CasParserOkHttpClient.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() + val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() val nsdlService = client.nsdl() val unifiedResponse = diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/SmartServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/SmartServiceTest.kt index 0f96eb7..d1f2d99 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/SmartServiceTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/SmartServiceTest.kt @@ -2,24 +2,17 @@ package com.cas_parser.api.services.blocking -import com.cas_parser.api.TestServerExtension import com.cas_parser.api.client.okhttp.CasParserOkHttpClient import com.cas_parser.api.models.smart.SmartParseCasPdfParams import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith -@ExtendWith(TestServerExtension::class) internal class SmartServiceTest { @Disabled("Prism tests are disabled") @Test fun parseCasPdf() { - val client = - CasParserOkHttpClient.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() + val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() val smartService = client.smart() val unifiedResponse = diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/VerifyTokenServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/VerifyTokenServiceTest.kt index 05a1f9f..485ae70 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/VerifyTokenServiceTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/VerifyTokenServiceTest.kt @@ -2,23 +2,16 @@ package com.cas_parser.api.services.blocking -import com.cas_parser.api.TestServerExtension import com.cas_parser.api.client.okhttp.CasParserOkHttpClient import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith -@ExtendWith(TestServerExtension::class) internal class VerifyTokenServiceTest { @Disabled("Prism tests are disabled") @Test fun verify() { - val client = - CasParserOkHttpClient.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() + val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() val verifyTokenService = client.verifyToken() val response = verifyTokenService.verify() diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/cdsl/FetchServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/cdsl/FetchServiceTest.kt index eedc3dd..1c83f66 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/cdsl/FetchServiceTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/cdsl/FetchServiceTest.kt @@ -2,25 +2,18 @@ package com.cas_parser.api.services.blocking.cdsl -import com.cas_parser.api.TestServerExtension import com.cas_parser.api.client.okhttp.CasParserOkHttpClient import com.cas_parser.api.models.cdsl.fetch.FetchRequestOtpParams import com.cas_parser.api.models.cdsl.fetch.FetchVerifyOtpParams import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith -@ExtendWith(TestServerExtension::class) internal class FetchServiceTest { @Disabled("Prism tests are disabled") @Test fun requestOtp() { - val client = - CasParserOkHttpClient.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() + val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() val fetchService = client.cdsl().fetch() val response = @@ -38,11 +31,7 @@ internal class FetchServiceTest { @Disabled("Prism tests are disabled") @Test fun verifyOtp() { - val client = - CasParserOkHttpClient.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My API Key") - .build() + val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() val fetchService = client.cdsl().fetch() val response = diff --git a/scripts/mock b/scripts/mock deleted file mode 100755 index 0b28f6e..0000000 --- a/scripts/mock +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env bash - -set -e - -cd "$(dirname "$0")/.." - -if [[ -n "$1" && "$1" != '--'* ]]; then - URL="$1" - shift -else - URL="$(grep 'openapi_spec_url' .stats.yml | cut -d' ' -f2)" -fi - -# Check if the URL is empty -if [ -z "$URL" ]; then - echo "Error: No OpenAPI spec path/url provided or found in .stats.yml" - exit 1 -fi - -echo "==> Starting mock server with URL ${URL}" - -# Run prism mock on the given spec -if [ "$1" == "--daemon" ]; then - npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock "$URL" &> .prism.log & - - # Wait for server to come online - echo -n "Waiting for server" - while ! grep -q "✖ fatal\|Prism is listening" ".prism.log" ; do - 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" -fi diff --git a/scripts/test b/scripts/test index 047bc1d..904aea6 100755 --- a/scripts/test +++ b/scripts/test @@ -4,53 +4,7 @@ set -e cd "$(dirname "$0")/.." -RED='\033[0;31m' -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 -} - -kill_server_on_port() { - pids=$(lsof -t -i tcp:"$1" || echo "") - if [ "$pids" != "" ]; then - kill "$pids" - echo "Stopped $pids." - fi -} - -function is_overriding_api_base_url() { - [ -n "$TEST_API_BASE_URL" ] -} - -if ! is_overriding_api_base_url && ! prism_is_running ; then - # When we exit this script, make sure to kill the background mock server process - trap 'kill_server_on_port 4010' EXIT - - # Start the dev server - ./scripts/mock --daemon -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" - 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 - echo -e " \$ ${YELLOW}npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock path/to/your.openapi.yml${NC}" - echo - - exit 1 -else - echo -e "${GREEN}✔ Mock prism server is running with your OpenAPI spec${NC}" - echo -fi echo "==> Running tests" ./gradlew test "$@" From 21ffb1d3ac4cb64cb0adb1697cb0133cf1ec382b Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 20 Feb 2026 05:23:57 +0000 Subject: [PATCH 54/99] chore: update mock server docs --- .../com/cas_parser/api/services/ServiceParamsTest.kt | 2 +- .../api/services/async/AccessTokenServiceAsyncTest.kt | 2 +- .../api/services/async/CamsKfintechServiceAsyncTest.kt | 2 +- .../cas_parser/api/services/async/CdslServiceAsyncTest.kt | 2 +- .../api/services/async/ContractNoteServiceAsyncTest.kt | 2 +- .../api/services/async/CreditServiceAsyncTest.kt | 2 +- .../api/services/async/InboxServiceAsyncTest.kt | 8 ++++---- .../api/services/async/KfintechServiceAsyncTest.kt | 2 +- .../cas_parser/api/services/async/LogServiceAsyncTest.kt | 4 ++-- .../cas_parser/api/services/async/NsdlServiceAsyncTest.kt | 2 +- .../api/services/async/SmartServiceAsyncTest.kt | 2 +- .../api/services/async/VerifyTokenServiceAsyncTest.kt | 2 +- .../api/services/async/cdsl/FetchServiceAsyncTest.kt | 4 ++-- .../api/services/blocking/AccessTokenServiceTest.kt | 2 +- .../api/services/blocking/CamsKfintechServiceTest.kt | 2 +- .../cas_parser/api/services/blocking/CdslServiceTest.kt | 2 +- .../api/services/blocking/ContractNoteServiceTest.kt | 2 +- .../cas_parser/api/services/blocking/CreditServiceTest.kt | 2 +- .../cas_parser/api/services/blocking/InboxServiceTest.kt | 8 ++++---- .../api/services/blocking/KfintechServiceTest.kt | 2 +- .../cas_parser/api/services/blocking/LogServiceTest.kt | 4 ++-- .../cas_parser/api/services/blocking/NsdlServiceTest.kt | 2 +- .../cas_parser/api/services/blocking/SmartServiceTest.kt | 2 +- .../api/services/blocking/VerifyTokenServiceTest.kt | 2 +- .../api/services/blocking/cdsl/FetchServiceTest.kt | 4 ++-- 25 files changed, 35 insertions(+), 35 deletions(-) diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/ServiceParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/ServiceParamsTest.kt index 2d2074d..4cdd376 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/ServiceParamsTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/ServiceParamsTest.kt @@ -36,7 +36,7 @@ internal class ServiceParamsTest { .build() } - @Disabled("Prism tests are disabled") + @Disabled("Mock server tests are disabled") @Test fun check() { val creditService = client.credits() diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsyncTest.kt index bb9558e..c795a5c 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsyncTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsyncTest.kt @@ -9,7 +9,7 @@ import org.junit.jupiter.api.Test internal class AccessTokenServiceAsyncTest { - @Disabled("Prism tests are disabled") + @Disabled("Mock server tests are disabled") @Test fun create() { val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CamsKfintechServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CamsKfintechServiceAsyncTest.kt index 5597a2e..046850e 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CamsKfintechServiceAsyncTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CamsKfintechServiceAsyncTest.kt @@ -9,7 +9,7 @@ import org.junit.jupiter.api.Test internal class CamsKfintechServiceAsyncTest { - @Disabled("Prism tests are disabled") + @Disabled("Mock server tests are disabled") @Test fun parse() { val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CdslServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CdslServiceAsyncTest.kt index 33d3092..35d78b1 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CdslServiceAsyncTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CdslServiceAsyncTest.kt @@ -9,7 +9,7 @@ import org.junit.jupiter.api.Test internal class CdslServiceAsyncTest { - @Disabled("Prism tests are disabled") + @Disabled("Mock server tests are disabled") @Test fun parsePdf() { val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/ContractNoteServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/ContractNoteServiceAsyncTest.kt index 02dc255..1d51efe 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/ContractNoteServiceAsyncTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/ContractNoteServiceAsyncTest.kt @@ -9,7 +9,7 @@ import org.junit.jupiter.api.Test internal class ContractNoteServiceAsyncTest { - @Disabled("Prism tests are disabled") + @Disabled("Mock server tests are disabled") @Test fun parse() { val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CreditServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CreditServiceAsyncTest.kt index c831f4e..6c9e4d8 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CreditServiceAsyncTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CreditServiceAsyncTest.kt @@ -8,7 +8,7 @@ import org.junit.jupiter.api.Test internal class CreditServiceAsyncTest { - @Disabled("Prism tests are disabled") + @Disabled("Mock server tests are disabled") @Test fun check() { val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/InboxServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/InboxServiceAsyncTest.kt index f80c8f1..47362c1 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/InboxServiceAsyncTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/InboxServiceAsyncTest.kt @@ -13,7 +13,7 @@ import org.junit.jupiter.api.Test internal class InboxServiceAsyncTest { - @Disabled("Prism tests are disabled") + @Disabled("Mock server tests are disabled") @Test fun checkConnectionStatus() { val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() @@ -28,7 +28,7 @@ internal class InboxServiceAsyncTest { response.validate() } - @Disabled("Prism tests are disabled") + @Disabled("Mock server tests are disabled") @Test fun connectEmail() { val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() @@ -46,7 +46,7 @@ internal class InboxServiceAsyncTest { response.validate() } - @Disabled("Prism tests are disabled") + @Disabled("Mock server tests are disabled") @Test fun disconnectEmail() { val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() @@ -61,7 +61,7 @@ internal class InboxServiceAsyncTest { response.validate() } - @Disabled("Prism tests are disabled") + @Disabled("Mock server tests are disabled") @Test fun listCasFiles() { val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/KfintechServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/KfintechServiceAsyncTest.kt index 3e8ebf1..0632267 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/KfintechServiceAsyncTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/KfintechServiceAsyncTest.kt @@ -9,7 +9,7 @@ import org.junit.jupiter.api.Test internal class KfintechServiceAsyncTest { - @Disabled("Prism tests are disabled") + @Disabled("Mock server tests are disabled") @Test fun generateCas() { val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/LogServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/LogServiceAsyncTest.kt index 7779a3c..532be8d 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/LogServiceAsyncTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/LogServiceAsyncTest.kt @@ -11,7 +11,7 @@ import org.junit.jupiter.api.Test internal class LogServiceAsyncTest { - @Disabled("Prism tests are disabled") + @Disabled("Mock server tests are disabled") @Test fun create() { val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() @@ -30,7 +30,7 @@ internal class LogServiceAsyncTest { log.validate() } - @Disabled("Prism tests are disabled") + @Disabled("Mock server tests are disabled") @Test fun getSummary() { val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/NsdlServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/NsdlServiceAsyncTest.kt index 4b569bc..de5bda4 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/NsdlServiceAsyncTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/NsdlServiceAsyncTest.kt @@ -9,7 +9,7 @@ import org.junit.jupiter.api.Test internal class NsdlServiceAsyncTest { - @Disabled("Prism tests are disabled") + @Disabled("Mock server tests are disabled") @Test fun parse() { val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/SmartServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/SmartServiceAsyncTest.kt index c574f20..db32247 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/SmartServiceAsyncTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/SmartServiceAsyncTest.kt @@ -9,7 +9,7 @@ import org.junit.jupiter.api.Test internal class SmartServiceAsyncTest { - @Disabled("Prism tests are disabled") + @Disabled("Mock server tests are disabled") @Test fun parseCasPdf() { val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsyncTest.kt index 028abdd..3d7800c 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsyncTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsyncTest.kt @@ -8,7 +8,7 @@ import org.junit.jupiter.api.Test internal class VerifyTokenServiceAsyncTest { - @Disabled("Prism tests are disabled") + @Disabled("Mock server tests are disabled") @Test fun verify() { val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/cdsl/FetchServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/cdsl/FetchServiceAsyncTest.kt index aee0987..a7ac051 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/cdsl/FetchServiceAsyncTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/cdsl/FetchServiceAsyncTest.kt @@ -10,7 +10,7 @@ import org.junit.jupiter.api.Test internal class FetchServiceAsyncTest { - @Disabled("Prism tests are disabled") + @Disabled("Mock server tests are disabled") @Test fun requestOtp() { val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() @@ -29,7 +29,7 @@ internal class FetchServiceAsyncTest { response.validate() } - @Disabled("Prism tests are disabled") + @Disabled("Mock server tests are disabled") @Test fun verifyOtp() { val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/AccessTokenServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/AccessTokenServiceTest.kt index b236856..f7c9696 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/AccessTokenServiceTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/AccessTokenServiceTest.kt @@ -9,7 +9,7 @@ import org.junit.jupiter.api.Test internal class AccessTokenServiceTest { - @Disabled("Prism tests are disabled") + @Disabled("Mock server tests are disabled") @Test fun create() { val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CamsKfintechServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CamsKfintechServiceTest.kt index fc27735..f23fd75 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CamsKfintechServiceTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CamsKfintechServiceTest.kt @@ -9,7 +9,7 @@ import org.junit.jupiter.api.Test internal class CamsKfintechServiceTest { - @Disabled("Prism tests are disabled") + @Disabled("Mock server tests are disabled") @Test fun parse() { val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CdslServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CdslServiceTest.kt index 7529333..87dffc2 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CdslServiceTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CdslServiceTest.kt @@ -9,7 +9,7 @@ import org.junit.jupiter.api.Test internal class CdslServiceTest { - @Disabled("Prism tests are disabled") + @Disabled("Mock server tests are disabled") @Test fun parsePdf() { val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/ContractNoteServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/ContractNoteServiceTest.kt index 93bf156..effc5f4 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/ContractNoteServiceTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/ContractNoteServiceTest.kt @@ -9,7 +9,7 @@ import org.junit.jupiter.api.Test internal class ContractNoteServiceTest { - @Disabled("Prism tests are disabled") + @Disabled("Mock server tests are disabled") @Test fun parse() { val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CreditServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CreditServiceTest.kt index faff248..94239a3 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CreditServiceTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CreditServiceTest.kt @@ -8,7 +8,7 @@ import org.junit.jupiter.api.Test internal class CreditServiceTest { - @Disabled("Prism tests are disabled") + @Disabled("Mock server tests are disabled") @Test fun check() { val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/InboxServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/InboxServiceTest.kt index 177e27d..dc041fb 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/InboxServiceTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/InboxServiceTest.kt @@ -13,7 +13,7 @@ import org.junit.jupiter.api.Test internal class InboxServiceTest { - @Disabled("Prism tests are disabled") + @Disabled("Mock server tests are disabled") @Test fun checkConnectionStatus() { val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() @@ -27,7 +27,7 @@ internal class InboxServiceTest { response.validate() } - @Disabled("Prism tests are disabled") + @Disabled("Mock server tests are disabled") @Test fun connectEmail() { val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() @@ -44,7 +44,7 @@ internal class InboxServiceTest { response.validate() } - @Disabled("Prism tests are disabled") + @Disabled("Mock server tests are disabled") @Test fun disconnectEmail() { val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() @@ -58,7 +58,7 @@ internal class InboxServiceTest { response.validate() } - @Disabled("Prism tests are disabled") + @Disabled("Mock server tests are disabled") @Test fun listCasFiles() { val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/KfintechServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/KfintechServiceTest.kt index 15b7879..ddc39f7 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/KfintechServiceTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/KfintechServiceTest.kt @@ -9,7 +9,7 @@ import org.junit.jupiter.api.Test internal class KfintechServiceTest { - @Disabled("Prism tests are disabled") + @Disabled("Mock server tests are disabled") @Test fun generateCas() { val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/LogServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/LogServiceTest.kt index fe5349c..2ef5c48 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/LogServiceTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/LogServiceTest.kt @@ -11,7 +11,7 @@ import org.junit.jupiter.api.Test internal class LogServiceTest { - @Disabled("Prism tests are disabled") + @Disabled("Mock server tests are disabled") @Test fun create() { val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() @@ -29,7 +29,7 @@ internal class LogServiceTest { log.validate() } - @Disabled("Prism tests are disabled") + @Disabled("Mock server tests are disabled") @Test fun getSummary() { val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/NsdlServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/NsdlServiceTest.kt index 8ae0dc3..9121446 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/NsdlServiceTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/NsdlServiceTest.kt @@ -9,7 +9,7 @@ import org.junit.jupiter.api.Test internal class NsdlServiceTest { - @Disabled("Prism tests are disabled") + @Disabled("Mock server tests are disabled") @Test fun parse() { val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/SmartServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/SmartServiceTest.kt index d1f2d99..d28949d 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/SmartServiceTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/SmartServiceTest.kt @@ -9,7 +9,7 @@ import org.junit.jupiter.api.Test internal class SmartServiceTest { - @Disabled("Prism tests are disabled") + @Disabled("Mock server tests are disabled") @Test fun parseCasPdf() { val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/VerifyTokenServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/VerifyTokenServiceTest.kt index 485ae70..19af27d 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/VerifyTokenServiceTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/VerifyTokenServiceTest.kt @@ -8,7 +8,7 @@ import org.junit.jupiter.api.Test internal class VerifyTokenServiceTest { - @Disabled("Prism tests are disabled") + @Disabled("Mock server tests are disabled") @Test fun verify() { val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/cdsl/FetchServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/cdsl/FetchServiceTest.kt index 1c83f66..8c93c2a 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/cdsl/FetchServiceTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/cdsl/FetchServiceTest.kt @@ -10,7 +10,7 @@ import org.junit.jupiter.api.Test internal class FetchServiceTest { - @Disabled("Prism tests are disabled") + @Disabled("Mock server tests are disabled") @Test fun requestOtp() { val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() @@ -28,7 +28,7 @@ internal class FetchServiceTest { response.validate() } - @Disabled("Prism tests are disabled") + @Disabled("Mock server tests are disabled") @Test fun verifyOtp() { val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() From 63af50e930a3b287427b526363020b5c1047db1d Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 21 Feb 2026 21:17:40 +0000 Subject: [PATCH 55/99] feat(api): api update --- .stats.yml | 6 +- README.md | 70 +- .../accesstoken/AccessTokenCreateParams.kt | 410 ----------- .../accesstoken/AccessTokenCreateResponse.kt | 239 ------- .../api/models/credits/CreditCheckParams.kt | 219 ------ .../api/models/credits/CreditCheckResponse.kt | 387 ---------- .../api/models/logs/LogCreateParams.kt | 528 -------------- .../api/models/logs/LogCreateResponse.kt | 578 --------------- .../api/models/logs/LogGetSummaryParams.kt | 468 ------------- .../api/models/logs/LogGetSummaryResponse.kt | 663 ------------------ .../verifytoken/VerifyTokenVerifyParams.kt | 211 ------ .../verifytoken/VerifyTokenVerifyResponse.kt | 240 ------- .../services/async/AccessTokenServiceAsync.kt | 60 -- .../async/AccessTokenServiceAsyncImpl.kt | 56 -- .../api/services/async/CreditServiceAsync.kt | 57 -- .../services/async/CreditServiceAsyncImpl.kt | 56 -- .../api/services/async/LogServiceAsync.kt | 103 --- .../api/services/async/LogServiceAsyncImpl.kt | 96 --- .../services/async/VerifyTokenServiceAsync.kt | 49 -- .../async/VerifyTokenServiceAsyncImpl.kt | 56 -- .../services/blocking/AccessTokenService.kt | 60 -- .../blocking/AccessTokenServiceImpl.kt | 52 -- .../api/services/blocking/CreditService.kt | 56 -- .../services/blocking/CreditServiceImpl.kt | 52 -- .../api/services/blocking/LogService.kt | 102 --- .../api/services/blocking/LogServiceImpl.kt | 89 --- .../services/blocking/VerifyTokenService.kt | 49 -- .../blocking/VerifyTokenServiceImpl.kt | 52 -- .../AccessTokenCreateParamsTest.kt | 30 - .../AccessTokenCreateResponseTest.kt | 45 -- .../models/credits/CreditCheckParamsTest.kt | 13 - .../models/credits/CreditCheckResponseTest.kt | 61 -- .../api/models/logs/LogCreateParamsTest.kt | 42 -- .../api/models/logs/LogCreateResponseTest.kt | 74 -- .../models/logs/LogGetSummaryParamsTest.kt | 39 -- .../models/logs/LogGetSummaryResponseTest.kt | 78 --- .../VerifyTokenVerifyParamsTest.kt | 13 - .../VerifyTokenVerifyResponseTest.kt | 44 -- .../api/services/ErrorHandlingTest.kt | 256 +++++-- .../api/services/ServiceParamsTest.kt | 13 +- .../async/AccessTokenServiceAsyncTest.kt | 26 - .../services/async/CreditServiceAsyncTest.kt | 22 - .../api/services/async/LogServiceAsyncTest.kt | 50 -- .../async/VerifyTokenServiceAsyncTest.kt | 22 - .../blocking/AccessTokenServiceTest.kt | 23 - .../services/blocking/CreditServiceTest.kt | 21 - .../api/services/blocking/LogServiceTest.kt | 48 -- .../blocking/VerifyTokenServiceTest.kt | 21 - .../api/proguard/ProGuardCompatibilityTest.kt | 25 +- 49 files changed, 258 insertions(+), 5772 deletions(-) delete mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateParams.kt delete mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateResponse.kt delete mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/credits/CreditCheckParams.kt delete mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/credits/CreditCheckResponse.kt delete mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogCreateParams.kt delete mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogCreateResponse.kt delete mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogGetSummaryParams.kt delete mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogGetSummaryResponse.kt delete mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyParams.kt delete mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyResponse.kt delete mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateParamsTest.kt delete mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateResponseTest.kt delete mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/credits/CreditCheckParamsTest.kt delete mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/credits/CreditCheckResponseTest.kt delete mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogCreateParamsTest.kt delete mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogCreateResponseTest.kt delete mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogGetSummaryParamsTest.kt delete mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogGetSummaryResponseTest.kt delete mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyParamsTest.kt delete mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyResponseTest.kt delete mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsyncTest.kt delete mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CreditServiceAsyncTest.kt delete mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/LogServiceAsyncTest.kt delete mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsyncTest.kt delete mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/AccessTokenServiceTest.kt delete mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CreditServiceTest.kt delete mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/LogServiceTest.kt delete mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/VerifyTokenServiceTest.kt diff --git a/.stats.yml b/.stats.yml index 56f5a81..80a6900 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 17 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-56b0f699c5437d9e5326626d35dfc972c17d01f12cb416c7f4854c8ea6d0e95e.yml -openapi_spec_hash: 158f405c1880706266d83e6ff16b9d2f +configured_endpoints: 12 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-6a9d3b677dcfb856dc571865c34b3fe401e4d7f0d799edfc743acb9a55800bd0.yml +openapi_spec_hash: 037703a6c741e4310fda3f57c22fa51e config_hash: 41c337f5cda03b13880617490f82bad0 diff --git a/README.md b/README.md index 212151b..50e5c0c 100644 --- a/README.md +++ b/README.md @@ -57,14 +57,14 @@ This library requires Java 8 or later. ```java import com.cas_parser.api.client.CasParserClient; import com.cas_parser.api.client.okhttp.CasParserOkHttpClient; -import com.cas_parser.api.models.credits.CreditCheckParams; -import com.cas_parser.api.models.credits.CreditCheckResponse; +import com.cas_parser.api.models.camskfintech.CamsKfintechParseParams; +import com.cas_parser.api.models.camskfintech.UnifiedResponse; // Configures using the `casparser.apiKey` and `casparser.baseUrl` system properties // Or configures using the `CAS_PARSER_API_KEY` and `CAS_PARSER_BASE_URL` environment variables CasParserClient client = CasParserOkHttpClient.fromEnv(); -CreditCheckResponse response = client.credits().check(); +UnifiedResponse unifiedResponse = client.camsKfintech().parse(); ``` ## Client configuration @@ -137,7 +137,7 @@ The `withOptions()` method does not affect the original client or service. To send a request to the Cas Parser API, build an instance of some `Params` class and pass it to the corresponding client method. When the response is received, it will be deserialized into an instance of a Java class. -For example, `client.credits().check(...)` should be called with an instance of `CreditCheckParams`, and it will return an instance of `CreditCheckResponse`. +For example, `client.camsKfintech().parse(...)` should be called with an instance of `CamsKfintechParseParams`, and it will return an instance of `UnifiedResponse`. ## Immutability @@ -154,15 +154,15 @@ The default client is synchronous. To switch to asynchronous execution, call the ```java import com.cas_parser.api.client.CasParserClient; import com.cas_parser.api.client.okhttp.CasParserOkHttpClient; -import com.cas_parser.api.models.credits.CreditCheckParams; -import com.cas_parser.api.models.credits.CreditCheckResponse; +import com.cas_parser.api.models.camskfintech.CamsKfintechParseParams; +import com.cas_parser.api.models.camskfintech.UnifiedResponse; import java.util.concurrent.CompletableFuture; // Configures using the `casparser.apiKey` and `casparser.baseUrl` system properties // Or configures using the `CAS_PARSER_API_KEY` and `CAS_PARSER_BASE_URL` environment variables CasParserClient client = CasParserOkHttpClient.fromEnv(); -CompletableFuture response = client.async().credits().check(); +CompletableFuture unifiedResponse = client.async().camsKfintech().parse(); ``` Or create an asynchronous client from the beginning: @@ -170,15 +170,15 @@ Or create an asynchronous client from the beginning: ```java import com.cas_parser.api.client.CasParserClientAsync; import com.cas_parser.api.client.okhttp.CasParserOkHttpClientAsync; -import com.cas_parser.api.models.credits.CreditCheckParams; -import com.cas_parser.api.models.credits.CreditCheckResponse; +import com.cas_parser.api.models.camskfintech.CamsKfintechParseParams; +import com.cas_parser.api.models.camskfintech.UnifiedResponse; import java.util.concurrent.CompletableFuture; // Configures using the `casparser.apiKey` and `casparser.baseUrl` system properties // Or configures using the `CAS_PARSER_API_KEY` and `CAS_PARSER_BASE_URL` environment variables CasParserClientAsync client = CasParserOkHttpClientAsync.fromEnv(); -CompletableFuture response = client.credits().check(); +CompletableFuture unifiedResponse = client.camsKfintech().parse(); ``` The asynchronous client supports the same options as the synchronous one, except most methods return `CompletableFuture`s. @@ -192,21 +192,21 @@ To access this data, prefix any HTTP method call on a client or service with `wi ```java import com.cas_parser.api.core.http.Headers; import com.cas_parser.api.core.http.HttpResponseFor; -import com.cas_parser.api.models.credits.CreditCheckParams; -import com.cas_parser.api.models.credits.CreditCheckResponse; +import com.cas_parser.api.models.camskfintech.CamsKfintechParseParams; +import com.cas_parser.api.models.camskfintech.UnifiedResponse; -HttpResponseFor response = client.credits().withRawResponse().check(); +HttpResponseFor unifiedResponse = client.camsKfintech().withRawResponse().parse(); -int statusCode = response.statusCode(); -Headers headers = response.headers(); +int statusCode = unifiedResponse.statusCode(); +Headers headers = unifiedResponse.headers(); ``` You can still deserialize the response into an instance of a Java class if needed: ```java -import com.cas_parser.api.models.credits.CreditCheckResponse; +import com.cas_parser.api.models.camskfintech.UnifiedResponse; -CreditCheckResponse parsedResponse = response.parse(); +UnifiedResponse parsedUnifiedResponse = unifiedResponse.parse(); ``` ## Error handling @@ -304,9 +304,9 @@ Requests time out after 1 minute by default. To set a custom timeout, configure the method call using the `timeout` method: ```java -import com.cas_parser.api.models.credits.CreditCheckResponse; +import com.cas_parser.api.models.camskfintech.UnifiedResponse; -CreditCheckResponse response = client.credits().check(RequestOptions.builder().timeout(Duration.ofSeconds(30)).build()); +UnifiedResponse unifiedResponse = client.camsKfintech().parse(RequestOptions.builder().timeout(Duration.ofSeconds(30)).build()); ``` Or configure the default for all method calls at the client level: @@ -443,9 +443,9 @@ To set undocumented parameters, call the `putAdditionalHeader`, `putAdditionalQu ```java import com.cas_parser.api.core.JsonValue; -import com.cas_parser.api.models.credits.CreditCheckParams; +import com.cas_parser.api.models.camskfintech.CamsKfintechParseParams; -CreditCheckParams params = CreditCheckParams.builder() +CamsKfintechParseParams params = CamsKfintechParseParams.builder() .putAdditionalHeader("Secret-Header", "42") .putAdditionalQueryParam("secret_query_param", "42") .putAdditionalBodyProperty("secretProperty", JsonValue.from("42")) @@ -457,9 +457,9 @@ These can be accessed on the built object later using the `_additionalHeaders()` To set a documented parameter or property to an undocumented or not yet supported _value_, pass a [`JsonValue`](cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Values.kt) object to its setter: ```java -import com.cas_parser.api.models.credits.CreditCheckParams; +import com.cas_parser.api.models.camskfintech.CamsKfintechParseParams; -CreditCheckParams params = CreditCheckParams.builder().build(); +CamsKfintechParseParams params = CamsKfintechParseParams.builder().build(); ``` The most straightforward way to create a [`JsonValue`](cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Values.kt) is using its `from(...)` method: @@ -507,10 +507,10 @@ To forcibly omit a required parameter or property, pass [`JsonMissing`](cas-pars ```java import com.cas_parser.api.core.JsonMissing; +import com.cas_parser.api.models.camskfintech.CamsKfintechParseParams; import com.cas_parser.api.models.cdsl.fetch.FetchRequestOtpParams; -import com.cas_parser.api.models.credits.CreditCheckParams; -CreditCheckParams params = FetchRequestOtpParams.builder() +CamsKfintechParseParams params = FetchRequestOtpParams.builder() .dob("1990-01-15") .pan("ABCDE1234F") .boId(JsonMissing.of()) @@ -525,7 +525,7 @@ To access undocumented response properties, call the `_additionalProperties()` m import com.cas_parser.api.core.JsonValue; import java.util.Map; -Map additionalProperties = client.credits().check(params)._additionalProperties(); +Map additionalProperties = client.camsKfintech().parse(params)._additionalProperties(); JsonValue secretPropertyValue = additionalProperties.get("secretProperty"); String result = secretPropertyValue.accept(new JsonValue.Visitor<>() { @@ -555,19 +555,19 @@ To access a property's raw JSON value, which may be undocumented, call its `_` p import com.cas_parser.api.core.JsonField; import java.util.Optional; -JsonField field = client.credits().check(params)._field(); +JsonField password = client.camsKfintech().parse(params)._password(); -if (field.isMissing()) { +if (password.isMissing()) { // The property is absent from the JSON response -} else if (field.isNull()) { +} else if (password.isNull()) { // The property was set to literal null } else { // Check if value was provided as a string // Other methods include `asNumber()`, `asBoolean()`, etc. - Optional jsonString = field.asString(); + Optional jsonString = password.asString(); // Try to deserialize into a custom type - MyClass myObject = field.asUnknown().orElseThrow().convert(MyClass.class); + MyClass myObject = password.asUnknown().orElseThrow().convert(MyClass.class); } ``` @@ -580,17 +580,17 @@ By default, the SDK will not throw an exception in this case. It will throw [`Ca If you would prefer to check that the response is completely well-typed upfront, then either call `validate()`: ```java -import com.cas_parser.api.models.credits.CreditCheckResponse; +import com.cas_parser.api.models.camskfintech.UnifiedResponse; -CreditCheckResponse response = client.credits().check(params).validate(); +UnifiedResponse unifiedResponse = client.camsKfintech().parse(params).validate(); ``` Or configure the method call to validate the response using the `responseValidation` method: ```java -import com.cas_parser.api.models.credits.CreditCheckResponse; +import com.cas_parser.api.models.camskfintech.UnifiedResponse; -CreditCheckResponse response = client.credits().check(RequestOptions.builder().responseValidation(true).build()); +UnifiedResponse unifiedResponse = client.camsKfintech().parse(RequestOptions.builder().responseValidation(true).build()); ``` Or configure the default for all method calls at the client level: diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateParams.kt deleted file mode 100644 index 676dc4d..0000000 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateParams.kt +++ /dev/null @@ -1,410 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.models.accesstoken - -import com.cas_parser.api.core.ExcludeMissing -import com.cas_parser.api.core.JsonField -import com.cas_parser.api.core.JsonMissing -import com.cas_parser.api.core.JsonValue -import com.cas_parser.api.core.Params -import com.cas_parser.api.core.http.Headers -import com.cas_parser.api.core.http.QueryParams -import com.cas_parser.api.errors.CasParserInvalidDataException -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 - -/** - * Generate a short-lived access token from your API key. - * - * **Use this endpoint from your backend** to create tokens that can be safely passed to - * frontend/SDK. - * - * Access tokens: - * - Are prefixed with `at_` for easy identification - * - Valid for up to 60 minutes - * - Can be used in place of API keys on all v4 endpoints - * - Cannot be used to generate other access tokens - */ -class AccessTokenCreateParams -private constructor( - private val body: Body, - private val additionalHeaders: Headers, - private val additionalQueryParams: QueryParams, -) : Params { - - /** - * Token validity in minutes (max 60) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun expiryMinutes(): Optional = body.expiryMinutes() - - /** - * Returns the raw JSON value of [expiryMinutes]. - * - * Unlike [expiryMinutes], this method doesn't throw if the JSON field has an unexpected type. - */ - fun _expiryMinutes(): JsonField = body._expiryMinutes() - - fun _additionalBodyProperties(): Map = body._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 { - - @JvmStatic fun none(): AccessTokenCreateParams = builder().build() - - /** Returns a mutable builder for constructing an instance of [AccessTokenCreateParams]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [AccessTokenCreateParams]. */ - class Builder internal constructor() { - - private var body: Body.Builder = Body.builder() - private var additionalHeaders: Headers.Builder = Headers.builder() - private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() - - @JvmSynthetic - internal fun from(accessTokenCreateParams: AccessTokenCreateParams) = apply { - body = accessTokenCreateParams.body.toBuilder() - additionalHeaders = accessTokenCreateParams.additionalHeaders.toBuilder() - additionalQueryParams = accessTokenCreateParams.additionalQueryParams.toBuilder() - } - - /** - * Sets the entire request body. - * - * This is generally only useful if you are already constructing the body separately. - * Otherwise, it's more convenient to use the top-level setters instead: - * - [expiryMinutes] - */ - fun body(body: Body) = apply { this.body = body.toBuilder() } - - /** Token validity in minutes (max 60) */ - fun expiryMinutes(expiryMinutes: Long) = apply { body.expiryMinutes(expiryMinutes) } - - /** - * Sets [Builder.expiryMinutes] to an arbitrary JSON value. - * - * You should usually call [Builder.expiryMinutes] with a well-typed [Long] value instead. - * This method is primarily for setting the field to an undocumented or not yet supported - * value. - */ - fun expiryMinutes(expiryMinutes: JsonField) = apply { - body.expiryMinutes(expiryMinutes) - } - - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - body.additionalProperties(additionalBodyProperties) - } - - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - body.putAdditionalProperty(key, value) - } - - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = - apply { - body.putAllAdditionalProperties(additionalBodyProperties) - } - - fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } - - fun removeAllAdditionalBodyProperties(keys: Set) = apply { - body.removeAllAdditionalProperties(keys) - } - - 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 [AccessTokenCreateParams]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): AccessTokenCreateParams = - AccessTokenCreateParams( - body.build(), - additionalHeaders.build(), - additionalQueryParams.build(), - ) - } - - fun _body(): Body = body - - override fun _headers(): Headers = additionalHeaders - - override fun _queryParams(): QueryParams = additionalQueryParams - - class Body - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val expiryMinutes: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("expiry_minutes") - @ExcludeMissing - expiryMinutes: JsonField = JsonMissing.of() - ) : this(expiryMinutes, mutableMapOf()) - - /** - * Token validity in minutes (max 60) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun expiryMinutes(): Optional = expiryMinutes.getOptional("expiry_minutes") - - /** - * Returns the raw JSON value of [expiryMinutes]. - * - * Unlike [expiryMinutes], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("expiry_minutes") - @ExcludeMissing - fun _expiryMinutes(): JsonField = expiryMinutes - - @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 [Body]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Body]. */ - class Builder internal constructor() { - - private var expiryMinutes: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(body: Body) = apply { - expiryMinutes = body.expiryMinutes - additionalProperties = body.additionalProperties.toMutableMap() - } - - /** Token validity in minutes (max 60) */ - fun expiryMinutes(expiryMinutes: Long) = expiryMinutes(JsonField.of(expiryMinutes)) - - /** - * Sets [Builder.expiryMinutes] to an arbitrary JSON value. - * - * You should usually call [Builder.expiryMinutes] with a well-typed [Long] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun expiryMinutes(expiryMinutes: JsonField) = apply { - this.expiryMinutes = expiryMinutes - } - - 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 [Body]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): Body = Body(expiryMinutes, additionalProperties.toMutableMap()) - } - - private var validated: Boolean = false - - fun validate(): Body = apply { - if (validated) { - return@apply - } - - expiryMinutes() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - 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 (expiryMinutes.asKnown().isPresent) 1 else 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Body && - expiryMinutes == other.expiryMinutes && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { Objects.hash(expiryMinutes, additionalProperties) } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Body{expiryMinutes=$expiryMinutes, additionalProperties=$additionalProperties}" - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is AccessTokenCreateParams && - body == other.body && - additionalHeaders == other.additionalHeaders && - additionalQueryParams == other.additionalQueryParams - } - - override fun hashCode(): Int = Objects.hash(body, additionalHeaders, additionalQueryParams) - - override fun toString() = - "AccessTokenCreateParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" -} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateResponse.kt deleted file mode 100644 index a23d37b..0000000 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateResponse.kt +++ /dev/null @@ -1,239 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.models.accesstoken - -import com.cas_parser.api.core.ExcludeMissing -import com.cas_parser.api.core.JsonField -import com.cas_parser.api.core.JsonMissing -import com.cas_parser.api.core.JsonValue -import com.cas_parser.api.errors.CasParserInvalidDataException -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 - -class AccessTokenCreateResponse -@JsonCreator(mode = JsonCreator.Mode.DISABLED) -private constructor( - private val accessToken: JsonField, - private val expiresIn: JsonField, - private val tokenType: JsonField, - private val additionalProperties: MutableMap, -) { - - @JsonCreator - private constructor( - @JsonProperty("access_token") - @ExcludeMissing - accessToken: JsonField = JsonMissing.of(), - @JsonProperty("expires_in") @ExcludeMissing expiresIn: JsonField = JsonMissing.of(), - @JsonProperty("token_type") @ExcludeMissing tokenType: JsonField = JsonMissing.of(), - ) : this(accessToken, expiresIn, tokenType, mutableMapOf()) - - /** - * The at_ prefixed access token - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun accessToken(): Optional = accessToken.getOptional("access_token") - - /** - * Token validity in seconds - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun expiresIn(): Optional = expiresIn.getOptional("expires_in") - - /** - * Always "api_key" - token is a drop-in replacement for x-api-key header - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun tokenType(): Optional = tokenType.getOptional("token_type") - - /** - * Returns the raw JSON value of [accessToken]. - * - * Unlike [accessToken], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("access_token") - @ExcludeMissing - fun _accessToken(): JsonField = accessToken - - /** - * Returns the raw JSON value of [expiresIn]. - * - * Unlike [expiresIn], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("expires_in") @ExcludeMissing fun _expiresIn(): JsonField = expiresIn - - /** - * Returns the raw JSON value of [tokenType]. - * - * Unlike [tokenType], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("token_type") @ExcludeMissing fun _tokenType(): JsonField = tokenType - - @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 [AccessTokenCreateResponse]. - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [AccessTokenCreateResponse]. */ - class Builder internal constructor() { - - private var accessToken: JsonField = JsonMissing.of() - private var expiresIn: JsonField = JsonMissing.of() - private var tokenType: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(accessTokenCreateResponse: AccessTokenCreateResponse) = apply { - accessToken = accessTokenCreateResponse.accessToken - expiresIn = accessTokenCreateResponse.expiresIn - tokenType = accessTokenCreateResponse.tokenType - additionalProperties = accessTokenCreateResponse.additionalProperties.toMutableMap() - } - - /** The at_ prefixed access token */ - fun accessToken(accessToken: String) = accessToken(JsonField.of(accessToken)) - - /** - * Sets [Builder.accessToken] to an arbitrary JSON value. - * - * You should usually call [Builder.accessToken] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet supported - * value. - */ - fun accessToken(accessToken: JsonField) = apply { this.accessToken = accessToken } - - /** Token validity in seconds */ - fun expiresIn(expiresIn: Long) = expiresIn(JsonField.of(expiresIn)) - - /** - * Sets [Builder.expiresIn] to an arbitrary JSON value. - * - * You should usually call [Builder.expiresIn] with a well-typed [Long] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun expiresIn(expiresIn: JsonField) = apply { this.expiresIn = expiresIn } - - /** Always "api_key" - token is a drop-in replacement for x-api-key header */ - fun tokenType(tokenType: String) = tokenType(JsonField.of(tokenType)) - - /** - * Sets [Builder.tokenType] to an arbitrary JSON value. - * - * You should usually call [Builder.tokenType] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet supported - * value. - */ - fun tokenType(tokenType: JsonField) = apply { this.tokenType = tokenType } - - 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 [AccessTokenCreateResponse]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): AccessTokenCreateResponse = - AccessTokenCreateResponse( - accessToken, - expiresIn, - tokenType, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): AccessTokenCreateResponse = apply { - if (validated) { - return@apply - } - - accessToken() - expiresIn() - tokenType() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - 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 (accessToken.asKnown().isPresent) 1 else 0) + - (if (expiresIn.asKnown().isPresent) 1 else 0) + - (if (tokenType.asKnown().isPresent) 1 else 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is AccessTokenCreateResponse && - accessToken == other.accessToken && - expiresIn == other.expiresIn && - tokenType == other.tokenType && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash(accessToken, expiresIn, tokenType, additionalProperties) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "AccessTokenCreateResponse{accessToken=$accessToken, expiresIn=$expiresIn, tokenType=$tokenType, additionalProperties=$additionalProperties}" -} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/credits/CreditCheckParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/credits/CreditCheckParams.kt deleted file mode 100644 index aa45ce8..0000000 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/credits/CreditCheckParams.kt +++ /dev/null @@ -1,219 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.models.credits - -import com.cas_parser.api.core.JsonValue -import com.cas_parser.api.core.Params -import com.cas_parser.api.core.http.Headers -import com.cas_parser.api.core.http.QueryParams -import com.cas_parser.api.core.toImmutable -import java.util.Objects -import java.util.Optional - -/** - * Check your remaining API credits and usage for the current billing period. - * - * Returns: - * - Number of API calls used and remaining credits - * - Credit limit and reset date - * - List of enabled features for your plan - * - * Credits reset at the start of each billing period. - */ -class CreditCheckParams -private constructor( - private val additionalHeaders: Headers, - private val additionalQueryParams: QueryParams, - private val additionalBodyProperties: Map, -) : Params { - - /** Additional body properties to send with the request. */ - fun _additionalBodyProperties(): Map = additionalBodyProperties - - /** 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 { - - @JvmStatic fun none(): CreditCheckParams = builder().build() - - /** Returns a mutable builder for constructing an instance of [CreditCheckParams]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [CreditCheckParams]. */ - class Builder internal constructor() { - - private var additionalHeaders: Headers.Builder = Headers.builder() - private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() - private var additionalBodyProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(creditCheckParams: CreditCheckParams) = apply { - additionalHeaders = creditCheckParams.additionalHeaders.toBuilder() - additionalQueryParams = creditCheckParams.additionalQueryParams.toBuilder() - additionalBodyProperties = creditCheckParams.additionalBodyProperties.toMutableMap() - } - - 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) - } - - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - putAllAdditionalBodyProperties(additionalBodyProperties) - } - - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - additionalBodyProperties.put(key, value) - } - - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = - apply { - this.additionalBodyProperties.putAll(additionalBodyProperties) - } - - fun removeAdditionalBodyProperty(key: String) = apply { - additionalBodyProperties.remove(key) - } - - fun removeAllAdditionalBodyProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalBodyProperty) - } - - /** - * Returns an immutable instance of [CreditCheckParams]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): CreditCheckParams = - CreditCheckParams( - additionalHeaders.build(), - additionalQueryParams.build(), - additionalBodyProperties.toImmutable(), - ) - } - - fun _body(): Optional> = - Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) - - override fun _headers(): Headers = additionalHeaders - - override fun _queryParams(): QueryParams = additionalQueryParams - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is CreditCheckParams && - additionalHeaders == other.additionalHeaders && - additionalQueryParams == other.additionalQueryParams && - additionalBodyProperties == other.additionalBodyProperties - } - - override fun hashCode(): Int = - Objects.hash(additionalHeaders, additionalQueryParams, additionalBodyProperties) - - override fun toString() = - "CreditCheckParams{additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" -} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/credits/CreditCheckResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/credits/CreditCheckResponse.kt deleted file mode 100644 index 6a3f1a3..0000000 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/credits/CreditCheckResponse.kt +++ /dev/null @@ -1,387 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.models.credits - -import com.cas_parser.api.core.ExcludeMissing -import com.cas_parser.api.core.JsonField -import com.cas_parser.api.core.JsonMissing -import com.cas_parser.api.core.JsonValue -import com.cas_parser.api.core.checkKnown -import com.cas_parser.api.core.toImmutable -import com.cas_parser.api.errors.CasParserInvalidDataException -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.time.OffsetDateTime -import java.util.Collections -import java.util.Objects -import java.util.Optional -import kotlin.jvm.optionals.getOrNull - -class CreditCheckResponse -@JsonCreator(mode = JsonCreator.Mode.DISABLED) -private constructor( - private val enabledFeatures: JsonField>, - private val isUnlimited: JsonField, - private val limit: JsonField, - private val remaining: JsonField, - private val resetsAt: JsonField, - private val used: JsonField, - private val additionalProperties: MutableMap, -) { - - @JsonCreator - private constructor( - @JsonProperty("enabled_features") - @ExcludeMissing - enabledFeatures: JsonField> = JsonMissing.of(), - @JsonProperty("is_unlimited") - @ExcludeMissing - isUnlimited: JsonField = JsonMissing.of(), - @JsonProperty("limit") @ExcludeMissing limit: JsonField = JsonMissing.of(), - @JsonProperty("remaining") @ExcludeMissing remaining: JsonField = JsonMissing.of(), - @JsonProperty("resets_at") - @ExcludeMissing - resetsAt: JsonField = JsonMissing.of(), - @JsonProperty("used") @ExcludeMissing used: JsonField = JsonMissing.of(), - ) : this(enabledFeatures, isUnlimited, limit, remaining, resetsAt, used, mutableMapOf()) - - /** - * List of API features enabled for your plan - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun enabledFeatures(): Optional> = enabledFeatures.getOptional("enabled_features") - - /** - * Whether the account has unlimited credits - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun isUnlimited(): Optional = isUnlimited.getOptional("is_unlimited") - - /** - * Total credit limit for billing period - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun limit(): Optional = limit.getOptional("limit") - - /** - * Remaining credits (null if unlimited) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun remaining(): Optional = remaining.getOptional("remaining") - - /** - * When credits reset (ISO 8601) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun resetsAt(): Optional = resetsAt.getOptional("resets_at") - - /** - * Number of credits used this billing period - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun used(): Optional = used.getOptional("used") - - /** - * Returns the raw JSON value of [enabledFeatures]. - * - * Unlike [enabledFeatures], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("enabled_features") - @ExcludeMissing - fun _enabledFeatures(): JsonField> = enabledFeatures - - /** - * Returns the raw JSON value of [isUnlimited]. - * - * Unlike [isUnlimited], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("is_unlimited") - @ExcludeMissing - fun _isUnlimited(): JsonField = isUnlimited - - /** - * Returns the raw JSON value of [limit]. - * - * Unlike [limit], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("limit") @ExcludeMissing fun _limit(): JsonField = limit - - /** - * Returns the raw JSON value of [remaining]. - * - * Unlike [remaining], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("remaining") @ExcludeMissing fun _remaining(): JsonField = remaining - - /** - * Returns the raw JSON value of [resetsAt]. - * - * Unlike [resetsAt], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("resets_at") @ExcludeMissing fun _resetsAt(): JsonField = resetsAt - - /** - * Returns the raw JSON value of [used]. - * - * Unlike [used], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("used") @ExcludeMissing fun _used(): JsonField = used - - @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 [CreditCheckResponse]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [CreditCheckResponse]. */ - class Builder internal constructor() { - - private var enabledFeatures: JsonField>? = null - private var isUnlimited: JsonField = JsonMissing.of() - private var limit: JsonField = JsonMissing.of() - private var remaining: JsonField = JsonMissing.of() - private var resetsAt: JsonField = JsonMissing.of() - private var used: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(creditCheckResponse: CreditCheckResponse) = apply { - enabledFeatures = creditCheckResponse.enabledFeatures.map { it.toMutableList() } - isUnlimited = creditCheckResponse.isUnlimited - limit = creditCheckResponse.limit - remaining = creditCheckResponse.remaining - resetsAt = creditCheckResponse.resetsAt - used = creditCheckResponse.used - additionalProperties = creditCheckResponse.additionalProperties.toMutableMap() - } - - /** List of API features enabled for your plan */ - fun enabledFeatures(enabledFeatures: List) = - enabledFeatures(JsonField.of(enabledFeatures)) - - /** - * Sets [Builder.enabledFeatures] to an arbitrary JSON value. - * - * You should usually call [Builder.enabledFeatures] with a well-typed `List` value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun enabledFeatures(enabledFeatures: JsonField>) = apply { - this.enabledFeatures = enabledFeatures.map { it.toMutableList() } - } - - /** - * Adds a single [String] to [enabledFeatures]. - * - * @throws IllegalStateException if the field was previously set to a non-list. - */ - fun addEnabledFeature(enabledFeature: String) = apply { - enabledFeatures = - (enabledFeatures ?: JsonField.of(mutableListOf())).also { - checkKnown("enabledFeatures", it).add(enabledFeature) - } - } - - /** Whether the account has unlimited credits */ - fun isUnlimited(isUnlimited: Boolean) = isUnlimited(JsonField.of(isUnlimited)) - - /** - * Sets [Builder.isUnlimited] to an arbitrary JSON value. - * - * You should usually call [Builder.isUnlimited] with a well-typed [Boolean] value instead. - * This method is primarily for setting the field to an undocumented or not yet supported - * value. - */ - fun isUnlimited(isUnlimited: JsonField) = apply { this.isUnlimited = isUnlimited } - - /** Total credit limit for billing period */ - fun limit(limit: Long) = limit(JsonField.of(limit)) - - /** - * Sets [Builder.limit] to an arbitrary JSON value. - * - * You should usually call [Builder.limit] with a well-typed [Long] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun limit(limit: JsonField) = apply { this.limit = limit } - - /** Remaining credits (null if unlimited) */ - fun remaining(remaining: Double?) = remaining(JsonField.ofNullable(remaining)) - - /** - * Alias for [Builder.remaining]. - * - * This unboxed primitive overload exists for backwards compatibility. - */ - fun remaining(remaining: Double) = remaining(remaining as Double?) - - /** Alias for calling [Builder.remaining] with `remaining.orElse(null)`. */ - fun remaining(remaining: Optional) = remaining(remaining.getOrNull()) - - /** - * Sets [Builder.remaining] to an arbitrary JSON value. - * - * You should usually call [Builder.remaining] with a well-typed [Double] value instead. - * This method is primarily for setting the field to an undocumented or not yet supported - * value. - */ - fun remaining(remaining: JsonField) = apply { this.remaining = remaining } - - /** When credits reset (ISO 8601) */ - fun resetsAt(resetsAt: OffsetDateTime?) = resetsAt(JsonField.ofNullable(resetsAt)) - - /** Alias for calling [Builder.resetsAt] with `resetsAt.orElse(null)`. */ - fun resetsAt(resetsAt: Optional) = resetsAt(resetsAt.getOrNull()) - - /** - * Sets [Builder.resetsAt] to an arbitrary JSON value. - * - * You should usually call [Builder.resetsAt] with a well-typed [OffsetDateTime] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun resetsAt(resetsAt: JsonField) = apply { this.resetsAt = resetsAt } - - /** Number of credits used this billing period */ - fun used(used: Double) = used(JsonField.of(used)) - - /** - * Sets [Builder.used] to an arbitrary JSON value. - * - * You should usually call [Builder.used] with a well-typed [Double] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun used(used: JsonField) = apply { this.used = used } - - 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 [CreditCheckResponse]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): CreditCheckResponse = - CreditCheckResponse( - (enabledFeatures ?: JsonMissing.of()).map { it.toImmutable() }, - isUnlimited, - limit, - remaining, - resetsAt, - used, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): CreditCheckResponse = apply { - if (validated) { - return@apply - } - - enabledFeatures() - isUnlimited() - limit() - remaining() - resetsAt() - used() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - 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 = - (enabledFeatures.asKnown().getOrNull()?.size ?: 0) + - (if (isUnlimited.asKnown().isPresent) 1 else 0) + - (if (limit.asKnown().isPresent) 1 else 0) + - (if (remaining.asKnown().isPresent) 1 else 0) + - (if (resetsAt.asKnown().isPresent) 1 else 0) + - (if (used.asKnown().isPresent) 1 else 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is CreditCheckResponse && - enabledFeatures == other.enabledFeatures && - isUnlimited == other.isUnlimited && - limit == other.limit && - remaining == other.remaining && - resetsAt == other.resetsAt && - used == other.used && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash( - enabledFeatures, - isUnlimited, - limit, - remaining, - resetsAt, - used, - additionalProperties, - ) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "CreditCheckResponse{enabledFeatures=$enabledFeatures, isUnlimited=$isUnlimited, limit=$limit, remaining=$remaining, resetsAt=$resetsAt, used=$used, additionalProperties=$additionalProperties}" -} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogCreateParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogCreateParams.kt deleted file mode 100644 index c46a795..0000000 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogCreateParams.kt +++ /dev/null @@ -1,528 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.models.logs - -import com.cas_parser.api.core.ExcludeMissing -import com.cas_parser.api.core.JsonField -import com.cas_parser.api.core.JsonMissing -import com.cas_parser.api.core.JsonValue -import com.cas_parser.api.core.Params -import com.cas_parser.api.core.http.Headers -import com.cas_parser.api.core.http.QueryParams -import com.cas_parser.api.errors.CasParserInvalidDataException -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.time.OffsetDateTime -import java.util.Collections -import java.util.Objects -import java.util.Optional - -/** - * Retrieve detailed API usage logs for your account. - * - * Returns a list of API calls with timestamps, features used, status codes, and credits consumed. - * Useful for monitoring usage patterns and debugging. - */ -class LogCreateParams -private constructor( - private val body: Body, - private val additionalHeaders: Headers, - private val additionalQueryParams: QueryParams, -) : Params { - - /** - * End time filter (ISO 8601). Defaults to now. - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun endTime(): Optional = body.endTime() - - /** - * Maximum number of logs to return - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun limit(): Optional = body.limit() - - /** - * Start time filter (ISO 8601). Defaults to 30 days ago. - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun startTime(): Optional = body.startTime() - - /** - * Returns the raw JSON value of [endTime]. - * - * Unlike [endTime], this method doesn't throw if the JSON field has an unexpected type. - */ - fun _endTime(): JsonField = body._endTime() - - /** - * Returns the raw JSON value of [limit]. - * - * Unlike [limit], this method doesn't throw if the JSON field has an unexpected type. - */ - fun _limit(): JsonField = body._limit() - - /** - * Returns the raw JSON value of [startTime]. - * - * Unlike [startTime], this method doesn't throw if the JSON field has an unexpected type. - */ - fun _startTime(): JsonField = body._startTime() - - fun _additionalBodyProperties(): Map = body._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 { - - @JvmStatic fun none(): LogCreateParams = builder().build() - - /** Returns a mutable builder for constructing an instance of [LogCreateParams]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [LogCreateParams]. */ - class Builder internal constructor() { - - private var body: Body.Builder = Body.builder() - private var additionalHeaders: Headers.Builder = Headers.builder() - private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() - - @JvmSynthetic - internal fun from(logCreateParams: LogCreateParams) = apply { - body = logCreateParams.body.toBuilder() - additionalHeaders = logCreateParams.additionalHeaders.toBuilder() - additionalQueryParams = logCreateParams.additionalQueryParams.toBuilder() - } - - /** - * Sets the entire request body. - * - * This is generally only useful if you are already constructing the body separately. - * Otherwise, it's more convenient to use the top-level setters instead: - * - [endTime] - * - [limit] - * - [startTime] - */ - fun body(body: Body) = apply { this.body = body.toBuilder() } - - /** End time filter (ISO 8601). Defaults to now. */ - fun endTime(endTime: OffsetDateTime) = apply { body.endTime(endTime) } - - /** - * Sets [Builder.endTime] to an arbitrary JSON value. - * - * You should usually call [Builder.endTime] with a well-typed [OffsetDateTime] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun endTime(endTime: JsonField) = apply { body.endTime(endTime) } - - /** Maximum number of logs to return */ - fun limit(limit: Long) = apply { body.limit(limit) } - - /** - * Sets [Builder.limit] to an arbitrary JSON value. - * - * You should usually call [Builder.limit] with a well-typed [Long] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun limit(limit: JsonField) = apply { body.limit(limit) } - - /** Start time filter (ISO 8601). Defaults to 30 days ago. */ - fun startTime(startTime: OffsetDateTime) = apply { body.startTime(startTime) } - - /** - * Sets [Builder.startTime] to an arbitrary JSON value. - * - * You should usually call [Builder.startTime] with a well-typed [OffsetDateTime] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun startTime(startTime: JsonField) = apply { body.startTime(startTime) } - - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - body.additionalProperties(additionalBodyProperties) - } - - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - body.putAdditionalProperty(key, value) - } - - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = - apply { - body.putAllAdditionalProperties(additionalBodyProperties) - } - - fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } - - fun removeAllAdditionalBodyProperties(keys: Set) = apply { - body.removeAllAdditionalProperties(keys) - } - - 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 [LogCreateParams]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): LogCreateParams = - LogCreateParams(body.build(), additionalHeaders.build(), additionalQueryParams.build()) - } - - fun _body(): Body = body - - override fun _headers(): Headers = additionalHeaders - - override fun _queryParams(): QueryParams = additionalQueryParams - - class Body - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val endTime: JsonField, - private val limit: JsonField, - private val startTime: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("end_time") - @ExcludeMissing - endTime: JsonField = JsonMissing.of(), - @JsonProperty("limit") @ExcludeMissing limit: JsonField = JsonMissing.of(), - @JsonProperty("start_time") - @ExcludeMissing - startTime: JsonField = JsonMissing.of(), - ) : this(endTime, limit, startTime, mutableMapOf()) - - /** - * End time filter (ISO 8601). Defaults to now. - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun endTime(): Optional = endTime.getOptional("end_time") - - /** - * Maximum number of logs to return - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun limit(): Optional = limit.getOptional("limit") - - /** - * Start time filter (ISO 8601). Defaults to 30 days ago. - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun startTime(): Optional = startTime.getOptional("start_time") - - /** - * Returns the raw JSON value of [endTime]. - * - * Unlike [endTime], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("end_time") - @ExcludeMissing - fun _endTime(): JsonField = endTime - - /** - * Returns the raw JSON value of [limit]. - * - * Unlike [limit], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("limit") @ExcludeMissing fun _limit(): JsonField = limit - - /** - * Returns the raw JSON value of [startTime]. - * - * Unlike [startTime], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("start_time") - @ExcludeMissing - fun _startTime(): JsonField = startTime - - @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 [Body]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Body]. */ - class Builder internal constructor() { - - private var endTime: JsonField = JsonMissing.of() - private var limit: JsonField = JsonMissing.of() - private var startTime: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(body: Body) = apply { - endTime = body.endTime - limit = body.limit - startTime = body.startTime - additionalProperties = body.additionalProperties.toMutableMap() - } - - /** End time filter (ISO 8601). Defaults to now. */ - fun endTime(endTime: OffsetDateTime) = endTime(JsonField.of(endTime)) - - /** - * Sets [Builder.endTime] to an arbitrary JSON value. - * - * You should usually call [Builder.endTime] with a well-typed [OffsetDateTime] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun endTime(endTime: JsonField) = apply { this.endTime = endTime } - - /** Maximum number of logs to return */ - fun limit(limit: Long) = limit(JsonField.of(limit)) - - /** - * Sets [Builder.limit] to an arbitrary JSON value. - * - * You should usually call [Builder.limit] with a well-typed [Long] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported - * value. - */ - fun limit(limit: JsonField) = apply { this.limit = limit } - - /** Start time filter (ISO 8601). Defaults to 30 days ago. */ - fun startTime(startTime: OffsetDateTime) = startTime(JsonField.of(startTime)) - - /** - * Sets [Builder.startTime] to an arbitrary JSON value. - * - * You should usually call [Builder.startTime] with a well-typed [OffsetDateTime] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun startTime(startTime: JsonField) = apply { - this.startTime = startTime - } - - 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 [Body]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): Body = Body(endTime, limit, startTime, additionalProperties.toMutableMap()) - } - - private var validated: Boolean = false - - fun validate(): Body = apply { - if (validated) { - return@apply - } - - endTime() - limit() - startTime() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - 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 (endTime.asKnown().isPresent) 1 else 0) + - (if (limit.asKnown().isPresent) 1 else 0) + - (if (startTime.asKnown().isPresent) 1 else 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Body && - endTime == other.endTime && - limit == other.limit && - startTime == other.startTime && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash(endTime, limit, startTime, additionalProperties) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Body{endTime=$endTime, limit=$limit, startTime=$startTime, additionalProperties=$additionalProperties}" - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is LogCreateParams && - body == other.body && - additionalHeaders == other.additionalHeaders && - additionalQueryParams == other.additionalQueryParams - } - - override fun hashCode(): Int = Objects.hash(body, additionalHeaders, additionalQueryParams) - - override fun toString() = - "LogCreateParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" -} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogCreateResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogCreateResponse.kt deleted file mode 100644 index b77a776..0000000 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogCreateResponse.kt +++ /dev/null @@ -1,578 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.models.logs - -import com.cas_parser.api.core.ExcludeMissing -import com.cas_parser.api.core.JsonField -import com.cas_parser.api.core.JsonMissing -import com.cas_parser.api.core.JsonValue -import com.cas_parser.api.core.checkKnown -import com.cas_parser.api.core.toImmutable -import com.cas_parser.api.errors.CasParserInvalidDataException -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.time.OffsetDateTime -import java.util.Collections -import java.util.Objects -import java.util.Optional -import kotlin.jvm.optionals.getOrNull - -class LogCreateResponse -@JsonCreator(mode = JsonCreator.Mode.DISABLED) -private constructor( - private val count: JsonField, - private val logs: JsonField>, - private val status: JsonField, - private val additionalProperties: MutableMap, -) { - - @JsonCreator - private constructor( - @JsonProperty("count") @ExcludeMissing count: JsonField = JsonMissing.of(), - @JsonProperty("logs") @ExcludeMissing logs: JsonField> = JsonMissing.of(), - @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(), - ) : this(count, logs, status, mutableMapOf()) - - /** - * Number of logs returned - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun count(): Optional = count.getOptional("count") - - /** - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun logs(): Optional> = logs.getOptional("logs") - - /** - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun status(): Optional = status.getOptional("status") - - /** - * Returns the raw JSON value of [count]. - * - * Unlike [count], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("count") @ExcludeMissing fun _count(): JsonField = count - - /** - * Returns the raw JSON value of [logs]. - * - * Unlike [logs], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("logs") @ExcludeMissing fun _logs(): JsonField> = logs - - /** - * Returns the raw JSON value of [status]. - * - * Unlike [status], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("status") @ExcludeMissing fun _status(): JsonField = status - - @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 [LogCreateResponse]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [LogCreateResponse]. */ - class Builder internal constructor() { - - private var count: JsonField = JsonMissing.of() - private var logs: JsonField>? = null - private var status: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(logCreateResponse: LogCreateResponse) = apply { - count = logCreateResponse.count - logs = logCreateResponse.logs.map { it.toMutableList() } - status = logCreateResponse.status - additionalProperties = logCreateResponse.additionalProperties.toMutableMap() - } - - /** Number of logs returned */ - fun count(count: Long) = count(JsonField.of(count)) - - /** - * Sets [Builder.count] to an arbitrary JSON value. - * - * You should usually call [Builder.count] with a well-typed [Long] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun count(count: JsonField) = apply { this.count = count } - - fun logs(logs: List) = logs(JsonField.of(logs)) - - /** - * Sets [Builder.logs] to an arbitrary JSON value. - * - * You should usually call [Builder.logs] with a well-typed `List` value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun logs(logs: JsonField>) = apply { this.logs = logs.map { it.toMutableList() } } - - /** - * Adds a single [Log] to [logs]. - * - * @throws IllegalStateException if the field was previously set to a non-list. - */ - fun addLog(log: Log) = apply { - logs = (logs ?: JsonField.of(mutableListOf())).also { checkKnown("logs", it).add(log) } - } - - fun status(status: String) = status(JsonField.of(status)) - - /** - * Sets [Builder.status] to an arbitrary JSON value. - * - * You should usually call [Builder.status] with a well-typed [String] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun status(status: JsonField) = apply { this.status = status } - - 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 [LogCreateResponse]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): LogCreateResponse = - LogCreateResponse( - count, - (logs ?: JsonMissing.of()).map { it.toImmutable() }, - status, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): LogCreateResponse = apply { - if (validated) { - return@apply - } - - count() - logs().ifPresent { it.forEach { it.validate() } } - status() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - 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 (count.asKnown().isPresent) 1 else 0) + - (logs.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + - (if (status.asKnown().isPresent) 1 else 0) - - class Log - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val credits: JsonField, - private val feature: JsonField, - private val path: JsonField, - private val requestId: JsonField, - private val statusCode: JsonField, - private val timestamp: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("credits") @ExcludeMissing credits: JsonField = JsonMissing.of(), - @JsonProperty("feature") @ExcludeMissing feature: JsonField = JsonMissing.of(), - @JsonProperty("path") @ExcludeMissing path: JsonField = JsonMissing.of(), - @JsonProperty("request_id") - @ExcludeMissing - requestId: JsonField = JsonMissing.of(), - @JsonProperty("status_code") - @ExcludeMissing - statusCode: JsonField = JsonMissing.of(), - @JsonProperty("timestamp") - @ExcludeMissing - timestamp: JsonField = JsonMissing.of(), - ) : this(credits, feature, path, requestId, statusCode, timestamp, mutableMapOf()) - - /** - * Credits consumed for this request - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun credits(): Optional = credits.getOptional("credits") - - /** - * API feature used - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun feature(): Optional = feature.getOptional("feature") - - /** - * API endpoint path - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun path(): Optional = path.getOptional("path") - - /** - * Unique request identifier - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun requestId(): Optional = requestId.getOptional("request_id") - - /** - * HTTP response status code - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun statusCode(): Optional = statusCode.getOptional("status_code") - - /** - * When the request was made - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun timestamp(): Optional = timestamp.getOptional("timestamp") - - /** - * Returns the raw JSON value of [credits]. - * - * Unlike [credits], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("credits") @ExcludeMissing fun _credits(): JsonField = credits - - /** - * Returns the raw JSON value of [feature]. - * - * Unlike [feature], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("feature") @ExcludeMissing fun _feature(): JsonField = feature - - /** - * Returns the raw JSON value of [path]. - * - * Unlike [path], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("path") @ExcludeMissing fun _path(): JsonField = path - - /** - * Returns the raw JSON value of [requestId]. - * - * Unlike [requestId], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("request_id") @ExcludeMissing fun _requestId(): JsonField = requestId - - /** - * Returns the raw JSON value of [statusCode]. - * - * Unlike [statusCode], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("status_code") @ExcludeMissing fun _statusCode(): JsonField = statusCode - - /** - * Returns the raw JSON value of [timestamp]. - * - * Unlike [timestamp], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("timestamp") - @ExcludeMissing - fun _timestamp(): JsonField = timestamp - - @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 [Log]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Log]. */ - class Builder internal constructor() { - - private var credits: JsonField = JsonMissing.of() - private var feature: JsonField = JsonMissing.of() - private var path: JsonField = JsonMissing.of() - private var requestId: JsonField = JsonMissing.of() - private var statusCode: JsonField = JsonMissing.of() - private var timestamp: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(log: Log) = apply { - credits = log.credits - feature = log.feature - path = log.path - requestId = log.requestId - statusCode = log.statusCode - timestamp = log.timestamp - additionalProperties = log.additionalProperties.toMutableMap() - } - - /** Credits consumed for this request */ - fun credits(credits: Double) = credits(JsonField.of(credits)) - - /** - * Sets [Builder.credits] to an arbitrary JSON value. - * - * You should usually call [Builder.credits] with a well-typed [Double] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun credits(credits: JsonField) = apply { this.credits = credits } - - /** API feature used */ - fun feature(feature: String) = feature(JsonField.of(feature)) - - /** - * Sets [Builder.feature] to an arbitrary JSON value. - * - * You should usually call [Builder.feature] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun feature(feature: JsonField) = apply { this.feature = feature } - - /** API endpoint path */ - fun path(path: String) = path(JsonField.of(path)) - - /** - * Sets [Builder.path] to an arbitrary JSON value. - * - * You should usually call [Builder.path] with a well-typed [String] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported - * value. - */ - fun path(path: JsonField) = apply { this.path = path } - - /** Unique request identifier */ - fun requestId(requestId: String) = requestId(JsonField.of(requestId)) - - /** - * Sets [Builder.requestId] to an arbitrary JSON value. - * - * You should usually call [Builder.requestId] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun requestId(requestId: JsonField) = apply { this.requestId = requestId } - - /** HTTP response status code */ - fun statusCode(statusCode: Long) = statusCode(JsonField.of(statusCode)) - - /** - * Sets [Builder.statusCode] to an arbitrary JSON value. - * - * You should usually call [Builder.statusCode] with a well-typed [Long] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun statusCode(statusCode: JsonField) = apply { this.statusCode = statusCode } - - /** When the request was made */ - fun timestamp(timestamp: OffsetDateTime) = timestamp(JsonField.of(timestamp)) - - /** - * Sets [Builder.timestamp] to an arbitrary JSON value. - * - * You should usually call [Builder.timestamp] with a well-typed [OffsetDateTime] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun timestamp(timestamp: JsonField) = apply { - this.timestamp = timestamp - } - - 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 [Log]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): Log = - Log( - credits, - feature, - path, - requestId, - statusCode, - timestamp, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): Log = apply { - if (validated) { - return@apply - } - - credits() - feature() - path() - requestId() - statusCode() - timestamp() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - 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 (credits.asKnown().isPresent) 1 else 0) + - (if (feature.asKnown().isPresent) 1 else 0) + - (if (path.asKnown().isPresent) 1 else 0) + - (if (requestId.asKnown().isPresent) 1 else 0) + - (if (statusCode.asKnown().isPresent) 1 else 0) + - (if (timestamp.asKnown().isPresent) 1 else 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Log && - credits == other.credits && - feature == other.feature && - path == other.path && - requestId == other.requestId && - statusCode == other.statusCode && - timestamp == other.timestamp && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash( - credits, - feature, - path, - requestId, - statusCode, - timestamp, - additionalProperties, - ) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Log{credits=$credits, feature=$feature, path=$path, requestId=$requestId, statusCode=$statusCode, timestamp=$timestamp, additionalProperties=$additionalProperties}" - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is LogCreateResponse && - count == other.count && - logs == other.logs && - status == other.status && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { Objects.hash(count, logs, status, additionalProperties) } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "LogCreateResponse{count=$count, logs=$logs, status=$status, additionalProperties=$additionalProperties}" -} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogGetSummaryParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogGetSummaryParams.kt deleted file mode 100644 index f14f253..0000000 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogGetSummaryParams.kt +++ /dev/null @@ -1,468 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.models.logs - -import com.cas_parser.api.core.ExcludeMissing -import com.cas_parser.api.core.JsonField -import com.cas_parser.api.core.JsonMissing -import com.cas_parser.api.core.JsonValue -import com.cas_parser.api.core.Params -import com.cas_parser.api.core.http.Headers -import com.cas_parser.api.core.http.QueryParams -import com.cas_parser.api.errors.CasParserInvalidDataException -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.time.OffsetDateTime -import java.util.Collections -import java.util.Objects -import java.util.Optional - -/** - * Get aggregated usage statistics grouped by feature. - * - * Useful for understanding which API features are being used most and tracking usage trends. - */ -class LogGetSummaryParams -private constructor( - private val body: Body, - private val additionalHeaders: Headers, - private val additionalQueryParams: QueryParams, -) : Params { - - /** - * End time filter (ISO 8601). Defaults to now. - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun endTime(): Optional = body.endTime() - - /** - * Start time filter (ISO 8601). Defaults to start of current month. - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun startTime(): Optional = body.startTime() - - /** - * Returns the raw JSON value of [endTime]. - * - * Unlike [endTime], this method doesn't throw if the JSON field has an unexpected type. - */ - fun _endTime(): JsonField = body._endTime() - - /** - * Returns the raw JSON value of [startTime]. - * - * Unlike [startTime], this method doesn't throw if the JSON field has an unexpected type. - */ - fun _startTime(): JsonField = body._startTime() - - fun _additionalBodyProperties(): Map = body._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 { - - @JvmStatic fun none(): LogGetSummaryParams = builder().build() - - /** Returns a mutable builder for constructing an instance of [LogGetSummaryParams]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [LogGetSummaryParams]. */ - class Builder internal constructor() { - - private var body: Body.Builder = Body.builder() - private var additionalHeaders: Headers.Builder = Headers.builder() - private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() - - @JvmSynthetic - internal fun from(logGetSummaryParams: LogGetSummaryParams) = apply { - body = logGetSummaryParams.body.toBuilder() - additionalHeaders = logGetSummaryParams.additionalHeaders.toBuilder() - additionalQueryParams = logGetSummaryParams.additionalQueryParams.toBuilder() - } - - /** - * Sets the entire request body. - * - * This is generally only useful if you are already constructing the body separately. - * Otherwise, it's more convenient to use the top-level setters instead: - * - [endTime] - * - [startTime] - */ - fun body(body: Body) = apply { this.body = body.toBuilder() } - - /** End time filter (ISO 8601). Defaults to now. */ - fun endTime(endTime: OffsetDateTime) = apply { body.endTime(endTime) } - - /** - * Sets [Builder.endTime] to an arbitrary JSON value. - * - * You should usually call [Builder.endTime] with a well-typed [OffsetDateTime] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun endTime(endTime: JsonField) = apply { body.endTime(endTime) } - - /** Start time filter (ISO 8601). Defaults to start of current month. */ - fun startTime(startTime: OffsetDateTime) = apply { body.startTime(startTime) } - - /** - * Sets [Builder.startTime] to an arbitrary JSON value. - * - * You should usually call [Builder.startTime] with a well-typed [OffsetDateTime] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun startTime(startTime: JsonField) = apply { body.startTime(startTime) } - - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - body.additionalProperties(additionalBodyProperties) - } - - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - body.putAdditionalProperty(key, value) - } - - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = - apply { - body.putAllAdditionalProperties(additionalBodyProperties) - } - - fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } - - fun removeAllAdditionalBodyProperties(keys: Set) = apply { - body.removeAllAdditionalProperties(keys) - } - - 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 [LogGetSummaryParams]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): LogGetSummaryParams = - LogGetSummaryParams( - body.build(), - additionalHeaders.build(), - additionalQueryParams.build(), - ) - } - - fun _body(): Body = body - - override fun _headers(): Headers = additionalHeaders - - override fun _queryParams(): QueryParams = additionalQueryParams - - class Body - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val endTime: JsonField, - private val startTime: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("end_time") - @ExcludeMissing - endTime: JsonField = JsonMissing.of(), - @JsonProperty("start_time") - @ExcludeMissing - startTime: JsonField = JsonMissing.of(), - ) : this(endTime, startTime, mutableMapOf()) - - /** - * End time filter (ISO 8601). Defaults to now. - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun endTime(): Optional = endTime.getOptional("end_time") - - /** - * Start time filter (ISO 8601). Defaults to start of current month. - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun startTime(): Optional = startTime.getOptional("start_time") - - /** - * Returns the raw JSON value of [endTime]. - * - * Unlike [endTime], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("end_time") - @ExcludeMissing - fun _endTime(): JsonField = endTime - - /** - * Returns the raw JSON value of [startTime]. - * - * Unlike [startTime], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("start_time") - @ExcludeMissing - fun _startTime(): JsonField = startTime - - @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 [Body]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Body]. */ - class Builder internal constructor() { - - private var endTime: JsonField = JsonMissing.of() - private var startTime: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(body: Body) = apply { - endTime = body.endTime - startTime = body.startTime - additionalProperties = body.additionalProperties.toMutableMap() - } - - /** End time filter (ISO 8601). Defaults to now. */ - fun endTime(endTime: OffsetDateTime) = endTime(JsonField.of(endTime)) - - /** - * Sets [Builder.endTime] to an arbitrary JSON value. - * - * You should usually call [Builder.endTime] with a well-typed [OffsetDateTime] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun endTime(endTime: JsonField) = apply { this.endTime = endTime } - - /** Start time filter (ISO 8601). Defaults to start of current month. */ - fun startTime(startTime: OffsetDateTime) = startTime(JsonField.of(startTime)) - - /** - * Sets [Builder.startTime] to an arbitrary JSON value. - * - * You should usually call [Builder.startTime] with a well-typed [OffsetDateTime] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun startTime(startTime: JsonField) = apply { - this.startTime = startTime - } - - 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 [Body]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): Body = Body(endTime, startTime, additionalProperties.toMutableMap()) - } - - private var validated: Boolean = false - - fun validate(): Body = apply { - if (validated) { - return@apply - } - - endTime() - startTime() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - 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 (endTime.asKnown().isPresent) 1 else 0) + - (if (startTime.asKnown().isPresent) 1 else 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Body && - endTime == other.endTime && - startTime == other.startTime && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { Objects.hash(endTime, startTime, additionalProperties) } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Body{endTime=$endTime, startTime=$startTime, additionalProperties=$additionalProperties}" - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is LogGetSummaryParams && - body == other.body && - additionalHeaders == other.additionalHeaders && - additionalQueryParams == other.additionalQueryParams - } - - override fun hashCode(): Int = Objects.hash(body, additionalHeaders, additionalQueryParams) - - override fun toString() = - "LogGetSummaryParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" -} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogGetSummaryResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogGetSummaryResponse.kt deleted file mode 100644 index a78d1ba..0000000 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogGetSummaryResponse.kt +++ /dev/null @@ -1,663 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.models.logs - -import com.cas_parser.api.core.ExcludeMissing -import com.cas_parser.api.core.JsonField -import com.cas_parser.api.core.JsonMissing -import com.cas_parser.api.core.JsonValue -import com.cas_parser.api.core.checkKnown -import com.cas_parser.api.core.toImmutable -import com.cas_parser.api.errors.CasParserInvalidDataException -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 - -class LogGetSummaryResponse -@JsonCreator(mode = JsonCreator.Mode.DISABLED) -private constructor( - private val status: JsonField, - private val summary: JsonField, - private val additionalProperties: MutableMap, -) { - - @JsonCreator - private constructor( - @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(), - @JsonProperty("summary") @ExcludeMissing summary: JsonField = JsonMissing.of(), - ) : this(status, summary, mutableMapOf()) - - /** - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun status(): Optional = status.getOptional("status") - - /** - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun summary(): Optional = summary.getOptional("summary") - - /** - * Returns the raw JSON value of [status]. - * - * Unlike [status], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("status") @ExcludeMissing fun _status(): JsonField = status - - /** - * Returns the raw JSON value of [summary]. - * - * Unlike [summary], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("summary") @ExcludeMissing fun _summary(): JsonField = summary - - @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 [LogGetSummaryResponse]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [LogGetSummaryResponse]. */ - class Builder internal constructor() { - - private var status: JsonField = JsonMissing.of() - private var summary: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(logGetSummaryResponse: LogGetSummaryResponse) = apply { - status = logGetSummaryResponse.status - summary = logGetSummaryResponse.summary - additionalProperties = logGetSummaryResponse.additionalProperties.toMutableMap() - } - - fun status(status: String) = status(JsonField.of(status)) - - /** - * Sets [Builder.status] to an arbitrary JSON value. - * - * You should usually call [Builder.status] with a well-typed [String] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun status(status: JsonField) = apply { this.status = status } - - fun summary(summary: Summary) = summary(JsonField.of(summary)) - - /** - * Sets [Builder.summary] to an arbitrary JSON value. - * - * You should usually call [Builder.summary] with a well-typed [Summary] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun summary(summary: JsonField) = apply { this.summary = summary } - - 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 [LogGetSummaryResponse]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): LogGetSummaryResponse = - LogGetSummaryResponse(status, summary, additionalProperties.toMutableMap()) - } - - private var validated: Boolean = false - - fun validate(): LogGetSummaryResponse = apply { - if (validated) { - return@apply - } - - status() - summary().ifPresent { it.validate() } - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - 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 (status.asKnown().isPresent) 1 else 0) + - (summary.asKnown().getOrNull()?.validity() ?: 0) - - class Summary - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val byFeature: JsonField>, - private val totalCredits: JsonField, - private val totalRequests: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("by_feature") - @ExcludeMissing - byFeature: JsonField> = JsonMissing.of(), - @JsonProperty("total_credits") - @ExcludeMissing - totalCredits: JsonField = JsonMissing.of(), - @JsonProperty("total_requests") - @ExcludeMissing - totalRequests: JsonField = JsonMissing.of(), - ) : this(byFeature, totalCredits, totalRequests, mutableMapOf()) - - /** - * Usage breakdown by feature - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun byFeature(): Optional> = byFeature.getOptional("by_feature") - - /** - * Total credits consumed in the period - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun totalCredits(): Optional = totalCredits.getOptional("total_credits") - - /** - * Total API requests made in the period - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun totalRequests(): Optional = totalRequests.getOptional("total_requests") - - /** - * Returns the raw JSON value of [byFeature]. - * - * Unlike [byFeature], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("by_feature") - @ExcludeMissing - fun _byFeature(): JsonField> = byFeature - - /** - * Returns the raw JSON value of [totalCredits]. - * - * Unlike [totalCredits], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("total_credits") - @ExcludeMissing - fun _totalCredits(): JsonField = totalCredits - - /** - * Returns the raw JSON value of [totalRequests]. - * - * Unlike [totalRequests], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("total_requests") - @ExcludeMissing - fun _totalRequests(): JsonField = totalRequests - - @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 [Summary]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Summary]. */ - class Builder internal constructor() { - - private var byFeature: JsonField>? = null - private var totalCredits: JsonField = JsonMissing.of() - private var totalRequests: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(summary: Summary) = apply { - byFeature = summary.byFeature.map { it.toMutableList() } - totalCredits = summary.totalCredits - totalRequests = summary.totalRequests - additionalProperties = summary.additionalProperties.toMutableMap() - } - - /** Usage breakdown by feature */ - fun byFeature(byFeature: List) = byFeature(JsonField.of(byFeature)) - - /** - * Sets [Builder.byFeature] to an arbitrary JSON value. - * - * You should usually call [Builder.byFeature] with a well-typed `List` value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun byFeature(byFeature: JsonField>) = apply { - this.byFeature = byFeature.map { it.toMutableList() } - } - - /** - * Adds a single [ByFeature] to [Builder.byFeature]. - * - * @throws IllegalStateException if the field was previously set to a non-list. - */ - fun addByFeature(byFeature: ByFeature) = apply { - this.byFeature = - (this.byFeature ?: JsonField.of(mutableListOf())).also { - checkKnown("byFeature", it).add(byFeature) - } - } - - /** Total credits consumed in the period */ - fun totalCredits(totalCredits: Double) = totalCredits(JsonField.of(totalCredits)) - - /** - * Sets [Builder.totalCredits] to an arbitrary JSON value. - * - * You should usually call [Builder.totalCredits] with a well-typed [Double] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun totalCredits(totalCredits: JsonField) = apply { - this.totalCredits = totalCredits - } - - /** Total API requests made in the period */ - fun totalRequests(totalRequests: Long) = totalRequests(JsonField.of(totalRequests)) - - /** - * Sets [Builder.totalRequests] to an arbitrary JSON value. - * - * You should usually call [Builder.totalRequests] with a well-typed [Long] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun totalRequests(totalRequests: JsonField) = apply { - this.totalRequests = totalRequests - } - - 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 [Summary]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): Summary = - Summary( - (byFeature ?: JsonMissing.of()).map { it.toImmutable() }, - totalCredits, - totalRequests, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): Summary = apply { - if (validated) { - return@apply - } - - byFeature().ifPresent { it.forEach { it.validate() } } - totalCredits() - totalRequests() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - 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 = - (byFeature.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + - (if (totalCredits.asKnown().isPresent) 1 else 0) + - (if (totalRequests.asKnown().isPresent) 1 else 0) - - class ByFeature - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val credits: JsonField, - private val feature: JsonField, - private val requests: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("credits") - @ExcludeMissing - credits: JsonField = JsonMissing.of(), - @JsonProperty("feature") - @ExcludeMissing - feature: JsonField = JsonMissing.of(), - @JsonProperty("requests") - @ExcludeMissing - requests: JsonField = JsonMissing.of(), - ) : this(credits, feature, requests, mutableMapOf()) - - /** - * Credits consumed by this feature - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun credits(): Optional = credits.getOptional("credits") - - /** - * API feature name - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun feature(): Optional = feature.getOptional("feature") - - /** - * Number of requests for this feature - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun requests(): Optional = requests.getOptional("requests") - - /** - * Returns the raw JSON value of [credits]. - * - * Unlike [credits], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("credits") @ExcludeMissing fun _credits(): JsonField = credits - - /** - * Returns the raw JSON value of [feature]. - * - * Unlike [feature], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("feature") @ExcludeMissing fun _feature(): JsonField = feature - - /** - * Returns the raw JSON value of [requests]. - * - * Unlike [requests], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("requests") @ExcludeMissing fun _requests(): JsonField = requests - - @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 [ByFeature]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [ByFeature]. */ - class Builder internal constructor() { - - private var credits: JsonField = JsonMissing.of() - private var feature: JsonField = JsonMissing.of() - private var requests: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(byFeature: ByFeature) = apply { - credits = byFeature.credits - feature = byFeature.feature - requests = byFeature.requests - additionalProperties = byFeature.additionalProperties.toMutableMap() - } - - /** Credits consumed by this feature */ - fun credits(credits: Double) = credits(JsonField.of(credits)) - - /** - * Sets [Builder.credits] to an arbitrary JSON value. - * - * You should usually call [Builder.credits] with a well-typed [Double] value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. - */ - fun credits(credits: JsonField) = apply { this.credits = credits } - - /** API feature name */ - fun feature(feature: String) = feature(JsonField.of(feature)) - - /** - * Sets [Builder.feature] to an arbitrary JSON value. - * - * You should usually call [Builder.feature] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. - */ - fun feature(feature: JsonField) = apply { this.feature = feature } - - /** Number of requests for this feature */ - fun requests(requests: Long) = requests(JsonField.of(requests)) - - /** - * Sets [Builder.requests] to an arbitrary JSON value. - * - * You should usually call [Builder.requests] with a well-typed [Long] value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. - */ - fun requests(requests: JsonField) = apply { this.requests = requests } - - 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 [ByFeature]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): ByFeature = - ByFeature(credits, feature, requests, additionalProperties.toMutableMap()) - } - - private var validated: Boolean = false - - fun validate(): ByFeature = apply { - if (validated) { - return@apply - } - - credits() - feature() - requests() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - 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 (credits.asKnown().isPresent) 1 else 0) + - (if (feature.asKnown().isPresent) 1 else 0) + - (if (requests.asKnown().isPresent) 1 else 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ByFeature && - credits == other.credits && - feature == other.feature && - requests == other.requests && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash(credits, feature, requests, additionalProperties) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "ByFeature{credits=$credits, feature=$feature, requests=$requests, additionalProperties=$additionalProperties}" - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Summary && - byFeature == other.byFeature && - totalCredits == other.totalCredits && - totalRequests == other.totalRequests && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash(byFeature, totalCredits, totalRequests, additionalProperties) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Summary{byFeature=$byFeature, totalCredits=$totalCredits, totalRequests=$totalRequests, additionalProperties=$additionalProperties}" - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is LogGetSummaryResponse && - status == other.status && - summary == other.summary && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { Objects.hash(status, summary, additionalProperties) } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "LogGetSummaryResponse{status=$status, summary=$summary, additionalProperties=$additionalProperties}" -} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyParams.kt deleted file mode 100644 index aac1a81..0000000 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyParams.kt +++ /dev/null @@ -1,211 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.models.verifytoken - -import com.cas_parser.api.core.JsonValue -import com.cas_parser.api.core.Params -import com.cas_parser.api.core.http.Headers -import com.cas_parser.api.core.http.QueryParams -import com.cas_parser.api.core.toImmutable -import java.util.Objects -import java.util.Optional - -/** Verify an access token and check if it's still valid. Useful for debugging token issues. */ -class VerifyTokenVerifyParams -private constructor( - private val additionalHeaders: Headers, - private val additionalQueryParams: QueryParams, - private val additionalBodyProperties: Map, -) : Params { - - /** Additional body properties to send with the request. */ - fun _additionalBodyProperties(): Map = additionalBodyProperties - - /** 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 { - - @JvmStatic fun none(): VerifyTokenVerifyParams = builder().build() - - /** Returns a mutable builder for constructing an instance of [VerifyTokenVerifyParams]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [VerifyTokenVerifyParams]. */ - class Builder internal constructor() { - - private var additionalHeaders: Headers.Builder = Headers.builder() - private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() - private var additionalBodyProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(verifyTokenVerifyParams: VerifyTokenVerifyParams) = apply { - additionalHeaders = verifyTokenVerifyParams.additionalHeaders.toBuilder() - additionalQueryParams = verifyTokenVerifyParams.additionalQueryParams.toBuilder() - additionalBodyProperties = - verifyTokenVerifyParams.additionalBodyProperties.toMutableMap() - } - - 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) - } - - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - putAllAdditionalBodyProperties(additionalBodyProperties) - } - - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - additionalBodyProperties.put(key, value) - } - - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = - apply { - this.additionalBodyProperties.putAll(additionalBodyProperties) - } - - fun removeAdditionalBodyProperty(key: String) = apply { - additionalBodyProperties.remove(key) - } - - fun removeAllAdditionalBodyProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalBodyProperty) - } - - /** - * Returns an immutable instance of [VerifyTokenVerifyParams]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): VerifyTokenVerifyParams = - VerifyTokenVerifyParams( - additionalHeaders.build(), - additionalQueryParams.build(), - additionalBodyProperties.toImmutable(), - ) - } - - fun _body(): Optional> = - Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) - - override fun _headers(): Headers = additionalHeaders - - override fun _queryParams(): QueryParams = additionalQueryParams - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is VerifyTokenVerifyParams && - additionalHeaders == other.additionalHeaders && - additionalQueryParams == other.additionalQueryParams && - additionalBodyProperties == other.additionalBodyProperties - } - - override fun hashCode(): Int = - Objects.hash(additionalHeaders, additionalQueryParams, additionalBodyProperties) - - override fun toString() = - "VerifyTokenVerifyParams{additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" -} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyResponse.kt deleted file mode 100644 index b8859a0..0000000 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyResponse.kt +++ /dev/null @@ -1,240 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.models.verifytoken - -import com.cas_parser.api.core.ExcludeMissing -import com.cas_parser.api.core.JsonField -import com.cas_parser.api.core.JsonMissing -import com.cas_parser.api.core.JsonValue -import com.cas_parser.api.errors.CasParserInvalidDataException -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 - -class VerifyTokenVerifyResponse -@JsonCreator(mode = JsonCreator.Mode.DISABLED) -private constructor( - private val error: JsonField, - private val maskedApiKey: JsonField, - private val valid: JsonField, - private val additionalProperties: MutableMap, -) { - - @JsonCreator - private constructor( - @JsonProperty("error") @ExcludeMissing error: JsonField = JsonMissing.of(), - @JsonProperty("masked_api_key") - @ExcludeMissing - maskedApiKey: JsonField = JsonMissing.of(), - @JsonProperty("valid") @ExcludeMissing valid: JsonField = JsonMissing.of(), - ) : this(error, maskedApiKey, valid, mutableMapOf()) - - /** - * Error message (only shown if invalid) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun error(): Optional = error.getOptional("error") - - /** - * Masked API key (only shown if valid) - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun maskedApiKey(): Optional = maskedApiKey.getOptional("masked_api_key") - - /** - * Whether the token is valid - * - * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun valid(): Optional = valid.getOptional("valid") - - /** - * Returns the raw JSON value of [error]. - * - * Unlike [error], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("error") @ExcludeMissing fun _error(): JsonField = error - - /** - * Returns the raw JSON value of [maskedApiKey]. - * - * Unlike [maskedApiKey], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("masked_api_key") - @ExcludeMissing - fun _maskedApiKey(): JsonField = maskedApiKey - - /** - * Returns the raw JSON value of [valid]. - * - * Unlike [valid], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("valid") @ExcludeMissing fun _valid(): JsonField = valid - - @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 [VerifyTokenVerifyResponse]. - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [VerifyTokenVerifyResponse]. */ - class Builder internal constructor() { - - private var error: JsonField = JsonMissing.of() - private var maskedApiKey: JsonField = JsonMissing.of() - private var valid: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(verifyTokenVerifyResponse: VerifyTokenVerifyResponse) = apply { - error = verifyTokenVerifyResponse.error - maskedApiKey = verifyTokenVerifyResponse.maskedApiKey - valid = verifyTokenVerifyResponse.valid - additionalProperties = verifyTokenVerifyResponse.additionalProperties.toMutableMap() - } - - /** Error message (only shown if invalid) */ - fun error(error: String) = error(JsonField.of(error)) - - /** - * Sets [Builder.error] to an arbitrary JSON value. - * - * You should usually call [Builder.error] with a well-typed [String] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun error(error: JsonField) = apply { this.error = error } - - /** Masked API key (only shown if valid) */ - fun maskedApiKey(maskedApiKey: String) = maskedApiKey(JsonField.of(maskedApiKey)) - - /** - * Sets [Builder.maskedApiKey] to an arbitrary JSON value. - * - * You should usually call [Builder.maskedApiKey] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet supported - * value. - */ - fun maskedApiKey(maskedApiKey: JsonField) = apply { - this.maskedApiKey = maskedApiKey - } - - /** Whether the token is valid */ - fun valid(valid: Boolean) = valid(JsonField.of(valid)) - - /** - * Sets [Builder.valid] to an arbitrary JSON value. - * - * You should usually call [Builder.valid] with a well-typed [Boolean] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun valid(valid: JsonField) = apply { this.valid = valid } - - 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 [VerifyTokenVerifyResponse]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): VerifyTokenVerifyResponse = - VerifyTokenVerifyResponse( - error, - maskedApiKey, - valid, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): VerifyTokenVerifyResponse = apply { - if (validated) { - return@apply - } - - error() - maskedApiKey() - valid() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: CasParserInvalidDataException) { - 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 (error.asKnown().isPresent) 1 else 0) + - (if (maskedApiKey.asKnown().isPresent) 1 else 0) + - (if (valid.asKnown().isPresent) 1 else 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is VerifyTokenVerifyResponse && - error == other.error && - maskedApiKey == other.maskedApiKey && - valid == other.valid && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash(error, maskedApiKey, valid, additionalProperties) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "VerifyTokenVerifyResponse{error=$error, maskedApiKey=$maskedApiKey, valid=$valid, additionalProperties=$additionalProperties}" -} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsync.kt index 0948924..3809ee6 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsync.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsync.kt @@ -3,11 +3,6 @@ package com.cas_parser.api.services.async import com.cas_parser.api.core.ClientOptions -import com.cas_parser.api.core.RequestOptions -import com.cas_parser.api.core.http.HttpResponseFor -import com.cas_parser.api.models.accesstoken.AccessTokenCreateParams -import com.cas_parser.api.models.accesstoken.AccessTokenCreateResponse -import java.util.concurrent.CompletableFuture import java.util.function.Consumer interface AccessTokenServiceAsync { @@ -24,36 +19,6 @@ interface AccessTokenServiceAsync { */ fun withOptions(modifier: Consumer): AccessTokenServiceAsync - /** - * Generate a short-lived access token from your API key. - * - * **Use this endpoint from your backend** to create tokens that can be safely passed to - * frontend/SDK. - * - * Access tokens: - * - Are prefixed with `at_` for easy identification - * - Valid for up to 60 minutes - * - Can be used in place of API keys on all v4 endpoints - * - Cannot be used to generate other access tokens - */ - fun create(): CompletableFuture = - create(AccessTokenCreateParams.none()) - - /** @see create */ - fun create( - params: AccessTokenCreateParams = AccessTokenCreateParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture - - /** @see create */ - fun create( - params: AccessTokenCreateParams = AccessTokenCreateParams.none() - ): CompletableFuture = create(params, RequestOptions.none()) - - /** @see create */ - fun create(requestOptions: RequestOptions): CompletableFuture = - create(AccessTokenCreateParams.none(), requestOptions) - /** * A view of [AccessTokenServiceAsync] that provides access to raw HTTP responses for each * method. @@ -68,30 +33,5 @@ interface AccessTokenServiceAsync { fun withOptions( modifier: Consumer ): AccessTokenServiceAsync.WithRawResponse - - /** - * Returns a raw HTTP response for `post /v1/access-token`, but is otherwise the same as - * [AccessTokenServiceAsync.create]. - */ - fun create(): CompletableFuture> = - create(AccessTokenCreateParams.none()) - - /** @see create */ - fun create( - params: AccessTokenCreateParams = AccessTokenCreateParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture> - - /** @see create */ - fun create( - params: AccessTokenCreateParams = AccessTokenCreateParams.none() - ): CompletableFuture> = - create(params, RequestOptions.none()) - - /** @see create */ - fun create( - requestOptions: RequestOptions - ): CompletableFuture> = - create(AccessTokenCreateParams.none(), requestOptions) } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsyncImpl.kt index e71b99c..a947c34 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsyncImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsyncImpl.kt @@ -3,21 +3,6 @@ package com.cas_parser.api.services.async import com.cas_parser.api.core.ClientOptions -import com.cas_parser.api.core.RequestOptions -import com.cas_parser.api.core.handlers.errorBodyHandler -import com.cas_parser.api.core.handlers.errorHandler -import com.cas_parser.api.core.handlers.jsonHandler -import com.cas_parser.api.core.http.HttpMethod -import com.cas_parser.api.core.http.HttpRequest -import com.cas_parser.api.core.http.HttpResponse -import com.cas_parser.api.core.http.HttpResponse.Handler -import com.cas_parser.api.core.http.HttpResponseFor -import com.cas_parser.api.core.http.json -import com.cas_parser.api.core.http.parseable -import com.cas_parser.api.core.prepareAsync -import com.cas_parser.api.models.accesstoken.AccessTokenCreateParams -import com.cas_parser.api.models.accesstoken.AccessTokenCreateResponse -import java.util.concurrent.CompletableFuture import java.util.function.Consumer class AccessTokenServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : @@ -32,55 +17,14 @@ class AccessTokenServiceAsyncImpl internal constructor(private val clientOptions override fun withOptions(modifier: Consumer): AccessTokenServiceAsync = AccessTokenServiceAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build()) - override fun create( - params: AccessTokenCreateParams, - requestOptions: RequestOptions, - ): CompletableFuture = - // post /v1/access-token - withRawResponse().create(params, requestOptions).thenApply { it.parse() } - class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : AccessTokenServiceAsync.WithRawResponse { - private val errorHandler: Handler = - errorHandler(errorBodyHandler(clientOptions.jsonMapper)) - override fun withOptions( modifier: Consumer ): AccessTokenServiceAsync.WithRawResponse = AccessTokenServiceAsyncImpl.WithRawResponseImpl( clientOptions.toBuilder().apply(modifier::accept).build() ) - - private val createHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - - override fun create( - params: AccessTokenCreateParams, - requestOptions: RequestOptions, - ): CompletableFuture> { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .baseUrl(clientOptions.baseUrl()) - .addPathSegments("v1", "access-token") - .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 { createHandler.handle(it) } - .also { - if (requestOptions.responseValidation!!) { - it.validate() - } - } - } - } - } } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CreditServiceAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CreditServiceAsync.kt index 05290f8..70f75cb 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CreditServiceAsync.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CreditServiceAsync.kt @@ -3,11 +3,6 @@ package com.cas_parser.api.services.async import com.cas_parser.api.core.ClientOptions -import com.cas_parser.api.core.RequestOptions -import com.cas_parser.api.core.http.HttpResponseFor -import com.cas_parser.api.models.credits.CreditCheckParams -import com.cas_parser.api.models.credits.CreditCheckResponse -import java.util.concurrent.CompletableFuture import java.util.function.Consumer interface CreditServiceAsync { @@ -24,33 +19,6 @@ interface CreditServiceAsync { */ fun withOptions(modifier: Consumer): CreditServiceAsync - /** - * Check your remaining API credits and usage for the current billing period. - * - * Returns: - * - Number of API calls used and remaining credits - * - Credit limit and reset date - * - List of enabled features for your plan - * - * Credits reset at the start of each billing period. - */ - fun check(): CompletableFuture = check(CreditCheckParams.none()) - - /** @see check */ - fun check( - params: CreditCheckParams = CreditCheckParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture - - /** @see check */ - fun check( - params: CreditCheckParams = CreditCheckParams.none() - ): CompletableFuture = check(params, RequestOptions.none()) - - /** @see check */ - fun check(requestOptions: RequestOptions): CompletableFuture = - check(CreditCheckParams.none(), requestOptions) - /** * A view of [CreditServiceAsync] that provides access to raw HTTP responses for each method. */ @@ -64,30 +32,5 @@ interface CreditServiceAsync { fun withOptions( modifier: Consumer ): CreditServiceAsync.WithRawResponse - - /** - * Returns a raw HTTP response for `post /credits`, but is otherwise the same as - * [CreditServiceAsync.check]. - */ - fun check(): CompletableFuture> = - check(CreditCheckParams.none()) - - /** @see check */ - fun check( - params: CreditCheckParams = CreditCheckParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture> - - /** @see check */ - fun check( - params: CreditCheckParams = CreditCheckParams.none() - ): CompletableFuture> = - check(params, RequestOptions.none()) - - /** @see check */ - fun check( - requestOptions: RequestOptions - ): CompletableFuture> = - check(CreditCheckParams.none(), requestOptions) } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CreditServiceAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CreditServiceAsyncImpl.kt index 6f2806c..9995851 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CreditServiceAsyncImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CreditServiceAsyncImpl.kt @@ -3,21 +3,6 @@ package com.cas_parser.api.services.async import com.cas_parser.api.core.ClientOptions -import com.cas_parser.api.core.RequestOptions -import com.cas_parser.api.core.handlers.errorBodyHandler -import com.cas_parser.api.core.handlers.errorHandler -import com.cas_parser.api.core.handlers.jsonHandler -import com.cas_parser.api.core.http.HttpMethod -import com.cas_parser.api.core.http.HttpRequest -import com.cas_parser.api.core.http.HttpResponse -import com.cas_parser.api.core.http.HttpResponse.Handler -import com.cas_parser.api.core.http.HttpResponseFor -import com.cas_parser.api.core.http.json -import com.cas_parser.api.core.http.parseable -import com.cas_parser.api.core.prepareAsync -import com.cas_parser.api.models.credits.CreditCheckParams -import com.cas_parser.api.models.credits.CreditCheckResponse -import java.util.concurrent.CompletableFuture import java.util.function.Consumer class CreditServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : @@ -32,55 +17,14 @@ class CreditServiceAsyncImpl internal constructor(private val clientOptions: Cli override fun withOptions(modifier: Consumer): CreditServiceAsync = CreditServiceAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build()) - override fun check( - params: CreditCheckParams, - requestOptions: RequestOptions, - ): CompletableFuture = - // post /credits - withRawResponse().check(params, requestOptions).thenApply { it.parse() } - class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : CreditServiceAsync.WithRawResponse { - private val errorHandler: Handler = - errorHandler(errorBodyHandler(clientOptions.jsonMapper)) - override fun withOptions( modifier: Consumer ): CreditServiceAsync.WithRawResponse = CreditServiceAsyncImpl.WithRawResponseImpl( clientOptions.toBuilder().apply(modifier::accept).build() ) - - private val checkHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - - override fun check( - params: CreditCheckParams, - requestOptions: RequestOptions, - ): CompletableFuture> { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .baseUrl(clientOptions.baseUrl()) - .addPathSegments("credits") - .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 { checkHandler.handle(it) } - .also { - if (requestOptions.responseValidation!!) { - it.validate() - } - } - } - } - } } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/LogServiceAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/LogServiceAsync.kt index 641ee6a..4dc2b00 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/LogServiceAsync.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/LogServiceAsync.kt @@ -3,13 +3,6 @@ package com.cas_parser.api.services.async import com.cas_parser.api.core.ClientOptions -import com.cas_parser.api.core.RequestOptions -import com.cas_parser.api.core.http.HttpResponseFor -import com.cas_parser.api.models.logs.LogCreateParams -import com.cas_parser.api.models.logs.LogCreateResponse -import com.cas_parser.api.models.logs.LogGetSummaryParams -import com.cas_parser.api.models.logs.LogGetSummaryResponse -import java.util.concurrent.CompletableFuture import java.util.function.Consumer interface LogServiceAsync { @@ -26,52 +19,6 @@ interface LogServiceAsync { */ fun withOptions(modifier: Consumer): LogServiceAsync - /** - * Retrieve detailed API usage logs for your account. - * - * Returns a list of API calls with timestamps, features used, status codes, and credits - * consumed. Useful for monitoring usage patterns and debugging. - */ - fun create(): CompletableFuture = create(LogCreateParams.none()) - - /** @see create */ - fun create( - params: LogCreateParams = LogCreateParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture - - /** @see create */ - fun create( - params: LogCreateParams = LogCreateParams.none() - ): CompletableFuture = create(params, RequestOptions.none()) - - /** @see create */ - fun create(requestOptions: RequestOptions): CompletableFuture = - create(LogCreateParams.none(), requestOptions) - - /** - * Get aggregated usage statistics grouped by feature. - * - * Useful for understanding which API features are being used most and tracking usage trends. - */ - fun getSummary(): CompletableFuture = - getSummary(LogGetSummaryParams.none()) - - /** @see getSummary */ - fun getSummary( - params: LogGetSummaryParams = LogGetSummaryParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture - - /** @see getSummary */ - fun getSummary( - params: LogGetSummaryParams = LogGetSummaryParams.none() - ): CompletableFuture = getSummary(params, RequestOptions.none()) - - /** @see getSummary */ - fun getSummary(requestOptions: RequestOptions): CompletableFuture = - getSummary(LogGetSummaryParams.none(), requestOptions) - /** A view of [LogServiceAsync] that provides access to raw HTTP responses for each method. */ interface WithRawResponse { @@ -81,55 +28,5 @@ interface LogServiceAsync { * The original service is not modified. */ fun withOptions(modifier: Consumer): LogServiceAsync.WithRawResponse - - /** - * Returns a raw HTTP response for `post /logs`, but is otherwise the same as - * [LogServiceAsync.create]. - */ - fun create(): CompletableFuture> = - create(LogCreateParams.none()) - - /** @see create */ - fun create( - params: LogCreateParams = LogCreateParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture> - - /** @see create */ - fun create( - params: LogCreateParams = LogCreateParams.none() - ): CompletableFuture> = - create(params, RequestOptions.none()) - - /** @see create */ - fun create( - requestOptions: RequestOptions - ): CompletableFuture> = - create(LogCreateParams.none(), requestOptions) - - /** - * Returns a raw HTTP response for `post /logs/summary`, but is otherwise the same as - * [LogServiceAsync.getSummary]. - */ - fun getSummary(): CompletableFuture> = - getSummary(LogGetSummaryParams.none()) - - /** @see getSummary */ - fun getSummary( - params: LogGetSummaryParams = LogGetSummaryParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture> - - /** @see getSummary */ - fun getSummary( - params: LogGetSummaryParams = LogGetSummaryParams.none() - ): CompletableFuture> = - getSummary(params, RequestOptions.none()) - - /** @see getSummary */ - fun getSummary( - requestOptions: RequestOptions - ): CompletableFuture> = - getSummary(LogGetSummaryParams.none(), requestOptions) } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/LogServiceAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/LogServiceAsyncImpl.kt index 1dd0192..6797075 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/LogServiceAsyncImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/LogServiceAsyncImpl.kt @@ -3,23 +3,6 @@ package com.cas_parser.api.services.async import com.cas_parser.api.core.ClientOptions -import com.cas_parser.api.core.RequestOptions -import com.cas_parser.api.core.handlers.errorBodyHandler -import com.cas_parser.api.core.handlers.errorHandler -import com.cas_parser.api.core.handlers.jsonHandler -import com.cas_parser.api.core.http.HttpMethod -import com.cas_parser.api.core.http.HttpRequest -import com.cas_parser.api.core.http.HttpResponse -import com.cas_parser.api.core.http.HttpResponse.Handler -import com.cas_parser.api.core.http.HttpResponseFor -import com.cas_parser.api.core.http.json -import com.cas_parser.api.core.http.parseable -import com.cas_parser.api.core.prepareAsync -import com.cas_parser.api.models.logs.LogCreateParams -import com.cas_parser.api.models.logs.LogCreateResponse -import com.cas_parser.api.models.logs.LogGetSummaryParams -import com.cas_parser.api.models.logs.LogGetSummaryResponse -import java.util.concurrent.CompletableFuture import java.util.function.Consumer class LogServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : @@ -34,93 +17,14 @@ class LogServiceAsyncImpl internal constructor(private val clientOptions: Client override fun withOptions(modifier: Consumer): LogServiceAsync = LogServiceAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build()) - override fun create( - params: LogCreateParams, - requestOptions: RequestOptions, - ): CompletableFuture = - // post /logs - withRawResponse().create(params, requestOptions).thenApply { it.parse() } - - override fun getSummary( - params: LogGetSummaryParams, - requestOptions: RequestOptions, - ): CompletableFuture = - // post /logs/summary - withRawResponse().getSummary(params, requestOptions).thenApply { it.parse() } - class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : LogServiceAsync.WithRawResponse { - private val errorHandler: Handler = - errorHandler(errorBodyHandler(clientOptions.jsonMapper)) - override fun withOptions( modifier: Consumer ): LogServiceAsync.WithRawResponse = LogServiceAsyncImpl.WithRawResponseImpl( clientOptions.toBuilder().apply(modifier::accept).build() ) - - private val createHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - - override fun create( - params: LogCreateParams, - requestOptions: RequestOptions, - ): CompletableFuture> { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .baseUrl(clientOptions.baseUrl()) - .addPathSegments("logs") - .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 { createHandler.handle(it) } - .also { - if (requestOptions.responseValidation!!) { - it.validate() - } - } - } - } - } - - private val getSummaryHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - - override fun getSummary( - params: LogGetSummaryParams, - requestOptions: RequestOptions, - ): CompletableFuture> { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .baseUrl(clientOptions.baseUrl()) - .addPathSegments("logs", "summary") - .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 { getSummaryHandler.handle(it) } - .also { - if (requestOptions.responseValidation!!) { - it.validate() - } - } - } - } - } } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsync.kt index 2a7125e..4ff8c23 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsync.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsync.kt @@ -3,11 +3,6 @@ package com.cas_parser.api.services.async import com.cas_parser.api.core.ClientOptions -import com.cas_parser.api.core.RequestOptions -import com.cas_parser.api.core.http.HttpResponseFor -import com.cas_parser.api.models.verifytoken.VerifyTokenVerifyParams -import com.cas_parser.api.models.verifytoken.VerifyTokenVerifyResponse -import java.util.concurrent.CompletableFuture import java.util.function.Consumer interface VerifyTokenServiceAsync { @@ -24,25 +19,6 @@ interface VerifyTokenServiceAsync { */ fun withOptions(modifier: Consumer): VerifyTokenServiceAsync - /** Verify an access token and check if it's still valid. Useful for debugging token issues. */ - fun verify(): CompletableFuture = - verify(VerifyTokenVerifyParams.none()) - - /** @see verify */ - fun verify( - params: VerifyTokenVerifyParams = VerifyTokenVerifyParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture - - /** @see verify */ - fun verify( - params: VerifyTokenVerifyParams = VerifyTokenVerifyParams.none() - ): CompletableFuture = verify(params, RequestOptions.none()) - - /** @see verify */ - fun verify(requestOptions: RequestOptions): CompletableFuture = - verify(VerifyTokenVerifyParams.none(), requestOptions) - /** * A view of [VerifyTokenServiceAsync] that provides access to raw HTTP responses for each * method. @@ -57,30 +33,5 @@ interface VerifyTokenServiceAsync { fun withOptions( modifier: Consumer ): VerifyTokenServiceAsync.WithRawResponse - - /** - * Returns a raw HTTP response for `post /v1/verify-token`, but is otherwise the same as - * [VerifyTokenServiceAsync.verify]. - */ - fun verify(): CompletableFuture> = - verify(VerifyTokenVerifyParams.none()) - - /** @see verify */ - fun verify( - params: VerifyTokenVerifyParams = VerifyTokenVerifyParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture> - - /** @see verify */ - fun verify( - params: VerifyTokenVerifyParams = VerifyTokenVerifyParams.none() - ): CompletableFuture> = - verify(params, RequestOptions.none()) - - /** @see verify */ - fun verify( - requestOptions: RequestOptions - ): CompletableFuture> = - verify(VerifyTokenVerifyParams.none(), requestOptions) } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsyncImpl.kt index ba12f1b..c617351 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsyncImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsyncImpl.kt @@ -3,21 +3,6 @@ package com.cas_parser.api.services.async import com.cas_parser.api.core.ClientOptions -import com.cas_parser.api.core.RequestOptions -import com.cas_parser.api.core.handlers.errorBodyHandler -import com.cas_parser.api.core.handlers.errorHandler -import com.cas_parser.api.core.handlers.jsonHandler -import com.cas_parser.api.core.http.HttpMethod -import com.cas_parser.api.core.http.HttpRequest -import com.cas_parser.api.core.http.HttpResponse -import com.cas_parser.api.core.http.HttpResponse.Handler -import com.cas_parser.api.core.http.HttpResponseFor -import com.cas_parser.api.core.http.json -import com.cas_parser.api.core.http.parseable -import com.cas_parser.api.core.prepareAsync -import com.cas_parser.api.models.verifytoken.VerifyTokenVerifyParams -import com.cas_parser.api.models.verifytoken.VerifyTokenVerifyResponse -import java.util.concurrent.CompletableFuture import java.util.function.Consumer class VerifyTokenServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : @@ -32,55 +17,14 @@ class VerifyTokenServiceAsyncImpl internal constructor(private val clientOptions override fun withOptions(modifier: Consumer): VerifyTokenServiceAsync = VerifyTokenServiceAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build()) - override fun verify( - params: VerifyTokenVerifyParams, - requestOptions: RequestOptions, - ): CompletableFuture = - // post /v1/verify-token - withRawResponse().verify(params, requestOptions).thenApply { it.parse() } - class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : VerifyTokenServiceAsync.WithRawResponse { - private val errorHandler: Handler = - errorHandler(errorBodyHandler(clientOptions.jsonMapper)) - override fun withOptions( modifier: Consumer ): VerifyTokenServiceAsync.WithRawResponse = VerifyTokenServiceAsyncImpl.WithRawResponseImpl( clientOptions.toBuilder().apply(modifier::accept).build() ) - - private val verifyHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - - override fun verify( - params: VerifyTokenVerifyParams, - requestOptions: RequestOptions, - ): CompletableFuture> { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .baseUrl(clientOptions.baseUrl()) - .addPathSegments("v1", "verify-token") - .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 { verifyHandler.handle(it) } - .also { - if (requestOptions.responseValidation!!) { - it.validate() - } - } - } - } - } } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/AccessTokenService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/AccessTokenService.kt index 3414d2a..2779802 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/AccessTokenService.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/AccessTokenService.kt @@ -3,11 +3,6 @@ package com.cas_parser.api.services.blocking import com.cas_parser.api.core.ClientOptions -import com.cas_parser.api.core.RequestOptions -import com.cas_parser.api.core.http.HttpResponseFor -import com.cas_parser.api.models.accesstoken.AccessTokenCreateParams -import com.cas_parser.api.models.accesstoken.AccessTokenCreateResponse -import com.google.errorprone.annotations.MustBeClosed import java.util.function.Consumer interface AccessTokenService { @@ -24,35 +19,6 @@ interface AccessTokenService { */ fun withOptions(modifier: Consumer): AccessTokenService - /** - * Generate a short-lived access token from your API key. - * - * **Use this endpoint from your backend** to create tokens that can be safely passed to - * frontend/SDK. - * - * Access tokens: - * - Are prefixed with `at_` for easy identification - * - Valid for up to 60 minutes - * - Can be used in place of API keys on all v4 endpoints - * - Cannot be used to generate other access tokens - */ - fun create(): AccessTokenCreateResponse = create(AccessTokenCreateParams.none()) - - /** @see create */ - fun create( - params: AccessTokenCreateParams = AccessTokenCreateParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): AccessTokenCreateResponse - - /** @see create */ - fun create( - params: AccessTokenCreateParams = AccessTokenCreateParams.none() - ): AccessTokenCreateResponse = create(params, RequestOptions.none()) - - /** @see create */ - fun create(requestOptions: RequestOptions): AccessTokenCreateResponse = - create(AccessTokenCreateParams.none(), requestOptions) - /** * A view of [AccessTokenService] that provides access to raw HTTP responses for each method. */ @@ -66,31 +32,5 @@ interface AccessTokenService { fun withOptions( modifier: Consumer ): AccessTokenService.WithRawResponse - - /** - * Returns a raw HTTP response for `post /v1/access-token`, but is otherwise the same as - * [AccessTokenService.create]. - */ - @MustBeClosed - fun create(): HttpResponseFor = - create(AccessTokenCreateParams.none()) - - /** @see create */ - @MustBeClosed - fun create( - params: AccessTokenCreateParams = AccessTokenCreateParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): HttpResponseFor - - /** @see create */ - @MustBeClosed - fun create( - params: AccessTokenCreateParams = AccessTokenCreateParams.none() - ): HttpResponseFor = create(params, RequestOptions.none()) - - /** @see create */ - @MustBeClosed - fun create(requestOptions: RequestOptions): HttpResponseFor = - create(AccessTokenCreateParams.none(), requestOptions) } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/AccessTokenServiceImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/AccessTokenServiceImpl.kt index 9906e2d..a8c27c2 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/AccessTokenServiceImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/AccessTokenServiceImpl.kt @@ -3,20 +3,6 @@ package com.cas_parser.api.services.blocking import com.cas_parser.api.core.ClientOptions -import com.cas_parser.api.core.RequestOptions -import com.cas_parser.api.core.handlers.errorBodyHandler -import com.cas_parser.api.core.handlers.errorHandler -import com.cas_parser.api.core.handlers.jsonHandler -import com.cas_parser.api.core.http.HttpMethod -import com.cas_parser.api.core.http.HttpRequest -import com.cas_parser.api.core.http.HttpResponse -import com.cas_parser.api.core.http.HttpResponse.Handler -import com.cas_parser.api.core.http.HttpResponseFor -import com.cas_parser.api.core.http.json -import com.cas_parser.api.core.http.parseable -import com.cas_parser.api.core.prepare -import com.cas_parser.api.models.accesstoken.AccessTokenCreateParams -import com.cas_parser.api.models.accesstoken.AccessTokenCreateResponse import java.util.function.Consumer class AccessTokenServiceImpl internal constructor(private val clientOptions: ClientOptions) : @@ -31,52 +17,14 @@ class AccessTokenServiceImpl internal constructor(private val clientOptions: Cli override fun withOptions(modifier: Consumer): AccessTokenService = AccessTokenServiceImpl(clientOptions.toBuilder().apply(modifier::accept).build()) - override fun create( - params: AccessTokenCreateParams, - requestOptions: RequestOptions, - ): AccessTokenCreateResponse = - // post /v1/access-token - withRawResponse().create(params, requestOptions).parse() - class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : AccessTokenService.WithRawResponse { - private val errorHandler: Handler = - errorHandler(errorBodyHandler(clientOptions.jsonMapper)) - override fun withOptions( modifier: Consumer ): AccessTokenService.WithRawResponse = AccessTokenServiceImpl.WithRawResponseImpl( clientOptions.toBuilder().apply(modifier::accept).build() ) - - private val createHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - - override fun create( - params: AccessTokenCreateParams, - requestOptions: RequestOptions, - ): HttpResponseFor { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .baseUrl(clientOptions.baseUrl()) - .addPathSegments("v1", "access-token") - .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 { createHandler.handle(it) } - .also { - if (requestOptions.responseValidation!!) { - it.validate() - } - } - } - } } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CreditService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CreditService.kt index 5d22d46..60ebf10 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CreditService.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CreditService.kt @@ -3,11 +3,6 @@ package com.cas_parser.api.services.blocking import com.cas_parser.api.core.ClientOptions -import com.cas_parser.api.core.RequestOptions -import com.cas_parser.api.core.http.HttpResponseFor -import com.cas_parser.api.models.credits.CreditCheckParams -import com.cas_parser.api.models.credits.CreditCheckResponse -import com.google.errorprone.annotations.MustBeClosed import java.util.function.Consumer interface CreditService { @@ -24,32 +19,6 @@ interface CreditService { */ fun withOptions(modifier: Consumer): CreditService - /** - * Check your remaining API credits and usage for the current billing period. - * - * Returns: - * - Number of API calls used and remaining credits - * - Credit limit and reset date - * - List of enabled features for your plan - * - * Credits reset at the start of each billing period. - */ - fun check(): CreditCheckResponse = check(CreditCheckParams.none()) - - /** @see check */ - fun check( - params: CreditCheckParams = CreditCheckParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): CreditCheckResponse - - /** @see check */ - fun check(params: CreditCheckParams = CreditCheckParams.none()): CreditCheckResponse = - check(params, RequestOptions.none()) - - /** @see check */ - fun check(requestOptions: RequestOptions): CreditCheckResponse = - check(CreditCheckParams.none(), requestOptions) - /** A view of [CreditService] that provides access to raw HTTP responses for each method. */ interface WithRawResponse { @@ -59,30 +28,5 @@ interface CreditService { * The original service is not modified. */ fun withOptions(modifier: Consumer): CreditService.WithRawResponse - - /** - * Returns a raw HTTP response for `post /credits`, but is otherwise the same as - * [CreditService.check]. - */ - @MustBeClosed - fun check(): HttpResponseFor = check(CreditCheckParams.none()) - - /** @see check */ - @MustBeClosed - fun check( - params: CreditCheckParams = CreditCheckParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): HttpResponseFor - - /** @see check */ - @MustBeClosed - fun check( - params: CreditCheckParams = CreditCheckParams.none() - ): HttpResponseFor = check(params, RequestOptions.none()) - - /** @see check */ - @MustBeClosed - fun check(requestOptions: RequestOptions): HttpResponseFor = - check(CreditCheckParams.none(), requestOptions) } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CreditServiceImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CreditServiceImpl.kt index 549e113..a33b3c5 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CreditServiceImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CreditServiceImpl.kt @@ -3,20 +3,6 @@ package com.cas_parser.api.services.blocking import com.cas_parser.api.core.ClientOptions -import com.cas_parser.api.core.RequestOptions -import com.cas_parser.api.core.handlers.errorBodyHandler -import com.cas_parser.api.core.handlers.errorHandler -import com.cas_parser.api.core.handlers.jsonHandler -import com.cas_parser.api.core.http.HttpMethod -import com.cas_parser.api.core.http.HttpRequest -import com.cas_parser.api.core.http.HttpResponse -import com.cas_parser.api.core.http.HttpResponse.Handler -import com.cas_parser.api.core.http.HttpResponseFor -import com.cas_parser.api.core.http.json -import com.cas_parser.api.core.http.parseable -import com.cas_parser.api.core.prepare -import com.cas_parser.api.models.credits.CreditCheckParams -import com.cas_parser.api.models.credits.CreditCheckResponse import java.util.function.Consumer class CreditServiceImpl internal constructor(private val clientOptions: ClientOptions) : @@ -31,52 +17,14 @@ class CreditServiceImpl internal constructor(private val clientOptions: ClientOp override fun withOptions(modifier: Consumer): CreditService = CreditServiceImpl(clientOptions.toBuilder().apply(modifier::accept).build()) - override fun check( - params: CreditCheckParams, - requestOptions: RequestOptions, - ): CreditCheckResponse = - // post /credits - withRawResponse().check(params, requestOptions).parse() - class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : CreditService.WithRawResponse { - private val errorHandler: Handler = - errorHandler(errorBodyHandler(clientOptions.jsonMapper)) - override fun withOptions( modifier: Consumer ): CreditService.WithRawResponse = CreditServiceImpl.WithRawResponseImpl( clientOptions.toBuilder().apply(modifier::accept).build() ) - - private val checkHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - - override fun check( - params: CreditCheckParams, - requestOptions: RequestOptions, - ): HttpResponseFor { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .baseUrl(clientOptions.baseUrl()) - .addPathSegments("credits") - .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 { checkHandler.handle(it) } - .also { - if (requestOptions.responseValidation!!) { - it.validate() - } - } - } - } } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/LogService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/LogService.kt index ce35cba..f95703a 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/LogService.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/LogService.kt @@ -3,13 +3,6 @@ package com.cas_parser.api.services.blocking import com.cas_parser.api.core.ClientOptions -import com.cas_parser.api.core.RequestOptions -import com.cas_parser.api.core.http.HttpResponseFor -import com.cas_parser.api.models.logs.LogCreateParams -import com.cas_parser.api.models.logs.LogCreateResponse -import com.cas_parser.api.models.logs.LogGetSummaryParams -import com.cas_parser.api.models.logs.LogGetSummaryResponse -import com.google.errorprone.annotations.MustBeClosed import java.util.function.Consumer interface LogService { @@ -26,50 +19,6 @@ interface LogService { */ fun withOptions(modifier: Consumer): LogService - /** - * Retrieve detailed API usage logs for your account. - * - * Returns a list of API calls with timestamps, features used, status codes, and credits - * consumed. Useful for monitoring usage patterns and debugging. - */ - fun create(): LogCreateResponse = create(LogCreateParams.none()) - - /** @see create */ - fun create( - params: LogCreateParams = LogCreateParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): LogCreateResponse - - /** @see create */ - fun create(params: LogCreateParams = LogCreateParams.none()): LogCreateResponse = - create(params, RequestOptions.none()) - - /** @see create */ - fun create(requestOptions: RequestOptions): LogCreateResponse = - create(LogCreateParams.none(), requestOptions) - - /** - * Get aggregated usage statistics grouped by feature. - * - * Useful for understanding which API features are being used most and tracking usage trends. - */ - fun getSummary(): LogGetSummaryResponse = getSummary(LogGetSummaryParams.none()) - - /** @see getSummary */ - fun getSummary( - params: LogGetSummaryParams = LogGetSummaryParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): LogGetSummaryResponse - - /** @see getSummary */ - fun getSummary( - params: LogGetSummaryParams = LogGetSummaryParams.none() - ): LogGetSummaryResponse = getSummary(params, RequestOptions.none()) - - /** @see getSummary */ - fun getSummary(requestOptions: RequestOptions): LogGetSummaryResponse = - getSummary(LogGetSummaryParams.none(), requestOptions) - /** A view of [LogService] that provides access to raw HTTP responses for each method. */ interface WithRawResponse { @@ -79,56 +28,5 @@ interface LogService { * The original service is not modified. */ fun withOptions(modifier: Consumer): LogService.WithRawResponse - - /** - * Returns a raw HTTP response for `post /logs`, but is otherwise the same as - * [LogService.create]. - */ - @MustBeClosed - fun create(): HttpResponseFor = create(LogCreateParams.none()) - - /** @see create */ - @MustBeClosed - fun create( - params: LogCreateParams = LogCreateParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): HttpResponseFor - - /** @see create */ - @MustBeClosed - fun create( - params: LogCreateParams = LogCreateParams.none() - ): HttpResponseFor = create(params, RequestOptions.none()) - - /** @see create */ - @MustBeClosed - fun create(requestOptions: RequestOptions): HttpResponseFor = - create(LogCreateParams.none(), requestOptions) - - /** - * Returns a raw HTTP response for `post /logs/summary`, but is otherwise the same as - * [LogService.getSummary]. - */ - @MustBeClosed - fun getSummary(): HttpResponseFor = - getSummary(LogGetSummaryParams.none()) - - /** @see getSummary */ - @MustBeClosed - fun getSummary( - params: LogGetSummaryParams = LogGetSummaryParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): HttpResponseFor - - /** @see getSummary */ - @MustBeClosed - fun getSummary( - params: LogGetSummaryParams = LogGetSummaryParams.none() - ): HttpResponseFor = getSummary(params, RequestOptions.none()) - - /** @see getSummary */ - @MustBeClosed - fun getSummary(requestOptions: RequestOptions): HttpResponseFor = - getSummary(LogGetSummaryParams.none(), requestOptions) } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/LogServiceImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/LogServiceImpl.kt index fb303d1..0a82263 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/LogServiceImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/LogServiceImpl.kt @@ -3,22 +3,6 @@ package com.cas_parser.api.services.blocking import com.cas_parser.api.core.ClientOptions -import com.cas_parser.api.core.RequestOptions -import com.cas_parser.api.core.handlers.errorBodyHandler -import com.cas_parser.api.core.handlers.errorHandler -import com.cas_parser.api.core.handlers.jsonHandler -import com.cas_parser.api.core.http.HttpMethod -import com.cas_parser.api.core.http.HttpRequest -import com.cas_parser.api.core.http.HttpResponse -import com.cas_parser.api.core.http.HttpResponse.Handler -import com.cas_parser.api.core.http.HttpResponseFor -import com.cas_parser.api.core.http.json -import com.cas_parser.api.core.http.parseable -import com.cas_parser.api.core.prepare -import com.cas_parser.api.models.logs.LogCreateParams -import com.cas_parser.api.models.logs.LogCreateResponse -import com.cas_parser.api.models.logs.LogGetSummaryParams -import com.cas_parser.api.models.logs.LogGetSummaryResponse import java.util.function.Consumer class LogServiceImpl internal constructor(private val clientOptions: ClientOptions) : LogService { @@ -32,87 +16,14 @@ class LogServiceImpl internal constructor(private val clientOptions: ClientOptio override fun withOptions(modifier: Consumer): LogService = LogServiceImpl(clientOptions.toBuilder().apply(modifier::accept).build()) - override fun create( - params: LogCreateParams, - requestOptions: RequestOptions, - ): LogCreateResponse = - // post /logs - withRawResponse().create(params, requestOptions).parse() - - override fun getSummary( - params: LogGetSummaryParams, - requestOptions: RequestOptions, - ): LogGetSummaryResponse = - // post /logs/summary - withRawResponse().getSummary(params, requestOptions).parse() - class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : LogService.WithRawResponse { - private val errorHandler: Handler = - errorHandler(errorBodyHandler(clientOptions.jsonMapper)) - override fun withOptions( modifier: Consumer ): LogService.WithRawResponse = LogServiceImpl.WithRawResponseImpl( clientOptions.toBuilder().apply(modifier::accept).build() ) - - private val createHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - - override fun create( - params: LogCreateParams, - requestOptions: RequestOptions, - ): HttpResponseFor { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .baseUrl(clientOptions.baseUrl()) - .addPathSegments("logs") - .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 { createHandler.handle(it) } - .also { - if (requestOptions.responseValidation!!) { - it.validate() - } - } - } - } - - private val getSummaryHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - - override fun getSummary( - params: LogGetSummaryParams, - requestOptions: RequestOptions, - ): HttpResponseFor { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .baseUrl(clientOptions.baseUrl()) - .addPathSegments("logs", "summary") - .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 { getSummaryHandler.handle(it) } - .also { - if (requestOptions.responseValidation!!) { - it.validate() - } - } - } - } } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/VerifyTokenService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/VerifyTokenService.kt index 6596370..a44e1df 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/VerifyTokenService.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/VerifyTokenService.kt @@ -3,11 +3,6 @@ package com.cas_parser.api.services.blocking import com.cas_parser.api.core.ClientOptions -import com.cas_parser.api.core.RequestOptions -import com.cas_parser.api.core.http.HttpResponseFor -import com.cas_parser.api.models.verifytoken.VerifyTokenVerifyParams -import com.cas_parser.api.models.verifytoken.VerifyTokenVerifyResponse -import com.google.errorprone.annotations.MustBeClosed import java.util.function.Consumer interface VerifyTokenService { @@ -24,24 +19,6 @@ interface VerifyTokenService { */ fun withOptions(modifier: Consumer): VerifyTokenService - /** Verify an access token and check if it's still valid. Useful for debugging token issues. */ - fun verify(): VerifyTokenVerifyResponse = verify(VerifyTokenVerifyParams.none()) - - /** @see verify */ - fun verify( - params: VerifyTokenVerifyParams = VerifyTokenVerifyParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): VerifyTokenVerifyResponse - - /** @see verify */ - fun verify( - params: VerifyTokenVerifyParams = VerifyTokenVerifyParams.none() - ): VerifyTokenVerifyResponse = verify(params, RequestOptions.none()) - - /** @see verify */ - fun verify(requestOptions: RequestOptions): VerifyTokenVerifyResponse = - verify(VerifyTokenVerifyParams.none(), requestOptions) - /** * A view of [VerifyTokenService] that provides access to raw HTTP responses for each method. */ @@ -55,31 +32,5 @@ interface VerifyTokenService { fun withOptions( modifier: Consumer ): VerifyTokenService.WithRawResponse - - /** - * Returns a raw HTTP response for `post /v1/verify-token`, but is otherwise the same as - * [VerifyTokenService.verify]. - */ - @MustBeClosed - fun verify(): HttpResponseFor = - verify(VerifyTokenVerifyParams.none()) - - /** @see verify */ - @MustBeClosed - fun verify( - params: VerifyTokenVerifyParams = VerifyTokenVerifyParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): HttpResponseFor - - /** @see verify */ - @MustBeClosed - fun verify( - params: VerifyTokenVerifyParams = VerifyTokenVerifyParams.none() - ): HttpResponseFor = verify(params, RequestOptions.none()) - - /** @see verify */ - @MustBeClosed - fun verify(requestOptions: RequestOptions): HttpResponseFor = - verify(VerifyTokenVerifyParams.none(), requestOptions) } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/VerifyTokenServiceImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/VerifyTokenServiceImpl.kt index 6780bb3..e202bbc 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/VerifyTokenServiceImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/VerifyTokenServiceImpl.kt @@ -3,20 +3,6 @@ package com.cas_parser.api.services.blocking import com.cas_parser.api.core.ClientOptions -import com.cas_parser.api.core.RequestOptions -import com.cas_parser.api.core.handlers.errorBodyHandler -import com.cas_parser.api.core.handlers.errorHandler -import com.cas_parser.api.core.handlers.jsonHandler -import com.cas_parser.api.core.http.HttpMethod -import com.cas_parser.api.core.http.HttpRequest -import com.cas_parser.api.core.http.HttpResponse -import com.cas_parser.api.core.http.HttpResponse.Handler -import com.cas_parser.api.core.http.HttpResponseFor -import com.cas_parser.api.core.http.json -import com.cas_parser.api.core.http.parseable -import com.cas_parser.api.core.prepare -import com.cas_parser.api.models.verifytoken.VerifyTokenVerifyParams -import com.cas_parser.api.models.verifytoken.VerifyTokenVerifyResponse import java.util.function.Consumer class VerifyTokenServiceImpl internal constructor(private val clientOptions: ClientOptions) : @@ -31,52 +17,14 @@ class VerifyTokenServiceImpl internal constructor(private val clientOptions: Cli override fun withOptions(modifier: Consumer): VerifyTokenService = VerifyTokenServiceImpl(clientOptions.toBuilder().apply(modifier::accept).build()) - override fun verify( - params: VerifyTokenVerifyParams, - requestOptions: RequestOptions, - ): VerifyTokenVerifyResponse = - // post /v1/verify-token - withRawResponse().verify(params, requestOptions).parse() - class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : VerifyTokenService.WithRawResponse { - private val errorHandler: Handler = - errorHandler(errorBodyHandler(clientOptions.jsonMapper)) - override fun withOptions( modifier: Consumer ): VerifyTokenService.WithRawResponse = VerifyTokenServiceImpl.WithRawResponseImpl( clientOptions.toBuilder().apply(modifier::accept).build() ) - - private val verifyHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - - override fun verify( - params: VerifyTokenVerifyParams, - requestOptions: RequestOptions, - ): HttpResponseFor { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .baseUrl(clientOptions.baseUrl()) - .addPathSegments("v1", "verify-token") - .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 { verifyHandler.handle(it) } - .also { - if (requestOptions.responseValidation!!) { - it.validate() - } - } - } - } } } diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateParamsTest.kt deleted file mode 100644 index a6a696b..0000000 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateParamsTest.kt +++ /dev/null @@ -1,30 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.models.accesstoken - -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -internal class AccessTokenCreateParamsTest { - - @Test - fun create() { - AccessTokenCreateParams.builder().expiryMinutes(60L).build() - } - - @Test - fun body() { - val params = AccessTokenCreateParams.builder().expiryMinutes(60L).build() - - val body = params._body() - - assertThat(body.expiryMinutes()).contains(60L) - } - - @Test - fun bodyWithoutOptionalFields() { - val params = AccessTokenCreateParams.builder().build() - - val body = params._body() - } -} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateResponseTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateResponseTest.kt deleted file mode 100644 index 09382b7..0000000 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateResponseTest.kt +++ /dev/null @@ -1,45 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.models.accesstoken - -import com.cas_parser.api.core.jsonMapper -import com.fasterxml.jackson.module.kotlin.jacksonTypeRef -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -internal class AccessTokenCreateResponseTest { - - @Test - fun create() { - val accessTokenCreateResponse = - AccessTokenCreateResponse.builder() - .accessToken("at_eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...") - .expiresIn(3600L) - .tokenType("api_key") - .build() - - assertThat(accessTokenCreateResponse.accessToken()) - .contains("at_eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...") - assertThat(accessTokenCreateResponse.expiresIn()).contains(3600L) - assertThat(accessTokenCreateResponse.tokenType()).contains("api_key") - } - - @Test - fun roundtrip() { - val jsonMapper = jsonMapper() - val accessTokenCreateResponse = - AccessTokenCreateResponse.builder() - .accessToken("at_eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...") - .expiresIn(3600L) - .tokenType("api_key") - .build() - - val roundtrippedAccessTokenCreateResponse = - jsonMapper.readValue( - jsonMapper.writeValueAsString(accessTokenCreateResponse), - jacksonTypeRef(), - ) - - assertThat(roundtrippedAccessTokenCreateResponse).isEqualTo(accessTokenCreateResponse) - } -} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/credits/CreditCheckParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/credits/CreditCheckParamsTest.kt deleted file mode 100644 index b26664b..0000000 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/credits/CreditCheckParamsTest.kt +++ /dev/null @@ -1,13 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.models.credits - -import org.junit.jupiter.api.Test - -internal class CreditCheckParamsTest { - - @Test - fun create() { - CreditCheckParams.builder().build() - } -} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/credits/CreditCheckResponseTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/credits/CreditCheckResponseTest.kt deleted file mode 100644 index 17d52f9..0000000 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/credits/CreditCheckResponseTest.kt +++ /dev/null @@ -1,61 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.models.credits - -import com.cas_parser.api.core.jsonMapper -import com.fasterxml.jackson.module.kotlin.jacksonTypeRef -import java.time.OffsetDateTime -import kotlin.jvm.optionals.getOrNull -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -internal class CreditCheckResponseTest { - - @Test - fun create() { - val creditCheckResponse = - CreditCheckResponse.builder() - .enabledFeatures( - listOf("cams_kfintech_cas_parser", "cdsl_cas_parser", "nsdl_cas_parser") - ) - .isUnlimited(false) - .limit(50L) - .remaining(35.0) - .resetsAt(OffsetDateTime.parse("2026-02-15T00:00:00Z")) - .used(15.0) - .build() - - assertThat(creditCheckResponse.enabledFeatures().getOrNull()) - .containsExactly("cams_kfintech_cas_parser", "cdsl_cas_parser", "nsdl_cas_parser") - assertThat(creditCheckResponse.isUnlimited()).contains(false) - assertThat(creditCheckResponse.limit()).contains(50L) - assertThat(creditCheckResponse.remaining()).contains(35.0) - assertThat(creditCheckResponse.resetsAt()) - .contains(OffsetDateTime.parse("2026-02-15T00:00:00Z")) - assertThat(creditCheckResponse.used()).contains(15.0) - } - - @Test - fun roundtrip() { - val jsonMapper = jsonMapper() - val creditCheckResponse = - CreditCheckResponse.builder() - .enabledFeatures( - listOf("cams_kfintech_cas_parser", "cdsl_cas_parser", "nsdl_cas_parser") - ) - .isUnlimited(false) - .limit(50L) - .remaining(35.0) - .resetsAt(OffsetDateTime.parse("2026-02-15T00:00:00Z")) - .used(15.0) - .build() - - val roundtrippedCreditCheckResponse = - jsonMapper.readValue( - jsonMapper.writeValueAsString(creditCheckResponse), - jacksonTypeRef(), - ) - - assertThat(roundtrippedCreditCheckResponse).isEqualTo(creditCheckResponse) - } -} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogCreateParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogCreateParamsTest.kt deleted file mode 100644 index e7212ba..0000000 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogCreateParamsTest.kt +++ /dev/null @@ -1,42 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.models.logs - -import java.time.OffsetDateTime -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -internal class LogCreateParamsTest { - - @Test - fun create() { - LogCreateParams.builder() - .endTime(OffsetDateTime.parse("2026-01-31T23:59:59Z")) - .limit(1L) - .startTime(OffsetDateTime.parse("2026-01-01T00:00:00Z")) - .build() - } - - @Test - fun body() { - val params = - LogCreateParams.builder() - .endTime(OffsetDateTime.parse("2026-01-31T23:59:59Z")) - .limit(1L) - .startTime(OffsetDateTime.parse("2026-01-01T00:00:00Z")) - .build() - - val body = params._body() - - assertThat(body.endTime()).contains(OffsetDateTime.parse("2026-01-31T23:59:59Z")) - assertThat(body.limit()).contains(1L) - assertThat(body.startTime()).contains(OffsetDateTime.parse("2026-01-01T00:00:00Z")) - } - - @Test - fun bodyWithoutOptionalFields() { - val params = LogCreateParams.builder().build() - - val body = params._body() - } -} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogCreateResponseTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogCreateResponseTest.kt deleted file mode 100644 index 0f24a21..0000000 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogCreateResponseTest.kt +++ /dev/null @@ -1,74 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.models.logs - -import com.cas_parser.api.core.jsonMapper -import com.fasterxml.jackson.module.kotlin.jacksonTypeRef -import java.time.OffsetDateTime -import kotlin.jvm.optionals.getOrNull -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -internal class LogCreateResponseTest { - - @Test - fun create() { - val logCreateResponse = - LogCreateResponse.builder() - .count(25L) - .addLog( - LogCreateResponse.Log.builder() - .credits(1.0) - .feature("cdsl_cas_parser") - .path("/v4/cdsl/parse") - .requestId("req_2xYz7KpL8mN3Ab") - .statusCode(200L) - .timestamp(OffsetDateTime.parse("2026-01-15T14:30:00Z")) - .build() - ) - .status("success") - .build() - - assertThat(logCreateResponse.count()).contains(25L) - assertThat(logCreateResponse.logs().getOrNull()) - .containsExactly( - LogCreateResponse.Log.builder() - .credits(1.0) - .feature("cdsl_cas_parser") - .path("/v4/cdsl/parse") - .requestId("req_2xYz7KpL8mN3Ab") - .statusCode(200L) - .timestamp(OffsetDateTime.parse("2026-01-15T14:30:00Z")) - .build() - ) - assertThat(logCreateResponse.status()).contains("success") - } - - @Test - fun roundtrip() { - val jsonMapper = jsonMapper() - val logCreateResponse = - LogCreateResponse.builder() - .count(25L) - .addLog( - LogCreateResponse.Log.builder() - .credits(1.0) - .feature("cdsl_cas_parser") - .path("/v4/cdsl/parse") - .requestId("req_2xYz7KpL8mN3Ab") - .statusCode(200L) - .timestamp(OffsetDateTime.parse("2026-01-15T14:30:00Z")) - .build() - ) - .status("success") - .build() - - val roundtrippedLogCreateResponse = - jsonMapper.readValue( - jsonMapper.writeValueAsString(logCreateResponse), - jacksonTypeRef(), - ) - - assertThat(roundtrippedLogCreateResponse).isEqualTo(logCreateResponse) - } -} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogGetSummaryParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogGetSummaryParamsTest.kt deleted file mode 100644 index a2cfd4a..0000000 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogGetSummaryParamsTest.kt +++ /dev/null @@ -1,39 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.models.logs - -import java.time.OffsetDateTime -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -internal class LogGetSummaryParamsTest { - - @Test - fun create() { - LogGetSummaryParams.builder() - .endTime(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .startTime(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .build() - } - - @Test - fun body() { - val params = - LogGetSummaryParams.builder() - .endTime(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .startTime(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .build() - - val body = params._body() - - assertThat(body.endTime()).contains(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - assertThat(body.startTime()).contains(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - } - - @Test - fun bodyWithoutOptionalFields() { - val params = LogGetSummaryParams.builder().build() - - val body = params._body() - } -} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogGetSummaryResponseTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogGetSummaryResponseTest.kt deleted file mode 100644 index 94e8bc7..0000000 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogGetSummaryResponseTest.kt +++ /dev/null @@ -1,78 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.models.logs - -import com.cas_parser.api.core.jsonMapper -import com.fasterxml.jackson.module.kotlin.jacksonTypeRef -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -internal class LogGetSummaryResponseTest { - - @Test - fun create() { - val logGetSummaryResponse = - LogGetSummaryResponse.builder() - .status("success") - .summary( - LogGetSummaryResponse.Summary.builder() - .addByFeature( - LogGetSummaryResponse.Summary.ByFeature.builder() - .credits(15.0) - .feature("cdsl_cas_parser") - .requests(15L) - .build() - ) - .totalCredits(45.5) - .totalRequests(42L) - .build() - ) - .build() - - assertThat(logGetSummaryResponse.status()).contains("success") - assertThat(logGetSummaryResponse.summary()) - .contains( - LogGetSummaryResponse.Summary.builder() - .addByFeature( - LogGetSummaryResponse.Summary.ByFeature.builder() - .credits(15.0) - .feature("cdsl_cas_parser") - .requests(15L) - .build() - ) - .totalCredits(45.5) - .totalRequests(42L) - .build() - ) - } - - @Test - fun roundtrip() { - val jsonMapper = jsonMapper() - val logGetSummaryResponse = - LogGetSummaryResponse.builder() - .status("success") - .summary( - LogGetSummaryResponse.Summary.builder() - .addByFeature( - LogGetSummaryResponse.Summary.ByFeature.builder() - .credits(15.0) - .feature("cdsl_cas_parser") - .requests(15L) - .build() - ) - .totalCredits(45.5) - .totalRequests(42L) - .build() - ) - .build() - - val roundtrippedLogGetSummaryResponse = - jsonMapper.readValue( - jsonMapper.writeValueAsString(logGetSummaryResponse), - jacksonTypeRef(), - ) - - assertThat(roundtrippedLogGetSummaryResponse).isEqualTo(logGetSummaryResponse) - } -} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyParamsTest.kt deleted file mode 100644 index 6e75d40..0000000 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyParamsTest.kt +++ /dev/null @@ -1,13 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.models.verifytoken - -import org.junit.jupiter.api.Test - -internal class VerifyTokenVerifyParamsTest { - - @Test - fun create() { - VerifyTokenVerifyParams.builder().build() - } -} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyResponseTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyResponseTest.kt deleted file mode 100644 index 813bc45..0000000 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyResponseTest.kt +++ /dev/null @@ -1,44 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.models.verifytoken - -import com.cas_parser.api.core.jsonMapper -import com.fasterxml.jackson.module.kotlin.jacksonTypeRef -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -internal class VerifyTokenVerifyResponseTest { - - @Test - fun create() { - val verifyTokenVerifyResponse = - VerifyTokenVerifyResponse.builder() - .error("Token has expired") - .maskedApiKey("abc1****ef23") - .valid(true) - .build() - - assertThat(verifyTokenVerifyResponse.error()).contains("Token has expired") - assertThat(verifyTokenVerifyResponse.maskedApiKey()).contains("abc1****ef23") - assertThat(verifyTokenVerifyResponse.valid()).contains(true) - } - - @Test - fun roundtrip() { - val jsonMapper = jsonMapper() - val verifyTokenVerifyResponse = - VerifyTokenVerifyResponse.builder() - .error("Token has expired") - .maskedApiKey("abc1****ef23") - .valid(true) - .build() - - val roundtrippedVerifyTokenVerifyResponse = - jsonMapper.readValue( - jsonMapper.writeValueAsString(verifyTokenVerifyResponse), - jacksonTypeRef(), - ) - - assertThat(roundtrippedVerifyTokenVerifyResponse).isEqualTo(verifyTokenVerifyResponse) - } -} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/ErrorHandlingTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/ErrorHandlingTest.kt index f58190a..0cce742 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/ErrorHandlingTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/ErrorHandlingTest.kt @@ -16,6 +16,7 @@ import com.cas_parser.api.errors.RateLimitException import com.cas_parser.api.errors.UnauthorizedException import com.cas_parser.api.errors.UnexpectedStatusCodeException import com.cas_parser.api.errors.UnprocessableEntityException +import com.cas_parser.api.models.camskfintech.CamsKfintechParseParams import com.github.tomakehurst.wiremock.client.WireMock.anyUrl import com.github.tomakehurst.wiremock.client.WireMock.post import com.github.tomakehurst.wiremock.client.WireMock.status @@ -58,8 +59,8 @@ internal class ErrorHandlingTest { } @Test - fun creditsCheck400() { - val creditService = client.credits() + fun camsKfintechParse400() { + val camsKfintechService = client.camsKfintech() stubFor( post(anyUrl()) .willReturn( @@ -67,7 +68,16 @@ internal class ErrorHandlingTest { ) ) - val e = assertThrows { creditService.check() } + val e = + assertThrows { + camsKfintechService.parse( + CamsKfintechParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + } assertThat(e.statusCode()).isEqualTo(400) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -75,8 +85,8 @@ internal class ErrorHandlingTest { } @Test - fun creditsCheck400WithRawResponse() { - val creditService = client.credits().withRawResponse() + fun camsKfintechParse400WithRawResponse() { + val camsKfintechService = client.camsKfintech().withRawResponse() stubFor( post(anyUrl()) .willReturn( @@ -84,7 +94,16 @@ internal class ErrorHandlingTest { ) ) - val e = assertThrows { creditService.check() } + val e = + assertThrows { + camsKfintechService.parse( + CamsKfintechParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + } assertThat(e.statusCode()).isEqualTo(400) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -92,8 +111,8 @@ internal class ErrorHandlingTest { } @Test - fun creditsCheck401() { - val creditService = client.credits() + fun camsKfintechParse401() { + val camsKfintechService = client.camsKfintech() stubFor( post(anyUrl()) .willReturn( @@ -101,7 +120,16 @@ internal class ErrorHandlingTest { ) ) - val e = assertThrows { creditService.check() } + val e = + assertThrows { + camsKfintechService.parse( + CamsKfintechParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + } assertThat(e.statusCode()).isEqualTo(401) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -109,8 +137,8 @@ internal class ErrorHandlingTest { } @Test - fun creditsCheck401WithRawResponse() { - val creditService = client.credits().withRawResponse() + fun camsKfintechParse401WithRawResponse() { + val camsKfintechService = client.camsKfintech().withRawResponse() stubFor( post(anyUrl()) .willReturn( @@ -118,7 +146,16 @@ internal class ErrorHandlingTest { ) ) - val e = assertThrows { creditService.check() } + val e = + assertThrows { + camsKfintechService.parse( + CamsKfintechParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + } assertThat(e.statusCode()).isEqualTo(401) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -126,8 +163,8 @@ internal class ErrorHandlingTest { } @Test - fun creditsCheck403() { - val creditService = client.credits() + fun camsKfintechParse403() { + val camsKfintechService = client.camsKfintech() stubFor( post(anyUrl()) .willReturn( @@ -135,7 +172,16 @@ internal class ErrorHandlingTest { ) ) - val e = assertThrows { creditService.check() } + val e = + assertThrows { + camsKfintechService.parse( + CamsKfintechParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + } assertThat(e.statusCode()).isEqualTo(403) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -143,8 +189,8 @@ internal class ErrorHandlingTest { } @Test - fun creditsCheck403WithRawResponse() { - val creditService = client.credits().withRawResponse() + fun camsKfintechParse403WithRawResponse() { + val camsKfintechService = client.camsKfintech().withRawResponse() stubFor( post(anyUrl()) .willReturn( @@ -152,7 +198,16 @@ internal class ErrorHandlingTest { ) ) - val e = assertThrows { creditService.check() } + val e = + assertThrows { + camsKfintechService.parse( + CamsKfintechParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + } assertThat(e.statusCode()).isEqualTo(403) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -160,8 +215,8 @@ internal class ErrorHandlingTest { } @Test - fun creditsCheck404() { - val creditService = client.credits() + fun camsKfintechParse404() { + val camsKfintechService = client.camsKfintech() stubFor( post(anyUrl()) .willReturn( @@ -169,7 +224,16 @@ internal class ErrorHandlingTest { ) ) - val e = assertThrows { creditService.check() } + val e = + assertThrows { + camsKfintechService.parse( + CamsKfintechParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + } assertThat(e.statusCode()).isEqualTo(404) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -177,8 +241,8 @@ internal class ErrorHandlingTest { } @Test - fun creditsCheck404WithRawResponse() { - val creditService = client.credits().withRawResponse() + fun camsKfintechParse404WithRawResponse() { + val camsKfintechService = client.camsKfintech().withRawResponse() stubFor( post(anyUrl()) .willReturn( @@ -186,7 +250,16 @@ internal class ErrorHandlingTest { ) ) - val e = assertThrows { creditService.check() } + val e = + assertThrows { + camsKfintechService.parse( + CamsKfintechParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + } assertThat(e.statusCode()).isEqualTo(404) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -194,8 +267,8 @@ internal class ErrorHandlingTest { } @Test - fun creditsCheck422() { - val creditService = client.credits() + fun camsKfintechParse422() { + val camsKfintechService = client.camsKfintech() stubFor( post(anyUrl()) .willReturn( @@ -203,7 +276,16 @@ internal class ErrorHandlingTest { ) ) - val e = assertThrows { creditService.check() } + val e = + assertThrows { + camsKfintechService.parse( + CamsKfintechParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + } assertThat(e.statusCode()).isEqualTo(422) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -211,8 +293,8 @@ internal class ErrorHandlingTest { } @Test - fun creditsCheck422WithRawResponse() { - val creditService = client.credits().withRawResponse() + fun camsKfintechParse422WithRawResponse() { + val camsKfintechService = client.camsKfintech().withRawResponse() stubFor( post(anyUrl()) .willReturn( @@ -220,7 +302,16 @@ internal class ErrorHandlingTest { ) ) - val e = assertThrows { creditService.check() } + val e = + assertThrows { + camsKfintechService.parse( + CamsKfintechParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + } assertThat(e.statusCode()).isEqualTo(422) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -228,8 +319,8 @@ internal class ErrorHandlingTest { } @Test - fun creditsCheck429() { - val creditService = client.credits() + fun camsKfintechParse429() { + val camsKfintechService = client.camsKfintech() stubFor( post(anyUrl()) .willReturn( @@ -237,7 +328,16 @@ internal class ErrorHandlingTest { ) ) - val e = assertThrows { creditService.check() } + val e = + assertThrows { + camsKfintechService.parse( + CamsKfintechParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + } assertThat(e.statusCode()).isEqualTo(429) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -245,8 +345,8 @@ internal class ErrorHandlingTest { } @Test - fun creditsCheck429WithRawResponse() { - val creditService = client.credits().withRawResponse() + fun camsKfintechParse429WithRawResponse() { + val camsKfintechService = client.camsKfintech().withRawResponse() stubFor( post(anyUrl()) .willReturn( @@ -254,7 +354,16 @@ internal class ErrorHandlingTest { ) ) - val e = assertThrows { creditService.check() } + val e = + assertThrows { + camsKfintechService.parse( + CamsKfintechParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + } assertThat(e.statusCode()).isEqualTo(429) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -262,8 +371,8 @@ internal class ErrorHandlingTest { } @Test - fun creditsCheck500() { - val creditService = client.credits() + fun camsKfintechParse500() { + val camsKfintechService = client.camsKfintech() stubFor( post(anyUrl()) .willReturn( @@ -271,7 +380,16 @@ internal class ErrorHandlingTest { ) ) - val e = assertThrows { creditService.check() } + val e = + assertThrows { + camsKfintechService.parse( + CamsKfintechParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + } assertThat(e.statusCode()).isEqualTo(500) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -279,8 +397,8 @@ internal class ErrorHandlingTest { } @Test - fun creditsCheck500WithRawResponse() { - val creditService = client.credits().withRawResponse() + fun camsKfintechParse500WithRawResponse() { + val camsKfintechService = client.camsKfintech().withRawResponse() stubFor( post(anyUrl()) .willReturn( @@ -288,7 +406,16 @@ internal class ErrorHandlingTest { ) ) - val e = assertThrows { creditService.check() } + val e = + assertThrows { + camsKfintechService.parse( + CamsKfintechParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + } assertThat(e.statusCode()).isEqualTo(500) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -296,8 +423,8 @@ internal class ErrorHandlingTest { } @Test - fun creditsCheck999() { - val creditService = client.credits() + fun camsKfintechParse999() { + val camsKfintechService = client.camsKfintech() stubFor( post(anyUrl()) .willReturn( @@ -305,7 +432,16 @@ internal class ErrorHandlingTest { ) ) - val e = assertThrows { creditService.check() } + val e = + assertThrows { + camsKfintechService.parse( + CamsKfintechParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + } assertThat(e.statusCode()).isEqualTo(999) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -313,8 +449,8 @@ internal class ErrorHandlingTest { } @Test - fun creditsCheck999WithRawResponse() { - val creditService = client.credits().withRawResponse() + fun camsKfintechParse999WithRawResponse() { + val camsKfintechService = client.camsKfintech().withRawResponse() stubFor( post(anyUrl()) .willReturn( @@ -322,7 +458,16 @@ internal class ErrorHandlingTest { ) ) - val e = assertThrows { creditService.check() } + val e = + assertThrows { + camsKfintechService.parse( + CamsKfintechParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + } assertThat(e.statusCode()).isEqualTo(999) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -330,14 +475,23 @@ internal class ErrorHandlingTest { } @Test - fun creditsCheckInvalidJsonBody() { - val creditService = client.credits() + fun camsKfintechParseInvalidJsonBody() { + val camsKfintechService = client.camsKfintech() stubFor( post(anyUrl()) .willReturn(status(200).withHeader(HEADER_NAME, HEADER_VALUE).withBody(NOT_JSON)) ) - val e = assertThrows { creditService.check() } + val e = + assertThrows { + camsKfintechService.parse( + CamsKfintechParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") + .build() + ) + } assertThat(e).hasMessage("Error reading response") } diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/ServiceParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/ServiceParamsTest.kt index 4cdd376..be4ed15 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/ServiceParamsTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/ServiceParamsTest.kt @@ -5,7 +5,7 @@ package com.cas_parser.api.services import com.cas_parser.api.client.CasParserClient import com.cas_parser.api.client.okhttp.CasParserOkHttpClient import com.cas_parser.api.core.JsonValue -import com.cas_parser.api.models.credits.CreditCheckParams +import com.cas_parser.api.models.camskfintech.CamsKfintechParseParams import com.github.tomakehurst.wiremock.client.WireMock.anyUrl import com.github.tomakehurst.wiremock.client.WireMock.equalTo import com.github.tomakehurst.wiremock.client.WireMock.matchingJsonPath @@ -38,12 +38,15 @@ internal class ServiceParamsTest { @Disabled("Mock server tests are disabled") @Test - fun check() { - val creditService = client.credits() + fun parse() { + val camsKfintechService = client.camsKfintech() stubFor(post(anyUrl()).willReturn(ok("{}"))) - creditService.check( - CreditCheckParams.builder() + camsKfintechService.parse( + CamsKfintechParseParams.builder() + .password("password") + .pdfFile("pdf_file") + .pdfUrl("https://example.com") .putAdditionalHeader("Secret-Header", "42") .putAdditionalQueryParam("secret_query_param", "42") .putAdditionalBodyProperty("secretProperty", JsonValue.from("42")) diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsyncTest.kt deleted file mode 100644 index c795a5c..0000000 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsyncTest.kt +++ /dev/null @@ -1,26 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.services.async - -import com.cas_parser.api.client.okhttp.CasParserOkHttpClientAsync -import com.cas_parser.api.models.accesstoken.AccessTokenCreateParams -import org.junit.jupiter.api.Disabled -import org.junit.jupiter.api.Test - -internal class AccessTokenServiceAsyncTest { - - @Disabled("Mock server tests are disabled") - @Test - fun create() { - val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() - val accessTokenServiceAsync = client.accessToken() - - val accessTokenFuture = - accessTokenServiceAsync.create( - AccessTokenCreateParams.builder().expiryMinutes(60L).build() - ) - - val accessToken = accessTokenFuture.get() - accessToken.validate() - } -} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CreditServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CreditServiceAsyncTest.kt deleted file mode 100644 index 6c9e4d8..0000000 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CreditServiceAsyncTest.kt +++ /dev/null @@ -1,22 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.services.async - -import com.cas_parser.api.client.okhttp.CasParserOkHttpClientAsync -import org.junit.jupiter.api.Disabled -import org.junit.jupiter.api.Test - -internal class CreditServiceAsyncTest { - - @Disabled("Mock server tests are disabled") - @Test - fun check() { - val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() - val creditServiceAsync = client.credits() - - val responseFuture = creditServiceAsync.check() - - val response = responseFuture.get() - response.validate() - } -} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/LogServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/LogServiceAsyncTest.kt deleted file mode 100644 index 532be8d..0000000 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/LogServiceAsyncTest.kt +++ /dev/null @@ -1,50 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.services.async - -import com.cas_parser.api.client.okhttp.CasParserOkHttpClientAsync -import com.cas_parser.api.models.logs.LogCreateParams -import com.cas_parser.api.models.logs.LogGetSummaryParams -import java.time.OffsetDateTime -import org.junit.jupiter.api.Disabled -import org.junit.jupiter.api.Test - -internal class LogServiceAsyncTest { - - @Disabled("Mock server tests are disabled") - @Test - fun create() { - val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() - val logServiceAsync = client.logs() - - val logFuture = - logServiceAsync.create( - LogCreateParams.builder() - .endTime(OffsetDateTime.parse("2026-01-31T23:59:59Z")) - .limit(1L) - .startTime(OffsetDateTime.parse("2026-01-01T00:00:00Z")) - .build() - ) - - val log = logFuture.get() - log.validate() - } - - @Disabled("Mock server tests are disabled") - @Test - fun getSummary() { - val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() - val logServiceAsync = client.logs() - - val responseFuture = - logServiceAsync.getSummary( - LogGetSummaryParams.builder() - .endTime(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .startTime(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .build() - ) - - val response = responseFuture.get() - response.validate() - } -} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsyncTest.kt deleted file mode 100644 index 3d7800c..0000000 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsyncTest.kt +++ /dev/null @@ -1,22 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.services.async - -import com.cas_parser.api.client.okhttp.CasParserOkHttpClientAsync -import org.junit.jupiter.api.Disabled -import org.junit.jupiter.api.Test - -internal class VerifyTokenServiceAsyncTest { - - @Disabled("Mock server tests are disabled") - @Test - fun verify() { - val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() - val verifyTokenServiceAsync = client.verifyToken() - - val responseFuture = verifyTokenServiceAsync.verify() - - val response = responseFuture.get() - response.validate() - } -} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/AccessTokenServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/AccessTokenServiceTest.kt deleted file mode 100644 index f7c9696..0000000 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/AccessTokenServiceTest.kt +++ /dev/null @@ -1,23 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.services.blocking - -import com.cas_parser.api.client.okhttp.CasParserOkHttpClient -import com.cas_parser.api.models.accesstoken.AccessTokenCreateParams -import org.junit.jupiter.api.Disabled -import org.junit.jupiter.api.Test - -internal class AccessTokenServiceTest { - - @Disabled("Mock server tests are disabled") - @Test - fun create() { - val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() - val accessTokenService = client.accessToken() - - val accessToken = - accessTokenService.create(AccessTokenCreateParams.builder().expiryMinutes(60L).build()) - - accessToken.validate() - } -} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CreditServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CreditServiceTest.kt deleted file mode 100644 index 94239a3..0000000 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CreditServiceTest.kt +++ /dev/null @@ -1,21 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.services.blocking - -import com.cas_parser.api.client.okhttp.CasParserOkHttpClient -import org.junit.jupiter.api.Disabled -import org.junit.jupiter.api.Test - -internal class CreditServiceTest { - - @Disabled("Mock server tests are disabled") - @Test - fun check() { - val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() - val creditService = client.credits() - - val response = creditService.check() - - response.validate() - } -} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/LogServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/LogServiceTest.kt deleted file mode 100644 index 2ef5c48..0000000 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/LogServiceTest.kt +++ /dev/null @@ -1,48 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.services.blocking - -import com.cas_parser.api.client.okhttp.CasParserOkHttpClient -import com.cas_parser.api.models.logs.LogCreateParams -import com.cas_parser.api.models.logs.LogGetSummaryParams -import java.time.OffsetDateTime -import org.junit.jupiter.api.Disabled -import org.junit.jupiter.api.Test - -internal class LogServiceTest { - - @Disabled("Mock server tests are disabled") - @Test - fun create() { - val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() - val logService = client.logs() - - val log = - logService.create( - LogCreateParams.builder() - .endTime(OffsetDateTime.parse("2026-01-31T23:59:59Z")) - .limit(1L) - .startTime(OffsetDateTime.parse("2026-01-01T00:00:00Z")) - .build() - ) - - log.validate() - } - - @Disabled("Mock server tests are disabled") - @Test - fun getSummary() { - val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() - val logService = client.logs() - - val response = - logService.getSummary( - LogGetSummaryParams.builder() - .endTime(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .startTime(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .build() - ) - - response.validate() - } -} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/VerifyTokenServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/VerifyTokenServiceTest.kt deleted file mode 100644 index 19af27d..0000000 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/VerifyTokenServiceTest.kt +++ /dev/null @@ -1,21 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.cas_parser.api.services.blocking - -import com.cas_parser.api.client.okhttp.CasParserOkHttpClient -import org.junit.jupiter.api.Disabled -import org.junit.jupiter.api.Test - -internal class VerifyTokenServiceTest { - - @Disabled("Mock server tests are disabled") - @Test - fun verify() { - val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() - val verifyTokenService = client.verifyToken() - - val response = verifyTokenService.verify() - - response.validate() - } -} diff --git a/cas-parser-java-proguard-test/src/test/kotlin/com/cas_parser/api/proguard/ProGuardCompatibilityTest.kt b/cas-parser-java-proguard-test/src/test/kotlin/com/cas_parser/api/proguard/ProGuardCompatibilityTest.kt index bdbc9b7..8592efc 100644 --- a/cas-parser-java-proguard-test/src/test/kotlin/com/cas_parser/api/proguard/ProGuardCompatibilityTest.kt +++ b/cas-parser-java-proguard-test/src/test/kotlin/com/cas_parser/api/proguard/ProGuardCompatibilityTest.kt @@ -4,9 +4,8 @@ package com.cas_parser.api.proguard import com.cas_parser.api.client.okhttp.CasParserOkHttpClient import com.cas_parser.api.core.jsonMapper -import com.cas_parser.api.models.credits.CreditCheckResponse +import com.cas_parser.api.models.camskfintech.LinkedHolder import com.fasterxml.jackson.module.kotlin.jacksonTypeRef -import java.time.OffsetDateTime import kotlin.reflect.full.memberFunctions import kotlin.reflect.jvm.javaMethod import org.assertj.core.api.Assertions.assertThat @@ -62,26 +61,16 @@ internal class ProGuardCompatibilityTest { } @Test - fun creditCheckResponseRoundtrip() { + fun linkedHolderRoundtrip() { val jsonMapper = jsonMapper() - val creditCheckResponse = - CreditCheckResponse.builder() - .enabledFeatures( - listOf("cams_kfintech_cas_parser", "cdsl_cas_parser", "nsdl_cas_parser") - ) - .isUnlimited(false) - .limit(50L) - .remaining(35.0) - .resetsAt(OffsetDateTime.parse("2026-02-15T00:00:00Z")) - .used(15.0) - .build() + val linkedHolder = LinkedHolder.builder().name("name").pan("pan").build() - val roundtrippedCreditCheckResponse = + val roundtrippedLinkedHolder = jsonMapper.readValue( - jsonMapper.writeValueAsString(creditCheckResponse), - jacksonTypeRef(), + jsonMapper.writeValueAsString(linkedHolder), + jacksonTypeRef(), ) - assertThat(roundtrippedCreditCheckResponse).isEqualTo(creditCheckResponse) + assertThat(roundtrippedLinkedHolder).isEqualTo(linkedHolder) } } From 89daf7d0f4221d4936fa6a339c3b4fe12d808918 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sun, 22 Feb 2026 23:17:51 +0000 Subject: [PATCH 56/99] feat(api): api update --- .stats.yml | 4 +- .../models/inbox/InboxListCasFilesResponse.kt | 45 ++++++++++++++++++- .../inbox/InboxListCasFilesResponseTest.kt | 3 ++ 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/.stats.yml b/.stats.yml index 80a6900..1e5b8d1 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 12 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-6a9d3b677dcfb856dc571865c34b3fe401e4d7f0d799edfc743acb9a55800bd0.yml -openapi_spec_hash: 037703a6c741e4310fda3f57c22fa51e +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-e6762e83ef7cdff129d03d0ab8c130db2fb5d1d820142847c27d72b40a0e9f53.yml +openapi_spec_hash: f38fb40a2b28bae4b0c9c4228c1c0e0d config_hash: 41c337f5cda03b13880617490f82bad0 diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesResponse.kt index 84d490e..e2c0cc3 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesResponse.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesResponse.kt @@ -232,6 +232,7 @@ private constructor( private val messageDate: JsonField, private val messageId: JsonField, private val originalFilename: JsonField, + private val senderEmail: JsonField, private val size: JsonField, private val url: JsonField, private val additionalProperties: MutableMap, @@ -257,6 +258,9 @@ private constructor( @JsonProperty("original_filename") @ExcludeMissing originalFilename: JsonField = JsonMissing.of(), + @JsonProperty("sender_email") + @ExcludeMissing + senderEmail: JsonField = JsonMissing.of(), @JsonProperty("size") @ExcludeMissing size: JsonField = JsonMissing.of(), @JsonProperty("url") @ExcludeMissing url: JsonField = JsonMissing.of(), ) : this( @@ -266,6 +270,7 @@ private constructor( messageDate, messageId, originalFilename, + senderEmail, size, url, mutableMapOf(), @@ -319,6 +324,14 @@ private constructor( */ fun originalFilename(): Optional = originalFilename.getOptional("original_filename") + /** + * Email address of the CAS authority who sent this + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun senderEmail(): Optional = senderEmail.getOptional("sender_email") + /** * File size in bytes * @@ -382,6 +395,15 @@ private constructor( @ExcludeMissing fun _originalFilename(): JsonField = originalFilename + /** + * Returns the raw JSON value of [senderEmail]. + * + * Unlike [senderEmail], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("sender_email") + @ExcludeMissing + fun _senderEmail(): JsonField = senderEmail + /** * Returns the raw JSON value of [size]. * @@ -423,6 +445,7 @@ private constructor( private var messageDate: JsonField = JsonMissing.of() private var messageId: JsonField = JsonMissing.of() private var originalFilename: JsonField = JsonMissing.of() + private var senderEmail: JsonField = JsonMissing.of() private var size: JsonField = JsonMissing.of() private var url: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @@ -435,6 +458,7 @@ private constructor( messageDate = file.messageDate messageId = file.messageId originalFilename = file.originalFilename + senderEmail = file.senderEmail size = file.size url = file.url additionalProperties = file.additionalProperties.toMutableMap() @@ -517,6 +541,20 @@ private constructor( this.originalFilename = originalFilename } + /** Email address of the CAS authority who sent this */ + fun senderEmail(senderEmail: String) = senderEmail(JsonField.of(senderEmail)) + + /** + * Sets [Builder.senderEmail] to an arbitrary JSON value. + * + * You should usually call [Builder.senderEmail] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun senderEmail(senderEmail: JsonField) = apply { + this.senderEmail = senderEmail + } + /** File size in bytes */ fun size(size: Long) = size(JsonField.of(size)) @@ -573,6 +611,7 @@ private constructor( messageDate, messageId, originalFilename, + senderEmail, size, url, additionalProperties.toMutableMap(), @@ -592,6 +631,7 @@ private constructor( messageDate() messageId() originalFilename() + senderEmail() size() url() validated = true @@ -619,6 +659,7 @@ private constructor( (if (messageDate.asKnown().isPresent) 1 else 0) + (if (messageId.asKnown().isPresent) 1 else 0) + (if (originalFilename.asKnown().isPresent) 1 else 0) + + (if (senderEmail.asKnown().isPresent) 1 else 0) + (if (size.asKnown().isPresent) 1 else 0) + (if (url.asKnown().isPresent) 1 else 0) @@ -777,6 +818,7 @@ private constructor( messageDate == other.messageDate && messageId == other.messageId && originalFilename == other.originalFilename && + senderEmail == other.senderEmail && size == other.size && url == other.url && additionalProperties == other.additionalProperties @@ -790,6 +832,7 @@ private constructor( messageDate, messageId, originalFilename, + senderEmail, size, url, additionalProperties, @@ -799,7 +842,7 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "File{casType=$casType, expiresIn=$expiresIn, filename=$filename, messageDate=$messageDate, messageId=$messageId, originalFilename=$originalFilename, size=$size, url=$url, additionalProperties=$additionalProperties}" + "File{casType=$casType, expiresIn=$expiresIn, filename=$filename, messageDate=$messageDate, messageId=$messageId, originalFilename=$originalFilename, senderEmail=$senderEmail, size=$size, url=$url, additionalProperties=$additionalProperties}" } override fun equals(other: Any?): Boolean { diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesResponseTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesResponseTest.kt index 1f710cb..a491c06 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesResponseTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesResponseTest.kt @@ -24,6 +24,7 @@ internal class InboxListCasFilesResponseTest { .messageDate(LocalDate.parse("2025-01-15")) .messageId("18d4a2b3c4d5e6f7") .originalFilename("CDSL_CAS_Statement.pdf") + .senderEmail("eCAS@cdslstatement.com") .size(245000L) .url( "https://cdn.casparser.in/email-cas/user123/cdsl_20250115_a1b2c3d4.pdf" @@ -43,6 +44,7 @@ internal class InboxListCasFilesResponseTest { .messageDate(LocalDate.parse("2025-01-15")) .messageId("18d4a2b3c4d5e6f7") .originalFilename("CDSL_CAS_Statement.pdf") + .senderEmail("eCAS@cdslstatement.com") .size(245000L) .url("https://cdn.casparser.in/email-cas/user123/cdsl_20250115_a1b2c3d4.pdf") .build() @@ -64,6 +66,7 @@ internal class InboxListCasFilesResponseTest { .messageDate(LocalDate.parse("2025-01-15")) .messageId("18d4a2b3c4d5e6f7") .originalFilename("CDSL_CAS_Statement.pdf") + .senderEmail("eCAS@cdslstatement.com") .size(245000L) .url( "https://cdn.casparser.in/email-cas/user123/cdsl_20250115_a1b2c3d4.pdf" From e7b585edb6e57e637ecd29d6df2f360610ad3740 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 23 Feb 2026 00:17:41 +0000 Subject: [PATCH 57/99] feat(api): api update --- .stats.yml | 4 ++-- .../api/models/inbox/InboxListCasFilesResponse.kt | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.stats.yml b/.stats.yml index 1e5b8d1..b880d0c 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 12 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-e6762e83ef7cdff129d03d0ab8c130db2fb5d1d820142847c27d72b40a0e9f53.yml -openapi_spec_hash: f38fb40a2b28bae4b0c9c4228c1c0e0d +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-d9763d006969b49a1473851069fdfa429eb13133b64103a62963bb70ddb22305.yml +openapi_spec_hash: 6aee689b7a759b12c85c088c15e29bc0 config_hash: 41c337f5cda03b13880617490f82bad0 diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesResponse.kt index e2c0cc3..1373c71 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesResponse.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesResponse.kt @@ -325,7 +325,8 @@ private constructor( fun originalFilename(): Optional = originalFilename.getOptional("original_filename") /** - * Email address of the CAS authority who sent this + * Email address of the CAS authority (CDSL, NSDL, CAMS, or KFintech) who originally sent + * this statement * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if * the server responded with an unexpected value). @@ -541,7 +542,10 @@ private constructor( this.originalFilename = originalFilename } - /** Email address of the CAS authority who sent this */ + /** + * Email address of the CAS authority (CDSL, NSDL, CAMS, or KFintech) who originally + * sent this statement + */ fun senderEmail(senderEmail: String) = senderEmail(JsonField.of(senderEmail)) /** From bc9e123796a11d9c250d6afe0e09ed048c536a99 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 23 Feb 2026 02:53:14 +0000 Subject: [PATCH 58/99] feat(api): manual updates --- .stats.yml | 4 +- README.md | 70 +- .../cas_parser/api/client/CasParserClient.kt | 5 + .../api/client/CasParserClientAsync.kt | 5 + .../api/client/CasParserClientAsyncImpl.kt | 14 + .../api/client/CasParserClientImpl.kt | 14 + .../accesstoken/AccessTokenCreateParams.kt | 412 ++++++ .../accesstoken/AccessTokenCreateResponse.kt | 239 ++++ .../api/models/credits/CreditCheckParams.kt | 219 +++ .../api/models/credits/CreditCheckResponse.kt | 387 ++++++ .../inboundemail/InboundEmailCreateParams.kt | 1061 +++++++++++++++ .../InboundEmailCreateResponse.kt | 884 ++++++++++++ .../inboundemail/InboundEmailDeleteParams.kt | 241 ++++ .../InboundEmailDeleteResponse.kt | 186 +++ .../inboundemail/InboundEmailListParams.kt | 381 ++++++ .../inboundemail/InboundEmailListResponse.kt | 1194 +++++++++++++++++ .../InboundEmailRetrieveParams.kt | 197 +++ .../InboundEmailRetrieveResponse.kt | 884 ++++++++++++ .../api/models/logs/LogCreateParams.kt | 530 ++++++++ .../api/models/logs/LogCreateResponse.kt | 578 ++++++++ .../api/models/logs/LogGetSummaryParams.kt | 470 +++++++ .../api/models/logs/LogGetSummaryResponse.kt | 663 +++++++++ .../verifytoken/VerifyTokenVerifyParams.kt | 211 +++ .../verifytoken/VerifyTokenVerifyResponse.kt | 240 ++++ .../services/async/AccessTokenServiceAsync.kt | 62 + .../async/AccessTokenServiceAsyncImpl.kt | 56 + .../api/services/async/CreditServiceAsync.kt | 57 + .../services/async/CreditServiceAsyncImpl.kt | 56 + .../async/InboundEmailServiceAsync.kt | 300 +++++ .../async/InboundEmailServiceAsyncImpl.kt | 212 +++ .../api/services/async/LogServiceAsync.kt | 107 ++ .../api/services/async/LogServiceAsyncImpl.kt | 96 ++ .../services/async/VerifyTokenServiceAsync.kt | 49 + .../async/VerifyTokenServiceAsyncImpl.kt | 56 + .../services/blocking/AccessTokenService.kt | 62 + .../blocking/AccessTokenServiceImpl.kt | 52 + .../api/services/blocking/CreditService.kt | 56 + .../services/blocking/CreditServiceImpl.kt | 52 + .../services/blocking/InboundEmailService.kt | 298 ++++ .../blocking/InboundEmailServiceImpl.kt | 199 +++ .../api/services/blocking/LogService.kt | 106 ++ .../api/services/blocking/LogServiceImpl.kt | 89 ++ .../services/blocking/VerifyTokenService.kt | 49 + .../blocking/VerifyTokenServiceImpl.kt | 52 + .../AccessTokenCreateParamsTest.kt | 30 + .../AccessTokenCreateResponseTest.kt | 45 + .../models/credits/CreditCheckParamsTest.kt | 13 + .../models/credits/CreditCheckResponseTest.kt | 61 + .../InboundEmailCreateParamsTest.kt | 76 ++ .../InboundEmailCreateResponseTest.kt | 89 ++ .../InboundEmailDeleteParamsTest.kt | 23 + .../InboundEmailDeleteResponseTest.kt | 41 + .../InboundEmailListParamsTest.kt | 49 + .../InboundEmailListResponseTest.kt | 105 ++ .../InboundEmailRetrieveParamsTest.kt | 23 + .../InboundEmailRetrieveResponseTest.kt | 89 ++ .../api/models/logs/LogCreateParamsTest.kt | 42 + .../api/models/logs/LogCreateResponseTest.kt | 74 + .../models/logs/LogGetSummaryParamsTest.kt | 39 + .../models/logs/LogGetSummaryResponseTest.kt | 78 ++ .../VerifyTokenVerifyParamsTest.kt | 13 + .../VerifyTokenVerifyResponseTest.kt | 44 + .../api/services/ErrorHandlingTest.kt | 256 +--- .../api/services/ServiceParamsTest.kt | 13 +- .../async/AccessTokenServiceAsyncTest.kt | 26 + .../services/async/CreditServiceAsyncTest.kt | 22 + .../async/InboundEmailServiceAsyncTest.kt | 83 ++ .../api/services/async/LogServiceAsyncTest.kt | 50 + .../async/VerifyTokenServiceAsyncTest.kt | 22 + .../blocking/AccessTokenServiceTest.kt | 23 + .../services/blocking/CreditServiceTest.kt | 21 + .../blocking/InboundEmailServiceTest.kt | 79 ++ .../api/services/blocking/LogServiceTest.kt | 48 + .../blocking/VerifyTokenServiceTest.kt | 21 + .../api/proguard/ProGuardCompatibilityTest.kt | 26 +- 75 files changed, 12522 insertions(+), 257 deletions(-) create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateParams.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateResponse.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/credits/CreditCheckParams.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/credits/CreditCheckResponse.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateParams.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateResponse.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailDeleteParams.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailDeleteResponse.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailListParams.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailListResponse.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailRetrieveParams.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailRetrieveResponse.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogCreateParams.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogCreateResponse.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogGetSummaryParams.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogGetSummaryResponse.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyParams.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyResponse.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/InboundEmailServiceAsync.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/InboundEmailServiceAsyncImpl.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/InboundEmailService.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/InboundEmailServiceImpl.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateParamsTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateResponseTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/credits/CreditCheckParamsTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/credits/CreditCheckResponseTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateParamsTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateResponseTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailDeleteParamsTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailDeleteResponseTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailListParamsTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailListResponseTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailRetrieveParamsTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailRetrieveResponseTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogCreateParamsTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogCreateResponseTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogGetSummaryParamsTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogGetSummaryResponseTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyParamsTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyResponseTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsyncTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CreditServiceAsyncTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/InboundEmailServiceAsyncTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/LogServiceAsyncTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsyncTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/AccessTokenServiceTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CreditServiceTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/InboundEmailServiceTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/LogServiceTest.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/VerifyTokenServiceTest.kt diff --git a/.stats.yml b/.stats.yml index b880d0c..cdf3c0a 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 12 +configured_endpoints: 21 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-d9763d006969b49a1473851069fdfa429eb13133b64103a62963bb70ddb22305.yml openapi_spec_hash: 6aee689b7a759b12c85c088c15e29bc0 -config_hash: 41c337f5cda03b13880617490f82bad0 +config_hash: d54f39abb185904495bef7c5f8702746 diff --git a/README.md b/README.md index 50e5c0c..212151b 100644 --- a/README.md +++ b/README.md @@ -57,14 +57,14 @@ This library requires Java 8 or later. ```java import com.cas_parser.api.client.CasParserClient; import com.cas_parser.api.client.okhttp.CasParserOkHttpClient; -import com.cas_parser.api.models.camskfintech.CamsKfintechParseParams; -import com.cas_parser.api.models.camskfintech.UnifiedResponse; +import com.cas_parser.api.models.credits.CreditCheckParams; +import com.cas_parser.api.models.credits.CreditCheckResponse; // Configures using the `casparser.apiKey` and `casparser.baseUrl` system properties // Or configures using the `CAS_PARSER_API_KEY` and `CAS_PARSER_BASE_URL` environment variables CasParserClient client = CasParserOkHttpClient.fromEnv(); -UnifiedResponse unifiedResponse = client.camsKfintech().parse(); +CreditCheckResponse response = client.credits().check(); ``` ## Client configuration @@ -137,7 +137,7 @@ The `withOptions()` method does not affect the original client or service. To send a request to the Cas Parser API, build an instance of some `Params` class and pass it to the corresponding client method. When the response is received, it will be deserialized into an instance of a Java class. -For example, `client.camsKfintech().parse(...)` should be called with an instance of `CamsKfintechParseParams`, and it will return an instance of `UnifiedResponse`. +For example, `client.credits().check(...)` should be called with an instance of `CreditCheckParams`, and it will return an instance of `CreditCheckResponse`. ## Immutability @@ -154,15 +154,15 @@ The default client is synchronous. To switch to asynchronous execution, call the ```java import com.cas_parser.api.client.CasParserClient; import com.cas_parser.api.client.okhttp.CasParserOkHttpClient; -import com.cas_parser.api.models.camskfintech.CamsKfintechParseParams; -import com.cas_parser.api.models.camskfintech.UnifiedResponse; +import com.cas_parser.api.models.credits.CreditCheckParams; +import com.cas_parser.api.models.credits.CreditCheckResponse; import java.util.concurrent.CompletableFuture; // Configures using the `casparser.apiKey` and `casparser.baseUrl` system properties // Or configures using the `CAS_PARSER_API_KEY` and `CAS_PARSER_BASE_URL` environment variables CasParserClient client = CasParserOkHttpClient.fromEnv(); -CompletableFuture unifiedResponse = client.async().camsKfintech().parse(); +CompletableFuture response = client.async().credits().check(); ``` Or create an asynchronous client from the beginning: @@ -170,15 +170,15 @@ Or create an asynchronous client from the beginning: ```java import com.cas_parser.api.client.CasParserClientAsync; import com.cas_parser.api.client.okhttp.CasParserOkHttpClientAsync; -import com.cas_parser.api.models.camskfintech.CamsKfintechParseParams; -import com.cas_parser.api.models.camskfintech.UnifiedResponse; +import com.cas_parser.api.models.credits.CreditCheckParams; +import com.cas_parser.api.models.credits.CreditCheckResponse; import java.util.concurrent.CompletableFuture; // Configures using the `casparser.apiKey` and `casparser.baseUrl` system properties // Or configures using the `CAS_PARSER_API_KEY` and `CAS_PARSER_BASE_URL` environment variables CasParserClientAsync client = CasParserOkHttpClientAsync.fromEnv(); -CompletableFuture unifiedResponse = client.camsKfintech().parse(); +CompletableFuture response = client.credits().check(); ``` The asynchronous client supports the same options as the synchronous one, except most methods return `CompletableFuture`s. @@ -192,21 +192,21 @@ To access this data, prefix any HTTP method call on a client or service with `wi ```java import com.cas_parser.api.core.http.Headers; import com.cas_parser.api.core.http.HttpResponseFor; -import com.cas_parser.api.models.camskfintech.CamsKfintechParseParams; -import com.cas_parser.api.models.camskfintech.UnifiedResponse; +import com.cas_parser.api.models.credits.CreditCheckParams; +import com.cas_parser.api.models.credits.CreditCheckResponse; -HttpResponseFor unifiedResponse = client.camsKfintech().withRawResponse().parse(); +HttpResponseFor response = client.credits().withRawResponse().check(); -int statusCode = unifiedResponse.statusCode(); -Headers headers = unifiedResponse.headers(); +int statusCode = response.statusCode(); +Headers headers = response.headers(); ``` You can still deserialize the response into an instance of a Java class if needed: ```java -import com.cas_parser.api.models.camskfintech.UnifiedResponse; +import com.cas_parser.api.models.credits.CreditCheckResponse; -UnifiedResponse parsedUnifiedResponse = unifiedResponse.parse(); +CreditCheckResponse parsedResponse = response.parse(); ``` ## Error handling @@ -304,9 +304,9 @@ Requests time out after 1 minute by default. To set a custom timeout, configure the method call using the `timeout` method: ```java -import com.cas_parser.api.models.camskfintech.UnifiedResponse; +import com.cas_parser.api.models.credits.CreditCheckResponse; -UnifiedResponse unifiedResponse = client.camsKfintech().parse(RequestOptions.builder().timeout(Duration.ofSeconds(30)).build()); +CreditCheckResponse response = client.credits().check(RequestOptions.builder().timeout(Duration.ofSeconds(30)).build()); ``` Or configure the default for all method calls at the client level: @@ -443,9 +443,9 @@ To set undocumented parameters, call the `putAdditionalHeader`, `putAdditionalQu ```java import com.cas_parser.api.core.JsonValue; -import com.cas_parser.api.models.camskfintech.CamsKfintechParseParams; +import com.cas_parser.api.models.credits.CreditCheckParams; -CamsKfintechParseParams params = CamsKfintechParseParams.builder() +CreditCheckParams params = CreditCheckParams.builder() .putAdditionalHeader("Secret-Header", "42") .putAdditionalQueryParam("secret_query_param", "42") .putAdditionalBodyProperty("secretProperty", JsonValue.from("42")) @@ -457,9 +457,9 @@ These can be accessed on the built object later using the `_additionalHeaders()` To set a documented parameter or property to an undocumented or not yet supported _value_, pass a [`JsonValue`](cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Values.kt) object to its setter: ```java -import com.cas_parser.api.models.camskfintech.CamsKfintechParseParams; +import com.cas_parser.api.models.credits.CreditCheckParams; -CamsKfintechParseParams params = CamsKfintechParseParams.builder().build(); +CreditCheckParams params = CreditCheckParams.builder().build(); ``` The most straightforward way to create a [`JsonValue`](cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Values.kt) is using its `from(...)` method: @@ -507,10 +507,10 @@ To forcibly omit a required parameter or property, pass [`JsonMissing`](cas-pars ```java import com.cas_parser.api.core.JsonMissing; -import com.cas_parser.api.models.camskfintech.CamsKfintechParseParams; import com.cas_parser.api.models.cdsl.fetch.FetchRequestOtpParams; +import com.cas_parser.api.models.credits.CreditCheckParams; -CamsKfintechParseParams params = FetchRequestOtpParams.builder() +CreditCheckParams params = FetchRequestOtpParams.builder() .dob("1990-01-15") .pan("ABCDE1234F") .boId(JsonMissing.of()) @@ -525,7 +525,7 @@ To access undocumented response properties, call the `_additionalProperties()` m import com.cas_parser.api.core.JsonValue; import java.util.Map; -Map additionalProperties = client.camsKfintech().parse(params)._additionalProperties(); +Map additionalProperties = client.credits().check(params)._additionalProperties(); JsonValue secretPropertyValue = additionalProperties.get("secretProperty"); String result = secretPropertyValue.accept(new JsonValue.Visitor<>() { @@ -555,19 +555,19 @@ To access a property's raw JSON value, which may be undocumented, call its `_` p import com.cas_parser.api.core.JsonField; import java.util.Optional; -JsonField password = client.camsKfintech().parse(params)._password(); +JsonField field = client.credits().check(params)._field(); -if (password.isMissing()) { +if (field.isMissing()) { // The property is absent from the JSON response -} else if (password.isNull()) { +} else if (field.isNull()) { // The property was set to literal null } else { // Check if value was provided as a string // Other methods include `asNumber()`, `asBoolean()`, etc. - Optional jsonString = password.asString(); + Optional jsonString = field.asString(); // Try to deserialize into a custom type - MyClass myObject = password.asUnknown().orElseThrow().convert(MyClass.class); + MyClass myObject = field.asUnknown().orElseThrow().convert(MyClass.class); } ``` @@ -580,17 +580,17 @@ By default, the SDK will not throw an exception in this case. It will throw [`Ca If you would prefer to check that the response is completely well-typed upfront, then either call `validate()`: ```java -import com.cas_parser.api.models.camskfintech.UnifiedResponse; +import com.cas_parser.api.models.credits.CreditCheckResponse; -UnifiedResponse unifiedResponse = client.camsKfintech().parse(params).validate(); +CreditCheckResponse response = client.credits().check(params).validate(); ``` Or configure the method call to validate the response using the `responseValidation` method: ```java -import com.cas_parser.api.models.camskfintech.UnifiedResponse; +import com.cas_parser.api.models.credits.CreditCheckResponse; -UnifiedResponse unifiedResponse = client.camsKfintech().parse(RequestOptions.builder().responseValidation(true).build()); +CreditCheckResponse response = client.credits().check(RequestOptions.builder().responseValidation(true).build()); ``` Or configure the default for all method calls at the client level: diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClient.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClient.kt index 87a671b..df928cf 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClient.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClient.kt @@ -8,6 +8,7 @@ import com.cas_parser.api.services.blocking.CamsKfintechService import com.cas_parser.api.services.blocking.CdslService import com.cas_parser.api.services.blocking.ContractNoteService import com.cas_parser.api.services.blocking.CreditService +import com.cas_parser.api.services.blocking.InboundEmailService import com.cas_parser.api.services.blocking.InboxService import com.cas_parser.api.services.blocking.KfintechService import com.cas_parser.api.services.blocking.LogService @@ -74,6 +75,8 @@ interface CasParserClient { fun smart(): SmartService + fun inboundEmail(): InboundEmailService + /** * Closes this client, relinquishing any underlying resources. * @@ -118,5 +121,7 @@ interface CasParserClient { fun nsdl(): NsdlService.WithRawResponse fun smart(): SmartService.WithRawResponse + + fun inboundEmail(): InboundEmailService.WithRawResponse } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientAsync.kt index 22f6ad3..4d828d5 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientAsync.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientAsync.kt @@ -8,6 +8,7 @@ import com.cas_parser.api.services.async.CamsKfintechServiceAsync import com.cas_parser.api.services.async.CdslServiceAsync import com.cas_parser.api.services.async.ContractNoteServiceAsync import com.cas_parser.api.services.async.CreditServiceAsync +import com.cas_parser.api.services.async.InboundEmailServiceAsync import com.cas_parser.api.services.async.InboxServiceAsync import com.cas_parser.api.services.async.KfintechServiceAsync import com.cas_parser.api.services.async.LogServiceAsync @@ -74,6 +75,8 @@ interface CasParserClientAsync { fun smart(): SmartServiceAsync + fun inboundEmail(): InboundEmailServiceAsync + /** * Closes this client, relinquishing any underlying resources. * @@ -122,5 +125,7 @@ interface CasParserClientAsync { fun nsdl(): NsdlServiceAsync.WithRawResponse fun smart(): SmartServiceAsync.WithRawResponse + + fun inboundEmail(): InboundEmailServiceAsync.WithRawResponse } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientAsyncImpl.kt index 5f28136..b10af0a 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientAsyncImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientAsyncImpl.kt @@ -14,6 +14,8 @@ import com.cas_parser.api.services.async.ContractNoteServiceAsync import com.cas_parser.api.services.async.ContractNoteServiceAsyncImpl import com.cas_parser.api.services.async.CreditServiceAsync import com.cas_parser.api.services.async.CreditServiceAsyncImpl +import com.cas_parser.api.services.async.InboundEmailServiceAsync +import com.cas_parser.api.services.async.InboundEmailServiceAsyncImpl import com.cas_parser.api.services.async.InboxServiceAsync import com.cas_parser.api.services.async.InboxServiceAsyncImpl import com.cas_parser.api.services.async.KfintechServiceAsync @@ -83,6 +85,10 @@ class CasParserClientAsyncImpl(private val clientOptions: ClientOptions) : CasPa SmartServiceAsyncImpl(clientOptionsWithUserAgent) } + private val inboundEmail: InboundEmailServiceAsync by lazy { + InboundEmailServiceAsyncImpl(clientOptionsWithUserAgent) + } + override fun sync(): CasParserClient = sync override fun withRawResponse(): CasParserClientAsync.WithRawResponse = withRawResponse @@ -112,6 +118,8 @@ class CasParserClientAsyncImpl(private val clientOptions: ClientOptions) : CasPa override fun smart(): SmartServiceAsync = smart + override fun inboundEmail(): InboundEmailServiceAsync = inboundEmail + override fun close() = clientOptions.close() class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : @@ -161,6 +169,10 @@ class CasParserClientAsyncImpl(private val clientOptions: ClientOptions) : CasPa SmartServiceAsyncImpl.WithRawResponseImpl(clientOptions) } + private val inboundEmail: InboundEmailServiceAsync.WithRawResponse by lazy { + InboundEmailServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + override fun withOptions( modifier: Consumer ): CasParserClientAsync.WithRawResponse = @@ -189,5 +201,7 @@ class CasParserClientAsyncImpl(private val clientOptions: ClientOptions) : CasPa override fun nsdl(): NsdlServiceAsync.WithRawResponse = nsdl override fun smart(): SmartServiceAsync.WithRawResponse = smart + + override fun inboundEmail(): InboundEmailServiceAsync.WithRawResponse = inboundEmail } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientImpl.kt index f4b18e8..db32253 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientImpl.kt @@ -14,6 +14,8 @@ import com.cas_parser.api.services.blocking.ContractNoteService import com.cas_parser.api.services.blocking.ContractNoteServiceImpl import com.cas_parser.api.services.blocking.CreditService import com.cas_parser.api.services.blocking.CreditServiceImpl +import com.cas_parser.api.services.blocking.InboundEmailService +import com.cas_parser.api.services.blocking.InboundEmailServiceImpl import com.cas_parser.api.services.blocking.InboxService import com.cas_parser.api.services.blocking.InboxServiceImpl import com.cas_parser.api.services.blocking.KfintechService @@ -77,6 +79,10 @@ class CasParserClientImpl(private val clientOptions: ClientOptions) : CasParserC private val smart: SmartService by lazy { SmartServiceImpl(clientOptionsWithUserAgent) } + private val inboundEmail: InboundEmailService by lazy { + InboundEmailServiceImpl(clientOptionsWithUserAgent) + } + override fun async(): CasParserClientAsync = async override fun withRawResponse(): CasParserClient.WithRawResponse = withRawResponse @@ -106,6 +112,8 @@ class CasParserClientImpl(private val clientOptions: ClientOptions) : CasParserC override fun smart(): SmartService = smart + override fun inboundEmail(): InboundEmailService = inboundEmail + override fun close() = clientOptions.close() class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : @@ -155,6 +163,10 @@ class CasParserClientImpl(private val clientOptions: ClientOptions) : CasParserC SmartServiceImpl.WithRawResponseImpl(clientOptions) } + private val inboundEmail: InboundEmailService.WithRawResponse by lazy { + InboundEmailServiceImpl.WithRawResponseImpl(clientOptions) + } + override fun withOptions( modifier: Consumer ): CasParserClient.WithRawResponse = @@ -183,5 +195,7 @@ class CasParserClientImpl(private val clientOptions: ClientOptions) : CasParserC override fun nsdl(): NsdlService.WithRawResponse = nsdl override fun smart(): SmartService.WithRawResponse = smart + + override fun inboundEmail(): InboundEmailService.WithRawResponse = inboundEmail } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateParams.kt new file mode 100644 index 0000000..93daf86 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateParams.kt @@ -0,0 +1,412 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.accesstoken + +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonField +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.Params +import com.cas_parser.api.core.http.Headers +import com.cas_parser.api.core.http.QueryParams +import com.cas_parser.api.errors.CasParserInvalidDataException +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 + +/** + * Generate a short-lived access token from your API key. + * + * **Use this endpoint from your backend** to create tokens that can be safely passed to + * frontend/SDK. + * + * **Legacy path:** `/v1/access-token` (still supported) + * + * Access tokens: + * - Are prefixed with `at_` for easy identification + * - Valid for up to 60 minutes + * - Can be used in place of API keys on all v4 endpoints + * - Cannot be used to generate other access tokens + */ +class AccessTokenCreateParams +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Token validity in minutes (max 60) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun expiryMinutes(): Optional = body.expiryMinutes() + + /** + * Returns the raw JSON value of [expiryMinutes]. + * + * Unlike [expiryMinutes], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _expiryMinutes(): JsonField = body._expiryMinutes() + + fun _additionalBodyProperties(): Map = body._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 { + + @JvmStatic fun none(): AccessTokenCreateParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [AccessTokenCreateParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AccessTokenCreateParams]. */ + class Builder internal constructor() { + + private var body: Body.Builder = Body.builder() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(accessTokenCreateParams: AccessTokenCreateParams) = apply { + body = accessTokenCreateParams.body.toBuilder() + additionalHeaders = accessTokenCreateParams.additionalHeaders.toBuilder() + additionalQueryParams = accessTokenCreateParams.additionalQueryParams.toBuilder() + } + + /** + * Sets the entire request body. + * + * This is generally only useful if you are already constructing the body separately. + * Otherwise, it's more convenient to use the top-level setters instead: + * - [expiryMinutes] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + /** Token validity in minutes (max 60) */ + fun expiryMinutes(expiryMinutes: Long) = apply { body.expiryMinutes(expiryMinutes) } + + /** + * Sets [Builder.expiryMinutes] to an arbitrary JSON value. + * + * You should usually call [Builder.expiryMinutes] with a well-typed [Long] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun expiryMinutes(expiryMinutes: JsonField) = apply { + body.expiryMinutes(expiryMinutes) + } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) + } + + 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 [AccessTokenCreateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): AccessTokenCreateParams = + AccessTokenCreateParams( + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + class Body + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val expiryMinutes: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("expiry_minutes") + @ExcludeMissing + expiryMinutes: JsonField = JsonMissing.of() + ) : this(expiryMinutes, mutableMapOf()) + + /** + * Token validity in minutes (max 60) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun expiryMinutes(): Optional = expiryMinutes.getOptional("expiry_minutes") + + /** + * Returns the raw JSON value of [expiryMinutes]. + * + * Unlike [expiryMinutes], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("expiry_minutes") + @ExcludeMissing + fun _expiryMinutes(): JsonField = expiryMinutes + + @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 [Body]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var expiryMinutes: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + expiryMinutes = body.expiryMinutes + additionalProperties = body.additionalProperties.toMutableMap() + } + + /** Token validity in minutes (max 60) */ + fun expiryMinutes(expiryMinutes: Long) = expiryMinutes(JsonField.of(expiryMinutes)) + + /** + * Sets [Builder.expiryMinutes] to an arbitrary JSON value. + * + * You should usually call [Builder.expiryMinutes] with a well-typed [Long] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun expiryMinutes(expiryMinutes: JsonField) = apply { + this.expiryMinutes = expiryMinutes + } + + 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 [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Body = Body(expiryMinutes, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + expiryMinutes() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (expiryMinutes.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + expiryMinutes == other.expiryMinutes && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(expiryMinutes, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{expiryMinutes=$expiryMinutes, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AccessTokenCreateParams && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = Objects.hash(body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "AccessTokenCreateParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateResponse.kt new file mode 100644 index 0000000..a23d37b --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateResponse.kt @@ -0,0 +1,239 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.accesstoken + +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonField +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.errors.CasParserInvalidDataException +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 + +class AccessTokenCreateResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val accessToken: JsonField, + private val expiresIn: JsonField, + private val tokenType: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("access_token") + @ExcludeMissing + accessToken: JsonField = JsonMissing.of(), + @JsonProperty("expires_in") @ExcludeMissing expiresIn: JsonField = JsonMissing.of(), + @JsonProperty("token_type") @ExcludeMissing tokenType: JsonField = JsonMissing.of(), + ) : this(accessToken, expiresIn, tokenType, mutableMapOf()) + + /** + * The at_ prefixed access token + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun accessToken(): Optional = accessToken.getOptional("access_token") + + /** + * Token validity in seconds + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun expiresIn(): Optional = expiresIn.getOptional("expires_in") + + /** + * Always "api_key" - token is a drop-in replacement for x-api-key header + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun tokenType(): Optional = tokenType.getOptional("token_type") + + /** + * Returns the raw JSON value of [accessToken]. + * + * Unlike [accessToken], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("access_token") + @ExcludeMissing + fun _accessToken(): JsonField = accessToken + + /** + * Returns the raw JSON value of [expiresIn]. + * + * Unlike [expiresIn], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("expires_in") @ExcludeMissing fun _expiresIn(): JsonField = expiresIn + + /** + * Returns the raw JSON value of [tokenType]. + * + * Unlike [tokenType], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("token_type") @ExcludeMissing fun _tokenType(): JsonField = tokenType + + @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 [AccessTokenCreateResponse]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AccessTokenCreateResponse]. */ + class Builder internal constructor() { + + private var accessToken: JsonField = JsonMissing.of() + private var expiresIn: JsonField = JsonMissing.of() + private var tokenType: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(accessTokenCreateResponse: AccessTokenCreateResponse) = apply { + accessToken = accessTokenCreateResponse.accessToken + expiresIn = accessTokenCreateResponse.expiresIn + tokenType = accessTokenCreateResponse.tokenType + additionalProperties = accessTokenCreateResponse.additionalProperties.toMutableMap() + } + + /** The at_ prefixed access token */ + fun accessToken(accessToken: String) = accessToken(JsonField.of(accessToken)) + + /** + * Sets [Builder.accessToken] to an arbitrary JSON value. + * + * You should usually call [Builder.accessToken] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun accessToken(accessToken: JsonField) = apply { this.accessToken = accessToken } + + /** Token validity in seconds */ + fun expiresIn(expiresIn: Long) = expiresIn(JsonField.of(expiresIn)) + + /** + * Sets [Builder.expiresIn] to an arbitrary JSON value. + * + * You should usually call [Builder.expiresIn] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun expiresIn(expiresIn: JsonField) = apply { this.expiresIn = expiresIn } + + /** Always "api_key" - token is a drop-in replacement for x-api-key header */ + fun tokenType(tokenType: String) = tokenType(JsonField.of(tokenType)) + + /** + * Sets [Builder.tokenType] to an arbitrary JSON value. + * + * You should usually call [Builder.tokenType] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun tokenType(tokenType: JsonField) = apply { this.tokenType = tokenType } + + 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 [AccessTokenCreateResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): AccessTokenCreateResponse = + AccessTokenCreateResponse( + accessToken, + expiresIn, + tokenType, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): AccessTokenCreateResponse = apply { + if (validated) { + return@apply + } + + accessToken() + expiresIn() + tokenType() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (accessToken.asKnown().isPresent) 1 else 0) + + (if (expiresIn.asKnown().isPresent) 1 else 0) + + (if (tokenType.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AccessTokenCreateResponse && + accessToken == other.accessToken && + expiresIn == other.expiresIn && + tokenType == other.tokenType && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(accessToken, expiresIn, tokenType, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AccessTokenCreateResponse{accessToken=$accessToken, expiresIn=$expiresIn, tokenType=$tokenType, additionalProperties=$additionalProperties}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/credits/CreditCheckParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/credits/CreditCheckParams.kt new file mode 100644 index 0000000..aa45ce8 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/credits/CreditCheckParams.kt @@ -0,0 +1,219 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.credits + +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.Params +import com.cas_parser.api.core.http.Headers +import com.cas_parser.api.core.http.QueryParams +import com.cas_parser.api.core.toImmutable +import java.util.Objects +import java.util.Optional + +/** + * Check your remaining API credits and usage for the current billing period. + * + * Returns: + * - Number of API calls used and remaining credits + * - Credit limit and reset date + * - List of enabled features for your plan + * + * Credits reset at the start of each billing period. + */ +class CreditCheckParams +private constructor( + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, + private val additionalBodyProperties: Map, +) : Params { + + /** Additional body properties to send with the request. */ + fun _additionalBodyProperties(): Map = additionalBodyProperties + + /** 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 { + + @JvmStatic fun none(): CreditCheckParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [CreditCheckParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [CreditCheckParams]. */ + class Builder internal constructor() { + + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + private var additionalBodyProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(creditCheckParams: CreditCheckParams) = apply { + additionalHeaders = creditCheckParams.additionalHeaders.toBuilder() + additionalQueryParams = creditCheckParams.additionalQueryParams.toBuilder() + additionalBodyProperties = creditCheckParams.additionalBodyProperties.toMutableMap() + } + + 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) + } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + this.additionalBodyProperties.clear() + putAllAdditionalBodyProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + additionalBodyProperties.put(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + this.additionalBodyProperties.putAll(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { + additionalBodyProperties.remove(key) + } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalBodyProperty) + } + + /** + * Returns an immutable instance of [CreditCheckParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): CreditCheckParams = + CreditCheckParams( + additionalHeaders.build(), + additionalQueryParams.build(), + additionalBodyProperties.toImmutable(), + ) + } + + fun _body(): Optional> = + Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is CreditCheckParams && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams && + additionalBodyProperties == other.additionalBodyProperties + } + + override fun hashCode(): Int = + Objects.hash(additionalHeaders, additionalQueryParams, additionalBodyProperties) + + override fun toString() = + "CreditCheckParams{additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/credits/CreditCheckResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/credits/CreditCheckResponse.kt new file mode 100644 index 0000000..6a3f1a3 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/credits/CreditCheckResponse.kt @@ -0,0 +1,387 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.credits + +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonField +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.checkKnown +import com.cas_parser.api.core.toImmutable +import com.cas_parser.api.errors.CasParserInvalidDataException +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.time.OffsetDateTime +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +class CreditCheckResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val enabledFeatures: JsonField>, + private val isUnlimited: JsonField, + private val limit: JsonField, + private val remaining: JsonField, + private val resetsAt: JsonField, + private val used: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("enabled_features") + @ExcludeMissing + enabledFeatures: JsonField> = JsonMissing.of(), + @JsonProperty("is_unlimited") + @ExcludeMissing + isUnlimited: JsonField = JsonMissing.of(), + @JsonProperty("limit") @ExcludeMissing limit: JsonField = JsonMissing.of(), + @JsonProperty("remaining") @ExcludeMissing remaining: JsonField = JsonMissing.of(), + @JsonProperty("resets_at") + @ExcludeMissing + resetsAt: JsonField = JsonMissing.of(), + @JsonProperty("used") @ExcludeMissing used: JsonField = JsonMissing.of(), + ) : this(enabledFeatures, isUnlimited, limit, remaining, resetsAt, used, mutableMapOf()) + + /** + * List of API features enabled for your plan + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun enabledFeatures(): Optional> = enabledFeatures.getOptional("enabled_features") + + /** + * Whether the account has unlimited credits + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun isUnlimited(): Optional = isUnlimited.getOptional("is_unlimited") + + /** + * Total credit limit for billing period + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun limit(): Optional = limit.getOptional("limit") + + /** + * Remaining credits (null if unlimited) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun remaining(): Optional = remaining.getOptional("remaining") + + /** + * When credits reset (ISO 8601) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun resetsAt(): Optional = resetsAt.getOptional("resets_at") + + /** + * Number of credits used this billing period + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun used(): Optional = used.getOptional("used") + + /** + * Returns the raw JSON value of [enabledFeatures]. + * + * Unlike [enabledFeatures], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("enabled_features") + @ExcludeMissing + fun _enabledFeatures(): JsonField> = enabledFeatures + + /** + * Returns the raw JSON value of [isUnlimited]. + * + * Unlike [isUnlimited], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("is_unlimited") + @ExcludeMissing + fun _isUnlimited(): JsonField = isUnlimited + + /** + * Returns the raw JSON value of [limit]. + * + * Unlike [limit], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("limit") @ExcludeMissing fun _limit(): JsonField = limit + + /** + * Returns the raw JSON value of [remaining]. + * + * Unlike [remaining], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("remaining") @ExcludeMissing fun _remaining(): JsonField = remaining + + /** + * Returns the raw JSON value of [resetsAt]. + * + * Unlike [resetsAt], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("resets_at") @ExcludeMissing fun _resetsAt(): JsonField = resetsAt + + /** + * Returns the raw JSON value of [used]. + * + * Unlike [used], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("used") @ExcludeMissing fun _used(): JsonField = used + + @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 [CreditCheckResponse]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [CreditCheckResponse]. */ + class Builder internal constructor() { + + private var enabledFeatures: JsonField>? = null + private var isUnlimited: JsonField = JsonMissing.of() + private var limit: JsonField = JsonMissing.of() + private var remaining: JsonField = JsonMissing.of() + private var resetsAt: JsonField = JsonMissing.of() + private var used: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(creditCheckResponse: CreditCheckResponse) = apply { + enabledFeatures = creditCheckResponse.enabledFeatures.map { it.toMutableList() } + isUnlimited = creditCheckResponse.isUnlimited + limit = creditCheckResponse.limit + remaining = creditCheckResponse.remaining + resetsAt = creditCheckResponse.resetsAt + used = creditCheckResponse.used + additionalProperties = creditCheckResponse.additionalProperties.toMutableMap() + } + + /** List of API features enabled for your plan */ + fun enabledFeatures(enabledFeatures: List) = + enabledFeatures(JsonField.of(enabledFeatures)) + + /** + * Sets [Builder.enabledFeatures] to an arbitrary JSON value. + * + * You should usually call [Builder.enabledFeatures] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun enabledFeatures(enabledFeatures: JsonField>) = apply { + this.enabledFeatures = enabledFeatures.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [enabledFeatures]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addEnabledFeature(enabledFeature: String) = apply { + enabledFeatures = + (enabledFeatures ?: JsonField.of(mutableListOf())).also { + checkKnown("enabledFeatures", it).add(enabledFeature) + } + } + + /** Whether the account has unlimited credits */ + fun isUnlimited(isUnlimited: Boolean) = isUnlimited(JsonField.of(isUnlimited)) + + /** + * Sets [Builder.isUnlimited] to an arbitrary JSON value. + * + * You should usually call [Builder.isUnlimited] with a well-typed [Boolean] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun isUnlimited(isUnlimited: JsonField) = apply { this.isUnlimited = isUnlimited } + + /** Total credit limit for billing period */ + fun limit(limit: Long) = limit(JsonField.of(limit)) + + /** + * Sets [Builder.limit] to an arbitrary JSON value. + * + * You should usually call [Builder.limit] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun limit(limit: JsonField) = apply { this.limit = limit } + + /** Remaining credits (null if unlimited) */ + fun remaining(remaining: Double?) = remaining(JsonField.ofNullable(remaining)) + + /** + * Alias for [Builder.remaining]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun remaining(remaining: Double) = remaining(remaining as Double?) + + /** Alias for calling [Builder.remaining] with `remaining.orElse(null)`. */ + fun remaining(remaining: Optional) = remaining(remaining.getOrNull()) + + /** + * Sets [Builder.remaining] to an arbitrary JSON value. + * + * You should usually call [Builder.remaining] with a well-typed [Double] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun remaining(remaining: JsonField) = apply { this.remaining = remaining } + + /** When credits reset (ISO 8601) */ + fun resetsAt(resetsAt: OffsetDateTime?) = resetsAt(JsonField.ofNullable(resetsAt)) + + /** Alias for calling [Builder.resetsAt] with `resetsAt.orElse(null)`. */ + fun resetsAt(resetsAt: Optional) = resetsAt(resetsAt.getOrNull()) + + /** + * Sets [Builder.resetsAt] to an arbitrary JSON value. + * + * You should usually call [Builder.resetsAt] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun resetsAt(resetsAt: JsonField) = apply { this.resetsAt = resetsAt } + + /** Number of credits used this billing period */ + fun used(used: Double) = used(JsonField.of(used)) + + /** + * Sets [Builder.used] to an arbitrary JSON value. + * + * You should usually call [Builder.used] with a well-typed [Double] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun used(used: JsonField) = apply { this.used = used } + + 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 [CreditCheckResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): CreditCheckResponse = + CreditCheckResponse( + (enabledFeatures ?: JsonMissing.of()).map { it.toImmutable() }, + isUnlimited, + limit, + remaining, + resetsAt, + used, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): CreditCheckResponse = apply { + if (validated) { + return@apply + } + + enabledFeatures() + isUnlimited() + limit() + remaining() + resetsAt() + used() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 = + (enabledFeatures.asKnown().getOrNull()?.size ?: 0) + + (if (isUnlimited.asKnown().isPresent) 1 else 0) + + (if (limit.asKnown().isPresent) 1 else 0) + + (if (remaining.asKnown().isPresent) 1 else 0) + + (if (resetsAt.asKnown().isPresent) 1 else 0) + + (if (used.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is CreditCheckResponse && + enabledFeatures == other.enabledFeatures && + isUnlimited == other.isUnlimited && + limit == other.limit && + remaining == other.remaining && + resetsAt == other.resetsAt && + used == other.used && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + enabledFeatures, + isUnlimited, + limit, + remaining, + resetsAt, + used, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "CreditCheckResponse{enabledFeatures=$enabledFeatures, isUnlimited=$isUnlimited, limit=$limit, remaining=$remaining, resetsAt=$resetsAt, used=$used, additionalProperties=$additionalProperties}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateParams.kt new file mode 100644 index 0000000..a20d52b --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateParams.kt @@ -0,0 +1,1061 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.inboundemail + +import com.cas_parser.api.core.Enum +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonField +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.Params +import com.cas_parser.api.core.checkKnown +import com.cas_parser.api.core.checkRequired +import com.cas_parser.api.core.http.Headers +import com.cas_parser.api.core.http.QueryParams +import com.cas_parser.api.core.toImmutable +import com.cas_parser.api.errors.CasParserInvalidDataException +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 + +/** + * Create a dedicated inbound email address for collecting CAS statements via email forwarding. + * + * **How it works:** + * 1. Create an inbound email with your webhook URL + * 2. Display the email address to your user (e.g., "Forward your CAS to + * ie_xxx@import.casparser.in") + * 3. When an investor forwards a CAS email, we verify the sender and deliver to your webhook + * + * **Webhook Delivery:** + * - We POST to your `callback_url` with JSON body containing files (matching EmailCASFile schema) + * - Failed deliveries are retried automatically with exponential backoff + * + * **Inactivity:** + * - Inbound emails with no activity in 30 days are marked inactive + * - Active inbound emails remain operational indefinitely + */ +class InboundEmailCreateParams +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Webhook URL where we POST email notifications. Must be HTTPS in production (HTTP allowed for + * localhost during development). + * + * @throws CasParserInvalidDataException 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 callbackUrl(): String = body.callbackUrl() + + /** + * Optional custom email prefix for user-friendly addresses. + * - Must be 3-32 characters + * - Alphanumeric + hyphens only + * - Must start and end with letter/number + * - Example: `john-portfolio@import.casparser.in` + * - If omitted, generates random ID like `ie_abc123xyz@import.casparser.in` + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun alias(): Optional = body.alias() + + /** + * Filter emails by CAS provider. If omitted, accepts all providers. + * - `cdsl` → eCAS@cdslstatement.com + * - `nsdl` → NSDL-CAS@nsdl.co.in + * - `cams` → donotreply@camsonline.com + * - `kfintech` → samfS@kfintech.com + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun allowedSources(): Optional> = body.allowedSources() + + /** + * Optional key-value pairs (max 10) to include in webhook payload. Useful for passing context + * like plan_type, campaign_id, etc. + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun metadata(): Optional = body.metadata() + + /** + * Your internal identifier (e.g., user_id, account_id). Returned in webhook payload for + * correlation. + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun reference(): Optional = body.reference() + + /** + * Returns the raw JSON value of [callbackUrl]. + * + * Unlike [callbackUrl], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _callbackUrl(): JsonField = body._callbackUrl() + + /** + * Returns the raw JSON value of [alias]. + * + * Unlike [alias], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _alias(): JsonField = body._alias() + + /** + * Returns the raw JSON value of [allowedSources]. + * + * Unlike [allowedSources], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _allowedSources(): JsonField> = body._allowedSources() + + /** + * Returns the raw JSON value of [metadata]. + * + * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _metadata(): JsonField = body._metadata() + + /** + * Returns the raw JSON value of [reference]. + * + * Unlike [reference], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _reference(): JsonField = body._reference() + + fun _additionalBodyProperties(): Map = body._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 [InboundEmailCreateParams]. + * + * The following fields are required: + * ```java + * .callbackUrl() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [InboundEmailCreateParams]. */ + class Builder internal constructor() { + + private var body: Body.Builder = Body.builder() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(inboundEmailCreateParams: InboundEmailCreateParams) = apply { + body = inboundEmailCreateParams.body.toBuilder() + additionalHeaders = inboundEmailCreateParams.additionalHeaders.toBuilder() + additionalQueryParams = inboundEmailCreateParams.additionalQueryParams.toBuilder() + } + + /** + * Sets the entire request body. + * + * This is generally only useful if you are already constructing the body separately. + * Otherwise, it's more convenient to use the top-level setters instead: + * - [callbackUrl] + * - [alias] + * - [allowedSources] + * - [metadata] + * - [reference] + * - etc. + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + /** + * Webhook URL where we POST email notifications. Must be HTTPS in production (HTTP allowed + * for localhost during development). + */ + fun callbackUrl(callbackUrl: String) = apply { body.callbackUrl(callbackUrl) } + + /** + * Sets [Builder.callbackUrl] to an arbitrary JSON value. + * + * You should usually call [Builder.callbackUrl] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun callbackUrl(callbackUrl: JsonField) = apply { body.callbackUrl(callbackUrl) } + + /** + * Optional custom email prefix for user-friendly addresses. + * - Must be 3-32 characters + * - Alphanumeric + hyphens only + * - Must start and end with letter/number + * - Example: `john-portfolio@import.casparser.in` + * - If omitted, generates random ID like `ie_abc123xyz@import.casparser.in` + */ + fun alias(alias: String) = apply { body.alias(alias) } + + /** + * Sets [Builder.alias] to an arbitrary JSON value. + * + * You should usually call [Builder.alias] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun alias(alias: JsonField) = apply { body.alias(alias) } + + /** + * Filter emails by CAS provider. If omitted, accepts all providers. + * - `cdsl` → eCAS@cdslstatement.com + * - `nsdl` → NSDL-CAS@nsdl.co.in + * - `cams` → donotreply@camsonline.com + * - `kfintech` → samfS@kfintech.com + */ + fun allowedSources(allowedSources: List) = apply { + body.allowedSources(allowedSources) + } + + /** + * Sets [Builder.allowedSources] to an arbitrary JSON value. + * + * You should usually call [Builder.allowedSources] with a well-typed `List` + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun allowedSources(allowedSources: JsonField>) = apply { + body.allowedSources(allowedSources) + } + + /** + * Adds a single [AllowedSource] to [allowedSources]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addAllowedSource(allowedSource: AllowedSource) = apply { + body.addAllowedSource(allowedSource) + } + + /** + * Optional key-value pairs (max 10) to include in webhook payload. Useful for passing + * context like plan_type, campaign_id, etc. + */ + fun metadata(metadata: Metadata) = apply { body.metadata(metadata) } + + /** + * Sets [Builder.metadata] to an arbitrary JSON value. + * + * You should usually call [Builder.metadata] with a well-typed [Metadata] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun metadata(metadata: JsonField) = apply { body.metadata(metadata) } + + /** + * Your internal identifier (e.g., user_id, account_id). Returned in webhook payload for + * correlation. + */ + fun reference(reference: String) = apply { body.reference(reference) } + + /** + * Sets [Builder.reference] to an arbitrary JSON value. + * + * You should usually call [Builder.reference] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun reference(reference: JsonField) = apply { body.reference(reference) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) + } + + 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 [InboundEmailCreateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .callbackUrl() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): InboundEmailCreateParams = + InboundEmailCreateParams( + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + class Body + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val callbackUrl: JsonField, + private val alias: JsonField, + private val allowedSources: JsonField>, + private val metadata: JsonField, + private val reference: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("callback_url") + @ExcludeMissing + callbackUrl: JsonField = JsonMissing.of(), + @JsonProperty("alias") @ExcludeMissing alias: JsonField = JsonMissing.of(), + @JsonProperty("allowed_sources") + @ExcludeMissing + allowedSources: JsonField> = JsonMissing.of(), + @JsonProperty("metadata") + @ExcludeMissing + metadata: JsonField = JsonMissing.of(), + @JsonProperty("reference") + @ExcludeMissing + reference: JsonField = JsonMissing.of(), + ) : this(callbackUrl, alias, allowedSources, metadata, reference, mutableMapOf()) + + /** + * Webhook URL where we POST email notifications. Must be HTTPS in production (HTTP allowed + * for localhost during development). + * + * @throws CasParserInvalidDataException 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 callbackUrl(): String = callbackUrl.getRequired("callback_url") + + /** + * Optional custom email prefix for user-friendly addresses. + * - Must be 3-32 characters + * - Alphanumeric + hyphens only + * - Must start and end with letter/number + * - Example: `john-portfolio@import.casparser.in` + * - If omitted, generates random ID like `ie_abc123xyz@import.casparser.in` + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun alias(): Optional = alias.getOptional("alias") + + /** + * Filter emails by CAS provider. If omitted, accepts all providers. + * - `cdsl` → eCAS@cdslstatement.com + * - `nsdl` → NSDL-CAS@nsdl.co.in + * - `cams` → donotreply@camsonline.com + * - `kfintech` → samfS@kfintech.com + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun allowedSources(): Optional> = + allowedSources.getOptional("allowed_sources") + + /** + * Optional key-value pairs (max 10) to include in webhook payload. Useful for passing + * context like plan_type, campaign_id, etc. + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun metadata(): Optional = metadata.getOptional("metadata") + + /** + * Your internal identifier (e.g., user_id, account_id). Returned in webhook payload for + * correlation. + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun reference(): Optional = reference.getOptional("reference") + + /** + * Returns the raw JSON value of [callbackUrl]. + * + * Unlike [callbackUrl], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("callback_url") + @ExcludeMissing + fun _callbackUrl(): JsonField = callbackUrl + + /** + * Returns the raw JSON value of [alias]. + * + * Unlike [alias], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("alias") @ExcludeMissing fun _alias(): JsonField = alias + + /** + * Returns the raw JSON value of [allowedSources]. + * + * Unlike [allowedSources], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("allowed_sources") + @ExcludeMissing + fun _allowedSources(): JsonField> = allowedSources + + /** + * Returns the raw JSON value of [metadata]. + * + * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("metadata") @ExcludeMissing fun _metadata(): JsonField = metadata + + /** + * Returns the raw JSON value of [reference]. + * + * Unlike [reference], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("reference") @ExcludeMissing fun _reference(): JsonField = reference + + @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 [Body]. + * + * The following fields are required: + * ```java + * .callbackUrl() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var callbackUrl: JsonField? = null + private var alias: JsonField = JsonMissing.of() + private var allowedSources: JsonField>? = null + private var metadata: JsonField = JsonMissing.of() + private var reference: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + callbackUrl = body.callbackUrl + alias = body.alias + allowedSources = body.allowedSources.map { it.toMutableList() } + metadata = body.metadata + reference = body.reference + additionalProperties = body.additionalProperties.toMutableMap() + } + + /** + * Webhook URL where we POST email notifications. Must be HTTPS in production (HTTP + * allowed for localhost during development). + */ + fun callbackUrl(callbackUrl: String) = callbackUrl(JsonField.of(callbackUrl)) + + /** + * Sets [Builder.callbackUrl] to an arbitrary JSON value. + * + * You should usually call [Builder.callbackUrl] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun callbackUrl(callbackUrl: JsonField) = apply { + this.callbackUrl = callbackUrl + } + + /** + * Optional custom email prefix for user-friendly addresses. + * - Must be 3-32 characters + * - Alphanumeric + hyphens only + * - Must start and end with letter/number + * - Example: `john-portfolio@import.casparser.in` + * - If omitted, generates random ID like `ie_abc123xyz@import.casparser.in` + */ + fun alias(alias: String) = alias(JsonField.of(alias)) + + /** + * Sets [Builder.alias] to an arbitrary JSON value. + * + * You should usually call [Builder.alias] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun alias(alias: JsonField) = apply { this.alias = alias } + + /** + * Filter emails by CAS provider. If omitted, accepts all providers. + * - `cdsl` → eCAS@cdslstatement.com + * - `nsdl` → NSDL-CAS@nsdl.co.in + * - `cams` → donotreply@camsonline.com + * - `kfintech` → samfS@kfintech.com + */ + fun allowedSources(allowedSources: List) = + allowedSources(JsonField.of(allowedSources)) + + /** + * Sets [Builder.allowedSources] to an arbitrary JSON value. + * + * You should usually call [Builder.allowedSources] with a well-typed + * `List` value instead. This method is primarily for setting the field + * to an undocumented or not yet supported value. + */ + fun allowedSources(allowedSources: JsonField>) = apply { + this.allowedSources = allowedSources.map { it.toMutableList() } + } + + /** + * Adds a single [AllowedSource] to [allowedSources]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addAllowedSource(allowedSource: AllowedSource) = apply { + allowedSources = + (allowedSources ?: JsonField.of(mutableListOf())).also { + checkKnown("allowedSources", it).add(allowedSource) + } + } + + /** + * Optional key-value pairs (max 10) to include in webhook payload. Useful for passing + * context like plan_type, campaign_id, etc. + */ + fun metadata(metadata: Metadata) = metadata(JsonField.of(metadata)) + + /** + * Sets [Builder.metadata] to an arbitrary JSON value. + * + * You should usually call [Builder.metadata] with a well-typed [Metadata] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun metadata(metadata: JsonField) = apply { this.metadata = metadata } + + /** + * Your internal identifier (e.g., user_id, account_id). Returned in webhook payload for + * correlation. + */ + fun reference(reference: String) = reference(JsonField.of(reference)) + + /** + * Sets [Builder.reference] to an arbitrary JSON value. + * + * You should usually call [Builder.reference] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun reference(reference: JsonField) = apply { this.reference = reference } + + 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 [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .callbackUrl() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("callbackUrl", callbackUrl), + alias, + (allowedSources ?: JsonMissing.of()).map { it.toImmutable() }, + metadata, + reference, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + callbackUrl() + alias() + allowedSources().ifPresent { it.forEach { it.validate() } } + metadata().ifPresent { it.validate() } + reference() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (callbackUrl.asKnown().isPresent) 1 else 0) + + (if (alias.asKnown().isPresent) 1 else 0) + + (allowedSources.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (metadata.asKnown().getOrNull()?.validity() ?: 0) + + (if (reference.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + callbackUrl == other.callbackUrl && + alias == other.alias && + allowedSources == other.allowedSources && + metadata == other.metadata && + reference == other.reference && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + callbackUrl, + alias, + allowedSources, + metadata, + reference, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{callbackUrl=$callbackUrl, alias=$alias, allowedSources=$allowedSources, metadata=$metadata, reference=$reference, additionalProperties=$additionalProperties}" + } + + class AllowedSource @JsonCreator private constructor(private val value: JsonField) : + Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val CDSL = of("cdsl") + + @JvmField val NSDL = of("nsdl") + + @JvmField val CAMS = of("cams") + + @JvmField val KFINTECH = of("kfintech") + + @JvmStatic fun of(value: String) = AllowedSource(JsonField.of(value)) + } + + /** An enum containing [AllowedSource]'s known values. */ + enum class Known { + CDSL, + NSDL, + CAMS, + KFINTECH, + } + + /** + * An enum containing [AllowedSource]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [AllowedSource] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + CDSL, + NSDL, + CAMS, + KFINTECH, + /** + * An enum member indicating that [AllowedSource] was instantiated with an unknown + * value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + CDSL -> Value.CDSL + NSDL -> Value.NSDL + CAMS -> Value.CAMS + KFINTECH -> Value.KFINTECH + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws CasParserInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + CDSL -> Known.CDSL + NSDL -> Known.NSDL + CAMS -> Known.CAMS + KFINTECH -> Known.KFINTECH + else -> throw CasParserInvalidDataException("Unknown AllowedSource: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws CasParserInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CasParserInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): AllowedSource = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AllowedSource && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** + * Optional key-value pairs (max 10) to include in webhook payload. Useful for passing context + * like plan_type, campaign_id, etc. + */ + class Metadata + @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 [Metadata]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Metadata]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(metadata: Metadata) = apply { + additionalProperties = metadata.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 [Metadata]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Metadata = Metadata(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): Metadata = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 Metadata && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Metadata{additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is InboundEmailCreateParams && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = Objects.hash(body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "InboundEmailCreateParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateResponse.kt new file mode 100644 index 0000000..fb3d9d5 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateResponse.kt @@ -0,0 +1,884 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.inboundemail + +import com.cas_parser.api.core.Enum +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonField +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.checkKnown +import com.cas_parser.api.core.toImmutable +import com.cas_parser.api.errors.CasParserInvalidDataException +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.time.OffsetDateTime +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** An inbound email address for receiving forwarded CAS emails */ +class InboundEmailCreateResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val allowedSources: JsonField>, + private val callbackUrl: JsonField, + private val createdAt: JsonField, + private val email: JsonField, + private val inboundEmailId: JsonField, + private val metadata: JsonField, + private val reference: JsonField, + private val status: JsonField, + private val updatedAt: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("allowed_sources") + @ExcludeMissing + allowedSources: JsonField> = JsonMissing.of(), + @JsonProperty("callback_url") + @ExcludeMissing + callbackUrl: JsonField = JsonMissing.of(), + @JsonProperty("created_at") + @ExcludeMissing + createdAt: JsonField = JsonMissing.of(), + @JsonProperty("email") @ExcludeMissing email: JsonField = JsonMissing.of(), + @JsonProperty("inbound_email_id") + @ExcludeMissing + inboundEmailId: JsonField = JsonMissing.of(), + @JsonProperty("metadata") @ExcludeMissing metadata: JsonField = JsonMissing.of(), + @JsonProperty("reference") @ExcludeMissing reference: JsonField = JsonMissing.of(), + @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(), + @JsonProperty("updated_at") + @ExcludeMissing + updatedAt: JsonField = JsonMissing.of(), + ) : this( + allowedSources, + callbackUrl, + createdAt, + email, + inboundEmailId, + metadata, + reference, + status, + updatedAt, + mutableMapOf(), + ) + + /** + * Accepted CAS providers (empty = all) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun allowedSources(): Optional> = + allowedSources.getOptional("allowed_sources") + + /** + * Webhook URL for email notifications + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun callbackUrl(): Optional = callbackUrl.getOptional("callback_url") + + /** + * When the mailbox was created + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun createdAt(): Optional = createdAt.getOptional("created_at") + + /** + * The inbound email address to forward CAS statements to + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun email(): Optional = email.getOptional("email") + + /** + * Unique inbound email identifier + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun inboundEmailId(): Optional = inboundEmailId.getOptional("inbound_email_id") + + /** + * Custom key-value metadata + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun metadata(): Optional = metadata.getOptional("metadata") + + /** + * Your internal reference identifier + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun reference(): Optional = reference.getOptional("reference") + + /** + * Current mailbox status + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun status(): Optional = status.getOptional("status") + + /** + * When the mailbox was last updated + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun updatedAt(): Optional = updatedAt.getOptional("updated_at") + + /** + * Returns the raw JSON value of [allowedSources]. + * + * Unlike [allowedSources], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("allowed_sources") + @ExcludeMissing + fun _allowedSources(): JsonField> = allowedSources + + /** + * Returns the raw JSON value of [callbackUrl]. + * + * Unlike [callbackUrl], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("callback_url") + @ExcludeMissing + fun _callbackUrl(): JsonField = callbackUrl + + /** + * Returns the raw JSON value of [createdAt]. + * + * Unlike [createdAt], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created_at") + @ExcludeMissing + fun _createdAt(): JsonField = createdAt + + /** + * Returns the raw JSON value of [email]. + * + * Unlike [email], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("email") @ExcludeMissing fun _email(): JsonField = email + + /** + * Returns the raw JSON value of [inboundEmailId]. + * + * Unlike [inboundEmailId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("inbound_email_id") + @ExcludeMissing + fun _inboundEmailId(): JsonField = inboundEmailId + + /** + * Returns the raw JSON value of [metadata]. + * + * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("metadata") @ExcludeMissing fun _metadata(): JsonField = metadata + + /** + * Returns the raw JSON value of [reference]. + * + * Unlike [reference], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("reference") @ExcludeMissing fun _reference(): JsonField = reference + + /** + * Returns the raw JSON value of [status]. + * + * Unlike [status], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("status") @ExcludeMissing fun _status(): JsonField = status + + /** + * Returns the raw JSON value of [updatedAt]. + * + * Unlike [updatedAt], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("updated_at") + @ExcludeMissing + fun _updatedAt(): JsonField = updatedAt + + @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 [InboundEmailCreateResponse]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [InboundEmailCreateResponse]. */ + class Builder internal constructor() { + + private var allowedSources: JsonField>? = null + private var callbackUrl: JsonField = JsonMissing.of() + private var createdAt: JsonField = JsonMissing.of() + private var email: JsonField = JsonMissing.of() + private var inboundEmailId: JsonField = JsonMissing.of() + private var metadata: JsonField = JsonMissing.of() + private var reference: JsonField = JsonMissing.of() + private var status: JsonField = JsonMissing.of() + private var updatedAt: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(inboundEmailCreateResponse: InboundEmailCreateResponse) = apply { + allowedSources = inboundEmailCreateResponse.allowedSources.map { it.toMutableList() } + callbackUrl = inboundEmailCreateResponse.callbackUrl + createdAt = inboundEmailCreateResponse.createdAt + email = inboundEmailCreateResponse.email + inboundEmailId = inboundEmailCreateResponse.inboundEmailId + metadata = inboundEmailCreateResponse.metadata + reference = inboundEmailCreateResponse.reference + status = inboundEmailCreateResponse.status + updatedAt = inboundEmailCreateResponse.updatedAt + additionalProperties = inboundEmailCreateResponse.additionalProperties.toMutableMap() + } + + /** Accepted CAS providers (empty = all) */ + fun allowedSources(allowedSources: List) = + allowedSources(JsonField.of(allowedSources)) + + /** + * Sets [Builder.allowedSources] to an arbitrary JSON value. + * + * You should usually call [Builder.allowedSources] with a well-typed `List` + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun allowedSources(allowedSources: JsonField>) = apply { + this.allowedSources = allowedSources.map { it.toMutableList() } + } + + /** + * Adds a single [AllowedSource] to [allowedSources]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addAllowedSource(allowedSource: AllowedSource) = apply { + allowedSources = + (allowedSources ?: JsonField.of(mutableListOf())).also { + checkKnown("allowedSources", it).add(allowedSource) + } + } + + /** Webhook URL for email notifications */ + fun callbackUrl(callbackUrl: String) = callbackUrl(JsonField.of(callbackUrl)) + + /** + * Sets [Builder.callbackUrl] to an arbitrary JSON value. + * + * You should usually call [Builder.callbackUrl] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun callbackUrl(callbackUrl: JsonField) = apply { this.callbackUrl = callbackUrl } + + /** When the mailbox was created */ + fun createdAt(createdAt: OffsetDateTime) = createdAt(JsonField.of(createdAt)) + + /** + * Sets [Builder.createdAt] to an arbitrary JSON value. + * + * You should usually call [Builder.createdAt] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun createdAt(createdAt: JsonField) = apply { this.createdAt = createdAt } + + /** The inbound email address to forward CAS statements to */ + fun email(email: String) = email(JsonField.of(email)) + + /** + * Sets [Builder.email] to an arbitrary JSON value. + * + * You should usually call [Builder.email] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun email(email: JsonField) = apply { this.email = email } + + /** Unique inbound email identifier */ + fun inboundEmailId(inboundEmailId: String) = inboundEmailId(JsonField.of(inboundEmailId)) + + /** + * Sets [Builder.inboundEmailId] to an arbitrary JSON value. + * + * You should usually call [Builder.inboundEmailId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun inboundEmailId(inboundEmailId: JsonField) = apply { + this.inboundEmailId = inboundEmailId + } + + /** Custom key-value metadata */ + fun metadata(metadata: Metadata) = metadata(JsonField.of(metadata)) + + /** + * Sets [Builder.metadata] to an arbitrary JSON value. + * + * You should usually call [Builder.metadata] with a well-typed [Metadata] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun metadata(metadata: JsonField) = apply { this.metadata = metadata } + + /** Your internal reference identifier */ + fun reference(reference: String?) = reference(JsonField.ofNullable(reference)) + + /** Alias for calling [Builder.reference] with `reference.orElse(null)`. */ + fun reference(reference: Optional) = reference(reference.getOrNull()) + + /** + * Sets [Builder.reference] to an arbitrary JSON value. + * + * You should usually call [Builder.reference] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun reference(reference: JsonField) = apply { this.reference = reference } + + /** Current mailbox status */ + fun status(status: Status) = status(JsonField.of(status)) + + /** + * Sets [Builder.status] to an arbitrary JSON value. + * + * You should usually call [Builder.status] with a well-typed [Status] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun status(status: JsonField) = apply { this.status = status } + + /** When the mailbox was last updated */ + fun updatedAt(updatedAt: OffsetDateTime) = updatedAt(JsonField.of(updatedAt)) + + /** + * Sets [Builder.updatedAt] to an arbitrary JSON value. + * + * You should usually call [Builder.updatedAt] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun updatedAt(updatedAt: JsonField) = apply { this.updatedAt = updatedAt } + + 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 [InboundEmailCreateResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): InboundEmailCreateResponse = + InboundEmailCreateResponse( + (allowedSources ?: JsonMissing.of()).map { it.toImmutable() }, + callbackUrl, + createdAt, + email, + inboundEmailId, + metadata, + reference, + status, + updatedAt, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): InboundEmailCreateResponse = apply { + if (validated) { + return@apply + } + + allowedSources().ifPresent { it.forEach { it.validate() } } + callbackUrl() + createdAt() + email() + inboundEmailId() + metadata().ifPresent { it.validate() } + reference() + status().ifPresent { it.validate() } + updatedAt() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 = + (allowedSources.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (callbackUrl.asKnown().isPresent) 1 else 0) + + (if (createdAt.asKnown().isPresent) 1 else 0) + + (if (email.asKnown().isPresent) 1 else 0) + + (if (inboundEmailId.asKnown().isPresent) 1 else 0) + + (metadata.asKnown().getOrNull()?.validity() ?: 0) + + (if (reference.asKnown().isPresent) 1 else 0) + + (status.asKnown().getOrNull()?.validity() ?: 0) + + (if (updatedAt.asKnown().isPresent) 1 else 0) + + class AllowedSource @JsonCreator private constructor(private val value: JsonField) : + Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val CDSL = of("cdsl") + + @JvmField val NSDL = of("nsdl") + + @JvmField val CAMS = of("cams") + + @JvmField val KFINTECH = of("kfintech") + + @JvmStatic fun of(value: String) = AllowedSource(JsonField.of(value)) + } + + /** An enum containing [AllowedSource]'s known values. */ + enum class Known { + CDSL, + NSDL, + CAMS, + KFINTECH, + } + + /** + * An enum containing [AllowedSource]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [AllowedSource] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + CDSL, + NSDL, + CAMS, + KFINTECH, + /** + * An enum member indicating that [AllowedSource] was instantiated with an unknown + * value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + CDSL -> Value.CDSL + NSDL -> Value.NSDL + CAMS -> Value.CAMS + KFINTECH -> Value.KFINTECH + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws CasParserInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + CDSL -> Known.CDSL + NSDL -> Known.NSDL + CAMS -> Known.CAMS + KFINTECH -> Known.KFINTECH + else -> throw CasParserInvalidDataException("Unknown AllowedSource: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws CasParserInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CasParserInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): AllowedSource = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AllowedSource && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** Custom key-value metadata */ + class Metadata + @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 [Metadata]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Metadata]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(metadata: Metadata) = apply { + additionalProperties = metadata.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 [Metadata]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Metadata = Metadata(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): Metadata = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 Metadata && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Metadata{additionalProperties=$additionalProperties}" + } + + /** Current mailbox status */ + class Status @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val ACTIVE = of("active") + + @JvmField val PAUSED = of("paused") + + @JvmStatic fun of(value: String) = Status(JsonField.of(value)) + } + + /** An enum containing [Status]'s known values. */ + enum class Known { + ACTIVE, + PAUSED, + } + + /** + * An enum containing [Status]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Status] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + ACTIVE, + PAUSED, + /** An enum member indicating that [Status] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + ACTIVE -> Value.ACTIVE + PAUSED -> Value.PAUSED + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws CasParserInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + ACTIVE -> Known.ACTIVE + PAUSED -> Known.PAUSED + else -> throw CasParserInvalidDataException("Unknown Status: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws CasParserInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CasParserInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): Status = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Status && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is InboundEmailCreateResponse && + allowedSources == other.allowedSources && + callbackUrl == other.callbackUrl && + createdAt == other.createdAt && + email == other.email && + inboundEmailId == other.inboundEmailId && + metadata == other.metadata && + reference == other.reference && + status == other.status && + updatedAt == other.updatedAt && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + allowedSources, + callbackUrl, + createdAt, + email, + inboundEmailId, + metadata, + reference, + status, + updatedAt, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "InboundEmailCreateResponse{allowedSources=$allowedSources, callbackUrl=$callbackUrl, createdAt=$createdAt, email=$email, inboundEmailId=$inboundEmailId, metadata=$metadata, reference=$reference, status=$status, updatedAt=$updatedAt, additionalProperties=$additionalProperties}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailDeleteParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailDeleteParams.kt new file mode 100644 index 0000000..1546fbf --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailDeleteParams.kt @@ -0,0 +1,241 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.inboundemail + +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.Params +import com.cas_parser.api.core.http.Headers +import com.cas_parser.api.core.http.QueryParams +import com.cas_parser.api.core.toImmutable +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * Permanently delete an inbound email address. It will stop accepting emails. + * + * **Note:** Deletion is immediate and cannot be undone. Any emails received after deletion will be + * rejected. + */ +class InboundEmailDeleteParams +private constructor( + private val inboundEmailId: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, + private val additionalBodyProperties: Map, +) : Params { + + fun inboundEmailId(): Optional = Optional.ofNullable(inboundEmailId) + + /** Additional body properties to send with the request. */ + fun _additionalBodyProperties(): Map = additionalBodyProperties + + /** 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 { + + @JvmStatic fun none(): InboundEmailDeleteParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [InboundEmailDeleteParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [InboundEmailDeleteParams]. */ + class Builder internal constructor() { + + private var inboundEmailId: String? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + private var additionalBodyProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(inboundEmailDeleteParams: InboundEmailDeleteParams) = apply { + inboundEmailId = inboundEmailDeleteParams.inboundEmailId + additionalHeaders = inboundEmailDeleteParams.additionalHeaders.toBuilder() + additionalQueryParams = inboundEmailDeleteParams.additionalQueryParams.toBuilder() + additionalBodyProperties = + inboundEmailDeleteParams.additionalBodyProperties.toMutableMap() + } + + fun inboundEmailId(inboundEmailId: String?) = apply { this.inboundEmailId = inboundEmailId } + + /** Alias for calling [Builder.inboundEmailId] with `inboundEmailId.orElse(null)`. */ + fun inboundEmailId(inboundEmailId: Optional) = + inboundEmailId(inboundEmailId.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) + } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + this.additionalBodyProperties.clear() + putAllAdditionalBodyProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + additionalBodyProperties.put(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + this.additionalBodyProperties.putAll(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { + additionalBodyProperties.remove(key) + } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalBodyProperty) + } + + /** + * Returns an immutable instance of [InboundEmailDeleteParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): InboundEmailDeleteParams = + InboundEmailDeleteParams( + inboundEmailId, + additionalHeaders.build(), + additionalQueryParams.build(), + additionalBodyProperties.toImmutable(), + ) + } + + fun _body(): Optional> = + Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) + + fun _pathParam(index: Int): String = + when (index) { + 0 -> inboundEmailId ?: "" + 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 InboundEmailDeleteParams && + inboundEmailId == other.inboundEmailId && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams && + additionalBodyProperties == other.additionalBodyProperties + } + + override fun hashCode(): Int = + Objects.hash( + inboundEmailId, + additionalHeaders, + additionalQueryParams, + additionalBodyProperties, + ) + + override fun toString() = + "InboundEmailDeleteParams{inboundEmailId=$inboundEmailId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailDeleteResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailDeleteResponse.kt new file mode 100644 index 0000000..332967a --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailDeleteResponse.kt @@ -0,0 +1,186 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.inboundemail + +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonField +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.errors.CasParserInvalidDataException +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 + +class InboundEmailDeleteResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val msg: JsonField, + private val status: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("msg") @ExcludeMissing msg: JsonField = JsonMissing.of(), + @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(), + ) : this(msg, status, mutableMapOf()) + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun msg(): Optional = msg.getOptional("msg") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun status(): Optional = status.getOptional("status") + + /** + * Returns the raw JSON value of [msg]. + * + * Unlike [msg], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("msg") @ExcludeMissing fun _msg(): JsonField = msg + + /** + * Returns the raw JSON value of [status]. + * + * Unlike [status], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("status") @ExcludeMissing fun _status(): JsonField = status + + @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 [InboundEmailDeleteResponse]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [InboundEmailDeleteResponse]. */ + class Builder internal constructor() { + + private var msg: JsonField = JsonMissing.of() + private var status: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(inboundEmailDeleteResponse: InboundEmailDeleteResponse) = apply { + msg = inboundEmailDeleteResponse.msg + status = inboundEmailDeleteResponse.status + additionalProperties = inboundEmailDeleteResponse.additionalProperties.toMutableMap() + } + + fun msg(msg: String) = msg(JsonField.of(msg)) + + /** + * Sets [Builder.msg] to an arbitrary JSON value. + * + * You should usually call [Builder.msg] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun msg(msg: JsonField) = apply { this.msg = msg } + + fun status(status: String) = status(JsonField.of(status)) + + /** + * Sets [Builder.status] to an arbitrary JSON value. + * + * You should usually call [Builder.status] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun status(status: JsonField) = apply { this.status = status } + + 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 [InboundEmailDeleteResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): InboundEmailDeleteResponse = + InboundEmailDeleteResponse(msg, status, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): InboundEmailDeleteResponse = apply { + if (validated) { + return@apply + } + + msg() + status() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (msg.asKnown().isPresent) 1 else 0) + (if (status.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is InboundEmailDeleteResponse && + msg == other.msg && + status == other.status && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(msg, status, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "InboundEmailDeleteResponse{msg=$msg, status=$status, additionalProperties=$additionalProperties}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailListParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailListParams.kt new file mode 100644 index 0000000..aea16e2 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailListParams.kt @@ -0,0 +1,381 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.inboundemail + +import com.cas_parser.api.core.Enum +import com.cas_parser.api.core.JsonField +import com.cas_parser.api.core.Params +import com.cas_parser.api.core.http.Headers +import com.cas_parser.api.core.http.QueryParams +import com.cas_parser.api.errors.CasParserInvalidDataException +import com.fasterxml.jackson.annotation.JsonCreator +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * List all mailboxes associated with your API key. Returns active and inactive mailboxes (deleted + * mailboxes are excluded). + */ +class InboundEmailListParams +private constructor( + private val limit: Long?, + private val offset: Long?, + private val status: Status?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** Maximum number of inbound emails to return */ + fun limit(): Optional = Optional.ofNullable(limit) + + /** Pagination offset */ + fun offset(): Optional = Optional.ofNullable(offset) + + /** Filter by status */ + fun status(): Optional = Optional.ofNullable(status) + + /** 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 { + + @JvmStatic fun none(): InboundEmailListParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [InboundEmailListParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [InboundEmailListParams]. */ + class Builder internal constructor() { + + private var limit: Long? = null + private var offset: Long? = null + private var status: Status? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(inboundEmailListParams: InboundEmailListParams) = apply { + limit = inboundEmailListParams.limit + offset = inboundEmailListParams.offset + status = inboundEmailListParams.status + additionalHeaders = inboundEmailListParams.additionalHeaders.toBuilder() + additionalQueryParams = inboundEmailListParams.additionalQueryParams.toBuilder() + } + + /** Maximum number of inbound emails to return */ + fun limit(limit: Long?) = apply { this.limit = limit } + + /** + * Alias for [Builder.limit]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun limit(limit: Long) = limit(limit as Long?) + + /** Alias for calling [Builder.limit] with `limit.orElse(null)`. */ + fun limit(limit: Optional) = limit(limit.getOrNull()) + + /** Pagination offset */ + fun offset(offset: Long?) = apply { this.offset = offset } + + /** + * Alias for [Builder.offset]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun offset(offset: Long) = offset(offset as Long?) + + /** Alias for calling [Builder.offset] with `offset.orElse(null)`. */ + fun offset(offset: Optional) = offset(offset.getOrNull()) + + /** Filter by status */ + fun status(status: Status?) = apply { this.status = status } + + /** Alias for calling [Builder.status] with `status.orElse(null)`. */ + fun status(status: Optional) = status(status.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 [InboundEmailListParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): InboundEmailListParams = + InboundEmailListParams( + limit, + offset, + status, + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + limit?.let { put("limit", it.toString()) } + offset?.let { put("offset", it.toString()) } + status?.let { put("status", it.toString()) } + putAll(additionalQueryParams) + } + .build() + + /** Filter by status */ + class Status @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val ACTIVE = of("active") + + @JvmField val PAUSED = of("paused") + + @JvmField val ALL = of("all") + + @JvmStatic fun of(value: String) = Status(JsonField.of(value)) + } + + /** An enum containing [Status]'s known values. */ + enum class Known { + ACTIVE, + PAUSED, + ALL, + } + + /** + * An enum containing [Status]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Status] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + ACTIVE, + PAUSED, + ALL, + /** An enum member indicating that [Status] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + ACTIVE -> Value.ACTIVE + PAUSED -> Value.PAUSED + ALL -> Value.ALL + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws CasParserInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + ACTIVE -> Known.ACTIVE + PAUSED -> Known.PAUSED + ALL -> Known.ALL + else -> throw CasParserInvalidDataException("Unknown Status: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws CasParserInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CasParserInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): Status = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Status && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is InboundEmailListParams && + limit == other.limit && + offset == other.offset && + status == other.status && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(limit, offset, status, additionalHeaders, additionalQueryParams) + + override fun toString() = + "InboundEmailListParams{limit=$limit, offset=$offset, status=$status, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailListResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailListResponse.kt new file mode 100644 index 0000000..12c0e54 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailListResponse.kt @@ -0,0 +1,1194 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.inboundemail + +import com.cas_parser.api.core.Enum +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonField +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.checkKnown +import com.cas_parser.api.core.toImmutable +import com.cas_parser.api.errors.CasParserInvalidDataException +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.time.OffsetDateTime +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +class InboundEmailListResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val inboundEmails: JsonField>, + private val limit: JsonField, + private val offset: JsonField, + private val status: JsonField, + private val total: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("inbound_emails") + @ExcludeMissing + inboundEmails: JsonField> = JsonMissing.of(), + @JsonProperty("limit") @ExcludeMissing limit: JsonField = JsonMissing.of(), + @JsonProperty("offset") @ExcludeMissing offset: JsonField = JsonMissing.of(), + @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(), + @JsonProperty("total") @ExcludeMissing total: JsonField = JsonMissing.of(), + ) : this(inboundEmails, limit, offset, status, total, mutableMapOf()) + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun inboundEmails(): Optional> = inboundEmails.getOptional("inbound_emails") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun limit(): Optional = limit.getOptional("limit") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun offset(): Optional = offset.getOptional("offset") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun status(): Optional = status.getOptional("status") + + /** + * Total number of inbound emails (for pagination) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun total(): Optional = total.getOptional("total") + + /** + * Returns the raw JSON value of [inboundEmails]. + * + * Unlike [inboundEmails], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("inbound_emails") + @ExcludeMissing + fun _inboundEmails(): JsonField> = inboundEmails + + /** + * Returns the raw JSON value of [limit]. + * + * Unlike [limit], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("limit") @ExcludeMissing fun _limit(): JsonField = limit + + /** + * Returns the raw JSON value of [offset]. + * + * Unlike [offset], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("offset") @ExcludeMissing fun _offset(): JsonField = offset + + /** + * Returns the raw JSON value of [status]. + * + * Unlike [status], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("status") @ExcludeMissing fun _status(): JsonField = status + + /** + * Returns the raw JSON value of [total]. + * + * Unlike [total], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("total") @ExcludeMissing fun _total(): JsonField = total + + @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 [InboundEmailListResponse]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [InboundEmailListResponse]. */ + class Builder internal constructor() { + + private var inboundEmails: JsonField>? = null + private var limit: JsonField = JsonMissing.of() + private var offset: JsonField = JsonMissing.of() + private var status: JsonField = JsonMissing.of() + private var total: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(inboundEmailListResponse: InboundEmailListResponse) = apply { + inboundEmails = inboundEmailListResponse.inboundEmails.map { it.toMutableList() } + limit = inboundEmailListResponse.limit + offset = inboundEmailListResponse.offset + status = inboundEmailListResponse.status + total = inboundEmailListResponse.total + additionalProperties = inboundEmailListResponse.additionalProperties.toMutableMap() + } + + fun inboundEmails(inboundEmails: List) = + inboundEmails(JsonField.of(inboundEmails)) + + /** + * Sets [Builder.inboundEmails] to an arbitrary JSON value. + * + * You should usually call [Builder.inboundEmails] with a well-typed `List` + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun inboundEmails(inboundEmails: JsonField>) = apply { + this.inboundEmails = inboundEmails.map { it.toMutableList() } + } + + /** + * Adds a single [InboundEmail] to [inboundEmails]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addInboundEmail(inboundEmail: InboundEmail) = apply { + inboundEmails = + (inboundEmails ?: JsonField.of(mutableListOf())).also { + checkKnown("inboundEmails", it).add(inboundEmail) + } + } + + fun limit(limit: Long) = limit(JsonField.of(limit)) + + /** + * Sets [Builder.limit] to an arbitrary JSON value. + * + * You should usually call [Builder.limit] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun limit(limit: JsonField) = apply { this.limit = limit } + + fun offset(offset: Long) = offset(JsonField.of(offset)) + + /** + * Sets [Builder.offset] to an arbitrary JSON value. + * + * You should usually call [Builder.offset] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun offset(offset: JsonField) = apply { this.offset = offset } + + fun status(status: String) = status(JsonField.of(status)) + + /** + * Sets [Builder.status] to an arbitrary JSON value. + * + * You should usually call [Builder.status] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun status(status: JsonField) = apply { this.status = status } + + /** Total number of inbound emails (for pagination) */ + fun total(total: Long) = total(JsonField.of(total)) + + /** + * Sets [Builder.total] to an arbitrary JSON value. + * + * You should usually call [Builder.total] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun total(total: JsonField) = apply { this.total = total } + + 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 [InboundEmailListResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): InboundEmailListResponse = + InboundEmailListResponse( + (inboundEmails ?: JsonMissing.of()).map { it.toImmutable() }, + limit, + offset, + status, + total, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): InboundEmailListResponse = apply { + if (validated) { + return@apply + } + + inboundEmails().ifPresent { it.forEach { it.validate() } } + limit() + offset() + status() + total() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 = + (inboundEmails.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (limit.asKnown().isPresent) 1 else 0) + + (if (offset.asKnown().isPresent) 1 else 0) + + (if (status.asKnown().isPresent) 1 else 0) + + (if (total.asKnown().isPresent) 1 else 0) + + /** An inbound email address for receiving forwarded CAS emails */ + class InboundEmail + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val allowedSources: JsonField>, + private val callbackUrl: JsonField, + private val createdAt: JsonField, + private val email: JsonField, + private val inboundEmailId: JsonField, + private val metadata: JsonField, + private val reference: JsonField, + private val status: JsonField, + private val updatedAt: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("allowed_sources") + @ExcludeMissing + allowedSources: JsonField> = JsonMissing.of(), + @JsonProperty("callback_url") + @ExcludeMissing + callbackUrl: JsonField = JsonMissing.of(), + @JsonProperty("created_at") + @ExcludeMissing + createdAt: JsonField = JsonMissing.of(), + @JsonProperty("email") @ExcludeMissing email: JsonField = JsonMissing.of(), + @JsonProperty("inbound_email_id") + @ExcludeMissing + inboundEmailId: JsonField = JsonMissing.of(), + @JsonProperty("metadata") + @ExcludeMissing + metadata: JsonField = JsonMissing.of(), + @JsonProperty("reference") + @ExcludeMissing + reference: JsonField = JsonMissing.of(), + @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(), + @JsonProperty("updated_at") + @ExcludeMissing + updatedAt: JsonField = JsonMissing.of(), + ) : this( + allowedSources, + callbackUrl, + createdAt, + email, + inboundEmailId, + metadata, + reference, + status, + updatedAt, + mutableMapOf(), + ) + + /** + * Accepted CAS providers (empty = all) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun allowedSources(): Optional> = + allowedSources.getOptional("allowed_sources") + + /** + * Webhook URL for email notifications + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun callbackUrl(): Optional = callbackUrl.getOptional("callback_url") + + /** + * When the mailbox was created + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun createdAt(): Optional = createdAt.getOptional("created_at") + + /** + * The inbound email address to forward CAS statements to + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun email(): Optional = email.getOptional("email") + + /** + * Unique inbound email identifier + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun inboundEmailId(): Optional = inboundEmailId.getOptional("inbound_email_id") + + /** + * Custom key-value metadata + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun metadata(): Optional = metadata.getOptional("metadata") + + /** + * Your internal reference identifier + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun reference(): Optional = reference.getOptional("reference") + + /** + * Current mailbox status + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun status(): Optional = status.getOptional("status") + + /** + * When the mailbox was last updated + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun updatedAt(): Optional = updatedAt.getOptional("updated_at") + + /** + * Returns the raw JSON value of [allowedSources]. + * + * Unlike [allowedSources], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("allowed_sources") + @ExcludeMissing + fun _allowedSources(): JsonField> = allowedSources + + /** + * Returns the raw JSON value of [callbackUrl]. + * + * Unlike [callbackUrl], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("callback_url") + @ExcludeMissing + fun _callbackUrl(): JsonField = callbackUrl + + /** + * Returns the raw JSON value of [createdAt]. + * + * Unlike [createdAt], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created_at") + @ExcludeMissing + fun _createdAt(): JsonField = createdAt + + /** + * Returns the raw JSON value of [email]. + * + * Unlike [email], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("email") @ExcludeMissing fun _email(): JsonField = email + + /** + * Returns the raw JSON value of [inboundEmailId]. + * + * Unlike [inboundEmailId], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("inbound_email_id") + @ExcludeMissing + fun _inboundEmailId(): JsonField = inboundEmailId + + /** + * Returns the raw JSON value of [metadata]. + * + * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("metadata") @ExcludeMissing fun _metadata(): JsonField = metadata + + /** + * Returns the raw JSON value of [reference]. + * + * Unlike [reference], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("reference") @ExcludeMissing fun _reference(): JsonField = reference + + /** + * Returns the raw JSON value of [status]. + * + * Unlike [status], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("status") @ExcludeMissing fun _status(): JsonField = status + + /** + * Returns the raw JSON value of [updatedAt]. + * + * Unlike [updatedAt], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("updated_at") + @ExcludeMissing + fun _updatedAt(): JsonField = updatedAt + + @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 [InboundEmail]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [InboundEmail]. */ + class Builder internal constructor() { + + private var allowedSources: JsonField>? = null + private var callbackUrl: JsonField = JsonMissing.of() + private var createdAt: JsonField = JsonMissing.of() + private var email: JsonField = JsonMissing.of() + private var inboundEmailId: JsonField = JsonMissing.of() + private var metadata: JsonField = JsonMissing.of() + private var reference: JsonField = JsonMissing.of() + private var status: JsonField = JsonMissing.of() + private var updatedAt: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(inboundEmail: InboundEmail) = apply { + allowedSources = inboundEmail.allowedSources.map { it.toMutableList() } + callbackUrl = inboundEmail.callbackUrl + createdAt = inboundEmail.createdAt + email = inboundEmail.email + inboundEmailId = inboundEmail.inboundEmailId + metadata = inboundEmail.metadata + reference = inboundEmail.reference + status = inboundEmail.status + updatedAt = inboundEmail.updatedAt + additionalProperties = inboundEmail.additionalProperties.toMutableMap() + } + + /** Accepted CAS providers (empty = all) */ + fun allowedSources(allowedSources: List) = + allowedSources(JsonField.of(allowedSources)) + + /** + * Sets [Builder.allowedSources] to an arbitrary JSON value. + * + * You should usually call [Builder.allowedSources] with a well-typed + * `List` value instead. This method is primarily for setting the field + * to an undocumented or not yet supported value. + */ + fun allowedSources(allowedSources: JsonField>) = apply { + this.allowedSources = allowedSources.map { it.toMutableList() } + } + + /** + * Adds a single [AllowedSource] to [allowedSources]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addAllowedSource(allowedSource: AllowedSource) = apply { + allowedSources = + (allowedSources ?: JsonField.of(mutableListOf())).also { + checkKnown("allowedSources", it).add(allowedSource) + } + } + + /** Webhook URL for email notifications */ + fun callbackUrl(callbackUrl: String) = callbackUrl(JsonField.of(callbackUrl)) + + /** + * Sets [Builder.callbackUrl] to an arbitrary JSON value. + * + * You should usually call [Builder.callbackUrl] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun callbackUrl(callbackUrl: JsonField) = apply { + this.callbackUrl = callbackUrl + } + + /** When the mailbox was created */ + fun createdAt(createdAt: OffsetDateTime) = createdAt(JsonField.of(createdAt)) + + /** + * Sets [Builder.createdAt] to an arbitrary JSON value. + * + * You should usually call [Builder.createdAt] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun createdAt(createdAt: JsonField) = apply { + this.createdAt = createdAt + } + + /** The inbound email address to forward CAS statements to */ + fun email(email: String) = email(JsonField.of(email)) + + /** + * Sets [Builder.email] to an arbitrary JSON value. + * + * You should usually call [Builder.email] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun email(email: JsonField) = apply { this.email = email } + + /** Unique inbound email identifier */ + fun inboundEmailId(inboundEmailId: String) = + inboundEmailId(JsonField.of(inboundEmailId)) + + /** + * Sets [Builder.inboundEmailId] to an arbitrary JSON value. + * + * You should usually call [Builder.inboundEmailId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun inboundEmailId(inboundEmailId: JsonField) = apply { + this.inboundEmailId = inboundEmailId + } + + /** Custom key-value metadata */ + fun metadata(metadata: Metadata) = metadata(JsonField.of(metadata)) + + /** + * Sets [Builder.metadata] to an arbitrary JSON value. + * + * You should usually call [Builder.metadata] with a well-typed [Metadata] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun metadata(metadata: JsonField) = apply { this.metadata = metadata } + + /** Your internal reference identifier */ + fun reference(reference: String?) = reference(JsonField.ofNullable(reference)) + + /** Alias for calling [Builder.reference] with `reference.orElse(null)`. */ + fun reference(reference: Optional) = reference(reference.getOrNull()) + + /** + * Sets [Builder.reference] to an arbitrary JSON value. + * + * You should usually call [Builder.reference] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun reference(reference: JsonField) = apply { this.reference = reference } + + /** Current mailbox status */ + fun status(status: Status) = status(JsonField.of(status)) + + /** + * Sets [Builder.status] to an arbitrary JSON value. + * + * You should usually call [Builder.status] with a well-typed [Status] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun status(status: JsonField) = apply { this.status = status } + + /** When the mailbox was last updated */ + fun updatedAt(updatedAt: OffsetDateTime) = updatedAt(JsonField.of(updatedAt)) + + /** + * Sets [Builder.updatedAt] to an arbitrary JSON value. + * + * You should usually call [Builder.updatedAt] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun updatedAt(updatedAt: JsonField) = apply { + this.updatedAt = updatedAt + } + + 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 [InboundEmail]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): InboundEmail = + InboundEmail( + (allowedSources ?: JsonMissing.of()).map { it.toImmutable() }, + callbackUrl, + createdAt, + email, + inboundEmailId, + metadata, + reference, + status, + updatedAt, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): InboundEmail = apply { + if (validated) { + return@apply + } + + allowedSources().ifPresent { it.forEach { it.validate() } } + callbackUrl() + createdAt() + email() + inboundEmailId() + metadata().ifPresent { it.validate() } + reference() + status().ifPresent { it.validate() } + updatedAt() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 = + (allowedSources.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (callbackUrl.asKnown().isPresent) 1 else 0) + + (if (createdAt.asKnown().isPresent) 1 else 0) + + (if (email.asKnown().isPresent) 1 else 0) + + (if (inboundEmailId.asKnown().isPresent) 1 else 0) + + (metadata.asKnown().getOrNull()?.validity() ?: 0) + + (if (reference.asKnown().isPresent) 1 else 0) + + (status.asKnown().getOrNull()?.validity() ?: 0) + + (if (updatedAt.asKnown().isPresent) 1 else 0) + + class AllowedSource @JsonCreator private constructor(private val value: JsonField) : + Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is + * on an older version than the API, then the API may respond with new members that the + * SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val CDSL = of("cdsl") + + @JvmField val NSDL = of("nsdl") + + @JvmField val CAMS = of("cams") + + @JvmField val KFINTECH = of("kfintech") + + @JvmStatic fun of(value: String) = AllowedSource(JsonField.of(value)) + } + + /** An enum containing [AllowedSource]'s known values. */ + enum class Known { + CDSL, + NSDL, + CAMS, + KFINTECH, + } + + /** + * An enum containing [AllowedSource]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [AllowedSource] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if + * the SDK is on an older version than the API, then the API may respond with new + * members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + CDSL, + NSDL, + CAMS, + KFINTECH, + /** + * An enum member indicating that [AllowedSource] was instantiated with an unknown + * value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you + * want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + CDSL -> Value.CDSL + NSDL -> Value.NSDL + CAMS -> Value.CAMS + KFINTECH -> Value.KFINTECH + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and + * don't want to throw for the unknown case. + * + * @throws CasParserInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + CDSL -> Known.CDSL + NSDL -> Known.NSDL + CAMS -> Known.CAMS + KFINTECH -> Known.KFINTECH + else -> throw CasParserInvalidDataException("Unknown AllowedSource: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws CasParserInvalidDataException if this class instance's value does not have + * the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CasParserInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): AllowedSource = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AllowedSource && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** Custom key-value metadata */ + class Metadata + @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 [Metadata]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Metadata]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(metadata: Metadata) = apply { + additionalProperties = metadata.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 [Metadata]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Metadata = Metadata(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): Metadata = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 Metadata && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Metadata{additionalProperties=$additionalProperties}" + } + + /** Current mailbox status */ + class Status @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is + * on an older version than the API, then the API may respond with new members that the + * SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val ACTIVE = of("active") + + @JvmField val PAUSED = of("paused") + + @JvmStatic fun of(value: String) = Status(JsonField.of(value)) + } + + /** An enum containing [Status]'s known values. */ + enum class Known { + ACTIVE, + PAUSED, + } + + /** + * An enum containing [Status]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Status] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if + * the SDK is on an older version than the API, then the API may respond with new + * members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + ACTIVE, + PAUSED, + /** + * An enum member indicating that [Status] was instantiated with an unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you + * want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + ACTIVE -> Value.ACTIVE + PAUSED -> Value.PAUSED + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and + * don't want to throw for the unknown case. + * + * @throws CasParserInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + ACTIVE -> Known.ACTIVE + PAUSED -> Known.PAUSED + else -> throw CasParserInvalidDataException("Unknown Status: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws CasParserInvalidDataException if this class instance's value does not have + * the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CasParserInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): Status = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Status && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is InboundEmail && + allowedSources == other.allowedSources && + callbackUrl == other.callbackUrl && + createdAt == other.createdAt && + email == other.email && + inboundEmailId == other.inboundEmailId && + metadata == other.metadata && + reference == other.reference && + status == other.status && + updatedAt == other.updatedAt && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + allowedSources, + callbackUrl, + createdAt, + email, + inboundEmailId, + metadata, + reference, + status, + updatedAt, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "InboundEmail{allowedSources=$allowedSources, callbackUrl=$callbackUrl, createdAt=$createdAt, email=$email, inboundEmailId=$inboundEmailId, metadata=$metadata, reference=$reference, status=$status, updatedAt=$updatedAt, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is InboundEmailListResponse && + inboundEmails == other.inboundEmails && + limit == other.limit && + offset == other.offset && + status == other.status && + total == other.total && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(inboundEmails, limit, offset, status, total, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "InboundEmailListResponse{inboundEmails=$inboundEmails, limit=$limit, offset=$offset, status=$status, total=$total, additionalProperties=$additionalProperties}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailRetrieveParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailRetrieveParams.kt new file mode 100644 index 0000000..1c0676b --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailRetrieveParams.kt @@ -0,0 +1,197 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.inboundemail + +import com.cas_parser.api.core.Params +import com.cas_parser.api.core.http.Headers +import com.cas_parser.api.core.http.QueryParams +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Retrieve details of a specific mailbox including statistics. */ +class InboundEmailRetrieveParams +private constructor( + private val inboundEmailId: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun inboundEmailId(): Optional = Optional.ofNullable(inboundEmailId) + + /** 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 { + + @JvmStatic fun none(): InboundEmailRetrieveParams = builder().build() + + /** + * Returns a mutable builder for constructing an instance of [InboundEmailRetrieveParams]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [InboundEmailRetrieveParams]. */ + class Builder internal constructor() { + + private var inboundEmailId: String? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(inboundEmailRetrieveParams: InboundEmailRetrieveParams) = apply { + inboundEmailId = inboundEmailRetrieveParams.inboundEmailId + additionalHeaders = inboundEmailRetrieveParams.additionalHeaders.toBuilder() + additionalQueryParams = inboundEmailRetrieveParams.additionalQueryParams.toBuilder() + } + + fun inboundEmailId(inboundEmailId: String?) = apply { this.inboundEmailId = inboundEmailId } + + /** Alias for calling [Builder.inboundEmailId] with `inboundEmailId.orElse(null)`. */ + fun inboundEmailId(inboundEmailId: Optional) = + inboundEmailId(inboundEmailId.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 [InboundEmailRetrieveParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): InboundEmailRetrieveParams = + InboundEmailRetrieveParams( + inboundEmailId, + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _pathParam(index: Int): String = + when (index) { + 0 -> inboundEmailId ?: "" + 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 InboundEmailRetrieveParams && + inboundEmailId == other.inboundEmailId && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(inboundEmailId, additionalHeaders, additionalQueryParams) + + override fun toString() = + "InboundEmailRetrieveParams{inboundEmailId=$inboundEmailId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailRetrieveResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailRetrieveResponse.kt new file mode 100644 index 0000000..c997bf9 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailRetrieveResponse.kt @@ -0,0 +1,884 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.inboundemail + +import com.cas_parser.api.core.Enum +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonField +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.checkKnown +import com.cas_parser.api.core.toImmutable +import com.cas_parser.api.errors.CasParserInvalidDataException +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.time.OffsetDateTime +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** An inbound email address for receiving forwarded CAS emails */ +class InboundEmailRetrieveResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val allowedSources: JsonField>, + private val callbackUrl: JsonField, + private val createdAt: JsonField, + private val email: JsonField, + private val inboundEmailId: JsonField, + private val metadata: JsonField, + private val reference: JsonField, + private val status: JsonField, + private val updatedAt: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("allowed_sources") + @ExcludeMissing + allowedSources: JsonField> = JsonMissing.of(), + @JsonProperty("callback_url") + @ExcludeMissing + callbackUrl: JsonField = JsonMissing.of(), + @JsonProperty("created_at") + @ExcludeMissing + createdAt: JsonField = JsonMissing.of(), + @JsonProperty("email") @ExcludeMissing email: JsonField = JsonMissing.of(), + @JsonProperty("inbound_email_id") + @ExcludeMissing + inboundEmailId: JsonField = JsonMissing.of(), + @JsonProperty("metadata") @ExcludeMissing metadata: JsonField = JsonMissing.of(), + @JsonProperty("reference") @ExcludeMissing reference: JsonField = JsonMissing.of(), + @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(), + @JsonProperty("updated_at") + @ExcludeMissing + updatedAt: JsonField = JsonMissing.of(), + ) : this( + allowedSources, + callbackUrl, + createdAt, + email, + inboundEmailId, + metadata, + reference, + status, + updatedAt, + mutableMapOf(), + ) + + /** + * Accepted CAS providers (empty = all) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun allowedSources(): Optional> = + allowedSources.getOptional("allowed_sources") + + /** + * Webhook URL for email notifications + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun callbackUrl(): Optional = callbackUrl.getOptional("callback_url") + + /** + * When the mailbox was created + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun createdAt(): Optional = createdAt.getOptional("created_at") + + /** + * The inbound email address to forward CAS statements to + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun email(): Optional = email.getOptional("email") + + /** + * Unique inbound email identifier + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun inboundEmailId(): Optional = inboundEmailId.getOptional("inbound_email_id") + + /** + * Custom key-value metadata + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun metadata(): Optional = metadata.getOptional("metadata") + + /** + * Your internal reference identifier + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun reference(): Optional = reference.getOptional("reference") + + /** + * Current mailbox status + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun status(): Optional = status.getOptional("status") + + /** + * When the mailbox was last updated + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun updatedAt(): Optional = updatedAt.getOptional("updated_at") + + /** + * Returns the raw JSON value of [allowedSources]. + * + * Unlike [allowedSources], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("allowed_sources") + @ExcludeMissing + fun _allowedSources(): JsonField> = allowedSources + + /** + * Returns the raw JSON value of [callbackUrl]. + * + * Unlike [callbackUrl], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("callback_url") + @ExcludeMissing + fun _callbackUrl(): JsonField = callbackUrl + + /** + * Returns the raw JSON value of [createdAt]. + * + * Unlike [createdAt], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created_at") + @ExcludeMissing + fun _createdAt(): JsonField = createdAt + + /** + * Returns the raw JSON value of [email]. + * + * Unlike [email], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("email") @ExcludeMissing fun _email(): JsonField = email + + /** + * Returns the raw JSON value of [inboundEmailId]. + * + * Unlike [inboundEmailId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("inbound_email_id") + @ExcludeMissing + fun _inboundEmailId(): JsonField = inboundEmailId + + /** + * Returns the raw JSON value of [metadata]. + * + * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("metadata") @ExcludeMissing fun _metadata(): JsonField = metadata + + /** + * Returns the raw JSON value of [reference]. + * + * Unlike [reference], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("reference") @ExcludeMissing fun _reference(): JsonField = reference + + /** + * Returns the raw JSON value of [status]. + * + * Unlike [status], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("status") @ExcludeMissing fun _status(): JsonField = status + + /** + * Returns the raw JSON value of [updatedAt]. + * + * Unlike [updatedAt], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("updated_at") + @ExcludeMissing + fun _updatedAt(): JsonField = updatedAt + + @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 [InboundEmailRetrieveResponse]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [InboundEmailRetrieveResponse]. */ + class Builder internal constructor() { + + private var allowedSources: JsonField>? = null + private var callbackUrl: JsonField = JsonMissing.of() + private var createdAt: JsonField = JsonMissing.of() + private var email: JsonField = JsonMissing.of() + private var inboundEmailId: JsonField = JsonMissing.of() + private var metadata: JsonField = JsonMissing.of() + private var reference: JsonField = JsonMissing.of() + private var status: JsonField = JsonMissing.of() + private var updatedAt: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(inboundEmailRetrieveResponse: InboundEmailRetrieveResponse) = apply { + allowedSources = inboundEmailRetrieveResponse.allowedSources.map { it.toMutableList() } + callbackUrl = inboundEmailRetrieveResponse.callbackUrl + createdAt = inboundEmailRetrieveResponse.createdAt + email = inboundEmailRetrieveResponse.email + inboundEmailId = inboundEmailRetrieveResponse.inboundEmailId + metadata = inboundEmailRetrieveResponse.metadata + reference = inboundEmailRetrieveResponse.reference + status = inboundEmailRetrieveResponse.status + updatedAt = inboundEmailRetrieveResponse.updatedAt + additionalProperties = inboundEmailRetrieveResponse.additionalProperties.toMutableMap() + } + + /** Accepted CAS providers (empty = all) */ + fun allowedSources(allowedSources: List) = + allowedSources(JsonField.of(allowedSources)) + + /** + * Sets [Builder.allowedSources] to an arbitrary JSON value. + * + * You should usually call [Builder.allowedSources] with a well-typed `List` + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun allowedSources(allowedSources: JsonField>) = apply { + this.allowedSources = allowedSources.map { it.toMutableList() } + } + + /** + * Adds a single [AllowedSource] to [allowedSources]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addAllowedSource(allowedSource: AllowedSource) = apply { + allowedSources = + (allowedSources ?: JsonField.of(mutableListOf())).also { + checkKnown("allowedSources", it).add(allowedSource) + } + } + + /** Webhook URL for email notifications */ + fun callbackUrl(callbackUrl: String) = callbackUrl(JsonField.of(callbackUrl)) + + /** + * Sets [Builder.callbackUrl] to an arbitrary JSON value. + * + * You should usually call [Builder.callbackUrl] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun callbackUrl(callbackUrl: JsonField) = apply { this.callbackUrl = callbackUrl } + + /** When the mailbox was created */ + fun createdAt(createdAt: OffsetDateTime) = createdAt(JsonField.of(createdAt)) + + /** + * Sets [Builder.createdAt] to an arbitrary JSON value. + * + * You should usually call [Builder.createdAt] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun createdAt(createdAt: JsonField) = apply { this.createdAt = createdAt } + + /** The inbound email address to forward CAS statements to */ + fun email(email: String) = email(JsonField.of(email)) + + /** + * Sets [Builder.email] to an arbitrary JSON value. + * + * You should usually call [Builder.email] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun email(email: JsonField) = apply { this.email = email } + + /** Unique inbound email identifier */ + fun inboundEmailId(inboundEmailId: String) = inboundEmailId(JsonField.of(inboundEmailId)) + + /** + * Sets [Builder.inboundEmailId] to an arbitrary JSON value. + * + * You should usually call [Builder.inboundEmailId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun inboundEmailId(inboundEmailId: JsonField) = apply { + this.inboundEmailId = inboundEmailId + } + + /** Custom key-value metadata */ + fun metadata(metadata: Metadata) = metadata(JsonField.of(metadata)) + + /** + * Sets [Builder.metadata] to an arbitrary JSON value. + * + * You should usually call [Builder.metadata] with a well-typed [Metadata] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun metadata(metadata: JsonField) = apply { this.metadata = metadata } + + /** Your internal reference identifier */ + fun reference(reference: String?) = reference(JsonField.ofNullable(reference)) + + /** Alias for calling [Builder.reference] with `reference.orElse(null)`. */ + fun reference(reference: Optional) = reference(reference.getOrNull()) + + /** + * Sets [Builder.reference] to an arbitrary JSON value. + * + * You should usually call [Builder.reference] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun reference(reference: JsonField) = apply { this.reference = reference } + + /** Current mailbox status */ + fun status(status: Status) = status(JsonField.of(status)) + + /** + * Sets [Builder.status] to an arbitrary JSON value. + * + * You should usually call [Builder.status] with a well-typed [Status] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun status(status: JsonField) = apply { this.status = status } + + /** When the mailbox was last updated */ + fun updatedAt(updatedAt: OffsetDateTime) = updatedAt(JsonField.of(updatedAt)) + + /** + * Sets [Builder.updatedAt] to an arbitrary JSON value. + * + * You should usually call [Builder.updatedAt] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun updatedAt(updatedAt: JsonField) = apply { this.updatedAt = updatedAt } + + 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 [InboundEmailRetrieveResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): InboundEmailRetrieveResponse = + InboundEmailRetrieveResponse( + (allowedSources ?: JsonMissing.of()).map { it.toImmutable() }, + callbackUrl, + createdAt, + email, + inboundEmailId, + metadata, + reference, + status, + updatedAt, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): InboundEmailRetrieveResponse = apply { + if (validated) { + return@apply + } + + allowedSources().ifPresent { it.forEach { it.validate() } } + callbackUrl() + createdAt() + email() + inboundEmailId() + metadata().ifPresent { it.validate() } + reference() + status().ifPresent { it.validate() } + updatedAt() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 = + (allowedSources.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (callbackUrl.asKnown().isPresent) 1 else 0) + + (if (createdAt.asKnown().isPresent) 1 else 0) + + (if (email.asKnown().isPresent) 1 else 0) + + (if (inboundEmailId.asKnown().isPresent) 1 else 0) + + (metadata.asKnown().getOrNull()?.validity() ?: 0) + + (if (reference.asKnown().isPresent) 1 else 0) + + (status.asKnown().getOrNull()?.validity() ?: 0) + + (if (updatedAt.asKnown().isPresent) 1 else 0) + + class AllowedSource @JsonCreator private constructor(private val value: JsonField) : + Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val CDSL = of("cdsl") + + @JvmField val NSDL = of("nsdl") + + @JvmField val CAMS = of("cams") + + @JvmField val KFINTECH = of("kfintech") + + @JvmStatic fun of(value: String) = AllowedSource(JsonField.of(value)) + } + + /** An enum containing [AllowedSource]'s known values. */ + enum class Known { + CDSL, + NSDL, + CAMS, + KFINTECH, + } + + /** + * An enum containing [AllowedSource]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [AllowedSource] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + CDSL, + NSDL, + CAMS, + KFINTECH, + /** + * An enum member indicating that [AllowedSource] was instantiated with an unknown + * value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + CDSL -> Value.CDSL + NSDL -> Value.NSDL + CAMS -> Value.CAMS + KFINTECH -> Value.KFINTECH + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws CasParserInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + CDSL -> Known.CDSL + NSDL -> Known.NSDL + CAMS -> Known.CAMS + KFINTECH -> Known.KFINTECH + else -> throw CasParserInvalidDataException("Unknown AllowedSource: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws CasParserInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CasParserInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): AllowedSource = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AllowedSource && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** Custom key-value metadata */ + class Metadata + @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 [Metadata]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Metadata]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(metadata: Metadata) = apply { + additionalProperties = metadata.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 [Metadata]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Metadata = Metadata(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): Metadata = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 Metadata && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Metadata{additionalProperties=$additionalProperties}" + } + + /** Current mailbox status */ + class Status @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val ACTIVE = of("active") + + @JvmField val PAUSED = of("paused") + + @JvmStatic fun of(value: String) = Status(JsonField.of(value)) + } + + /** An enum containing [Status]'s known values. */ + enum class Known { + ACTIVE, + PAUSED, + } + + /** + * An enum containing [Status]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Status] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + ACTIVE, + PAUSED, + /** An enum member indicating that [Status] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + ACTIVE -> Value.ACTIVE + PAUSED -> Value.PAUSED + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws CasParserInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + ACTIVE -> Known.ACTIVE + PAUSED -> Known.PAUSED + else -> throw CasParserInvalidDataException("Unknown Status: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws CasParserInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CasParserInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): Status = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Status && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is InboundEmailRetrieveResponse && + allowedSources == other.allowedSources && + callbackUrl == other.callbackUrl && + createdAt == other.createdAt && + email == other.email && + inboundEmailId == other.inboundEmailId && + metadata == other.metadata && + reference == other.reference && + status == other.status && + updatedAt == other.updatedAt && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + allowedSources, + callbackUrl, + createdAt, + email, + inboundEmailId, + metadata, + reference, + status, + updatedAt, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "InboundEmailRetrieveResponse{allowedSources=$allowedSources, callbackUrl=$callbackUrl, createdAt=$createdAt, email=$email, inboundEmailId=$inboundEmailId, metadata=$metadata, reference=$reference, status=$status, updatedAt=$updatedAt, additionalProperties=$additionalProperties}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogCreateParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogCreateParams.kt new file mode 100644 index 0000000..b5db085 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogCreateParams.kt @@ -0,0 +1,530 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.logs + +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonField +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.Params +import com.cas_parser.api.core.http.Headers +import com.cas_parser.api.core.http.QueryParams +import com.cas_parser.api.errors.CasParserInvalidDataException +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.time.OffsetDateTime +import java.util.Collections +import java.util.Objects +import java.util.Optional + +/** + * Retrieve detailed API usage logs for your account. + * + * Returns a list of API calls with timestamps, features used, status codes, and credits consumed. + * Useful for monitoring usage patterns and debugging. + * + * **Legacy path:** `/logs` (still supported) + */ +class LogCreateParams +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * End time filter (ISO 8601). Defaults to now. + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun endTime(): Optional = body.endTime() + + /** + * Maximum number of logs to return + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun limit(): Optional = body.limit() + + /** + * Start time filter (ISO 8601). Defaults to 30 days ago. + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun startTime(): Optional = body.startTime() + + /** + * Returns the raw JSON value of [endTime]. + * + * Unlike [endTime], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _endTime(): JsonField = body._endTime() + + /** + * Returns the raw JSON value of [limit]. + * + * Unlike [limit], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _limit(): JsonField = body._limit() + + /** + * Returns the raw JSON value of [startTime]. + * + * Unlike [startTime], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _startTime(): JsonField = body._startTime() + + fun _additionalBodyProperties(): Map = body._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 { + + @JvmStatic fun none(): LogCreateParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [LogCreateParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [LogCreateParams]. */ + class Builder internal constructor() { + + private var body: Body.Builder = Body.builder() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(logCreateParams: LogCreateParams) = apply { + body = logCreateParams.body.toBuilder() + additionalHeaders = logCreateParams.additionalHeaders.toBuilder() + additionalQueryParams = logCreateParams.additionalQueryParams.toBuilder() + } + + /** + * Sets the entire request body. + * + * This is generally only useful if you are already constructing the body separately. + * Otherwise, it's more convenient to use the top-level setters instead: + * - [endTime] + * - [limit] + * - [startTime] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + /** End time filter (ISO 8601). Defaults to now. */ + fun endTime(endTime: OffsetDateTime) = apply { body.endTime(endTime) } + + /** + * Sets [Builder.endTime] to an arbitrary JSON value. + * + * You should usually call [Builder.endTime] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun endTime(endTime: JsonField) = apply { body.endTime(endTime) } + + /** Maximum number of logs to return */ + fun limit(limit: Long) = apply { body.limit(limit) } + + /** + * Sets [Builder.limit] to an arbitrary JSON value. + * + * You should usually call [Builder.limit] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun limit(limit: JsonField) = apply { body.limit(limit) } + + /** Start time filter (ISO 8601). Defaults to 30 days ago. */ + fun startTime(startTime: OffsetDateTime) = apply { body.startTime(startTime) } + + /** + * Sets [Builder.startTime] to an arbitrary JSON value. + * + * You should usually call [Builder.startTime] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun startTime(startTime: JsonField) = apply { body.startTime(startTime) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) + } + + 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 [LogCreateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): LogCreateParams = + LogCreateParams(body.build(), additionalHeaders.build(), additionalQueryParams.build()) + } + + fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + class Body + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val endTime: JsonField, + private val limit: JsonField, + private val startTime: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("end_time") + @ExcludeMissing + endTime: JsonField = JsonMissing.of(), + @JsonProperty("limit") @ExcludeMissing limit: JsonField = JsonMissing.of(), + @JsonProperty("start_time") + @ExcludeMissing + startTime: JsonField = JsonMissing.of(), + ) : this(endTime, limit, startTime, mutableMapOf()) + + /** + * End time filter (ISO 8601). Defaults to now. + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun endTime(): Optional = endTime.getOptional("end_time") + + /** + * Maximum number of logs to return + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun limit(): Optional = limit.getOptional("limit") + + /** + * Start time filter (ISO 8601). Defaults to 30 days ago. + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun startTime(): Optional = startTime.getOptional("start_time") + + /** + * Returns the raw JSON value of [endTime]. + * + * Unlike [endTime], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("end_time") + @ExcludeMissing + fun _endTime(): JsonField = endTime + + /** + * Returns the raw JSON value of [limit]. + * + * Unlike [limit], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("limit") @ExcludeMissing fun _limit(): JsonField = limit + + /** + * Returns the raw JSON value of [startTime]. + * + * Unlike [startTime], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("start_time") + @ExcludeMissing + fun _startTime(): JsonField = startTime + + @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 [Body]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var endTime: JsonField = JsonMissing.of() + private var limit: JsonField = JsonMissing.of() + private var startTime: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + endTime = body.endTime + limit = body.limit + startTime = body.startTime + additionalProperties = body.additionalProperties.toMutableMap() + } + + /** End time filter (ISO 8601). Defaults to now. */ + fun endTime(endTime: OffsetDateTime) = endTime(JsonField.of(endTime)) + + /** + * Sets [Builder.endTime] to an arbitrary JSON value. + * + * You should usually call [Builder.endTime] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun endTime(endTime: JsonField) = apply { this.endTime = endTime } + + /** Maximum number of logs to return */ + fun limit(limit: Long) = limit(JsonField.of(limit)) + + /** + * Sets [Builder.limit] to an arbitrary JSON value. + * + * You should usually call [Builder.limit] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun limit(limit: JsonField) = apply { this.limit = limit } + + /** Start time filter (ISO 8601). Defaults to 30 days ago. */ + fun startTime(startTime: OffsetDateTime) = startTime(JsonField.of(startTime)) + + /** + * Sets [Builder.startTime] to an arbitrary JSON value. + * + * You should usually call [Builder.startTime] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun startTime(startTime: JsonField) = apply { + this.startTime = startTime + } + + 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 [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Body = Body(endTime, limit, startTime, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + endTime() + limit() + startTime() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (endTime.asKnown().isPresent) 1 else 0) + + (if (limit.asKnown().isPresent) 1 else 0) + + (if (startTime.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + endTime == other.endTime && + limit == other.limit && + startTime == other.startTime && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(endTime, limit, startTime, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{endTime=$endTime, limit=$limit, startTime=$startTime, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is LogCreateParams && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = Objects.hash(body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "LogCreateParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogCreateResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogCreateResponse.kt new file mode 100644 index 0000000..b77a776 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogCreateResponse.kt @@ -0,0 +1,578 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.logs + +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonField +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.checkKnown +import com.cas_parser.api.core.toImmutable +import com.cas_parser.api.errors.CasParserInvalidDataException +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.time.OffsetDateTime +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +class LogCreateResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val count: JsonField, + private val logs: JsonField>, + private val status: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("count") @ExcludeMissing count: JsonField = JsonMissing.of(), + @JsonProperty("logs") @ExcludeMissing logs: JsonField> = JsonMissing.of(), + @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(), + ) : this(count, logs, status, mutableMapOf()) + + /** + * Number of logs returned + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun count(): Optional = count.getOptional("count") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun logs(): Optional> = logs.getOptional("logs") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun status(): Optional = status.getOptional("status") + + /** + * Returns the raw JSON value of [count]. + * + * Unlike [count], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("count") @ExcludeMissing fun _count(): JsonField = count + + /** + * Returns the raw JSON value of [logs]. + * + * Unlike [logs], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("logs") @ExcludeMissing fun _logs(): JsonField> = logs + + /** + * Returns the raw JSON value of [status]. + * + * Unlike [status], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("status") @ExcludeMissing fun _status(): JsonField = status + + @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 [LogCreateResponse]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [LogCreateResponse]. */ + class Builder internal constructor() { + + private var count: JsonField = JsonMissing.of() + private var logs: JsonField>? = null + private var status: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(logCreateResponse: LogCreateResponse) = apply { + count = logCreateResponse.count + logs = logCreateResponse.logs.map { it.toMutableList() } + status = logCreateResponse.status + additionalProperties = logCreateResponse.additionalProperties.toMutableMap() + } + + /** Number of logs returned */ + fun count(count: Long) = count(JsonField.of(count)) + + /** + * Sets [Builder.count] to an arbitrary JSON value. + * + * You should usually call [Builder.count] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun count(count: JsonField) = apply { this.count = count } + + fun logs(logs: List) = logs(JsonField.of(logs)) + + /** + * Sets [Builder.logs] to an arbitrary JSON value. + * + * You should usually call [Builder.logs] with a well-typed `List` value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun logs(logs: JsonField>) = apply { this.logs = logs.map { it.toMutableList() } } + + /** + * Adds a single [Log] to [logs]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addLog(log: Log) = apply { + logs = (logs ?: JsonField.of(mutableListOf())).also { checkKnown("logs", it).add(log) } + } + + fun status(status: String) = status(JsonField.of(status)) + + /** + * Sets [Builder.status] to an arbitrary JSON value. + * + * You should usually call [Builder.status] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun status(status: JsonField) = apply { this.status = status } + + 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 [LogCreateResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): LogCreateResponse = + LogCreateResponse( + count, + (logs ?: JsonMissing.of()).map { it.toImmutable() }, + status, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): LogCreateResponse = apply { + if (validated) { + return@apply + } + + count() + logs().ifPresent { it.forEach { it.validate() } } + status() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (count.asKnown().isPresent) 1 else 0) + + (logs.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (status.asKnown().isPresent) 1 else 0) + + class Log + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val credits: JsonField, + private val feature: JsonField, + private val path: JsonField, + private val requestId: JsonField, + private val statusCode: JsonField, + private val timestamp: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("credits") @ExcludeMissing credits: JsonField = JsonMissing.of(), + @JsonProperty("feature") @ExcludeMissing feature: JsonField = JsonMissing.of(), + @JsonProperty("path") @ExcludeMissing path: JsonField = JsonMissing.of(), + @JsonProperty("request_id") + @ExcludeMissing + requestId: JsonField = JsonMissing.of(), + @JsonProperty("status_code") + @ExcludeMissing + statusCode: JsonField = JsonMissing.of(), + @JsonProperty("timestamp") + @ExcludeMissing + timestamp: JsonField = JsonMissing.of(), + ) : this(credits, feature, path, requestId, statusCode, timestamp, mutableMapOf()) + + /** + * Credits consumed for this request + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun credits(): Optional = credits.getOptional("credits") + + /** + * API feature used + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun feature(): Optional = feature.getOptional("feature") + + /** + * API endpoint path + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun path(): Optional = path.getOptional("path") + + /** + * Unique request identifier + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun requestId(): Optional = requestId.getOptional("request_id") + + /** + * HTTP response status code + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun statusCode(): Optional = statusCode.getOptional("status_code") + + /** + * When the request was made + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun timestamp(): Optional = timestamp.getOptional("timestamp") + + /** + * Returns the raw JSON value of [credits]. + * + * Unlike [credits], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("credits") @ExcludeMissing fun _credits(): JsonField = credits + + /** + * Returns the raw JSON value of [feature]. + * + * Unlike [feature], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("feature") @ExcludeMissing fun _feature(): JsonField = feature + + /** + * Returns the raw JSON value of [path]. + * + * Unlike [path], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("path") @ExcludeMissing fun _path(): JsonField = path + + /** + * Returns the raw JSON value of [requestId]. + * + * Unlike [requestId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("request_id") @ExcludeMissing fun _requestId(): JsonField = requestId + + /** + * Returns the raw JSON value of [statusCode]. + * + * Unlike [statusCode], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("status_code") @ExcludeMissing fun _statusCode(): JsonField = statusCode + + /** + * Returns the raw JSON value of [timestamp]. + * + * Unlike [timestamp], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("timestamp") + @ExcludeMissing + fun _timestamp(): JsonField = timestamp + + @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 [Log]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Log]. */ + class Builder internal constructor() { + + private var credits: JsonField = JsonMissing.of() + private var feature: JsonField = JsonMissing.of() + private var path: JsonField = JsonMissing.of() + private var requestId: JsonField = JsonMissing.of() + private var statusCode: JsonField = JsonMissing.of() + private var timestamp: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(log: Log) = apply { + credits = log.credits + feature = log.feature + path = log.path + requestId = log.requestId + statusCode = log.statusCode + timestamp = log.timestamp + additionalProperties = log.additionalProperties.toMutableMap() + } + + /** Credits consumed for this request */ + fun credits(credits: Double) = credits(JsonField.of(credits)) + + /** + * Sets [Builder.credits] to an arbitrary JSON value. + * + * You should usually call [Builder.credits] with a well-typed [Double] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun credits(credits: JsonField) = apply { this.credits = credits } + + /** API feature used */ + fun feature(feature: String) = feature(JsonField.of(feature)) + + /** + * Sets [Builder.feature] to an arbitrary JSON value. + * + * You should usually call [Builder.feature] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun feature(feature: JsonField) = apply { this.feature = feature } + + /** API endpoint path */ + fun path(path: String) = path(JsonField.of(path)) + + /** + * Sets [Builder.path] to an arbitrary JSON value. + * + * You should usually call [Builder.path] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun path(path: JsonField) = apply { this.path = path } + + /** Unique request identifier */ + fun requestId(requestId: String) = requestId(JsonField.of(requestId)) + + /** + * Sets [Builder.requestId] to an arbitrary JSON value. + * + * You should usually call [Builder.requestId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun requestId(requestId: JsonField) = apply { this.requestId = requestId } + + /** HTTP response status code */ + fun statusCode(statusCode: Long) = statusCode(JsonField.of(statusCode)) + + /** + * Sets [Builder.statusCode] to an arbitrary JSON value. + * + * You should usually call [Builder.statusCode] with a well-typed [Long] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun statusCode(statusCode: JsonField) = apply { this.statusCode = statusCode } + + /** When the request was made */ + fun timestamp(timestamp: OffsetDateTime) = timestamp(JsonField.of(timestamp)) + + /** + * Sets [Builder.timestamp] to an arbitrary JSON value. + * + * You should usually call [Builder.timestamp] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun timestamp(timestamp: JsonField) = apply { + this.timestamp = timestamp + } + + 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 [Log]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Log = + Log( + credits, + feature, + path, + requestId, + statusCode, + timestamp, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Log = apply { + if (validated) { + return@apply + } + + credits() + feature() + path() + requestId() + statusCode() + timestamp() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (credits.asKnown().isPresent) 1 else 0) + + (if (feature.asKnown().isPresent) 1 else 0) + + (if (path.asKnown().isPresent) 1 else 0) + + (if (requestId.asKnown().isPresent) 1 else 0) + + (if (statusCode.asKnown().isPresent) 1 else 0) + + (if (timestamp.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Log && + credits == other.credits && + feature == other.feature && + path == other.path && + requestId == other.requestId && + statusCode == other.statusCode && + timestamp == other.timestamp && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + credits, + feature, + path, + requestId, + statusCode, + timestamp, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Log{credits=$credits, feature=$feature, path=$path, requestId=$requestId, statusCode=$statusCode, timestamp=$timestamp, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is LogCreateResponse && + count == other.count && + logs == other.logs && + status == other.status && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(count, logs, status, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "LogCreateResponse{count=$count, logs=$logs, status=$status, additionalProperties=$additionalProperties}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogGetSummaryParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogGetSummaryParams.kt new file mode 100644 index 0000000..28648da --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogGetSummaryParams.kt @@ -0,0 +1,470 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.logs + +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonField +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.Params +import com.cas_parser.api.core.http.Headers +import com.cas_parser.api.core.http.QueryParams +import com.cas_parser.api.errors.CasParserInvalidDataException +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.time.OffsetDateTime +import java.util.Collections +import java.util.Objects +import java.util.Optional + +/** + * Get aggregated usage statistics grouped by feature. + * + * Useful for understanding which API features are being used most and tracking usage trends. + * + * **Legacy path:** `/logs/summary` (still supported) + */ +class LogGetSummaryParams +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * End time filter (ISO 8601). Defaults to now. + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun endTime(): Optional = body.endTime() + + /** + * Start time filter (ISO 8601). Defaults to start of current month. + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun startTime(): Optional = body.startTime() + + /** + * Returns the raw JSON value of [endTime]. + * + * Unlike [endTime], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _endTime(): JsonField = body._endTime() + + /** + * Returns the raw JSON value of [startTime]. + * + * Unlike [startTime], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _startTime(): JsonField = body._startTime() + + fun _additionalBodyProperties(): Map = body._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 { + + @JvmStatic fun none(): LogGetSummaryParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [LogGetSummaryParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [LogGetSummaryParams]. */ + class Builder internal constructor() { + + private var body: Body.Builder = Body.builder() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(logGetSummaryParams: LogGetSummaryParams) = apply { + body = logGetSummaryParams.body.toBuilder() + additionalHeaders = logGetSummaryParams.additionalHeaders.toBuilder() + additionalQueryParams = logGetSummaryParams.additionalQueryParams.toBuilder() + } + + /** + * Sets the entire request body. + * + * This is generally only useful if you are already constructing the body separately. + * Otherwise, it's more convenient to use the top-level setters instead: + * - [endTime] + * - [startTime] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + /** End time filter (ISO 8601). Defaults to now. */ + fun endTime(endTime: OffsetDateTime) = apply { body.endTime(endTime) } + + /** + * Sets [Builder.endTime] to an arbitrary JSON value. + * + * You should usually call [Builder.endTime] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun endTime(endTime: JsonField) = apply { body.endTime(endTime) } + + /** Start time filter (ISO 8601). Defaults to start of current month. */ + fun startTime(startTime: OffsetDateTime) = apply { body.startTime(startTime) } + + /** + * Sets [Builder.startTime] to an arbitrary JSON value. + * + * You should usually call [Builder.startTime] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun startTime(startTime: JsonField) = apply { body.startTime(startTime) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) + } + + 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 [LogGetSummaryParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): LogGetSummaryParams = + LogGetSummaryParams( + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + class Body + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val endTime: JsonField, + private val startTime: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("end_time") + @ExcludeMissing + endTime: JsonField = JsonMissing.of(), + @JsonProperty("start_time") + @ExcludeMissing + startTime: JsonField = JsonMissing.of(), + ) : this(endTime, startTime, mutableMapOf()) + + /** + * End time filter (ISO 8601). Defaults to now. + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun endTime(): Optional = endTime.getOptional("end_time") + + /** + * Start time filter (ISO 8601). Defaults to start of current month. + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun startTime(): Optional = startTime.getOptional("start_time") + + /** + * Returns the raw JSON value of [endTime]. + * + * Unlike [endTime], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("end_time") + @ExcludeMissing + fun _endTime(): JsonField = endTime + + /** + * Returns the raw JSON value of [startTime]. + * + * Unlike [startTime], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("start_time") + @ExcludeMissing + fun _startTime(): JsonField = startTime + + @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 [Body]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var endTime: JsonField = JsonMissing.of() + private var startTime: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + endTime = body.endTime + startTime = body.startTime + additionalProperties = body.additionalProperties.toMutableMap() + } + + /** End time filter (ISO 8601). Defaults to now. */ + fun endTime(endTime: OffsetDateTime) = endTime(JsonField.of(endTime)) + + /** + * Sets [Builder.endTime] to an arbitrary JSON value. + * + * You should usually call [Builder.endTime] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun endTime(endTime: JsonField) = apply { this.endTime = endTime } + + /** Start time filter (ISO 8601). Defaults to start of current month. */ + fun startTime(startTime: OffsetDateTime) = startTime(JsonField.of(startTime)) + + /** + * Sets [Builder.startTime] to an arbitrary JSON value. + * + * You should usually call [Builder.startTime] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun startTime(startTime: JsonField) = apply { + this.startTime = startTime + } + + 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 [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Body = Body(endTime, startTime, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + endTime() + startTime() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (endTime.asKnown().isPresent) 1 else 0) + + (if (startTime.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + endTime == other.endTime && + startTime == other.startTime && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(endTime, startTime, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{endTime=$endTime, startTime=$startTime, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is LogGetSummaryParams && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = Objects.hash(body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "LogGetSummaryParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogGetSummaryResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogGetSummaryResponse.kt new file mode 100644 index 0000000..a78d1ba --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogGetSummaryResponse.kt @@ -0,0 +1,663 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.logs + +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonField +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.checkKnown +import com.cas_parser.api.core.toImmutable +import com.cas_parser.api.errors.CasParserInvalidDataException +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 + +class LogGetSummaryResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val status: JsonField, + private val summary: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(), + @JsonProperty("summary") @ExcludeMissing summary: JsonField = JsonMissing.of(), + ) : this(status, summary, mutableMapOf()) + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun status(): Optional = status.getOptional("status") + + /** + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun summary(): Optional = summary.getOptional("summary") + + /** + * Returns the raw JSON value of [status]. + * + * Unlike [status], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("status") @ExcludeMissing fun _status(): JsonField = status + + /** + * Returns the raw JSON value of [summary]. + * + * Unlike [summary], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("summary") @ExcludeMissing fun _summary(): JsonField = summary + + @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 [LogGetSummaryResponse]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [LogGetSummaryResponse]. */ + class Builder internal constructor() { + + private var status: JsonField = JsonMissing.of() + private var summary: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(logGetSummaryResponse: LogGetSummaryResponse) = apply { + status = logGetSummaryResponse.status + summary = logGetSummaryResponse.summary + additionalProperties = logGetSummaryResponse.additionalProperties.toMutableMap() + } + + fun status(status: String) = status(JsonField.of(status)) + + /** + * Sets [Builder.status] to an arbitrary JSON value. + * + * You should usually call [Builder.status] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun status(status: JsonField) = apply { this.status = status } + + fun summary(summary: Summary) = summary(JsonField.of(summary)) + + /** + * Sets [Builder.summary] to an arbitrary JSON value. + * + * You should usually call [Builder.summary] with a well-typed [Summary] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun summary(summary: JsonField) = apply { this.summary = summary } + + 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 [LogGetSummaryResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): LogGetSummaryResponse = + LogGetSummaryResponse(status, summary, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): LogGetSummaryResponse = apply { + if (validated) { + return@apply + } + + status() + summary().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (status.asKnown().isPresent) 1 else 0) + + (summary.asKnown().getOrNull()?.validity() ?: 0) + + class Summary + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val byFeature: JsonField>, + private val totalCredits: JsonField, + private val totalRequests: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("by_feature") + @ExcludeMissing + byFeature: JsonField> = JsonMissing.of(), + @JsonProperty("total_credits") + @ExcludeMissing + totalCredits: JsonField = JsonMissing.of(), + @JsonProperty("total_requests") + @ExcludeMissing + totalRequests: JsonField = JsonMissing.of(), + ) : this(byFeature, totalCredits, totalRequests, mutableMapOf()) + + /** + * Usage breakdown by feature + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun byFeature(): Optional> = byFeature.getOptional("by_feature") + + /** + * Total credits consumed in the period + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun totalCredits(): Optional = totalCredits.getOptional("total_credits") + + /** + * Total API requests made in the period + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun totalRequests(): Optional = totalRequests.getOptional("total_requests") + + /** + * Returns the raw JSON value of [byFeature]. + * + * Unlike [byFeature], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("by_feature") + @ExcludeMissing + fun _byFeature(): JsonField> = byFeature + + /** + * Returns the raw JSON value of [totalCredits]. + * + * Unlike [totalCredits], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("total_credits") + @ExcludeMissing + fun _totalCredits(): JsonField = totalCredits + + /** + * Returns the raw JSON value of [totalRequests]. + * + * Unlike [totalRequests], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("total_requests") + @ExcludeMissing + fun _totalRequests(): JsonField = totalRequests + + @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 [Summary]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Summary]. */ + class Builder internal constructor() { + + private var byFeature: JsonField>? = null + private var totalCredits: JsonField = JsonMissing.of() + private var totalRequests: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(summary: Summary) = apply { + byFeature = summary.byFeature.map { it.toMutableList() } + totalCredits = summary.totalCredits + totalRequests = summary.totalRequests + additionalProperties = summary.additionalProperties.toMutableMap() + } + + /** Usage breakdown by feature */ + fun byFeature(byFeature: List) = byFeature(JsonField.of(byFeature)) + + /** + * Sets [Builder.byFeature] to an arbitrary JSON value. + * + * You should usually call [Builder.byFeature] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun byFeature(byFeature: JsonField>) = apply { + this.byFeature = byFeature.map { it.toMutableList() } + } + + /** + * Adds a single [ByFeature] to [Builder.byFeature]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addByFeature(byFeature: ByFeature) = apply { + this.byFeature = + (this.byFeature ?: JsonField.of(mutableListOf())).also { + checkKnown("byFeature", it).add(byFeature) + } + } + + /** Total credits consumed in the period */ + fun totalCredits(totalCredits: Double) = totalCredits(JsonField.of(totalCredits)) + + /** + * Sets [Builder.totalCredits] to an arbitrary JSON value. + * + * You should usually call [Builder.totalCredits] with a well-typed [Double] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun totalCredits(totalCredits: JsonField) = apply { + this.totalCredits = totalCredits + } + + /** Total API requests made in the period */ + fun totalRequests(totalRequests: Long) = totalRequests(JsonField.of(totalRequests)) + + /** + * Sets [Builder.totalRequests] to an arbitrary JSON value. + * + * You should usually call [Builder.totalRequests] with a well-typed [Long] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun totalRequests(totalRequests: JsonField) = apply { + this.totalRequests = totalRequests + } + + 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 [Summary]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Summary = + Summary( + (byFeature ?: JsonMissing.of()).map { it.toImmutable() }, + totalCredits, + totalRequests, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Summary = apply { + if (validated) { + return@apply + } + + byFeature().ifPresent { it.forEach { it.validate() } } + totalCredits() + totalRequests() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 = + (byFeature.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (totalCredits.asKnown().isPresent) 1 else 0) + + (if (totalRequests.asKnown().isPresent) 1 else 0) + + class ByFeature + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val credits: JsonField, + private val feature: JsonField, + private val requests: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("credits") + @ExcludeMissing + credits: JsonField = JsonMissing.of(), + @JsonProperty("feature") + @ExcludeMissing + feature: JsonField = JsonMissing.of(), + @JsonProperty("requests") + @ExcludeMissing + requests: JsonField = JsonMissing.of(), + ) : this(credits, feature, requests, mutableMapOf()) + + /** + * Credits consumed by this feature + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun credits(): Optional = credits.getOptional("credits") + + /** + * API feature name + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun feature(): Optional = feature.getOptional("feature") + + /** + * Number of requests for this feature + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun requests(): Optional = requests.getOptional("requests") + + /** + * Returns the raw JSON value of [credits]. + * + * Unlike [credits], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("credits") @ExcludeMissing fun _credits(): JsonField = credits + + /** + * Returns the raw JSON value of [feature]. + * + * Unlike [feature], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("feature") @ExcludeMissing fun _feature(): JsonField = feature + + /** + * Returns the raw JSON value of [requests]. + * + * Unlike [requests], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("requests") @ExcludeMissing fun _requests(): JsonField = requests + + @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 [ByFeature]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ByFeature]. */ + class Builder internal constructor() { + + private var credits: JsonField = JsonMissing.of() + private var feature: JsonField = JsonMissing.of() + private var requests: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(byFeature: ByFeature) = apply { + credits = byFeature.credits + feature = byFeature.feature + requests = byFeature.requests + additionalProperties = byFeature.additionalProperties.toMutableMap() + } + + /** Credits consumed by this feature */ + fun credits(credits: Double) = credits(JsonField.of(credits)) + + /** + * Sets [Builder.credits] to an arbitrary JSON value. + * + * You should usually call [Builder.credits] with a well-typed [Double] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun credits(credits: JsonField) = apply { this.credits = credits } + + /** API feature name */ + fun feature(feature: String) = feature(JsonField.of(feature)) + + /** + * Sets [Builder.feature] to an arbitrary JSON value. + * + * You should usually call [Builder.feature] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun feature(feature: JsonField) = apply { this.feature = feature } + + /** Number of requests for this feature */ + fun requests(requests: Long) = requests(JsonField.of(requests)) + + /** + * Sets [Builder.requests] to an arbitrary JSON value. + * + * You should usually call [Builder.requests] with a well-typed [Long] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun requests(requests: JsonField) = apply { this.requests = requests } + + 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 [ByFeature]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): ByFeature = + ByFeature(credits, feature, requests, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): ByFeature = apply { + if (validated) { + return@apply + } + + credits() + feature() + requests() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (credits.asKnown().isPresent) 1 else 0) + + (if (feature.asKnown().isPresent) 1 else 0) + + (if (requests.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ByFeature && + credits == other.credits && + feature == other.feature && + requests == other.requests && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(credits, feature, requests, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ByFeature{credits=$credits, feature=$feature, requests=$requests, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Summary && + byFeature == other.byFeature && + totalCredits == other.totalCredits && + totalRequests == other.totalRequests && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(byFeature, totalCredits, totalRequests, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Summary{byFeature=$byFeature, totalCredits=$totalCredits, totalRequests=$totalRequests, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is LogGetSummaryResponse && + status == other.status && + summary == other.summary && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(status, summary, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "LogGetSummaryResponse{status=$status, summary=$summary, additionalProperties=$additionalProperties}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyParams.kt new file mode 100644 index 0000000..aac1a81 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyParams.kt @@ -0,0 +1,211 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.verifytoken + +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.Params +import com.cas_parser.api.core.http.Headers +import com.cas_parser.api.core.http.QueryParams +import com.cas_parser.api.core.toImmutable +import java.util.Objects +import java.util.Optional + +/** Verify an access token and check if it's still valid. Useful for debugging token issues. */ +class VerifyTokenVerifyParams +private constructor( + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, + private val additionalBodyProperties: Map, +) : Params { + + /** Additional body properties to send with the request. */ + fun _additionalBodyProperties(): Map = additionalBodyProperties + + /** 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 { + + @JvmStatic fun none(): VerifyTokenVerifyParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [VerifyTokenVerifyParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [VerifyTokenVerifyParams]. */ + class Builder internal constructor() { + + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + private var additionalBodyProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(verifyTokenVerifyParams: VerifyTokenVerifyParams) = apply { + additionalHeaders = verifyTokenVerifyParams.additionalHeaders.toBuilder() + additionalQueryParams = verifyTokenVerifyParams.additionalQueryParams.toBuilder() + additionalBodyProperties = + verifyTokenVerifyParams.additionalBodyProperties.toMutableMap() + } + + 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) + } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + this.additionalBodyProperties.clear() + putAllAdditionalBodyProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + additionalBodyProperties.put(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + this.additionalBodyProperties.putAll(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { + additionalBodyProperties.remove(key) + } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalBodyProperty) + } + + /** + * Returns an immutable instance of [VerifyTokenVerifyParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): VerifyTokenVerifyParams = + VerifyTokenVerifyParams( + additionalHeaders.build(), + additionalQueryParams.build(), + additionalBodyProperties.toImmutable(), + ) + } + + fun _body(): Optional> = + Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is VerifyTokenVerifyParams && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams && + additionalBodyProperties == other.additionalBodyProperties + } + + override fun hashCode(): Int = + Objects.hash(additionalHeaders, additionalQueryParams, additionalBodyProperties) + + override fun toString() = + "VerifyTokenVerifyParams{additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyResponse.kt new file mode 100644 index 0000000..b8859a0 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyResponse.kt @@ -0,0 +1,240 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.verifytoken + +import com.cas_parser.api.core.ExcludeMissing +import com.cas_parser.api.core.JsonField +import com.cas_parser.api.core.JsonMissing +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.errors.CasParserInvalidDataException +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 + +class VerifyTokenVerifyResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val error: JsonField, + private val maskedApiKey: JsonField, + private val valid: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("error") @ExcludeMissing error: JsonField = JsonMissing.of(), + @JsonProperty("masked_api_key") + @ExcludeMissing + maskedApiKey: JsonField = JsonMissing.of(), + @JsonProperty("valid") @ExcludeMissing valid: JsonField = JsonMissing.of(), + ) : this(error, maskedApiKey, valid, mutableMapOf()) + + /** + * Error message (only shown if invalid) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun error(): Optional = error.getOptional("error") + + /** + * Masked API key (only shown if valid) + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun maskedApiKey(): Optional = maskedApiKey.getOptional("masked_api_key") + + /** + * Whether the token is valid + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun valid(): Optional = valid.getOptional("valid") + + /** + * Returns the raw JSON value of [error]. + * + * Unlike [error], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("error") @ExcludeMissing fun _error(): JsonField = error + + /** + * Returns the raw JSON value of [maskedApiKey]. + * + * Unlike [maskedApiKey], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("masked_api_key") + @ExcludeMissing + fun _maskedApiKey(): JsonField = maskedApiKey + + /** + * Returns the raw JSON value of [valid]. + * + * Unlike [valid], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("valid") @ExcludeMissing fun _valid(): JsonField = valid + + @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 [VerifyTokenVerifyResponse]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [VerifyTokenVerifyResponse]. */ + class Builder internal constructor() { + + private var error: JsonField = JsonMissing.of() + private var maskedApiKey: JsonField = JsonMissing.of() + private var valid: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(verifyTokenVerifyResponse: VerifyTokenVerifyResponse) = apply { + error = verifyTokenVerifyResponse.error + maskedApiKey = verifyTokenVerifyResponse.maskedApiKey + valid = verifyTokenVerifyResponse.valid + additionalProperties = verifyTokenVerifyResponse.additionalProperties.toMutableMap() + } + + /** Error message (only shown if invalid) */ + fun error(error: String) = error(JsonField.of(error)) + + /** + * Sets [Builder.error] to an arbitrary JSON value. + * + * You should usually call [Builder.error] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun error(error: JsonField) = apply { this.error = error } + + /** Masked API key (only shown if valid) */ + fun maskedApiKey(maskedApiKey: String) = maskedApiKey(JsonField.of(maskedApiKey)) + + /** + * Sets [Builder.maskedApiKey] to an arbitrary JSON value. + * + * You should usually call [Builder.maskedApiKey] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun maskedApiKey(maskedApiKey: JsonField) = apply { + this.maskedApiKey = maskedApiKey + } + + /** Whether the token is valid */ + fun valid(valid: Boolean) = valid(JsonField.of(valid)) + + /** + * Sets [Builder.valid] to an arbitrary JSON value. + * + * You should usually call [Builder.valid] with a well-typed [Boolean] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun valid(valid: JsonField) = apply { this.valid = valid } + + 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 [VerifyTokenVerifyResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): VerifyTokenVerifyResponse = + VerifyTokenVerifyResponse( + error, + maskedApiKey, + valid, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): VerifyTokenVerifyResponse = apply { + if (validated) { + return@apply + } + + error() + maskedApiKey() + valid() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CasParserInvalidDataException) { + 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 (error.asKnown().isPresent) 1 else 0) + + (if (maskedApiKey.asKnown().isPresent) 1 else 0) + + (if (valid.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is VerifyTokenVerifyResponse && + error == other.error && + maskedApiKey == other.maskedApiKey && + valid == other.valid && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(error, maskedApiKey, valid, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "VerifyTokenVerifyResponse{error=$error, maskedApiKey=$maskedApiKey, valid=$valid, additionalProperties=$additionalProperties}" +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsync.kt index 3809ee6..acfdef1 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsync.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsync.kt @@ -3,6 +3,11 @@ package com.cas_parser.api.services.async import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.models.accesstoken.AccessTokenCreateParams +import com.cas_parser.api.models.accesstoken.AccessTokenCreateResponse +import java.util.concurrent.CompletableFuture import java.util.function.Consumer interface AccessTokenServiceAsync { @@ -19,6 +24,38 @@ interface AccessTokenServiceAsync { */ fun withOptions(modifier: Consumer): AccessTokenServiceAsync + /** + * Generate a short-lived access token from your API key. + * + * **Use this endpoint from your backend** to create tokens that can be safely passed to + * frontend/SDK. + * + * **Legacy path:** `/v1/access-token` (still supported) + * + * Access tokens: + * - Are prefixed with `at_` for easy identification + * - Valid for up to 60 minutes + * - Can be used in place of API keys on all v4 endpoints + * - Cannot be used to generate other access tokens + */ + fun create(): CompletableFuture = + create(AccessTokenCreateParams.none()) + + /** @see create */ + fun create( + params: AccessTokenCreateParams = AccessTokenCreateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see create */ + fun create( + params: AccessTokenCreateParams = AccessTokenCreateParams.none() + ): CompletableFuture = create(params, RequestOptions.none()) + + /** @see create */ + fun create(requestOptions: RequestOptions): CompletableFuture = + create(AccessTokenCreateParams.none(), requestOptions) + /** * A view of [AccessTokenServiceAsync] that provides access to raw HTTP responses for each * method. @@ -33,5 +70,30 @@ interface AccessTokenServiceAsync { fun withOptions( modifier: Consumer ): AccessTokenServiceAsync.WithRawResponse + + /** + * Returns a raw HTTP response for `post /v1/token`, but is otherwise the same as + * [AccessTokenServiceAsync.create]. + */ + fun create(): CompletableFuture> = + create(AccessTokenCreateParams.none()) + + /** @see create */ + fun create( + params: AccessTokenCreateParams = AccessTokenCreateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see create */ + fun create( + params: AccessTokenCreateParams = AccessTokenCreateParams.none() + ): CompletableFuture> = + create(params, RequestOptions.none()) + + /** @see create */ + fun create( + requestOptions: RequestOptions + ): CompletableFuture> = + create(AccessTokenCreateParams.none(), requestOptions) } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsyncImpl.kt index a947c34..ec51534 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsyncImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsyncImpl.kt @@ -3,6 +3,21 @@ package com.cas_parser.api.services.async import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.handlers.errorBodyHandler +import com.cas_parser.api.core.handlers.errorHandler +import com.cas_parser.api.core.handlers.jsonHandler +import com.cas_parser.api.core.http.HttpMethod +import com.cas_parser.api.core.http.HttpRequest +import com.cas_parser.api.core.http.HttpResponse +import com.cas_parser.api.core.http.HttpResponse.Handler +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.core.http.json +import com.cas_parser.api.core.http.parseable +import com.cas_parser.api.core.prepareAsync +import com.cas_parser.api.models.accesstoken.AccessTokenCreateParams +import com.cas_parser.api.models.accesstoken.AccessTokenCreateResponse +import java.util.concurrent.CompletableFuture import java.util.function.Consumer class AccessTokenServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : @@ -17,14 +32,55 @@ class AccessTokenServiceAsyncImpl internal constructor(private val clientOptions override fun withOptions(modifier: Consumer): AccessTokenServiceAsync = AccessTokenServiceAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + override fun create( + params: AccessTokenCreateParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v1/token + withRawResponse().create(params, requestOptions).thenApply { it.parse() } + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : AccessTokenServiceAsync.WithRawResponse { + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + override fun withOptions( modifier: Consumer ): AccessTokenServiceAsync.WithRawResponse = AccessTokenServiceAsyncImpl.WithRawResponseImpl( clientOptions.toBuilder().apply(modifier::accept).build() ) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun create( + params: AccessTokenCreateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v1", "token") + .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 { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CreditServiceAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CreditServiceAsync.kt index 70f75cb..dd5a54f 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CreditServiceAsync.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CreditServiceAsync.kt @@ -3,6 +3,11 @@ package com.cas_parser.api.services.async import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.models.credits.CreditCheckParams +import com.cas_parser.api.models.credits.CreditCheckResponse +import java.util.concurrent.CompletableFuture import java.util.function.Consumer interface CreditServiceAsync { @@ -19,6 +24,33 @@ interface CreditServiceAsync { */ fun withOptions(modifier: Consumer): CreditServiceAsync + /** + * Check your remaining API credits and usage for the current billing period. + * + * Returns: + * - Number of API calls used and remaining credits + * - Credit limit and reset date + * - List of enabled features for your plan + * + * Credits reset at the start of each billing period. + */ + fun check(): CompletableFuture = check(CreditCheckParams.none()) + + /** @see check */ + fun check( + params: CreditCheckParams = CreditCheckParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see check */ + fun check( + params: CreditCheckParams = CreditCheckParams.none() + ): CompletableFuture = check(params, RequestOptions.none()) + + /** @see check */ + fun check(requestOptions: RequestOptions): CompletableFuture = + check(CreditCheckParams.none(), requestOptions) + /** * A view of [CreditServiceAsync] that provides access to raw HTTP responses for each method. */ @@ -32,5 +64,30 @@ interface CreditServiceAsync { fun withOptions( modifier: Consumer ): CreditServiceAsync.WithRawResponse + + /** + * Returns a raw HTTP response for `post /v1/credits`, but is otherwise the same as + * [CreditServiceAsync.check]. + */ + fun check(): CompletableFuture> = + check(CreditCheckParams.none()) + + /** @see check */ + fun check( + params: CreditCheckParams = CreditCheckParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see check */ + fun check( + params: CreditCheckParams = CreditCheckParams.none() + ): CompletableFuture> = + check(params, RequestOptions.none()) + + /** @see check */ + fun check( + requestOptions: RequestOptions + ): CompletableFuture> = + check(CreditCheckParams.none(), requestOptions) } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CreditServiceAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CreditServiceAsyncImpl.kt index 9995851..02b806c 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CreditServiceAsyncImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CreditServiceAsyncImpl.kt @@ -3,6 +3,21 @@ package com.cas_parser.api.services.async import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.handlers.errorBodyHandler +import com.cas_parser.api.core.handlers.errorHandler +import com.cas_parser.api.core.handlers.jsonHandler +import com.cas_parser.api.core.http.HttpMethod +import com.cas_parser.api.core.http.HttpRequest +import com.cas_parser.api.core.http.HttpResponse +import com.cas_parser.api.core.http.HttpResponse.Handler +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.core.http.json +import com.cas_parser.api.core.http.parseable +import com.cas_parser.api.core.prepareAsync +import com.cas_parser.api.models.credits.CreditCheckParams +import com.cas_parser.api.models.credits.CreditCheckResponse +import java.util.concurrent.CompletableFuture import java.util.function.Consumer class CreditServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : @@ -17,14 +32,55 @@ class CreditServiceAsyncImpl internal constructor(private val clientOptions: Cli override fun withOptions(modifier: Consumer): CreditServiceAsync = CreditServiceAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + override fun check( + params: CreditCheckParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v1/credits + withRawResponse().check(params, requestOptions).thenApply { it.parse() } + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : CreditServiceAsync.WithRawResponse { + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + override fun withOptions( modifier: Consumer ): CreditServiceAsync.WithRawResponse = CreditServiceAsyncImpl.WithRawResponseImpl( clientOptions.toBuilder().apply(modifier::accept).build() ) + + private val checkHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun check( + params: CreditCheckParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v1", "credits") + .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 { checkHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/InboundEmailServiceAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/InboundEmailServiceAsync.kt new file mode 100644 index 0000000..8ff0edb --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/InboundEmailServiceAsync.kt @@ -0,0 +1,300 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.models.inboundemail.InboundEmailCreateParams +import com.cas_parser.api.models.inboundemail.InboundEmailCreateResponse +import com.cas_parser.api.models.inboundemail.InboundEmailDeleteParams +import com.cas_parser.api.models.inboundemail.InboundEmailDeleteResponse +import com.cas_parser.api.models.inboundemail.InboundEmailListParams +import com.cas_parser.api.models.inboundemail.InboundEmailListResponse +import com.cas_parser.api.models.inboundemail.InboundEmailRetrieveParams +import com.cas_parser.api.models.inboundemail.InboundEmailRetrieveResponse +import java.util.concurrent.CompletableFuture +import java.util.function.Consumer + +interface InboundEmailServiceAsync { + + /** + * 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): InboundEmailServiceAsync + + /** + * Create a dedicated inbound email address for collecting CAS statements via email forwarding. + * + * **How it works:** + * 1. Create an inbound email with your webhook URL + * 2. Display the email address to your user (e.g., "Forward your CAS to + * ie_xxx@import.casparser.in") + * 3. When an investor forwards a CAS email, we verify the sender and deliver to your webhook + * + * **Webhook Delivery:** + * - We POST to your `callback_url` with JSON body containing files (matching EmailCASFile + * schema) + * - Failed deliveries are retried automatically with exponential backoff + * + * **Inactivity:** + * - Inbound emails with no activity in 30 days are marked inactive + * - Active inbound emails remain operational indefinitely + */ + fun create(params: InboundEmailCreateParams): CompletableFuture = + create(params, RequestOptions.none()) + + /** @see create */ + fun create( + params: InboundEmailCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** Retrieve details of a specific mailbox including statistics. */ + fun retrieve(inboundEmailId: String): CompletableFuture = + retrieve(inboundEmailId, InboundEmailRetrieveParams.none()) + + /** @see retrieve */ + fun retrieve( + inboundEmailId: String, + params: InboundEmailRetrieveParams = InboundEmailRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + retrieve(params.toBuilder().inboundEmailId(inboundEmailId).build(), requestOptions) + + /** @see retrieve */ + fun retrieve( + inboundEmailId: String, + params: InboundEmailRetrieveParams = InboundEmailRetrieveParams.none(), + ): CompletableFuture = + retrieve(inboundEmailId, params, RequestOptions.none()) + + /** @see retrieve */ + fun retrieve( + params: InboundEmailRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see retrieve */ + fun retrieve( + params: InboundEmailRetrieveParams + ): CompletableFuture = retrieve(params, RequestOptions.none()) + + /** @see retrieve */ + fun retrieve( + inboundEmailId: String, + requestOptions: RequestOptions, + ): CompletableFuture = + retrieve(inboundEmailId, InboundEmailRetrieveParams.none(), requestOptions) + + /** + * List all mailboxes associated with your API key. Returns active and inactive mailboxes + * (deleted mailboxes are excluded). + */ + fun list(): CompletableFuture = list(InboundEmailListParams.none()) + + /** @see list */ + fun list( + params: InboundEmailListParams = InboundEmailListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see list */ + fun list( + params: InboundEmailListParams = InboundEmailListParams.none() + ): CompletableFuture = list(params, RequestOptions.none()) + + /** @see list */ + fun list(requestOptions: RequestOptions): CompletableFuture = + list(InboundEmailListParams.none(), requestOptions) + + /** + * Permanently delete an inbound email address. It will stop accepting emails. + * + * **Note:** Deletion is immediate and cannot be undone. Any emails received after deletion will + * be rejected. + */ + fun delete(inboundEmailId: String): CompletableFuture = + delete(inboundEmailId, InboundEmailDeleteParams.none()) + + /** @see delete */ + fun delete( + inboundEmailId: String, + params: InboundEmailDeleteParams = InboundEmailDeleteParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + delete(params.toBuilder().inboundEmailId(inboundEmailId).build(), requestOptions) + + /** @see delete */ + fun delete( + inboundEmailId: String, + params: InboundEmailDeleteParams = InboundEmailDeleteParams.none(), + ): CompletableFuture = + delete(inboundEmailId, params, RequestOptions.none()) + + /** @see delete */ + fun delete( + params: InboundEmailDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see delete */ + fun delete(params: InboundEmailDeleteParams): CompletableFuture = + delete(params, RequestOptions.none()) + + /** @see delete */ + fun delete( + inboundEmailId: String, + requestOptions: RequestOptions, + ): CompletableFuture = + delete(inboundEmailId, InboundEmailDeleteParams.none(), requestOptions) + + /** + * A view of [InboundEmailServiceAsync] 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 + ): InboundEmailServiceAsync.WithRawResponse + + /** + * Returns a raw HTTP response for `post /v4/inbound-email`, but is otherwise the same as + * [InboundEmailServiceAsync.create]. + */ + fun create( + params: InboundEmailCreateParams + ): CompletableFuture> = + create(params, RequestOptions.none()) + + /** @see create */ + fun create( + params: InboundEmailCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `get /v4/inbound-email/{inbound_email_id}`, but is + * otherwise the same as [InboundEmailServiceAsync.retrieve]. + */ + fun retrieve( + inboundEmailId: String + ): CompletableFuture> = + retrieve(inboundEmailId, InboundEmailRetrieveParams.none()) + + /** @see retrieve */ + fun retrieve( + inboundEmailId: String, + params: InboundEmailRetrieveParams = InboundEmailRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + retrieve(params.toBuilder().inboundEmailId(inboundEmailId).build(), requestOptions) + + /** @see retrieve */ + fun retrieve( + inboundEmailId: String, + params: InboundEmailRetrieveParams = InboundEmailRetrieveParams.none(), + ): CompletableFuture> = + retrieve(inboundEmailId, params, RequestOptions.none()) + + /** @see retrieve */ + fun retrieve( + params: InboundEmailRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see retrieve */ + fun retrieve( + params: InboundEmailRetrieveParams + ): CompletableFuture> = + retrieve(params, RequestOptions.none()) + + /** @see retrieve */ + fun retrieve( + inboundEmailId: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + retrieve(inboundEmailId, InboundEmailRetrieveParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `get /v4/inbound-email`, but is otherwise the same as + * [InboundEmailServiceAsync.list]. + */ + fun list(): CompletableFuture> = + list(InboundEmailListParams.none()) + + /** @see list */ + fun list( + params: InboundEmailListParams = InboundEmailListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see list */ + fun list( + params: InboundEmailListParams = InboundEmailListParams.none() + ): CompletableFuture> = + list(params, RequestOptions.none()) + + /** @see list */ + fun list( + requestOptions: RequestOptions + ): CompletableFuture> = + list(InboundEmailListParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `delete /v4/inbound-email/{inbound_email_id}`, but is + * otherwise the same as [InboundEmailServiceAsync.delete]. + */ + fun delete( + inboundEmailId: String + ): CompletableFuture> = + delete(inboundEmailId, InboundEmailDeleteParams.none()) + + /** @see delete */ + fun delete( + inboundEmailId: String, + params: InboundEmailDeleteParams = InboundEmailDeleteParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + delete(params.toBuilder().inboundEmailId(inboundEmailId).build(), requestOptions) + + /** @see delete */ + fun delete( + inboundEmailId: String, + params: InboundEmailDeleteParams = InboundEmailDeleteParams.none(), + ): CompletableFuture> = + delete(inboundEmailId, params, RequestOptions.none()) + + /** @see delete */ + fun delete( + params: InboundEmailDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see delete */ + fun delete( + params: InboundEmailDeleteParams + ): CompletableFuture> = + delete(params, RequestOptions.none()) + + /** @see delete */ + fun delete( + inboundEmailId: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + delete(inboundEmailId, InboundEmailDeleteParams.none(), requestOptions) + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/InboundEmailServiceAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/InboundEmailServiceAsyncImpl.kt new file mode 100644 index 0000000..a199b5f --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/InboundEmailServiceAsyncImpl.kt @@ -0,0 +1,212 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.checkRequired +import com.cas_parser.api.core.handlers.errorBodyHandler +import com.cas_parser.api.core.handlers.errorHandler +import com.cas_parser.api.core.handlers.jsonHandler +import com.cas_parser.api.core.http.HttpMethod +import com.cas_parser.api.core.http.HttpRequest +import com.cas_parser.api.core.http.HttpResponse +import com.cas_parser.api.core.http.HttpResponse.Handler +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.core.http.json +import com.cas_parser.api.core.http.parseable +import com.cas_parser.api.core.prepareAsync +import com.cas_parser.api.models.inboundemail.InboundEmailCreateParams +import com.cas_parser.api.models.inboundemail.InboundEmailCreateResponse +import com.cas_parser.api.models.inboundemail.InboundEmailDeleteParams +import com.cas_parser.api.models.inboundemail.InboundEmailDeleteResponse +import com.cas_parser.api.models.inboundemail.InboundEmailListParams +import com.cas_parser.api.models.inboundemail.InboundEmailListResponse +import com.cas_parser.api.models.inboundemail.InboundEmailRetrieveParams +import com.cas_parser.api.models.inboundemail.InboundEmailRetrieveResponse +import java.util.concurrent.CompletableFuture +import java.util.function.Consumer +import kotlin.jvm.optionals.getOrNull + +class InboundEmailServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + InboundEmailServiceAsync { + + private val withRawResponse: InboundEmailServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): InboundEmailServiceAsync.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): InboundEmailServiceAsync = + InboundEmailServiceAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun create( + params: InboundEmailCreateParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v4/inbound-email + withRawResponse().create(params, requestOptions).thenApply { it.parse() } + + override fun retrieve( + params: InboundEmailRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v4/inbound-email/{inbound_email_id} + withRawResponse().retrieve(params, requestOptions).thenApply { it.parse() } + + override fun list( + params: InboundEmailListParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v4/inbound-email + withRawResponse().list(params, requestOptions).thenApply { it.parse() } + + override fun delete( + params: InboundEmailDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // delete /v4/inbound-email/{inbound_email_id} + withRawResponse().delete(params, requestOptions).thenApply { it.parse() } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + InboundEmailServiceAsync.WithRawResponse { + + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + + override fun withOptions( + modifier: Consumer + ): InboundEmailServiceAsync.WithRawResponse = + InboundEmailServiceAsyncImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun create( + params: InboundEmailCreateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v4", "inbound-email") + .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 { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun retrieve( + params: InboundEmailRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("inboundEmailId", params.inboundEmailId().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v4", "inbound-email", params._pathParam(0)) + .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() + } + } + } + } + } + + private val listHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun list( + params: InboundEmailListParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v4", "inbound-email") + .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 { listHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + + private val deleteHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun delete( + params: InboundEmailDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("inboundEmailId", params.inboundEmailId().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v4", "inbound-email", params._pathParam(0)) + .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 { deleteHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/LogServiceAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/LogServiceAsync.kt index 4dc2b00..3f2546a 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/LogServiceAsync.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/LogServiceAsync.kt @@ -3,6 +3,13 @@ package com.cas_parser.api.services.async import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.models.logs.LogCreateParams +import com.cas_parser.api.models.logs.LogCreateResponse +import com.cas_parser.api.models.logs.LogGetSummaryParams +import com.cas_parser.api.models.logs.LogGetSummaryResponse +import java.util.concurrent.CompletableFuture import java.util.function.Consumer interface LogServiceAsync { @@ -19,6 +26,56 @@ interface LogServiceAsync { */ fun withOptions(modifier: Consumer): LogServiceAsync + /** + * Retrieve detailed API usage logs for your account. + * + * Returns a list of API calls with timestamps, features used, status codes, and credits + * consumed. Useful for monitoring usage patterns and debugging. + * + * **Legacy path:** `/logs` (still supported) + */ + fun create(): CompletableFuture = create(LogCreateParams.none()) + + /** @see create */ + fun create( + params: LogCreateParams = LogCreateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see create */ + fun create( + params: LogCreateParams = LogCreateParams.none() + ): CompletableFuture = create(params, RequestOptions.none()) + + /** @see create */ + fun create(requestOptions: RequestOptions): CompletableFuture = + create(LogCreateParams.none(), requestOptions) + + /** + * Get aggregated usage statistics grouped by feature. + * + * Useful for understanding which API features are being used most and tracking usage trends. + * + * **Legacy path:** `/logs/summary` (still supported) + */ + fun getSummary(): CompletableFuture = + getSummary(LogGetSummaryParams.none()) + + /** @see getSummary */ + fun getSummary( + params: LogGetSummaryParams = LogGetSummaryParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see getSummary */ + fun getSummary( + params: LogGetSummaryParams = LogGetSummaryParams.none() + ): CompletableFuture = getSummary(params, RequestOptions.none()) + + /** @see getSummary */ + fun getSummary(requestOptions: RequestOptions): CompletableFuture = + getSummary(LogGetSummaryParams.none(), requestOptions) + /** A view of [LogServiceAsync] that provides access to raw HTTP responses for each method. */ interface WithRawResponse { @@ -28,5 +85,55 @@ interface LogServiceAsync { * The original service is not modified. */ fun withOptions(modifier: Consumer): LogServiceAsync.WithRawResponse + + /** + * Returns a raw HTTP response for `post /v1/usage`, but is otherwise the same as + * [LogServiceAsync.create]. + */ + fun create(): CompletableFuture> = + create(LogCreateParams.none()) + + /** @see create */ + fun create( + params: LogCreateParams = LogCreateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see create */ + fun create( + params: LogCreateParams = LogCreateParams.none() + ): CompletableFuture> = + create(params, RequestOptions.none()) + + /** @see create */ + fun create( + requestOptions: RequestOptions + ): CompletableFuture> = + create(LogCreateParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `post /v1/usage/summary`, but is otherwise the same as + * [LogServiceAsync.getSummary]. + */ + fun getSummary(): CompletableFuture> = + getSummary(LogGetSummaryParams.none()) + + /** @see getSummary */ + fun getSummary( + params: LogGetSummaryParams = LogGetSummaryParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see getSummary */ + fun getSummary( + params: LogGetSummaryParams = LogGetSummaryParams.none() + ): CompletableFuture> = + getSummary(params, RequestOptions.none()) + + /** @see getSummary */ + fun getSummary( + requestOptions: RequestOptions + ): CompletableFuture> = + getSummary(LogGetSummaryParams.none(), requestOptions) } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/LogServiceAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/LogServiceAsyncImpl.kt index 6797075..a4bf0f2 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/LogServiceAsyncImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/LogServiceAsyncImpl.kt @@ -3,6 +3,23 @@ package com.cas_parser.api.services.async import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.handlers.errorBodyHandler +import com.cas_parser.api.core.handlers.errorHandler +import com.cas_parser.api.core.handlers.jsonHandler +import com.cas_parser.api.core.http.HttpMethod +import com.cas_parser.api.core.http.HttpRequest +import com.cas_parser.api.core.http.HttpResponse +import com.cas_parser.api.core.http.HttpResponse.Handler +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.core.http.json +import com.cas_parser.api.core.http.parseable +import com.cas_parser.api.core.prepareAsync +import com.cas_parser.api.models.logs.LogCreateParams +import com.cas_parser.api.models.logs.LogCreateResponse +import com.cas_parser.api.models.logs.LogGetSummaryParams +import com.cas_parser.api.models.logs.LogGetSummaryResponse +import java.util.concurrent.CompletableFuture import java.util.function.Consumer class LogServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : @@ -17,14 +34,93 @@ class LogServiceAsyncImpl internal constructor(private val clientOptions: Client override fun withOptions(modifier: Consumer): LogServiceAsync = LogServiceAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + override fun create( + params: LogCreateParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v1/usage + withRawResponse().create(params, requestOptions).thenApply { it.parse() } + + override fun getSummary( + params: LogGetSummaryParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v1/usage/summary + withRawResponse().getSummary(params, requestOptions).thenApply { it.parse() } + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : LogServiceAsync.WithRawResponse { + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + override fun withOptions( modifier: Consumer ): LogServiceAsync.WithRawResponse = LogServiceAsyncImpl.WithRawResponseImpl( clientOptions.toBuilder().apply(modifier::accept).build() ) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun create( + params: LogCreateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v1", "usage") + .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 { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + + private val getSummaryHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun getSummary( + params: LogGetSummaryParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v1", "usage", "summary") + .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 { getSummaryHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsync.kt index 4ff8c23..3d8b41e 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsync.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsync.kt @@ -3,6 +3,11 @@ package com.cas_parser.api.services.async import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.models.verifytoken.VerifyTokenVerifyParams +import com.cas_parser.api.models.verifytoken.VerifyTokenVerifyResponse +import java.util.concurrent.CompletableFuture import java.util.function.Consumer interface VerifyTokenServiceAsync { @@ -19,6 +24,25 @@ interface VerifyTokenServiceAsync { */ fun withOptions(modifier: Consumer): VerifyTokenServiceAsync + /** Verify an access token and check if it's still valid. Useful for debugging token issues. */ + fun verify(): CompletableFuture = + verify(VerifyTokenVerifyParams.none()) + + /** @see verify */ + fun verify( + params: VerifyTokenVerifyParams = VerifyTokenVerifyParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see verify */ + fun verify( + params: VerifyTokenVerifyParams = VerifyTokenVerifyParams.none() + ): CompletableFuture = verify(params, RequestOptions.none()) + + /** @see verify */ + fun verify(requestOptions: RequestOptions): CompletableFuture = + verify(VerifyTokenVerifyParams.none(), requestOptions) + /** * A view of [VerifyTokenServiceAsync] that provides access to raw HTTP responses for each * method. @@ -33,5 +57,30 @@ interface VerifyTokenServiceAsync { fun withOptions( modifier: Consumer ): VerifyTokenServiceAsync.WithRawResponse + + /** + * Returns a raw HTTP response for `post /v1/token/verify`, but is otherwise the same as + * [VerifyTokenServiceAsync.verify]. + */ + fun verify(): CompletableFuture> = + verify(VerifyTokenVerifyParams.none()) + + /** @see verify */ + fun verify( + params: VerifyTokenVerifyParams = VerifyTokenVerifyParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see verify */ + fun verify( + params: VerifyTokenVerifyParams = VerifyTokenVerifyParams.none() + ): CompletableFuture> = + verify(params, RequestOptions.none()) + + /** @see verify */ + fun verify( + requestOptions: RequestOptions + ): CompletableFuture> = + verify(VerifyTokenVerifyParams.none(), requestOptions) } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsyncImpl.kt index c617351..9a42c63 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsyncImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsyncImpl.kt @@ -3,6 +3,21 @@ package com.cas_parser.api.services.async import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.handlers.errorBodyHandler +import com.cas_parser.api.core.handlers.errorHandler +import com.cas_parser.api.core.handlers.jsonHandler +import com.cas_parser.api.core.http.HttpMethod +import com.cas_parser.api.core.http.HttpRequest +import com.cas_parser.api.core.http.HttpResponse +import com.cas_parser.api.core.http.HttpResponse.Handler +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.core.http.json +import com.cas_parser.api.core.http.parseable +import com.cas_parser.api.core.prepareAsync +import com.cas_parser.api.models.verifytoken.VerifyTokenVerifyParams +import com.cas_parser.api.models.verifytoken.VerifyTokenVerifyResponse +import java.util.concurrent.CompletableFuture import java.util.function.Consumer class VerifyTokenServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : @@ -17,14 +32,55 @@ class VerifyTokenServiceAsyncImpl internal constructor(private val clientOptions override fun withOptions(modifier: Consumer): VerifyTokenServiceAsync = VerifyTokenServiceAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + override fun verify( + params: VerifyTokenVerifyParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v1/token/verify + withRawResponse().verify(params, requestOptions).thenApply { it.parse() } + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : VerifyTokenServiceAsync.WithRawResponse { + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + override fun withOptions( modifier: Consumer ): VerifyTokenServiceAsync.WithRawResponse = VerifyTokenServiceAsyncImpl.WithRawResponseImpl( clientOptions.toBuilder().apply(modifier::accept).build() ) + + private val verifyHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun verify( + params: VerifyTokenVerifyParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v1", "token", "verify") + .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 { verifyHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/AccessTokenService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/AccessTokenService.kt index 2779802..784798e 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/AccessTokenService.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/AccessTokenService.kt @@ -3,6 +3,11 @@ package com.cas_parser.api.services.blocking import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.models.accesstoken.AccessTokenCreateParams +import com.cas_parser.api.models.accesstoken.AccessTokenCreateResponse +import com.google.errorprone.annotations.MustBeClosed import java.util.function.Consumer interface AccessTokenService { @@ -19,6 +24,37 @@ interface AccessTokenService { */ fun withOptions(modifier: Consumer): AccessTokenService + /** + * Generate a short-lived access token from your API key. + * + * **Use this endpoint from your backend** to create tokens that can be safely passed to + * frontend/SDK. + * + * **Legacy path:** `/v1/access-token` (still supported) + * + * Access tokens: + * - Are prefixed with `at_` for easy identification + * - Valid for up to 60 minutes + * - Can be used in place of API keys on all v4 endpoints + * - Cannot be used to generate other access tokens + */ + fun create(): AccessTokenCreateResponse = create(AccessTokenCreateParams.none()) + + /** @see create */ + fun create( + params: AccessTokenCreateParams = AccessTokenCreateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): AccessTokenCreateResponse + + /** @see create */ + fun create( + params: AccessTokenCreateParams = AccessTokenCreateParams.none() + ): AccessTokenCreateResponse = create(params, RequestOptions.none()) + + /** @see create */ + fun create(requestOptions: RequestOptions): AccessTokenCreateResponse = + create(AccessTokenCreateParams.none(), requestOptions) + /** * A view of [AccessTokenService] that provides access to raw HTTP responses for each method. */ @@ -32,5 +68,31 @@ interface AccessTokenService { fun withOptions( modifier: Consumer ): AccessTokenService.WithRawResponse + + /** + * Returns a raw HTTP response for `post /v1/token`, but is otherwise the same as + * [AccessTokenService.create]. + */ + @MustBeClosed + fun create(): HttpResponseFor = + create(AccessTokenCreateParams.none()) + + /** @see create */ + @MustBeClosed + fun create( + params: AccessTokenCreateParams = AccessTokenCreateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see create */ + @MustBeClosed + fun create( + params: AccessTokenCreateParams = AccessTokenCreateParams.none() + ): HttpResponseFor = create(params, RequestOptions.none()) + + /** @see create */ + @MustBeClosed + fun create(requestOptions: RequestOptions): HttpResponseFor = + create(AccessTokenCreateParams.none(), requestOptions) } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/AccessTokenServiceImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/AccessTokenServiceImpl.kt index a8c27c2..9fe0782 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/AccessTokenServiceImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/AccessTokenServiceImpl.kt @@ -3,6 +3,20 @@ package com.cas_parser.api.services.blocking import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.handlers.errorBodyHandler +import com.cas_parser.api.core.handlers.errorHandler +import com.cas_parser.api.core.handlers.jsonHandler +import com.cas_parser.api.core.http.HttpMethod +import com.cas_parser.api.core.http.HttpRequest +import com.cas_parser.api.core.http.HttpResponse +import com.cas_parser.api.core.http.HttpResponse.Handler +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.core.http.json +import com.cas_parser.api.core.http.parseable +import com.cas_parser.api.core.prepare +import com.cas_parser.api.models.accesstoken.AccessTokenCreateParams +import com.cas_parser.api.models.accesstoken.AccessTokenCreateResponse import java.util.function.Consumer class AccessTokenServiceImpl internal constructor(private val clientOptions: ClientOptions) : @@ -17,14 +31,52 @@ class AccessTokenServiceImpl internal constructor(private val clientOptions: Cli override fun withOptions(modifier: Consumer): AccessTokenService = AccessTokenServiceImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + override fun create( + params: AccessTokenCreateParams, + requestOptions: RequestOptions, + ): AccessTokenCreateResponse = + // post /v1/token + withRawResponse().create(params, requestOptions).parse() + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : AccessTokenService.WithRawResponse { + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + override fun withOptions( modifier: Consumer ): AccessTokenService.WithRawResponse = AccessTokenServiceImpl.WithRawResponseImpl( clientOptions.toBuilder().apply(modifier::accept).build() ) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun create( + params: AccessTokenCreateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v1", "token") + .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 { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CreditService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CreditService.kt index 60ebf10..0c7a9da 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CreditService.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CreditService.kt @@ -3,6 +3,11 @@ package com.cas_parser.api.services.blocking import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.models.credits.CreditCheckParams +import com.cas_parser.api.models.credits.CreditCheckResponse +import com.google.errorprone.annotations.MustBeClosed import java.util.function.Consumer interface CreditService { @@ -19,6 +24,32 @@ interface CreditService { */ fun withOptions(modifier: Consumer): CreditService + /** + * Check your remaining API credits and usage for the current billing period. + * + * Returns: + * - Number of API calls used and remaining credits + * - Credit limit and reset date + * - List of enabled features for your plan + * + * Credits reset at the start of each billing period. + */ + fun check(): CreditCheckResponse = check(CreditCheckParams.none()) + + /** @see check */ + fun check( + params: CreditCheckParams = CreditCheckParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CreditCheckResponse + + /** @see check */ + fun check(params: CreditCheckParams = CreditCheckParams.none()): CreditCheckResponse = + check(params, RequestOptions.none()) + + /** @see check */ + fun check(requestOptions: RequestOptions): CreditCheckResponse = + check(CreditCheckParams.none(), requestOptions) + /** A view of [CreditService] that provides access to raw HTTP responses for each method. */ interface WithRawResponse { @@ -28,5 +59,30 @@ interface CreditService { * The original service is not modified. */ fun withOptions(modifier: Consumer): CreditService.WithRawResponse + + /** + * Returns a raw HTTP response for `post /v1/credits`, but is otherwise the same as + * [CreditService.check]. + */ + @MustBeClosed + fun check(): HttpResponseFor = check(CreditCheckParams.none()) + + /** @see check */ + @MustBeClosed + fun check( + params: CreditCheckParams = CreditCheckParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see check */ + @MustBeClosed + fun check( + params: CreditCheckParams = CreditCheckParams.none() + ): HttpResponseFor = check(params, RequestOptions.none()) + + /** @see check */ + @MustBeClosed + fun check(requestOptions: RequestOptions): HttpResponseFor = + check(CreditCheckParams.none(), requestOptions) } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CreditServiceImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CreditServiceImpl.kt index a33b3c5..c611592 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CreditServiceImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CreditServiceImpl.kt @@ -3,6 +3,20 @@ package com.cas_parser.api.services.blocking import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.handlers.errorBodyHandler +import com.cas_parser.api.core.handlers.errorHandler +import com.cas_parser.api.core.handlers.jsonHandler +import com.cas_parser.api.core.http.HttpMethod +import com.cas_parser.api.core.http.HttpRequest +import com.cas_parser.api.core.http.HttpResponse +import com.cas_parser.api.core.http.HttpResponse.Handler +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.core.http.json +import com.cas_parser.api.core.http.parseable +import com.cas_parser.api.core.prepare +import com.cas_parser.api.models.credits.CreditCheckParams +import com.cas_parser.api.models.credits.CreditCheckResponse import java.util.function.Consumer class CreditServiceImpl internal constructor(private val clientOptions: ClientOptions) : @@ -17,14 +31,52 @@ class CreditServiceImpl internal constructor(private val clientOptions: ClientOp override fun withOptions(modifier: Consumer): CreditService = CreditServiceImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + override fun check( + params: CreditCheckParams, + requestOptions: RequestOptions, + ): CreditCheckResponse = + // post /v1/credits + withRawResponse().check(params, requestOptions).parse() + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : CreditService.WithRawResponse { + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + override fun withOptions( modifier: Consumer ): CreditService.WithRawResponse = CreditServiceImpl.WithRawResponseImpl( clientOptions.toBuilder().apply(modifier::accept).build() ) + + private val checkHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun check( + params: CreditCheckParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v1", "credits") + .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 { checkHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/InboundEmailService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/InboundEmailService.kt new file mode 100644 index 0000000..c46275e --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/InboundEmailService.kt @@ -0,0 +1,298 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.models.inboundemail.InboundEmailCreateParams +import com.cas_parser.api.models.inboundemail.InboundEmailCreateResponse +import com.cas_parser.api.models.inboundemail.InboundEmailDeleteParams +import com.cas_parser.api.models.inboundemail.InboundEmailDeleteResponse +import com.cas_parser.api.models.inboundemail.InboundEmailListParams +import com.cas_parser.api.models.inboundemail.InboundEmailListResponse +import com.cas_parser.api.models.inboundemail.InboundEmailRetrieveParams +import com.cas_parser.api.models.inboundemail.InboundEmailRetrieveResponse +import com.google.errorprone.annotations.MustBeClosed +import java.util.function.Consumer + +interface InboundEmailService { + + /** + * 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): InboundEmailService + + /** + * Create a dedicated inbound email address for collecting CAS statements via email forwarding. + * + * **How it works:** + * 1. Create an inbound email with your webhook URL + * 2. Display the email address to your user (e.g., "Forward your CAS to + * ie_xxx@import.casparser.in") + * 3. When an investor forwards a CAS email, we verify the sender and deliver to your webhook + * + * **Webhook Delivery:** + * - We POST to your `callback_url` with JSON body containing files (matching EmailCASFile + * schema) + * - Failed deliveries are retried automatically with exponential backoff + * + * **Inactivity:** + * - Inbound emails with no activity in 30 days are marked inactive + * - Active inbound emails remain operational indefinitely + */ + fun create(params: InboundEmailCreateParams): InboundEmailCreateResponse = + create(params, RequestOptions.none()) + + /** @see create */ + fun create( + params: InboundEmailCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): InboundEmailCreateResponse + + /** Retrieve details of a specific mailbox including statistics. */ + fun retrieve(inboundEmailId: String): InboundEmailRetrieveResponse = + retrieve(inboundEmailId, InboundEmailRetrieveParams.none()) + + /** @see retrieve */ + fun retrieve( + inboundEmailId: String, + params: InboundEmailRetrieveParams = InboundEmailRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): InboundEmailRetrieveResponse = + retrieve(params.toBuilder().inboundEmailId(inboundEmailId).build(), requestOptions) + + /** @see retrieve */ + fun retrieve( + inboundEmailId: String, + params: InboundEmailRetrieveParams = InboundEmailRetrieveParams.none(), + ): InboundEmailRetrieveResponse = retrieve(inboundEmailId, params, RequestOptions.none()) + + /** @see retrieve */ + fun retrieve( + params: InboundEmailRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): InboundEmailRetrieveResponse + + /** @see retrieve */ + fun retrieve(params: InboundEmailRetrieveParams): InboundEmailRetrieveResponse = + retrieve(params, RequestOptions.none()) + + /** @see retrieve */ + fun retrieve( + inboundEmailId: String, + requestOptions: RequestOptions, + ): InboundEmailRetrieveResponse = + retrieve(inboundEmailId, InboundEmailRetrieveParams.none(), requestOptions) + + /** + * List all mailboxes associated with your API key. Returns active and inactive mailboxes + * (deleted mailboxes are excluded). + */ + fun list(): InboundEmailListResponse = list(InboundEmailListParams.none()) + + /** @see list */ + fun list( + params: InboundEmailListParams = InboundEmailListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): InboundEmailListResponse + + /** @see list */ + fun list( + params: InboundEmailListParams = InboundEmailListParams.none() + ): InboundEmailListResponse = list(params, RequestOptions.none()) + + /** @see list */ + fun list(requestOptions: RequestOptions): InboundEmailListResponse = + list(InboundEmailListParams.none(), requestOptions) + + /** + * Permanently delete an inbound email address. It will stop accepting emails. + * + * **Note:** Deletion is immediate and cannot be undone. Any emails received after deletion will + * be rejected. + */ + fun delete(inboundEmailId: String): InboundEmailDeleteResponse = + delete(inboundEmailId, InboundEmailDeleteParams.none()) + + /** @see delete */ + fun delete( + inboundEmailId: String, + params: InboundEmailDeleteParams = InboundEmailDeleteParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): InboundEmailDeleteResponse = + delete(params.toBuilder().inboundEmailId(inboundEmailId).build(), requestOptions) + + /** @see delete */ + fun delete( + inboundEmailId: String, + params: InboundEmailDeleteParams = InboundEmailDeleteParams.none(), + ): InboundEmailDeleteResponse = delete(inboundEmailId, params, RequestOptions.none()) + + /** @see delete */ + fun delete( + params: InboundEmailDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): InboundEmailDeleteResponse + + /** @see delete */ + fun delete(params: InboundEmailDeleteParams): InboundEmailDeleteResponse = + delete(params, RequestOptions.none()) + + /** @see delete */ + fun delete(inboundEmailId: String, requestOptions: RequestOptions): InboundEmailDeleteResponse = + delete(inboundEmailId, InboundEmailDeleteParams.none(), requestOptions) + + /** + * A view of [InboundEmailService] 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 + ): InboundEmailService.WithRawResponse + + /** + * Returns a raw HTTP response for `post /v4/inbound-email`, but is otherwise the same as + * [InboundEmailService.create]. + */ + @MustBeClosed + fun create(params: InboundEmailCreateParams): HttpResponseFor = + create(params, RequestOptions.none()) + + /** @see create */ + @MustBeClosed + fun create( + params: InboundEmailCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `get /v4/inbound-email/{inbound_email_id}`, but is + * otherwise the same as [InboundEmailService.retrieve]. + */ + @MustBeClosed + fun retrieve(inboundEmailId: String): HttpResponseFor = + retrieve(inboundEmailId, InboundEmailRetrieveParams.none()) + + /** @see retrieve */ + @MustBeClosed + fun retrieve( + inboundEmailId: String, + params: InboundEmailRetrieveParams = InboundEmailRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + retrieve(params.toBuilder().inboundEmailId(inboundEmailId).build(), requestOptions) + + /** @see retrieve */ + @MustBeClosed + fun retrieve( + inboundEmailId: String, + params: InboundEmailRetrieveParams = InboundEmailRetrieveParams.none(), + ): HttpResponseFor = + retrieve(inboundEmailId, params, RequestOptions.none()) + + /** @see retrieve */ + @MustBeClosed + fun retrieve( + params: InboundEmailRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see retrieve */ + @MustBeClosed + fun retrieve( + params: InboundEmailRetrieveParams + ): HttpResponseFor = retrieve(params, RequestOptions.none()) + + /** @see retrieve */ + @MustBeClosed + fun retrieve( + inboundEmailId: String, + requestOptions: RequestOptions, + ): HttpResponseFor = + retrieve(inboundEmailId, InboundEmailRetrieveParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `get /v4/inbound-email`, but is otherwise the same as + * [InboundEmailService.list]. + */ + @MustBeClosed + fun list(): HttpResponseFor = list(InboundEmailListParams.none()) + + /** @see list */ + @MustBeClosed + fun list( + params: InboundEmailListParams = InboundEmailListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see list */ + @MustBeClosed + fun list( + params: InboundEmailListParams = InboundEmailListParams.none() + ): HttpResponseFor = list(params, RequestOptions.none()) + + /** @see list */ + @MustBeClosed + fun list(requestOptions: RequestOptions): HttpResponseFor = + list(InboundEmailListParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `delete /v4/inbound-email/{inbound_email_id}`, but is + * otherwise the same as [InboundEmailService.delete]. + */ + @MustBeClosed + fun delete(inboundEmailId: String): HttpResponseFor = + delete(inboundEmailId, InboundEmailDeleteParams.none()) + + /** @see delete */ + @MustBeClosed + fun delete( + inboundEmailId: String, + params: InboundEmailDeleteParams = InboundEmailDeleteParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + delete(params.toBuilder().inboundEmailId(inboundEmailId).build(), requestOptions) + + /** @see delete */ + @MustBeClosed + fun delete( + inboundEmailId: String, + params: InboundEmailDeleteParams = InboundEmailDeleteParams.none(), + ): HttpResponseFor = + delete(inboundEmailId, params, RequestOptions.none()) + + /** @see delete */ + @MustBeClosed + fun delete( + params: InboundEmailDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see delete */ + @MustBeClosed + fun delete(params: InboundEmailDeleteParams): HttpResponseFor = + delete(params, RequestOptions.none()) + + /** @see delete */ + @MustBeClosed + fun delete( + inboundEmailId: String, + requestOptions: RequestOptions, + ): HttpResponseFor = + delete(inboundEmailId, InboundEmailDeleteParams.none(), requestOptions) + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/InboundEmailServiceImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/InboundEmailServiceImpl.kt new file mode 100644 index 0000000..b0aefb3 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/InboundEmailServiceImpl.kt @@ -0,0 +1,199 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.checkRequired +import com.cas_parser.api.core.handlers.errorBodyHandler +import com.cas_parser.api.core.handlers.errorHandler +import com.cas_parser.api.core.handlers.jsonHandler +import com.cas_parser.api.core.http.HttpMethod +import com.cas_parser.api.core.http.HttpRequest +import com.cas_parser.api.core.http.HttpResponse +import com.cas_parser.api.core.http.HttpResponse.Handler +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.core.http.json +import com.cas_parser.api.core.http.parseable +import com.cas_parser.api.core.prepare +import com.cas_parser.api.models.inboundemail.InboundEmailCreateParams +import com.cas_parser.api.models.inboundemail.InboundEmailCreateResponse +import com.cas_parser.api.models.inboundemail.InboundEmailDeleteParams +import com.cas_parser.api.models.inboundemail.InboundEmailDeleteResponse +import com.cas_parser.api.models.inboundemail.InboundEmailListParams +import com.cas_parser.api.models.inboundemail.InboundEmailListResponse +import com.cas_parser.api.models.inboundemail.InboundEmailRetrieveParams +import com.cas_parser.api.models.inboundemail.InboundEmailRetrieveResponse +import java.util.function.Consumer +import kotlin.jvm.optionals.getOrNull + +class InboundEmailServiceImpl internal constructor(private val clientOptions: ClientOptions) : + InboundEmailService { + + private val withRawResponse: InboundEmailService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): InboundEmailService.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): InboundEmailService = + InboundEmailServiceImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun create( + params: InboundEmailCreateParams, + requestOptions: RequestOptions, + ): InboundEmailCreateResponse = + // post /v4/inbound-email + withRawResponse().create(params, requestOptions).parse() + + override fun retrieve( + params: InboundEmailRetrieveParams, + requestOptions: RequestOptions, + ): InboundEmailRetrieveResponse = + // get /v4/inbound-email/{inbound_email_id} + withRawResponse().retrieve(params, requestOptions).parse() + + override fun list( + params: InboundEmailListParams, + requestOptions: RequestOptions, + ): InboundEmailListResponse = + // get /v4/inbound-email + withRawResponse().list(params, requestOptions).parse() + + override fun delete( + params: InboundEmailDeleteParams, + requestOptions: RequestOptions, + ): InboundEmailDeleteResponse = + // delete /v4/inbound-email/{inbound_email_id} + withRawResponse().delete(params, requestOptions).parse() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + InboundEmailService.WithRawResponse { + + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + + override fun withOptions( + modifier: Consumer + ): InboundEmailService.WithRawResponse = + InboundEmailServiceImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun create( + params: InboundEmailCreateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v4", "inbound-email") + .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 { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun retrieve( + params: InboundEmailRetrieveParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("inboundEmailId", params.inboundEmailId().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v4", "inbound-email", params._pathParam(0)) + .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() + } + } + } + } + + private val listHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun list( + params: InboundEmailListParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v4", "inbound-email") + .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 { listHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + + private val deleteHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun delete( + params: InboundEmailDeleteParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("inboundEmailId", params.inboundEmailId().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v4", "inbound-email", params._pathParam(0)) + .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 { deleteHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/LogService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/LogService.kt index f95703a..7361743 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/LogService.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/LogService.kt @@ -3,6 +3,13 @@ package com.cas_parser.api.services.blocking import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.models.logs.LogCreateParams +import com.cas_parser.api.models.logs.LogCreateResponse +import com.cas_parser.api.models.logs.LogGetSummaryParams +import com.cas_parser.api.models.logs.LogGetSummaryResponse +import com.google.errorprone.annotations.MustBeClosed import java.util.function.Consumer interface LogService { @@ -19,6 +26,54 @@ interface LogService { */ fun withOptions(modifier: Consumer): LogService + /** + * Retrieve detailed API usage logs for your account. + * + * Returns a list of API calls with timestamps, features used, status codes, and credits + * consumed. Useful for monitoring usage patterns and debugging. + * + * **Legacy path:** `/logs` (still supported) + */ + fun create(): LogCreateResponse = create(LogCreateParams.none()) + + /** @see create */ + fun create( + params: LogCreateParams = LogCreateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): LogCreateResponse + + /** @see create */ + fun create(params: LogCreateParams = LogCreateParams.none()): LogCreateResponse = + create(params, RequestOptions.none()) + + /** @see create */ + fun create(requestOptions: RequestOptions): LogCreateResponse = + create(LogCreateParams.none(), requestOptions) + + /** + * Get aggregated usage statistics grouped by feature. + * + * Useful for understanding which API features are being used most and tracking usage trends. + * + * **Legacy path:** `/logs/summary` (still supported) + */ + fun getSummary(): LogGetSummaryResponse = getSummary(LogGetSummaryParams.none()) + + /** @see getSummary */ + fun getSummary( + params: LogGetSummaryParams = LogGetSummaryParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): LogGetSummaryResponse + + /** @see getSummary */ + fun getSummary( + params: LogGetSummaryParams = LogGetSummaryParams.none() + ): LogGetSummaryResponse = getSummary(params, RequestOptions.none()) + + /** @see getSummary */ + fun getSummary(requestOptions: RequestOptions): LogGetSummaryResponse = + getSummary(LogGetSummaryParams.none(), requestOptions) + /** A view of [LogService] that provides access to raw HTTP responses for each method. */ interface WithRawResponse { @@ -28,5 +83,56 @@ interface LogService { * The original service is not modified. */ fun withOptions(modifier: Consumer): LogService.WithRawResponse + + /** + * Returns a raw HTTP response for `post /v1/usage`, but is otherwise the same as + * [LogService.create]. + */ + @MustBeClosed + fun create(): HttpResponseFor = create(LogCreateParams.none()) + + /** @see create */ + @MustBeClosed + fun create( + params: LogCreateParams = LogCreateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see create */ + @MustBeClosed + fun create( + params: LogCreateParams = LogCreateParams.none() + ): HttpResponseFor = create(params, RequestOptions.none()) + + /** @see create */ + @MustBeClosed + fun create(requestOptions: RequestOptions): HttpResponseFor = + create(LogCreateParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `post /v1/usage/summary`, but is otherwise the same as + * [LogService.getSummary]. + */ + @MustBeClosed + fun getSummary(): HttpResponseFor = + getSummary(LogGetSummaryParams.none()) + + /** @see getSummary */ + @MustBeClosed + fun getSummary( + params: LogGetSummaryParams = LogGetSummaryParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see getSummary */ + @MustBeClosed + fun getSummary( + params: LogGetSummaryParams = LogGetSummaryParams.none() + ): HttpResponseFor = getSummary(params, RequestOptions.none()) + + /** @see getSummary */ + @MustBeClosed + fun getSummary(requestOptions: RequestOptions): HttpResponseFor = + getSummary(LogGetSummaryParams.none(), requestOptions) } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/LogServiceImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/LogServiceImpl.kt index 0a82263..4dce634 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/LogServiceImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/LogServiceImpl.kt @@ -3,6 +3,22 @@ package com.cas_parser.api.services.blocking import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.handlers.errorBodyHandler +import com.cas_parser.api.core.handlers.errorHandler +import com.cas_parser.api.core.handlers.jsonHandler +import com.cas_parser.api.core.http.HttpMethod +import com.cas_parser.api.core.http.HttpRequest +import com.cas_parser.api.core.http.HttpResponse +import com.cas_parser.api.core.http.HttpResponse.Handler +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.core.http.json +import com.cas_parser.api.core.http.parseable +import com.cas_parser.api.core.prepare +import com.cas_parser.api.models.logs.LogCreateParams +import com.cas_parser.api.models.logs.LogCreateResponse +import com.cas_parser.api.models.logs.LogGetSummaryParams +import com.cas_parser.api.models.logs.LogGetSummaryResponse import java.util.function.Consumer class LogServiceImpl internal constructor(private val clientOptions: ClientOptions) : LogService { @@ -16,14 +32,87 @@ class LogServiceImpl internal constructor(private val clientOptions: ClientOptio override fun withOptions(modifier: Consumer): LogService = LogServiceImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + override fun create( + params: LogCreateParams, + requestOptions: RequestOptions, + ): LogCreateResponse = + // post /v1/usage + withRawResponse().create(params, requestOptions).parse() + + override fun getSummary( + params: LogGetSummaryParams, + requestOptions: RequestOptions, + ): LogGetSummaryResponse = + // post /v1/usage/summary + withRawResponse().getSummary(params, requestOptions).parse() + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : LogService.WithRawResponse { + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + override fun withOptions( modifier: Consumer ): LogService.WithRawResponse = LogServiceImpl.WithRawResponseImpl( clientOptions.toBuilder().apply(modifier::accept).build() ) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun create( + params: LogCreateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v1", "usage") + .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 { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + + private val getSummaryHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun getSummary( + params: LogGetSummaryParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v1", "usage", "summary") + .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 { getSummaryHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/VerifyTokenService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/VerifyTokenService.kt index a44e1df..e8135cd 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/VerifyTokenService.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/VerifyTokenService.kt @@ -3,6 +3,11 @@ package com.cas_parser.api.services.blocking import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.models.verifytoken.VerifyTokenVerifyParams +import com.cas_parser.api.models.verifytoken.VerifyTokenVerifyResponse +import com.google.errorprone.annotations.MustBeClosed import java.util.function.Consumer interface VerifyTokenService { @@ -19,6 +24,24 @@ interface VerifyTokenService { */ fun withOptions(modifier: Consumer): VerifyTokenService + /** Verify an access token and check if it's still valid. Useful for debugging token issues. */ + fun verify(): VerifyTokenVerifyResponse = verify(VerifyTokenVerifyParams.none()) + + /** @see verify */ + fun verify( + params: VerifyTokenVerifyParams = VerifyTokenVerifyParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): VerifyTokenVerifyResponse + + /** @see verify */ + fun verify( + params: VerifyTokenVerifyParams = VerifyTokenVerifyParams.none() + ): VerifyTokenVerifyResponse = verify(params, RequestOptions.none()) + + /** @see verify */ + fun verify(requestOptions: RequestOptions): VerifyTokenVerifyResponse = + verify(VerifyTokenVerifyParams.none(), requestOptions) + /** * A view of [VerifyTokenService] that provides access to raw HTTP responses for each method. */ @@ -32,5 +55,31 @@ interface VerifyTokenService { fun withOptions( modifier: Consumer ): VerifyTokenService.WithRawResponse + + /** + * Returns a raw HTTP response for `post /v1/token/verify`, but is otherwise the same as + * [VerifyTokenService.verify]. + */ + @MustBeClosed + fun verify(): HttpResponseFor = + verify(VerifyTokenVerifyParams.none()) + + /** @see verify */ + @MustBeClosed + fun verify( + params: VerifyTokenVerifyParams = VerifyTokenVerifyParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see verify */ + @MustBeClosed + fun verify( + params: VerifyTokenVerifyParams = VerifyTokenVerifyParams.none() + ): HttpResponseFor = verify(params, RequestOptions.none()) + + /** @see verify */ + @MustBeClosed + fun verify(requestOptions: RequestOptions): HttpResponseFor = + verify(VerifyTokenVerifyParams.none(), requestOptions) } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/VerifyTokenServiceImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/VerifyTokenServiceImpl.kt index e202bbc..bf3fce7 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/VerifyTokenServiceImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/VerifyTokenServiceImpl.kt @@ -3,6 +3,20 @@ package com.cas_parser.api.services.blocking import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.handlers.errorBodyHandler +import com.cas_parser.api.core.handlers.errorHandler +import com.cas_parser.api.core.handlers.jsonHandler +import com.cas_parser.api.core.http.HttpMethod +import com.cas_parser.api.core.http.HttpRequest +import com.cas_parser.api.core.http.HttpResponse +import com.cas_parser.api.core.http.HttpResponse.Handler +import com.cas_parser.api.core.http.HttpResponseFor +import com.cas_parser.api.core.http.json +import com.cas_parser.api.core.http.parseable +import com.cas_parser.api.core.prepare +import com.cas_parser.api.models.verifytoken.VerifyTokenVerifyParams +import com.cas_parser.api.models.verifytoken.VerifyTokenVerifyResponse import java.util.function.Consumer class VerifyTokenServiceImpl internal constructor(private val clientOptions: ClientOptions) : @@ -17,14 +31,52 @@ class VerifyTokenServiceImpl internal constructor(private val clientOptions: Cli override fun withOptions(modifier: Consumer): VerifyTokenService = VerifyTokenServiceImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + override fun verify( + params: VerifyTokenVerifyParams, + requestOptions: RequestOptions, + ): VerifyTokenVerifyResponse = + // post /v1/token/verify + withRawResponse().verify(params, requestOptions).parse() + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : VerifyTokenService.WithRawResponse { + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + override fun withOptions( modifier: Consumer ): VerifyTokenService.WithRawResponse = VerifyTokenServiceImpl.WithRawResponseImpl( clientOptions.toBuilder().apply(modifier::accept).build() ) + + private val verifyHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun verify( + params: VerifyTokenVerifyParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v1", "token", "verify") + .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 { verifyHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } } } diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateParamsTest.kt new file mode 100644 index 0000000..a6a696b --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateParamsTest.kt @@ -0,0 +1,30 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.accesstoken + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class AccessTokenCreateParamsTest { + + @Test + fun create() { + AccessTokenCreateParams.builder().expiryMinutes(60L).build() + } + + @Test + fun body() { + val params = AccessTokenCreateParams.builder().expiryMinutes(60L).build() + + val body = params._body() + + assertThat(body.expiryMinutes()).contains(60L) + } + + @Test + fun bodyWithoutOptionalFields() { + val params = AccessTokenCreateParams.builder().build() + + val body = params._body() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateResponseTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateResponseTest.kt new file mode 100644 index 0000000..09382b7 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateResponseTest.kt @@ -0,0 +1,45 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.accesstoken + +import com.cas_parser.api.core.jsonMapper +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class AccessTokenCreateResponseTest { + + @Test + fun create() { + val accessTokenCreateResponse = + AccessTokenCreateResponse.builder() + .accessToken("at_eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...") + .expiresIn(3600L) + .tokenType("api_key") + .build() + + assertThat(accessTokenCreateResponse.accessToken()) + .contains("at_eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...") + assertThat(accessTokenCreateResponse.expiresIn()).contains(3600L) + assertThat(accessTokenCreateResponse.tokenType()).contains("api_key") + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val accessTokenCreateResponse = + AccessTokenCreateResponse.builder() + .accessToken("at_eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...") + .expiresIn(3600L) + .tokenType("api_key") + .build() + + val roundtrippedAccessTokenCreateResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(accessTokenCreateResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedAccessTokenCreateResponse).isEqualTo(accessTokenCreateResponse) + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/credits/CreditCheckParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/credits/CreditCheckParamsTest.kt new file mode 100644 index 0000000..b26664b --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/credits/CreditCheckParamsTest.kt @@ -0,0 +1,13 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.credits + +import org.junit.jupiter.api.Test + +internal class CreditCheckParamsTest { + + @Test + fun create() { + CreditCheckParams.builder().build() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/credits/CreditCheckResponseTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/credits/CreditCheckResponseTest.kt new file mode 100644 index 0000000..17d52f9 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/credits/CreditCheckResponseTest.kt @@ -0,0 +1,61 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.credits + +import com.cas_parser.api.core.jsonMapper +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import java.time.OffsetDateTime +import kotlin.jvm.optionals.getOrNull +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class CreditCheckResponseTest { + + @Test + fun create() { + val creditCheckResponse = + CreditCheckResponse.builder() + .enabledFeatures( + listOf("cams_kfintech_cas_parser", "cdsl_cas_parser", "nsdl_cas_parser") + ) + .isUnlimited(false) + .limit(50L) + .remaining(35.0) + .resetsAt(OffsetDateTime.parse("2026-02-15T00:00:00Z")) + .used(15.0) + .build() + + assertThat(creditCheckResponse.enabledFeatures().getOrNull()) + .containsExactly("cams_kfintech_cas_parser", "cdsl_cas_parser", "nsdl_cas_parser") + assertThat(creditCheckResponse.isUnlimited()).contains(false) + assertThat(creditCheckResponse.limit()).contains(50L) + assertThat(creditCheckResponse.remaining()).contains(35.0) + assertThat(creditCheckResponse.resetsAt()) + .contains(OffsetDateTime.parse("2026-02-15T00:00:00Z")) + assertThat(creditCheckResponse.used()).contains(15.0) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val creditCheckResponse = + CreditCheckResponse.builder() + .enabledFeatures( + listOf("cams_kfintech_cas_parser", "cdsl_cas_parser", "nsdl_cas_parser") + ) + .isUnlimited(false) + .limit(50L) + .remaining(35.0) + .resetsAt(OffsetDateTime.parse("2026-02-15T00:00:00Z")) + .used(15.0) + .build() + + val roundtrippedCreditCheckResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(creditCheckResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedCreditCheckResponse).isEqualTo(creditCheckResponse) + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateParamsTest.kt new file mode 100644 index 0000000..900b778 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateParamsTest.kt @@ -0,0 +1,76 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.inboundemail + +import com.cas_parser.api.core.JsonValue +import kotlin.jvm.optionals.getOrNull +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class InboundEmailCreateParamsTest { + + @Test + fun create() { + InboundEmailCreateParams.builder() + .callbackUrl("https://api.yourapp.com/webhooks/cas-email") + .alias("john-portfolio") + .addAllowedSource(InboundEmailCreateParams.AllowedSource.CDSL) + .addAllowedSource(InboundEmailCreateParams.AllowedSource.NSDL) + .metadata( + InboundEmailCreateParams.Metadata.builder() + .putAdditionalProperty("plan", JsonValue.from("premium")) + .putAdditionalProperty("source", JsonValue.from("onboarding")) + .build() + ) + .reference("user_12345") + .build() + } + + @Test + fun body() { + val params = + InboundEmailCreateParams.builder() + .callbackUrl("https://api.yourapp.com/webhooks/cas-email") + .alias("john-portfolio") + .addAllowedSource(InboundEmailCreateParams.AllowedSource.CDSL) + .addAllowedSource(InboundEmailCreateParams.AllowedSource.NSDL) + .metadata( + InboundEmailCreateParams.Metadata.builder() + .putAdditionalProperty("plan", JsonValue.from("premium")) + .putAdditionalProperty("source", JsonValue.from("onboarding")) + .build() + ) + .reference("user_12345") + .build() + + val body = params._body() + + assertThat(body.callbackUrl()).isEqualTo("https://api.yourapp.com/webhooks/cas-email") + assertThat(body.alias()).contains("john-portfolio") + assertThat(body.allowedSources().getOrNull()) + .containsExactly( + InboundEmailCreateParams.AllowedSource.CDSL, + InboundEmailCreateParams.AllowedSource.NSDL, + ) + assertThat(body.metadata()) + .contains( + InboundEmailCreateParams.Metadata.builder() + .putAdditionalProperty("plan", JsonValue.from("premium")) + .putAdditionalProperty("source", JsonValue.from("onboarding")) + .build() + ) + assertThat(body.reference()).contains("user_12345") + } + + @Test + fun bodyWithoutOptionalFields() { + val params = + InboundEmailCreateParams.builder() + .callbackUrl("https://api.yourapp.com/webhooks/cas-email") + .build() + + val body = params._body() + + assertThat(body.callbackUrl()).isEqualTo("https://api.yourapp.com/webhooks/cas-email") + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateResponseTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateResponseTest.kt new file mode 100644 index 0000000..1fbdbd1 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateResponseTest.kt @@ -0,0 +1,89 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.inboundemail + +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.jsonMapper +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import java.time.OffsetDateTime +import kotlin.jvm.optionals.getOrNull +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class InboundEmailCreateResponseTest { + + @Test + fun create() { + val inboundEmailCreateResponse = + InboundEmailCreateResponse.builder() + .addAllowedSource(InboundEmailCreateResponse.AllowedSource.CDSL) + .addAllowedSource(InboundEmailCreateResponse.AllowedSource.NSDL) + .callbackUrl("https://api.yourapp.com/webhooks/cas-email") + .createdAt(OffsetDateTime.parse("2025-02-21T10:30:00Z")) + .email("ie_a1b2c3d4e5f6@import.casparser.in") + .inboundEmailId("ie_a1b2c3d4e5f6") + .metadata( + InboundEmailCreateResponse.Metadata.builder() + .putAdditionalProperty("plan", JsonValue.from("premium")) + .build() + ) + .reference("user_12345") + .status(InboundEmailCreateResponse.Status.ACTIVE) + .updatedAt(OffsetDateTime.parse("2025-02-21T10:30:00Z")) + .build() + + assertThat(inboundEmailCreateResponse.allowedSources().getOrNull()) + .containsExactly( + InboundEmailCreateResponse.AllowedSource.CDSL, + InboundEmailCreateResponse.AllowedSource.NSDL, + ) + assertThat(inboundEmailCreateResponse.callbackUrl()) + .contains("https://api.yourapp.com/webhooks/cas-email") + assertThat(inboundEmailCreateResponse.createdAt()) + .contains(OffsetDateTime.parse("2025-02-21T10:30:00Z")) + assertThat(inboundEmailCreateResponse.email()) + .contains("ie_a1b2c3d4e5f6@import.casparser.in") + assertThat(inboundEmailCreateResponse.inboundEmailId()).contains("ie_a1b2c3d4e5f6") + assertThat(inboundEmailCreateResponse.metadata()) + .contains( + InboundEmailCreateResponse.Metadata.builder() + .putAdditionalProperty("plan", JsonValue.from("premium")) + .build() + ) + assertThat(inboundEmailCreateResponse.reference()).contains("user_12345") + assertThat(inboundEmailCreateResponse.status()) + .contains(InboundEmailCreateResponse.Status.ACTIVE) + assertThat(inboundEmailCreateResponse.updatedAt()) + .contains(OffsetDateTime.parse("2025-02-21T10:30:00Z")) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val inboundEmailCreateResponse = + InboundEmailCreateResponse.builder() + .addAllowedSource(InboundEmailCreateResponse.AllowedSource.CDSL) + .addAllowedSource(InboundEmailCreateResponse.AllowedSource.NSDL) + .callbackUrl("https://api.yourapp.com/webhooks/cas-email") + .createdAt(OffsetDateTime.parse("2025-02-21T10:30:00Z")) + .email("ie_a1b2c3d4e5f6@import.casparser.in") + .inboundEmailId("ie_a1b2c3d4e5f6") + .metadata( + InboundEmailCreateResponse.Metadata.builder() + .putAdditionalProperty("plan", JsonValue.from("premium")) + .build() + ) + .reference("user_12345") + .status(InboundEmailCreateResponse.Status.ACTIVE) + .updatedAt(OffsetDateTime.parse("2025-02-21T10:30:00Z")) + .build() + + val roundtrippedInboundEmailCreateResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(inboundEmailCreateResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedInboundEmailCreateResponse).isEqualTo(inboundEmailCreateResponse) + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailDeleteParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailDeleteParamsTest.kt new file mode 100644 index 0000000..917b4ee --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailDeleteParamsTest.kt @@ -0,0 +1,23 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.inboundemail + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class InboundEmailDeleteParamsTest { + + @Test + fun create() { + InboundEmailDeleteParams.builder().inboundEmailId("inbound_email_id").build() + } + + @Test + fun pathParams() { + val params = InboundEmailDeleteParams.builder().inboundEmailId("inbound_email_id").build() + + assertThat(params._pathParam(0)).isEqualTo("inbound_email_id") + // out-of-bound path param + assertThat(params._pathParam(1)).isEqualTo("") + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailDeleteResponseTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailDeleteResponseTest.kt new file mode 100644 index 0000000..0c8f6fe --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailDeleteResponseTest.kt @@ -0,0 +1,41 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.inboundemail + +import com.cas_parser.api.core.jsonMapper +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class InboundEmailDeleteResponseTest { + + @Test + fun create() { + val inboundEmailDeleteResponse = + InboundEmailDeleteResponse.builder() + .msg("Mailbox deleted successfully") + .status("success") + .build() + + assertThat(inboundEmailDeleteResponse.msg()).contains("Mailbox deleted successfully") + assertThat(inboundEmailDeleteResponse.status()).contains("success") + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val inboundEmailDeleteResponse = + InboundEmailDeleteResponse.builder() + .msg("Mailbox deleted successfully") + .status("success") + .build() + + val roundtrippedInboundEmailDeleteResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(inboundEmailDeleteResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedInboundEmailDeleteResponse).isEqualTo(inboundEmailDeleteResponse) + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailListParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailListParamsTest.kt new file mode 100644 index 0000000..b0dfb9d --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailListParamsTest.kt @@ -0,0 +1,49 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.inboundemail + +import com.cas_parser.api.core.http.QueryParams +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class InboundEmailListParamsTest { + + @Test + fun create() { + InboundEmailListParams.builder() + .limit(1L) + .offset(0L) + .status(InboundEmailListParams.Status.ACTIVE) + .build() + } + + @Test + fun queryParams() { + val params = + InboundEmailListParams.builder() + .limit(1L) + .offset(0L) + .status(InboundEmailListParams.Status.ACTIVE) + .build() + + val queryParams = params._queryParams() + + assertThat(queryParams) + .isEqualTo( + QueryParams.builder() + .put("limit", "1") + .put("offset", "0") + .put("status", "active") + .build() + ) + } + + @Test + fun queryParamsWithoutOptionalFields() { + val params = InboundEmailListParams.builder().build() + + val queryParams = params._queryParams() + + assertThat(queryParams).isEqualTo(QueryParams.builder().build()) + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailListResponseTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailListResponseTest.kt new file mode 100644 index 0000000..ff243b8 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailListResponseTest.kt @@ -0,0 +1,105 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.inboundemail + +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.jsonMapper +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import java.time.OffsetDateTime +import kotlin.jvm.optionals.getOrNull +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class InboundEmailListResponseTest { + + @Test + fun create() { + val inboundEmailListResponse = + InboundEmailListResponse.builder() + .addInboundEmail( + InboundEmailListResponse.InboundEmail.builder() + .addAllowedSource(InboundEmailListResponse.InboundEmail.AllowedSource.CDSL) + .addAllowedSource(InboundEmailListResponse.InboundEmail.AllowedSource.NSDL) + .callbackUrl("https://api.yourapp.com/webhooks/cas-email") + .createdAt(OffsetDateTime.parse("2025-02-21T10:30:00Z")) + .email("ie_a1b2c3d4e5f6@import.casparser.in") + .inboundEmailId("ie_a1b2c3d4e5f6") + .metadata( + InboundEmailListResponse.InboundEmail.Metadata.builder() + .putAdditionalProperty("plan", JsonValue.from("premium")) + .build() + ) + .reference("user_12345") + .status(InboundEmailListResponse.InboundEmail.Status.ACTIVE) + .updatedAt(OffsetDateTime.parse("2025-02-21T10:30:00Z")) + .build() + ) + .limit(50L) + .offset(0L) + .status("success") + .total(15L) + .build() + + assertThat(inboundEmailListResponse.inboundEmails().getOrNull()) + .containsExactly( + InboundEmailListResponse.InboundEmail.builder() + .addAllowedSource(InboundEmailListResponse.InboundEmail.AllowedSource.CDSL) + .addAllowedSource(InboundEmailListResponse.InboundEmail.AllowedSource.NSDL) + .callbackUrl("https://api.yourapp.com/webhooks/cas-email") + .createdAt(OffsetDateTime.parse("2025-02-21T10:30:00Z")) + .email("ie_a1b2c3d4e5f6@import.casparser.in") + .inboundEmailId("ie_a1b2c3d4e5f6") + .metadata( + InboundEmailListResponse.InboundEmail.Metadata.builder() + .putAdditionalProperty("plan", JsonValue.from("premium")) + .build() + ) + .reference("user_12345") + .status(InboundEmailListResponse.InboundEmail.Status.ACTIVE) + .updatedAt(OffsetDateTime.parse("2025-02-21T10:30:00Z")) + .build() + ) + assertThat(inboundEmailListResponse.limit()).contains(50L) + assertThat(inboundEmailListResponse.offset()).contains(0L) + assertThat(inboundEmailListResponse.status()).contains("success") + assertThat(inboundEmailListResponse.total()).contains(15L) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val inboundEmailListResponse = + InboundEmailListResponse.builder() + .addInboundEmail( + InboundEmailListResponse.InboundEmail.builder() + .addAllowedSource(InboundEmailListResponse.InboundEmail.AllowedSource.CDSL) + .addAllowedSource(InboundEmailListResponse.InboundEmail.AllowedSource.NSDL) + .callbackUrl("https://api.yourapp.com/webhooks/cas-email") + .createdAt(OffsetDateTime.parse("2025-02-21T10:30:00Z")) + .email("ie_a1b2c3d4e5f6@import.casparser.in") + .inboundEmailId("ie_a1b2c3d4e5f6") + .metadata( + InboundEmailListResponse.InboundEmail.Metadata.builder() + .putAdditionalProperty("plan", JsonValue.from("premium")) + .build() + ) + .reference("user_12345") + .status(InboundEmailListResponse.InboundEmail.Status.ACTIVE) + .updatedAt(OffsetDateTime.parse("2025-02-21T10:30:00Z")) + .build() + ) + .limit(50L) + .offset(0L) + .status("success") + .total(15L) + .build() + + val roundtrippedInboundEmailListResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(inboundEmailListResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedInboundEmailListResponse).isEqualTo(inboundEmailListResponse) + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailRetrieveParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailRetrieveParamsTest.kt new file mode 100644 index 0000000..2b76fc3 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailRetrieveParamsTest.kt @@ -0,0 +1,23 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.inboundemail + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class InboundEmailRetrieveParamsTest { + + @Test + fun create() { + InboundEmailRetrieveParams.builder().inboundEmailId("ie_a1b2c3d4e5f6").build() + } + + @Test + fun pathParams() { + val params = InboundEmailRetrieveParams.builder().inboundEmailId("ie_a1b2c3d4e5f6").build() + + assertThat(params._pathParam(0)).isEqualTo("ie_a1b2c3d4e5f6") + // out-of-bound path param + assertThat(params._pathParam(1)).isEqualTo("") + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailRetrieveResponseTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailRetrieveResponseTest.kt new file mode 100644 index 0000000..c6e9872 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailRetrieveResponseTest.kt @@ -0,0 +1,89 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.inboundemail + +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.core.jsonMapper +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import java.time.OffsetDateTime +import kotlin.jvm.optionals.getOrNull +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class InboundEmailRetrieveResponseTest { + + @Test + fun create() { + val inboundEmailRetrieveResponse = + InboundEmailRetrieveResponse.builder() + .addAllowedSource(InboundEmailRetrieveResponse.AllowedSource.CDSL) + .addAllowedSource(InboundEmailRetrieveResponse.AllowedSource.NSDL) + .callbackUrl("https://api.yourapp.com/webhooks/cas-email") + .createdAt(OffsetDateTime.parse("2025-02-21T10:30:00Z")) + .email("ie_a1b2c3d4e5f6@import.casparser.in") + .inboundEmailId("ie_a1b2c3d4e5f6") + .metadata( + InboundEmailRetrieveResponse.Metadata.builder() + .putAdditionalProperty("plan", JsonValue.from("premium")) + .build() + ) + .reference("user_12345") + .status(InboundEmailRetrieveResponse.Status.ACTIVE) + .updatedAt(OffsetDateTime.parse("2025-02-21T10:30:00Z")) + .build() + + assertThat(inboundEmailRetrieveResponse.allowedSources().getOrNull()) + .containsExactly( + InboundEmailRetrieveResponse.AllowedSource.CDSL, + InboundEmailRetrieveResponse.AllowedSource.NSDL, + ) + assertThat(inboundEmailRetrieveResponse.callbackUrl()) + .contains("https://api.yourapp.com/webhooks/cas-email") + assertThat(inboundEmailRetrieveResponse.createdAt()) + .contains(OffsetDateTime.parse("2025-02-21T10:30:00Z")) + assertThat(inboundEmailRetrieveResponse.email()) + .contains("ie_a1b2c3d4e5f6@import.casparser.in") + assertThat(inboundEmailRetrieveResponse.inboundEmailId()).contains("ie_a1b2c3d4e5f6") + assertThat(inboundEmailRetrieveResponse.metadata()) + .contains( + InboundEmailRetrieveResponse.Metadata.builder() + .putAdditionalProperty("plan", JsonValue.from("premium")) + .build() + ) + assertThat(inboundEmailRetrieveResponse.reference()).contains("user_12345") + assertThat(inboundEmailRetrieveResponse.status()) + .contains(InboundEmailRetrieveResponse.Status.ACTIVE) + assertThat(inboundEmailRetrieveResponse.updatedAt()) + .contains(OffsetDateTime.parse("2025-02-21T10:30:00Z")) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val inboundEmailRetrieveResponse = + InboundEmailRetrieveResponse.builder() + .addAllowedSource(InboundEmailRetrieveResponse.AllowedSource.CDSL) + .addAllowedSource(InboundEmailRetrieveResponse.AllowedSource.NSDL) + .callbackUrl("https://api.yourapp.com/webhooks/cas-email") + .createdAt(OffsetDateTime.parse("2025-02-21T10:30:00Z")) + .email("ie_a1b2c3d4e5f6@import.casparser.in") + .inboundEmailId("ie_a1b2c3d4e5f6") + .metadata( + InboundEmailRetrieveResponse.Metadata.builder() + .putAdditionalProperty("plan", JsonValue.from("premium")) + .build() + ) + .reference("user_12345") + .status(InboundEmailRetrieveResponse.Status.ACTIVE) + .updatedAt(OffsetDateTime.parse("2025-02-21T10:30:00Z")) + .build() + + val roundtrippedInboundEmailRetrieveResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(inboundEmailRetrieveResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedInboundEmailRetrieveResponse).isEqualTo(inboundEmailRetrieveResponse) + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogCreateParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogCreateParamsTest.kt new file mode 100644 index 0000000..e7212ba --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogCreateParamsTest.kt @@ -0,0 +1,42 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.logs + +import java.time.OffsetDateTime +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class LogCreateParamsTest { + + @Test + fun create() { + LogCreateParams.builder() + .endTime(OffsetDateTime.parse("2026-01-31T23:59:59Z")) + .limit(1L) + .startTime(OffsetDateTime.parse("2026-01-01T00:00:00Z")) + .build() + } + + @Test + fun body() { + val params = + LogCreateParams.builder() + .endTime(OffsetDateTime.parse("2026-01-31T23:59:59Z")) + .limit(1L) + .startTime(OffsetDateTime.parse("2026-01-01T00:00:00Z")) + .build() + + val body = params._body() + + assertThat(body.endTime()).contains(OffsetDateTime.parse("2026-01-31T23:59:59Z")) + assertThat(body.limit()).contains(1L) + assertThat(body.startTime()).contains(OffsetDateTime.parse("2026-01-01T00:00:00Z")) + } + + @Test + fun bodyWithoutOptionalFields() { + val params = LogCreateParams.builder().build() + + val body = params._body() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogCreateResponseTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogCreateResponseTest.kt new file mode 100644 index 0000000..0f24a21 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogCreateResponseTest.kt @@ -0,0 +1,74 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.logs + +import com.cas_parser.api.core.jsonMapper +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import java.time.OffsetDateTime +import kotlin.jvm.optionals.getOrNull +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class LogCreateResponseTest { + + @Test + fun create() { + val logCreateResponse = + LogCreateResponse.builder() + .count(25L) + .addLog( + LogCreateResponse.Log.builder() + .credits(1.0) + .feature("cdsl_cas_parser") + .path("/v4/cdsl/parse") + .requestId("req_2xYz7KpL8mN3Ab") + .statusCode(200L) + .timestamp(OffsetDateTime.parse("2026-01-15T14:30:00Z")) + .build() + ) + .status("success") + .build() + + assertThat(logCreateResponse.count()).contains(25L) + assertThat(logCreateResponse.logs().getOrNull()) + .containsExactly( + LogCreateResponse.Log.builder() + .credits(1.0) + .feature("cdsl_cas_parser") + .path("/v4/cdsl/parse") + .requestId("req_2xYz7KpL8mN3Ab") + .statusCode(200L) + .timestamp(OffsetDateTime.parse("2026-01-15T14:30:00Z")) + .build() + ) + assertThat(logCreateResponse.status()).contains("success") + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val logCreateResponse = + LogCreateResponse.builder() + .count(25L) + .addLog( + LogCreateResponse.Log.builder() + .credits(1.0) + .feature("cdsl_cas_parser") + .path("/v4/cdsl/parse") + .requestId("req_2xYz7KpL8mN3Ab") + .statusCode(200L) + .timestamp(OffsetDateTime.parse("2026-01-15T14:30:00Z")) + .build() + ) + .status("success") + .build() + + val roundtrippedLogCreateResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(logCreateResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedLogCreateResponse).isEqualTo(logCreateResponse) + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogGetSummaryParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogGetSummaryParamsTest.kt new file mode 100644 index 0000000..a2cfd4a --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogGetSummaryParamsTest.kt @@ -0,0 +1,39 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.logs + +import java.time.OffsetDateTime +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class LogGetSummaryParamsTest { + + @Test + fun create() { + LogGetSummaryParams.builder() + .endTime(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .startTime(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .build() + } + + @Test + fun body() { + val params = + LogGetSummaryParams.builder() + .endTime(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .startTime(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .build() + + val body = params._body() + + assertThat(body.endTime()).contains(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + assertThat(body.startTime()).contains(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + } + + @Test + fun bodyWithoutOptionalFields() { + val params = LogGetSummaryParams.builder().build() + + val body = params._body() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogGetSummaryResponseTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogGetSummaryResponseTest.kt new file mode 100644 index 0000000..94e8bc7 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/logs/LogGetSummaryResponseTest.kt @@ -0,0 +1,78 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.logs + +import com.cas_parser.api.core.jsonMapper +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class LogGetSummaryResponseTest { + + @Test + fun create() { + val logGetSummaryResponse = + LogGetSummaryResponse.builder() + .status("success") + .summary( + LogGetSummaryResponse.Summary.builder() + .addByFeature( + LogGetSummaryResponse.Summary.ByFeature.builder() + .credits(15.0) + .feature("cdsl_cas_parser") + .requests(15L) + .build() + ) + .totalCredits(45.5) + .totalRequests(42L) + .build() + ) + .build() + + assertThat(logGetSummaryResponse.status()).contains("success") + assertThat(logGetSummaryResponse.summary()) + .contains( + LogGetSummaryResponse.Summary.builder() + .addByFeature( + LogGetSummaryResponse.Summary.ByFeature.builder() + .credits(15.0) + .feature("cdsl_cas_parser") + .requests(15L) + .build() + ) + .totalCredits(45.5) + .totalRequests(42L) + .build() + ) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val logGetSummaryResponse = + LogGetSummaryResponse.builder() + .status("success") + .summary( + LogGetSummaryResponse.Summary.builder() + .addByFeature( + LogGetSummaryResponse.Summary.ByFeature.builder() + .credits(15.0) + .feature("cdsl_cas_parser") + .requests(15L) + .build() + ) + .totalCredits(45.5) + .totalRequests(42L) + .build() + ) + .build() + + val roundtrippedLogGetSummaryResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(logGetSummaryResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedLogGetSummaryResponse).isEqualTo(logGetSummaryResponse) + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyParamsTest.kt new file mode 100644 index 0000000..6e75d40 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyParamsTest.kt @@ -0,0 +1,13 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.verifytoken + +import org.junit.jupiter.api.Test + +internal class VerifyTokenVerifyParamsTest { + + @Test + fun create() { + VerifyTokenVerifyParams.builder().build() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyResponseTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyResponseTest.kt new file mode 100644 index 0000000..813bc45 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyResponseTest.kt @@ -0,0 +1,44 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.models.verifytoken + +import com.cas_parser.api.core.jsonMapper +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class VerifyTokenVerifyResponseTest { + + @Test + fun create() { + val verifyTokenVerifyResponse = + VerifyTokenVerifyResponse.builder() + .error("Token has expired") + .maskedApiKey("abc1****ef23") + .valid(true) + .build() + + assertThat(verifyTokenVerifyResponse.error()).contains("Token has expired") + assertThat(verifyTokenVerifyResponse.maskedApiKey()).contains("abc1****ef23") + assertThat(verifyTokenVerifyResponse.valid()).contains(true) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val verifyTokenVerifyResponse = + VerifyTokenVerifyResponse.builder() + .error("Token has expired") + .maskedApiKey("abc1****ef23") + .valid(true) + .build() + + val roundtrippedVerifyTokenVerifyResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(verifyTokenVerifyResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedVerifyTokenVerifyResponse).isEqualTo(verifyTokenVerifyResponse) + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/ErrorHandlingTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/ErrorHandlingTest.kt index 0cce742..f58190a 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/ErrorHandlingTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/ErrorHandlingTest.kt @@ -16,7 +16,6 @@ import com.cas_parser.api.errors.RateLimitException import com.cas_parser.api.errors.UnauthorizedException import com.cas_parser.api.errors.UnexpectedStatusCodeException import com.cas_parser.api.errors.UnprocessableEntityException -import com.cas_parser.api.models.camskfintech.CamsKfintechParseParams import com.github.tomakehurst.wiremock.client.WireMock.anyUrl import com.github.tomakehurst.wiremock.client.WireMock.post import com.github.tomakehurst.wiremock.client.WireMock.status @@ -59,8 +58,8 @@ internal class ErrorHandlingTest { } @Test - fun camsKfintechParse400() { - val camsKfintechService = client.camsKfintech() + fun creditsCheck400() { + val creditService = client.credits() stubFor( post(anyUrl()) .willReturn( @@ -68,16 +67,7 @@ internal class ErrorHandlingTest { ) ) - val e = - assertThrows { - camsKfintechService.parse( - CamsKfintechParseParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - } + val e = assertThrows { creditService.check() } assertThat(e.statusCode()).isEqualTo(400) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -85,8 +75,8 @@ internal class ErrorHandlingTest { } @Test - fun camsKfintechParse400WithRawResponse() { - val camsKfintechService = client.camsKfintech().withRawResponse() + fun creditsCheck400WithRawResponse() { + val creditService = client.credits().withRawResponse() stubFor( post(anyUrl()) .willReturn( @@ -94,16 +84,7 @@ internal class ErrorHandlingTest { ) ) - val e = - assertThrows { - camsKfintechService.parse( - CamsKfintechParseParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - } + val e = assertThrows { creditService.check() } assertThat(e.statusCode()).isEqualTo(400) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -111,8 +92,8 @@ internal class ErrorHandlingTest { } @Test - fun camsKfintechParse401() { - val camsKfintechService = client.camsKfintech() + fun creditsCheck401() { + val creditService = client.credits() stubFor( post(anyUrl()) .willReturn( @@ -120,16 +101,7 @@ internal class ErrorHandlingTest { ) ) - val e = - assertThrows { - camsKfintechService.parse( - CamsKfintechParseParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - } + val e = assertThrows { creditService.check() } assertThat(e.statusCode()).isEqualTo(401) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -137,8 +109,8 @@ internal class ErrorHandlingTest { } @Test - fun camsKfintechParse401WithRawResponse() { - val camsKfintechService = client.camsKfintech().withRawResponse() + fun creditsCheck401WithRawResponse() { + val creditService = client.credits().withRawResponse() stubFor( post(anyUrl()) .willReturn( @@ -146,16 +118,7 @@ internal class ErrorHandlingTest { ) ) - val e = - assertThrows { - camsKfintechService.parse( - CamsKfintechParseParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - } + val e = assertThrows { creditService.check() } assertThat(e.statusCode()).isEqualTo(401) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -163,8 +126,8 @@ internal class ErrorHandlingTest { } @Test - fun camsKfintechParse403() { - val camsKfintechService = client.camsKfintech() + fun creditsCheck403() { + val creditService = client.credits() stubFor( post(anyUrl()) .willReturn( @@ -172,16 +135,7 @@ internal class ErrorHandlingTest { ) ) - val e = - assertThrows { - camsKfintechService.parse( - CamsKfintechParseParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - } + val e = assertThrows { creditService.check() } assertThat(e.statusCode()).isEqualTo(403) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -189,8 +143,8 @@ internal class ErrorHandlingTest { } @Test - fun camsKfintechParse403WithRawResponse() { - val camsKfintechService = client.camsKfintech().withRawResponse() + fun creditsCheck403WithRawResponse() { + val creditService = client.credits().withRawResponse() stubFor( post(anyUrl()) .willReturn( @@ -198,16 +152,7 @@ internal class ErrorHandlingTest { ) ) - val e = - assertThrows { - camsKfintechService.parse( - CamsKfintechParseParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - } + val e = assertThrows { creditService.check() } assertThat(e.statusCode()).isEqualTo(403) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -215,8 +160,8 @@ internal class ErrorHandlingTest { } @Test - fun camsKfintechParse404() { - val camsKfintechService = client.camsKfintech() + fun creditsCheck404() { + val creditService = client.credits() stubFor( post(anyUrl()) .willReturn( @@ -224,16 +169,7 @@ internal class ErrorHandlingTest { ) ) - val e = - assertThrows { - camsKfintechService.parse( - CamsKfintechParseParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - } + val e = assertThrows { creditService.check() } assertThat(e.statusCode()).isEqualTo(404) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -241,8 +177,8 @@ internal class ErrorHandlingTest { } @Test - fun camsKfintechParse404WithRawResponse() { - val camsKfintechService = client.camsKfintech().withRawResponse() + fun creditsCheck404WithRawResponse() { + val creditService = client.credits().withRawResponse() stubFor( post(anyUrl()) .willReturn( @@ -250,16 +186,7 @@ internal class ErrorHandlingTest { ) ) - val e = - assertThrows { - camsKfintechService.parse( - CamsKfintechParseParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - } + val e = assertThrows { creditService.check() } assertThat(e.statusCode()).isEqualTo(404) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -267,8 +194,8 @@ internal class ErrorHandlingTest { } @Test - fun camsKfintechParse422() { - val camsKfintechService = client.camsKfintech() + fun creditsCheck422() { + val creditService = client.credits() stubFor( post(anyUrl()) .willReturn( @@ -276,16 +203,7 @@ internal class ErrorHandlingTest { ) ) - val e = - assertThrows { - camsKfintechService.parse( - CamsKfintechParseParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - } + val e = assertThrows { creditService.check() } assertThat(e.statusCode()).isEqualTo(422) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -293,8 +211,8 @@ internal class ErrorHandlingTest { } @Test - fun camsKfintechParse422WithRawResponse() { - val camsKfintechService = client.camsKfintech().withRawResponse() + fun creditsCheck422WithRawResponse() { + val creditService = client.credits().withRawResponse() stubFor( post(anyUrl()) .willReturn( @@ -302,16 +220,7 @@ internal class ErrorHandlingTest { ) ) - val e = - assertThrows { - camsKfintechService.parse( - CamsKfintechParseParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - } + val e = assertThrows { creditService.check() } assertThat(e.statusCode()).isEqualTo(422) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -319,8 +228,8 @@ internal class ErrorHandlingTest { } @Test - fun camsKfintechParse429() { - val camsKfintechService = client.camsKfintech() + fun creditsCheck429() { + val creditService = client.credits() stubFor( post(anyUrl()) .willReturn( @@ -328,16 +237,7 @@ internal class ErrorHandlingTest { ) ) - val e = - assertThrows { - camsKfintechService.parse( - CamsKfintechParseParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - } + val e = assertThrows { creditService.check() } assertThat(e.statusCode()).isEqualTo(429) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -345,8 +245,8 @@ internal class ErrorHandlingTest { } @Test - fun camsKfintechParse429WithRawResponse() { - val camsKfintechService = client.camsKfintech().withRawResponse() + fun creditsCheck429WithRawResponse() { + val creditService = client.credits().withRawResponse() stubFor( post(anyUrl()) .willReturn( @@ -354,16 +254,7 @@ internal class ErrorHandlingTest { ) ) - val e = - assertThrows { - camsKfintechService.parse( - CamsKfintechParseParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - } + val e = assertThrows { creditService.check() } assertThat(e.statusCode()).isEqualTo(429) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -371,8 +262,8 @@ internal class ErrorHandlingTest { } @Test - fun camsKfintechParse500() { - val camsKfintechService = client.camsKfintech() + fun creditsCheck500() { + val creditService = client.credits() stubFor( post(anyUrl()) .willReturn( @@ -380,16 +271,7 @@ internal class ErrorHandlingTest { ) ) - val e = - assertThrows { - camsKfintechService.parse( - CamsKfintechParseParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - } + val e = assertThrows { creditService.check() } assertThat(e.statusCode()).isEqualTo(500) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -397,8 +279,8 @@ internal class ErrorHandlingTest { } @Test - fun camsKfintechParse500WithRawResponse() { - val camsKfintechService = client.camsKfintech().withRawResponse() + fun creditsCheck500WithRawResponse() { + val creditService = client.credits().withRawResponse() stubFor( post(anyUrl()) .willReturn( @@ -406,16 +288,7 @@ internal class ErrorHandlingTest { ) ) - val e = - assertThrows { - camsKfintechService.parse( - CamsKfintechParseParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - } + val e = assertThrows { creditService.check() } assertThat(e.statusCode()).isEqualTo(500) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -423,8 +296,8 @@ internal class ErrorHandlingTest { } @Test - fun camsKfintechParse999() { - val camsKfintechService = client.camsKfintech() + fun creditsCheck999() { + val creditService = client.credits() stubFor( post(anyUrl()) .willReturn( @@ -432,16 +305,7 @@ internal class ErrorHandlingTest { ) ) - val e = - assertThrows { - camsKfintechService.parse( - CamsKfintechParseParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - } + val e = assertThrows { creditService.check() } assertThat(e.statusCode()).isEqualTo(999) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -449,8 +313,8 @@ internal class ErrorHandlingTest { } @Test - fun camsKfintechParse999WithRawResponse() { - val camsKfintechService = client.camsKfintech().withRawResponse() + fun creditsCheck999WithRawResponse() { + val creditService = client.credits().withRawResponse() stubFor( post(anyUrl()) .willReturn( @@ -458,16 +322,7 @@ internal class ErrorHandlingTest { ) ) - val e = - assertThrows { - camsKfintechService.parse( - CamsKfintechParseParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - } + val e = assertThrows { creditService.check() } assertThat(e.statusCode()).isEqualTo(999) assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) @@ -475,23 +330,14 @@ internal class ErrorHandlingTest { } @Test - fun camsKfintechParseInvalidJsonBody() { - val camsKfintechService = client.camsKfintech() + fun creditsCheckInvalidJsonBody() { + val creditService = client.credits() stubFor( post(anyUrl()) .willReturn(status(200).withHeader(HEADER_NAME, HEADER_VALUE).withBody(NOT_JSON)) ) - val e = - assertThrows { - camsKfintechService.parse( - CamsKfintechParseParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") - .build() - ) - } + val e = assertThrows { creditService.check() } assertThat(e).hasMessage("Error reading response") } diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/ServiceParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/ServiceParamsTest.kt index be4ed15..4cdd376 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/ServiceParamsTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/ServiceParamsTest.kt @@ -5,7 +5,7 @@ package com.cas_parser.api.services import com.cas_parser.api.client.CasParserClient import com.cas_parser.api.client.okhttp.CasParserOkHttpClient import com.cas_parser.api.core.JsonValue -import com.cas_parser.api.models.camskfintech.CamsKfintechParseParams +import com.cas_parser.api.models.credits.CreditCheckParams import com.github.tomakehurst.wiremock.client.WireMock.anyUrl import com.github.tomakehurst.wiremock.client.WireMock.equalTo import com.github.tomakehurst.wiremock.client.WireMock.matchingJsonPath @@ -38,15 +38,12 @@ internal class ServiceParamsTest { @Disabled("Mock server tests are disabled") @Test - fun parse() { - val camsKfintechService = client.camsKfintech() + fun check() { + val creditService = client.credits() stubFor(post(anyUrl()).willReturn(ok("{}"))) - camsKfintechService.parse( - CamsKfintechParseParams.builder() - .password("password") - .pdfFile("pdf_file") - .pdfUrl("https://example.com") + creditService.check( + CreditCheckParams.builder() .putAdditionalHeader("Secret-Header", "42") .putAdditionalQueryParam("secret_query_param", "42") .putAdditionalBodyProperty("secretProperty", JsonValue.from("42")) diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsyncTest.kt new file mode 100644 index 0000000..c795a5c --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsyncTest.kt @@ -0,0 +1,26 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.client.okhttp.CasParserOkHttpClientAsync +import com.cas_parser.api.models.accesstoken.AccessTokenCreateParams +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test + +internal class AccessTokenServiceAsyncTest { + + @Disabled("Mock server tests are disabled") + @Test + fun create() { + val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() + val accessTokenServiceAsync = client.accessToken() + + val accessTokenFuture = + accessTokenServiceAsync.create( + AccessTokenCreateParams.builder().expiryMinutes(60L).build() + ) + + val accessToken = accessTokenFuture.get() + accessToken.validate() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CreditServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CreditServiceAsyncTest.kt new file mode 100644 index 0000000..6c9e4d8 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/CreditServiceAsyncTest.kt @@ -0,0 +1,22 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.client.okhttp.CasParserOkHttpClientAsync +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test + +internal class CreditServiceAsyncTest { + + @Disabled("Mock server tests are disabled") + @Test + fun check() { + val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() + val creditServiceAsync = client.credits() + + val responseFuture = creditServiceAsync.check() + + val response = responseFuture.get() + response.validate() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/InboundEmailServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/InboundEmailServiceAsyncTest.kt new file mode 100644 index 0000000..0993dac --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/InboundEmailServiceAsyncTest.kt @@ -0,0 +1,83 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.client.okhttp.CasParserOkHttpClientAsync +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.models.inboundemail.InboundEmailCreateParams +import com.cas_parser.api.models.inboundemail.InboundEmailListParams +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test + +internal class InboundEmailServiceAsyncTest { + + @Disabled("Mock server tests are disabled") + @Test + fun create() { + val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() + val inboundEmailServiceAsync = client.inboundEmail() + + val inboundEmailFuture = + inboundEmailServiceAsync.create( + InboundEmailCreateParams.builder() + .callbackUrl("https://api.yourapp.com/webhooks/cas-email") + .alias("john-portfolio") + .addAllowedSource(InboundEmailCreateParams.AllowedSource.CDSL) + .addAllowedSource(InboundEmailCreateParams.AllowedSource.NSDL) + .metadata( + InboundEmailCreateParams.Metadata.builder() + .putAdditionalProperty("plan", JsonValue.from("premium")) + .putAdditionalProperty("source", JsonValue.from("onboarding")) + .build() + ) + .reference("user_12345") + .build() + ) + + val inboundEmail = inboundEmailFuture.get() + inboundEmail.validate() + } + + @Disabled("Mock server tests are disabled") + @Test + fun retrieve() { + val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() + val inboundEmailServiceAsync = client.inboundEmail() + + val inboundEmailFuture = inboundEmailServiceAsync.retrieve("ie_a1b2c3d4e5f6") + + val inboundEmail = inboundEmailFuture.get() + inboundEmail.validate() + } + + @Disabled("Mock server tests are disabled") + @Test + fun list() { + val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() + val inboundEmailServiceAsync = client.inboundEmail() + + val inboundEmailsFuture = + inboundEmailServiceAsync.list( + InboundEmailListParams.builder() + .limit(1L) + .offset(0L) + .status(InboundEmailListParams.Status.ACTIVE) + .build() + ) + + val inboundEmails = inboundEmailsFuture.get() + inboundEmails.validate() + } + + @Disabled("Mock server tests are disabled") + @Test + fun delete() { + val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() + val inboundEmailServiceAsync = client.inboundEmail() + + val inboundEmailFuture = inboundEmailServiceAsync.delete("inbound_email_id") + + val inboundEmail = inboundEmailFuture.get() + inboundEmail.validate() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/LogServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/LogServiceAsyncTest.kt new file mode 100644 index 0000000..532be8d --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/LogServiceAsyncTest.kt @@ -0,0 +1,50 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.client.okhttp.CasParserOkHttpClientAsync +import com.cas_parser.api.models.logs.LogCreateParams +import com.cas_parser.api.models.logs.LogGetSummaryParams +import java.time.OffsetDateTime +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test + +internal class LogServiceAsyncTest { + + @Disabled("Mock server tests are disabled") + @Test + fun create() { + val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() + val logServiceAsync = client.logs() + + val logFuture = + logServiceAsync.create( + LogCreateParams.builder() + .endTime(OffsetDateTime.parse("2026-01-31T23:59:59Z")) + .limit(1L) + .startTime(OffsetDateTime.parse("2026-01-01T00:00:00Z")) + .build() + ) + + val log = logFuture.get() + log.validate() + } + + @Disabled("Mock server tests are disabled") + @Test + fun getSummary() { + val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() + val logServiceAsync = client.logs() + + val responseFuture = + logServiceAsync.getSummary( + LogGetSummaryParams.builder() + .endTime(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .startTime(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .build() + ) + + val response = responseFuture.get() + response.validate() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsyncTest.kt new file mode 100644 index 0000000..3d7800c --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsyncTest.kt @@ -0,0 +1,22 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.async + +import com.cas_parser.api.client.okhttp.CasParserOkHttpClientAsync +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test + +internal class VerifyTokenServiceAsyncTest { + + @Disabled("Mock server tests are disabled") + @Test + fun verify() { + val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() + val verifyTokenServiceAsync = client.verifyToken() + + val responseFuture = verifyTokenServiceAsync.verify() + + val response = responseFuture.get() + response.validate() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/AccessTokenServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/AccessTokenServiceTest.kt new file mode 100644 index 0000000..f7c9696 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/AccessTokenServiceTest.kt @@ -0,0 +1,23 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.client.okhttp.CasParserOkHttpClient +import com.cas_parser.api.models.accesstoken.AccessTokenCreateParams +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test + +internal class AccessTokenServiceTest { + + @Disabled("Mock server tests are disabled") + @Test + fun create() { + val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() + val accessTokenService = client.accessToken() + + val accessToken = + accessTokenService.create(AccessTokenCreateParams.builder().expiryMinutes(60L).build()) + + accessToken.validate() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CreditServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CreditServiceTest.kt new file mode 100644 index 0000000..94239a3 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/CreditServiceTest.kt @@ -0,0 +1,21 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.client.okhttp.CasParserOkHttpClient +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test + +internal class CreditServiceTest { + + @Disabled("Mock server tests are disabled") + @Test + fun check() { + val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() + val creditService = client.credits() + + val response = creditService.check() + + response.validate() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/InboundEmailServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/InboundEmailServiceTest.kt new file mode 100644 index 0000000..66d6b0c --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/InboundEmailServiceTest.kt @@ -0,0 +1,79 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.client.okhttp.CasParserOkHttpClient +import com.cas_parser.api.core.JsonValue +import com.cas_parser.api.models.inboundemail.InboundEmailCreateParams +import com.cas_parser.api.models.inboundemail.InboundEmailListParams +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test + +internal class InboundEmailServiceTest { + + @Disabled("Mock server tests are disabled") + @Test + fun create() { + val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() + val inboundEmailService = client.inboundEmail() + + val inboundEmail = + inboundEmailService.create( + InboundEmailCreateParams.builder() + .callbackUrl("https://api.yourapp.com/webhooks/cas-email") + .alias("john-portfolio") + .addAllowedSource(InboundEmailCreateParams.AllowedSource.CDSL) + .addAllowedSource(InboundEmailCreateParams.AllowedSource.NSDL) + .metadata( + InboundEmailCreateParams.Metadata.builder() + .putAdditionalProperty("plan", JsonValue.from("premium")) + .putAdditionalProperty("source", JsonValue.from("onboarding")) + .build() + ) + .reference("user_12345") + .build() + ) + + inboundEmail.validate() + } + + @Disabled("Mock server tests are disabled") + @Test + fun retrieve() { + val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() + val inboundEmailService = client.inboundEmail() + + val inboundEmail = inboundEmailService.retrieve("ie_a1b2c3d4e5f6") + + inboundEmail.validate() + } + + @Disabled("Mock server tests are disabled") + @Test + fun list() { + val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() + val inboundEmailService = client.inboundEmail() + + val inboundEmails = + inboundEmailService.list( + InboundEmailListParams.builder() + .limit(1L) + .offset(0L) + .status(InboundEmailListParams.Status.ACTIVE) + .build() + ) + + inboundEmails.validate() + } + + @Disabled("Mock server tests are disabled") + @Test + fun delete() { + val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() + val inboundEmailService = client.inboundEmail() + + val inboundEmail = inboundEmailService.delete("inbound_email_id") + + inboundEmail.validate() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/LogServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/LogServiceTest.kt new file mode 100644 index 0000000..2ef5c48 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/LogServiceTest.kt @@ -0,0 +1,48 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.client.okhttp.CasParserOkHttpClient +import com.cas_parser.api.models.logs.LogCreateParams +import com.cas_parser.api.models.logs.LogGetSummaryParams +import java.time.OffsetDateTime +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test + +internal class LogServiceTest { + + @Disabled("Mock server tests are disabled") + @Test + fun create() { + val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() + val logService = client.logs() + + val log = + logService.create( + LogCreateParams.builder() + .endTime(OffsetDateTime.parse("2026-01-31T23:59:59Z")) + .limit(1L) + .startTime(OffsetDateTime.parse("2026-01-01T00:00:00Z")) + .build() + ) + + log.validate() + } + + @Disabled("Mock server tests are disabled") + @Test + fun getSummary() { + val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() + val logService = client.logs() + + val response = + logService.getSummary( + LogGetSummaryParams.builder() + .endTime(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .startTime(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .build() + ) + + response.validate() + } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/VerifyTokenServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/VerifyTokenServiceTest.kt new file mode 100644 index 0000000..19af27d --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/VerifyTokenServiceTest.kt @@ -0,0 +1,21 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.services.blocking + +import com.cas_parser.api.client.okhttp.CasParserOkHttpClient +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test + +internal class VerifyTokenServiceTest { + + @Disabled("Mock server tests are disabled") + @Test + fun verify() { + val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() + val verifyTokenService = client.verifyToken() + + val response = verifyTokenService.verify() + + response.validate() + } +} diff --git a/cas-parser-java-proguard-test/src/test/kotlin/com/cas_parser/api/proguard/ProGuardCompatibilityTest.kt b/cas-parser-java-proguard-test/src/test/kotlin/com/cas_parser/api/proguard/ProGuardCompatibilityTest.kt index 8592efc..bc06f0e 100644 --- a/cas-parser-java-proguard-test/src/test/kotlin/com/cas_parser/api/proguard/ProGuardCompatibilityTest.kt +++ b/cas-parser-java-proguard-test/src/test/kotlin/com/cas_parser/api/proguard/ProGuardCompatibilityTest.kt @@ -4,8 +4,9 @@ package com.cas_parser.api.proguard import com.cas_parser.api.client.okhttp.CasParserOkHttpClient import com.cas_parser.api.core.jsonMapper -import com.cas_parser.api.models.camskfintech.LinkedHolder +import com.cas_parser.api.models.credits.CreditCheckResponse import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import java.time.OffsetDateTime import kotlin.reflect.full.memberFunctions import kotlin.reflect.jvm.javaMethod import org.assertj.core.api.Assertions.assertThat @@ -58,19 +59,30 @@ internal class ProGuardCompatibilityTest { assertThat(client.kfintech()).isNotNull() assertThat(client.nsdl()).isNotNull() assertThat(client.smart()).isNotNull() + assertThat(client.inboundEmail()).isNotNull() } @Test - fun linkedHolderRoundtrip() { + fun creditCheckResponseRoundtrip() { val jsonMapper = jsonMapper() - val linkedHolder = LinkedHolder.builder().name("name").pan("pan").build() + val creditCheckResponse = + CreditCheckResponse.builder() + .enabledFeatures( + listOf("cams_kfintech_cas_parser", "cdsl_cas_parser", "nsdl_cas_parser") + ) + .isUnlimited(false) + .limit(50L) + .remaining(35.0) + .resetsAt(OffsetDateTime.parse("2026-02-15T00:00:00Z")) + .used(15.0) + .build() - val roundtrippedLinkedHolder = + val roundtrippedCreditCheckResponse = jsonMapper.readValue( - jsonMapper.writeValueAsString(linkedHolder), - jacksonTypeRef(), + jsonMapper.writeValueAsString(creditCheckResponse), + jacksonTypeRef(), ) - assertThat(roundtrippedLinkedHolder).isEqualTo(linkedHolder) + assertThat(roundtrippedCreditCheckResponse).isEqualTo(creditCheckResponse) } } From 4a8c6d6814194f5a48d294a7b43ada50961071b1 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 23 Feb 2026 03:00:43 +0000 Subject: [PATCH 59/99] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index cdf3c0a..49508b3 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 21 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-d9763d006969b49a1473851069fdfa429eb13133b64103a62963bb70ddb22305.yml openapi_spec_hash: 6aee689b7a759b12c85c088c15e29bc0 -config_hash: d54f39abb185904495bef7c5f8702746 +config_hash: 4ab3e1ee76a463e0ed214541260ee12e From 878711e92adeb838ba0d1a4df11fc93edd46ff24 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 23 Feb 2026 03:03:59 +0000 Subject: [PATCH 60/99] chore(internal): version bump --- .release-please-manifest.json | 2 +- README.md | 10 +++++----- build.gradle.kts | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 6b7b74c..da59f99 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.3.0" + ".": "0.4.0" } \ No newline at end of file diff --git a/README.md b/README.md index 212151b..bb3747b 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ -[![Maven Central](https://img.shields.io/maven-central/v/com.cas_parser.api/cas-parser-java)](https://central.sonatype.com/artifact/com.cas_parser.api/cas-parser-java/0.3.0) -[![javadoc](https://javadoc.io/badge2/com.cas_parser.api/cas-parser-java/0.3.0/javadoc.svg)](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.3.0) +[![Maven Central](https://img.shields.io/maven-central/v/com.cas_parser.api/cas-parser-java)](https://central.sonatype.com/artifact/com.cas_parser.api/cas-parser-java/0.4.0) +[![javadoc](https://javadoc.io/badge2/com.cas_parser.api/cas-parser-java/0.4.0/javadoc.svg)](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.4.0) @@ -22,7 +22,7 @@ Use the Cas Parser MCP Server to enable AI assistants to interact with this API, -The REST API documentation can be found on [docs.casparser.in](https://docs.casparser.in). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.3.0). +The REST API documentation can be found on [docs.casparser.in](https://docs.casparser.in). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.4.0). @@ -33,7 +33,7 @@ The REST API documentation can be found on [docs.casparser.in](https://docs.casp ### Gradle ```kotlin -implementation("com.cas_parser.api:cas-parser-java:0.3.0") +implementation("com.cas_parser.api:cas-parser-java:0.4.0") ``` ### Maven @@ -42,7 +42,7 @@ implementation("com.cas_parser.api:cas-parser-java:0.3.0") com.cas_parser.api cas-parser-java - 0.3.0 + 0.4.0 ``` diff --git a/build.gradle.kts b/build.gradle.kts index 90d29ec..40e9f7a 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -9,7 +9,7 @@ repositories { allprojects { group = "com.cas_parser.api" - version = "0.3.0" // x-release-please-version + version = "0.4.0" // x-release-please-version } subprojects { From dda51306a1e7500ef07fd1118f803492150c4817 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 23 Feb 2026 03:22:16 +0000 Subject: [PATCH 61/99] feat(api): manual updates --- .stats.yml | 2 +- README.md | 27 ++++------------ .../main/kotlin/cas-parser.publish.gradle.kts | 2 +- .../client/okhttp/CasParserOkHttpClient.kt | 12 +------ .../okhttp/CasParserOkHttpClientAsync.kt | 12 +------ .../com/cas_parser/api/core/ClientOptions.kt | 32 ++++--------------- 6 files changed, 17 insertions(+), 70 deletions(-) diff --git a/.stats.yml b/.stats.yml index 49508b3..603f57a 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 21 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-d9763d006969b49a1473851069fdfa429eb13133b64103a62963bb70ddb22305.yml openapi_spec_hash: 6aee689b7a759b12c85c088c15e29bc0 -config_hash: 4ab3e1ee76a463e0ed214541260ee12e +config_hash: 5509bb7a961ae2e79114b24c381606d4 diff --git a/README.md b/README.md index bb3747b..061327e 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ -The Cas Parser Java SDK provides convenient access to the [Cas Parser REST API](https://docs.casparser.in) from applications written in Java. +The Cas Parser Java SDK provides convenient access to the [Cas Parser REST API](https://casparser.in/docs) from applications written in Java. It is generated with [Stainless](https://www.stainless.com/). @@ -22,7 +22,7 @@ Use the Cas Parser MCP Server to enable AI assistants to interact with this API, -The REST API documentation can be found on [docs.casparser.in](https://docs.casparser.in). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.4.0). +The REST API documentation can be found on [casparser.in](https://casparser.in/docs). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.4.0). @@ -107,10 +107,10 @@ CasParserClient client = CasParserOkHttpClient.builder() See this table for the available options: -| Setter | System property | Environment variable | Required | Default value | -| --------- | ------------------- | --------------------- | -------- | --------------------------------------------- | -| `apiKey` | `casparser.apiKey` | `CAS_PARSER_API_KEY` | true | - | -| `baseUrl` | `casparser.baseUrl` | `CAS_PARSER_BASE_URL` | true | `"https://portfolio-parser.api.casparser.in"` | +| Setter | System property | Environment variable | Required | Default value | +| --------- | ------------------- | --------------------- | -------- | ---------------------------- | +| `apiKey` | `casparser.apiKey` | `CAS_PARSER_API_KEY` | true | - | +| `baseUrl` | `casparser.baseUrl` | `CAS_PARSER_BASE_URL` | true | `"https://api.casparser.in"` | System properties take precedence over environment variables. @@ -382,21 +382,6 @@ CasParserClient client = CasParserOkHttpClient.builder() .build(); ``` -### Environments - -The SDK sends requests to the production by default. To send requests to a different environment, configure the client like so: - -```java -import com.cas_parser.api.client.CasParserClient; -import com.cas_parser.api.client.okhttp.CasParserOkHttpClient; - -CasParserClient client = CasParserOkHttpClient.builder() - .fromEnv() - // Other options include `environment2` - .environment1() - .build(); -``` - ### Custom HTTP client The SDK consists of three artifacts: diff --git a/buildSrc/src/main/kotlin/cas-parser.publish.gradle.kts b/buildSrc/src/main/kotlin/cas-parser.publish.gradle.kts index e7683ee..f958b7b 100644 --- a/buildSrc/src/main/kotlin/cas-parser.publish.gradle.kts +++ b/buildSrc/src/main/kotlin/cas-parser.publish.gradle.kts @@ -11,7 +11,7 @@ configure { pom { name.set("CAS Parser - Track Portfolios from CDSL, NSDL, CAMS, KFintech") description.set("API for parsing and analyzing CAS (Consolidated Account Statement) PDF files\nfrom NSDL, CDSL, and CAMS/KFintech, with a unified response format") - url.set("https://docs.casparser.in") + url.set("https://casparser.in/docs") licenses { license { diff --git a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClient.kt b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClient.kt index 417682f..e6b85dd 100644 --- a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClient.kt +++ b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClient.kt @@ -207,23 +207,13 @@ class CasParserOkHttpClient private constructor() { /** * The base URL to use for every request. * - * Defaults to the production environment: `https://portfolio-parser.api.casparser.in`. - * - * The following other environments, with dedicated builder methods, are available: - * - environment_1: `https://client-apis.casparser.in` - * - environment_2: `http://localhost:5000` + * Defaults to the production environment: `https://api.casparser.in`. */ fun baseUrl(baseUrl: String?) = apply { clientOptions.baseUrl(baseUrl) } /** Alias for calling [Builder.baseUrl] with `baseUrl.orElse(null)`. */ fun baseUrl(baseUrl: Optional) = baseUrl(baseUrl.getOrNull()) - /** Sets [baseUrl] to `https://client-apis.casparser.in`. */ - fun environment1() = apply { clientOptions.environment1() } - - /** Sets [baseUrl] to `http://localhost:5000`. */ - fun environment2() = apply { clientOptions.environment2() } - /** * Whether to call `validate` on every response before returning it. * diff --git a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClientAsync.kt b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClientAsync.kt index e83fa10..71b4321 100644 --- a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClientAsync.kt +++ b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClientAsync.kt @@ -207,23 +207,13 @@ class CasParserOkHttpClientAsync private constructor() { /** * The base URL to use for every request. * - * Defaults to the production environment: `https://portfolio-parser.api.casparser.in`. - * - * The following other environments, with dedicated builder methods, are available: - * - environment_1: `https://client-apis.casparser.in` - * - environment_2: `http://localhost:5000` + * Defaults to the production environment: `https://api.casparser.in`. */ fun baseUrl(baseUrl: String?) = apply { clientOptions.baseUrl(baseUrl) } /** Alias for calling [Builder.baseUrl] with `baseUrl.orElse(null)`. */ fun baseUrl(baseUrl: Optional) = baseUrl(baseUrl.getOrNull()) - /** Sets [baseUrl] to `https://client-apis.casparser.in`. */ - fun environment1() = apply { clientOptions.environment1() } - - /** Sets [baseUrl] to `http://localhost:5000`. */ - fun environment2() = apply { clientOptions.environment2() } - /** * Whether to call `validate` on every response before returning it. * diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ClientOptions.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ClientOptions.kt index e3e4eaf..a0ed181 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ClientOptions.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ClientOptions.kt @@ -106,11 +106,7 @@ private constructor( /** * The base URL to use for every request. * - * Defaults to the production environment: `https://portfolio-parser.api.casparser.in`. - * - * The following other environments, with dedicated builder methods, are available: - * - environment_1: `https://client-apis.casparser.in` - * - environment_2: `http://localhost:5000` + * Defaults to the production environment: `https://api.casparser.in`. */ fun baseUrl(): String = baseUrl ?: PRODUCTION_URL @@ -118,11 +114,7 @@ private constructor( companion object { - const val PRODUCTION_URL = "https://portfolio-parser.api.casparser.in" - - const val ENVIRONMENT_1_URL = "https://client-apis.casparser.in" - - const val ENVIRONMENT_2_URL = "http://localhost:5000" + const val PRODUCTION_URL = "https://api.casparser.in" /** * Returns a mutable builder for constructing an instance of [ClientOptions]. @@ -228,23 +220,13 @@ private constructor( /** * The base URL to use for every request. * - * Defaults to the production environment: `https://portfolio-parser.api.casparser.in`. - * - * The following other environments, with dedicated builder methods, are available: - * - environment_1: `https://client-apis.casparser.in` - * - environment_2: `http://localhost:5000` + * Defaults to the production environment: `https://api.casparser.in`. */ fun baseUrl(baseUrl: String?) = apply { this.baseUrl = baseUrl } /** Alias for calling [Builder.baseUrl] with `baseUrl.orElse(null)`. */ fun baseUrl(baseUrl: Optional) = baseUrl(baseUrl.getOrNull()) - /** Sets [baseUrl] to `https://client-apis.casparser.in`. */ - fun environment1() = baseUrl(ENVIRONMENT_1_URL) - - /** Sets [baseUrl] to `http://localhost:5000`. */ - fun environment2() = baseUrl(ENVIRONMENT_2_URL) - /** * Whether to call `validate` on every response before returning it. * @@ -379,10 +361,10 @@ private constructor( * * See this table for the available options: * - * |Setter |System property |Environment variable |Required|Default value | - * |---------|-------------------|---------------------|--------|---------------------------------------------| - * |`apiKey` |`casparser.apiKey` |`CAS_PARSER_API_KEY` |true |- | - * |`baseUrl`|`casparser.baseUrl`|`CAS_PARSER_BASE_URL`|true |`"https://portfolio-parser.api.casparser.in"`| + * |Setter |System property |Environment variable |Required|Default value | + * |---------|-------------------|---------------------|--------|----------------------------| + * |`apiKey` |`casparser.apiKey` |`CAS_PARSER_API_KEY` |true |- | + * |`baseUrl`|`casparser.baseUrl`|`CAS_PARSER_BASE_URL`|true |`"https://api.casparser.in"`| * * System properties take precedence over environment variables. */ From 72e171bdb8d90f27803cc9ae95bea1e953df1273 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 23 Feb 2026 03:26:20 +0000 Subject: [PATCH 62/99] chore(internal): version bump --- .release-please-manifest.json | 2 +- README.md | 10 +++++----- build.gradle.kts | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index da59f99..2aca35a 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.4.0" + ".": "0.5.0" } \ No newline at end of file diff --git a/README.md b/README.md index 061327e..bcad7a7 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ -[![Maven Central](https://img.shields.io/maven-central/v/com.cas_parser.api/cas-parser-java)](https://central.sonatype.com/artifact/com.cas_parser.api/cas-parser-java/0.4.0) -[![javadoc](https://javadoc.io/badge2/com.cas_parser.api/cas-parser-java/0.4.0/javadoc.svg)](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.4.0) +[![Maven Central](https://img.shields.io/maven-central/v/com.cas_parser.api/cas-parser-java)](https://central.sonatype.com/artifact/com.cas_parser.api/cas-parser-java/0.5.0) +[![javadoc](https://javadoc.io/badge2/com.cas_parser.api/cas-parser-java/0.5.0/javadoc.svg)](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.5.0) @@ -22,7 +22,7 @@ Use the Cas Parser MCP Server to enable AI assistants to interact with this API, -The REST API documentation can be found on [casparser.in](https://casparser.in/docs). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.4.0). +The REST API documentation can be found on [casparser.in](https://casparser.in/docs). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.5.0). @@ -33,7 +33,7 @@ The REST API documentation can be found on [casparser.in](https://casparser.in/d ### Gradle ```kotlin -implementation("com.cas_parser.api:cas-parser-java:0.4.0") +implementation("com.cas_parser.api:cas-parser-java:0.5.0") ``` ### Maven @@ -42,7 +42,7 @@ implementation("com.cas_parser.api:cas-parser-java:0.4.0") com.cas_parser.api cas-parser-java - 0.4.0 + 0.5.0 ``` diff --git a/build.gradle.kts b/build.gradle.kts index 40e9f7a..4aa1227 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -9,7 +9,7 @@ repositories { allprojects { group = "com.cas_parser.api" - version = "0.4.0" // x-release-please-version + version = "0.5.0" // x-release-please-version } subprojects { From 5320c665d14cdbdb5db30612c888235aefaef345 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 24 Feb 2026 05:48:32 +0000 Subject: [PATCH 63/99] chore: make `Properties` more resilient to `null` --- .../src/main/kotlin/com/cas_parser/api/core/Properties.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Properties.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Properties.kt index dc9a375..f946e80 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Properties.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Properties.kt @@ -34,9 +34,9 @@ fun getOsName(): String { } } -fun getOsVersion(): String = System.getProperty("os.version", "unknown") +fun getOsVersion(): String = System.getProperty("os.version", "unknown") ?: "unknown" fun getPackageVersion(): String = - CasParserClient::class.java.`package`.implementationVersion ?: "unknown" + CasParserClient::class.java.`package`?.implementationVersion ?: "unknown" -fun getJavaVersion(): String = System.getProperty("java.version", "unknown") +fun getJavaVersion(): String = System.getProperty("java.version", "unknown") ?: "unknown" From e44293ef7af5e354f4856ae2ce5428e7d7c79438 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 24 Feb 2026 05:49:39 +0000 Subject: [PATCH 64/99] chore: drop apache dependency --- cas-parser-java-core/build.gradle.kts | 2 - .../api/core/http/HttpRequestBodies.kt | 297 +++++-- .../api/core/http/HttpRequestBodiesTest.kt | 729 ++++++++++++++++++ 3 files changed, 946 insertions(+), 82 deletions(-) create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/HttpRequestBodiesTest.kt diff --git a/cas-parser-java-core/build.gradle.kts b/cas-parser-java-core/build.gradle.kts index 5c40ab2..ccacdad 100644 --- a/cas-parser-java-core/build.gradle.kts +++ b/cas-parser-java-core/build.gradle.kts @@ -27,8 +27,6 @@ dependencies { implementation("com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.18.2") implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.18.2") implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.18.2") - implementation("org.apache.httpcomponents.core5:httpcore5:5.2.4") - implementation("org.apache.httpcomponents.client5:httpclient5:5.3.1") testImplementation(kotlin("test")) testImplementation(project(":cas-parser-java-client-okhttp")) diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/HttpRequestBodies.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/HttpRequestBodies.kt index 34ce9d6..6f7c370 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/HttpRequestBodies.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/HttpRequestBodies.kt @@ -5,16 +5,16 @@ package com.cas_parser.api.core.http import com.cas_parser.api.core.MultipartField +import com.cas_parser.api.core.toImmutable import com.cas_parser.api.errors.CasParserInvalidDataException import com.fasterxml.jackson.databind.JsonNode import com.fasterxml.jackson.databind.json.JsonMapper import com.fasterxml.jackson.databind.node.JsonNodeType +import java.io.ByteArrayInputStream import java.io.InputStream import java.io.OutputStream +import java.util.UUID import kotlin.jvm.optionals.getOrNull -import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder -import org.apache.hc.core5.http.ContentType -import org.apache.hc.core5.http.HttpEntity @JvmSynthetic internal inline fun json(jsonMapper: JsonMapper, value: T): HttpRequestBody = @@ -37,94 +37,231 @@ internal fun multipartFormData( jsonMapper: JsonMapper, fields: Map>, ): HttpRequestBody = - object : HttpRequestBody { - private val entity: HttpEntity by lazy { - MultipartEntityBuilder.create() - .apply { - fields.forEach { (name, field) -> - 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(field.value) - serializePart(name, node) + MultipartBody.Builder() + .apply { + fields.forEach { (name, field) -> + 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(field.value) + serializePart(name, node) + } + + parts.forEach { (name, bytes) -> + val partBody = + if (bytes is ByteArrayInputStream) { + val byteArray = bytes.readBytes() + + object : HttpRequestBody { + + override fun writeTo(outputStream: OutputStream) { + outputStream.write(byteArray) + } + + override fun contentType(): String = field.contentType + + override fun contentLength(): Long = byteArray.size.toLong() + + override fun repeatable(): Boolean = true + + override fun close() {} } + } else { + object : HttpRequestBody { + + override fun writeTo(outputStream: OutputStream) { + bytes.copyTo(outputStream) + } + + override fun contentType(): String = field.contentType + + override fun contentLength(): Long = -1L - parts.forEach { (name, bytes) -> - addBinaryBody( - name, - bytes, - ContentType.parseLenient(field.contentType), - field.filename().getOrNull(), - ) + override fun repeatable(): Boolean = false + + override fun close() = bytes.close() + } } - } + + addPart( + MultipartBody.Part.create( + name, + field.filename().getOrNull(), + field.contentType, + partBody, + ) + ) } - .build() + } } + .build() - private fun serializePart( - name: String, - node: JsonNode, - ): Sequence> = - when (node.nodeType) { - JsonNodeType.MISSING, - JsonNodeType.NULL -> emptySequence() - JsonNodeType.BINARY -> sequenceOf(name to node.binaryValue().inputStream()) - JsonNodeType.STRING -> sequenceOf(name to node.textValue().inputStream()) - JsonNodeType.BOOLEAN -> - sequenceOf(name to node.booleanValue().toString().inputStream()) - JsonNodeType.NUMBER -> - sequenceOf(name to node.numberValue().toString().inputStream()) - JsonNodeType.ARRAY -> - sequenceOf( - name to - node - .elements() - .asSequence() - .mapNotNull { element -> - when (element.nodeType) { - JsonNodeType.MISSING, - JsonNodeType.NULL -> null - JsonNodeType.STRING -> node.textValue() - JsonNodeType.BOOLEAN -> node.booleanValue().toString() - JsonNodeType.NUMBER -> node.numberValue().toString() - null, - JsonNodeType.BINARY, - JsonNodeType.ARRAY, - JsonNodeType.OBJECT, - JsonNodeType.POJO -> - throw CasParserInvalidDataException( - "Unexpected JsonNode type in array: ${node.nodeType}" - ) - } - } - .joinToString(",") - .inputStream() - ) - JsonNodeType.OBJECT -> - node.fields().asSequence().flatMap { (key, value) -> - serializePart("$name[$key]", value) - } - JsonNodeType.POJO, - null -> - throw CasParserInvalidDataException( - "Unexpected JsonNode type: ${node.nodeType}" - ) +private fun serializePart(name: String, node: JsonNode): Sequence> = + when (node.nodeType) { + JsonNodeType.MISSING, + JsonNodeType.NULL -> emptySequence() + JsonNodeType.BINARY -> sequenceOf(name to node.binaryValue().inputStream()) + JsonNodeType.STRING -> sequenceOf(name to node.textValue().byteInputStream()) + JsonNodeType.BOOLEAN -> sequenceOf(name to node.booleanValue().toString().byteInputStream()) + JsonNodeType.NUMBER -> sequenceOf(name to node.numberValue().toString().byteInputStream()) + JsonNodeType.ARRAY -> + sequenceOf( + name to + node + .elements() + .asSequence() + .mapNotNull { element -> + when (element.nodeType) { + JsonNodeType.MISSING, + JsonNodeType.NULL -> null + JsonNodeType.STRING -> element.textValue() + JsonNodeType.BOOLEAN -> element.booleanValue().toString() + JsonNodeType.NUMBER -> element.numberValue().toString() + null, + JsonNodeType.BINARY, + JsonNodeType.ARRAY, + JsonNodeType.OBJECT, + JsonNodeType.POJO -> + throw CasParserInvalidDataException( + "Unexpected JsonNode type in array: ${element.nodeType}" + ) + } + } + .joinToString(",") + .byteInputStream() + ) + JsonNodeType.OBJECT -> + node.fields().asSequence().flatMap { (key, value) -> + serializePart("$name[$key]", value) } + JsonNodeType.POJO, + null -> throw CasParserInvalidDataException("Unexpected JsonNode type: ${node.nodeType}") + } - private fun String.inputStream(): InputStream = toByteArray().inputStream() +private class MultipartBody +private constructor(private val boundary: String, private val parts: List) : HttpRequestBody { + private val boundaryBytes: ByteArray = boundary.toByteArray() + private val contentType = "multipart/form-data; boundary=$boundary" - override fun writeTo(outputStream: OutputStream) = entity.writeTo(outputStream) + // This must remain in sync with `contentLength`. + override fun writeTo(outputStream: OutputStream) { + parts.forEach { part -> + outputStream.write(DASHDASH) + outputStream.write(boundaryBytes) + outputStream.write(CRLF) - override fun contentType(): String = entity.contentType + outputStream.write(CONTENT_DISPOSITION) + outputStream.write(part.contentDisposition.toByteArray()) + outputStream.write(CRLF) - override fun contentLength(): Long = entity.contentLength + outputStream.write(CONTENT_TYPE) + outputStream.write(part.contentType.toByteArray()) + outputStream.write(CRLF) - override fun repeatable(): Boolean = entity.isRepeatable + outputStream.write(CRLF) + part.body.writeTo(outputStream) + outputStream.write(CRLF) + } - override fun close() = entity.close() + outputStream.write(DASHDASH) + outputStream.write(boundaryBytes) + outputStream.write(DASHDASH) + outputStream.write(CRLF) + } + + override fun contentType(): String = contentType + + // This must remain in sync with `writeTo`. + override fun contentLength(): Long { + var byteCount = 0L + + parts.forEach { part -> + val contentLength = part.body.contentLength() + if (contentLength == -1L) { + return -1L + } + + byteCount += + DASHDASH.size + + boundaryBytes.size + + CRLF.size + + CONTENT_DISPOSITION.size + + part.contentDisposition.toByteArray().size + + CRLF.size + + CONTENT_TYPE.size + + part.contentType.toByteArray().size + + CRLF.size + + CRLF.size + + contentLength + + CRLF.size + } + + byteCount += DASHDASH.size + boundaryBytes.size + DASHDASH.size + CRLF.size + return byteCount + } + + override fun repeatable(): Boolean = parts.all { it.body.repeatable() } + + override fun close() { + parts.forEach { it.body.close() } + } + + class Builder { + private val boundary = UUID.randomUUID().toString() + private val parts: MutableList = mutableListOf() + + fun addPart(part: Part) = apply { parts.add(part) } + + fun build() = MultipartBody(boundary, parts.toImmutable()) + } + + class Part + private constructor( + val contentDisposition: String, + val contentType: String, + val body: HttpRequestBody, + ) { + companion object { + fun create( + name: String, + filename: String?, + contentType: String, + body: HttpRequestBody, + ): Part { + val disposition = buildString { + append("form-data; name=") + appendQuotedString(name) + if (filename != null) { + append("; filename=") + appendQuotedString(filename) + } + } + return Part(disposition, contentType, body) + } + } + } + + companion object { + private val CRLF = byteArrayOf('\r'.code.toByte(), '\n'.code.toByte()) + private val DASHDASH = byteArrayOf('-'.code.toByte(), '-'.code.toByte()) + private val CONTENT_DISPOSITION = "Content-Disposition: ".toByteArray() + private val CONTENT_TYPE = "Content-Type: ".toByteArray() + + private fun StringBuilder.appendQuotedString(key: String) { + append('"') + for (ch in key) { + when (ch) { + '\n' -> append("%0A") + '\r' -> append("%0D") + '"' -> append("%22") + else -> append(ch) + } + } + append('"') + } } +} diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/HttpRequestBodiesTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/HttpRequestBodiesTest.kt new file mode 100644 index 0000000..8b9e0fd --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/HttpRequestBodiesTest.kt @@ -0,0 +1,729 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.core.http + +import com.cas_parser.api.core.MultipartField +import com.cas_parser.api.core.jsonMapper +import java.io.ByteArrayOutputStream +import java.io.InputStream +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class HttpRequestBodiesTest { + + @Test + fun multipartFormData_serializesFieldWithFilename() { + val body = + multipartFormData( + jsonMapper(), + mapOf( + "file" to + MultipartField.builder() + .value("hello") + .filename("hello.txt") + .contentType("text/plain") + .build() + ), + ) + + val output = ByteArrayOutputStream() + body.writeTo(output) + + assertThat(body.repeatable()).isTrue() + assertThat(output.size().toLong()).isEqualTo(body.contentLength()) + val boundary = body.contentType()!!.substringAfter("multipart/form-data; boundary=") + assertThat(output.toString("UTF-8")) + .isEqualTo( + """ + |--$boundary + |Content-Disposition: form-data; name="file"; filename="hello.txt" + |Content-Type: text/plain + | + |hello + |--$boundary-- + | + """ + .trimMargin() + .replace("\n", "\r\n") + ) + } + + @Test + fun multipartFormData_serializesFieldWithoutFilename() { + val body = + multipartFormData( + jsonMapper(), + mapOf( + "field" to + MultipartField.builder() + .value("value") + .contentType("text/plain") + .build() + ), + ) + + val output = ByteArrayOutputStream() + body.writeTo(output) + + assertThat(body.repeatable()).isTrue() + assertThat(output.size().toLong()).isEqualTo(body.contentLength()) + val boundary = boundary(body) + assertThat(output.toString("UTF-8")) + .isEqualTo( + """ + |--$boundary + |Content-Disposition: form-data; name="field" + |Content-Type: text/plain + | + |value + |--$boundary-- + | + """ + .trimMargin() + .replace("\n", "\r\n") + ) + } + + @Test + fun multipartFormData_serializesInputStream() { + // Use `.buffered()` to get a non-ByteArrayInputStream, which hits the non-repeatable code + // path. + val inputStream = "stream content".byteInputStream().buffered() + val body = + multipartFormData( + jsonMapper(), + mapOf( + "data" to + MultipartField.builder() + .value(inputStream) + .contentType("application/octet-stream") + .build() + ), + ) + + val output = ByteArrayOutputStream() + body.writeTo(output) + + assertThat(body.repeatable()).isFalse() + assertThat(body.contentLength()).isEqualTo(-1L) + val boundary = boundary(body) + assertThat(output.toString("UTF-8")) + .isEqualTo( + """ + |--$boundary + |Content-Disposition: form-data; name="data" + |Content-Type: application/octet-stream + | + |stream content + |--$boundary-- + | + """ + .trimMargin() + .replace("\n", "\r\n") + ) + } + + @Test + fun multipartFormData_serializesByteArray() { + val body = + multipartFormData( + jsonMapper(), + mapOf( + "binary" to + MultipartField.builder() + .value("abc".toByteArray()) + .contentType("application/octet-stream") + .build() + ), + ) + + val output = ByteArrayOutputStream() + body.writeTo(output) + + assertThat(body.repeatable()).isTrue() + assertThat(body.contentLength()).isEqualTo(output.size().toLong()) + val boundary = boundary(body) + assertThat(output.toString("UTF-8")) + .isEqualTo( + """ + |--$boundary + |Content-Disposition: form-data; name="binary" + |Content-Type: application/octet-stream + | + |abc + |--$boundary-- + | + """ + .trimMargin() + .replace("\n", "\r\n") + ) + } + + @Test + fun multipartFormData_serializesBooleanValue() { + val body = + multipartFormData( + jsonMapper(), + mapOf( + "flag" to + MultipartField.builder() + .value(true) + .contentType("text/plain") + .build() + ), + ) + + val output = ByteArrayOutputStream() + body.writeTo(output) + + assertThat(body.repeatable()).isTrue() + assertThat(body.contentLength()).isEqualTo(output.size().toLong()) + val boundary = boundary(body) + assertThat(output.toString("UTF-8")) + .isEqualTo( + """ + |--$boundary + |Content-Disposition: form-data; name="flag" + |Content-Type: text/plain + | + |true + |--$boundary-- + | + """ + .trimMargin() + .replace("\n", "\r\n") + ) + } + + @Test + fun multipartFormData_serializesNumberValue() { + val body = + multipartFormData( + jsonMapper(), + mapOf( + "count" to + MultipartField.builder().value(42).contentType("text/plain").build() + ), + ) + + val output = ByteArrayOutputStream() + body.writeTo(output) + + assertThat(body.repeatable()).isTrue() + assertThat(body.contentLength()).isEqualTo(output.size().toLong()) + val boundary = boundary(body) + assertThat(output.toString("UTF-8")) + .isEqualTo( + """ + |--$boundary + |Content-Disposition: form-data; name="count" + |Content-Type: text/plain + | + |42 + |--$boundary-- + | + """ + .trimMargin() + .replace("\n", "\r\n") + ) + } + + @Test + fun multipartFormData_serializesNullValueAsNoParts() { + val body = + multipartFormData( + jsonMapper(), + mapOf( + "present" to + MultipartField.builder() + .value("yes") + .contentType("text/plain") + .build(), + "absent" to + MultipartField.builder() + .value(null as String?) + .contentType("text/plain") + .build(), + ), + ) + + val output = ByteArrayOutputStream() + body.writeTo(output) + + assertThat(body.repeatable()).isTrue() + assertThat(body.contentLength()).isEqualTo(output.size().toLong()) + val boundary = boundary(body) + assertThat(output.toString("UTF-8")) + .isEqualTo( + """ + |--$boundary + |Content-Disposition: form-data; name="present" + |Content-Type: text/plain + | + |yes + |--$boundary-- + | + """ + .trimMargin() + .replace("\n", "\r\n") + ) + } + + @Test + fun multipartFormData_serializesArray() { + val body = + multipartFormData( + jsonMapper(), + mapOf( + "items" to + MultipartField.builder>() + .value(listOf("alpha", "beta", "gamma")) + .contentType("text/plain") + .build() + ), + ) + + val output = ByteArrayOutputStream() + body.writeTo(output) + + assertThat(body.repeatable()).isTrue() + assertThat(body.contentLength()).isEqualTo(output.size().toLong()) + val boundary = boundary(body) + assertThat(output.toString("UTF-8")) + .isEqualTo( + """ + |--$boundary + |Content-Disposition: form-data; name="items" + |Content-Type: text/plain + | + |alpha,beta,gamma + |--$boundary-- + | + """ + .trimMargin() + .replace("\n", "\r\n") + ) + } + + @Test + fun multipartFormData_serializesObjectAsNestedParts() { + val body = + multipartFormData( + jsonMapper(), + mapOf( + "meta" to + MultipartField.builder>() + .value(mapOf("key1" to "val1", "key2" to "val2")) + .contentType("text/plain") + .build() + ), + ) + + val output = ByteArrayOutputStream() + body.writeTo(output) + + assertThat(body.repeatable()).isTrue() + assertThat(body.contentLength()).isEqualTo(output.size().toLong()) + val boundary = boundary(body) + assertThat(output.toString("UTF-8")) + .isEqualTo( + """ + |--$boundary + |Content-Disposition: form-data; name="meta[key1]" + |Content-Type: text/plain + | + |val1 + |--$boundary + |Content-Disposition: form-data; name="meta[key2]" + |Content-Type: text/plain + | + |val2 + |--$boundary-- + | + """ + .trimMargin() + .replace("\n", "\r\n") + ) + } + + @Test + fun multipartFormData_serializesMultipleFields() { + val body = + multipartFormData( + jsonMapper(), + mapOf( + "name" to + MultipartField.builder() + .value("Alice") + .contentType("text/plain") + .build(), + "age" to + MultipartField.builder().value(30).contentType("text/plain").build(), + "file" to + MultipartField.builder() + .value("file contents") + .filename("doc.txt") + .contentType("text/plain") + .build(), + ), + ) + + val output = ByteArrayOutputStream() + body.writeTo(output) + + assertThat(body.repeatable()).isTrue() + assertThat(body.contentLength()).isEqualTo(output.size().toLong()) + val boundary = boundary(body) + assertThat(output.toString("UTF-8")) + .isEqualTo( + """ + |--$boundary + |Content-Disposition: form-data; name="name" + |Content-Type: text/plain + | + |Alice + |--$boundary + |Content-Disposition: form-data; name="age" + |Content-Type: text/plain + | + |30 + |--$boundary + |Content-Disposition: form-data; name="file"; filename="doc.txt" + |Content-Type: text/plain + | + |file contents + |--$boundary-- + | + """ + .trimMargin() + .replace("\n", "\r\n") + ) + } + + @Test + fun multipartFormData_quotesSpecialCharactersInNameAndFilename() { + val body = + multipartFormData( + jsonMapper(), + mapOf( + "field\nname" to + MultipartField.builder() + .value("value") + .filename("file\r\"name.txt") + .contentType("text/plain") + .build() + ), + ) + + val output = ByteArrayOutputStream() + body.writeTo(output) + + assertThat(body.repeatable()).isTrue() + assertThat(body.contentLength()).isEqualTo(output.size().toLong()) + val boundary = boundary(body) + assertThat(output.toString("UTF-8")) + .isEqualTo( + """ + |--$boundary + |Content-Disposition: form-data; name="field%0Aname"; filename="file%0D%22name.txt" + |Content-Type: text/plain + | + |value + |--$boundary-- + | + """ + .trimMargin() + .replace("\n", "\r\n") + ) + } + + @Test + fun multipartFormData_writeIsRepeatable() { + val body = + multipartFormData( + jsonMapper(), + mapOf( + "field" to + MultipartField.builder() + .value("repeatable") + .contentType("text/plain") + .build() + ), + ) + + val output1 = ByteArrayOutputStream() + body.writeTo(output1) + val output2 = ByteArrayOutputStream() + body.writeTo(output2) + + assertThat(body.repeatable()).isTrue() + assertThat(body.contentLength()).isEqualTo(output1.size().toLong()) + val boundary = boundary(body) + val expected = + """ + |--$boundary + |Content-Disposition: form-data; name="field" + |Content-Type: text/plain + | + |repeatable + |--$boundary-- + | + """ + .trimMargin() + .replace("\n", "\r\n") + assertThat(output1.toString("UTF-8")).isEqualTo(expected) + assertThat(output2.toString("UTF-8")).isEqualTo(expected) + } + + @Test + fun multipartFormData_serializesByteArrayInputStream() { + // ByteArrayInputStream is specifically handled as repeatable with known content length. + val inputStream = "byte array stream".byteInputStream() + val body = + multipartFormData( + jsonMapper(), + mapOf( + "data" to + MultipartField.builder() + .value(inputStream) + .contentType("application/octet-stream") + .build() + ), + ) + + val output = ByteArrayOutputStream() + body.writeTo(output) + + assertThat(body.repeatable()).isTrue() + assertThat(body.contentLength()).isEqualTo(output.size().toLong()) + val boundary = boundary(body) + assertThat(output.toString("UTF-8")) + .isEqualTo( + """ + |--$boundary + |Content-Disposition: form-data; name="data" + |Content-Type: application/octet-stream + | + |byte array stream + |--$boundary-- + | + """ + .trimMargin() + .replace("\n", "\r\n") + ) + } + + @Test + fun multipartFormData_serializesInputStreamWithFilename() { + // Use `.buffered()` to get a non-ByteArrayInputStream, which hits the non-repeatable code + // path. + val inputStream = "file data".byteInputStream().buffered() + val body = + multipartFormData( + jsonMapper(), + mapOf( + "upload" to + MultipartField.builder() + .value(inputStream) + .filename("upload.bin") + .contentType("application/octet-stream") + .build() + ), + ) + + val output = ByteArrayOutputStream() + body.writeTo(output) + + assertThat(body.repeatable()).isFalse() + assertThat(body.contentLength()).isEqualTo(-1L) + val boundary = boundary(body) + assertThat(output.toString("UTF-8")) + .isEqualTo( + """ + |--$boundary + |Content-Disposition: form-data; name="upload"; filename="upload.bin" + |Content-Type: application/octet-stream + | + |file data + |--$boundary-- + | + """ + .trimMargin() + .replace("\n", "\r\n") + ) + } + + @Test + fun multipartFormData_serializesNestedArrayInObject() { + val body = + multipartFormData( + jsonMapper(), + mapOf( + "data" to + MultipartField.builder>>() + .value(mapOf("tags" to listOf("a", "b"))) + .contentType("text/plain") + .build() + ), + ) + + val output = ByteArrayOutputStream() + body.writeTo(output) + + assertThat(body.repeatable()).isTrue() + assertThat(body.contentLength()).isEqualTo(output.size().toLong()) + val boundary = boundary(body) + assertThat(output.toString("UTF-8")) + .isEqualTo( + """ + |--$boundary + |Content-Disposition: form-data; name="data[tags]" + |Content-Type: text/plain + | + |a,b + |--$boundary-- + | + """ + .trimMargin() + .replace("\n", "\r\n") + ) + } + + @Test + fun multipartFormData_contentLengthIsUnknownWhenInputStreamPresent() { + val body = + multipartFormData( + jsonMapper(), + mapOf( + "text" to + MultipartField.builder() + .value("hello") + .contentType("text/plain") + .build(), + "stream" to + MultipartField.builder() + // Use `.buffered()` to get a non-ByteArrayInputStream, which hits the + // non-repeatable code path. + .value("data".byteInputStream().buffered()) + .contentType("application/octet-stream") + .build(), + ), + ) + + val output = ByteArrayOutputStream() + body.writeTo(output) + + assertThat(body.repeatable()).isFalse() + assertThat(body.contentLength()).isEqualTo(-1L) + val boundary = boundary(body) + assertThat(output.toString("UTF-8")) + .isEqualTo( + """ + |--$boundary + |Content-Disposition: form-data; name="text" + |Content-Type: text/plain + | + |hello + |--$boundary + |Content-Disposition: form-data; name="stream" + |Content-Type: application/octet-stream + | + |data + |--$boundary-- + | + """ + .trimMargin() + .replace("\n", "\r\n") + ) + } + + @Test + fun multipartFormData_serializesEmptyArray() { + val body = + multipartFormData( + jsonMapper(), + mapOf( + "required" to + MultipartField.builder() + .value("present") + .contentType("text/plain") + .build(), + "items" to + MultipartField.builder>() + .value(emptyList()) + .contentType("text/plain") + .build(), + ), + ) + + val output = ByteArrayOutputStream() + body.writeTo(output) + + assertThat(body.repeatable()).isTrue() + assertThat(body.contentLength()).isEqualTo(output.size().toLong()) + val boundary = boundary(body) + assertThat(output.toString("UTF-8")) + .isEqualTo( + """ + |--$boundary + |Content-Disposition: form-data; name="required" + |Content-Type: text/plain + | + |present + |--$boundary + |Content-Disposition: form-data; name="items" + |Content-Type: text/plain + | + | + |--$boundary-- + | + """ + .trimMargin() + .replace("\n", "\r\n") + ) + } + + @Test + fun multipartFormData_serializesEmptyObject() { + val body = + multipartFormData( + jsonMapper(), + mapOf( + "required" to + MultipartField.builder() + .value("present") + .contentType("text/plain") + .build(), + "meta" to + MultipartField.builder>() + .value(emptyMap()) + .contentType("text/plain") + .build(), + ), + ) + + val output = ByteArrayOutputStream() + body.writeTo(output) + + assertThat(body.repeatable()).isTrue() + assertThat(body.contentLength()).isEqualTo(output.size().toLong()) + val boundary = boundary(body) + assertThat(output.toString("UTF-8")) + .isEqualTo( + """ + |--$boundary + |Content-Disposition: form-data; name="required" + |Content-Type: text/plain + | + |present + |--$boundary-- + | + """ + .trimMargin() + .replace("\n", "\r\n") + ) + } + + private fun boundary(body: HttpRequestBody): String = + body.contentType()!!.substringAfter("multipart/form-data; boundary=") +} From becbe7bc6995b6b5d605b6c96aa23ace9fe9a592 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 25 Feb 2026 05:23:49 +0000 Subject: [PATCH 65/99] chore(internal): expand imports --- .../cas_parser/api/core/http/RetryingHttpClient.kt | 2 ++ .../api/core/http/RetryingHttpClientTest.kt | 13 ++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/RetryingHttpClient.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/RetryingHttpClient.kt index 3f34f6e..7b39c62 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/RetryingHttpClient.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/RetryingHttpClient.kt @@ -1,3 +1,5 @@ +// File generated from our OpenAPI spec by Stainless. + package com.cas_parser.api.core.http import com.cas_parser.api.core.DefaultSleeper diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/RetryingHttpClientTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/RetryingHttpClientTest.kt index 90db8ea..c3f47cd 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/RetryingHttpClientTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/RetryingHttpClientTest.kt @@ -1,10 +1,21 @@ +// File generated from our OpenAPI spec by Stainless. + package com.cas_parser.api.core.http import com.cas_parser.api.client.okhttp.OkHttpClient import com.cas_parser.api.core.RequestOptions import com.cas_parser.api.core.Sleeper import com.cas_parser.api.errors.CasParserRetryableException -import com.github.tomakehurst.wiremock.client.WireMock.* +import com.github.tomakehurst.wiremock.client.WireMock.equalTo +import com.github.tomakehurst.wiremock.client.WireMock.matching +import com.github.tomakehurst.wiremock.client.WireMock.ok +import com.github.tomakehurst.wiremock.client.WireMock.post +import com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor +import com.github.tomakehurst.wiremock.client.WireMock.resetAllScenarios +import com.github.tomakehurst.wiremock.client.WireMock.serviceUnavailable +import com.github.tomakehurst.wiremock.client.WireMock.stubFor +import com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo +import com.github.tomakehurst.wiremock.client.WireMock.verify import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo import com.github.tomakehurst.wiremock.junit5.WireMockTest import com.github.tomakehurst.wiremock.stubbing.Scenario From cbbff6c58bbac6e4e489327d1f123ae3cb1fd662 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 3 Mar 2026 08:19:36 +0000 Subject: [PATCH 66/99] chore(internal): codegen related update --- .../cas_parser/api/client/CasParserClient.kt | 138 ++++++++++++++++++ .../api/client/CasParserClientAsync.kt | 138 ++++++++++++++++++ .../api/client/CasParserClientAsyncImpl.kt | 138 ++++++++++++++++++ .../api/client/CasParserClientImpl.kt | 138 ++++++++++++++++++ .../services/async/AccessTokenServiceAsync.kt | 5 + .../async/AccessTokenServiceAsyncImpl.kt | 5 + .../async/CamsKfintechServiceAsync.kt | 1 + .../async/CamsKfintechServiceAsyncImpl.kt | 1 + .../api/services/async/CdslServiceAsync.kt | 9 ++ .../services/async/CdslServiceAsyncImpl.kt | 9 ++ .../async/ContractNoteServiceAsync.kt | 4 + .../async/ContractNoteServiceAsyncImpl.kt | 4 + .../api/services/async/CreditServiceAsync.kt | 4 + .../services/async/CreditServiceAsyncImpl.kt | 4 + .../async/InboundEmailServiceAsync.kt | 23 +++ .../async/InboundEmailServiceAsyncImpl.kt | 23 +++ .../api/services/async/InboxServiceAsync.kt | 17 +++ .../services/async/InboxServiceAsyncImpl.kt | 17 +++ .../services/async/KfintechServiceAsync.kt | 1 + .../async/KfintechServiceAsyncImpl.kt | 1 + .../api/services/async/LogServiceAsync.kt | 4 + .../api/services/async/LogServiceAsyncImpl.kt | 4 + .../api/services/async/NsdlServiceAsync.kt | 1 + .../services/async/NsdlServiceAsyncImpl.kt | 1 + .../api/services/async/SmartServiceAsync.kt | 1 + .../services/async/SmartServiceAsyncImpl.kt | 1 + .../services/async/VerifyTokenServiceAsync.kt | 5 + .../async/VerifyTokenServiceAsyncImpl.kt | 5 + .../services/async/cdsl/FetchServiceAsync.kt | 4 + .../async/cdsl/FetchServiceAsyncImpl.kt | 4 + .../services/blocking/AccessTokenService.kt | 5 + .../blocking/AccessTokenServiceImpl.kt | 5 + .../services/blocking/CamsKfintechService.kt | 1 + .../blocking/CamsKfintechServiceImpl.kt | 1 + .../api/services/blocking/CdslService.kt | 9 ++ .../api/services/blocking/CdslServiceImpl.kt | 9 ++ .../services/blocking/ContractNoteService.kt | 4 + .../blocking/ContractNoteServiceImpl.kt | 4 + .../api/services/blocking/CreditService.kt | 4 + .../services/blocking/CreditServiceImpl.kt | 4 + .../services/blocking/InboundEmailService.kt | 23 +++ .../blocking/InboundEmailServiceImpl.kt | 23 +++ .../api/services/blocking/InboxService.kt | 17 +++ .../api/services/blocking/InboxServiceImpl.kt | 17 +++ .../api/services/blocking/KfintechService.kt | 1 + .../services/blocking/KfintechServiceImpl.kt | 1 + .../api/services/blocking/LogService.kt | 4 + .../api/services/blocking/LogServiceImpl.kt | 4 + .../api/services/blocking/NsdlService.kt | 1 + .../api/services/blocking/NsdlServiceImpl.kt | 1 + .../api/services/blocking/SmartService.kt | 1 + .../api/services/blocking/SmartServiceImpl.kt | 1 + .../services/blocking/VerifyTokenService.kt | 5 + .../blocking/VerifyTokenServiceImpl.kt | 5 + .../services/blocking/cdsl/FetchService.kt | 4 + .../blocking/cdsl/FetchServiceImpl.kt | 4 + 56 files changed, 868 insertions(+) diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClient.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClient.kt index df928cf..6c17b45 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClient.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClient.kt @@ -53,28 +53,97 @@ interface CasParserClient { */ fun withOptions(modifier: Consumer): CasParserClient + /** + * Endpoints for checking API quota and credits usage. These endpoints help you monitor your API + * usage and remaining quota. + */ fun credits(): CreditService + /** + * Endpoints for checking API quota and credits usage. These endpoints help you monitor your API + * usage and remaining quota. + */ fun logs(): LogService + /** + * Endpoints for managing access tokens for the Portfolio Connect SDK. Use these to generate + * short-lived `at_` prefixed tokens that can be safely passed to frontend applications. Access + * tokens can be used in place of API keys on all v4 endpoints. + */ fun accessToken(): AccessTokenService + /** + * Endpoints for managing access tokens for the Portfolio Connect SDK. Use these to generate + * short-lived `at_` prefixed tokens that can be safely passed to frontend applications. Access + * tokens can be used in place of API keys on all v4 endpoints. + */ fun verifyToken(): VerifyTokenService + /** Endpoints for parsing CAS PDF files from different sources. */ fun camsKfintech(): CamsKfintechService + /** Endpoints for parsing CAS PDF files from different sources. */ fun cdsl(): CdslService + /** + * Endpoints for parsing Contract Note PDF files from various SEBI brokers like Zerodha, Groww, + * Upstox, ICICI etc. + */ fun contractNote(): ContractNoteService + /** + * Endpoints for importing CAS files directly from user email inboxes. + * + * **Supported Providers:** Gmail (more coming soon) + * + * **How it works:** + * 1. Call `POST /v4/inbox/connect` to get an OAuth URL + * 2. Redirect user to the OAuth URL for consent + * 3. User is redirected back to your `redirect_uri` with an encrypted `inbox_token` + * 4. Use the token to list/fetch CAS files from their inbox (`/v4/inbox/cas`) + * 5. Files are uploaded to temporary cloud storage (URLs expire in 24 hours) + * + * **Security:** + * - Read-only access (we cannot send emails) + * - Tokens are encrypted with server-side secret + * - User can revoke access anytime via `/v4/inbox/disconnect` + */ fun inbox(): InboxService + /** Endpoints for generating new CAS documents via email mailback (KFintech). */ fun kfintech(): KfintechService + /** Endpoints for parsing CAS PDF files from different sources. */ fun nsdl(): NsdlService + /** Endpoints for parsing CAS PDF files from different sources. */ fun smart(): SmartService + /** + * Create dedicated inbound email addresses for investors to forward their CAS statements. + * + * **Use Case:** Your app wants to collect CAS statements from users without requiring OAuth or + * file upload. + * + * **How it works:** + * 1. Call `POST /v4/inbound-email` to create a unique inbound email address + * 2. Display this email to your user: "Forward your CAS statement to + * ie_xxx@import.casparser.in" + * 3. When user forwards a CAS email, we verify sender authenticity (SPF/DKIM) and call your + * webhook + * 4. Your webhook receives email metadata + attachment download URLs + * + * **Sender Validation:** + * - Only emails from verified CAS authorities are processed: + * - CDSL: `eCAS@cdslstatement.com` + * - NSDL: `NSDL-CAS@nsdl.co.in` + * - CAMS: `donotreply@camsonline.com` + * - KFintech: `samfS@kfintech.com` + * - Emails failing SPF/DKIM/DMARC are rejected + * - Forwarded emails must contain the original sender in headers + * + * **Billing:** 0.2 credits per successfully processed valid email + */ fun inboundEmail(): InboundEmailService /** @@ -100,28 +169,97 @@ interface CasParserClient { */ fun withOptions(modifier: Consumer): CasParserClient.WithRawResponse + /** + * Endpoints for checking API quota and credits usage. These endpoints help you monitor your + * API usage and remaining quota. + */ fun credits(): CreditService.WithRawResponse + /** + * Endpoints for checking API quota and credits usage. These endpoints help you monitor your + * API usage and remaining quota. + */ fun logs(): LogService.WithRawResponse + /** + * Endpoints for managing access tokens for the Portfolio Connect SDK. Use these to generate + * short-lived `at_` prefixed tokens that can be safely passed to frontend applications. + * Access tokens can be used in place of API keys on all v4 endpoints. + */ fun accessToken(): AccessTokenService.WithRawResponse + /** + * Endpoints for managing access tokens for the Portfolio Connect SDK. Use these to generate + * short-lived `at_` prefixed tokens that can be safely passed to frontend applications. + * Access tokens can be used in place of API keys on all v4 endpoints. + */ fun verifyToken(): VerifyTokenService.WithRawResponse + /** Endpoints for parsing CAS PDF files from different sources. */ fun camsKfintech(): CamsKfintechService.WithRawResponse + /** Endpoints for parsing CAS PDF files from different sources. */ fun cdsl(): CdslService.WithRawResponse + /** + * Endpoints for parsing Contract Note PDF files from various SEBI brokers like Zerodha, + * Groww, Upstox, ICICI etc. + */ fun contractNote(): ContractNoteService.WithRawResponse + /** + * Endpoints for importing CAS files directly from user email inboxes. + * + * **Supported Providers:** Gmail (more coming soon) + * + * **How it works:** + * 1. Call `POST /v4/inbox/connect` to get an OAuth URL + * 2. Redirect user to the OAuth URL for consent + * 3. User is redirected back to your `redirect_uri` with an encrypted `inbox_token` + * 4. Use the token to list/fetch CAS files from their inbox (`/v4/inbox/cas`) + * 5. Files are uploaded to temporary cloud storage (URLs expire in 24 hours) + * + * **Security:** + * - Read-only access (we cannot send emails) + * - Tokens are encrypted with server-side secret + * - User can revoke access anytime via `/v4/inbox/disconnect` + */ fun inbox(): InboxService.WithRawResponse + /** Endpoints for generating new CAS documents via email mailback (KFintech). */ fun kfintech(): KfintechService.WithRawResponse + /** Endpoints for parsing CAS PDF files from different sources. */ fun nsdl(): NsdlService.WithRawResponse + /** Endpoints for parsing CAS PDF files from different sources. */ fun smart(): SmartService.WithRawResponse + /** + * Create dedicated inbound email addresses for investors to forward their CAS statements. + * + * **Use Case:** Your app wants to collect CAS statements from users without requiring OAuth + * or file upload. + * + * **How it works:** + * 1. Call `POST /v4/inbound-email` to create a unique inbound email address + * 2. Display this email to your user: "Forward your CAS statement to + * ie_xxx@import.casparser.in" + * 3. When user forwards a CAS email, we verify sender authenticity (SPF/DKIM) and call your + * webhook + * 4. Your webhook receives email metadata + attachment download URLs + * + * **Sender Validation:** + * - Only emails from verified CAS authorities are processed: + * - CDSL: `eCAS@cdslstatement.com` + * - NSDL: `NSDL-CAS@nsdl.co.in` + * - CAMS: `donotreply@camsonline.com` + * - KFintech: `samfS@kfintech.com` + * - Emails failing SPF/DKIM/DMARC are rejected + * - Forwarded emails must contain the original sender in headers + * + * **Billing:** 0.2 credits per successfully processed valid email + */ fun inboundEmail(): InboundEmailService.WithRawResponse } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientAsync.kt index 4d828d5..575d503 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientAsync.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientAsync.kt @@ -53,28 +53,97 @@ interface CasParserClientAsync { */ fun withOptions(modifier: Consumer): CasParserClientAsync + /** + * Endpoints for checking API quota and credits usage. These endpoints help you monitor your API + * usage and remaining quota. + */ fun credits(): CreditServiceAsync + /** + * Endpoints for checking API quota and credits usage. These endpoints help you monitor your API + * usage and remaining quota. + */ fun logs(): LogServiceAsync + /** + * Endpoints for managing access tokens for the Portfolio Connect SDK. Use these to generate + * short-lived `at_` prefixed tokens that can be safely passed to frontend applications. Access + * tokens can be used in place of API keys on all v4 endpoints. + */ fun accessToken(): AccessTokenServiceAsync + /** + * Endpoints for managing access tokens for the Portfolio Connect SDK. Use these to generate + * short-lived `at_` prefixed tokens that can be safely passed to frontend applications. Access + * tokens can be used in place of API keys on all v4 endpoints. + */ fun verifyToken(): VerifyTokenServiceAsync + /** Endpoints for parsing CAS PDF files from different sources. */ fun camsKfintech(): CamsKfintechServiceAsync + /** Endpoints for parsing CAS PDF files from different sources. */ fun cdsl(): CdslServiceAsync + /** + * Endpoints for parsing Contract Note PDF files from various SEBI brokers like Zerodha, Groww, + * Upstox, ICICI etc. + */ fun contractNote(): ContractNoteServiceAsync + /** + * Endpoints for importing CAS files directly from user email inboxes. + * + * **Supported Providers:** Gmail (more coming soon) + * + * **How it works:** + * 1. Call `POST /v4/inbox/connect` to get an OAuth URL + * 2. Redirect user to the OAuth URL for consent + * 3. User is redirected back to your `redirect_uri` with an encrypted `inbox_token` + * 4. Use the token to list/fetch CAS files from their inbox (`/v4/inbox/cas`) + * 5. Files are uploaded to temporary cloud storage (URLs expire in 24 hours) + * + * **Security:** + * - Read-only access (we cannot send emails) + * - Tokens are encrypted with server-side secret + * - User can revoke access anytime via `/v4/inbox/disconnect` + */ fun inbox(): InboxServiceAsync + /** Endpoints for generating new CAS documents via email mailback (KFintech). */ fun kfintech(): KfintechServiceAsync + /** Endpoints for parsing CAS PDF files from different sources. */ fun nsdl(): NsdlServiceAsync + /** Endpoints for parsing CAS PDF files from different sources. */ fun smart(): SmartServiceAsync + /** + * Create dedicated inbound email addresses for investors to forward their CAS statements. + * + * **Use Case:** Your app wants to collect CAS statements from users without requiring OAuth or + * file upload. + * + * **How it works:** + * 1. Call `POST /v4/inbound-email` to create a unique inbound email address + * 2. Display this email to your user: "Forward your CAS statement to + * ie_xxx@import.casparser.in" + * 3. When user forwards a CAS email, we verify sender authenticity (SPF/DKIM) and call your + * webhook + * 4. Your webhook receives email metadata + attachment download URLs + * + * **Sender Validation:** + * - Only emails from verified CAS authorities are processed: + * - CDSL: `eCAS@cdslstatement.com` + * - NSDL: `NSDL-CAS@nsdl.co.in` + * - CAMS: `donotreply@camsonline.com` + * - KFintech: `samfS@kfintech.com` + * - Emails failing SPF/DKIM/DMARC are rejected + * - Forwarded emails must contain the original sender in headers + * + * **Billing:** 0.2 credits per successfully processed valid email + */ fun inboundEmail(): InboundEmailServiceAsync /** @@ -104,28 +173,97 @@ interface CasParserClientAsync { modifier: Consumer ): CasParserClientAsync.WithRawResponse + /** + * Endpoints for checking API quota and credits usage. These endpoints help you monitor your + * API usage and remaining quota. + */ fun credits(): CreditServiceAsync.WithRawResponse + /** + * Endpoints for checking API quota and credits usage. These endpoints help you monitor your + * API usage and remaining quota. + */ fun logs(): LogServiceAsync.WithRawResponse + /** + * Endpoints for managing access tokens for the Portfolio Connect SDK. Use these to generate + * short-lived `at_` prefixed tokens that can be safely passed to frontend applications. + * Access tokens can be used in place of API keys on all v4 endpoints. + */ fun accessToken(): AccessTokenServiceAsync.WithRawResponse + /** + * Endpoints for managing access tokens for the Portfolio Connect SDK. Use these to generate + * short-lived `at_` prefixed tokens that can be safely passed to frontend applications. + * Access tokens can be used in place of API keys on all v4 endpoints. + */ fun verifyToken(): VerifyTokenServiceAsync.WithRawResponse + /** Endpoints for parsing CAS PDF files from different sources. */ fun camsKfintech(): CamsKfintechServiceAsync.WithRawResponse + /** Endpoints for parsing CAS PDF files from different sources. */ fun cdsl(): CdslServiceAsync.WithRawResponse + /** + * Endpoints for parsing Contract Note PDF files from various SEBI brokers like Zerodha, + * Groww, Upstox, ICICI etc. + */ fun contractNote(): ContractNoteServiceAsync.WithRawResponse + /** + * Endpoints for importing CAS files directly from user email inboxes. + * + * **Supported Providers:** Gmail (more coming soon) + * + * **How it works:** + * 1. Call `POST /v4/inbox/connect` to get an OAuth URL + * 2. Redirect user to the OAuth URL for consent + * 3. User is redirected back to your `redirect_uri` with an encrypted `inbox_token` + * 4. Use the token to list/fetch CAS files from their inbox (`/v4/inbox/cas`) + * 5. Files are uploaded to temporary cloud storage (URLs expire in 24 hours) + * + * **Security:** + * - Read-only access (we cannot send emails) + * - Tokens are encrypted with server-side secret + * - User can revoke access anytime via `/v4/inbox/disconnect` + */ fun inbox(): InboxServiceAsync.WithRawResponse + /** Endpoints for generating new CAS documents via email mailback (KFintech). */ fun kfintech(): KfintechServiceAsync.WithRawResponse + /** Endpoints for parsing CAS PDF files from different sources. */ fun nsdl(): NsdlServiceAsync.WithRawResponse + /** Endpoints for parsing CAS PDF files from different sources. */ fun smart(): SmartServiceAsync.WithRawResponse + /** + * Create dedicated inbound email addresses for investors to forward their CAS statements. + * + * **Use Case:** Your app wants to collect CAS statements from users without requiring OAuth + * or file upload. + * + * **How it works:** + * 1. Call `POST /v4/inbound-email` to create a unique inbound email address + * 2. Display this email to your user: "Forward your CAS statement to + * ie_xxx@import.casparser.in" + * 3. When user forwards a CAS email, we verify sender authenticity (SPF/DKIM) and call your + * webhook + * 4. Your webhook receives email metadata + attachment download URLs + * + * **Sender Validation:** + * - Only emails from verified CAS authorities are processed: + * - CDSL: `eCAS@cdslstatement.com` + * - NSDL: `NSDL-CAS@nsdl.co.in` + * - CAMS: `donotreply@camsonline.com` + * - KFintech: `samfS@kfintech.com` + * - Emails failing SPF/DKIM/DMARC are rejected + * - Forwarded emails must contain the original sender in headers + * + * **Billing:** 0.2 credits per successfully processed valid email + */ fun inboundEmail(): InboundEmailServiceAsync.WithRawResponse } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientAsyncImpl.kt index b10af0a..eed1327 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientAsyncImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientAsyncImpl.kt @@ -96,28 +96,97 @@ class CasParserClientAsyncImpl(private val clientOptions: ClientOptions) : CasPa override fun withOptions(modifier: Consumer): CasParserClientAsync = CasParserClientAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + /** + * Endpoints for checking API quota and credits usage. These endpoints help you monitor your API + * usage and remaining quota. + */ override fun credits(): CreditServiceAsync = credits + /** + * Endpoints for checking API quota and credits usage. These endpoints help you monitor your API + * usage and remaining quota. + */ override fun logs(): LogServiceAsync = logs + /** + * Endpoints for managing access tokens for the Portfolio Connect SDK. Use these to generate + * short-lived `at_` prefixed tokens that can be safely passed to frontend applications. Access + * tokens can be used in place of API keys on all v4 endpoints. + */ override fun accessToken(): AccessTokenServiceAsync = accessToken + /** + * Endpoints for managing access tokens for the Portfolio Connect SDK. Use these to generate + * short-lived `at_` prefixed tokens that can be safely passed to frontend applications. Access + * tokens can be used in place of API keys on all v4 endpoints. + */ override fun verifyToken(): VerifyTokenServiceAsync = verifyToken + /** Endpoints for parsing CAS PDF files from different sources. */ override fun camsKfintech(): CamsKfintechServiceAsync = camsKfintech + /** Endpoints for parsing CAS PDF files from different sources. */ override fun cdsl(): CdslServiceAsync = cdsl + /** + * Endpoints for parsing Contract Note PDF files from various SEBI brokers like Zerodha, Groww, + * Upstox, ICICI etc. + */ override fun contractNote(): ContractNoteServiceAsync = contractNote + /** + * Endpoints for importing CAS files directly from user email inboxes. + * + * **Supported Providers:** Gmail (more coming soon) + * + * **How it works:** + * 1. Call `POST /v4/inbox/connect` to get an OAuth URL + * 2. Redirect user to the OAuth URL for consent + * 3. User is redirected back to your `redirect_uri` with an encrypted `inbox_token` + * 4. Use the token to list/fetch CAS files from their inbox (`/v4/inbox/cas`) + * 5. Files are uploaded to temporary cloud storage (URLs expire in 24 hours) + * + * **Security:** + * - Read-only access (we cannot send emails) + * - Tokens are encrypted with server-side secret + * - User can revoke access anytime via `/v4/inbox/disconnect` + */ override fun inbox(): InboxServiceAsync = inbox + /** Endpoints for generating new CAS documents via email mailback (KFintech). */ override fun kfintech(): KfintechServiceAsync = kfintech + /** Endpoints for parsing CAS PDF files from different sources. */ override fun nsdl(): NsdlServiceAsync = nsdl + /** Endpoints for parsing CAS PDF files from different sources. */ override fun smart(): SmartServiceAsync = smart + /** + * Create dedicated inbound email addresses for investors to forward their CAS statements. + * + * **Use Case:** Your app wants to collect CAS statements from users without requiring OAuth or + * file upload. + * + * **How it works:** + * 1. Call `POST /v4/inbound-email` to create a unique inbound email address + * 2. Display this email to your user: "Forward your CAS statement to + * ie_xxx@import.casparser.in" + * 3. When user forwards a CAS email, we verify sender authenticity (SPF/DKIM) and call your + * webhook + * 4. Your webhook receives email metadata + attachment download URLs + * + * **Sender Validation:** + * - Only emails from verified CAS authorities are processed: + * - CDSL: `eCAS@cdslstatement.com` + * - NSDL: `NSDL-CAS@nsdl.co.in` + * - CAMS: `donotreply@camsonline.com` + * - KFintech: `samfS@kfintech.com` + * - Emails failing SPF/DKIM/DMARC are rejected + * - Forwarded emails must contain the original sender in headers + * + * **Billing:** 0.2 credits per successfully processed valid email + */ override fun inboundEmail(): InboundEmailServiceAsync = inboundEmail override fun close() = clientOptions.close() @@ -180,28 +249,97 @@ class CasParserClientAsyncImpl(private val clientOptions: ClientOptions) : CasPa clientOptions.toBuilder().apply(modifier::accept).build() ) + /** + * Endpoints for checking API quota and credits usage. These endpoints help you monitor your + * API usage and remaining quota. + */ override fun credits(): CreditServiceAsync.WithRawResponse = credits + /** + * Endpoints for checking API quota and credits usage. These endpoints help you monitor your + * API usage and remaining quota. + */ override fun logs(): LogServiceAsync.WithRawResponse = logs + /** + * Endpoints for managing access tokens for the Portfolio Connect SDK. Use these to generate + * short-lived `at_` prefixed tokens that can be safely passed to frontend applications. + * Access tokens can be used in place of API keys on all v4 endpoints. + */ override fun accessToken(): AccessTokenServiceAsync.WithRawResponse = accessToken + /** + * Endpoints for managing access tokens for the Portfolio Connect SDK. Use these to generate + * short-lived `at_` prefixed tokens that can be safely passed to frontend applications. + * Access tokens can be used in place of API keys on all v4 endpoints. + */ override fun verifyToken(): VerifyTokenServiceAsync.WithRawResponse = verifyToken + /** Endpoints for parsing CAS PDF files from different sources. */ override fun camsKfintech(): CamsKfintechServiceAsync.WithRawResponse = camsKfintech + /** Endpoints for parsing CAS PDF files from different sources. */ override fun cdsl(): CdslServiceAsync.WithRawResponse = cdsl + /** + * Endpoints for parsing Contract Note PDF files from various SEBI brokers like Zerodha, + * Groww, Upstox, ICICI etc. + */ override fun contractNote(): ContractNoteServiceAsync.WithRawResponse = contractNote + /** + * Endpoints for importing CAS files directly from user email inboxes. + * + * **Supported Providers:** Gmail (more coming soon) + * + * **How it works:** + * 1. Call `POST /v4/inbox/connect` to get an OAuth URL + * 2. Redirect user to the OAuth URL for consent + * 3. User is redirected back to your `redirect_uri` with an encrypted `inbox_token` + * 4. Use the token to list/fetch CAS files from their inbox (`/v4/inbox/cas`) + * 5. Files are uploaded to temporary cloud storage (URLs expire in 24 hours) + * + * **Security:** + * - Read-only access (we cannot send emails) + * - Tokens are encrypted with server-side secret + * - User can revoke access anytime via `/v4/inbox/disconnect` + */ override fun inbox(): InboxServiceAsync.WithRawResponse = inbox + /** Endpoints for generating new CAS documents via email mailback (KFintech). */ override fun kfintech(): KfintechServiceAsync.WithRawResponse = kfintech + /** Endpoints for parsing CAS PDF files from different sources. */ override fun nsdl(): NsdlServiceAsync.WithRawResponse = nsdl + /** Endpoints for parsing CAS PDF files from different sources. */ override fun smart(): SmartServiceAsync.WithRawResponse = smart + /** + * Create dedicated inbound email addresses for investors to forward their CAS statements. + * + * **Use Case:** Your app wants to collect CAS statements from users without requiring OAuth + * or file upload. + * + * **How it works:** + * 1. Call `POST /v4/inbound-email` to create a unique inbound email address + * 2. Display this email to your user: "Forward your CAS statement to + * ie_xxx@import.casparser.in" + * 3. When user forwards a CAS email, we verify sender authenticity (SPF/DKIM) and call your + * webhook + * 4. Your webhook receives email metadata + attachment download URLs + * + * **Sender Validation:** + * - Only emails from verified CAS authorities are processed: + * - CDSL: `eCAS@cdslstatement.com` + * - NSDL: `NSDL-CAS@nsdl.co.in` + * - CAMS: `donotreply@camsonline.com` + * - KFintech: `samfS@kfintech.com` + * - Emails failing SPF/DKIM/DMARC are rejected + * - Forwarded emails must contain the original sender in headers + * + * **Billing:** 0.2 credits per successfully processed valid email + */ override fun inboundEmail(): InboundEmailServiceAsync.WithRawResponse = inboundEmail } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientImpl.kt index db32253..75ee210 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/client/CasParserClientImpl.kt @@ -90,28 +90,97 @@ class CasParserClientImpl(private val clientOptions: ClientOptions) : CasParserC override fun withOptions(modifier: Consumer): CasParserClient = CasParserClientImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + /** + * Endpoints for checking API quota and credits usage. These endpoints help you monitor your API + * usage and remaining quota. + */ override fun credits(): CreditService = credits + /** + * Endpoints for checking API quota and credits usage. These endpoints help you monitor your API + * usage and remaining quota. + */ override fun logs(): LogService = logs + /** + * Endpoints for managing access tokens for the Portfolio Connect SDK. Use these to generate + * short-lived `at_` prefixed tokens that can be safely passed to frontend applications. Access + * tokens can be used in place of API keys on all v4 endpoints. + */ override fun accessToken(): AccessTokenService = accessToken + /** + * Endpoints for managing access tokens for the Portfolio Connect SDK. Use these to generate + * short-lived `at_` prefixed tokens that can be safely passed to frontend applications. Access + * tokens can be used in place of API keys on all v4 endpoints. + */ override fun verifyToken(): VerifyTokenService = verifyToken + /** Endpoints for parsing CAS PDF files from different sources. */ override fun camsKfintech(): CamsKfintechService = camsKfintech + /** Endpoints for parsing CAS PDF files from different sources. */ override fun cdsl(): CdslService = cdsl + /** + * Endpoints for parsing Contract Note PDF files from various SEBI brokers like Zerodha, Groww, + * Upstox, ICICI etc. + */ override fun contractNote(): ContractNoteService = contractNote + /** + * Endpoints for importing CAS files directly from user email inboxes. + * + * **Supported Providers:** Gmail (more coming soon) + * + * **How it works:** + * 1. Call `POST /v4/inbox/connect` to get an OAuth URL + * 2. Redirect user to the OAuth URL for consent + * 3. User is redirected back to your `redirect_uri` with an encrypted `inbox_token` + * 4. Use the token to list/fetch CAS files from their inbox (`/v4/inbox/cas`) + * 5. Files are uploaded to temporary cloud storage (URLs expire in 24 hours) + * + * **Security:** + * - Read-only access (we cannot send emails) + * - Tokens are encrypted with server-side secret + * - User can revoke access anytime via `/v4/inbox/disconnect` + */ override fun inbox(): InboxService = inbox + /** Endpoints for generating new CAS documents via email mailback (KFintech). */ override fun kfintech(): KfintechService = kfintech + /** Endpoints for parsing CAS PDF files from different sources. */ override fun nsdl(): NsdlService = nsdl + /** Endpoints for parsing CAS PDF files from different sources. */ override fun smart(): SmartService = smart + /** + * Create dedicated inbound email addresses for investors to forward their CAS statements. + * + * **Use Case:** Your app wants to collect CAS statements from users without requiring OAuth or + * file upload. + * + * **How it works:** + * 1. Call `POST /v4/inbound-email` to create a unique inbound email address + * 2. Display this email to your user: "Forward your CAS statement to + * ie_xxx@import.casparser.in" + * 3. When user forwards a CAS email, we verify sender authenticity (SPF/DKIM) and call your + * webhook + * 4. Your webhook receives email metadata + attachment download URLs + * + * **Sender Validation:** + * - Only emails from verified CAS authorities are processed: + * - CDSL: `eCAS@cdslstatement.com` + * - NSDL: `NSDL-CAS@nsdl.co.in` + * - CAMS: `donotreply@camsonline.com` + * - KFintech: `samfS@kfintech.com` + * - Emails failing SPF/DKIM/DMARC are rejected + * - Forwarded emails must contain the original sender in headers + * + * **Billing:** 0.2 credits per successfully processed valid email + */ override fun inboundEmail(): InboundEmailService = inboundEmail override fun close() = clientOptions.close() @@ -174,28 +243,97 @@ class CasParserClientImpl(private val clientOptions: ClientOptions) : CasParserC clientOptions.toBuilder().apply(modifier::accept).build() ) + /** + * Endpoints for checking API quota and credits usage. These endpoints help you monitor your + * API usage and remaining quota. + */ override fun credits(): CreditService.WithRawResponse = credits + /** + * Endpoints for checking API quota and credits usage. These endpoints help you monitor your + * API usage and remaining quota. + */ override fun logs(): LogService.WithRawResponse = logs + /** + * Endpoints for managing access tokens for the Portfolio Connect SDK. Use these to generate + * short-lived `at_` prefixed tokens that can be safely passed to frontend applications. + * Access tokens can be used in place of API keys on all v4 endpoints. + */ override fun accessToken(): AccessTokenService.WithRawResponse = accessToken + /** + * Endpoints for managing access tokens for the Portfolio Connect SDK. Use these to generate + * short-lived `at_` prefixed tokens that can be safely passed to frontend applications. + * Access tokens can be used in place of API keys on all v4 endpoints. + */ override fun verifyToken(): VerifyTokenService.WithRawResponse = verifyToken + /** Endpoints for parsing CAS PDF files from different sources. */ override fun camsKfintech(): CamsKfintechService.WithRawResponse = camsKfintech + /** Endpoints for parsing CAS PDF files from different sources. */ override fun cdsl(): CdslService.WithRawResponse = cdsl + /** + * Endpoints for parsing Contract Note PDF files from various SEBI brokers like Zerodha, + * Groww, Upstox, ICICI etc. + */ override fun contractNote(): ContractNoteService.WithRawResponse = contractNote + /** + * Endpoints for importing CAS files directly from user email inboxes. + * + * **Supported Providers:** Gmail (more coming soon) + * + * **How it works:** + * 1. Call `POST /v4/inbox/connect` to get an OAuth URL + * 2. Redirect user to the OAuth URL for consent + * 3. User is redirected back to your `redirect_uri` with an encrypted `inbox_token` + * 4. Use the token to list/fetch CAS files from their inbox (`/v4/inbox/cas`) + * 5. Files are uploaded to temporary cloud storage (URLs expire in 24 hours) + * + * **Security:** + * - Read-only access (we cannot send emails) + * - Tokens are encrypted with server-side secret + * - User can revoke access anytime via `/v4/inbox/disconnect` + */ override fun inbox(): InboxService.WithRawResponse = inbox + /** Endpoints for generating new CAS documents via email mailback (KFintech). */ override fun kfintech(): KfintechService.WithRawResponse = kfintech + /** Endpoints for parsing CAS PDF files from different sources. */ override fun nsdl(): NsdlService.WithRawResponse = nsdl + /** Endpoints for parsing CAS PDF files from different sources. */ override fun smart(): SmartService.WithRawResponse = smart + /** + * Create dedicated inbound email addresses for investors to forward their CAS statements. + * + * **Use Case:** Your app wants to collect CAS statements from users without requiring OAuth + * or file upload. + * + * **How it works:** + * 1. Call `POST /v4/inbound-email` to create a unique inbound email address + * 2. Display this email to your user: "Forward your CAS statement to + * ie_xxx@import.casparser.in" + * 3. When user forwards a CAS email, we verify sender authenticity (SPF/DKIM) and call your + * webhook + * 4. Your webhook receives email metadata + attachment download URLs + * + * **Sender Validation:** + * - Only emails from verified CAS authorities are processed: + * - CDSL: `eCAS@cdslstatement.com` + * - NSDL: `NSDL-CAS@nsdl.co.in` + * - CAMS: `donotreply@camsonline.com` + * - KFintech: `samfS@kfintech.com` + * - Emails failing SPF/DKIM/DMARC are rejected + * - Forwarded emails must contain the original sender in headers + * + * **Billing:** 0.2 credits per successfully processed valid email + */ override fun inboundEmail(): InboundEmailService.WithRawResponse = inboundEmail } } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsync.kt index acfdef1..6f0e9db 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsync.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsync.kt @@ -10,6 +10,11 @@ import com.cas_parser.api.models.accesstoken.AccessTokenCreateResponse import java.util.concurrent.CompletableFuture import java.util.function.Consumer +/** + * Endpoints for managing access tokens for the Portfolio Connect SDK. Use these to generate + * short-lived `at_` prefixed tokens that can be safely passed to frontend applications. Access + * tokens can be used in place of API keys on all v4 endpoints. + */ interface AccessTokenServiceAsync { /** diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsyncImpl.kt index ec51534..a36cbb7 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsyncImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/AccessTokenServiceAsyncImpl.kt @@ -20,6 +20,11 @@ import com.cas_parser.api.models.accesstoken.AccessTokenCreateResponse import java.util.concurrent.CompletableFuture import java.util.function.Consumer +/** + * Endpoints for managing access tokens for the Portfolio Connect SDK. Use these to generate + * short-lived `at_` prefixed tokens that can be safely passed to frontend applications. Access + * tokens can be used in place of API keys on all v4 endpoints. + */ class AccessTokenServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : AccessTokenServiceAsync { diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CamsKfintechServiceAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CamsKfintechServiceAsync.kt index c7651f1..e8d7cc2 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CamsKfintechServiceAsync.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CamsKfintechServiceAsync.kt @@ -10,6 +10,7 @@ import com.cas_parser.api.models.camskfintech.UnifiedResponse import java.util.concurrent.CompletableFuture import java.util.function.Consumer +/** Endpoints for parsing CAS PDF files from different sources. */ interface CamsKfintechServiceAsync { /** diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CamsKfintechServiceAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CamsKfintechServiceAsyncImpl.kt index ef05059..df53226 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CamsKfintechServiceAsyncImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CamsKfintechServiceAsyncImpl.kt @@ -20,6 +20,7 @@ import com.cas_parser.api.models.camskfintech.UnifiedResponse import java.util.concurrent.CompletableFuture import java.util.function.Consumer +/** Endpoints for parsing CAS PDF files from different sources. */ class CamsKfintechServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : CamsKfintechServiceAsync { diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CdslServiceAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CdslServiceAsync.kt index b00e28d..dd5e7d3 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CdslServiceAsync.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CdslServiceAsync.kt @@ -11,6 +11,7 @@ import com.cas_parser.api.services.async.cdsl.FetchServiceAsync import java.util.concurrent.CompletableFuture import java.util.function.Consumer +/** Endpoints for parsing CAS PDF files from different sources. */ interface CdslServiceAsync { /** @@ -25,6 +26,10 @@ interface CdslServiceAsync { */ fun withOptions(modifier: Consumer): CdslServiceAsync + /** + * Endpoints for fetching CAS documents with instant download. Currently supports CDSL via OTP + * authentication. + */ fun fetch(): FetchServiceAsync /** @@ -58,6 +63,10 @@ interface CdslServiceAsync { */ fun withOptions(modifier: Consumer): CdslServiceAsync.WithRawResponse + /** + * Endpoints for fetching CAS documents with instant download. Currently supports CDSL via + * OTP authentication. + */ fun fetch(): FetchServiceAsync.WithRawResponse /** diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CdslServiceAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CdslServiceAsyncImpl.kt index 2531112..0bb2f66 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CdslServiceAsyncImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CdslServiceAsyncImpl.kt @@ -22,6 +22,7 @@ import com.cas_parser.api.services.async.cdsl.FetchServiceAsyncImpl import java.util.concurrent.CompletableFuture import java.util.function.Consumer +/** Endpoints for parsing CAS PDF files from different sources. */ class CdslServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : CdslServiceAsync { @@ -36,6 +37,10 @@ class CdslServiceAsyncImpl internal constructor(private val clientOptions: Clien override fun withOptions(modifier: Consumer): CdslServiceAsync = CdslServiceAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + /** + * Endpoints for fetching CAS documents with instant download. Currently supports CDSL via OTP + * authentication. + */ override fun fetch(): FetchServiceAsync = fetch override fun parsePdf( @@ -62,6 +67,10 @@ class CdslServiceAsyncImpl internal constructor(private val clientOptions: Clien clientOptions.toBuilder().apply(modifier::accept).build() ) + /** + * Endpoints for fetching CAS documents with instant download. Currently supports CDSL via + * OTP authentication. + */ override fun fetch(): FetchServiceAsync.WithRawResponse = fetch private val parsePdfHandler: Handler = diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/ContractNoteServiceAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/ContractNoteServiceAsync.kt index 6168665..2fee7ca 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/ContractNoteServiceAsync.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/ContractNoteServiceAsync.kt @@ -10,6 +10,10 @@ import com.cas_parser.api.models.contractnote.ContractNoteParseResponse import java.util.concurrent.CompletableFuture import java.util.function.Consumer +/** + * Endpoints for parsing Contract Note PDF files from various SEBI brokers like Zerodha, Groww, + * Upstox, ICICI etc. + */ interface ContractNoteServiceAsync { /** diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/ContractNoteServiceAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/ContractNoteServiceAsyncImpl.kt index 7b8d062..b9c1014 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/ContractNoteServiceAsyncImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/ContractNoteServiceAsyncImpl.kt @@ -20,6 +20,10 @@ import com.cas_parser.api.models.contractnote.ContractNoteParseResponse import java.util.concurrent.CompletableFuture import java.util.function.Consumer +/** + * Endpoints for parsing Contract Note PDF files from various SEBI brokers like Zerodha, Groww, + * Upstox, ICICI etc. + */ class ContractNoteServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : ContractNoteServiceAsync { diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CreditServiceAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CreditServiceAsync.kt index dd5a54f..e737edd 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CreditServiceAsync.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CreditServiceAsync.kt @@ -10,6 +10,10 @@ import com.cas_parser.api.models.credits.CreditCheckResponse import java.util.concurrent.CompletableFuture import java.util.function.Consumer +/** + * Endpoints for checking API quota and credits usage. These endpoints help you monitor your API + * usage and remaining quota. + */ interface CreditServiceAsync { /** diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CreditServiceAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CreditServiceAsyncImpl.kt index 02b806c..e585dd5 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CreditServiceAsyncImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/CreditServiceAsyncImpl.kt @@ -20,6 +20,10 @@ import com.cas_parser.api.models.credits.CreditCheckResponse import java.util.concurrent.CompletableFuture import java.util.function.Consumer +/** + * Endpoints for checking API quota and credits usage. These endpoints help you monitor your API + * usage and remaining quota. + */ class CreditServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : CreditServiceAsync { diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/InboundEmailServiceAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/InboundEmailServiceAsync.kt index 8ff0edb..2c1b443 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/InboundEmailServiceAsync.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/InboundEmailServiceAsync.kt @@ -16,6 +16,29 @@ import com.cas_parser.api.models.inboundemail.InboundEmailRetrieveResponse import java.util.concurrent.CompletableFuture import java.util.function.Consumer +/** + * Create dedicated inbound email addresses for investors to forward their CAS statements. + * + * **Use Case:** Your app wants to collect CAS statements from users without requiring OAuth or file + * upload. + * + * **How it works:** + * 1. Call `POST /v4/inbound-email` to create a unique inbound email address + * 2. Display this email to your user: "Forward your CAS statement to ie_xxx@import.casparser.in" + * 3. When user forwards a CAS email, we verify sender authenticity (SPF/DKIM) and call your webhook + * 4. Your webhook receives email metadata + attachment download URLs + * + * **Sender Validation:** + * - Only emails from verified CAS authorities are processed: + * - CDSL: `eCAS@cdslstatement.com` + * - NSDL: `NSDL-CAS@nsdl.co.in` + * - CAMS: `donotreply@camsonline.com` + * - KFintech: `samfS@kfintech.com` + * - Emails failing SPF/DKIM/DMARC are rejected + * - Forwarded emails must contain the original sender in headers + * + * **Billing:** 0.2 credits per successfully processed valid email + */ interface InboundEmailServiceAsync { /** diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/InboundEmailServiceAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/InboundEmailServiceAsyncImpl.kt index a199b5f..9131ae8 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/InboundEmailServiceAsyncImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/InboundEmailServiceAsyncImpl.kt @@ -28,6 +28,29 @@ import java.util.concurrent.CompletableFuture import java.util.function.Consumer import kotlin.jvm.optionals.getOrNull +/** + * Create dedicated inbound email addresses for investors to forward their CAS statements. + * + * **Use Case:** Your app wants to collect CAS statements from users without requiring OAuth or file + * upload. + * + * **How it works:** + * 1. Call `POST /v4/inbound-email` to create a unique inbound email address + * 2. Display this email to your user: "Forward your CAS statement to ie_xxx@import.casparser.in" + * 3. When user forwards a CAS email, we verify sender authenticity (SPF/DKIM) and call your webhook + * 4. Your webhook receives email metadata + attachment download URLs + * + * **Sender Validation:** + * - Only emails from verified CAS authorities are processed: + * - CDSL: `eCAS@cdslstatement.com` + * - NSDL: `NSDL-CAS@nsdl.co.in` + * - CAMS: `donotreply@camsonline.com` + * - KFintech: `samfS@kfintech.com` + * - Emails failing SPF/DKIM/DMARC are rejected + * - Forwarded emails must contain the original sender in headers + * + * **Billing:** 0.2 credits per successfully processed valid email + */ class InboundEmailServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : InboundEmailServiceAsync { diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/InboxServiceAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/InboxServiceAsync.kt index b488405..d2a2a85 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/InboxServiceAsync.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/InboxServiceAsync.kt @@ -16,6 +16,23 @@ import com.cas_parser.api.models.inbox.InboxListCasFilesResponse import java.util.concurrent.CompletableFuture import java.util.function.Consumer +/** + * Endpoints for importing CAS files directly from user email inboxes. + * + * **Supported Providers:** Gmail (more coming soon) + * + * **How it works:** + * 1. Call `POST /v4/inbox/connect` to get an OAuth URL + * 2. Redirect user to the OAuth URL for consent + * 3. User is redirected back to your `redirect_uri` with an encrypted `inbox_token` + * 4. Use the token to list/fetch CAS files from their inbox (`/v4/inbox/cas`) + * 5. Files are uploaded to temporary cloud storage (URLs expire in 24 hours) + * + * **Security:** + * - Read-only access (we cannot send emails) + * - Tokens are encrypted with server-side secret + * - User can revoke access anytime via `/v4/inbox/disconnect` + */ interface InboxServiceAsync { /** diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/InboxServiceAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/InboxServiceAsyncImpl.kt index 29c7d03..f3f2599 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/InboxServiceAsyncImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/InboxServiceAsyncImpl.kt @@ -26,6 +26,23 @@ import com.cas_parser.api.models.inbox.InboxListCasFilesResponse import java.util.concurrent.CompletableFuture import java.util.function.Consumer +/** + * Endpoints for importing CAS files directly from user email inboxes. + * + * **Supported Providers:** Gmail (more coming soon) + * + * **How it works:** + * 1. Call `POST /v4/inbox/connect` to get an OAuth URL + * 2. Redirect user to the OAuth URL for consent + * 3. User is redirected back to your `redirect_uri` with an encrypted `inbox_token` + * 4. Use the token to list/fetch CAS files from their inbox (`/v4/inbox/cas`) + * 5. Files are uploaded to temporary cloud storage (URLs expire in 24 hours) + * + * **Security:** + * - Read-only access (we cannot send emails) + * - Tokens are encrypted with server-side secret + * - User can revoke access anytime via `/v4/inbox/disconnect` + */ class InboxServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : InboxServiceAsync { diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/KfintechServiceAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/KfintechServiceAsync.kt index fa22355..e2bfdc7 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/KfintechServiceAsync.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/KfintechServiceAsync.kt @@ -10,6 +10,7 @@ import com.cas_parser.api.models.kfintech.KfintechGenerateCasResponse import java.util.concurrent.CompletableFuture import java.util.function.Consumer +/** Endpoints for generating new CAS documents via email mailback (KFintech). */ interface KfintechServiceAsync { /** diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/KfintechServiceAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/KfintechServiceAsyncImpl.kt index 2445261..df04e64 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/KfintechServiceAsyncImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/KfintechServiceAsyncImpl.kt @@ -20,6 +20,7 @@ import com.cas_parser.api.models.kfintech.KfintechGenerateCasResponse import java.util.concurrent.CompletableFuture import java.util.function.Consumer +/** Endpoints for generating new CAS documents via email mailback (KFintech). */ class KfintechServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : KfintechServiceAsync { diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/LogServiceAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/LogServiceAsync.kt index 3f2546a..c74e947 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/LogServiceAsync.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/LogServiceAsync.kt @@ -12,6 +12,10 @@ import com.cas_parser.api.models.logs.LogGetSummaryResponse import java.util.concurrent.CompletableFuture import java.util.function.Consumer +/** + * Endpoints for checking API quota and credits usage. These endpoints help you monitor your API + * usage and remaining quota. + */ interface LogServiceAsync { /** diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/LogServiceAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/LogServiceAsyncImpl.kt index a4bf0f2..f2cc6a7 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/LogServiceAsyncImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/LogServiceAsyncImpl.kt @@ -22,6 +22,10 @@ import com.cas_parser.api.models.logs.LogGetSummaryResponse import java.util.concurrent.CompletableFuture import java.util.function.Consumer +/** + * Endpoints for checking API quota and credits usage. These endpoints help you monitor your API + * usage and remaining quota. + */ class LogServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : LogServiceAsync { diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/NsdlServiceAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/NsdlServiceAsync.kt index d9571cb..cb33723 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/NsdlServiceAsync.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/NsdlServiceAsync.kt @@ -10,6 +10,7 @@ import com.cas_parser.api.models.nsdl.NsdlParseParams import java.util.concurrent.CompletableFuture import java.util.function.Consumer +/** Endpoints for parsing CAS PDF files from different sources. */ interface NsdlServiceAsync { /** diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/NsdlServiceAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/NsdlServiceAsyncImpl.kt index 8fd0b0c..ee79b39 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/NsdlServiceAsyncImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/NsdlServiceAsyncImpl.kt @@ -20,6 +20,7 @@ import com.cas_parser.api.models.nsdl.NsdlParseParams import java.util.concurrent.CompletableFuture import java.util.function.Consumer +/** Endpoints for parsing CAS PDF files from different sources. */ class NsdlServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : NsdlServiceAsync { diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/SmartServiceAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/SmartServiceAsync.kt index 9fb8951..af7ed57 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/SmartServiceAsync.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/SmartServiceAsync.kt @@ -10,6 +10,7 @@ import com.cas_parser.api.models.smart.SmartParseCasPdfParams import java.util.concurrent.CompletableFuture import java.util.function.Consumer +/** Endpoints for parsing CAS PDF files from different sources. */ interface SmartServiceAsync { /** diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/SmartServiceAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/SmartServiceAsyncImpl.kt index 618e4fc..02f8c0a 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/SmartServiceAsyncImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/SmartServiceAsyncImpl.kt @@ -20,6 +20,7 @@ import com.cas_parser.api.models.smart.SmartParseCasPdfParams import java.util.concurrent.CompletableFuture import java.util.function.Consumer +/** Endpoints for parsing CAS PDF files from different sources. */ class SmartServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : SmartServiceAsync { diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsync.kt index 3d8b41e..fa58dfc 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsync.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsync.kt @@ -10,6 +10,11 @@ import com.cas_parser.api.models.verifytoken.VerifyTokenVerifyResponse import java.util.concurrent.CompletableFuture import java.util.function.Consumer +/** + * Endpoints for managing access tokens for the Portfolio Connect SDK. Use these to generate + * short-lived `at_` prefixed tokens that can be safely passed to frontend applications. Access + * tokens can be used in place of API keys on all v4 endpoints. + */ interface VerifyTokenServiceAsync { /** diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsyncImpl.kt index 9a42c63..cf826af 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsyncImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/VerifyTokenServiceAsyncImpl.kt @@ -20,6 +20,11 @@ import com.cas_parser.api.models.verifytoken.VerifyTokenVerifyResponse import java.util.concurrent.CompletableFuture import java.util.function.Consumer +/** + * Endpoints for managing access tokens for the Portfolio Connect SDK. Use these to generate + * short-lived `at_` prefixed tokens that can be safely passed to frontend applications. Access + * tokens can be used in place of API keys on all v4 endpoints. + */ class VerifyTokenServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : VerifyTokenServiceAsync { diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/cdsl/FetchServiceAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/cdsl/FetchServiceAsync.kt index 83b8d52..a60287d 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/cdsl/FetchServiceAsync.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/cdsl/FetchServiceAsync.kt @@ -12,6 +12,10 @@ import com.cas_parser.api.models.cdsl.fetch.FetchVerifyOtpResponse import java.util.concurrent.CompletableFuture import java.util.function.Consumer +/** + * Endpoints for fetching CAS documents with instant download. Currently supports CDSL via OTP + * authentication. + */ interface FetchServiceAsync { /** diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/cdsl/FetchServiceAsyncImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/cdsl/FetchServiceAsyncImpl.kt index fb97ea9..9e9453a 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/cdsl/FetchServiceAsyncImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/cdsl/FetchServiceAsyncImpl.kt @@ -24,6 +24,10 @@ import java.util.concurrent.CompletableFuture import java.util.function.Consumer import kotlin.jvm.optionals.getOrNull +/** + * Endpoints for fetching CAS documents with instant download. Currently supports CDSL via OTP + * authentication. + */ class FetchServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : FetchServiceAsync { diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/AccessTokenService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/AccessTokenService.kt index 784798e..cef38eb 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/AccessTokenService.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/AccessTokenService.kt @@ -10,6 +10,11 @@ import com.cas_parser.api.models.accesstoken.AccessTokenCreateResponse import com.google.errorprone.annotations.MustBeClosed import java.util.function.Consumer +/** + * Endpoints for managing access tokens for the Portfolio Connect SDK. Use these to generate + * short-lived `at_` prefixed tokens that can be safely passed to frontend applications. Access + * tokens can be used in place of API keys on all v4 endpoints. + */ interface AccessTokenService { /** diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/AccessTokenServiceImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/AccessTokenServiceImpl.kt index 9fe0782..cc2c4c0 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/AccessTokenServiceImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/AccessTokenServiceImpl.kt @@ -19,6 +19,11 @@ import com.cas_parser.api.models.accesstoken.AccessTokenCreateParams import com.cas_parser.api.models.accesstoken.AccessTokenCreateResponse import java.util.function.Consumer +/** + * Endpoints for managing access tokens for the Portfolio Connect SDK. Use these to generate + * short-lived `at_` prefixed tokens that can be safely passed to frontend applications. Access + * tokens can be used in place of API keys on all v4 endpoints. + */ class AccessTokenServiceImpl internal constructor(private val clientOptions: ClientOptions) : AccessTokenService { diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CamsKfintechService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CamsKfintechService.kt index 294210c..c8841a5 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CamsKfintechService.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CamsKfintechService.kt @@ -10,6 +10,7 @@ import com.cas_parser.api.models.camskfintech.UnifiedResponse import com.google.errorprone.annotations.MustBeClosed import java.util.function.Consumer +/** Endpoints for parsing CAS PDF files from different sources. */ interface CamsKfintechService { /** diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CamsKfintechServiceImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CamsKfintechServiceImpl.kt index 867c1c6..7796a20 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CamsKfintechServiceImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CamsKfintechServiceImpl.kt @@ -19,6 +19,7 @@ import com.cas_parser.api.models.camskfintech.CamsKfintechParseParams import com.cas_parser.api.models.camskfintech.UnifiedResponse import java.util.function.Consumer +/** Endpoints for parsing CAS PDF files from different sources. */ class CamsKfintechServiceImpl internal constructor(private val clientOptions: ClientOptions) : CamsKfintechService { diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CdslService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CdslService.kt index a8241be..7514c91 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CdslService.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CdslService.kt @@ -11,6 +11,7 @@ import com.cas_parser.api.services.blocking.cdsl.FetchService import com.google.errorprone.annotations.MustBeClosed import java.util.function.Consumer +/** Endpoints for parsing CAS PDF files from different sources. */ interface CdslService { /** @@ -25,6 +26,10 @@ interface CdslService { */ fun withOptions(modifier: Consumer): CdslService + /** + * Endpoints for fetching CAS documents with instant download. Currently supports CDSL via OTP + * authentication. + */ fun fetch(): FetchService /** @@ -57,6 +62,10 @@ interface CdslService { */ fun withOptions(modifier: Consumer): CdslService.WithRawResponse + /** + * Endpoints for fetching CAS documents with instant download. Currently supports CDSL via + * OTP authentication. + */ fun fetch(): FetchService.WithRawResponse /** diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CdslServiceImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CdslServiceImpl.kt index 0155aa6..7bbc6a3 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CdslServiceImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CdslServiceImpl.kt @@ -21,6 +21,7 @@ import com.cas_parser.api.services.blocking.cdsl.FetchService import com.cas_parser.api.services.blocking.cdsl.FetchServiceImpl import java.util.function.Consumer +/** Endpoints for parsing CAS PDF files from different sources. */ class CdslServiceImpl internal constructor(private val clientOptions: ClientOptions) : CdslService { private val withRawResponse: CdslService.WithRawResponse by lazy { @@ -34,6 +35,10 @@ class CdslServiceImpl internal constructor(private val clientOptions: ClientOpti override fun withOptions(modifier: Consumer): CdslService = CdslServiceImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + /** + * Endpoints for fetching CAS documents with instant download. Currently supports CDSL via OTP + * authentication. + */ override fun fetch(): FetchService = fetch override fun parsePdf( @@ -60,6 +65,10 @@ class CdslServiceImpl internal constructor(private val clientOptions: ClientOpti clientOptions.toBuilder().apply(modifier::accept).build() ) + /** + * Endpoints for fetching CAS documents with instant download. Currently supports CDSL via + * OTP authentication. + */ override fun fetch(): FetchService.WithRawResponse = fetch private val parsePdfHandler: Handler = diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/ContractNoteService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/ContractNoteService.kt index d7a1b64..bb49da3 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/ContractNoteService.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/ContractNoteService.kt @@ -10,6 +10,10 @@ import com.cas_parser.api.models.contractnote.ContractNoteParseResponse import com.google.errorprone.annotations.MustBeClosed import java.util.function.Consumer +/** + * Endpoints for parsing Contract Note PDF files from various SEBI brokers like Zerodha, Groww, + * Upstox, ICICI etc. + */ interface ContractNoteService { /** diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/ContractNoteServiceImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/ContractNoteServiceImpl.kt index 978c42b..7d5555f 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/ContractNoteServiceImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/ContractNoteServiceImpl.kt @@ -19,6 +19,10 @@ import com.cas_parser.api.models.contractnote.ContractNoteParseParams import com.cas_parser.api.models.contractnote.ContractNoteParseResponse import java.util.function.Consumer +/** + * Endpoints for parsing Contract Note PDF files from various SEBI brokers like Zerodha, Groww, + * Upstox, ICICI etc. + */ class ContractNoteServiceImpl internal constructor(private val clientOptions: ClientOptions) : ContractNoteService { diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CreditService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CreditService.kt index 0c7a9da..d4459c9 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CreditService.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CreditService.kt @@ -10,6 +10,10 @@ import com.cas_parser.api.models.credits.CreditCheckResponse import com.google.errorprone.annotations.MustBeClosed import java.util.function.Consumer +/** + * Endpoints for checking API quota and credits usage. These endpoints help you monitor your API + * usage and remaining quota. + */ interface CreditService { /** diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CreditServiceImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CreditServiceImpl.kt index c611592..6425e16 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CreditServiceImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/CreditServiceImpl.kt @@ -19,6 +19,10 @@ import com.cas_parser.api.models.credits.CreditCheckParams import com.cas_parser.api.models.credits.CreditCheckResponse import java.util.function.Consumer +/** + * Endpoints for checking API quota and credits usage. These endpoints help you monitor your API + * usage and remaining quota. + */ class CreditServiceImpl internal constructor(private val clientOptions: ClientOptions) : CreditService { diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/InboundEmailService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/InboundEmailService.kt index c46275e..be0ff40 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/InboundEmailService.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/InboundEmailService.kt @@ -16,6 +16,29 @@ import com.cas_parser.api.models.inboundemail.InboundEmailRetrieveResponse import com.google.errorprone.annotations.MustBeClosed import java.util.function.Consumer +/** + * Create dedicated inbound email addresses for investors to forward their CAS statements. + * + * **Use Case:** Your app wants to collect CAS statements from users without requiring OAuth or file + * upload. + * + * **How it works:** + * 1. Call `POST /v4/inbound-email` to create a unique inbound email address + * 2. Display this email to your user: "Forward your CAS statement to ie_xxx@import.casparser.in" + * 3. When user forwards a CAS email, we verify sender authenticity (SPF/DKIM) and call your webhook + * 4. Your webhook receives email metadata + attachment download URLs + * + * **Sender Validation:** + * - Only emails from verified CAS authorities are processed: + * - CDSL: `eCAS@cdslstatement.com` + * - NSDL: `NSDL-CAS@nsdl.co.in` + * - CAMS: `donotreply@camsonline.com` + * - KFintech: `samfS@kfintech.com` + * - Emails failing SPF/DKIM/DMARC are rejected + * - Forwarded emails must contain the original sender in headers + * + * **Billing:** 0.2 credits per successfully processed valid email + */ interface InboundEmailService { /** diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/InboundEmailServiceImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/InboundEmailServiceImpl.kt index b0aefb3..704f560 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/InboundEmailServiceImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/InboundEmailServiceImpl.kt @@ -27,6 +27,29 @@ import com.cas_parser.api.models.inboundemail.InboundEmailRetrieveResponse import java.util.function.Consumer import kotlin.jvm.optionals.getOrNull +/** + * Create dedicated inbound email addresses for investors to forward their CAS statements. + * + * **Use Case:** Your app wants to collect CAS statements from users without requiring OAuth or file + * upload. + * + * **How it works:** + * 1. Call `POST /v4/inbound-email` to create a unique inbound email address + * 2. Display this email to your user: "Forward your CAS statement to ie_xxx@import.casparser.in" + * 3. When user forwards a CAS email, we verify sender authenticity (SPF/DKIM) and call your webhook + * 4. Your webhook receives email metadata + attachment download URLs + * + * **Sender Validation:** + * - Only emails from verified CAS authorities are processed: + * - CDSL: `eCAS@cdslstatement.com` + * - NSDL: `NSDL-CAS@nsdl.co.in` + * - CAMS: `donotreply@camsonline.com` + * - KFintech: `samfS@kfintech.com` + * - Emails failing SPF/DKIM/DMARC are rejected + * - Forwarded emails must contain the original sender in headers + * + * **Billing:** 0.2 credits per successfully processed valid email + */ class InboundEmailServiceImpl internal constructor(private val clientOptions: ClientOptions) : InboundEmailService { diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/InboxService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/InboxService.kt index e2b5ce0..051365a 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/InboxService.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/InboxService.kt @@ -16,6 +16,23 @@ import com.cas_parser.api.models.inbox.InboxListCasFilesResponse import com.google.errorprone.annotations.MustBeClosed import java.util.function.Consumer +/** + * Endpoints for importing CAS files directly from user email inboxes. + * + * **Supported Providers:** Gmail (more coming soon) + * + * **How it works:** + * 1. Call `POST /v4/inbox/connect` to get an OAuth URL + * 2. Redirect user to the OAuth URL for consent + * 3. User is redirected back to your `redirect_uri` with an encrypted `inbox_token` + * 4. Use the token to list/fetch CAS files from their inbox (`/v4/inbox/cas`) + * 5. Files are uploaded to temporary cloud storage (URLs expire in 24 hours) + * + * **Security:** + * - Read-only access (we cannot send emails) + * - Tokens are encrypted with server-side secret + * - User can revoke access anytime via `/v4/inbox/disconnect` + */ interface InboxService { /** diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/InboxServiceImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/InboxServiceImpl.kt index 27ebb03..4abb1e6 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/InboxServiceImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/InboxServiceImpl.kt @@ -25,6 +25,23 @@ import com.cas_parser.api.models.inbox.InboxListCasFilesParams import com.cas_parser.api.models.inbox.InboxListCasFilesResponse import java.util.function.Consumer +/** + * Endpoints for importing CAS files directly from user email inboxes. + * + * **Supported Providers:** Gmail (more coming soon) + * + * **How it works:** + * 1. Call `POST /v4/inbox/connect` to get an OAuth URL + * 2. Redirect user to the OAuth URL for consent + * 3. User is redirected back to your `redirect_uri` with an encrypted `inbox_token` + * 4. Use the token to list/fetch CAS files from their inbox (`/v4/inbox/cas`) + * 5. Files are uploaded to temporary cloud storage (URLs expire in 24 hours) + * + * **Security:** + * - Read-only access (we cannot send emails) + * - Tokens are encrypted with server-side secret + * - User can revoke access anytime via `/v4/inbox/disconnect` + */ class InboxServiceImpl internal constructor(private val clientOptions: ClientOptions) : InboxService { diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/KfintechService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/KfintechService.kt index 0bc26c9..b4ac124 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/KfintechService.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/KfintechService.kt @@ -10,6 +10,7 @@ import com.cas_parser.api.models.kfintech.KfintechGenerateCasResponse import com.google.errorprone.annotations.MustBeClosed import java.util.function.Consumer +/** Endpoints for generating new CAS documents via email mailback (KFintech). */ interface KfintechService { /** diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/KfintechServiceImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/KfintechServiceImpl.kt index 679e4d8..aeccbb9 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/KfintechServiceImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/KfintechServiceImpl.kt @@ -19,6 +19,7 @@ import com.cas_parser.api.models.kfintech.KfintechGenerateCasParams import com.cas_parser.api.models.kfintech.KfintechGenerateCasResponse import java.util.function.Consumer +/** Endpoints for generating new CAS documents via email mailback (KFintech). */ class KfintechServiceImpl internal constructor(private val clientOptions: ClientOptions) : KfintechService { diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/LogService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/LogService.kt index 7361743..6c7468b 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/LogService.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/LogService.kt @@ -12,6 +12,10 @@ import com.cas_parser.api.models.logs.LogGetSummaryResponse import com.google.errorprone.annotations.MustBeClosed import java.util.function.Consumer +/** + * Endpoints for checking API quota and credits usage. These endpoints help you monitor your API + * usage and remaining quota. + */ interface LogService { /** diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/LogServiceImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/LogServiceImpl.kt index 4dce634..d481476 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/LogServiceImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/LogServiceImpl.kt @@ -21,6 +21,10 @@ import com.cas_parser.api.models.logs.LogGetSummaryParams import com.cas_parser.api.models.logs.LogGetSummaryResponse import java.util.function.Consumer +/** + * Endpoints for checking API quota and credits usage. These endpoints help you monitor your API + * usage and remaining quota. + */ class LogServiceImpl internal constructor(private val clientOptions: ClientOptions) : LogService { private val withRawResponse: LogService.WithRawResponse by lazy { diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/NsdlService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/NsdlService.kt index 8ca3b7c..786d115 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/NsdlService.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/NsdlService.kt @@ -10,6 +10,7 @@ import com.cas_parser.api.models.nsdl.NsdlParseParams import com.google.errorprone.annotations.MustBeClosed import java.util.function.Consumer +/** Endpoints for parsing CAS PDF files from different sources. */ interface NsdlService { /** diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/NsdlServiceImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/NsdlServiceImpl.kt index a887773..582c6df 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/NsdlServiceImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/NsdlServiceImpl.kt @@ -19,6 +19,7 @@ import com.cas_parser.api.models.camskfintech.UnifiedResponse import com.cas_parser.api.models.nsdl.NsdlParseParams import java.util.function.Consumer +/** Endpoints for parsing CAS PDF files from different sources. */ class NsdlServiceImpl internal constructor(private val clientOptions: ClientOptions) : NsdlService { private val withRawResponse: NsdlService.WithRawResponse by lazy { diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/SmartService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/SmartService.kt index fce30ed..79198c1 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/SmartService.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/SmartService.kt @@ -10,6 +10,7 @@ import com.cas_parser.api.models.smart.SmartParseCasPdfParams import com.google.errorprone.annotations.MustBeClosed import java.util.function.Consumer +/** Endpoints for parsing CAS PDF files from different sources. */ interface SmartService { /** diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/SmartServiceImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/SmartServiceImpl.kt index 6808cd7..2c8c2d8 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/SmartServiceImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/SmartServiceImpl.kt @@ -19,6 +19,7 @@ import com.cas_parser.api.models.camskfintech.UnifiedResponse import com.cas_parser.api.models.smart.SmartParseCasPdfParams import java.util.function.Consumer +/** Endpoints for parsing CAS PDF files from different sources. */ class SmartServiceImpl internal constructor(private val clientOptions: ClientOptions) : SmartService { diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/VerifyTokenService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/VerifyTokenService.kt index e8135cd..468e98d 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/VerifyTokenService.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/VerifyTokenService.kt @@ -10,6 +10,11 @@ import com.cas_parser.api.models.verifytoken.VerifyTokenVerifyResponse import com.google.errorprone.annotations.MustBeClosed import java.util.function.Consumer +/** + * Endpoints for managing access tokens for the Portfolio Connect SDK. Use these to generate + * short-lived `at_` prefixed tokens that can be safely passed to frontend applications. Access + * tokens can be used in place of API keys on all v4 endpoints. + */ interface VerifyTokenService { /** diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/VerifyTokenServiceImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/VerifyTokenServiceImpl.kt index bf3fce7..e76ff7d 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/VerifyTokenServiceImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/VerifyTokenServiceImpl.kt @@ -19,6 +19,11 @@ import com.cas_parser.api.models.verifytoken.VerifyTokenVerifyParams import com.cas_parser.api.models.verifytoken.VerifyTokenVerifyResponse import java.util.function.Consumer +/** + * Endpoints for managing access tokens for the Portfolio Connect SDK. Use these to generate + * short-lived `at_` prefixed tokens that can be safely passed to frontend applications. Access + * tokens can be used in place of API keys on all v4 endpoints. + */ class VerifyTokenServiceImpl internal constructor(private val clientOptions: ClientOptions) : VerifyTokenService { diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/cdsl/FetchService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/cdsl/FetchService.kt index 81f2bc3..b8f7006 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/cdsl/FetchService.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/cdsl/FetchService.kt @@ -12,6 +12,10 @@ import com.cas_parser.api.models.cdsl.fetch.FetchVerifyOtpResponse import com.google.errorprone.annotations.MustBeClosed import java.util.function.Consumer +/** + * Endpoints for fetching CAS documents with instant download. Currently supports CDSL via OTP + * authentication. + */ interface FetchService { /** diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/cdsl/FetchServiceImpl.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/cdsl/FetchServiceImpl.kt index e9a3246..9c8db9f 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/cdsl/FetchServiceImpl.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/cdsl/FetchServiceImpl.kt @@ -23,6 +23,10 @@ import com.cas_parser.api.models.cdsl.fetch.FetchVerifyOtpResponse import java.util.function.Consumer import kotlin.jvm.optionals.getOrNull +/** + * Endpoints for fetching CAS documents with instant download. Currently supports CDSL via OTP + * authentication. + */ class FetchServiceImpl internal constructor(private val clientOptions: ClientOptions) : FetchService { From bc0192c1f217e7b812bb5d753f8793ca7226b444 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 3 Mar 2026 18:23:08 +0000 Subject: [PATCH 67/99] chore(internal): version bump --- .release-please-manifest.json | 2 +- README.md | 10 +++++----- build.gradle.kts | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 2aca35a..d04f223 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.5.0" + ".": "0.5.1" } \ No newline at end of file diff --git a/README.md b/README.md index bcad7a7..1e5410a 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ -[![Maven Central](https://img.shields.io/maven-central/v/com.cas_parser.api/cas-parser-java)](https://central.sonatype.com/artifact/com.cas_parser.api/cas-parser-java/0.5.0) -[![javadoc](https://javadoc.io/badge2/com.cas_parser.api/cas-parser-java/0.5.0/javadoc.svg)](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.5.0) +[![Maven Central](https://img.shields.io/maven-central/v/com.cas_parser.api/cas-parser-java)](https://central.sonatype.com/artifact/com.cas_parser.api/cas-parser-java/0.5.1) +[![javadoc](https://javadoc.io/badge2/com.cas_parser.api/cas-parser-java/0.5.1/javadoc.svg)](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.5.1) @@ -22,7 +22,7 @@ Use the Cas Parser MCP Server to enable AI assistants to interact with this API, -The REST API documentation can be found on [casparser.in](https://casparser.in/docs). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.5.0). +The REST API documentation can be found on [casparser.in](https://casparser.in/docs). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.5.1). @@ -33,7 +33,7 @@ The REST API documentation can be found on [casparser.in](https://casparser.in/d ### Gradle ```kotlin -implementation("com.cas_parser.api:cas-parser-java:0.5.0") +implementation("com.cas_parser.api:cas-parser-java:0.5.1") ``` ### Maven @@ -42,7 +42,7 @@ implementation("com.cas_parser.api:cas-parser-java:0.5.0") com.cas_parser.api cas-parser-java - 0.5.0 + 0.5.1 ``` diff --git a/build.gradle.kts b/build.gradle.kts index 4aa1227..cc1e16d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -9,7 +9,7 @@ repositories { allprojects { group = "com.cas_parser.api" - version = "0.5.0" // x-release-please-version + version = "0.5.1" // x-release-please-version } subprojects { From ab50cf60edaa5a1347ff0d19cd77c39e6db711e8 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 6 Mar 2026 08:00:48 +0000 Subject: [PATCH 68/99] chore(internal): codegen related update --- .../com/cas_parser/api/core/http/RetryingHttpClient.kt | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/RetryingHttpClient.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/RetryingHttpClient.kt index 7b39c62..795ceb0 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/RetryingHttpClient.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/RetryingHttpClient.kt @@ -214,13 +214,8 @@ private constructor( } } ?.let { retryAfterNanos -> - // If the API asks us to wait a certain amount of time (and it's a reasonable - // amount), just - // do what it says. - val retryAfter = Duration.ofNanos(retryAfterNanos.toLong()) - if (retryAfter in Duration.ofNanos(0)..Duration.ofMinutes(1)) { - return retryAfter - } + // If the API asks us to wait a certain amount of time, do what it says. + return Duration.ofNanos(retryAfterNanos.toLong()) } // Apply exponential backoff, but not more than the max. From 2fe3b424c7eb2d334a842b37e9d3cccff3d0cc56 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 6 Mar 2026 08:04:13 +0000 Subject: [PATCH 69/99] chore(internal): bump palantir-java-format --- buildSrc/src/main/kotlin/cas-parser.java.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/cas-parser.java.gradle.kts b/buildSrc/src/main/kotlin/cas-parser.java.gradle.kts index 81d5d32..a3cfe28 100644 --- a/buildSrc/src/main/kotlin/cas-parser.java.gradle.kts +++ b/buildSrc/src/main/kotlin/cas-parser.java.gradle.kts @@ -54,7 +54,7 @@ tasks.withType().configureEach { val palantir by configurations.creating dependencies { - palantir("com.palantir.javaformat:palantir-java-format:2.73.0") + palantir("com.palantir.javaformat:palantir-java-format:2.89.0") } fun registerPalantir( From 04222245bea873414d41beecba83bc5e7c307d22 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 7 Mar 2026 17:22:05 +0000 Subject: [PATCH 70/99] chore(ci): skip uploading artifacts on stainless-internal branches --- .github/workflows/ci.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2d1e49c..85ec8c4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -65,14 +65,18 @@ jobs: run: ./scripts/build - name: Get GitHub OIDC Token - if: github.repository == 'stainless-sdks/cas-parser-java' + if: |- + github.repository == 'stainless-sdks/cas-parser-java' && + !startsWith(github.ref, 'refs/heads/stl/') id: github-oidc uses: actions/github-script@v8 with: script: core.setOutput('github_token', await core.getIDToken()); - name: Build and upload Maven artifacts - if: github.repository == 'stainless-sdks/cas-parser-java' + if: |- + github.repository == 'stainless-sdks/cas-parser-java' && + !startsWith(github.ref, 'refs/heads/stl/') env: URL: https://pkg.stainless.com/s AUTH: ${{ steps.github-oidc.outputs.github_token }} From 8223641b0285a64b12fc1f88dcf8b4f752b1d6a7 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2026 09:54:40 +0000 Subject: [PATCH 71/99] chore(internal): version bump --- .release-please-manifest.json | 2 +- README.md | 10 +++++----- build.gradle.kts | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index d04f223..383dd5a 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.5.1" + ".": "0.5.2" } \ No newline at end of file diff --git a/README.md b/README.md index 1e5410a..ef44eb1 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ -[![Maven Central](https://img.shields.io/maven-central/v/com.cas_parser.api/cas-parser-java)](https://central.sonatype.com/artifact/com.cas_parser.api/cas-parser-java/0.5.1) -[![javadoc](https://javadoc.io/badge2/com.cas_parser.api/cas-parser-java/0.5.1/javadoc.svg)](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.5.1) +[![Maven Central](https://img.shields.io/maven-central/v/com.cas_parser.api/cas-parser-java)](https://central.sonatype.com/artifact/com.cas_parser.api/cas-parser-java/0.5.2) +[![javadoc](https://javadoc.io/badge2/com.cas_parser.api/cas-parser-java/0.5.2/javadoc.svg)](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.5.2) @@ -22,7 +22,7 @@ Use the Cas Parser MCP Server to enable AI assistants to interact with this API, -The REST API documentation can be found on [casparser.in](https://casparser.in/docs). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.5.1). +The REST API documentation can be found on [casparser.in](https://casparser.in/docs). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.5.2). @@ -33,7 +33,7 @@ The REST API documentation can be found on [casparser.in](https://casparser.in/d ### Gradle ```kotlin -implementation("com.cas_parser.api:cas-parser-java:0.5.1") +implementation("com.cas_parser.api:cas-parser-java:0.5.2") ``` ### Maven @@ -42,7 +42,7 @@ implementation("com.cas_parser.api:cas-parser-java:0.5.1") com.cas_parser.api cas-parser-java - 0.5.1 + 0.5.2 ``` diff --git a/build.gradle.kts b/build.gradle.kts index cc1e16d..ef89225 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -9,7 +9,7 @@ repositories { allprojects { group = "com.cas_parser.api" - version = "0.5.1" // x-release-please-version + version = "0.5.2" // x-release-please-version } subprojects { From ece2ff60a23f52e41af819519ef6563d31f28d61 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 11 Mar 2026 08:12:45 +0000 Subject: [PATCH 72/99] fix(client): incorrect `Retry-After` parsing --- .../api/core/http/RetryingHttpClient.kt | 2 +- .../api/core/http/RetryingHttpClientTest.kt | 224 +++++++++++++++--- 2 files changed, 192 insertions(+), 34 deletions(-) diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/RetryingHttpClient.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/RetryingHttpClient.kt index 795ceb0..5487fce 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/RetryingHttpClient.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/RetryingHttpClient.kt @@ -201,7 +201,7 @@ private constructor( ?: headers.values("Retry-After").getOrNull(0)?.let { retryAfter -> retryAfter.toFloatOrNull()?.times(TimeUnit.SECONDS.toNanos(1)) ?: try { - ChronoUnit.MILLIS.between( + ChronoUnit.NANOS.between( OffsetDateTime.now(clock), OffsetDateTime.parse( retryAfter, diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/RetryingHttpClientTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/RetryingHttpClientTest.kt index c3f47cd..39c7156 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/RetryingHttpClientTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/RetryingHttpClientTest.kt @@ -20,7 +20,11 @@ import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo import com.github.tomakehurst.wiremock.junit5.WireMockTest import com.github.tomakehurst.wiremock.stubbing.Scenario import java.io.InputStream +import java.time.Clock import java.time.Duration +import java.time.OffsetDateTime +import java.time.ZoneOffset +import java.time.format.DateTimeFormatter import java.util.concurrent.CompletableFuture import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.BeforeEach @@ -36,6 +40,21 @@ internal class RetryingHttpClientTest { private lateinit var baseUrl: String private lateinit var httpClient: HttpClient + private class RecordingSleeper : Sleeper { + val durations = mutableListOf() + + override fun sleep(duration: Duration) { + durations.add(duration) + } + + override fun sleepAsync(duration: Duration): CompletableFuture { + durations.add(duration) + return CompletableFuture.completedFuture(null) + } + + override fun close() {} + } + @BeforeEach fun beforeEach(wmRuntimeInfo: WireMockRuntimeInfo) { baseUrl = wmRuntimeInfo.httpBaseUrl @@ -86,7 +105,8 @@ internal class RetryingHttpClientTest { @ValueSource(booleans = [false, true]) fun execute(async: Boolean) { stubFor(post(urlPathEqualTo("/something")).willReturn(ok())) - val retryingClient = retryingHttpClientBuilder().build() + val sleeper = RecordingSleeper() + val retryingClient = retryingHttpClientBuilder(sleeper).build() val response = retryingClient.execute( @@ -100,6 +120,7 @@ internal class RetryingHttpClientTest { assertThat(response.statusCode()).isEqualTo(200) verify(1, postRequestedFor(urlPathEqualTo("/something"))) + assertThat(sleeper.durations).isEmpty() assertNoResponseLeaks() } @@ -111,8 +132,12 @@ internal class RetryingHttpClientTest { .withHeader("X-Some-Header", matching("stainless-java-retry-.+")) .willReturn(ok()) ) + val sleeper = RecordingSleeper() val retryingClient = - retryingHttpClientBuilder().maxRetries(2).idempotencyHeader("X-Some-Header").build() + retryingHttpClientBuilder(sleeper) + .maxRetries(2) + .idempotencyHeader("X-Some-Header") + .build() val response = retryingClient.execute( @@ -126,20 +151,20 @@ internal class RetryingHttpClientTest { assertThat(response.statusCode()).isEqualTo(200) verify(1, postRequestedFor(urlPathEqualTo("/something"))) + assertThat(sleeper.durations).isEmpty() assertNoResponseLeaks() } @ParameterizedTest @ValueSource(booleans = [false, true]) fun execute_withRetryAfterHeader(async: Boolean) { + val retryAfterDate = "Wed, 21 Oct 2015 07:28:00 GMT" stubFor( post(urlPathEqualTo("/something")) // First we fail with a retry after header given as a date .inScenario("foo") .whenScenarioStateIs(Scenario.STARTED) - .willReturn( - serviceUnavailable().withHeader("Retry-After", "Wed, 21 Oct 2015 07:28:00 GMT") - ) + .willReturn(serviceUnavailable().withHeader("Retry-After", retryAfterDate)) .willSetStateTo("RETRY_AFTER_DATE") ) stubFor( @@ -158,7 +183,13 @@ internal class RetryingHttpClientTest { .willReturn(ok()) .willSetStateTo("COMPLETED") ) - val retryingClient = retryingHttpClientBuilder().maxRetries(2).build() + // Fix the clock to 5 seconds before the Retry-After date so the date-based backoff is + // deterministic. + val retryAfterDateTime = + OffsetDateTime.parse(retryAfterDate, DateTimeFormatter.RFC_1123_DATE_TIME) + val clock = Clock.fixed(retryAfterDateTime.minusSeconds(5).toInstant(), ZoneOffset.UTC) + val sleeper = RecordingSleeper() + val retryingClient = retryingHttpClientBuilder(sleeper, clock).maxRetries(2).build() val response = retryingClient.execute( @@ -186,19 +217,20 @@ internal class RetryingHttpClientTest { postRequestedFor(urlPathEqualTo("/something")) .withHeader("x-stainless-retry-count", equalTo("2")), ) + assertThat(sleeper.durations) + .containsExactly(Duration.ofSeconds(5), Duration.ofMillis(1234)) assertNoResponseLeaks() } @ParameterizedTest @ValueSource(booleans = [false, true]) fun execute_withOverwrittenRetryCountHeader(async: Boolean) { + val retryAfterDate = "Wed, 21 Oct 2015 07:28:00 GMT" stubFor( post(urlPathEqualTo("/something")) .inScenario("foo") // first we fail with a retry after header given as a date .whenScenarioStateIs(Scenario.STARTED) - .willReturn( - serviceUnavailable().withHeader("Retry-After", "Wed, 21 Oct 2015 07:28:00 GMT") - ) + .willReturn(serviceUnavailable().withHeader("Retry-After", retryAfterDate)) .willSetStateTo("RETRY_AFTER_DATE") ) stubFor( @@ -208,7 +240,11 @@ internal class RetryingHttpClientTest { .willReturn(ok()) .willSetStateTo("COMPLETED") ) - val retryingClient = retryingHttpClientBuilder().maxRetries(2).build() + val retryAfterDateTime = + OffsetDateTime.parse(retryAfterDate, DateTimeFormatter.RFC_1123_DATE_TIME) + val clock = Clock.fixed(retryAfterDateTime.minusSeconds(5).toInstant(), ZoneOffset.UTC) + val sleeper = RecordingSleeper() + val retryingClient = retryingHttpClientBuilder(sleeper, clock).maxRetries(2).build() val response = retryingClient.execute( @@ -227,6 +263,7 @@ internal class RetryingHttpClientTest { postRequestedFor(urlPathEqualTo("/something")) .withHeader("x-stainless-retry-count", equalTo("42")), ) + assertThat(sleeper.durations).containsExactly(Duration.ofSeconds(5)) assertNoResponseLeaks() } @@ -247,7 +284,8 @@ internal class RetryingHttpClientTest { .willReturn(ok()) .willSetStateTo("COMPLETED") ) - val retryingClient = retryingHttpClientBuilder().maxRetries(1).build() + val sleeper = RecordingSleeper() + val retryingClient = retryingHttpClientBuilder(sleeper).maxRetries(1).build() val response = retryingClient.execute( @@ -261,6 +299,7 @@ internal class RetryingHttpClientTest { assertThat(response.statusCode()).isEqualTo(200) verify(2, postRequestedFor(urlPathEqualTo("/something"))) + assertThat(sleeper.durations).containsExactly(Duration.ofMillis(10)) assertNoResponseLeaks() } @@ -301,21 +340,12 @@ internal class RetryingHttpClientTest { override fun close() = httpClient.close() } + val sleeper = RecordingSleeper() val retryingClient = RetryingHttpClient.builder() .httpClient(failingHttpClient) .maxRetries(2) - .sleeper( - object : Sleeper { - - override fun sleep(duration: Duration) {} - - override fun sleepAsync(duration: Duration): CompletableFuture = - CompletableFuture.completedFuture(null) - - override fun close() {} - } - ) + .sleeper(sleeper) .build() val response = @@ -339,25 +369,153 @@ internal class RetryingHttpClientTest { postRequestedFor(urlPathEqualTo("/something")) .withHeader("x-stainless-retry-count", equalTo("0")), ) + // Exponential backoff with jitter: 0.5s * jitter where jitter is in [0.75, 1.0]. + assertThat(sleeper.durations).hasSize(1) + assertThat(sleeper.durations[0]).isBetween(Duration.ofMillis(375), Duration.ofMillis(500)) assertNoResponseLeaks() } - private fun retryingHttpClientBuilder() = - RetryingHttpClient.builder() - .httpClient(httpClient) - // Use a no-op `Sleeper` to make the test fast. - .sleeper( - object : Sleeper { + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun execute_withExponentialBackoff(async: Boolean) { + stubFor(post(urlPathEqualTo("/something")).willReturn(serviceUnavailable())) + val sleeper = RecordingSleeper() + val retryingClient = retryingHttpClientBuilder(sleeper).maxRetries(3).build() + + val response = + retryingClient.execute( + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(baseUrl) + .addPathSegment("something") + .build(), + async, + ) - override fun sleep(duration: Duration) {} + // All retries exhausted; the last 503 response is returned. + assertThat(response.statusCode()).isEqualTo(503) + verify(4, postRequestedFor(urlPathEqualTo("/something"))) + // Exponential backoff with jitter: backoff = min(0.5 * 2^(retries-1), 8) * jitter where + // jitter is in [0.75, 1.0]. + 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] + assertThat(sleeper.durations[1]).isBetween(Duration.ofMillis(750), Duration.ofMillis(1000)) + // retries=3: 2.0s * [0.75, 1.0] + assertThat(sleeper.durations[2]).isBetween(Duration.ofMillis(1500), Duration.ofMillis(2000)) + assertNoResponseLeaks() + } - override fun sleepAsync(duration: Duration): CompletableFuture = - CompletableFuture.completedFuture(null) + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun execute_withExponentialBackoffCap(async: Boolean) { + stubFor(post(urlPathEqualTo("/something")).willReturn(serviceUnavailable())) + val sleeper = RecordingSleeper() + val retryingClient = retryingHttpClientBuilder(sleeper).maxRetries(6).build() - override fun close() {} - } + val response = + retryingClient.execute( + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(baseUrl) + .addPathSegment("something") + .build(), + async, ) + 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] + 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) + assertThat(sleeper.durations[5]).isBetween(Duration.ofMillis(6000), Duration.ofMillis(8000)) + assertNoResponseLeaks() + } + + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun execute_withRetryAfterMsPriorityOverRetryAfter(async: Boolean) { + stubFor( + post(urlPathEqualTo("/something")) + .inScenario("foo") + .whenScenarioStateIs(Scenario.STARTED) + .willReturn( + serviceUnavailable() + .withHeader("Retry-After-Ms", "50") + .withHeader("Retry-After", "2") + ) + .willSetStateTo("RETRY") + ) + stubFor( + post(urlPathEqualTo("/something")) + .inScenario("foo") + .whenScenarioStateIs("RETRY") + .willReturn(ok()) + .willSetStateTo("COMPLETED") + ) + val sleeper = RecordingSleeper() + val retryingClient = retryingHttpClientBuilder(sleeper).maxRetries(1).build() + + val response = + retryingClient.execute( + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(baseUrl) + .addPathSegment("something") + .build(), + async, + ) + + assertThat(response.statusCode()).isEqualTo(200) + // Retry-After-Ms (50ms) takes priority over Retry-After (2s). + assertThat(sleeper.durations).containsExactly(Duration.ofMillis(50)) + assertNoResponseLeaks() + } + + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun execute_withRetryAfterUnparseable(async: Boolean) { + stubFor( + post(urlPathEqualTo("/something")) + .inScenario("foo") + .whenScenarioStateIs(Scenario.STARTED) + .willReturn(serviceUnavailable().withHeader("Retry-After", "not-a-date-or-number")) + .willSetStateTo("RETRY") + ) + stubFor( + post(urlPathEqualTo("/something")) + .inScenario("foo") + .whenScenarioStateIs("RETRY") + .willReturn(ok()) + .willSetStateTo("COMPLETED") + ) + val sleeper = RecordingSleeper() + val retryingClient = retryingHttpClientBuilder(sleeper).maxRetries(1).build() + + val response = + retryingClient.execute( + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(baseUrl) + .addPathSegment("something") + .build(), + async, + ) + + assertThat(response.statusCode()).isEqualTo(200) + // Unparseable Retry-After falls through to exponential backoff. + assertThat(sleeper.durations).hasSize(1) + assertThat(sleeper.durations[0]).isBetween(Duration.ofMillis(375), Duration.ofMillis(500)) + assertNoResponseLeaks() + } + + private fun retryingHttpClientBuilder( + sleeper: RecordingSleeper, + clock: Clock = Clock.systemUTC(), + ) = RetryingHttpClient.builder().httpClient(httpClient).sleeper(sleeper).clock(clock) + private fun HttpClient.execute(request: HttpRequest, async: Boolean): HttpResponse = if (async) executeAsync(request).get() else execute(request) From 85e0b5edc6f3aa0e085587341c23f6ba84f636e1 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 17 Mar 2026 10:59:54 +0000 Subject: [PATCH 73/99] chore(internal): tweak CI branches --- .github/workflows/ci.yml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 85ec8c4..88e7100 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/**' From 2c68b2b6db38603652872f2d697443a69b966a9b Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 18 Mar 2026 10:00:47 +0000 Subject: [PATCH 74/99] chore(internal): update retry delay tests --- .../cas_parser/api/core/http/RetryingHttpClientTest.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/RetryingHttpClientTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/RetryingHttpClientTest.kt index 39c7156..720423c 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/RetryingHttpClientTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/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() } From f5f891294658859092eff70aae870f6afe169104 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 18 Mar 2026 10:14:37 +0000 Subject: [PATCH 75/99] fix(client): allow updating header/query affecting fields in `toBuilder()` --- .../com/cas_parser/api/core/ClientOptions.kt | 7 +++--- .../cas_parser/api/core/ClientOptionsTest.kt | 22 +++++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ClientOptions.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ClientOptions.kt index a0ed181..e5fac28 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ClientOptions.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/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("x-api-key", it) + headers.replace("x-api-key", it) } } - headers.replaceAll(this.headers.build()) - queryParams.replaceAll(this.queryParams.build()) return ClientOptions( httpClient, diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/ClientOptionsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/ClientOptionsTest.kt index 3859537..4e9fb6e 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/ClientOptionsTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/ClientOptionsTest.kt @@ -16,6 +16,28 @@ 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_apiKeyAuthCanBeUpdated() { + var clientOptions = + ClientOptions.builder().httpClient(httpClient).apiKey("My API Key").build() + + clientOptions = clientOptions.toBuilder().apiKey("another My API Key").build() + + assertThat(clientOptions.headers.values("x-api-key")).containsExactly("another My API Key") + } + @Test fun toBuilder_whenOriginalClientOptionsGarbageCollected_doesNotCloseOriginalClient() { var clientOptions = From b8349974e53ab5096f808cc153f60c84ff911640 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 20 Mar 2026 03:28:35 +0000 Subject: [PATCH 76/99] chore(internal): bump ktfmt --- buildSrc/src/main/kotlin/cas-parser.kotlin.gradle.kts | 2 +- scripts/fast-format | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/buildSrc/src/main/kotlin/cas-parser.kotlin.gradle.kts b/buildSrc/src/main/kotlin/cas-parser.kotlin.gradle.kts index f1fa5f4..056d328 100644 --- a/buildSrc/src/main/kotlin/cas-parser.kotlin.gradle.kts +++ b/buildSrc/src/main/kotlin/cas-parser.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/scripts/fast-format b/scripts/fast-format index 1b3bc47..35a1dee 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 From 6a81d7a6aae5c36d2778d13b67dc87a2d1b9af34 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 24 Mar 2026 04:30:26 +0000 Subject: [PATCH 77/99] chore(internal): update gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index b1346e6..90b85e9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .prism.log +.stdy.log .gradle .idea .kotlin From e4b76e870f8a070a4fa747acd23d42a2b8c01265 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 25 Mar 2026 03:09:21 +0000 Subject: [PATCH 78/99] chore(ci): skip lint on metadata-only changes Note that we still want to run tests, as these depend on the metadata. --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 88e7100..6e70176 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,7 +19,7 @@ jobs: timeout-minutes: 15 name: lint runs-on: ${{ github.repository == 'stainless-sdks/cas-parser-java' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} - if: github.event_name == 'push' || github.event.pull_request.head.repo.fork + if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata') steps: - uses: actions/checkout@v6 @@ -46,7 +46,7 @@ jobs: contents: read id-token: write runs-on: ${{ github.repository == 'stainless-sdks/cas-parser-java' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} - if: github.event_name == 'push' || github.event.pull_request.head.repo.fork + if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata') steps: - uses: actions/checkout@v6 From 845ee569a90a556c7deddb09b3600c1afbaa90b4 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 27 Mar 2026 19:57:08 +0000 Subject: [PATCH 79/99] chore(internal): version bump --- .release-please-manifest.json | 2 +- README.md | 10 +++++----- build.gradle.kts | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 383dd5a..8d0a116 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.5.2" + ".": "0.5.4" } \ No newline at end of file diff --git a/README.md b/README.md index ef44eb1..2eca0b5 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ -[![Maven Central](https://img.shields.io/maven-central/v/com.cas_parser.api/cas-parser-java)](https://central.sonatype.com/artifact/com.cas_parser.api/cas-parser-java/0.5.2) -[![javadoc](https://javadoc.io/badge2/com.cas_parser.api/cas-parser-java/0.5.2/javadoc.svg)](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.5.2) +[![Maven Central](https://img.shields.io/maven-central/v/com.cas_parser.api/cas-parser-java)](https://central.sonatype.com/artifact/com.cas_parser.api/cas-parser-java/0.5.4) +[![javadoc](https://javadoc.io/badge2/com.cas_parser.api/cas-parser-java/0.5.4/javadoc.svg)](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.5.4) @@ -22,7 +22,7 @@ Use the Cas Parser MCP Server to enable AI assistants to interact with this API, -The REST API documentation can be found on [casparser.in](https://casparser.in/docs). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.5.2). +The REST API documentation can be found on [casparser.in](https://casparser.in/docs). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.5.4). @@ -33,7 +33,7 @@ The REST API documentation can be found on [casparser.in](https://casparser.in/d ### Gradle ```kotlin -implementation("com.cas_parser.api:cas-parser-java:0.5.2") +implementation("com.cas_parser.api:cas-parser-java:0.5.4") ``` ### Maven @@ -42,7 +42,7 @@ implementation("com.cas_parser.api:cas-parser-java:0.5.2") com.cas_parser.api cas-parser-java - 0.5.2 + 0.5.4 ``` diff --git a/build.gradle.kts b/build.gradle.kts index ef89225..bb21bd5 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -9,7 +9,7 @@ repositories { allprojects { group = "com.cas_parser.api" - version = "0.5.2" // x-release-please-version + version = "0.5.4" // x-release-please-version } subprojects { From 367a82c75c100a90d3ddcad27dd93656bd1580de Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 31 Mar 2026 18:23:14 +0000 Subject: [PATCH 80/99] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 603f57a..25ece8f 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 21 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-d9763d006969b49a1473851069fdfa429eb13133b64103a62963bb70ddb22305.yml -openapi_spec_hash: 6aee689b7a759b12c85c088c15e29bc0 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-d868ff00b7b07f6b6802b00f22fad531a91a76bb219a634f3f90fe488bd499ba.yml +openapi_spec_hash: 20e9f2fc31feee78878cdf56e46dab60 config_hash: 5509bb7a961ae2e79114b24c381606d4 From caf26b95b0b10aae4ce7475dea49dd98ab00df0b Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sun, 19 Apr 2026 19:25:08 +0000 Subject: [PATCH 81/99] feat(api): api update --- .stats.yml | 4 +- .../inboundemail/InboundEmailCreateParams.kt | 263 ++++++++---------- .../InboundEmailCreateResponse.kt | 13 +- .../inboundemail/InboundEmailListResponse.kt | 13 +- .../InboundEmailRetrieveResponse.kt | 13 +- .../async/InboundEmailServiceAsync.kt | 53 ++-- .../services/blocking/InboundEmailService.kt | 51 ++-- .../InboundEmailCreateParamsTest.kt | 13 +- .../async/InboundEmailServiceAsyncTest.kt | 2 +- .../blocking/InboundEmailServiceTest.kt | 2 +- 10 files changed, 214 insertions(+), 213 deletions(-) diff --git a/.stats.yml b/.stats.yml index 25ece8f..9c6cf93 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 21 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-d868ff00b7b07f6b6802b00f22fad531a91a76bb219a634f3f90fe488bd499ba.yml -openapi_spec_hash: 20e9f2fc31feee78878cdf56e46dab60 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-78ef474b9e171a3eaa430a9dacdc2fa5c7f7d5f89147cb20573a355d3dbb9f0e.yml +openapi_spec_hash: 11b6e43ef4ed724f9804c9d790a4faee config_hash: 5509bb7a961ae2e79114b24c381606d4 diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateParams.kt index a20d52b..54b1e1c 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateParams.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateParams.kt @@ -9,7 +9,6 @@ import com.cas_parser.api.core.JsonMissing import com.cas_parser.api.core.JsonValue import com.cas_parser.api.core.Params import com.cas_parser.api.core.checkKnown -import com.cas_parser.api.core.checkRequired import com.cas_parser.api.core.http.Headers import com.cas_parser.api.core.http.QueryParams import com.cas_parser.api.core.toImmutable @@ -24,21 +23,14 @@ import java.util.Optional import kotlin.jvm.optionals.getOrNull /** - * Create a dedicated inbound email address for collecting CAS statements via email forwarding. + * Create a dedicated inbound email address for collecting CAS statements via email forwarding. When + * an investor forwards a CAS email to this address, we verify the sender and make the file + * available to you. * - * **How it works:** - * 1. Create an inbound email with your webhook URL - * 2. Display the email address to your user (e.g., "Forward your CAS to - * ie_xxx@import.casparser.in") - * 3. When an investor forwards a CAS email, we verify the sender and deliver to your webhook - * - * **Webhook Delivery:** - * - We POST to your `callback_url` with JSON body containing files (matching EmailCASFile schema) - * - Failed deliveries are retried automatically with exponential backoff - * - * **Inactivity:** - * - Inbound emails with no activity in 30 days are marked inactive - * - Active inbound emails remain operational indefinitely + * `callback_url` is **optional**: + * - **Set it** — we POST each parsed email to your webhook as it arrives. + * - **Omit it** — retrieve files via `GET /v4/inbound-email/{id}/files` without building a webhook + * consumer. */ class InboundEmailCreateParams private constructor( @@ -48,21 +40,9 @@ private constructor( ) : Params { /** - * Webhook URL where we POST email notifications. Must be HTTPS in production (HTTP allowed for - * localhost during development). - * - * @throws CasParserInvalidDataException 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 callbackUrl(): String = body.callbackUrl() - - /** - * Optional custom email prefix for user-friendly addresses. - * - Must be 3-32 characters - * - Alphanumeric + hyphens only - * - Must start and end with letter/number - * - Example: `john-portfolio@import.casparser.in` - * - If omitted, generates random ID like `ie_abc123xyz@import.casparser.in` + * Optional custom email prefix (e.g. `john-portfolio@import.casparser.in`). 3-32 chars, + * alphanumeric + hyphens, must start/end with a letter or number. If omitted, a random ID is + * generated. * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -81,6 +61,15 @@ private constructor( */ fun allowedSources(): Optional> = body.allowedSources() + /** + * Optional webhook URL where we POST parsed emails. Must be HTTPS in production (HTTP allowed + * for localhost). If omitted, retrieve files via `GET /v4/inbound-email/{id}/files`. + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun callbackUrl(): Optional = body.callbackUrl() + /** * Optional key-value pairs (max 10) to include in webhook payload. Useful for passing context * like plan_type, campaign_id, etc. @@ -99,13 +88,6 @@ private constructor( */ fun reference(): Optional = body.reference() - /** - * Returns the raw JSON value of [callbackUrl]. - * - * Unlike [callbackUrl], this method doesn't throw if the JSON field has an unexpected type. - */ - fun _callbackUrl(): JsonField = body._callbackUrl() - /** * Returns the raw JSON value of [alias]. * @@ -120,6 +102,13 @@ private constructor( */ fun _allowedSources(): JsonField> = body._allowedSources() + /** + * Returns the raw JSON value of [callbackUrl]. + * + * Unlike [callbackUrl], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _callbackUrl(): JsonField = body._callbackUrl() + /** * Returns the raw JSON value of [metadata]. * @@ -146,14 +135,9 @@ private constructor( companion object { - /** - * Returns a mutable builder for constructing an instance of [InboundEmailCreateParams]. - * - * The following fields are required: - * ```java - * .callbackUrl() - * ``` - */ + @JvmStatic fun none(): InboundEmailCreateParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [InboundEmailCreateParams]. */ @JvmStatic fun builder() = Builder() } @@ -176,9 +160,9 @@ private constructor( * * This is generally only useful if you are already constructing the body separately. * Otherwise, it's more convenient to use the top-level setters instead: - * - [callbackUrl] * - [alias] * - [allowedSources] + * - [callbackUrl] * - [metadata] * - [reference] * - etc. @@ -186,27 +170,9 @@ private constructor( fun body(body: Body) = apply { this.body = body.toBuilder() } /** - * Webhook URL where we POST email notifications. Must be HTTPS in production (HTTP allowed - * for localhost during development). - */ - fun callbackUrl(callbackUrl: String) = apply { body.callbackUrl(callbackUrl) } - - /** - * Sets [Builder.callbackUrl] to an arbitrary JSON value. - * - * You should usually call [Builder.callbackUrl] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet supported - * value. - */ - fun callbackUrl(callbackUrl: JsonField) = apply { body.callbackUrl(callbackUrl) } - - /** - * Optional custom email prefix for user-friendly addresses. - * - Must be 3-32 characters - * - Alphanumeric + hyphens only - * - Must start and end with letter/number - * - Example: `john-portfolio@import.casparser.in` - * - If omitted, generates random ID like `ie_abc123xyz@import.casparser.in` + * Optional custom email prefix (e.g. `john-portfolio@import.casparser.in`). 3-32 chars, + * alphanumeric + hyphens, must start/end with a letter or number. If omitted, a random ID + * is generated. */ fun alias(alias: String) = apply { body.alias(alias) } @@ -249,6 +215,25 @@ private constructor( body.addAllowedSource(allowedSource) } + /** + * Optional webhook URL where we POST parsed emails. Must be HTTPS in production (HTTP + * allowed for localhost). If omitted, retrieve files via `GET + * /v4/inbound-email/{id}/files`. + */ + fun callbackUrl(callbackUrl: String?) = apply { body.callbackUrl(callbackUrl) } + + /** Alias for calling [Builder.callbackUrl] with `callbackUrl.orElse(null)`. */ + fun callbackUrl(callbackUrl: Optional) = callbackUrl(callbackUrl.getOrNull()) + + /** + * Sets [Builder.callbackUrl] to an arbitrary JSON value. + * + * You should usually call [Builder.callbackUrl] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun callbackUrl(callbackUrl: JsonField) = apply { body.callbackUrl(callbackUrl) } + /** * Optional key-value pairs (max 10) to include in webhook payload. Useful for passing * context like plan_type, campaign_id, etc. @@ -400,13 +385,6 @@ private constructor( * Returns an immutable instance of [InboundEmailCreateParams]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .callbackUrl() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): InboundEmailCreateParams = InboundEmailCreateParams( @@ -425,9 +403,9 @@ private constructor( class Body @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( - private val callbackUrl: JsonField, private val alias: JsonField, private val allowedSources: JsonField>, + private val callbackUrl: JsonField, private val metadata: JsonField, private val reference: JsonField, private val additionalProperties: MutableMap, @@ -435,37 +413,25 @@ private constructor( @JsonCreator private constructor( - @JsonProperty("callback_url") - @ExcludeMissing - callbackUrl: JsonField = JsonMissing.of(), @JsonProperty("alias") @ExcludeMissing alias: JsonField = JsonMissing.of(), @JsonProperty("allowed_sources") @ExcludeMissing allowedSources: JsonField> = JsonMissing.of(), + @JsonProperty("callback_url") + @ExcludeMissing + callbackUrl: JsonField = JsonMissing.of(), @JsonProperty("metadata") @ExcludeMissing metadata: JsonField = JsonMissing.of(), @JsonProperty("reference") @ExcludeMissing reference: JsonField = JsonMissing.of(), - ) : this(callbackUrl, alias, allowedSources, metadata, reference, mutableMapOf()) + ) : this(alias, allowedSources, callbackUrl, metadata, reference, mutableMapOf()) /** - * Webhook URL where we POST email notifications. Must be HTTPS in production (HTTP allowed - * for localhost during development). - * - * @throws CasParserInvalidDataException 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 callbackUrl(): String = callbackUrl.getRequired("callback_url") - - /** - * Optional custom email prefix for user-friendly addresses. - * - Must be 3-32 characters - * - Alphanumeric + hyphens only - * - Must start and end with letter/number - * - Example: `john-portfolio@import.casparser.in` - * - If omitted, generates random ID like `ie_abc123xyz@import.casparser.in` + * Optional custom email prefix (e.g. `john-portfolio@import.casparser.in`). 3-32 chars, + * alphanumeric + hyphens, must start/end with a letter or number. If omitted, a random ID + * is generated. * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if * the server responded with an unexpected value). @@ -485,6 +451,16 @@ private constructor( fun allowedSources(): Optional> = allowedSources.getOptional("allowed_sources") + /** + * Optional webhook URL where we POST parsed emails. Must be HTTPS in production (HTTP + * allowed for localhost). If omitted, retrieve files via `GET + * /v4/inbound-email/{id}/files`. + * + * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun callbackUrl(): Optional = callbackUrl.getOptional("callback_url") + /** * Optional key-value pairs (max 10) to include in webhook payload. Useful for passing * context like plan_type, campaign_id, etc. @@ -503,15 +479,6 @@ private constructor( */ fun reference(): Optional = reference.getOptional("reference") - /** - * Returns the raw JSON value of [callbackUrl]. - * - * Unlike [callbackUrl], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("callback_url") - @ExcludeMissing - fun _callbackUrl(): JsonField = callbackUrl - /** * Returns the raw JSON value of [alias]. * @@ -529,6 +496,15 @@ private constructor( @ExcludeMissing fun _allowedSources(): JsonField> = allowedSources + /** + * Returns the raw JSON value of [callbackUrl]. + * + * Unlike [callbackUrl], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("callback_url") + @ExcludeMissing + fun _callbackUrl(): JsonField = callbackUrl + /** * Returns the raw JSON value of [metadata]. * @@ -557,61 +533,34 @@ private constructor( companion object { - /** - * Returns a mutable builder for constructing an instance of [Body]. - * - * The following fields are required: - * ```java - * .callbackUrl() - * ``` - */ + /** Returns a mutable builder for constructing an instance of [Body]. */ @JvmStatic fun builder() = Builder() } /** A builder for [Body]. */ class Builder internal constructor() { - private var callbackUrl: JsonField? = null private var alias: JsonField = JsonMissing.of() private var allowedSources: JsonField>? = null + private var callbackUrl: JsonField = JsonMissing.of() private var metadata: JsonField = JsonMissing.of() private var reference: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(body: Body) = apply { - callbackUrl = body.callbackUrl alias = body.alias allowedSources = body.allowedSources.map { it.toMutableList() } + callbackUrl = body.callbackUrl metadata = body.metadata reference = body.reference additionalProperties = body.additionalProperties.toMutableMap() } /** - * Webhook URL where we POST email notifications. Must be HTTPS in production (HTTP - * allowed for localhost during development). - */ - fun callbackUrl(callbackUrl: String) = callbackUrl(JsonField.of(callbackUrl)) - - /** - * Sets [Builder.callbackUrl] to an arbitrary JSON value. - * - * You should usually call [Builder.callbackUrl] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun callbackUrl(callbackUrl: JsonField) = apply { - this.callbackUrl = callbackUrl - } - - /** - * Optional custom email prefix for user-friendly addresses. - * - Must be 3-32 characters - * - Alphanumeric + hyphens only - * - Must start and end with letter/number - * - Example: `john-portfolio@import.casparser.in` - * - If omitted, generates random ID like `ie_abc123xyz@import.casparser.in` + * Optional custom email prefix (e.g. `john-portfolio@import.casparser.in`). 3-32 chars, + * alphanumeric + hyphens, must start/end with a letter or number. If omitted, a random + * ID is generated. */ fun alias(alias: String) = alias(JsonField.of(alias)) @@ -657,6 +606,27 @@ private constructor( } } + /** + * Optional webhook URL where we POST parsed emails. Must be HTTPS in production (HTTP + * allowed for localhost). If omitted, retrieve files via `GET + * /v4/inbound-email/{id}/files`. + */ + fun callbackUrl(callbackUrl: String?) = callbackUrl(JsonField.ofNullable(callbackUrl)) + + /** Alias for calling [Builder.callbackUrl] with `callbackUrl.orElse(null)`. */ + fun callbackUrl(callbackUrl: Optional) = callbackUrl(callbackUrl.getOrNull()) + + /** + * Sets [Builder.callbackUrl] to an arbitrary JSON value. + * + * You should usually call [Builder.callbackUrl] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun callbackUrl(callbackUrl: JsonField) = apply { + this.callbackUrl = callbackUrl + } + /** * Optional key-value pairs (max 10) to include in webhook payload. Useful for passing * context like plan_type, campaign_id, etc. @@ -710,19 +680,12 @@ private constructor( * Returns an immutable instance of [Body]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .callbackUrl() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): Body = Body( - checkRequired("callbackUrl", callbackUrl), alias, (allowedSources ?: JsonMissing.of()).map { it.toImmutable() }, + callbackUrl, metadata, reference, additionalProperties.toMutableMap(), @@ -736,9 +699,9 @@ private constructor( return@apply } - callbackUrl() alias() allowedSources().ifPresent { it.forEach { it.validate() } } + callbackUrl() metadata().ifPresent { it.validate() } reference() validated = true @@ -760,9 +723,9 @@ private constructor( */ @JvmSynthetic internal fun validity(): Int = - (if (callbackUrl.asKnown().isPresent) 1 else 0) + - (if (alias.asKnown().isPresent) 1 else 0) + + (if (alias.asKnown().isPresent) 1 else 0) + (allowedSources.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (callbackUrl.asKnown().isPresent) 1 else 0) + (metadata.asKnown().getOrNull()?.validity() ?: 0) + (if (reference.asKnown().isPresent) 1 else 0) @@ -772,9 +735,9 @@ private constructor( } return other is Body && - callbackUrl == other.callbackUrl && alias == other.alias && allowedSources == other.allowedSources && + callbackUrl == other.callbackUrl && metadata == other.metadata && reference == other.reference && additionalProperties == other.additionalProperties @@ -782,9 +745,9 @@ private constructor( private val hashCode: Int by lazy { Objects.hash( - callbackUrl, alias, allowedSources, + callbackUrl, metadata, reference, additionalProperties, @@ -794,7 +757,7 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "Body{callbackUrl=$callbackUrl, alias=$alias, allowedSources=$allowedSources, metadata=$metadata, reference=$reference, additionalProperties=$additionalProperties}" + "Body{alias=$alias, allowedSources=$allowedSources, callbackUrl=$callbackUrl, metadata=$metadata, reference=$reference, additionalProperties=$additionalProperties}" } class AllowedSource @JsonCreator private constructor(private val value: JsonField) : diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateResponse.kt index fb3d9d5..90aaaf9 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateResponse.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateResponse.kt @@ -80,7 +80,8 @@ private constructor( allowedSources.getOptional("allowed_sources") /** - * Webhook URL for email notifications + * Webhook URL for email notifications. `null` means files are only retrievable via `GET + * /v4/inbound-email/{id}/files` (pull delivery). * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -291,8 +292,14 @@ private constructor( } } - /** Webhook URL for email notifications */ - fun callbackUrl(callbackUrl: String) = callbackUrl(JsonField.of(callbackUrl)) + /** + * Webhook URL for email notifications. `null` means files are only retrievable via `GET + * /v4/inbound-email/{id}/files` (pull delivery). + */ + fun callbackUrl(callbackUrl: String?) = callbackUrl(JsonField.ofNullable(callbackUrl)) + + /** Alias for calling [Builder.callbackUrl] with `callbackUrl.orElse(null)`. */ + fun callbackUrl(callbackUrl: Optional) = callbackUrl(callbackUrl.getOrNull()) /** * Sets [Builder.callbackUrl] to an arbitrary JSON value. diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailListResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailListResponse.kt index 12c0e54..0412e52 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailListResponse.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailListResponse.kt @@ -351,7 +351,8 @@ private constructor( allowedSources.getOptional("allowed_sources") /** - * Webhook URL for email notifications + * Webhook URL for email notifications. `null` means files are only retrievable via `GET + * /v4/inbound-email/{id}/files` (pull delivery). * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if * the server responded with an unexpected value). @@ -562,8 +563,14 @@ private constructor( } } - /** Webhook URL for email notifications */ - fun callbackUrl(callbackUrl: String) = callbackUrl(JsonField.of(callbackUrl)) + /** + * Webhook URL for email notifications. `null` means files are only retrievable via `GET + * /v4/inbound-email/{id}/files` (pull delivery). + */ + fun callbackUrl(callbackUrl: String?) = callbackUrl(JsonField.ofNullable(callbackUrl)) + + /** Alias for calling [Builder.callbackUrl] with `callbackUrl.orElse(null)`. */ + fun callbackUrl(callbackUrl: Optional) = callbackUrl(callbackUrl.getOrNull()) /** * Sets [Builder.callbackUrl] to an arbitrary JSON value. diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailRetrieveResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailRetrieveResponse.kt index c997bf9..39aad18 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailRetrieveResponse.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailRetrieveResponse.kt @@ -80,7 +80,8 @@ private constructor( allowedSources.getOptional("allowed_sources") /** - * Webhook URL for email notifications + * Webhook URL for email notifications. `null` means files are only retrievable via `GET + * /v4/inbound-email/{id}/files` (pull delivery). * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -291,8 +292,14 @@ private constructor( } } - /** Webhook URL for email notifications */ - fun callbackUrl(callbackUrl: String) = callbackUrl(JsonField.of(callbackUrl)) + /** + * Webhook URL for email notifications. `null` means files are only retrievable via `GET + * /v4/inbound-email/{id}/files` (pull delivery). + */ + fun callbackUrl(callbackUrl: String?) = callbackUrl(JsonField.ofNullable(callbackUrl)) + + /** Alias for calling [Builder.callbackUrl] with `callbackUrl.orElse(null)`. */ + fun callbackUrl(callbackUrl: Optional) = callbackUrl(callbackUrl.getOrNull()) /** * Sets [Builder.callbackUrl] to an arbitrary JSON value. diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/InboundEmailServiceAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/InboundEmailServiceAsync.kt index 2c1b443..70d732d 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/InboundEmailServiceAsync.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/InboundEmailServiceAsync.kt @@ -55,31 +55,32 @@ interface InboundEmailServiceAsync { /** * Create a dedicated inbound email address for collecting CAS statements via email forwarding. + * When an investor forwards a CAS email to this address, we verify the sender and make the file + * available to you. * - * **How it works:** - * 1. Create an inbound email with your webhook URL - * 2. Display the email address to your user (e.g., "Forward your CAS to - * ie_xxx@import.casparser.in") - * 3. When an investor forwards a CAS email, we verify the sender and deliver to your webhook - * - * **Webhook Delivery:** - * - We POST to your `callback_url` with JSON body containing files (matching EmailCASFile - * schema) - * - Failed deliveries are retried automatically with exponential backoff - * - * **Inactivity:** - * - Inbound emails with no activity in 30 days are marked inactive - * - Active inbound emails remain operational indefinitely + * `callback_url` is **optional**: + * - **Set it** — we POST each parsed email to your webhook as it arrives. + * - **Omit it** — retrieve files via `GET /v4/inbound-email/{id}/files` without building a + * webhook consumer. */ - fun create(params: InboundEmailCreateParams): CompletableFuture = - create(params, RequestOptions.none()) + fun create(): CompletableFuture = + create(InboundEmailCreateParams.none()) /** @see create */ fun create( - params: InboundEmailCreateParams, + params: InboundEmailCreateParams = InboundEmailCreateParams.none(), requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see create */ + fun create( + params: InboundEmailCreateParams = InboundEmailCreateParams.none() + ): CompletableFuture = create(params, RequestOptions.none()) + + /** @see create */ + fun create(requestOptions: RequestOptions): CompletableFuture = + create(InboundEmailCreateParams.none(), requestOptions) + /** Retrieve details of a specific mailbox including statistics. */ fun retrieve(inboundEmailId: String): CompletableFuture = retrieve(inboundEmailId, InboundEmailRetrieveParams.none()) @@ -198,16 +199,26 @@ interface InboundEmailServiceAsync { * Returns a raw HTTP response for `post /v4/inbound-email`, but is otherwise the same as * [InboundEmailServiceAsync.create]. */ + fun create(): CompletableFuture> = + create(InboundEmailCreateParams.none()) + + /** @see create */ fun create( - params: InboundEmailCreateParams + params: InboundEmailCreateParams = InboundEmailCreateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see create */ + fun create( + params: InboundEmailCreateParams = InboundEmailCreateParams.none() ): CompletableFuture> = create(params, RequestOptions.none()) /** @see create */ fun create( - params: InboundEmailCreateParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture> + requestOptions: RequestOptions + ): CompletableFuture> = + create(InboundEmailCreateParams.none(), requestOptions) /** * Returns a raw HTTP response for `get /v4/inbound-email/{inbound_email_id}`, but is diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/InboundEmailService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/InboundEmailService.kt index be0ff40..6b52989 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/InboundEmailService.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/InboundEmailService.kt @@ -55,31 +55,31 @@ interface InboundEmailService { /** * Create a dedicated inbound email address for collecting CAS statements via email forwarding. + * When an investor forwards a CAS email to this address, we verify the sender and make the file + * available to you. * - * **How it works:** - * 1. Create an inbound email with your webhook URL - * 2. Display the email address to your user (e.g., "Forward your CAS to - * ie_xxx@import.casparser.in") - * 3. When an investor forwards a CAS email, we verify the sender and deliver to your webhook - * - * **Webhook Delivery:** - * - We POST to your `callback_url` with JSON body containing files (matching EmailCASFile - * schema) - * - Failed deliveries are retried automatically with exponential backoff - * - * **Inactivity:** - * - Inbound emails with no activity in 30 days are marked inactive - * - Active inbound emails remain operational indefinitely + * `callback_url` is **optional**: + * - **Set it** — we POST each parsed email to your webhook as it arrives. + * - **Omit it** — retrieve files via `GET /v4/inbound-email/{id}/files` without building a + * webhook consumer. */ - fun create(params: InboundEmailCreateParams): InboundEmailCreateResponse = - create(params, RequestOptions.none()) + fun create(): InboundEmailCreateResponse = create(InboundEmailCreateParams.none()) /** @see create */ fun create( - params: InboundEmailCreateParams, + params: InboundEmailCreateParams = InboundEmailCreateParams.none(), requestOptions: RequestOptions = RequestOptions.none(), ): InboundEmailCreateResponse + /** @see create */ + fun create( + params: InboundEmailCreateParams = InboundEmailCreateParams.none() + ): InboundEmailCreateResponse = create(params, RequestOptions.none()) + + /** @see create */ + fun create(requestOptions: RequestOptions): InboundEmailCreateResponse = + create(InboundEmailCreateParams.none(), requestOptions) + /** Retrieve details of a specific mailbox including statistics. */ fun retrieve(inboundEmailId: String): InboundEmailRetrieveResponse = retrieve(inboundEmailId, InboundEmailRetrieveParams.none()) @@ -192,16 +192,27 @@ interface InboundEmailService { * [InboundEmailService.create]. */ @MustBeClosed - fun create(params: InboundEmailCreateParams): HttpResponseFor = - create(params, RequestOptions.none()) + fun create(): HttpResponseFor = + create(InboundEmailCreateParams.none()) /** @see create */ @MustBeClosed fun create( - params: InboundEmailCreateParams, + params: InboundEmailCreateParams = InboundEmailCreateParams.none(), requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + /** @see create */ + @MustBeClosed + fun create( + params: InboundEmailCreateParams = InboundEmailCreateParams.none() + ): HttpResponseFor = create(params, RequestOptions.none()) + + /** @see create */ + @MustBeClosed + fun create(requestOptions: RequestOptions): HttpResponseFor = + create(InboundEmailCreateParams.none(), requestOptions) + /** * Returns a raw HTTP response for `get /v4/inbound-email/{inbound_email_id}`, but is * otherwise the same as [InboundEmailService.retrieve]. diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateParamsTest.kt index 900b778..876cff9 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateParamsTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateParamsTest.kt @@ -12,10 +12,10 @@ internal class InboundEmailCreateParamsTest { @Test fun create() { InboundEmailCreateParams.builder() - .callbackUrl("https://api.yourapp.com/webhooks/cas-email") .alias("john-portfolio") .addAllowedSource(InboundEmailCreateParams.AllowedSource.CDSL) .addAllowedSource(InboundEmailCreateParams.AllowedSource.NSDL) + .callbackUrl("https://api.yourapp.com/webhooks/cas-email") .metadata( InboundEmailCreateParams.Metadata.builder() .putAdditionalProperty("plan", JsonValue.from("premium")) @@ -30,10 +30,10 @@ internal class InboundEmailCreateParamsTest { fun body() { val params = InboundEmailCreateParams.builder() - .callbackUrl("https://api.yourapp.com/webhooks/cas-email") .alias("john-portfolio") .addAllowedSource(InboundEmailCreateParams.AllowedSource.CDSL) .addAllowedSource(InboundEmailCreateParams.AllowedSource.NSDL) + .callbackUrl("https://api.yourapp.com/webhooks/cas-email") .metadata( InboundEmailCreateParams.Metadata.builder() .putAdditionalProperty("plan", JsonValue.from("premium")) @@ -45,13 +45,13 @@ internal class InboundEmailCreateParamsTest { val body = params._body() - assertThat(body.callbackUrl()).isEqualTo("https://api.yourapp.com/webhooks/cas-email") assertThat(body.alias()).contains("john-portfolio") assertThat(body.allowedSources().getOrNull()) .containsExactly( InboundEmailCreateParams.AllowedSource.CDSL, InboundEmailCreateParams.AllowedSource.NSDL, ) + assertThat(body.callbackUrl()).contains("https://api.yourapp.com/webhooks/cas-email") assertThat(body.metadata()) .contains( InboundEmailCreateParams.Metadata.builder() @@ -64,13 +64,8 @@ internal class InboundEmailCreateParamsTest { @Test fun bodyWithoutOptionalFields() { - val params = - InboundEmailCreateParams.builder() - .callbackUrl("https://api.yourapp.com/webhooks/cas-email") - .build() + val params = InboundEmailCreateParams.builder().build() val body = params._body() - - assertThat(body.callbackUrl()).isEqualTo("https://api.yourapp.com/webhooks/cas-email") } } diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/InboundEmailServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/InboundEmailServiceAsyncTest.kt index 0993dac..53fed09 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/InboundEmailServiceAsyncTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/InboundEmailServiceAsyncTest.kt @@ -20,10 +20,10 @@ internal class InboundEmailServiceAsyncTest { val inboundEmailFuture = inboundEmailServiceAsync.create( InboundEmailCreateParams.builder() - .callbackUrl("https://api.yourapp.com/webhooks/cas-email") .alias("john-portfolio") .addAllowedSource(InboundEmailCreateParams.AllowedSource.CDSL) .addAllowedSource(InboundEmailCreateParams.AllowedSource.NSDL) + .callbackUrl("https://api.yourapp.com/webhooks/cas-email") .metadata( InboundEmailCreateParams.Metadata.builder() .putAdditionalProperty("plan", JsonValue.from("premium")) diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/InboundEmailServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/InboundEmailServiceTest.kt index 66d6b0c..346d0de 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/InboundEmailServiceTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/InboundEmailServiceTest.kt @@ -20,10 +20,10 @@ internal class InboundEmailServiceTest { val inboundEmail = inboundEmailService.create( InboundEmailCreateParams.builder() - .callbackUrl("https://api.yourapp.com/webhooks/cas-email") .alias("john-portfolio") .addAllowedSource(InboundEmailCreateParams.AllowedSource.CDSL) .addAllowedSource(InboundEmailCreateParams.AllowedSource.NSDL) + .callbackUrl("https://api.yourapp.com/webhooks/cas-email") .metadata( InboundEmailCreateParams.Metadata.builder() .putAdditionalProperty("plan", JsonValue.from("premium")) From 531b588647bc3c9552c5878ceabd5e3606ca9f54 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sun, 19 Apr 2026 21:25:14 +0000 Subject: [PATCH 82/99] feat(api): api update --- .stats.yml | 4 ++-- .../models/inboundemail/InboundEmailRetrieveParamsTest.kt | 6 +++--- .../api/services/async/InboundEmailServiceAsyncTest.kt | 2 +- .../api/services/blocking/InboundEmailServiceTest.kt | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.stats.yml b/.stats.yml index 9c6cf93..e26d438 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 21 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-78ef474b9e171a3eaa430a9dacdc2fa5c7f7d5f89147cb20573a355d3dbb9f0e.yml -openapi_spec_hash: 11b6e43ef4ed724f9804c9d790a4faee +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-e5c0c65637cdf3a6c4360b8193973b73a3d35ad1056ef607c3319ef03e591a55.yml +openapi_spec_hash: 7515d1e5fe3130b9f5411f7aacbc8a64 config_hash: 5509bb7a961ae2e79114b24c381606d4 diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailRetrieveParamsTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailRetrieveParamsTest.kt index 2b76fc3..8d7abc0 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailRetrieveParamsTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailRetrieveParamsTest.kt @@ -9,14 +9,14 @@ internal class InboundEmailRetrieveParamsTest { @Test fun create() { - InboundEmailRetrieveParams.builder().inboundEmailId("ie_a1b2c3d4e5f6").build() + InboundEmailRetrieveParams.builder().inboundEmailId("inbound_email_id").build() } @Test fun pathParams() { - val params = InboundEmailRetrieveParams.builder().inboundEmailId("ie_a1b2c3d4e5f6").build() + val params = InboundEmailRetrieveParams.builder().inboundEmailId("inbound_email_id").build() - assertThat(params._pathParam(0)).isEqualTo("ie_a1b2c3d4e5f6") + assertThat(params._pathParam(0)).isEqualTo("inbound_email_id") // out-of-bound path param assertThat(params._pathParam(1)).isEqualTo("") } diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/InboundEmailServiceAsyncTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/InboundEmailServiceAsyncTest.kt index 53fed09..386e7ca 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/InboundEmailServiceAsyncTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/async/InboundEmailServiceAsyncTest.kt @@ -44,7 +44,7 @@ internal class InboundEmailServiceAsyncTest { val client = CasParserOkHttpClientAsync.builder().apiKey("My API Key").build() val inboundEmailServiceAsync = client.inboundEmail() - val inboundEmailFuture = inboundEmailServiceAsync.retrieve("ie_a1b2c3d4e5f6") + val inboundEmailFuture = inboundEmailServiceAsync.retrieve("inbound_email_id") val inboundEmail = inboundEmailFuture.get() inboundEmail.validate() diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/InboundEmailServiceTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/InboundEmailServiceTest.kt index 346d0de..8d826a9 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/InboundEmailServiceTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/services/blocking/InboundEmailServiceTest.kt @@ -43,7 +43,7 @@ internal class InboundEmailServiceTest { val client = CasParserOkHttpClient.builder().apiKey("My API Key").build() val inboundEmailService = client.inboundEmail() - val inboundEmail = inboundEmailService.retrieve("ie_a1b2c3d4e5f6") + val inboundEmail = inboundEmailService.retrieve("inbound_email_id") inboundEmail.validate() } From bac94864e2c488799b870d359c0300933af7c5b0 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 20 Apr 2026 17:56:46 +0000 Subject: [PATCH 83/99] chore(internal): version bump --- .release-please-manifest.json | 2 +- README.md | 10 +++++----- build.gradle.kts | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 8d0a116..4208b5c 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.5.4" + ".": "0.6.0" } \ No newline at end of file diff --git a/README.md b/README.md index 2eca0b5..7e9b378 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ -[![Maven Central](https://img.shields.io/maven-central/v/com.cas_parser.api/cas-parser-java)](https://central.sonatype.com/artifact/com.cas_parser.api/cas-parser-java/0.5.4) -[![javadoc](https://javadoc.io/badge2/com.cas_parser.api/cas-parser-java/0.5.4/javadoc.svg)](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.5.4) +[![Maven Central](https://img.shields.io/maven-central/v/com.cas_parser.api/cas-parser-java)](https://central.sonatype.com/artifact/com.cas_parser.api/cas-parser-java/0.6.0) +[![javadoc](https://javadoc.io/badge2/com.cas_parser.api/cas-parser-java/0.6.0/javadoc.svg)](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.6.0) @@ -22,7 +22,7 @@ Use the Cas Parser MCP Server to enable AI assistants to interact with this API, -The REST API documentation can be found on [casparser.in](https://casparser.in/docs). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.5.4). +The REST API documentation can be found on [casparser.in](https://casparser.in/docs). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.6.0). @@ -33,7 +33,7 @@ The REST API documentation can be found on [casparser.in](https://casparser.in/d ### Gradle ```kotlin -implementation("com.cas_parser.api:cas-parser-java:0.5.4") +implementation("com.cas_parser.api:cas-parser-java:0.6.0") ``` ### Maven @@ -42,7 +42,7 @@ implementation("com.cas_parser.api:cas-parser-java:0.5.4") com.cas_parser.api cas-parser-java - 0.5.4 + 0.6.0 ``` diff --git a/build.gradle.kts b/build.gradle.kts index bb21bd5..8f7d82f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -9,7 +9,7 @@ repositories { allprojects { group = "com.cas_parser.api" - version = "0.5.4" // x-release-please-version + version = "0.6.0" // x-release-please-version } subprojects { From 6418c98f0d0b0655eb0d920e7926839e1f5d701b Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 28 Apr 2026 04:38:56 +0000 Subject: [PATCH 84/99] feat: support setting headers via env --- .../main/kotlin/com/cas_parser/api/core/ClientOptions.kt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ClientOptions.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ClientOptions.kt index e5fac28..4fb3496 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ClientOptions.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ClientOptions.kt @@ -375,6 +375,14 @@ private constructor( (System.getProperty("casparser.apiKey") ?: System.getenv("CAS_PARSER_API_KEY"))?.let { apiKey(it) } + System.getenv("CAS_PARSER_CUSTOM_HEADERS")?.let { customHeadersEnv -> + for (line in customHeadersEnv.split("\n")) { + val colon = line.indexOf(':') + if (colon >= 0) { + putHeader(line.substring(0, colon).trim(), line.substring(colon + 1).trim()) + } + } + } } /** From 076a6318f253415f90ab6f2d49f4d34fabf6a629 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 30 Apr 2026 04:25:38 +0000 Subject: [PATCH 85/99] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index e26d438..4aee240 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 21 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-e5c0c65637cdf3a6c4360b8193973b73a3d35ad1056ef607c3319ef03e591a55.yml +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser/cas-parser-e5c0c65637cdf3a6c4360b8193973b73a3d35ad1056ef607c3319ef03e591a55.yml openapi_spec_hash: 7515d1e5fe3130b9f5411f7aacbc8a64 config_hash: 5509bb7a961ae2e79114b24c381606d4 From f102695033183acacbe5dbbaa9040747beb9f2dc Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 1 May 2026 03:25:18 +0000 Subject: [PATCH 86/99] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index 4aee240..d5b8f44 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 21 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser/cas-parser-e5c0c65637cdf3a6c4360b8193973b73a3d35ad1056ef607c3319ef03e591a55.yml +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser/cas-parser-2fd773786951b723a5d7d7342bf1c6ab46f08bd2851e916d188faae379d5aa4c.yml openapi_spec_hash: 7515d1e5fe3130b9f5411f7aacbc8a64 config_hash: 5509bb7a961ae2e79114b24c381606d4 From 7f59f767b956dfc2be7e807ebdc6910d7b5cdb53 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 2 May 2026 10:18:07 +0000 Subject: [PATCH 87/99] feat(api): api update --- .stats.yml | 4 +-- .../InboundEmailCreateResponse.kt | 27 +++++++++---------- .../inboundemail/InboundEmailListParams.kt | 4 +-- .../inboundemail/InboundEmailListResponse.kt | 27 +++++++++---------- .../InboundEmailRetrieveParams.kt | 2 +- .../InboundEmailRetrieveResponse.kt | 27 +++++++++---------- .../models/inbox/InboxListCasFilesResponse.kt | 12 +++++++-- .../async/InboundEmailServiceAsync.kt | 6 ++--- .../services/blocking/InboundEmailService.kt | 6 ++--- .../InboundEmailDeleteResponseTest.kt | 6 ++--- 10 files changed, 60 insertions(+), 61 deletions(-) diff --git a/.stats.yml b/.stats.yml index d5b8f44..cd58596 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 21 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser/cas-parser-2fd773786951b723a5d7d7342bf1c6ab46f08bd2851e916d188faae379d5aa4c.yml -openapi_spec_hash: 7515d1e5fe3130b9f5411f7aacbc8a64 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser/cas-parser-c7cca9a7a8e15f8a584c22eab142c4af72a329117f63cc3b3f7cabb25410f2ce.yml +openapi_spec_hash: f40d936e433bbf8c98179d0b36f304c8 config_hash: 5509bb7a961ae2e79114b24c381606d4 diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateResponse.kt index 90aaaf9..77d0134 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateResponse.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateResponse.kt @@ -80,8 +80,8 @@ private constructor( allowedSources.getOptional("allowed_sources") /** - * Webhook URL for email notifications. `null` means files are only retrievable via `GET - * /v4/inbound-email/{id}/files` (pull delivery). + * Webhook URL for email notifications. Empty string (`""`) means files are only retrievable via + * `GET /v4/inbound-email/{id}/files` (SDK / pull mode). * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -89,7 +89,7 @@ private constructor( fun callbackUrl(): Optional = callbackUrl.getOptional("callback_url") /** - * When the mailbox was created + * When the inbound email was created * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -129,7 +129,7 @@ private constructor( fun reference(): Optional = reference.getOptional("reference") /** - * Current mailbox status + * Current inbound email lifecycle status * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -137,7 +137,7 @@ private constructor( fun status(): Optional = status.getOptional("status") /** - * When the mailbox was last updated + * When the inbound email was last updated * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -293,13 +293,10 @@ private constructor( } /** - * Webhook URL for email notifications. `null` means files are only retrievable via `GET - * /v4/inbound-email/{id}/files` (pull delivery). + * Webhook URL for email notifications. Empty string (`""`) means files are only retrievable + * via `GET /v4/inbound-email/{id}/files` (SDK / pull mode). */ - fun callbackUrl(callbackUrl: String?) = callbackUrl(JsonField.ofNullable(callbackUrl)) - - /** Alias for calling [Builder.callbackUrl] with `callbackUrl.orElse(null)`. */ - fun callbackUrl(callbackUrl: Optional) = callbackUrl(callbackUrl.getOrNull()) + fun callbackUrl(callbackUrl: String) = callbackUrl(JsonField.of(callbackUrl)) /** * Sets [Builder.callbackUrl] to an arbitrary JSON value. @@ -310,7 +307,7 @@ private constructor( */ fun callbackUrl(callbackUrl: JsonField) = apply { this.callbackUrl = callbackUrl } - /** When the mailbox was created */ + /** When the inbound email was created */ fun createdAt(createdAt: OffsetDateTime) = createdAt(JsonField.of(createdAt)) /** @@ -374,7 +371,7 @@ private constructor( */ fun reference(reference: JsonField) = apply { this.reference = reference } - /** Current mailbox status */ + /** Current inbound email lifecycle status */ fun status(status: Status) = status(JsonField.of(status)) /** @@ -385,7 +382,7 @@ private constructor( */ fun status(status: JsonField) = apply { this.status = status } - /** When the mailbox was last updated */ + /** When the inbound email was last updated */ fun updatedAt(updatedAt: OffsetDateTime) = updatedAt(JsonField.of(updatedAt)) /** @@ -723,7 +720,7 @@ private constructor( override fun toString() = "Metadata{additionalProperties=$additionalProperties}" } - /** Current mailbox status */ + /** Current inbound email lifecycle status */ class Status @JsonCreator private constructor(private val value: JsonField) : Enum { /** diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailListParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailListParams.kt index aea16e2..aadb63b 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailListParams.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailListParams.kt @@ -14,8 +14,8 @@ import java.util.Optional import kotlin.jvm.optionals.getOrNull /** - * List all mailboxes associated with your API key. Returns active and inactive mailboxes (deleted - * mailboxes are excluded). + * List all inbound emails associated with your API key. Returns active and paused inbound emails + * (deleted ones are excluded). */ class InboundEmailListParams private constructor( diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailListResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailListResponse.kt index 0412e52..9c8a3c0 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailListResponse.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailListResponse.kt @@ -351,8 +351,8 @@ private constructor( allowedSources.getOptional("allowed_sources") /** - * Webhook URL for email notifications. `null` means files are only retrievable via `GET - * /v4/inbound-email/{id}/files` (pull delivery). + * Webhook URL for email notifications. Empty string (`""`) means files are only retrievable + * via `GET /v4/inbound-email/{id}/files` (SDK / pull mode). * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if * the server responded with an unexpected value). @@ -360,7 +360,7 @@ private constructor( fun callbackUrl(): Optional = callbackUrl.getOptional("callback_url") /** - * When the mailbox was created + * When the inbound email was created * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if * the server responded with an unexpected value). @@ -400,7 +400,7 @@ private constructor( fun reference(): Optional = reference.getOptional("reference") /** - * Current mailbox status + * Current inbound email lifecycle status * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if * the server responded with an unexpected value). @@ -408,7 +408,7 @@ private constructor( fun status(): Optional = status.getOptional("status") /** - * When the mailbox was last updated + * When the inbound email was last updated * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if * the server responded with an unexpected value). @@ -564,13 +564,10 @@ private constructor( } /** - * Webhook URL for email notifications. `null` means files are only retrievable via `GET - * /v4/inbound-email/{id}/files` (pull delivery). + * Webhook URL for email notifications. Empty string (`""`) means files are only + * retrievable via `GET /v4/inbound-email/{id}/files` (SDK / pull mode). */ - fun callbackUrl(callbackUrl: String?) = callbackUrl(JsonField.ofNullable(callbackUrl)) - - /** Alias for calling [Builder.callbackUrl] with `callbackUrl.orElse(null)`. */ - fun callbackUrl(callbackUrl: Optional) = callbackUrl(callbackUrl.getOrNull()) + fun callbackUrl(callbackUrl: String) = callbackUrl(JsonField.of(callbackUrl)) /** * Sets [Builder.callbackUrl] to an arbitrary JSON value. @@ -583,7 +580,7 @@ private constructor( this.callbackUrl = callbackUrl } - /** When the mailbox was created */ + /** When the inbound email was created */ fun createdAt(createdAt: OffsetDateTime) = createdAt(JsonField.of(createdAt)) /** @@ -651,7 +648,7 @@ private constructor( */ fun reference(reference: JsonField) = apply { this.reference = reference } - /** Current mailbox status */ + /** Current inbound email lifecycle status */ fun status(status: Status) = status(JsonField.of(status)) /** @@ -663,7 +660,7 @@ private constructor( */ fun status(status: JsonField) = apply { this.status = status } - /** When the mailbox was last updated */ + /** When the inbound email was last updated */ fun updatedAt(updatedAt: OffsetDateTime) = updatedAt(JsonField.of(updatedAt)) /** @@ -1007,7 +1004,7 @@ private constructor( override fun toString() = "Metadata{additionalProperties=$additionalProperties}" } - /** Current mailbox status */ + /** Current inbound email lifecycle status */ class Status @JsonCreator private constructor(private val value: JsonField) : Enum { /** diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailRetrieveParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailRetrieveParams.kt index 1c0676b..676faaa 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailRetrieveParams.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailRetrieveParams.kt @@ -9,7 +9,7 @@ import java.util.Objects import java.util.Optional import kotlin.jvm.optionals.getOrNull -/** Retrieve details of a specific mailbox including statistics. */ +/** Retrieve details of a specific inbound email including statistics. */ class InboundEmailRetrieveParams private constructor( private val inboundEmailId: String?, diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailRetrieveResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailRetrieveResponse.kt index 39aad18..7521768 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailRetrieveResponse.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailRetrieveResponse.kt @@ -80,8 +80,8 @@ private constructor( allowedSources.getOptional("allowed_sources") /** - * Webhook URL for email notifications. `null` means files are only retrievable via `GET - * /v4/inbound-email/{id}/files` (pull delivery). + * Webhook URL for email notifications. Empty string (`""`) means files are only retrievable via + * `GET /v4/inbound-email/{id}/files` (SDK / pull mode). * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -89,7 +89,7 @@ private constructor( fun callbackUrl(): Optional = callbackUrl.getOptional("callback_url") /** - * When the mailbox was created + * When the inbound email was created * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -129,7 +129,7 @@ private constructor( fun reference(): Optional = reference.getOptional("reference") /** - * Current mailbox status + * Current inbound email lifecycle status * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -137,7 +137,7 @@ private constructor( fun status(): Optional = status.getOptional("status") /** - * When the mailbox was last updated + * When the inbound email was last updated * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -293,13 +293,10 @@ private constructor( } /** - * Webhook URL for email notifications. `null` means files are only retrievable via `GET - * /v4/inbound-email/{id}/files` (pull delivery). + * Webhook URL for email notifications. Empty string (`""`) means files are only retrievable + * via `GET /v4/inbound-email/{id}/files` (SDK / pull mode). */ - fun callbackUrl(callbackUrl: String?) = callbackUrl(JsonField.ofNullable(callbackUrl)) - - /** Alias for calling [Builder.callbackUrl] with `callbackUrl.orElse(null)`. */ - fun callbackUrl(callbackUrl: Optional) = callbackUrl(callbackUrl.getOrNull()) + fun callbackUrl(callbackUrl: String) = callbackUrl(JsonField.of(callbackUrl)) /** * Sets [Builder.callbackUrl] to an arbitrary JSON value. @@ -310,7 +307,7 @@ private constructor( */ fun callbackUrl(callbackUrl: JsonField) = apply { this.callbackUrl = callbackUrl } - /** When the mailbox was created */ + /** When the inbound email was created */ fun createdAt(createdAt: OffsetDateTime) = createdAt(JsonField.of(createdAt)) /** @@ -374,7 +371,7 @@ private constructor( */ fun reference(reference: JsonField) = apply { this.reference = reference } - /** Current mailbox status */ + /** Current inbound email lifecycle status */ fun status(status: Status) = status(JsonField.of(status)) /** @@ -385,7 +382,7 @@ private constructor( */ fun status(status: JsonField) = apply { this.status = status } - /** When the mailbox was last updated */ + /** When the inbound email was last updated */ fun updatedAt(updatedAt: OffsetDateTime) = updatedAt(JsonField.of(updatedAt)) /** @@ -723,7 +720,7 @@ private constructor( override fun toString() = "Metadata{additionalProperties=$additionalProperties}" } - /** Current mailbox status */ + /** Current inbound email lifecycle status */ class Status @JsonCreator private constructor(private val value: JsonField) : Enum { /** diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesResponse.kt index 1373c71..e4b8285 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesResponse.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesResponse.kt @@ -285,7 +285,10 @@ private constructor( fun casType(): Optional = casType.getOptional("cas_type") /** - * URL expiration time in seconds (default 86400 = 24 hours) + * URL expiration time in seconds. Defaults vary by source: + * - Gmail Inbox Import: 86400 (24h) + * - Inbound Email (webhook mode): 172800 (48h) + * - Inbound Email (SDK mode): aligned with the session TTL (~30 min) * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if * the server responded with an unexpected value). @@ -477,7 +480,12 @@ private constructor( */ fun casType(casType: JsonField) = apply { this.casType = casType } - /** URL expiration time in seconds (default 86400 = 24 hours) */ + /** + * URL expiration time in seconds. Defaults vary by source: + * - Gmail Inbox Import: 86400 (24h) + * - Inbound Email (webhook mode): 172800 (48h) + * - Inbound Email (SDK mode): aligned with the session TTL (~30 min) + */ fun expiresIn(expiresIn: Long) = expiresIn(JsonField.of(expiresIn)) /** diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/InboundEmailServiceAsync.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/InboundEmailServiceAsync.kt index 70d732d..cfd29f4 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/InboundEmailServiceAsync.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/async/InboundEmailServiceAsync.kt @@ -81,7 +81,7 @@ interface InboundEmailServiceAsync { fun create(requestOptions: RequestOptions): CompletableFuture = create(InboundEmailCreateParams.none(), requestOptions) - /** Retrieve details of a specific mailbox including statistics. */ + /** Retrieve details of a specific inbound email including statistics. */ fun retrieve(inboundEmailId: String): CompletableFuture = retrieve(inboundEmailId, InboundEmailRetrieveParams.none()) @@ -119,8 +119,8 @@ interface InboundEmailServiceAsync { retrieve(inboundEmailId, InboundEmailRetrieveParams.none(), requestOptions) /** - * List all mailboxes associated with your API key. Returns active and inactive mailboxes - * (deleted mailboxes are excluded). + * List all inbound emails associated with your API key. Returns active and paused inbound + * emails (deleted ones are excluded). */ fun list(): CompletableFuture = list(InboundEmailListParams.none()) diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/InboundEmailService.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/InboundEmailService.kt index 6b52989..ab31236 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/InboundEmailService.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/services/blocking/InboundEmailService.kt @@ -80,7 +80,7 @@ interface InboundEmailService { fun create(requestOptions: RequestOptions): InboundEmailCreateResponse = create(InboundEmailCreateParams.none(), requestOptions) - /** Retrieve details of a specific mailbox including statistics. */ + /** Retrieve details of a specific inbound email including statistics. */ fun retrieve(inboundEmailId: String): InboundEmailRetrieveResponse = retrieve(inboundEmailId, InboundEmailRetrieveParams.none()) @@ -116,8 +116,8 @@ interface InboundEmailService { retrieve(inboundEmailId, InboundEmailRetrieveParams.none(), requestOptions) /** - * List all mailboxes associated with your API key. Returns active and inactive mailboxes - * (deleted mailboxes are excluded). + * List all inbound emails associated with your API key. Returns active and paused inbound + * emails (deleted ones are excluded). */ fun list(): InboundEmailListResponse = list(InboundEmailListParams.none()) diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailDeleteResponseTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailDeleteResponseTest.kt index 0c8f6fe..476763e 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailDeleteResponseTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailDeleteResponseTest.kt @@ -13,11 +13,11 @@ internal class InboundEmailDeleteResponseTest { fun create() { val inboundEmailDeleteResponse = InboundEmailDeleteResponse.builder() - .msg("Mailbox deleted successfully") + .msg("Inbound email deleted successfully") .status("success") .build() - assertThat(inboundEmailDeleteResponse.msg()).contains("Mailbox deleted successfully") + assertThat(inboundEmailDeleteResponse.msg()).contains("Inbound email deleted successfully") assertThat(inboundEmailDeleteResponse.status()).contains("success") } @@ -26,7 +26,7 @@ internal class InboundEmailDeleteResponseTest { val jsonMapper = jsonMapper() val inboundEmailDeleteResponse = InboundEmailDeleteResponse.builder() - .msg("Mailbox deleted successfully") + .msg("Inbound email deleted successfully") .status("success") .build() From 016886138381f323c545c4847ffb4c4c0a9c1935 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 2 May 2026 11:18:11 +0000 Subject: [PATCH 88/99] feat(api): api update --- .stats.yml | 4 ++-- .../api/models/inboundemail/InboundEmailCreateResponse.kt | 8 ++++---- .../api/models/inboundemail/InboundEmailListResponse.kt | 8 ++++---- .../models/inboundemail/InboundEmailRetrieveResponse.kt | 8 ++++---- .../api/models/inbox/InboxListCasFilesResponse.kt | 8 ++++---- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/.stats.yml b/.stats.yml index cd58596..d224bd8 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 21 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser/cas-parser-c7cca9a7a8e15f8a584c22eab142c4af72a329117f63cc3b3f7cabb25410f2ce.yml -openapi_spec_hash: f40d936e433bbf8c98179d0b36f304c8 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser/cas-parser-0dce3ce202e44ecf2270f6ca42942cc297bbeeafddb3128f8230ba3ae85c7551.yml +openapi_spec_hash: e9cef5743f686d9f12910c81832accca config_hash: 5509bb7a961ae2e79114b24c381606d4 diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateResponse.kt index 77d0134..c3bf786 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateResponse.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateResponse.kt @@ -80,8 +80,8 @@ private constructor( allowedSources.getOptional("allowed_sources") /** - * Webhook URL for email notifications. Empty string (`""`) means files are only retrievable via - * `GET /v4/inbound-email/{id}/files` (SDK / pull mode). + * Webhook URL for email notifications. If set, we POST each parsed email here. If omitted, + * files are only retrievable via `GET /v4/inbound-email/{id}/files`. * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -293,8 +293,8 @@ private constructor( } /** - * Webhook URL for email notifications. Empty string (`""`) means files are only retrievable - * via `GET /v4/inbound-email/{id}/files` (SDK / pull mode). + * Webhook URL for email notifications. If set, we POST each parsed email here. If omitted, + * files are only retrievable via `GET /v4/inbound-email/{id}/files`. */ fun callbackUrl(callbackUrl: String) = callbackUrl(JsonField.of(callbackUrl)) diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailListResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailListResponse.kt index 9c8a3c0..17b898d 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailListResponse.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailListResponse.kt @@ -351,8 +351,8 @@ private constructor( allowedSources.getOptional("allowed_sources") /** - * Webhook URL for email notifications. Empty string (`""`) means files are only retrievable - * via `GET /v4/inbound-email/{id}/files` (SDK / pull mode). + * Webhook URL for email notifications. If set, we POST each parsed email here. If omitted, + * files are only retrievable via `GET /v4/inbound-email/{id}/files`. * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if * the server responded with an unexpected value). @@ -564,8 +564,8 @@ private constructor( } /** - * Webhook URL for email notifications. Empty string (`""`) means files are only - * retrievable via `GET /v4/inbound-email/{id}/files` (SDK / pull mode). + * Webhook URL for email notifications. If set, we POST each parsed email here. If + * omitted, files are only retrievable via `GET /v4/inbound-email/{id}/files`. */ fun callbackUrl(callbackUrl: String) = callbackUrl(JsonField.of(callbackUrl)) diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailRetrieveResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailRetrieveResponse.kt index 7521768..9b4c99a 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailRetrieveResponse.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailRetrieveResponse.kt @@ -80,8 +80,8 @@ private constructor( allowedSources.getOptional("allowed_sources") /** - * Webhook URL for email notifications. Empty string (`""`) means files are only retrievable via - * `GET /v4/inbound-email/{id}/files` (SDK / pull mode). + * Webhook URL for email notifications. If set, we POST each parsed email here. If omitted, + * files are only retrievable via `GET /v4/inbound-email/{id}/files`. * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -293,8 +293,8 @@ private constructor( } /** - * Webhook URL for email notifications. Empty string (`""`) means files are only retrievable - * via `GET /v4/inbound-email/{id}/files` (SDK / pull mode). + * Webhook URL for email notifications. If set, we POST each parsed email here. If omitted, + * files are only retrievable via `GET /v4/inbound-email/{id}/files`. */ fun callbackUrl(callbackUrl: String) = callbackUrl(JsonField.of(callbackUrl)) diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesResponse.kt index e4b8285..7ef110a 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesResponse.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesResponse.kt @@ -287,8 +287,8 @@ private constructor( /** * URL expiration time in seconds. Defaults vary by source: * - Gmail Inbox Import: 86400 (24h) - * - Inbound Email (webhook mode): 172800 (48h) - * - Inbound Email (SDK mode): aligned with the session TTL (~30 min) + * - Inbound Email with `callback_url` set: 172800 (48h) + * - Inbound Email without `callback_url`: aligned with the session TTL (~30 min) * * @throws CasParserInvalidDataException if the JSON field has an unexpected type (e.g. if * the server responded with an unexpected value). @@ -483,8 +483,8 @@ private constructor( /** * URL expiration time in seconds. Defaults vary by source: * - Gmail Inbox Import: 86400 (24h) - * - Inbound Email (webhook mode): 172800 (48h) - * - Inbound Email (SDK mode): aligned with the session TTL (~30 min) + * - Inbound Email with `callback_url` set: 172800 (48h) + * - Inbound Email without `callback_url`: aligned with the session TTL (~30 min) */ fun expiresIn(expiresIn: Long) = expiresIn(JsonField.of(expiresIn)) From e77af62bf1dd67c952870dfdddc7589c65de3692 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 2 May 2026 23:18:11 +0000 Subject: [PATCH 89/99] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index d224bd8..582a92c 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 21 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser/cas-parser-0dce3ce202e44ecf2270f6ca42942cc297bbeeafddb3128f8230ba3ae85c7551.yml -openapi_spec_hash: e9cef5743f686d9f12910c81832accca +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser/cas-parser-e572d88c2af6e4d7bc4f7e119357fd3f68b1e67d612fd1d3a657d916cde0087c.yml +openapi_spec_hash: a9fc7d947111bffa9184f8ca8be4a579 config_hash: 5509bb7a961ae2e79114b24c381606d4 From d561640ceb9aad0ab948800ec2e42f3c6f6b15cc Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 5 May 2026 03:54:07 +0000 Subject: [PATCH 90/99] docs: clarify forwards compat behavior --- README.md | 4 +- .../client/okhttp/CasParserOkHttpClient.kt | 3 + .../okhttp/CasParserOkHttpClientAsync.kt | 3 + .../com/cas_parser/api/core/ClientOptions.kt | 6 + .../com/cas_parser/api/core/RequestOptions.kt | 9 + .../accesstoken/AccessTokenCreateParams.kt | 9 + .../accesstoken/AccessTokenCreateResponse.kt | 8 + .../camskfintech/CamsKfintechParseParams.kt | 9 + .../api/models/camskfintech/LinkedHolder.kt | 8 + .../api/models/camskfintech/Transaction.kt | 26 ++ .../models/camskfintech/UnifiedResponse.kt | 361 ++++++++++++++++++ .../api/models/cdsl/CdslParsePdfParams.kt | 9 + .../cdsl/fetch/FetchRequestOtpParams.kt | 9 + .../cdsl/fetch/FetchRequestOtpResponse.kt | 8 + .../models/cdsl/fetch/FetchVerifyOtpParams.kt | 9 + .../cdsl/fetch/FetchVerifyOtpResponse.kt | 17 + .../contractnote/ContractNoteParseParams.kt | 18 + .../contractnote/ContractNoteParseResponse.kt | 97 +++++ .../api/models/credits/CreditCheckResponse.kt | 8 + .../inboundemail/InboundEmailCreateParams.kt | 27 ++ .../InboundEmailCreateResponse.kt | 35 ++ .../InboundEmailDeleteResponse.kt | 8 + .../inboundemail/InboundEmailListParams.kt | 9 + .../inboundemail/InboundEmailListResponse.kt | 47 +++ .../InboundEmailRetrieveResponse.kt | 35 ++ .../InboxCheckConnectionStatusResponse.kt | 8 + .../models/inbox/InboxConnectEmailParams.kt | 9 + .../models/inbox/InboxConnectEmailResponse.kt | 8 + .../inbox/InboxDisconnectEmailResponse.kt | 8 + .../models/inbox/InboxListCasFilesParams.kt | 18 + .../models/inbox/InboxListCasFilesResponse.kt | 27 ++ .../kfintech/KfintechGenerateCasParams.kt | 9 + .../kfintech/KfintechGenerateCasResponse.kt | 8 + .../api/models/logs/LogCreateParams.kt | 9 + .../api/models/logs/LogCreateResponse.kt | 17 + .../api/models/logs/LogGetSummaryParams.kt | 9 + .../api/models/logs/LogGetSummaryResponse.kt | 27 ++ .../api/models/nsdl/NsdlParseParams.kt | 9 + .../models/smart/SmartParseCasPdfParams.kt | 9 + .../verifytoken/VerifyTokenVerifyResponse.kt | 8 + 40 files changed, 964 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7e9b378..6665e07 100644 --- a/README.md +++ b/README.md @@ -562,7 +562,9 @@ In rare cases, the API may return a response that doesn't match the expected typ By default, the SDK will not throw an exception in this case. It will throw [`CasParserInvalidDataException`](cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/CasParserInvalidDataException.kt) only if you directly access the property. -If you would prefer to check that the response is completely well-typed upfront, then either call `validate()`: +Validating the response is _not_ forwards compatible with new types from the API for existing fields. + +If you would still prefer to check that the response is completely well-typed upfront, then either call `validate()`: ```java import com.cas_parser.api.models.credits.CreditCheckResponse; diff --git a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClient.kt b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClient.kt index e6b85dd..982e175 100644 --- a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClient.kt +++ b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClient.kt @@ -217,6 +217,9 @@ class CasParserOkHttpClient private constructor() { /** * Whether to call `validate` on every response before returning it. * + * Setting this to `true` is _not_ forwards compatible with new types from the API for + * existing fields. + * * Defaults to false, which means the shape of the response will not be validated upfront. * Instead, validation will only occur for the parts of the response that are accessed. */ diff --git a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClientAsync.kt b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClientAsync.kt index 71b4321..b3ef3ef 100644 --- a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClientAsync.kt +++ b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClientAsync.kt @@ -217,6 +217,9 @@ class CasParserOkHttpClientAsync private constructor() { /** * Whether to call `validate` on every response before returning it. * + * Setting this to `true` is _not_ forwards compatible with new types from the API for + * existing fields. + * * Defaults to false, which means the shape of the response will not be validated upfront. * Instead, validation will only occur for the parts of the response that are accessed. */ diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ClientOptions.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ClientOptions.kt index 4fb3496..2129ec2 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ClientOptions.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ClientOptions.kt @@ -66,6 +66,9 @@ private constructor( /** * Whether to call `validate` on every response before returning it. * + * Setting this to `true` is _not_ forwards compatible with new types from the API for existing + * fields. + * * Defaults to false, which means the shape of the response will not be validated upfront. * Instead, validation will only occur for the parts of the response that are accessed. */ @@ -230,6 +233,9 @@ private constructor( /** * Whether to call `validate` on every response before returning it. * + * Setting this to `true` is _not_ forwards compatible with new types from the API for + * existing fields. + * * Defaults to false, which means the shape of the response will not be validated upfront. * Instead, validation will only occur for the parts of the response that are accessed. */ diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/RequestOptions.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/RequestOptions.kt index 0232e87..b873e13 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/RequestOptions.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/RequestOptions.kt @@ -33,6 +33,15 @@ class RequestOptions private constructor(val responseValidation: Boolean?, val t private var responseValidation: Boolean? = null private var timeout: Timeout? = null + /** + * Whether to call `validate` on the response before returning it. + * + * Setting this to `true` is _not_ forwards compatible with new types from the API for + * existing fields. + * + * Defaults to false, which means the shape of the response will not be validated upfront. + * Instead, validation will only occur for the parts of the response that are accessed. + */ fun responseValidation(responseValidation: Boolean) = apply { this.responseValidation = responseValidation } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateParams.kt index 93daf86..d8e5a20 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateParams.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateParams.kt @@ -350,6 +350,15 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): Body = apply { if (validated) { return@apply diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateResponse.kt index a23d37b..00a9e51 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateResponse.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/accesstoken/AccessTokenCreateResponse.kt @@ -186,6 +186,14 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): AccessTokenCreateResponse = apply { if (validated) { return@apply diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/camskfintech/CamsKfintechParseParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/camskfintech/CamsKfintechParseParams.kt index 2b503a6..20c4db0 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/camskfintech/CamsKfintechParseParams.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/camskfintech/CamsKfintechParseParams.kt @@ -444,6 +444,15 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): Body = apply { if (validated) { return@apply diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/camskfintech/LinkedHolder.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/camskfintech/LinkedHolder.kt index 9aa025d..4ccd215 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/camskfintech/LinkedHolder.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/camskfintech/LinkedHolder.kt @@ -142,6 +142,14 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): LinkedHolder = apply { if (validated) { return@apply diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/camskfintech/Transaction.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/camskfintech/Transaction.kt index 64c2700..94bec94 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/camskfintech/Transaction.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/camskfintech/Transaction.kt @@ -433,6 +433,14 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): Transaction = apply { if (validated) { return@apply @@ -799,6 +807,15 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): AdditionalInfo = apply { if (validated) { return@apply @@ -1051,6 +1068,15 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): Type = apply { if (validated) { return@apply diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/camskfintech/UnifiedResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/camskfintech/UnifiedResponse.kt index 6a27c6f..cceadd0 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/camskfintech/UnifiedResponse.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/camskfintech/UnifiedResponse.kt @@ -342,6 +342,14 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): UnifiedResponse = apply { if (validated) { return@apply @@ -784,6 +792,15 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): DematAccount = apply { if (validated) { return@apply @@ -1200,6 +1217,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match + * its expected type. + */ fun validate(): AdditionalInfo = apply { if (validated) { return@apply @@ -1372,6 +1399,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match + * its expected type. + */ fun validate(): DematType = apply { if (validated) { return@apply @@ -1733,6 +1770,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match + * its expected type. + */ fun validate(): Holdings = apply { if (validated) { return@apply @@ -2076,6 +2123,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't + * match its expected type. + */ fun validate(): Aif = apply { if (validated) { return@apply @@ -2295,6 +2352,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected + * types recursively. + * + * This method is _not_ forwards compatible with new types from the API for + * existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object + * doesn't match its expected type. + */ fun validate(): AdditionalInfo = apply { if (validated) { return@apply @@ -2687,6 +2754,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't + * match its expected type. + */ fun validate(): CorporateBond = apply { if (validated) { return@apply @@ -2906,6 +2983,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected + * types recursively. + * + * This method is _not_ forwards compatible with new types from the API for + * existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object + * doesn't match its expected type. + */ fun validate(): AdditionalInfo = apply { if (validated) { return@apply @@ -3298,6 +3385,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't + * match its expected type. + */ fun validate(): DematMutualFund = apply { if (validated) { return@apply @@ -3517,6 +3614,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected + * types recursively. + * + * This method is _not_ forwards compatible with new types from the API for + * existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object + * doesn't match its expected type. + */ fun validate(): AdditionalInfo = apply { if (validated) { return@apply @@ -3907,6 +4014,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't + * match its expected type. + */ fun validate(): Equity = apply { if (validated) { return@apply @@ -4126,6 +4243,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected + * types recursively. + * + * This method is _not_ forwards compatible with new types from the API for + * existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object + * doesn't match its expected type. + */ fun validate(): AdditionalInfo = apply { if (validated) { return@apply @@ -4520,6 +4647,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't + * match its expected type. + */ fun validate(): GovernmentSecurity = apply { if (validated) { return@apply @@ -4739,6 +4876,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected + * types recursively. + * + * This method is _not_ forwards compatible with new types from the API for + * existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object + * doesn't match its expected type. + */ fun validate(): AdditionalInfo = apply { if (validated) { return@apply @@ -5013,6 +5160,15 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): Insurance = apply { if (validated) { return@apply @@ -5456,6 +5612,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match + * its expected type. + */ fun validate(): LifeInsurancePolicy = apply { if (validated) { return@apply @@ -5850,6 +6016,15 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): Investor = apply { if (validated) { return@apply @@ -6090,6 +6265,15 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): Meta = apply { if (validated) { return@apply @@ -6220,6 +6404,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match + * its expected type. + */ fun validate(): CasType = apply { if (validated) { return@apply @@ -6391,6 +6585,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match + * its expected type. + */ fun validate(): StatementPeriod = apply { if (validated) { return@apply @@ -6814,6 +7018,15 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): MutualFund = apply { if (validated) { return@apply @@ -7018,6 +7231,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match + * its expected type. + */ fun validate(): AdditionalInfo = apply { if (validated) { return@apply @@ -7552,6 +7775,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match + * its expected type. + */ fun validate(): Scheme = apply { if (validated) { return@apply @@ -7881,6 +8114,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't + * match its expected type. + */ fun validate(): AdditionalInfo = apply { if (validated) { return@apply @@ -8092,6 +8335,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't + * match its expected type. + */ fun validate(): Gain = apply { if (validated) { return@apply @@ -8247,6 +8500,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't + * match its expected type. + */ fun validate(): Type = apply { if (validated) { return@apply @@ -8649,6 +8912,15 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): Np = apply { if (validated) { return@apply @@ -8958,6 +9230,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match + * its expected type. + */ fun validate(): Fund = apply { if (validated) { return@apply @@ -9138,6 +9420,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't + * match its expected type. + */ fun validate(): AdditionalInfo = apply { if (validated) { return@apply @@ -9258,6 +9550,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected + * types recursively. + * + * This method is _not_ forwards compatible with new types from the API for + * existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object + * doesn't match its expected type. + */ fun validate(): Tier = apply { if (validated) { return@apply @@ -9509,6 +9811,15 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): Summary = apply { if (validated) { return@apply @@ -9741,6 +10052,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match + * its expected type. + */ fun validate(): Accounts = apply { if (validated) { return@apply @@ -9917,6 +10238,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't + * match its expected type. + */ fun validate(): Demat = apply { if (validated) { return@apply @@ -10110,6 +10441,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't + * match its expected type. + */ fun validate(): Insurance = apply { if (validated) { return@apply @@ -10303,6 +10644,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't + * match its expected type. + */ fun validate(): MutualFunds = apply { if (validated) { return@apply @@ -10495,6 +10846,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't + * match its expected type. + */ fun validate(): Nps = apply { if (validated) { return@apply diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/cdsl/CdslParsePdfParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/cdsl/CdslParsePdfParams.kt index e9440f6..81df339 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/cdsl/CdslParsePdfParams.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/cdsl/CdslParsePdfParams.kt @@ -443,6 +443,15 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): Body = apply { if (validated) { return@apply diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchRequestOtpParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchRequestOtpParams.kt index 34b641d..e1509fd 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchRequestOtpParams.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchRequestOtpParams.kt @@ -492,6 +492,15 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): Body = apply { if (validated) { return@apply diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchRequestOtpResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchRequestOtpResponse.kt index cf0cf74..12de1bb 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchRequestOtpResponse.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchRequestOtpResponse.kt @@ -168,6 +168,14 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): FetchRequestOtpResponse = apply { if (validated) { return@apply diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchVerifyOtpParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchVerifyOtpParams.kt index 854f921..0a81238 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchVerifyOtpParams.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchVerifyOtpParams.kt @@ -438,6 +438,15 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): Body = apply { if (validated) { return@apply diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchVerifyOtpResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchVerifyOtpResponse.kt index 2e72418..49d6bdf 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchVerifyOtpResponse.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/cdsl/fetch/FetchVerifyOtpResponse.kt @@ -185,6 +185,14 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): FetchVerifyOtpResponse = apply { if (validated) { return@apply @@ -343,6 +351,15 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): File = apply { if (validated) { return@apply diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/contractnote/ContractNoteParseParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/contractnote/ContractNoteParseParams.kt index 6c6ee9e..eee36e7 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/contractnote/ContractNoteParseParams.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/contractnote/ContractNoteParseParams.kt @@ -539,6 +539,15 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): Body = apply { if (validated) { return@apply @@ -686,6 +695,15 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): BrokerType = apply { if (validated) { return@apply diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/contractnote/ContractNoteParseResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/contractnote/ContractNoteParseResponse.kt index 370d8b0..9f81c80 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/contractnote/ContractNoteParseResponse.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/contractnote/ContractNoteParseResponse.kt @@ -171,6 +171,14 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): ContractNoteParseResponse = apply { if (validated) { return@apply @@ -592,6 +600,15 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): Data = apply { if (validated) { return@apply @@ -817,6 +834,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match + * its expected type. + */ fun validate(): BrokerInfo = apply { if (validated) { return@apply @@ -961,6 +988,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't + * match its expected type. + */ fun validate(): BrokerType = apply { if (validated) { return@apply @@ -1488,6 +1525,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match + * its expected type. + */ fun validate(): ChargesSummary = apply { if (validated) { return@apply @@ -1856,6 +1903,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match + * its expected type. + */ fun validate(): ClientInfo = apply { if (validated) { return@apply @@ -2167,6 +2224,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match + * its expected type. + */ fun validate(): ContractNoteInfo = apply { if (validated) { return@apply @@ -2586,6 +2653,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match + * its expected type. + */ fun validate(): DerivativesTransaction = apply { if (validated) { return@apply @@ -3232,6 +3309,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match + * its expected type. + */ fun validate(): DetailedTrade = apply { if (validated) { return@apply @@ -3792,6 +3879,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match + * its expected type. + */ fun validate(): EquityTransaction = apply { if (validated) { return@apply diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/credits/CreditCheckResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/credits/CreditCheckResponse.kt index 6a3f1a3..c5f263b 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/credits/CreditCheckResponse.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/credits/CreditCheckResponse.kt @@ -317,6 +317,14 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): CreditCheckResponse = apply { if (validated) { return@apply diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateParams.kt index 54b1e1c..d042ab7 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateParams.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateParams.kt @@ -694,6 +694,15 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): Body = apply { if (validated) { return@apply @@ -865,6 +874,15 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): AllowedSource = apply { if (validated) { return@apply @@ -965,6 +983,15 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): Metadata = apply { if (validated) { return@apply diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateResponse.kt index c3bf786..9ef158d 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateResponse.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailCreateResponse.kt @@ -435,6 +435,14 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): InboundEmailCreateResponse = apply { if (validated) { return@apply @@ -582,6 +590,15 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): AllowedSource = apply { if (validated) { return@apply @@ -679,6 +696,15 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): Metadata = apply { if (validated) { return@apply @@ -810,6 +836,15 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): Status = apply { if (validated) { return@apply diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailDeleteResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailDeleteResponse.kt index 332967a..a5ed525 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailDeleteResponse.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailDeleteResponse.kt @@ -139,6 +139,14 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): InboundEmailDeleteResponse = apply { if (validated) { return@apply diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailListParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailListParams.kt index aadb63b..8b77162 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailListParams.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailListParams.kt @@ -322,6 +322,15 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): Status = apply { if (validated) { return@apply diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailListResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailListResponse.kt index 17b898d..e6f0048 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailListResponse.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailListResponse.kt @@ -253,6 +253,14 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): InboundEmailListResponse = apply { if (validated) { return@apply @@ -715,6 +723,15 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): InboundEmail = apply { if (validated) { return@apply @@ -863,6 +880,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match + * its expected type. + */ fun validate(): AllowedSource = apply { if (validated) { return@apply @@ -963,6 +990,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match + * its expected type. + */ fun validate(): Metadata = apply { if (validated) { return@apply @@ -1096,6 +1133,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match + * its expected type. + */ fun validate(): Status = apply { if (validated) { return@apply diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailRetrieveResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailRetrieveResponse.kt index 9b4c99a..3bbfbd9 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailRetrieveResponse.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inboundemail/InboundEmailRetrieveResponse.kt @@ -435,6 +435,14 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): InboundEmailRetrieveResponse = apply { if (validated) { return@apply @@ -582,6 +590,15 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): AllowedSource = apply { if (validated) { return@apply @@ -679,6 +696,15 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): Metadata = apply { if (validated) { return@apply @@ -810,6 +836,15 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): Status = apply { if (validated) { return@apply diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxCheckConnectionStatusResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxCheckConnectionStatusResponse.kt index dad4ab0..585828e 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxCheckConnectionStatusResponse.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxCheckConnectionStatusResponse.kt @@ -209,6 +209,14 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): InboxCheckConnectionStatusResponse = apply { if (validated) { return@apply diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxConnectEmailParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxConnectEmailParams.kt index dc2c277..12bb059 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxConnectEmailParams.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxConnectEmailParams.kt @@ -440,6 +440,15 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): Body = apply { if (validated) { return@apply diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxConnectEmailResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxConnectEmailResponse.kt index 4511a59..968248e 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxConnectEmailResponse.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxConnectEmailResponse.kt @@ -177,6 +177,14 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): InboxConnectEmailResponse = apply { if (validated) { return@apply diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxDisconnectEmailResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxDisconnectEmailResponse.kt index 0214edc..48cb354 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxDisconnectEmailResponse.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxDisconnectEmailResponse.kt @@ -139,6 +139,14 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): InboxDisconnectEmailResponse = apply { if (validated) { return@apply diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesParams.kt index b3c976d..aa23aae 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesParams.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesParams.kt @@ -543,6 +543,15 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): Body = apply { if (validated) { return@apply @@ -697,6 +706,15 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): CasType = apply { if (validated) { return@apply diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesResponse.kt index 7ef110a..2240910 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesResponse.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/inbox/InboxListCasFilesResponse.kt @@ -192,6 +192,14 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): InboxListCasFilesResponse = apply { if (validated) { return@apply @@ -632,6 +640,15 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): File = apply { if (validated) { return@apply @@ -780,6 +797,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match + * its expected type. + */ fun validate(): CasType = apply { if (validated) { return@apply diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/kfintech/KfintechGenerateCasParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/kfintech/KfintechGenerateCasParams.kt index 87b8b15..b8a20e9 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/kfintech/KfintechGenerateCasParams.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/kfintech/KfintechGenerateCasParams.kt @@ -616,6 +616,15 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): Body = apply { if (validated) { return@apply diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/kfintech/KfintechGenerateCasResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/kfintech/KfintechGenerateCasResponse.kt index 40e0359..e1d5883 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/kfintech/KfintechGenerateCasResponse.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/kfintech/KfintechGenerateCasResponse.kt @@ -139,6 +139,14 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): KfintechGenerateCasResponse = apply { if (validated) { return@apply diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogCreateParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogCreateParams.kt index b5db085..fbd9946 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogCreateParams.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogCreateParams.kt @@ -459,6 +459,15 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): Body = apply { if (validated) { return@apply diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogCreateResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogCreateResponse.kt index b77a776..e545f51 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogCreateResponse.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogCreateResponse.kt @@ -185,6 +185,14 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): LogCreateResponse = apply { if (validated) { return@apply @@ -487,6 +495,15 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): Log = apply { if (validated) { return@apply diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogGetSummaryParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogGetSummaryParams.kt index 28648da..b645d12 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogGetSummaryParams.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogGetSummaryParams.kt @@ -404,6 +404,15 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): Body = apply { if (validated) { return@apply diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogGetSummaryResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogGetSummaryResponse.kt index a78d1ba..892fb73 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogGetSummaryResponse.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/logs/LogGetSummaryResponse.kt @@ -140,6 +140,14 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): LogGetSummaryResponse = apply { if (validated) { return@apply @@ -366,6 +374,15 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): Summary = apply { if (validated) { return@apply @@ -568,6 +585,16 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match + * its expected type. + */ fun validate(): ByFeature = apply { if (validated) { return@apply diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/nsdl/NsdlParseParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/nsdl/NsdlParseParams.kt index 240f71c..96eb267 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/nsdl/NsdlParseParams.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/nsdl/NsdlParseParams.kt @@ -439,6 +439,15 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): Body = apply { if (validated) { return@apply diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/smart/SmartParseCasPdfParams.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/smart/SmartParseCasPdfParams.kt index cbfbeb1..730a047 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/smart/SmartParseCasPdfParams.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/smart/SmartParseCasPdfParams.kt @@ -444,6 +444,15 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): Body = apply { if (validated) { return@apply diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyResponse.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyResponse.kt index b8859a0..f34e4bd 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyResponse.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/models/verifytoken/VerifyTokenVerifyResponse.kt @@ -187,6 +187,14 @@ private constructor( private var validated: Boolean = false + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CasParserInvalidDataException if any value type in this object doesn't match its + * expected type. + */ fun validate(): VerifyTokenVerifyResponse = apply { if (validated) { return@apply From 005a34fb21e955a38abd6532a083dd557d006ab4 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 5 May 2026 03:56:05 +0000 Subject: [PATCH 91/99] feat(client): more robust error parsing --- .../com/cas_parser/api/errors/BadRequestException.kt | 6 +++++- .../com/cas_parser/api/errors/InternalServerException.kt | 7 ++++++- .../kotlin/com/cas_parser/api/errors/NotFoundException.kt | 6 +++++- .../com/cas_parser/api/errors/PermissionDeniedException.kt | 6 +++++- .../kotlin/com/cas_parser/api/errors/RateLimitException.kt | 6 +++++- .../com/cas_parser/api/errors/UnauthorizedException.kt | 6 +++++- .../cas_parser/api/errors/UnexpectedStatusCodeException.kt | 7 ++++++- .../cas_parser/api/errors/UnprocessableEntityException.kt | 6 +++++- 8 files changed, 42 insertions(+), 8 deletions(-) diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/BadRequestException.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/BadRequestException.kt index a0737dc..074ca61 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/BadRequestException.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/BadRequestException.kt @@ -5,12 +5,16 @@ package com.cas_parser.api.errors import com.cas_parser.api.core.JsonValue import com.cas_parser.api.core.checkRequired import com.cas_parser.api.core.http.Headers +import com.cas_parser.api.core.jsonMapper import java.util.Optional import kotlin.jvm.optionals.getOrNull class BadRequestException private constructor(private val headers: Headers, private val body: JsonValue, cause: Throwable?) : - CasParserServiceException("400: $body", cause) { + CasParserServiceException( + "400: ${if (body.isMissing()) "Unknown" else jsonMapper().writeValueAsString(body)}", + cause, + ) { override fun statusCode(): Int = 400 diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/InternalServerException.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/InternalServerException.kt index ec2af8e..75987e6 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/InternalServerException.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/InternalServerException.kt @@ -5,6 +5,7 @@ package com.cas_parser.api.errors import com.cas_parser.api.core.JsonValue import com.cas_parser.api.core.checkRequired import com.cas_parser.api.core.http.Headers +import com.cas_parser.api.core.jsonMapper import java.util.Optional import kotlin.jvm.optionals.getOrNull @@ -14,7 +15,11 @@ private constructor( private val headers: Headers, private val body: JsonValue, cause: Throwable?, -) : CasParserServiceException("$statusCode: $body", cause) { +) : + CasParserServiceException( + "$statusCode: ${if (body.isMissing()) "Unknown" else jsonMapper().writeValueAsString(body)}", + cause, + ) { override fun statusCode(): Int = statusCode diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/NotFoundException.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/NotFoundException.kt index c01b9dd..6856cd6 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/NotFoundException.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/NotFoundException.kt @@ -5,12 +5,16 @@ package com.cas_parser.api.errors import com.cas_parser.api.core.JsonValue import com.cas_parser.api.core.checkRequired import com.cas_parser.api.core.http.Headers +import com.cas_parser.api.core.jsonMapper import java.util.Optional import kotlin.jvm.optionals.getOrNull class NotFoundException private constructor(private val headers: Headers, private val body: JsonValue, cause: Throwable?) : - CasParserServiceException("404: $body", cause) { + CasParserServiceException( + "404: ${if (body.isMissing()) "Unknown" else jsonMapper().writeValueAsString(body)}", + cause, + ) { override fun statusCode(): Int = 404 diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/PermissionDeniedException.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/PermissionDeniedException.kt index 520a46f..bb97c2e 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/PermissionDeniedException.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/PermissionDeniedException.kt @@ -5,12 +5,16 @@ package com.cas_parser.api.errors import com.cas_parser.api.core.JsonValue import com.cas_parser.api.core.checkRequired import com.cas_parser.api.core.http.Headers +import com.cas_parser.api.core.jsonMapper import java.util.Optional import kotlin.jvm.optionals.getOrNull class PermissionDeniedException private constructor(private val headers: Headers, private val body: JsonValue, cause: Throwable?) : - CasParserServiceException("403: $body", cause) { + CasParserServiceException( + "403: ${if (body.isMissing()) "Unknown" else jsonMapper().writeValueAsString(body)}", + cause, + ) { override fun statusCode(): Int = 403 diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/RateLimitException.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/RateLimitException.kt index 10c79f3..c14384b 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/RateLimitException.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/RateLimitException.kt @@ -5,12 +5,16 @@ package com.cas_parser.api.errors import com.cas_parser.api.core.JsonValue import com.cas_parser.api.core.checkRequired import com.cas_parser.api.core.http.Headers +import com.cas_parser.api.core.jsonMapper import java.util.Optional import kotlin.jvm.optionals.getOrNull class RateLimitException private constructor(private val headers: Headers, private val body: JsonValue, cause: Throwable?) : - CasParserServiceException("429: $body", cause) { + CasParserServiceException( + "429: ${if (body.isMissing()) "Unknown" else jsonMapper().writeValueAsString(body)}", + cause, + ) { override fun statusCode(): Int = 429 diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/UnauthorizedException.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/UnauthorizedException.kt index 290a3e7..3d9e25a 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/UnauthorizedException.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/UnauthorizedException.kt @@ -5,12 +5,16 @@ package com.cas_parser.api.errors import com.cas_parser.api.core.JsonValue import com.cas_parser.api.core.checkRequired import com.cas_parser.api.core.http.Headers +import com.cas_parser.api.core.jsonMapper import java.util.Optional import kotlin.jvm.optionals.getOrNull class UnauthorizedException private constructor(private val headers: Headers, private val body: JsonValue, cause: Throwable?) : - CasParserServiceException("401: $body", cause) { + CasParserServiceException( + "401: ${if (body.isMissing()) "Unknown" else jsonMapper().writeValueAsString(body)}", + cause, + ) { override fun statusCode(): Int = 401 diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/UnexpectedStatusCodeException.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/UnexpectedStatusCodeException.kt index 55a37fe..2ea9523 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/UnexpectedStatusCodeException.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/UnexpectedStatusCodeException.kt @@ -5,6 +5,7 @@ package com.cas_parser.api.errors import com.cas_parser.api.core.JsonValue import com.cas_parser.api.core.checkRequired import com.cas_parser.api.core.http.Headers +import com.cas_parser.api.core.jsonMapper import java.util.Optional import kotlin.jvm.optionals.getOrNull @@ -14,7 +15,11 @@ private constructor( private val headers: Headers, private val body: JsonValue, cause: Throwable?, -) : CasParserServiceException("$statusCode: $body", cause) { +) : + CasParserServiceException( + "$statusCode: ${if (body.isMissing()) "Unknown" else jsonMapper().writeValueAsString(body)}", + cause, + ) { override fun statusCode(): Int = statusCode diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/UnprocessableEntityException.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/UnprocessableEntityException.kt index 678980c..a6a9f9a 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/UnprocessableEntityException.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/errors/UnprocessableEntityException.kt @@ -5,12 +5,16 @@ package com.cas_parser.api.errors import com.cas_parser.api.core.JsonValue import com.cas_parser.api.core.checkRequired import com.cas_parser.api.core.http.Headers +import com.cas_parser.api.core.jsonMapper import java.util.Optional import kotlin.jvm.optionals.getOrNull class UnprocessableEntityException private constructor(private val headers: Headers, private val body: JsonValue, cause: Throwable?) : - CasParserServiceException("422: $body", cause) { + CasParserServiceException( + "422: ${if (body.isMissing()) "Unknown" else jsonMapper().writeValueAsString(body)}", + cause, + ) { override fun statusCode(): Int = 422 From 6700189ea3680afc75996f8a4081be58efae11c0 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 5 May 2026 04:00:17 +0000 Subject: [PATCH 92/99] chore: remove duplicated dokka setup --- build.gradle.kts | 1 - 1 file changed, 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 8f7d82f..794ef23 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -22,7 +22,6 @@ subprojects { group = "Verification" description = "Verifies all source files are formatted." } - apply(plugin = "org.jetbrains.dokka") } subprojects { From b6b5359dc3d4503a11ab6499e2fe1be1921b718c Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 5 May 2026 04:02:46 +0000 Subject: [PATCH 93/99] perf(client): create one json mapper --- .../src/main/kotlin/com/cas_parser/api/core/ObjectMappers.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ObjectMappers.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ObjectMappers.kt index e067f70..0c4aadd 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ObjectMappers.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ObjectMappers.kt @@ -29,7 +29,9 @@ import java.time.ZoneId import java.time.format.DateTimeFormatter import java.time.temporal.ChronoField -fun jsonMapper(): JsonMapper = +fun jsonMapper(): JsonMapper = JSON_MAPPER + +private val JSON_MAPPER: JsonMapper = JsonMapper.builder() .addModule(kotlinModule()) .addModule(Jdk8Module()) From cf68ae8d1a96441f8aebdea0d456ad7c1b433e46 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 6 May 2026 04:16:55 +0000 Subject: [PATCH 94/99] feat(client): support proxy authentication --- README.md | 15 ++ .../client/okhttp/CasParserOkHttpClient.kt | 17 ++ .../okhttp/CasParserOkHttpClientAsync.kt | 17 ++ .../api/client/okhttp/OkHttpClient.kt | 234 +++++++++++------- .../api/core/http/ProxyAuthenticator.kt | 59 +++++ 5 files changed, 257 insertions(+), 85 deletions(-) create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/ProxyAuthenticator.kt diff --git a/README.md b/README.md index 6665e07..976361d 100644 --- a/README.md +++ b/README.md @@ -342,6 +342,21 @@ CasParserClient client = CasParserOkHttpClient.builder() .build(); ``` +If the proxy responds with `407 Proxy Authentication Required`, supply credentials by also configuring `proxyAuthenticator`: + +```java +import com.cas_parser.api.client.CasParserClient; +import com.cas_parser.api.client.okhttp.CasParserOkHttpClient; +import com.cas_parser.api.core.http.ProxyAuthenticator; + +CasParserClient client = CasParserOkHttpClient.builder() + .fromEnv() + .proxy(...) + // Or a custom implementation of `ProxyAuthenticator`. + .proxyAuthenticator(ProxyAuthenticator.basic("username", "password")) + .build(); +``` + ### Connection pooling To customize the underlying OkHttp connection pool, configure the client using the `maxIdleConnections` and `keepAliveDuration` methods: diff --git a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClient.kt b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClient.kt index 982e175..4446514 100644 --- a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClient.kt +++ b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClient.kt @@ -9,6 +9,7 @@ import com.cas_parser.api.core.Sleeper import com.cas_parser.api.core.Timeout import com.cas_parser.api.core.http.Headers import com.cas_parser.api.core.http.HttpClient +import com.cas_parser.api.core.http.ProxyAuthenticator import com.cas_parser.api.core.http.QueryParams import com.cas_parser.api.core.jsonMapper import com.fasterxml.jackson.databind.json.JsonMapper @@ -47,6 +48,7 @@ class CasParserOkHttpClient private constructor() { private var clientOptions: ClientOptions.Builder = ClientOptions.builder() private var dispatcherExecutorService: ExecutorService? = null private var proxy: Proxy? = null + private var proxyAuthenticator: ProxyAuthenticator? = null private var maxIdleConnections: Int? = null private var keepAliveDuration: Duration? = null private var sslSocketFactory: SSLSocketFactory? = null @@ -77,6 +79,20 @@ class CasParserOkHttpClient private constructor() { /** Alias for calling [Builder.proxy] with `proxy.orElse(null)`. */ fun proxy(proxy: Optional) = proxy(proxy.getOrNull()) + /** + * Provides credentials when an HTTP proxy responds with `407 Proxy Authentication + * Required`. + */ + fun proxyAuthenticator(proxyAuthenticator: ProxyAuthenticator?) = apply { + this.proxyAuthenticator = proxyAuthenticator + } + + /** + * Alias for calling [Builder.proxyAuthenticator] with `proxyAuthenticator.orElse(null)`. + */ + fun proxyAuthenticator(proxyAuthenticator: Optional) = + proxyAuthenticator(proxyAuthenticator.getOrNull()) + /** * The maximum number of idle connections kept by the underlying OkHttp connection pool. * @@ -363,6 +379,7 @@ class CasParserOkHttpClient private constructor() { OkHttpClient.builder() .timeout(clientOptions.timeout()) .proxy(proxy) + .proxyAuthenticator(proxyAuthenticator) .maxIdleConnections(maxIdleConnections) .keepAliveDuration(keepAliveDuration) .dispatcherExecutorService(dispatcherExecutorService) diff --git a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClientAsync.kt b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClientAsync.kt index b3ef3ef..2b7f952 100644 --- a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClientAsync.kt +++ b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClientAsync.kt @@ -9,6 +9,7 @@ import com.cas_parser.api.core.Sleeper import com.cas_parser.api.core.Timeout import com.cas_parser.api.core.http.Headers import com.cas_parser.api.core.http.HttpClient +import com.cas_parser.api.core.http.ProxyAuthenticator import com.cas_parser.api.core.http.QueryParams import com.cas_parser.api.core.jsonMapper import com.fasterxml.jackson.databind.json.JsonMapper @@ -47,6 +48,7 @@ class CasParserOkHttpClientAsync private constructor() { private var clientOptions: ClientOptions.Builder = ClientOptions.builder() private var dispatcherExecutorService: ExecutorService? = null private var proxy: Proxy? = null + private var proxyAuthenticator: ProxyAuthenticator? = null private var maxIdleConnections: Int? = null private var keepAliveDuration: Duration? = null private var sslSocketFactory: SSLSocketFactory? = null @@ -77,6 +79,20 @@ class CasParserOkHttpClientAsync private constructor() { /** Alias for calling [Builder.proxy] with `proxy.orElse(null)`. */ fun proxy(proxy: Optional) = proxy(proxy.getOrNull()) + /** + * Provides credentials when an HTTP proxy responds with `407 Proxy Authentication + * Required`. + */ + fun proxyAuthenticator(proxyAuthenticator: ProxyAuthenticator?) = apply { + this.proxyAuthenticator = proxyAuthenticator + } + + /** + * Alias for calling [Builder.proxyAuthenticator] with `proxyAuthenticator.orElse(null)`. + */ + fun proxyAuthenticator(proxyAuthenticator: Optional) = + proxyAuthenticator(proxyAuthenticator.getOrNull()) + /** * The maximum number of idle connections kept by the underlying OkHttp connection pool. * @@ -363,6 +379,7 @@ class CasParserOkHttpClientAsync private constructor() { OkHttpClient.builder() .timeout(clientOptions.timeout()) .proxy(proxy) + .proxyAuthenticator(proxyAuthenticator) .maxIdleConnections(maxIdleConnections) .keepAliveDuration(keepAliveDuration) .dispatcherExecutorService(dispatcherExecutorService) diff --git a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/OkHttpClient.kt b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/OkHttpClient.kt index 7bc37ab..0630211 100644 --- a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/OkHttpClient.kt +++ b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/OkHttpClient.kt @@ -8,9 +8,11 @@ import com.cas_parser.api.core.http.HttpMethod import com.cas_parser.api.core.http.HttpRequest import com.cas_parser.api.core.http.HttpRequestBody import com.cas_parser.api.core.http.HttpResponse +import com.cas_parser.api.core.http.ProxyAuthenticator import com.cas_parser.api.errors.CasParserIoException import java.io.IOException import java.io.InputStream +import java.io.OutputStream import java.net.Proxy import java.time.Duration import java.util.concurrent.CancellationException @@ -20,10 +22,12 @@ import java.util.concurrent.TimeUnit import javax.net.ssl.HostnameVerifier import javax.net.ssl.SSLSocketFactory import javax.net.ssl.X509TrustManager +import kotlin.jvm.optionals.getOrNull import okhttp3.Call import okhttp3.Callback import okhttp3.ConnectionPool import okhttp3.Dispatcher +import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.MediaType import okhttp3.MediaType.Companion.toMediaType @@ -33,6 +37,8 @@ import okhttp3.RequestBody.Companion.toRequestBody import okhttp3.Response import okhttp3.logging.HttpLoggingInterceptor import okio.BufferedSink +import okio.buffer +import okio.sink class OkHttpClient internal constructor(@JvmSynthetic internal val okHttpClient: okhttp3.OkHttpClient) : HttpClient { @@ -41,7 +47,7 @@ internal constructor(@JvmSynthetic internal val okHttpClient: okhttp3.OkHttpClie val call = newCall(request, requestOptions) return try { - call.execute().toResponse() + call.execute().toHttpResponse() } catch (e: IOException) { throw CasParserIoException("Request failed", e) } finally { @@ -59,7 +65,7 @@ internal constructor(@JvmSynthetic internal val okHttpClient: okhttp3.OkHttpClie call.enqueue( object : Callback { override fun onResponse(call: Call, response: Response) { - future.complete(response.toResponse()) + future.complete(response.toHttpResponse()) } override fun onFailure(call: Call, e: IOException) { @@ -111,89 +117,6 @@ internal constructor(@JvmSynthetic internal val okHttpClient: okhttp3.OkHttpClie return client.newCall(request.toRequest(client)) } - private fun HttpRequest.toRequest(client: okhttp3.OkHttpClient): Request { - var body: RequestBody? = body?.toRequestBody() - if (body == null && requiresBody(method)) { - body = "".toRequestBody() - } - - val builder = Request.Builder().url(toUrl()).method(method.name, body) - headers.names().forEach { name -> - headers.values(name).forEach { builder.addHeader(name, it) } - } - - if ( - !headers.names().contains("X-Stainless-Read-Timeout") && client.readTimeoutMillis != 0 - ) { - builder.addHeader( - "X-Stainless-Read-Timeout", - Duration.ofMillis(client.readTimeoutMillis.toLong()).seconds.toString(), - ) - } - if (!headers.names().contains("X-Stainless-Timeout") && client.callTimeoutMillis != 0) { - builder.addHeader( - "X-Stainless-Timeout", - Duration.ofMillis(client.callTimeoutMillis.toLong()).seconds.toString(), - ) - } - - return builder.build() - } - - /** `OkHttpClient` always requires a request body for some methods. */ - private fun requiresBody(method: HttpMethod): Boolean = - when (method) { - HttpMethod.POST, - HttpMethod.PUT, - HttpMethod.PATCH -> true - else -> false - } - - private fun HttpRequest.toUrl(): String { - val builder = baseUrl.toHttpUrl().newBuilder() - pathSegments.forEach(builder::addPathSegment) - queryParams.keys().forEach { key -> - queryParams.values(key).forEach { builder.addQueryParameter(key, it) } - } - - return builder.toString() - } - - private fun HttpRequestBody.toRequestBody(): RequestBody { - val mediaType = contentType()?.toMediaType() - val length = contentLength() - - return object : RequestBody() { - override fun contentType(): MediaType? = mediaType - - override fun contentLength(): Long = length - - override fun isOneShot(): Boolean = !repeatable() - - override fun writeTo(sink: BufferedSink) = writeTo(sink.outputStream()) - } - } - - private fun Response.toResponse(): HttpResponse { - val headers = headers.toHeaders() - - return object : HttpResponse { - override fun statusCode(): Int = code - - override fun headers(): Headers = headers - - override fun body(): InputStream = body!!.byteStream() - - override fun close() = body!!.close() - } - } - - private fun okhttp3.Headers.toHeaders(): Headers { - val headersBuilder = Headers.builder() - forEach { (name, value) -> headersBuilder.put(name, value) } - return headersBuilder.build() - } - companion object { @JvmStatic fun builder() = Builder() } @@ -202,6 +125,7 @@ internal constructor(@JvmSynthetic internal val okHttpClient: okhttp3.OkHttpClie private var timeout: Timeout = Timeout.default() private var proxy: Proxy? = null + private var proxyAuthenticator: ProxyAuthenticator? = null private var maxIdleConnections: Int? = null private var keepAliveDuration: Duration? = null private var dispatcherExecutorService: ExecutorService? = null @@ -215,6 +139,10 @@ internal constructor(@JvmSynthetic internal val okHttpClient: okhttp3.OkHttpClie fun proxy(proxy: Proxy?) = apply { this.proxy = proxy } + fun proxyAuthenticator(proxyAuthenticator: ProxyAuthenticator?) = apply { + this.proxyAuthenticator = proxyAuthenticator + } + /** * Sets the maximum number of idle connections kept by the underlying [ConnectionPool]. * @@ -264,6 +192,19 @@ internal constructor(@JvmSynthetic internal val okHttpClient: okhttp3.OkHttpClie .callTimeout(timeout.request()) .proxy(proxy) .apply { + proxyAuthenticator?.let { auth -> + proxyAuthenticator { route, response -> + auth + .authenticate( + route?.proxy ?: Proxy.NO_PROXY, + response.request.toHttpRequest(), + response.toHttpResponse(), + ) + .getOrNull() + ?.toRequest(client = null) + } + } + dispatcherExecutorService?.let { dispatcher(Dispatcher(it)) } val maxIdleConnections = maxIdleConnections @@ -303,3 +244,126 @@ internal constructor(@JvmSynthetic internal val okHttpClient: okhttp3.OkHttpClie ) } } + +private fun HttpRequest.toRequest(client: okhttp3.OkHttpClient?): Request { + var body: RequestBody? = body?.toRequestBody() + if (body == null && requiresBody(method)) { + body = "".toRequestBody() + } + + val builder = Request.Builder().url(toUrl()).method(method.name, body) + headers.names().forEach { name -> headers.values(name).forEach { builder.addHeader(name, it) } } + + if (client != null) { + if ( + !headers.names().contains("X-Stainless-Read-Timeout") && client.readTimeoutMillis != 0 + ) { + builder.addHeader( + "X-Stainless-Read-Timeout", + Duration.ofMillis(client.readTimeoutMillis.toLong()).seconds.toString(), + ) + } + if (!headers.names().contains("X-Stainless-Timeout") && client.callTimeoutMillis != 0) { + builder.addHeader( + "X-Stainless-Timeout", + Duration.ofMillis(client.callTimeoutMillis.toLong()).seconds.toString(), + ) + } + } + + return builder.build() +} + +/** `OkHttpClient` always requires a request body for some methods. */ +private fun requiresBody(method: HttpMethod): Boolean = + when (method) { + HttpMethod.POST, + HttpMethod.PUT, + HttpMethod.PATCH -> true + else -> false + } + +private fun HttpRequest.toUrl(): String { + val builder = baseUrl.toHttpUrl().newBuilder() + pathSegments.forEach(builder::addPathSegment) + queryParams.keys().forEach { key -> + queryParams.values(key).forEach { builder.addQueryParameter(key, it) } + } + + return builder.toString() +} + +private fun HttpRequestBody.toRequestBody(): RequestBody { + val mediaType = contentType()?.toMediaType() + val length = contentLength() + + return object : RequestBody() { + override fun contentType(): MediaType? = mediaType + + override fun contentLength(): Long = length + + override fun isOneShot(): Boolean = !repeatable() + + override fun writeTo(sink: BufferedSink) = writeTo(sink.outputStream()) + } +} + +private fun Request.toHttpRequest(): HttpRequest { + val builder = HttpRequest.builder().method(HttpMethod.valueOf(method)).baseUrl(url.toBaseUrl()) + url.pathSegments.forEach(builder::addPathSegment) + url.queryParameterNames.forEach { name -> + url.queryParameterValues(name).filterNotNull().forEach { builder.putQueryParam(name, it) } + } + headers.forEach { (name, value) -> builder.putHeader(name, value) } + body?.let { builder.body(it.toHttpRequestBody()) } + return builder.build() +} + +private fun HttpUrl.toBaseUrl(): String = buildString { + append(scheme).append("://").append(host) + if (port != HttpUrl.defaultPort(scheme)) { + append(":").append(port) + } +} + +private fun RequestBody.toHttpRequestBody(): HttpRequestBody { + val mediaType = contentType()?.toString() + val length = contentLength() + val isOneShot = isOneShot() + val source = this + return object : HttpRequestBody { + override fun contentType(): String? = mediaType + + override fun contentLength(): Long = length + + override fun repeatable(): Boolean = !isOneShot + + override fun writeTo(outputStream: OutputStream) { + val sink = outputStream.sink().buffer() + source.writeTo(sink) + sink.flush() + } + + override fun close() {} + } +} + +private fun Response.toHttpResponse(): HttpResponse { + val headers = headers.toHeaders() + + return object : HttpResponse { + override fun statusCode(): Int = code + + override fun headers(): Headers = headers + + override fun body(): InputStream = body!!.byteStream() + + override fun close() = body!!.close() + } +} + +private fun okhttp3.Headers.toHeaders(): Headers { + val headersBuilder = Headers.builder() + forEach { (name, value) -> headersBuilder.put(name, value) } + return headersBuilder.build() +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/ProxyAuthenticator.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/ProxyAuthenticator.kt new file mode 100644 index 0000000..a131d34 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/ProxyAuthenticator.kt @@ -0,0 +1,59 @@ +package com.cas_parser.api.core.http + +import java.net.Proxy +import java.nio.charset.Charset +import java.nio.charset.StandardCharsets +import java.util.Base64 +import java.util.Optional + +/** + * Provides credentials when an HTTP proxy responds with `407 Proxy Authentication Required`. + * + * Implementations inspect the 407 [response] (typically its `Proxy-Authenticate` header) and return + * the request to retry with a `Proxy-Authorization` header set, or [Optional.empty] to abandon + * authentication and surface the 407 to the caller. + * + * Implementations must be thread-safe; they may be invoked concurrently from multiple HTTP calls. + */ +fun interface ProxyAuthenticator { + + /** + * @param proxy the proxy that produced the challenge, or [Proxy.NO_PROXY] if the route is not + * yet established + * @param request the request that produced [response] + * @param response the 407 challenge response + * @return the retry request to send (typically [request] with a `Proxy-Authorization` header + * added), or [Optional.empty] to abandon authentication + */ + fun authenticate( + proxy: Proxy, + request: HttpRequest, + response: HttpResponse, + ): Optional + + companion object { + + /** + * A [ProxyAuthenticator] that uses RFC 7617 Basic authentication with the ISO-8859-1 + * charset. + */ + @JvmStatic + fun basic(username: String, password: String): ProxyAuthenticator = + basic(username, password, StandardCharsets.ISO_8859_1) + + /** + * A [ProxyAuthenticator] that uses RFC 7617 Basic authentication with the given [charset]. + */ + @JvmStatic + fun basic(username: String, password: String, charset: Charset): ProxyAuthenticator { + val token = + Base64.getEncoder().encodeToString("$username:$password".toByteArray(charset)) + val headerValue = "Basic $token" + return ProxyAuthenticator { _, request, _ -> + Optional.of( + request.toBuilder().putHeader("Proxy-Authorization", headerValue).build() + ) + } + } + } +} From 3cf0f7352b3ae84648793ee709807f35dbfa6547 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 7 May 2026 03:28:30 +0000 Subject: [PATCH 95/99] feat(client): improve logging Logging is now: 1. Streaming 4. Configurable in-memory 5. Generally more robust 6. Usable with any underlying http client --- README.md | 15 +- .../build.gradle.kts | 1 - .../client/okhttp/CasParserOkHttpClient.kt | 10 + .../okhttp/CasParserOkHttpClientAsync.kt | 10 + .../api/client/okhttp/OkHttpClient.kt | 13 - .../com/cas_parser/api/core/ClientOptions.kt | 30 +- .../com/cas_parser/api/core/LogLevel.kt | 33 + .../kotlin/com/cas_parser/api/core/Utils.kt | 6 + .../api/core/http/LoggingHttpClient.kt | 627 +++++++++++ .../api/core/http/LoggingHttpClientTest.kt | 999 ++++++++++++++++++ 10 files changed, 1727 insertions(+), 17 deletions(-) create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/LogLevel.kt create mode 100644 cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/LoggingHttpClient.kt create mode 100644 cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/LoggingHttpClientTest.kt diff --git a/README.md b/README.md index 976361d..39c2cc3 100644 --- a/README.md +++ b/README.md @@ -236,8 +236,6 @@ The SDK throws custom unchecked exception types: ## Logging -The SDK uses the standard [OkHttp logging interceptor](https://github.com/square/okhttp/tree/master/okhttp-logging-interceptor). - Enable logging by setting the `CAS_PARSER_LOG` environment variable to `info`: ```sh @@ -250,6 +248,19 @@ Or to `debug` for more verbose logging: export CAS_PARSER_LOG=debug ``` +Or configure the client manually using the `logLevel` method: + +```java +import com.cas_parser.api.client.CasParserClient; +import com.cas_parser.api.client.okhttp.CasParserOkHttpClient; +import com.cas_parser.api.core.LogLevel; + +CasParserClient client = CasParserOkHttpClient.builder() + .fromEnv() + .logLevel(LogLevel.INFO) + .build(); +``` + ## ProGuard and R8 Although the SDK uses reflection, it is still usable with [ProGuard](https://github.com/Guardsquare/proguard) and [R8](https://developer.android.com/topic/performance/app-optimization/enable-app-optimization) because `cas-parser-java-core` is published with a [configuration file](cas-parser-java-core/src/main/resources/META-INF/proguard/cas-parser-java-core.pro) containing [keep rules](https://www.guardsquare.com/manual/configuration/usage). diff --git a/cas-parser-java-client-okhttp/build.gradle.kts b/cas-parser-java-client-okhttp/build.gradle.kts index b311e82..0824fab 100644 --- a/cas-parser-java-client-okhttp/build.gradle.kts +++ b/cas-parser-java-client-okhttp/build.gradle.kts @@ -7,7 +7,6 @@ dependencies { api(project(":cas-parser-java-core")) implementation("com.squareup.okhttp3:okhttp:4.12.0") - implementation("com.squareup.okhttp3:logging-interceptor:4.12.0") testImplementation(kotlin("test")) testImplementation("org.assertj:assertj-core:3.27.7") diff --git a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClient.kt b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClient.kt index 4446514..ce3933f 100644 --- a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClient.kt +++ b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClient.kt @@ -5,6 +5,7 @@ package com.cas_parser.api.client.okhttp import com.cas_parser.api.client.CasParserClient import com.cas_parser.api.client.CasParserClientImpl import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.LogLevel import com.cas_parser.api.core.Sleeper import com.cas_parser.api.core.Timeout import com.cas_parser.api.core.http.Headers @@ -277,6 +278,15 @@ class CasParserOkHttpClient private constructor() { */ fun maxRetries(maxRetries: Int) = apply { clientOptions.maxRetries(maxRetries) } + /** + * The level at which to log request and response information. + * + * [fromEnv] will set the level from environment variables. See [LogLevel.fromEnv]. + * + * Defaults to [LogLevel.fromEnv]. + */ + fun logLevel(logLevel: LogLevel) = apply { clientOptions.logLevel(logLevel) } + /** Your API key for authentication. Use `sandbox-with-json-responses` as Sandbox key. */ fun apiKey(apiKey: String) = apply { clientOptions.apiKey(apiKey) } diff --git a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClientAsync.kt b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClientAsync.kt index 2b7f952..53c82ef 100644 --- a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClientAsync.kt +++ b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/CasParserOkHttpClientAsync.kt @@ -5,6 +5,7 @@ package com.cas_parser.api.client.okhttp import com.cas_parser.api.client.CasParserClientAsync import com.cas_parser.api.client.CasParserClientAsyncImpl import com.cas_parser.api.core.ClientOptions +import com.cas_parser.api.core.LogLevel import com.cas_parser.api.core.Sleeper import com.cas_parser.api.core.Timeout import com.cas_parser.api.core.http.Headers @@ -277,6 +278,15 @@ class CasParserOkHttpClientAsync private constructor() { */ fun maxRetries(maxRetries: Int) = apply { clientOptions.maxRetries(maxRetries) } + /** + * The level at which to log request and response information. + * + * [fromEnv] will set the level from environment variables. See [LogLevel.fromEnv]. + * + * Defaults to [LogLevel.fromEnv]. + */ + fun logLevel(logLevel: LogLevel) = apply { clientOptions.logLevel(logLevel) } + /** Your API key for authentication. Use `sandbox-with-json-responses` as Sandbox key. */ fun apiKey(apiKey: String) = apply { clientOptions.apiKey(apiKey) } diff --git a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/OkHttpClient.kt b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/OkHttpClient.kt index 0630211..5494e32 100644 --- a/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/OkHttpClient.kt +++ b/cas-parser-java-client-okhttp/src/main/kotlin/com/cas_parser/api/client/okhttp/OkHttpClient.kt @@ -35,7 +35,6 @@ import okhttp3.Request import okhttp3.RequestBody import okhttp3.RequestBody.Companion.toRequestBody import okhttp3.Response -import okhttp3.logging.HttpLoggingInterceptor import okio.BufferedSink import okio.buffer import okio.sink @@ -93,18 +92,6 @@ internal constructor(@JvmSynthetic internal val okHttpClient: okhttp3.OkHttpClie private fun newCall(request: HttpRequest, requestOptions: RequestOptions): Call { val clientBuilder = okHttpClient.newBuilder() - val logLevel = - when (System.getenv("CAS_PARSER_LOG")?.lowercase()) { - "info" -> HttpLoggingInterceptor.Level.BASIC - "debug" -> HttpLoggingInterceptor.Level.BODY - else -> null - } - if (logLevel != null) { - clientBuilder.addNetworkInterceptor( - HttpLoggingInterceptor().setLevel(logLevel).apply { redactHeader("x-api-key") } - ) - } - requestOptions.timeout?.let { clientBuilder .connectTimeout(it.connect()) diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ClientOptions.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ClientOptions.kt index 2129ec2..00f28b4 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ClientOptions.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/ClientOptions.kt @@ -4,6 +4,7 @@ package com.cas_parser.api.core import com.cas_parser.api.core.http.Headers import com.cas_parser.api.core.http.HttpClient +import com.cas_parser.api.core.http.LoggingHttpClient import com.cas_parser.api.core.http.PhantomReachableClosingHttpClient import com.cas_parser.api.core.http.QueryParams import com.cas_parser.api.core.http.RetryingHttpClient @@ -96,6 +97,14 @@ private constructor( * Defaults to 2. */ @get:JvmName("maxRetries") val maxRetries: Int, + /** + * The level at which to log request and response information. + * + * [fromEnv] will set the level from environment variables. See [LogLevel.fromEnv]. + * + * Defaults to [LogLevel.fromEnv]. + */ + @get:JvmName("logLevel") val logLevel: LogLevel, /** Your API key for authentication. Use `sandbox-with-json-responses` as Sandbox key. */ @get:JvmName("apiKey") val apiKey: String, ) { @@ -152,6 +161,7 @@ private constructor( private var responseValidation: Boolean = false private var timeout: Timeout = Timeout.default() private var maxRetries: Int = 2 + private var logLevel: LogLevel = LogLevel.fromEnv() private var apiKey: String? = null @JvmSynthetic @@ -167,6 +177,7 @@ private constructor( responseValidation = clientOptions.responseValidation timeout = clientOptions.timeout maxRetries = clientOptions.maxRetries + logLevel = clientOptions.logLevel apiKey = clientOptions.apiKey } @@ -277,6 +288,15 @@ private constructor( */ fun maxRetries(maxRetries: Int) = apply { this.maxRetries = maxRetries } + /** + * The level at which to log request and response information. + * + * [fromEnv] will set the level from environment variables. See [LogLevel.fromEnv]. + * + * Defaults to [LogLevel.fromEnv]. + */ + fun logLevel(logLevel: LogLevel) = apply { this.logLevel = logLevel } + /** Your API key for authentication. Use `sandbox-with-json-responses` as Sandbox key. */ fun apiKey(apiKey: String) = apply { this.apiKey = apiKey } @@ -375,6 +395,7 @@ private constructor( * System properties take precedence over environment variables. */ fun fromEnv() = apply { + logLevel(LogLevel.fromEnv()) (System.getProperty("casparser.baseUrl") ?: System.getenv("CAS_PARSER_BASE_URL"))?.let { baseUrl(it) } @@ -431,7 +452,13 @@ private constructor( return ClientOptions( httpClient, RetryingHttpClient.builder() - .httpClient(httpClient) + .httpClient( + LoggingHttpClient.builder() + .httpClient(httpClient) + .clock(clock) + .level(logLevel) + .build() + ) .sleeper(sleeper) .clock(clock) .maxRetries(maxRetries) @@ -446,6 +473,7 @@ private constructor( responseValidation, timeout, maxRetries, + logLevel, apiKey, ) } diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/LogLevel.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/LogLevel.kt new file mode 100644 index 0000000..4e66497 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/LogLevel.kt @@ -0,0 +1,33 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.core + +/** The level at which to log request and response information. */ +enum class LogLevel { + /** No logging. */ + OFF, + /** Minimal request and response summary logs. No headers or bodies are logged. */ + INFO, + /** [INFO] logs plus details about request failures. */ + ERROR, + /** + * Full request and response logs. Sensitive headers are redacted, but sensitive data in request + * and response bodies may still be visible. + */ + DEBUG; + + /** Returns whether this level is at or higher than the given [level]. */ + fun shouldLog(level: LogLevel): Boolean = ordinal >= level.ordinal + + companion object { + + /** Returns a [LogLevel] based on the `CAS_PARSER_LOG` environment variable. */ + fun fromEnv() = + when (System.getenv("CAS_PARSER_LOG")?.lowercase()) { + "info" -> INFO + "error" -> ERROR + "debug" -> DEBUG + else -> OFF + } + } +} diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Utils.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Utils.kt index 9cdb07b..978563a 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Utils.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/Utils.kt @@ -5,6 +5,7 @@ package com.cas_parser.api.core import com.cas_parser.api.errors.CasParserInvalidDataException import java.util.Collections import java.util.SortedMap +import java.util.SortedSet import java.util.concurrent.CompletableFuture import java.util.concurrent.locks.Lock @@ -16,6 +17,11 @@ internal fun T?.getOrThrow(name: String): T = internal fun List.toImmutable(): List = if (isEmpty()) Collections.emptyList() else Collections.unmodifiableList(toList()) +@JvmSynthetic +internal fun > SortedSet.toImmutable(): SortedSet = + if (isEmpty()) Collections.emptySortedSet() + else Collections.unmodifiableSortedSet(toSortedSet(comparator() ?: Comparator.naturalOrder())) + @JvmSynthetic internal fun Map.toImmutable(): Map = if (isEmpty()) immutableEmptyMap() else Collections.unmodifiableMap(toMap()) diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/LoggingHttpClient.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/LoggingHttpClient.kt new file mode 100644 index 0000000..95573e3 --- /dev/null +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/LoggingHttpClient.kt @@ -0,0 +1,627 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.core.http + +import com.cas_parser.api.core.LogLevel +import com.cas_parser.api.core.RequestOptions +import com.cas_parser.api.core.checkRequired +import com.cas_parser.api.core.toImmutable +import java.io.ByteArrayOutputStream +import java.io.InputStream +import java.io.OutputStream +import java.nio.ByteBuffer +import java.nio.charset.CharacterCodingException +import java.nio.charset.Charset +import java.nio.charset.CharsetDecoder +import java.nio.charset.CodingErrorAction +import java.nio.charset.StandardCharsets +import java.time.Clock +import java.time.Duration +import java.time.OffsetDateTime +import java.util.SortedSet +import java.util.concurrent.CompletableFuture +import java.util.concurrent.CompletionException +import kotlin.time.toKotlinDuration + +/** A wrapper [HttpClient] around [httpClient] that logs request and response information. */ +class LoggingHttpClient +private constructor( + /** The underlying [HttpClient] for making requests. */ + @get:JvmName("httpClient") val httpClient: HttpClient, + /** + * Sensitive headers to redact from logs. + * + * Defaults to `Set.of("x-api-key")`. + */ + @get:JvmName("redactedHeaders") val redactedHeaders: SortedSet, + /** + * The clock to use for measuring request and response durations. + * + * This is primarily useful for using a fake clock in tests. + * + * Defaults to [Clock.systemUTC]. + */ + @get:JvmName("clock") val clock: Clock, + /** + * The log level to use. + * + * Pass [LogLevel.fromEnv] to read from environment variables. + */ + @get:JvmName("level") val level: LogLevel, +) : HttpClient { + + override fun execute(request: HttpRequest, requestOptions: RequestOptions): HttpResponse { + val loggingRequest = logRequest(request) + + val before = OffsetDateTime.now(clock) + val response = + try { + httpClient.execute(loggingRequest, requestOptions) + } catch (e: Throwable) { + logFailure(e, Duration.between(before, OffsetDateTime.now(clock))) + throw e + } + + val took = Duration.between(before, OffsetDateTime.now(clock)) + return logResponse(response, took) + } + + override fun executeAsync( + request: HttpRequest, + requestOptions: RequestOptions, + ): CompletableFuture { + val loggingRequest = logRequest(request) + + val before = OffsetDateTime.now(clock) + val future = + try { + httpClient.executeAsync(loggingRequest, requestOptions) + } catch (e: Throwable) { + logFailure(e, Duration.between(before, OffsetDateTime.now(clock))) + throw e + } + return future.handle { response, error -> + val took = Duration.between(before, OffsetDateTime.now(clock)) + if (error != null) { + logFailure(unwrapCompletionException(error), took) + throw error + } + logResponse(response, took) + } + } + + private fun logRequest(request: HttpRequest): HttpRequest { + if (!level.shouldLog(LogLevel.INFO)) { + return request + } + + System.err.println( + buildString { + append("--> ${request.method} ${request.url()}") + request.body?.let { + val length = it.contentLength() + append(if (length >= 0) " ($length-byte body)" else " (unknown-length body)") + } + } + ) + + if (!level.shouldLog(LogLevel.DEBUG)) { + return request + } + + logHeaders(request.headers) + + if (request.body == null) { + System.err.println("--> END ${request.method}") + System.err.println() + return request + } + + return request + .toBuilder() + .body(LoggingHttpRequestBody(request.method, request.body)) + .build() + } + + private fun logResponse(response: HttpResponse, took: Duration): HttpResponse { + if (!level.shouldLog(LogLevel.INFO)) { + return response + } + + val contentLength = response.headers().values("Content-Length").firstOrNull()?.toIntOrNull() + System.err.println( + "<-- ${response.statusCode()} (${ + buildString { + append(took.format()) + contentLength?.let { append(", $contentLength-byte body") } + } + })" + ) + + if (!level.shouldLog(LogLevel.DEBUG)) { + return response + } + + logHeaders(response.headers()) + return LoggingHttpResponse(response) + } + + private fun logFailure(error: Throwable, took: Duration) { + if (!level.shouldLog(LogLevel.ERROR)) { + return + } + + System.err.println( + buildString { + append("<-- !! ${error.javaClass.simpleName}") + error.message?.let { append(": $it") } + append(" (${took.format()})") + } + ) + } + + private fun unwrapCompletionException(error: Throwable): Throwable = + if (error is CompletionException && error.cause != null) error.cause!! else error + + private fun logHeaders(headers: Headers) = + headers.names().forEach { name -> + headers.values(name).forEach { value -> + System.err.println("$name: ${if (redactedHeaders.contains(name)) "██" else value}") + } + } + + override fun close() = httpClient.close() + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [LoggingHttpClient]. + * + * The following fields are required: + * ```java + * .httpClient() + * .level() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [LoggingHttpClient]. */ + class Builder internal constructor() { + + private var httpClient: HttpClient? = null + private var redactedHeaders: Set = setOf("x-api-key") + private var clock: Clock = Clock.systemUTC() + private var level: LogLevel? = null + + @JvmSynthetic + internal fun from(loggingHttpClient: LoggingHttpClient) = apply { + httpClient = loggingHttpClient.httpClient + redactedHeaders = loggingHttpClient.redactedHeaders + clock = loggingHttpClient.clock + level = loggingHttpClient.level + } + + /** The underlying [HttpClient] for making requests. */ + fun httpClient(httpClient: HttpClient) = apply { this.httpClient = httpClient } + + /** + * Sensitive headers to redact from logs. + * + * Defaults to `Set.of("x-api-key")`. + */ + fun redactedHeaders(redactedHeaders: Set) = apply { + this.redactedHeaders = redactedHeaders + } + + /** + * The clock to use for measuring request and response durations. + * + * This is primarily useful for using a fake clock in tests. + * + * Defaults to [Clock.systemUTC]. + */ + fun clock(clock: Clock) = apply { this.clock = clock } + + /** + * The log level to use. + * + * Pass [LogLevel.fromEnv] to read from environment variables. + */ + fun level(level: LogLevel) = apply { this.level = level } + + /** + * Returns an immutable instance of [LoggingHttpClient]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .httpClient() + * .level() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): LoggingHttpClient = + LoggingHttpClient( + checkRequired("httpClient", httpClient), + redactedHeaders.toSortedSet(String.CASE_INSENSITIVE_ORDER).toImmutable(), + clock, + checkRequired("level", level), + ) + } +} + +/** + * An [HttpRequestBody] wrapper that delegates to [body] while also logging line by line as it's + * written. + * + * The logging occurs in a streaming manner with minimal buffering. + */ +private class LoggingHttpRequestBody( + private val method: HttpMethod, + private val body: HttpRequestBody, +) : HttpRequestBody { + + private val charset by lazy { parseCharset(body.contentType()) } + + override fun writeTo(outputStream: OutputStream) { + val loggingOutputStream = LoggingOutputStream(outputStream, charset) + body.writeTo(loggingOutputStream) + + loggingOutputStream.flush() + System.err.println("--> END $method (${loggingOutputStream.writeCount()}-byte body)") + System.err.println() + } + + override fun contentType(): String? = body.contentType() + + override fun contentLength(): Long = body.contentLength() + + override fun repeatable(): Boolean = body.repeatable() + + override fun close() = body.close() +} + +/** + * An [OutputStream] wrapper that delegates to [outputStream] while also logging bytes line by line + * as it's written to. + * + * The written content is assumed to be in the given [charset] and the logging occurs in a streaming + * manner with minimal buffering. + */ +private class LoggingOutputStream(private val outputStream: OutputStream, charset: Charset?) : + OutputStream() { + + private val buffer = LoggingBuffer(charset) + + fun writeCount() = buffer.writeCount() + + override fun write(b: Int) { + outputStream.write(b) + buffer.write(b) + } + + override fun write(b: ByteArray, off: Int, len: Int) { + outputStream.write(b, off, len) + for (i in off until off + len) { + buffer.write(b[i].toInt() and 0xFF) + } + } + + /** Prints any currently buffered content. */ + override fun flush() { + buffer.flush() + outputStream.flush() + } + + override fun close() = outputStream.close() +} + +/** + * An [HttpResponse] wrapper that delegates to [response] while also logging line-by-line as it's + * read. + * + * The logging occurs in a streaming manner with minimal buffering. + */ +private class LoggingHttpResponse(private val response: HttpResponse) : HttpResponse { + + private val loggingBody: Lazy = lazy { + LoggingInputStream( + response.body(), + parseCharset(response.headers().values("Content-Type").firstOrNull()), + ) + } + + override fun statusCode(): Int = response.statusCode() + + override fun headers(): Headers = response.headers() + + override fun body(): InputStream = loggingBody.value + + override fun close() { + if (loggingBody.isInitialized()) { + loggingBody.value.close() + } + response.close() + } +} + +/** + * An [InputStream] wrapper that delegates to [inputStream] while also logging bytes line by line as + * it's read. + * + * The contents of [inputStream] are assumed to be in the given [charset] and the logging occurs in + * a streaming manner with minimal buffering. + */ +private class LoggingInputStream(private val inputStream: InputStream, charset: Charset?) : + InputStream() { + + private var isDone = false + private val buffer = LoggingBuffer(charset) + + override fun read(): Int { + if (isDone) { + return -1 + } + + val b = inputStream.read() + + if (b == -1) { + markDone() + return b + } + + buffer.write(b) + return b + } + + override fun read(b: ByteArray, off: Int, len: Int): Int { + if (isDone) { + return -1 + } + + val bytesRead = inputStream.read(b, off, len) + + if (bytesRead == -1) { + markDone() + return bytesRead + } + + for (i in off until off + bytesRead) { + buffer.write(b[i].toInt() and 0xFF) + } + return bytesRead + } + + override fun close() { + if (!isDone) { + markDone(closedEarly = true) + } + inputStream.close() + } + + private fun markDone(closedEarly: Boolean = false) { + isDone = true + buffer.flush() + val suffix = if (closedEarly) ", closed early" else "" + System.err.println("<-- END HTTP (${buffer.writeCount()}-byte body$suffix)") + System.err.println() + } +} + +/** + * A byte buffer that prints line by line, using the given [charset], as bytes are written to it. + * + * When [charset] is `null`, the buffer performs an upfront check to detect binary content. If + * non-whitespace ISO control characters are found in the first [PROBABLY_UTF8_CODE_POINT_LIMIT] + * code points, body logging is suppressed entirely. + */ +private class LoggingBuffer(charset: Charset?) { + + private val charset = charset ?: StandardCharsets.UTF_8 + + private val decoder: CharsetDecoder = + this.charset + .newDecoder() + .onMalformedInput(CodingErrorAction.REPORT) + .onUnmappableCharacter(CodingErrorAction.REPORT) + private var writeCount = 0 + private val buffer = ByteArrayOutputStream(128) + + /** + * Whether logging has been suppressed because the content doesn't appear to be readable text. + * + * This is only set when [charset] is `null` and the content fails the [isProbablyUtf8] check. + */ + private var suppressed = false + + /** + * Bytes accumulated for the [isProbablyUtf8] check before any lines are printed. + * + * Once the check passes (or [charset] is non-null), this is set to `null` and bytes flow + * directly to [buffer]. + */ + private var prefetchBuffer: ByteArrayOutputStream? = + if (charset != null) null else ByteArrayOutputStream(128) + + fun writeCount() = writeCount + + fun write(b: Int) { + if (writeCount == 0) { + // Print a newline before we start printing anything to separate the printed content + // from previous content. + System.err.println() + } + + writeCount++ + + if (suppressed) { + return + } + + val prefetch = prefetchBuffer + if (prefetch != null) { + prefetch.write(b) + // Continue accumulating until we have enough bytes to decide. + if (prefetch.size() < PROBABLY_UTF8_BYTE_LIMIT && b != '\n'.code) { + return + } + // We have enough bytes. Check if the content is probably UTF-8. + prefetchBuffer = null + val bytes = prefetch.toByteArray() + if (!isProbablyUtf8(bytes)) { + suppressed = true + System.err.println("(binary body omitted)") + return + } + // Content looks like UTF-8. Feed the accumulated bytes into the normal buffer. + for (byte in bytes) { + writeToBuffer(byte.toInt() and 0xFF) + } + return + } + + writeToBuffer(b) + } + + private fun writeToBuffer(b: Int) { + if (b == '\n'.code) { + flush() + return + } + + buffer.write(b) + } + + /** Prints any currently buffered content. */ + fun flush() { + if (suppressed) { + return + } + + // If we still have a prefetch buffer when flush is called (body was shorter than the + // limit), run the check now. + val prefetch = prefetchBuffer + if (prefetch != null) { + prefetchBuffer = null + val bytes = prefetch.toByteArray() + if (bytes.isEmpty()) { + return + } + if (!isProbablyUtf8(bytes)) { + suppressed = true + System.err.println("(binary body omitted)") + return + } + for (byte in bytes) { + writeToBuffer(byte.toInt() and 0xFF) + } + } + + if (buffer.size() == 0) { + return + } + + val line = + try { + decoder.decode(ByteBuffer.wrap(buffer.toByteArray())) + } catch (e: CharacterCodingException) { + "(omitted line is not valid $charset)" + } + buffer.reset() + System.err.println(line) + } +} + +/** The maximum number of code points to sample when checking if content is probably UTF-8. */ +private const val PROBABLY_UTF8_CODE_POINT_LIMIT = 64 + +/** + * The maximum number of bytes to accumulate before running the [isProbablyUtf8] check. UTF-8 code + * points are at most 4 bytes, so this accommodates [PROBABLY_UTF8_CODE_POINT_LIMIT] code points. + */ +private const val PROBABLY_UTF8_BYTE_LIMIT = PROBABLY_UTF8_CODE_POINT_LIMIT * 4 + +/** + * Returns `true` if the given [bytes] probably contain human-readable UTF-8 text. + * + * Decodes up to [PROBABLY_UTF8_CODE_POINT_LIMIT] code points and returns `false` if any + * non-whitespace ISO control characters are found, or if the bytes are not valid UTF-8. + */ +private fun isProbablyUtf8(bytes: ByteArray): Boolean { + try { + val decoder = + StandardCharsets.UTF_8.newDecoder() + .onMalformedInput(CodingErrorAction.REPORT) + .onUnmappableCharacter(CodingErrorAction.REPORT) + val charBuffer = decoder.decode(ByteBuffer.wrap(bytes)) + var codePointCount = 0 + var i = 0 + while (i < charBuffer.length && codePointCount < PROBABLY_UTF8_CODE_POINT_LIMIT) { + val codePoint = Character.codePointAt(charBuffer, i) + if (Character.isISOControl(codePoint) && !Character.isWhitespace(codePoint)) { + return false + } + i += Character.charCount(codePoint) + codePointCount++ + } + return true + } catch (e: CharacterCodingException) { + return false + } +} + +/** Returns the [Charset] in the given [contentType] string, or `null` if unspecified. */ +private fun parseCharset(contentType: String?): Charset? = + contentType + ?.split(";") + ?.drop(1) + ?.map { it.trim() } + ?.firstOrNull { it.startsWith("charset=", ignoreCase = true) } + ?.substringAfter("=") + ?.trim() + ?.removeSurrounding("\"") + ?.let { runCatching { charset(it) }.getOrNull() } + +/** Formats the [Duration] into a string like "1m 40s 467ms". */ +private fun Duration.format(): String = + toKotlinDuration().toComponents { days, hours, minutes, seconds, nanoseconds -> + buildString { + val milliseconds = nanoseconds / 1_000_000 + if (days > 0) { + append("${days}d") + } + if (hours > 0) { + if (isNotEmpty()) { + append(" ") + } + append("${hours}h") + } + if (minutes > 0) { + if (isNotEmpty()) { + append(" ") + } + append("${minutes}m") + } + if (seconds > 0) { + if (isNotEmpty()) { + append(" ") + } + append("${seconds}s") + } + if (milliseconds > 0) { + if (isNotEmpty()) { + append(" ") + } + append("${milliseconds}ms") + } + + if (isEmpty()) { + append("0s") + } + } + } diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/LoggingHttpClientTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/LoggingHttpClientTest.kt new file mode 100644 index 0000000..97de099 --- /dev/null +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/LoggingHttpClientTest.kt @@ -0,0 +1,999 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.cas_parser.api.core.http + +import com.cas_parser.api.core.LogLevel +import com.cas_parser.api.core.RequestOptions +import java.io.ByteArrayInputStream +import java.io.ByteArrayOutputStream +import java.io.IOException +import java.io.InputStream +import java.io.OutputStream +import java.io.PrintStream +import java.nio.charset.StandardCharsets +import java.time.Clock +import java.time.Instant +import java.time.ZoneOffset +import java.util.concurrent.CompletableFuture +import org.assertj.core.api.Assertions.assertThat +import org.assertj.core.api.Assertions.assertThatThrownBy +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.parallel.ResourceLock +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.ValueSource + +@ResourceLock("stderr") +internal class LoggingHttpClientTest { + + private lateinit var originalErr: PrintStream + private lateinit var errContent: ByteArrayOutputStream + + @BeforeEach + fun beforeEach() { + originalErr = System.err + errContent = ByteArrayOutputStream() + System.setErr(PrintStream(errContent)) + } + + @AfterEach + fun afterEach() { + System.setErr(originalErr) + } + + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun offLevel_noOutput(async: Boolean) { + val client = loggingClient(fakeHttpClient(), LogLevel.OFF) + + val response = client.execute(simpleGetRequest(), async).apply { body().readBytes() } + + assertThat(response.statusCode()).isEqualTo(200) + assertThat(stderrOutput()).isEmpty() + } + + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun infoLevel_logsGetRequest(async: Boolean) { + val client = loggingClient(fakeHttpClient(), LogLevel.INFO) + + client.execute(simpleGetRequest(), async).body().readBytes() + + assertThat(stderrOutput()) + .isEqualTo( + """ + |--> GET https://api.example.com/v1/resources + |<-- 200 (0s) + |""" + .trimMargin() + ) + } + + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun infoLevel_logsPostRequestWithBodySize(async: Boolean) { + val client = loggingClient(fakeHttpClient(), LogLevel.INFO) + + client.execute(postRequestWithBody("""{"key":"value"}"""), async).body().readBytes() + + assertThat(stderrOutput()) + .isEqualTo( + """ + |--> POST https://api.example.com/v1/resources (15-byte body) + |<-- 200 (0s) + |""" + .trimMargin() + ) + } + + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun infoLevel_logsRequestWithUnknownLengthBody(async: Boolean) { + val client = loggingClient(fakeHttpClient(), LogLevel.INFO) + + client + .execute(postRequestWithBody("""{"key":"value"}""", contentLength = -1L), async) + .body() + .readBytes() + + assertThat(stderrOutput()) + .isEqualTo( + """ + |--> POST https://api.example.com/v1/resources (unknown-length body) + |<-- 200 (0s) + |""" + .trimMargin() + ) + } + + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun infoLevel_logsResponseStatusAndDuration(async: Boolean) { + val clock = + clockFrom( + Instant.parse("1998-04-21T00:00:00Z"), + Instant.parse("1998-04-21T00:00:01.234Z"), + ) + val client = loggingClient(fakeHttpClient(statusCode = 201), LogLevel.INFO, clock) + + client.execute(simpleGetRequest(), async).body().readBytes() + + assertThat(stderrOutput()) + .isEqualTo( + """ + |--> GET https://api.example.com/v1/resources + |<-- 201 (1s 234ms) + |""" + .trimMargin() + ) + } + + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun infoLevel_logsResponseContentLength(async: Boolean) { + val headers = + Headers.builder().put("Content-Length", "42").put("Content-Type", "text/plain").build() + val client = loggingClient(fakeHttpClient(responseHeaders = headers), LogLevel.INFO) + + client.execute(simpleGetRequest(), async).body().readBytes() + + assertThat(stderrOutput()) + .isEqualTo( + """ + |--> GET https://api.example.com/v1/resources + |<-- 200 (0s, 42-byte body) + |""" + .trimMargin() + ) + } + + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun infoLevel_doesNotLogHeaders(async: Boolean) { + val headers = Headers.builder().put("X-Custom", "visible").build() + val client = loggingClient(fakeHttpClient(responseHeaders = headers), LogLevel.INFO) + + client + .execute( + HttpRequest.builder() + .method(HttpMethod.GET) + .baseUrl("https://api.example.com") + .addPathSegment("v1") + .putHeader("X-Request-Custom", "req-value") + .build(), + async, + ) + .body() + .readBytes() + + assertThat(stderrOutput()) + .isEqualTo( + """ + |--> GET https://api.example.com/v1 + |<-- 200 (0s) + |""" + .trimMargin() + ) + } + + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun debugLevel_logsGetWithEndMarker(async: Boolean) { + val client = loggingClient(fakeHttpClient(), LogLevel.DEBUG) + + client.execute(simpleGetRequest(), async).body().readBytes() + + assertThat(stderrOutput()) + .isEqualTo( + """ + |--> GET https://api.example.com/v1/resources + |--> END GET + | + |<-- 200 (0s) + |<-- END HTTP (0-byte body) + | + |""" + .trimMargin() + ) + } + + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun debugLevel_logsRequestAndResponseHeaders(async: Boolean) { + val responseHeaders = + Headers.builder() + .put("X-Response-Id", "abc-123") + .put("Content-Type", "text/plain") + .build() + val client = + loggingClient(fakeHttpClient(responseHeaders = responseHeaders), LogLevel.DEBUG) + + client + .execute( + HttpRequest.builder() + .method(HttpMethod.GET) + .baseUrl("https://api.example.com") + .addPathSegment("test") + .putHeader("X-Custom", "my-value") + .build(), + async, + ) + .body() + .readBytes() + + assertThat(stderrOutput()) + .isEqualTo( + """ + |--> GET https://api.example.com/test + |X-Custom: my-value + |--> END GET + | + |<-- 200 (0s) + |Content-Type: text/plain + |X-Response-Id: abc-123 + |<-- END HTTP (0-byte body) + | + |""" + .trimMargin() + ) + } + + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun debugLevel_redactsSensitiveHeaders(async: Boolean) { + val client = + loggingClient( + fakeHttpClient(), + LogLevel.DEBUG, + redactedHeaders = setOf("Authorization", "X-Secret"), + ) + + client + .execute( + HttpRequest.builder() + .method(HttpMethod.GET) + .baseUrl("https://api.example.com") + .addPathSegment("test") + .putHeader("Authorization", "Bearer token-123") + .putHeader("X-Secret", "secret-value") + .putHeader("X-Public", "public-value") + .build(), + async, + ) + .body() + .readBytes() + + assertThat(stderrOutput()) + .isEqualTo( + """ + |--> GET https://api.example.com/test + |Authorization: ██ + |X-Public: public-value + |X-Secret: ██ + |--> END GET + | + |<-- 200 (0s) + |<-- END HTTP (0-byte body) + | + |""" + .trimMargin() + ) + } + + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun debugLevel_redactsHeadersCaseInsensitively(async: Boolean) { + val client = + loggingClient( + fakeHttpClient(), + LogLevel.DEBUG, + redactedHeaders = setOf("Authorization"), + ) + + client + .execute( + HttpRequest.builder() + .method(HttpMethod.GET) + .baseUrl("https://api.example.com") + .addPathSegment("test") + .putHeader("authorization", "Bearer secret") + .build(), + async, + ) + .body() + .readBytes() + + assertThat(stderrOutput()) + .isEqualTo( + """ + |--> GET https://api.example.com/test + |authorization: ██ + |--> END GET + | + |<-- 200 (0s) + |<-- END HTTP (0-byte body) + | + |""" + .trimMargin() + ) + } + + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun debugLevel_logsRequestBody(async: Boolean) { + val client = loggingClient(fakeHttpClient(), LogLevel.DEBUG) + val body = """{"name":"test","value":42}""" + + client.execute(postRequestWithBody(body), async).body().readBytes() + + assertThat(stderrOutput()) + .isEqualTo( + """ + |--> POST https://api.example.com/v1/resources (26-byte body) + | + |{"name":"test","value":42} + |--> END POST (26-byte body) + | + |<-- 200 (0s) + |<-- END HTTP (0-byte body) + | + |""" + .trimMargin() + ) + } + + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun debugLevel_logsResponseBody(async: Boolean) { + val responseBody = """{"id":1,"status":"ok"}""" + val headers = Headers.builder().put("Content-Type", "application/json").build() + val client = + loggingClient( + fakeHttpClient( + responseHeaders = headers, + responseBody = responseBody.toByteArray(StandardCharsets.UTF_8), + ), + LogLevel.DEBUG, + ) + + val response = client.execute(simpleGetRequest(), async) + val body = response.body().readBytes().toString(StandardCharsets.UTF_8) + + assertThat(body).isEqualTo(responseBody) + assertThat(stderrOutput()) + .isEqualTo( + """ + |--> GET https://api.example.com/v1/resources + |--> END GET + | + |<-- 200 (0s) + |Content-Type: application/json + | + |{"id":1,"status":"ok"} + |<-- END HTTP (22-byte body) + | + |""" + .trimMargin() + ) + } + + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun debugLevel_logsBinaryResponseBodyAsOmitted(async: Boolean) { + val binaryBody = ByteArray(256) { it.toByte() } + val client = loggingClient(fakeHttpClient(responseBody = binaryBody), LogLevel.DEBUG) + + client.execute(simpleGetRequest(), async).body().readBytes() + + assertThat(stderrOutput()) + .isEqualTo( + """ + |--> GET https://api.example.com/v1/resources + |--> END GET + | + |<-- 200 (0s) + | + |(binary body omitted) + |<-- END HTTP (256-byte body) + | + |""" + .trimMargin() + ) + } + + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun debugLevel_logsMultilineResponseBody(async: Boolean) { + val multilineBody = "line1\nline2\nline3" + val headers = Headers.builder().put("Content-Type", "text/plain; charset=utf-8").build() + val client = + loggingClient( + fakeHttpClient( + responseHeaders = headers, + responseBody = multilineBody.toByteArray(StandardCharsets.UTF_8), + ), + LogLevel.DEBUG, + ) + + client.execute(simpleGetRequest(), async).body().readBytes() + + assertThat(stderrOutput()) + .isEqualTo( + """ + |--> GET https://api.example.com/v1/resources + |--> END GET + | + |<-- 200 (0s) + |Content-Type: text/plain; charset=utf-8 + | + |line1 + |line2 + |line3 + |<-- END HTTP (17-byte body) + | + |""" + .trimMargin() + ) + } + + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun debugLevel_logsResponseBodyWithExplicitCharset(async: Boolean) { + val responseBody = "héllo wörld" + val headers = Headers.builder().put("Content-Type", "text/plain; charset=utf-8").build() + val client = + loggingClient( + fakeHttpClient( + responseHeaders = headers, + responseBody = responseBody.toByteArray(StandardCharsets.UTF_8), + ), + LogLevel.DEBUG, + ) + + client.execute(simpleGetRequest(), async).body().readBytes() + + assertThat(stderrOutput()) + .isEqualTo( + """ + |--> GET https://api.example.com/v1/resources + |--> END GET + | + |<-- 200 (0s) + |Content-Type: text/plain; charset=utf-8 + | + |héllo wörld + |<-- END HTTP (13-byte body) + | + |""" + .trimMargin() + ) + } + + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun debugLevel_logsResponseBodyWithNoContentType(async: Boolean) { + val responseBody = "plain text body" + val client = + loggingClient( + fakeHttpClient(responseBody = responseBody.toByteArray(StandardCharsets.UTF_8)), + LogLevel.DEBUG, + ) + + client.execute(simpleGetRequest(), async).body().readBytes() + + assertThat(stderrOutput()) + .isEqualTo( + """ + |--> GET https://api.example.com/v1/resources + |--> END GET + | + |<-- 200 (0s) + | + |plain text body + |<-- END HTTP (15-byte body) + | + |""" + .trimMargin() + ) + } + + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun debugLevel_logsEmptyResponseBody(async: Boolean) { + val client = loggingClient(fakeHttpClient(), LogLevel.DEBUG) + + client.execute(simpleGetRequest(), async).body().readBytes() + + assertThat(stderrOutput()) + .isEqualTo( + """ + |--> GET https://api.example.com/v1/resources + |--> END GET + | + |<-- 200 (0s) + |<-- END HTTP (0-byte body) + | + |""" + .trimMargin() + ) + } + + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun debugLevel_logsEndHttpMarkerOnEarlyClose(async: Boolean) { + val responseBody = """{"id":1,"status":"ok"}""" + val headers = Headers.builder().put("Content-Type", "application/json").build() + val client = + loggingClient( + fakeHttpClient( + responseHeaders = headers, + responseBody = responseBody.toByteArray(StandardCharsets.UTF_8), + ), + LogLevel.DEBUG, + ) + + val body = client.execute(simpleGetRequest(), async).body() + body.read(ByteArray(5)) + body.close() + + assertThat(stderrOutput()) + .isEqualTo( + """ + |--> GET https://api.example.com/v1/resources + |--> END GET + | + |<-- 200 (0s) + |Content-Type: application/json + | + |{"id" + |<-- END HTTP (5-byte body, closed early) + | + |""" + .trimMargin() + ) + } + + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun debugLevel_logsEndHttpMarkerOnCloseWithoutReading(async: Boolean) { + val responseBody = """{"id":1,"status":"ok"}""" + val headers = Headers.builder().put("Content-Type", "application/json").build() + val client = + loggingClient( + fakeHttpClient( + responseHeaders = headers, + responseBody = responseBody.toByteArray(StandardCharsets.UTF_8), + ), + LogLevel.DEBUG, + ) + + client.execute(simpleGetRequest(), async).body().close() + + assertThat(stderrOutput()) + .isEqualTo( + """ + |--> GET https://api.example.com/v1/resources + |--> END GET + | + |<-- 200 (0s) + |Content-Type: application/json + |<-- END HTTP (0-byte body, closed early) + | + |""" + .trimMargin() + ) + } + + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun debugLevel_logsEndHttpMarkerWhenResponseClosedAfterPartialRead(async: Boolean) { + val responseBody = """{"id":1,"status":"ok"}""" + val headers = Headers.builder().put("Content-Type", "application/json").build() + val client = + loggingClient( + fakeHttpClient( + responseHeaders = headers, + responseBody = responseBody.toByteArray(StandardCharsets.UTF_8), + ), + LogLevel.DEBUG, + ) + + val response = client.execute(simpleGetRequest(), async) + response.body().read(ByteArray(5)) + response.close() + + assertThat(stderrOutput()) + .isEqualTo( + """ + |--> GET https://api.example.com/v1/resources + |--> END GET + | + |<-- 200 (0s) + |Content-Type: application/json + | + |{"id" + |<-- END HTTP (5-byte body, closed early) + | + |""" + .trimMargin() + ) + } + + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun debugLevel_doesNotLogEndHttpMarkerWhenResponseClosedWithoutBodyAccess(async: Boolean) { + val responseBody = """{"id":1,"status":"ok"}""" + val headers = Headers.builder().put("Content-Type", "application/json").build() + val client = + loggingClient( + fakeHttpClient( + responseHeaders = headers, + responseBody = responseBody.toByteArray(StandardCharsets.UTF_8), + ), + LogLevel.DEBUG, + ) + + client.execute(simpleGetRequest(), async).close() + + assertThat(stderrOutput()) + .isEqualTo( + """ + |--> GET https://api.example.com/v1/resources + |--> END GET + | + |<-- 200 (0s) + |Content-Type: application/json + |""" + .trimMargin() + ) + } + + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun errorLevel_logsRequestFailure(async: Boolean) { + val clock = + clockFrom( + Instant.parse("1998-04-21T00:00:00Z"), + Instant.parse("1998-04-21T00:00:01.234Z"), + ) + val client = + loggingClient( + failingHttpClient(IOException("Connection refused")), + LogLevel.ERROR, + clock, + ) + + assertThatThrownBy { client.execute(simpleGetRequest(), async) } + + assertThat(stderrOutput()) + .isEqualTo( + """ + |--> GET https://api.example.com/v1/resources + |<-- !! IOException: Connection refused (1s 234ms) + |""" + .trimMargin() + ) + } + + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun infoLevel_doesNotLogRequestFailure(async: Boolean) { + val client = + loggingClient(failingHttpClient(IOException("Connection refused")), LogLevel.INFO) + + assertThatThrownBy { client.execute(simpleGetRequest(), async) } + + assertThat(stderrOutput()) + .isEqualTo( + """ + |--> GET https://api.example.com/v1/resources + |""" + .trimMargin() + ) + } + + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun debugLevel_logsRequestFailureAfterHeaders(async: Boolean) { + val client = + loggingClient(failingHttpClient(IOException("Connection refused")), LogLevel.DEBUG) + + assertThatThrownBy { client.execute(simpleGetRequest(), async) } + + assertThat(stderrOutput()) + .isEqualTo( + """ + |--> GET https://api.example.com/v1/resources + |--> END GET + | + |<-- !! IOException: Connection refused (0s) + |""" + .trimMargin() + ) + } + + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun errorLevel_logsRequestFailureWithoutMessage(async: Boolean) { + val client = loggingClient(failingHttpClient(IOException()), LogLevel.ERROR) + + assertThatThrownBy { client.execute(simpleGetRequest(), async) } + + assertThat(stderrOutput()) + .isEqualTo( + """ + |--> GET https://api.example.com/v1/resources + |<-- !! IOException (0s) + |""" + .trimMargin() + ) + } + + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun offLevel_doesNotLogRequestFailure(async: Boolean) { + val client = + loggingClient(failingHttpClient(IOException("Connection refused")), LogLevel.OFF) + + assertThatThrownBy { client.execute(simpleGetRequest(), async) } + + assertThat(stderrOutput()).isEmpty() + } + + @Test + fun errorLevel_logsExecuteAsyncSynchronousThrow() { + val error = IOException("Connection refused") + val client = + loggingClient( + object : HttpClient { + override fun execute( + request: HttpRequest, + requestOptions: RequestOptions, + ): HttpResponse = throw UnsupportedOperationException() + + override fun executeAsync( + request: HttpRequest, + requestOptions: RequestOptions, + ): CompletableFuture = throw error + + override fun close() {} + }, + LogLevel.ERROR, + ) + + assertThatThrownBy { client.execute(simpleGetRequest(), async = true) }.isSameAs(error) + + assertThat(stderrOutput()) + .isEqualTo( + """ + |--> GET https://api.example.com/v1/resources + |<-- !! IOException: Connection refused (0s) + |""" + .trimMargin() + ) + } + + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun durationFormat_seconds(async: Boolean) { + val clock = + clockFrom( + Instant.parse("1998-04-21T00:00:00Z"), + Instant.parse("1998-04-21T00:00:02.500Z"), + ) + val client = loggingClient(fakeHttpClient(), LogLevel.INFO, clock) + + client.execute(simpleGetRequest(), async).body().readBytes() + + assertThat(stderrOutput()) + .isEqualTo( + """ + |--> GET https://api.example.com/v1/resources + |<-- 200 (2s 500ms) + |""" + .trimMargin() + ) + } + + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun durationFormat_minutesAndSeconds(async: Boolean) { + val clock = + clockFrom( + Instant.parse("1998-04-21T00:00:00Z"), + Instant.parse("1998-04-21T00:01:40.467Z"), + ) + val client = loggingClient(fakeHttpClient(), LogLevel.INFO, clock) + + client.execute(simpleGetRequest(), async).body().readBytes() + + assertThat(stderrOutput()) + .isEqualTo( + """ + |--> GET https://api.example.com/v1/resources + |<-- 200 (1m 40s 467ms) + |""" + .trimMargin() + ) + } + + @Test + fun builder_toBuilder_roundtrips() { + val delegate = fakeHttpClient() + val clock = Clock.fixed(Instant.parse("1998-04-21T00:00:00Z"), ZoneOffset.UTC) + val client = + LoggingHttpClient.builder() + .httpClient(delegate) + .level(LogLevel.DEBUG) + .redactedHeaders(setOf("X-Secret")) + .clock(clock) + .build() + + val rebuilt = client.toBuilder().build() + + assertThat(rebuilt.httpClient).isSameAs(delegate) + assertThat(rebuilt.level).isEqualTo(LogLevel.DEBUG) + assertThat(rebuilt.redactedHeaders).containsExactly("X-Secret") + assertThat(rebuilt.clock).isEqualTo(clock) + } + + @Test + fun close_delegatesToUnderlyingClient() { + var closed = false + val delegate = + object : HttpClient { + override fun execute( + request: HttpRequest, + requestOptions: RequestOptions, + ): HttpResponse = throw UnsupportedOperationException() + + override fun executeAsync( + request: HttpRequest, + requestOptions: RequestOptions, + ): CompletableFuture = throw UnsupportedOperationException() + + override fun close() { + closed = true + } + } + val client = loggingClient(delegate, LogLevel.OFF) + + client.close() + + assertThat(closed).isTrue() + } + + private fun stderrOutput(): String = errContent.toString("UTF-8") + + private fun loggingClient( + httpClient: HttpClient, + level: LogLevel, + clock: Clock = clockFrom(Instant.parse("1998-04-21T00:00:00Z")), + redactedHeaders: Set = setOf("x-api-key"), + ): LoggingHttpClient = + LoggingHttpClient.builder() + .httpClient(httpClient) + .level(level) + .clock(clock) + .redactedHeaders(redactedHeaders) + .build() + + private fun simpleGetRequest(): HttpRequest = + HttpRequest.builder() + .method(HttpMethod.GET) + .baseUrl("https://api.example.com") + .addPathSegment("v1") + .addPathSegment("resources") + .build() + + private fun postRequestWithBody( + body: String, + contentType: String = "application/json", + contentLength: Long? = null, + ): HttpRequest = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl("https://api.example.com") + .addPathSegment("v1") + .addPathSegment("resources") + .body( + object : HttpRequestBody { + private val bytes = body.toByteArray(StandardCharsets.UTF_8) + + override fun writeTo(outputStream: OutputStream) { + outputStream.write(bytes) + } + + override fun contentType(): String = contentType + + override fun contentLength(): Long = contentLength ?: bytes.size.toLong() + + override fun repeatable(): Boolean = true + + override fun close() {} + } + ) + .build() + + private fun fakeHttpClient( + statusCode: Int = 200, + responseHeaders: Headers = Headers.builder().build(), + responseBody: ByteArray = ByteArray(0), + ): HttpClient = + object : HttpClient { + override fun execute( + request: HttpRequest, + requestOptions: RequestOptions, + ): HttpResponse { + // Consume the request body if present to trigger logging. + request.body?.let { + val out = ByteArrayOutputStream() + it.writeTo(out) + } + return fakeResponse(statusCode, responseHeaders, responseBody) + } + + override fun executeAsync( + request: HttpRequest, + requestOptions: RequestOptions, + ): CompletableFuture = + CompletableFuture.completedFuture(execute(request, requestOptions)) + + override fun close() {} + } + + private fun failingHttpClient(error: Throwable): HttpClient = + object : HttpClient { + override fun execute( + request: HttpRequest, + requestOptions: RequestOptions, + ): HttpResponse { + request.body?.let { + val out = ByteArrayOutputStream() + it.writeTo(out) + } + throw error + } + + override fun executeAsync( + request: HttpRequest, + requestOptions: RequestOptions, + ): CompletableFuture { + val future = CompletableFuture() + future.completeExceptionally(error) + return future + } + + override fun close() {} + } + + private fun fakeResponse(statusCode: Int, headers: Headers, body: ByteArray): HttpResponse = + object : HttpResponse { + override fun statusCode(): Int = statusCode + + override fun headers(): Headers = headers + + override fun body(): InputStream = ByteArrayInputStream(body) + + override fun close() {} + } + + private fun clockFrom(vararg instants: Instant): Clock = + object : Clock() { + private var index = 0 + + override fun getZone() = ZoneOffset.UTC + + override fun withZone(zone: java.time.ZoneId?) = this + + override fun instant(): Instant { + val instant = instants[index % instants.size] + index++ + return instant + } + } + + private fun HttpClient.execute(request: HttpRequest, async: Boolean): HttpResponse = + if (async) executeAsync(request).get() else execute(request) +} From d94559c811655d8d5b32907eb4796fabb4da9815 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 8 May 2026 03:33:34 +0000 Subject: [PATCH 96/99] chore: redact api-key headers in debug logs --- .../com/cas_parser/api/core/http/LoggingHttpClient.kt | 7 ++++--- .../com/cas_parser/api/core/http/LoggingHttpClientTest.kt | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/LoggingHttpClient.kt b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/LoggingHttpClient.kt index 95573e3..a482a89 100644 --- a/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/LoggingHttpClient.kt +++ b/cas-parser-java-core/src/main/kotlin/com/cas_parser/api/core/http/LoggingHttpClient.kt @@ -31,7 +31,7 @@ private constructor( /** * Sensitive headers to redact from logs. * - * Defaults to `Set.of("x-api-key")`. + * Defaults to `Set.of("authorization", "api-key", "x-api-key", "cookie", "set-cookie")`. */ @get:JvmName("redactedHeaders") val redactedHeaders: SortedSet, /** @@ -192,7 +192,8 @@ private constructor( class Builder internal constructor() { private var httpClient: HttpClient? = null - private var redactedHeaders: Set = setOf("x-api-key") + private var redactedHeaders: Set = + setOf("authorization", "api-key", "x-api-key", "cookie", "set-cookie") private var clock: Clock = Clock.systemUTC() private var level: LogLevel? = null @@ -210,7 +211,7 @@ private constructor( /** * Sensitive headers to redact from logs. * - * Defaults to `Set.of("x-api-key")`. + * Defaults to `Set.of("authorization", "api-key", "x-api-key", "cookie", "set-cookie")`. */ fun redactedHeaders(redactedHeaders: Set) = apply { this.redactedHeaders = redactedHeaders diff --git a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/LoggingHttpClientTest.kt b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/LoggingHttpClientTest.kt index 97de099..ad94107 100644 --- a/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/LoggingHttpClientTest.kt +++ b/cas-parser-java-core/src/test/kotlin/com/cas_parser/api/core/http/LoggingHttpClientTest.kt @@ -870,7 +870,8 @@ internal class LoggingHttpClientTest { httpClient: HttpClient, level: LogLevel, clock: Clock = clockFrom(Instant.parse("1998-04-21T00:00:00Z")), - redactedHeaders: Set = setOf("x-api-key"), + redactedHeaders: Set = + setOf("authorization", "api-key", "x-api-key", "cookie", "set-cookie"), ): LoggingHttpClient = LoggingHttpClient.builder() .httpClient(httpClient) From 602cbd579e1caafae21dd683b03f606e70828263 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 9 May 2026 13:19:59 +0000 Subject: [PATCH 97/99] chore(internal): version bump --- .release-please-manifest.json | 2 +- README.md | 10 +++++----- build.gradle.kts | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 4208b5c..1b77f50 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.6.0" + ".": "0.7.0" } \ No newline at end of file diff --git a/README.md b/README.md index 39c2cc3..60011e7 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ -[![Maven Central](https://img.shields.io/maven-central/v/com.cas_parser.api/cas-parser-java)](https://central.sonatype.com/artifact/com.cas_parser.api/cas-parser-java/0.6.0) -[![javadoc](https://javadoc.io/badge2/com.cas_parser.api/cas-parser-java/0.6.0/javadoc.svg)](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.6.0) +[![Maven Central](https://img.shields.io/maven-central/v/com.cas_parser.api/cas-parser-java)](https://central.sonatype.com/artifact/com.cas_parser.api/cas-parser-java/0.7.0) +[![javadoc](https://javadoc.io/badge2/com.cas_parser.api/cas-parser-java/0.7.0/javadoc.svg)](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.7.0) @@ -22,7 +22,7 @@ Use the Cas Parser MCP Server to enable AI assistants to interact with this API, -The REST API documentation can be found on [casparser.in](https://casparser.in/docs). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.6.0). +The REST API documentation can be found on [casparser.in](https://casparser.in/docs). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.cas_parser.api/cas-parser-java/0.7.0). @@ -33,7 +33,7 @@ The REST API documentation can be found on [casparser.in](https://casparser.in/d ### Gradle ```kotlin -implementation("com.cas_parser.api:cas-parser-java:0.6.0") +implementation("com.cas_parser.api:cas-parser-java:0.7.0") ``` ### Maven @@ -42,7 +42,7 @@ implementation("com.cas_parser.api:cas-parser-java:0.6.0") com.cas_parser.api cas-parser-java - 0.6.0 + 0.7.0 ``` diff --git a/build.gradle.kts b/build.gradle.kts index 794ef23..d0f1e15 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -9,7 +9,7 @@ repositories { allprojects { group = "com.cas_parser.api" - version = "0.6.0" // x-release-please-version + version = "0.7.0" // x-release-please-version } subprojects { From 7d94a30e7b16edd271a03fdcbe3ce1d011c078e1 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 13 May 2026 02:36:45 +0000 Subject: [PATCH 98/99] ci: pin GitHub Actions to commit SHAs Pin all GitHub Actions referenced in generated workflows (both first-party `actions/*` and third-party) to immutable commit SHAs. Updating pinned actions is now a deliberate codegen-side bump rather than implicit on every workflow run. --- .github/workflows/ci.yml | 20 ++++++++++---------- .github/workflows/publish-sonatype.yml | 6 +++--- .github/workflows/release-doctor.yml | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6e70176..5e1426a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,10 +22,10 @@ jobs: if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata') steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Java - uses: actions/setup-java@v5 + uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0 with: distribution: temurin java-version: | @@ -34,7 +34,7 @@ jobs: cache: gradle - name: Set up Gradle - uses: gradle/actions/setup-gradle@v4 + uses: gradle/actions/setup-gradle@ed408507eac070d1f99cc633dbcf757c94c7933a # v4.4.3 - name: Run lints run: ./scripts/lint @@ -49,10 +49,10 @@ jobs: if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata') steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Java - uses: actions/setup-java@v5 + uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0 with: distribution: temurin java-version: | @@ -61,7 +61,7 @@ jobs: cache: gradle - name: Set up Gradle - uses: gradle/actions/setup-gradle@v4 + uses: gradle/actions/setup-gradle@ed408507eac070d1f99cc633dbcf757c94c7933a # v4.4.3 - name: Build SDK run: ./scripts/build @@ -71,7 +71,7 @@ jobs: github.repository == 'stainless-sdks/cas-parser-java' && !startsWith(github.ref, 'refs/heads/stl/') id: github-oidc - uses: actions/github-script@v8 + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 with: script: core.setOutput('github_token', await core.getIDToken()); @@ -91,10 +91,10 @@ jobs: runs-on: ${{ github.repository == 'stainless-sdks/cas-parser-java' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} if: github.event_name == 'push' || github.event.pull_request.head.repo.fork steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Java - uses: actions/setup-java@v5 + uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0 with: distribution: temurin java-version: | @@ -103,7 +103,7 @@ jobs: cache: gradle - name: Set up Gradle - uses: gradle/gradle-build-action@v2 + uses: gradle/gradle-build-action@a8f75513eafdebd8141bd1cd4e30fcd194af8dfa # v2.12.0 - name: Run tests run: ./scripts/test diff --git a/.github/workflows/publish-sonatype.yml b/.github/workflows/publish-sonatype.yml index 2bfe3c5..ed2e8c8 100644 --- a/.github/workflows/publish-sonatype.yml +++ b/.github/workflows/publish-sonatype.yml @@ -14,10 +14,10 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Java - uses: actions/setup-java@v5 + uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0 with: distribution: temurin java-version: | @@ -26,7 +26,7 @@ jobs: cache: gradle - name: Set up Gradle - uses: gradle/gradle-build-action@v2 + uses: gradle/gradle-build-action@a8f75513eafdebd8141bd1cd4e30fcd194af8dfa # v2.12.0 - name: Publish to Sonatype run: |- diff --git a/.github/workflows/release-doctor.yml b/.github/workflows/release-doctor.yml index a636804..6e803cf 100644 --- a/.github/workflows/release-doctor.yml +++ b/.github/workflows/release-doctor.yml @@ -12,7 +12,7 @@ jobs: if: github.repository == 'CASParser/cas-parser-java' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || startsWith(github.head_ref, 'release-please') || github.head_ref == 'next') steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Check release environment run: | From d186685dc698cc2cc563374c931334a6a6575f79 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 18 May 2026 10:17:48 +0000 Subject: [PATCH 99/99] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 582a92c..fb087e4 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 21 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser/cas-parser-e572d88c2af6e4d7bc4f7e119357fd3f68b1e67d612fd1d3a657d916cde0087c.yml -openapi_spec_hash: a9fc7d947111bffa9184f8ca8be4a579 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser/cas-parser-904e3aa8081755d046016db9d84d13d140a4235c724e18e1cd7f8ebb7712883e.yml +openapi_spec_hash: 453b8e667c364b064e04352ad4deccfa config_hash: 5509bb7a961ae2e79114b24c381606d4