diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 00000000..bd8e2619 --- /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 00000000..d55fc4d6 --- /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/.fernignore b/.fernignore deleted file mode 100644 index 793636f0..00000000 --- a/.fernignore +++ /dev/null @@ -1,4 +0,0 @@ -# Specify files that shouldn't be modified by Fern - -LICENSE -README.md diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..022b8414 --- /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 index 2e52af1f..f668ddf3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,65 +1,85 @@ -name: ci - -on: [push] +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: - compile: - runs-on: ubuntu-latest + lint: + timeout-minutes: 15 + name: lint + runs-on: ${{ github.repository == 'stainless-sdks/courier-java' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} + if: github.event_name == 'push' || github.event.pull_request.head.repo.fork steps: - - name: Checkout repo - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Java - id: setup-jre - uses: actions/setup-java@v1 + uses: actions/setup-java@v4 with: - java-version: "11" - architecture: x64 + distribution: temurin + java-version: | + 8 + 21 + cache: gradle - - name: Compile - run: ./gradlew compileJava + - 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/courier-java' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} + if: github.event_name == 'push' || github.event.pull_request.head.repo.fork - test: - needs: [ compile ] - runs-on: ubuntu-latest steps: - - name: Checkout repo - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Java - id: setup-jre - uses: actions/setup-java@v1 + uses: actions/setup-java@v4 with: - java-version: "11" - architecture: x64 + distribution: temurin + java-version: | + 8 + 21 + cache: gradle - - name: Test - run: ./gradlew test - publish: - needs: [ compile, test ] - if: github.event_name == 'push' && contains(github.ref, 'refs/tags/') - runs-on: ubuntu-latest + - 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/courier-java' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} + if: github.event_name == 'push' || github.event.pull_request.head.repo.fork steps: - - name: Checkout repo - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Java - id: setup-jre - uses: actions/setup-java@v1 + uses: actions/setup-java@v4 with: - java-version: "11" - architecture: x64 + distribution: temurin + java-version: | + 8 + 21 + cache: gradle + + - name: Set up Gradle + uses: gradle/gradle-build-action@v2 - - name: Publish to maven - run: | - ./.publish/prepare.sh - ./gradlew publish - env: - MAVEN_USERNAME: ${{ secrets.MAVEN_USERNAME }} - MAVEN_PASSWORD: ${{ secrets.MAVEN_PASSWORD }} - MAVEN_PUBLISH_REGISTRY_URL: "https://oss.sonatype.org/service/local/staging/deploy/maven2/" - MAVEN_SIGNATURE_KID: ${{ secrets.MAVEN_SIGNATURE_KID }} - MAVEN_SIGNATURE_SECRET_KEY: ${{ secrets.MAVEN_SIGNATURE_SECRET_KEY }} - MAVEN_SIGNATURE_PASSWORD: ${{ secrets.MAVEN_SIGNATURE_PASSWORD }} + - name: Run tests + run: ./scripts/test diff --git a/.github/workflows/publish-sonatype.yml b/.github/workflows/publish-sonatype.yml new file mode 100644 index 00000000..bb1398a4 --- /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/trycourier/courier-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 + 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.COURIER_SONATYPE_USERNAME || secrets.SONATYPE_USERNAME }} + SONATYPE_PASSWORD: ${{ secrets.COURIER_SONATYPE_PASSWORD || secrets.SONATYPE_PASSWORD }} + GPG_SIGNING_KEY: ${{ secrets.COURIER_SONATYPE_GPG_SIGNING_KEY || secrets.GPG_SIGNING_KEY }} + GPG_SIGNING_PASSWORD: ${{ secrets.COURIER_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 00000000..ba006aee --- /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 == 'trycourier/courier-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.COURIER_SONATYPE_USERNAME || secrets.SONATYPE_USERNAME }} + SONATYPE_PASSWORD: ${{ secrets.COURIER_SONATYPE_PASSWORD || secrets.SONATYPE_PASSWORD }} + GPG_SIGNING_KEY: ${{ secrets.COURIER_SONATYPE_GPG_SIGNING_KEY || secrets.GPG_SIGNING_KEY }} + GPG_SIGNING_PASSWORD: ${{ secrets.COURIER_SONATYPE_GPG_SIGNING_PASSWORD || secrets.GPG_SIGNING_PASSWORD }} diff --git a/.gitignore b/.gitignore index d4199abc..b1346e6d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,24 +1,7 @@ -*.class -.project +.prism.log .gradle -? -.classpath -.checkstyle -.settings -.node -build - -# IntelliJ -*.iml -*.ipr -*.iws -.idea/ -out/ - -# Eclipse/IntelliJ APT -generated_src/ -generated_testSrc/ -generated/ - -bin -build \ No newline at end of file +.idea +.kotlin +build/ +codegen.log +kls_database.db diff --git a/.publish/prepare.sh b/.publish/prepare.sh deleted file mode 100755 index df3948e3..00000000 --- a/.publish/prepare.sh +++ /dev/null @@ -1,8 +0,0 @@ -# Write key ring file -echo "$MAVEN_SIGNATURE_SECRET_KEY" > armored_key.asc -gpg -o publish_key.gpg --dearmor armored_key.asc - -# Generate gradle.properties file -echo "signing.keyId=$MAVEN_SIGNATURE_KID" > gradle.properties -echo "signing.secretKeyRingFile=publish_key.gpg" >> gradle.properties -echo "signing.password=$MAVEN_SIGNATURE_PASSWORD" >> gradle.properties diff --git a/.release-please-manifest.json b/.release-please-manifest.json new file mode 100644 index 00000000..3d2ac0bd --- /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 new file mode 100644 index 00000000..ed4a28c3 --- /dev/null +++ b/.stats.yml @@ -0,0 +1,4 @@ +configured_endpoints: 77 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/courier%2Fcourier-dac3180af01aad486854bd76602df9cd66d2c245baa2bddf60741d962dc5aa38.yml +openapi_spec_hash: 2ba7c45b6a49a540a97b6a3336547cd4 +config_hash: 61ff8407ac3b017189b34dfe19b0d230 diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..d5f28fd3 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,35 @@ +# Changelog + +## 0.1.0 (2025-10-07) + +Full Changelog: [v0.0.1...v0.1.0](https://github.com/trycourier/courier-java/compare/v0.0.1...v0.1.0) + +### Features + +* **api:** manual updates ([51e1a35](https://github.com/trycourier/courier-java/commit/51e1a35ffcee9de2e8f8eb6b6e5ee443ba3cc1e3)) +* **api:** manual updates ([25ea9c2](https://github.com/trycourier/courier-java/commit/25ea9c20e06aaf842128758a136bcf961dcdc707)) +* **api:** manual updates ([61a87f9](https://github.com/trycourier/courier-java/commit/61a87f9d18bb355e008a69ab86c578d2763fddcc)) +* **api:** manual updates ([822e2a4](https://github.com/trycourier/courier-java/commit/822e2a4a7d93bdc32bfc2c92bd0cc1ac4b3ff359)) +* **api:** manual updates ([6bb1fba](https://github.com/trycourier/courier-java/commit/6bb1fbabc235d3cc1eb7489919bbb71b42bc22e9)) +* **api:** manual updates ([ead7d7c](https://github.com/trycourier/courier-java/commit/ead7d7cbf54c37a6aed22496051334693aa647ea)) +* **api:** manual updates ([e5bfbdb](https://github.com/trycourier/courier-java/commit/e5bfbdb1174fafbc1852694c138e364a98010ef3)) +* **api:** manual updates ([0435076](https://github.com/trycourier/courier-java/commit/043507613239e61b8173032071dd91f3b378c514)) +* **api:** manual updates ([e6ed828](https://github.com/trycourier/courier-java/commit/e6ed82846b54dea4c15295f1df79439dca3c4875)) +* **api:** manual updates ([0ec4d93](https://github.com/trycourier/courier-java/commit/0ec4d9354b7a702a83e9d305ea8a493eda3af820)) +* **api:** manual updates ([70aa287](https://github.com/trycourier/courier-java/commit/70aa2874518fd8f48e5cc8927b7abcea60787b7c)) +* **api:** manual updates ([998a0c1](https://github.com/trycourier/courier-java/commit/998a0c13140b88e4fba9fbd2374e07b3ec6a4849)) +* **api:** manual updates ([1d5dae3](https://github.com/trycourier/courier-java/commit/1d5dae306c780129e17111dae95b55bc600ad6e9)) +* **api:** manual updates ([26e335a](https://github.com/trycourier/courier-java/commit/26e335a72dc4aebf9c3b71f440f317ce4409371c)) +* **api:** manual updates ([6b9f529](https://github.com/trycourier/courier-java/commit/6b9f5296179dccc64931dd2afe8802cf06b69873)) +* **api:** manual updates ([2f68cbe](https://github.com/trycourier/courier-java/commit/2f68cbe54d8ed9f6ae5dc5c060e3067131acf3fb)) +* **api:** manual updates ([33a23f3](https://github.com/trycourier/courier-java/commit/33a23f3e6c64100af51e328215bc7d2a93fef331)) +* **api:** manual updates ([5c5e618](https://github.com/trycourier/courier-java/commit/5c5e61819a03f950fc01468e21f1aa58b3f9a49a)) +* **api:** manual updates ([1a3eab1](https://github.com/trycourier/courier-java/commit/1a3eab10a8b1eba2ed8bbdd82dffb81efae0155f)) +* **api:** manual updates ([e4986bc](https://github.com/trycourier/courier-java/commit/e4986bcd194638319398f2375e0a5304cbda49dd)) +* **api:** manual updates ([ab3ef5d](https://github.com/trycourier/courier-java/commit/ab3ef5d4292e846a80b39ae7c608305830637f64)) + + +### Chores + +* sync repo ([166f09d](https://github.com/trycourier/courier-java/commit/166f09d23f53cda5b63b60a9a785bc9e2e430fb7)) +* update SDK settings ([d4cde45](https://github.com/trycourier/courier-java/commit/d4cde450dc82626223aee050c5c848f70fe79382)) diff --git a/LICENSE b/LICENSE index d82d2ea7..efaa7fe8 100644 --- a/LICENSE +++ b/LICENSE @@ -1,21 +1,201 @@ -MIT License - -Copyright (c) 2020 Courier - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file + 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 Courier + + 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 60ee7d22..8d746006 100644 --- a/README.md +++ b/README.md @@ -1,149 +1,669 @@ -# Courier Java Library +# Courier Java API Library -[![Maven Central](https://img.shields.io/maven-central/v/com.courier/courier-java)](https://central.sonatype.com/artifact/com.courier/courier-java) -[![fern shield](https://img.shields.io/badge/%F0%9F%8C%BF-SDK%20generated%20by%20Fern-brightgreen)](https://buildwithfern.com/?utm_source=trycourier/courier-java/readme) + -This is the official Java library for sending notifications with the [Courier](https://courier.com) REST API. +[![Maven Central](https://img.shields.io/maven-central/v/com.courier.api/courier-java)](https://central.sonatype.com/artifact/com.courier.api/courier-java/0.1.0) +[![javadoc](https://javadoc.io/badge2/com.courier.api/courier-java/0.1.0/javadoc.svg)](https://javadoc.io/doc/com.courier.api/courier-java/0.1.0) -## Documentation + -For a full description of request and response payloads and properties, please see the -[official Courier API docs](https://www.courier.com/docs/reference/). +The Courier Java SDK provides convenient access to the Courier REST API from applications written in Java. -## Requirements +It is generated with [Stainless](https://www.stainless.com/). + + -This library requires Java 11+. +Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.courier.api/courier-java/0.1.0). + + ## Installation -### Gradle + -Add the dependency in your `build.gradle`: +### Gradle -```groovy -dependencies { - implementation 'com.courier:courier-java:x.x.x' -} +```kotlin +implementation("com.courier.api:courier-java:0.1.0") ``` ### Maven -Add the dependency in your `pom.xml`: - ```xml - com.courier - courier-java - 0.x.x + com.courier.api + courier-java + 0.1.0 ``` + + +## Requirements + +This library requires Java 8 or later. + ## Usage -Below is an example of how to instantiate the Courier client -and send a message. ```java -import com.courier.api.Courier; +import com.courier.api.client.CourierClient; +import com.courier.api.client.okhttp.CourierOkHttpClient; +import com.courier.api.core.JsonValue; +import com.courier.api.models.bulk.UserRecipient; +import com.courier.api.models.send.SendMessageParams; +import com.courier.api.models.send.SendMessageResponse; + +// Configures using the `courier.apiKey` and `courier.baseUrl` system properties +// Or configures using the `COURIER_API_KEY` and `COURIER_BASE_URL` environment variables +CourierClient client = CourierOkHttpClient.fromEnv(); + +SendMessageParams params = SendMessageParams.builder() + .message(SendMessageParams.Message.builder() + .to(UserRecipient.builder() + .userId("your_user_id") + .build()) + .data(SendMessageParams.Message.Data.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build()) + .build()) + .build(); +SendMessageResponse response = client.send().message(params); +``` + +## Client configuration + +Configure the client using system properties or environment variables: + +```java +import com.courier.api.client.CourierClient; +import com.courier.api.client.okhttp.CourierOkHttpClient; + +// Configures using the `courier.apiKey` and `courier.baseUrl` system properties +// Or configures using the `COURIER_API_KEY` and `COURIER_BASE_URL` environment variables +CourierClient client = CourierOkHttpClient.fromEnv(); +``` + +Or manually: + +```java +import com.courier.api.client.CourierClient; +import com.courier.api.client.okhttp.CourierOkHttpClient; + +CourierClient client = CourierOkHttpClient.builder() + .apiKey("My API Key") + .build(); +``` + +Or using a combination of the two approaches: + +```java +import com.courier.api.client.CourierClient; +import com.courier.api.client.okhttp.CourierOkHttpClient; + +CourierClient client = CourierOkHttpClient.builder() + // Configures using the `courier.apiKey` and `courier.baseUrl` system properties + // Or configures using the `COURIER_API_KEY` and `COURIER_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` | `courier.apiKey` | `COURIER_API_KEY` | true | - | +| `baseUrl` | `courier.baseUrl` | `COURIER_BASE_URL` | true | `"https://api.courier.com"` | + +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.courier.api.client.CourierClient; + +CourierClient 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 Courier 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.send().message(...)` should be called with an instance of `SendMessageParams`, and it will return an instance of `SendMessageResponse`. + +## 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.courier.api.client.CourierClient; +import com.courier.api.client.okhttp.CourierOkHttpClient; +import com.courier.api.core.JsonValue; +import com.courier.api.models.bulk.UserRecipient; +import com.courier.api.models.send.SendMessageParams; +import com.courier.api.models.send.SendMessageResponse; +import java.util.concurrent.CompletableFuture; + +// Configures using the `courier.apiKey` and `courier.baseUrl` system properties +// Or configures using the `COURIER_API_KEY` and `COURIER_BASE_URL` environment variables +CourierClient client = CourierOkHttpClient.fromEnv(); + +SendMessageParams params = SendMessageParams.builder() + .message(SendMessageParams.Message.builder() + .to(UserRecipient.builder() + .userId("your_user_id") + .build()) + .data(SendMessageParams.Message.Data.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build()) + .build()) + .build(); +CompletableFuture response = client.async().send().message(params); +``` + +Or create an asynchronous client from the beginning: -Courier courier = Courier.builder() - .authorizationToken("YOUR_TOKEN") # Defaults to System.getenv("COURIER_AUTHORIZATION_TOKEN") +```java +import com.courier.api.client.CourierClientAsync; +import com.courier.api.client.okhttp.CourierOkHttpClientAsync; +import com.courier.api.core.JsonValue; +import com.courier.api.models.bulk.UserRecipient; +import com.courier.api.models.send.SendMessageParams; +import com.courier.api.models.send.SendMessageResponse; +import java.util.concurrent.CompletableFuture; + +// Configures using the `courier.apiKey` and `courier.baseUrl` system properties +// Or configures using the `COURIER_API_KEY` and `COURIER_BASE_URL` environment variables +CourierClientAsync client = CourierOkHttpClientAsync.fromEnv(); + +SendMessageParams params = SendMessageParams.builder() + .message(SendMessageParams.Message.builder() + .to(UserRecipient.builder() + .userId("your_user_id") + .build()) + .data(SendMessageParams.Message.Data.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build()) + .build()) .build(); +CompletableFuture response = client.send().message(params); +``` + +The asynchronous client supports the same options as the synchronous one, except most methods return `CompletableFuture`s. + +## Raw responses -courier.send(SendMessageRequest.builder() - .message(Message.of(TemplateMessage.builder() - .template("") - .to(MessageRecipient.of(Recipient.of(UserRecipient.builder() - .email("marty_mcfly@email.com") - .build()))) - .build())) - .build()); +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.courier.api.core.JsonValue; +import com.courier.api.core.http.Headers; +import com.courier.api.core.http.HttpResponseFor; +import com.courier.api.models.bulk.UserRecipient; +import com.courier.api.models.send.SendMessageParams; +import com.courier.api.models.send.SendMessageResponse; + +SendMessageParams params = SendMessageParams.builder() + .message(SendMessageParams.Message.builder() + .to(UserRecipient.builder() + .userId("your_user_id") + .build()) + .data(SendMessageParams.Message.Data.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build()) + .build()) + .build(); +HttpResponseFor response = client.send().withRawResponse().message(params); + +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.courier.api.models.send.SendMessageResponse; + +SendMessageResponse parsedResponse = response.parse(); ``` -## Upgrade Guides +## Error handling + +The SDK throws custom unchecked exception types: + +- [`CourierServiceException`](courier-java-core/src/main/kotlin/com/courier/api/errors/CourierServiceException.kt): Base class for HTTP errors. See this table for which exception subclass is thrown for each HTTP status code: + + | Status | Exception | + | ------ | ---------------------------------------------------------------------------------------------------------------------------- | + | 400 | [`BadRequestException`](courier-java-core/src/main/kotlin/com/courier/api/errors/BadRequestException.kt) | + | 401 | [`UnauthorizedException`](courier-java-core/src/main/kotlin/com/courier/api/errors/UnauthorizedException.kt) | + | 403 | [`PermissionDeniedException`](courier-java-core/src/main/kotlin/com/courier/api/errors/PermissionDeniedException.kt) | + | 404 | [`NotFoundException`](courier-java-core/src/main/kotlin/com/courier/api/errors/NotFoundException.kt) | + | 422 | [`UnprocessableEntityException`](courier-java-core/src/main/kotlin/com/courier/api/errors/UnprocessableEntityException.kt) | + | 429 | [`RateLimitException`](courier-java-core/src/main/kotlin/com/courier/api/errors/RateLimitException.kt) | + | 5xx | [`InternalServerException`](courier-java-core/src/main/kotlin/com/courier/api/errors/InternalServerException.kt) | + | others | [`UnexpectedStatusCodeException`](courier-java-core/src/main/kotlin/com/courier/api/errors/UnexpectedStatusCodeException.kt) | + +- [`CourierIoException`](courier-java-core/src/main/kotlin/com/courier/api/errors/CourierIoException.kt): I/O networking errors. + +- [`CourierRetryableException`](courier-java-core/src/main/kotlin/com/courier/api/errors/CourierRetryableException.kt): Generic error indicating a failure that could be retried by the client. -### v2 to v3 +- [`CourierInvalidDataException`](courier-java-core/src/main/kotlin/com/courier/api/errors/CourierInvalidDataException.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. -v3 of our SDK is automatically generated by [Fern](https://buildwithfern.com/). v3 comes -with several improvements that we describe below: +- [`CourierException`](courier-java-core/src/main/kotlin/com/courier/api/errors/CourierException.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. -- **Resource-scoped SDK methods**: Endpoints are scoped under their resource. For - example, instead of `courier.deleteBrands` the SDK now reads `courier.brands.delete(...)` -- **Docs on Hover**: All endpoint and parameter level documentation that you see - on our docs website is now embedded directly within the SDKs. -- **Retries with exponential backoff**: The SDK will automatically retry failures with - exponential backoff. -- **Strongly Typed**: The SDK has Java objects to describe each of our request and - response models. Each object has a static `builder` method and uses the staged - builder pattern. - ```java - UserRecipient.builder() - .email("marty_mcfly@email.com") - .build(); - ``` -- **Unions** The SDK has natively supports unions. Every union is modelled as a java - class that has static factory methods. - ```java - // Message has static factory methods that either take a TemplateMessage or - // ContentMessage - Message.of(TemplateMessage.builder()...) - - Message.of(ContentMessage.builder()...) - ``` +## Logging -## Request Options -Every endpoint has an overloaded equivalent which takes [RequestOptions](./src/main/java/com/courier/api/core/RequestOptions.java) -that allow you to override settings for that particular request. +The SDK uses the standard [OkHttp logging interceptor](https://github.com/square/okhttp/tree/master/okhttp-logging-interceptor). + +Enable logging by setting the `COURIER_LOG` environment variable to `info`: + +```sh +$ export COURIER_LOG=info +``` + +Or to `debug` for more verbose logging: + +```sh +$ export COURIER_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 `courier-java-core` is published with a [configuration file](courier-java-core/src/main/resources/META-INF/proguard/courier-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 [`CourierOkHttpClient`](courier-java-client-okhttp/src/main/kotlin/com/courier/api/client/okhttp/CourierOkHttpClient.kt) or [`CourierOkHttpClientAsync`](courier-java-client-okhttp/src/main/kotlin/com/courier/api/client/okhttp/CourierOkHttpClientAsync.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.courier.api.Courier; +import com.courier.api.client.CourierClient; +import com.courier.api.client.okhttp.CourierOkHttpClient; -courier.brands.get(..., RequestOptions.builder() - .authorizationToken(...) - .build()) +CourierClient client = CourierOkHttpClient.builder() + .fromEnv() + .maxRetries(4) + .build(); ``` -## Idempotency Headers -You can specify idempotency headers by providing an `IdempotentRequestOptions` parameter. +### 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.courier.api.Courier; -import java.util.UUID; +import com.courier.api.models.send.SendMessageResponse; -courier.send(..., IdempotentRequestOptions.builder() - .idempotencyKey(UUID.randomUUID().toString()) - .build()) +SendMessageResponse response = client.send().message( + params, RequestOptions.builder().timeout(Duration.ofSeconds(30)).build() +); ``` -## Exception Handling -All errors thrown by the SDK will be subclasses of `com.courier.api.APIError`. +Or configure the default for all method calls at the client level: ```java -import com.courier.api.core.ApiError; +import com.courier.api.client.CourierClient; +import com.courier.api.client.okhttp.CourierOkHttpClient; +import java.time.Duration; -try { - courier.brands.get(...) -} catch (ApiError e) { - System.out.println(e.statusCode()); - System.out.println(e.body()); +CourierClient client = CourierOkHttpClient.builder() + .fromEnv() + .timeout(Duration.ofSeconds(30)) + .build(); +``` + +### Proxies + +To route requests through a proxy, configure the client using the `proxy` method: + +```java +import com.courier.api.client.CourierClient; +import com.courier.api.client.okhttp.CourierOkHttpClient; +import java.net.InetSocketAddress; +import java.net.Proxy; + +CourierClient client = CourierOkHttpClient.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.courier.api.client.CourierClient; +import com.courier.api.client.okhttp.CourierOkHttpClient; + +CourierClient client = CourierOkHttpClient.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: + +- `courier-java-core` + - Contains core SDK logic + - Does not depend on [OkHttp](https://square.github.io/okhttp) + - Exposes [`CourierClient`](courier-java-core/src/main/kotlin/com/courier/api/client/CourierClient.kt), [`CourierClientAsync`](courier-java-core/src/main/kotlin/com/courier/api/client/CourierClientAsync.kt), [`CourierClientImpl`](courier-java-core/src/main/kotlin/com/courier/api/client/CourierClientImpl.kt), and [`CourierClientAsyncImpl`](courier-java-core/src/main/kotlin/com/courier/api/client/CourierClientAsyncImpl.kt), all of which can work with any HTTP client +- `courier-java-client-okhttp` + - Depends on [OkHttp](https://square.github.io/okhttp) + - Exposes [`CourierOkHttpClient`](courier-java-client-okhttp/src/main/kotlin/com/courier/api/client/okhttp/CourierOkHttpClient.kt) and [`CourierOkHttpClientAsync`](courier-java-client-okhttp/src/main/kotlin/com/courier/api/client/okhttp/CourierOkHttpClientAsync.kt), which provide a way to construct [`CourierClientImpl`](courier-java-core/src/main/kotlin/com/courier/api/client/CourierClientImpl.kt) and [`CourierClientAsyncImpl`](courier-java-core/src/main/kotlin/com/courier/api/client/CourierClientAsyncImpl.kt), respectively, using OkHttp +- `courier-java` + - Depends on and exposes the APIs of both `courier-java-core` and `courier-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 [`courier-java` dependency](#installation) with `courier-java-core` +2. Copy `courier-java-client-okhttp`'s [`OkHttpClient`](courier-java-client-okhttp/src/main/kotlin/com/courier/api/client/okhttp/OkHttpClient.kt) class into your code and customize it +3. Construct [`CourierClientImpl`](courier-java-core/src/main/kotlin/com/courier/api/client/CourierClientImpl.kt) or [`CourierClientAsyncImpl`](courier-java-core/src/main/kotlin/com/courier/api/client/CourierClientAsyncImpl.kt), similarly to [`CourierOkHttpClient`](courier-java-client-okhttp/src/main/kotlin/com/courier/api/client/okhttp/CourierOkHttpClient.kt) or [`CourierOkHttpClientAsync`](courier-java-client-okhttp/src/main/kotlin/com/courier/api/client/okhttp/CourierOkHttpClientAsync.kt), using your customized client + +### Completely custom HTTP client + +To use a completely custom HTTP client: + +1. Replace your [`courier-java` dependency](#installation) with `courier-java-core` +2. Write a class that implements the [`HttpClient`](courier-java-core/src/main/kotlin/com/courier/api/core/http/HttpClient.kt) interface +3. Construct [`CourierClientImpl`](courier-java-core/src/main/kotlin/com/courier/api/client/CourierClientImpl.kt) or [`CourierClientAsyncImpl`](courier-java-core/src/main/kotlin/com/courier/api/client/CourierClientAsyncImpl.kt), similarly to [`CourierOkHttpClient`](courier-java-client-okhttp/src/main/kotlin/com/courier/api/client/okhttp/CourierOkHttpClient.kt) or [`CourierOkHttpClientAsync`](courier-java-client-okhttp/src/main/kotlin/com/courier/api/client/okhttp/CourierOkHttpClientAsync.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.courier.api.core.JsonValue; +import com.courier.api.models.send.SendMessageParams; + +SendMessageParams params = SendMessageParams.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 undocumented parameters on _nested_ headers, query params, or body classes, call the `putAdditionalProperty` method on the nested class: + +```java +import com.courier.api.core.JsonValue; +import com.courier.api.models.send.SendMessageParams; + +SendMessageParams params = SendMessageParams.builder() + .message(SendMessageParams.Message.builder() + .putAdditionalProperty("secretProperty", JsonValue.from("42")) + .build()) + .build(); +``` + +These properties can be accessed on the nested built object later using the `_additionalProperties()` method. + +To set a documented parameter or property to an undocumented or not yet supported _value_, pass a [`JsonValue`](courier-java-core/src/main/kotlin/com/courier/api/core/Values.kt) object to its setter: + +```java +import com.courier.api.core.JsonValue; +import com.courier.api.models.send.SendMessageParams; + +SendMessageParams params = SendMessageParams.builder() + .message(JsonValue.from(42)) + .build(); +``` + +The most straightforward way to create a [`JsonValue`](courier-java-core/src/main/kotlin/com/courier/api/core/Values.kt) is using its `from(...)` method: + +```java +import com.courier.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`](courier-java-core/src/main/kotlin/com/courier/api/core/Values.kt): + +```java +import com.courier.api.core.JsonMissing; +import com.courier.api.models.send.SendMessageParams; + +SendMessageParams params = SendMessageParams.builder() + .message(JsonMissing.of()) + .build(); +``` + +### Response properties + +To access undocumented response properties, call the `_additionalProperties()` method: + +```java +import com.courier.api.core.JsonValue; +import java.util.Map; + +Map additionalProperties = client.send().message(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.courier.api.core.JsonField; +import com.courier.api.models.send.SendMessageParams; +import java.util.Optional; + +JsonField message = client.send().message(params)._message(); + +if (message.isMissing()) { + // The property is absent from the JSON response +} else if (message.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 = message.asString(); + + // Try to deserialize into a custom type + MyClass myObject = message.asUnknown().orElseThrow().convert(MyClass.class); } ``` -## Retries -409 Conflict, 429 Rate Limit, and >=500 Internal errors will all be retried twice -with exponential backoff. +### 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 [`CourierInvalidDataException`](courier-java-core/src/main/kotlin/com/courier/api/errors/CourierInvalidDataException.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.courier.api.models.send.SendMessageResponse; + +SendMessageResponse response = client.send().message(params).validate(); +``` + +Or configure the method call to validate the response using the `responseValidation` method: + +```java +import com.courier.api.models.send.SendMessageResponse; + +SendMessageResponse response = client.send().message( + params, RequestOptions.builder().responseValidation(true).build() +); +``` -## Additional Properties -Sometimes, the server response may include additional properties that are not -available in the SDK. Use the `getAdditionalProperties()` method to access them. +Or configure the default for all method calls at the client level: ```java -Object value = entity.getAdditionalProperties().get("new_prop"); +import com.courier.api.client.CourierClient; +import com.courier.api.client.okhttp.CourierOkHttpClient; + +CourierClient client = CourierOkHttpClient.builder() + .fromEnv() + .responseValidation(true) + .build(); ``` -## Contributing -While we value open-source contributions to this SDK, this library is generated programmatically. -Additions made directly to this library would have to be moved over to our generation code, otherwise -they would be overwritten upon the next generated release. Feel free to open a PR as a proof of concept, -but know that we will not be able to merge it as-is. We suggest opening an issue first to discuss with us! +## 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. -On the other hand, contributions to the README are always very welcome! \ No newline at end of file +We are keen for your feedback; please open an [issue](https://www.github.com/trycourier/courier-java/issues) with questions, bugs, or suggestions. diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000..e8a2e774 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,23 @@ +# 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 Courier, please follow the respective company's security reporting guidelines. + +--- + +Thank you for helping us keep the SDKs and systems they interact with secure. diff --git a/bin/check-release-environment b/bin/check-release-environment new file mode 100644 index 00000000..3a6a7b4a --- /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 b/build.gradle deleted file mode 100644 index 2154b2e1..00000000 --- a/build.gradle +++ /dev/null @@ -1,88 +0,0 @@ -plugins { - id 'java-library' - id 'maven-publish' - id 'com.diffplug.spotless' version '6.11.0' - id 'signing' -} - -repositories { - mavenCentral() - maven { - url 'https://oss.sonatype.org/service/local/staging/deploy/maven2/' - } -} - -dependencies { - api 'com.squareup.okhttp3:okhttp:4.12.0' - api 'com.fasterxml.jackson.core:jackson-databind:2.13.0' - api 'com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.12.3' - api 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.12.3' - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2' - testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.8.2' -} - - -sourceCompatibility = 1.8 -targetCompatibility = 1.8 - -spotless { - java { - palantirJavaFormat() - } -} - -java { - withSourcesJar() - withJavadocJar() -} - -signing { - sign(publishing.publications) -} -test { - useJUnitPlatform() - testLogging { - showStandardStreams = true - } -} -publishing { - publications { - maven(MavenPublication) { - groupId = 'com.courier' - artifactId = 'courier-java' - version = '3.6.0' - from components.java - pom { - name = 'courier' - description = 'The official Java library for sending notifications with the Courier REST API.' - url = 'https://www.courier.com/docs/reference/' - licenses { - license { - name = 'MIT' - } - } - developers { - developer { - name = 'courier' - email = 'developers@courier.com' - } - } - scm { - connection = 'scm:git:git://github.com/trycourier/courier-java.git' - developerConnection = 'scm:git:git://github.com/trycourier/courier-java.git' - url = 'https://github.com/trycourier/courier-java' - } - } - } - } - repositories { - maven { - url "$System.env.MAVEN_PUBLISH_REGISTRY_URL" - credentials { - username "$System.env.MAVEN_USERNAME" - password "$System.env.MAVEN_PASSWORD" - } - } - } -} - diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 00000000..d942981c --- /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.courier.api" + version = "0.1.0" // x-release-please-version +} + +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 != "courier-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 00000000..0b141353 --- /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/courier.java.gradle.kts b/buildSrc/src/main/kotlin/courier.java.gradle.kts new file mode 100644 index 00000000..81d5d32b --- /dev/null +++ b/buildSrc/src/main/kotlin/courier.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/courier.kotlin.gradle.kts b/buildSrc/src/main/kotlin/courier.kotlin.gradle.kts new file mode 100644 index 00000000..365ccefa --- /dev/null +++ b/buildSrc/src/main/kotlin/courier.kotlin.gradle.kts @@ -0,0 +1,106 @@ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget +import org.jetbrains.kotlin.gradle.dsl.KotlinVersion + +plugins { + id("courier.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/courier.publish.gradle.kts b/buildSrc/src/main/kotlin/courier.publish.gradle.kts new file mode 100644 index 00000000..e36e7d24 --- /dev/null +++ b/buildSrc/src/main/kotlin/courier.publish.gradle.kts @@ -0,0 +1,60 @@ +plugins { + `maven-publish` + signing +} + +configure { + publications { + register("maven") { + from(components["java"]) + + pom { + name.set("Courier") + description.set("An SDK library for courier") + url.set("https://www.github.com/trycourier/courier-java") + + licenses { + license { + name.set("Apache-2.0") + } + } + + developers { + developer { + name.set("Courier") + } + } + + scm { + connection.set("scm:git:git://github.com/trycourier/courier-java.git") + developerConnection.set("scm:git:git://github.com/trycourier/courier-java.git") + url.set("https://github.com/trycourier/courier-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/courier-java-client-okhttp/build.gradle.kts b/courier-java-client-okhttp/build.gradle.kts new file mode 100644 index 00000000..4b62416c --- /dev/null +++ b/courier-java-client-okhttp/build.gradle.kts @@ -0,0 +1,14 @@ +plugins { + id("courier.kotlin") + id("courier.publish") +} + +dependencies { + api(project(":courier-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/courier-java-client-okhttp/src/main/kotlin/com/courier/api/client/okhttp/CourierOkHttpClient.kt b/courier-java-client-okhttp/src/main/kotlin/com/courier/api/client/okhttp/CourierOkHttpClient.kt new file mode 100644 index 00000000..4ff91a1b --- /dev/null +++ b/courier-java-client-okhttp/src/main/kotlin/com/courier/api/client/okhttp/CourierOkHttpClient.kt @@ -0,0 +1,307 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.client.okhttp + +import com.courier.api.client.CourierClient +import com.courier.api.client.CourierClientImpl +import com.courier.api.core.ClientOptions +import com.courier.api.core.Sleeper +import com.courier.api.core.Timeout +import com.courier.api.core.http.Headers +import com.courier.api.core.http.HttpClient +import com.courier.api.core.http.QueryParams +import com.courier.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 [CourierClient] with [OkHttpClient] as the underlying + * [HttpClient]. + */ +class CourierOkHttpClient private constructor() { + + companion object { + + /** Returns a mutable builder for constructing an instance of [CourierClient]. */ + @JvmStatic fun builder() = Builder() + + /** + * Returns a client configured using system properties and environment variables. + * + * @see ClientOptions.Builder.fromEnv + */ + @JvmStatic fun fromEnv(): CourierClient = builder().fromEnv().build() + } + + /** A builder for [CourierOkHttpClient]. */ + 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.courier.api.core.jsonMapper]. The default is usually sufficient and + * rarely needs to be overridden. + */ + 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. + * + * 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://api.courier.com`. + */ + 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) } + + 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 [CourierClient]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): CourierClient = + CourierClientImpl( + clientOptions + .httpClient( + OkHttpClient.builder() + .timeout(clientOptions.timeout()) + .proxy(proxy) + .sslSocketFactory(sslSocketFactory) + .trustManager(trustManager) + .hostnameVerifier(hostnameVerifier) + .build() + ) + .build() + ) + } +} diff --git a/courier-java-client-okhttp/src/main/kotlin/com/courier/api/client/okhttp/CourierOkHttpClientAsync.kt b/courier-java-client-okhttp/src/main/kotlin/com/courier/api/client/okhttp/CourierOkHttpClientAsync.kt new file mode 100644 index 00000000..9360f485 --- /dev/null +++ b/courier-java-client-okhttp/src/main/kotlin/com/courier/api/client/okhttp/CourierOkHttpClientAsync.kt @@ -0,0 +1,307 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.client.okhttp + +import com.courier.api.client.CourierClientAsync +import com.courier.api.client.CourierClientAsyncImpl +import com.courier.api.core.ClientOptions +import com.courier.api.core.Sleeper +import com.courier.api.core.Timeout +import com.courier.api.core.http.Headers +import com.courier.api.core.http.HttpClient +import com.courier.api.core.http.QueryParams +import com.courier.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 [CourierClientAsync] with [OkHttpClient] as the + * underlying [HttpClient]. + */ +class CourierOkHttpClientAsync private constructor() { + + companion object { + + /** Returns a mutable builder for constructing an instance of [CourierClientAsync]. */ + @JvmStatic fun builder() = Builder() + + /** + * Returns a client configured using system properties and environment variables. + * + * @see ClientOptions.Builder.fromEnv + */ + @JvmStatic fun fromEnv(): CourierClientAsync = builder().fromEnv().build() + } + + /** A builder for [CourierOkHttpClientAsync]. */ + 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.courier.api.core.jsonMapper]. The default is usually sufficient and + * rarely needs to be overridden. + */ + 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. + * + * 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://api.courier.com`. + */ + 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) } + + 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 [CourierClientAsync]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): CourierClientAsync = + CourierClientAsyncImpl( + clientOptions + .httpClient( + OkHttpClient.builder() + .timeout(clientOptions.timeout()) + .proxy(proxy) + .sslSocketFactory(sslSocketFactory) + .trustManager(trustManager) + .hostnameVerifier(hostnameVerifier) + .build() + ) + .build() + ) + } +} diff --git a/courier-java-client-okhttp/src/main/kotlin/com/courier/api/client/okhttp/OkHttpClient.kt b/courier-java-client-okhttp/src/main/kotlin/com/courier/api/client/okhttp/OkHttpClient.kt new file mode 100644 index 00000000..33ff3abe --- /dev/null +++ b/courier-java-client-okhttp/src/main/kotlin/com/courier/api/client/okhttp/OkHttpClient.kt @@ -0,0 +1,246 @@ +package com.courier.api.client.okhttp + +import com.courier.api.core.RequestOptions +import com.courier.api.core.Timeout +import com.courier.api.core.http.Headers +import com.courier.api.core.http.HttpClient +import com.courier.api.core.http.HttpMethod +import com.courier.api.core.http.HttpRequest +import com.courier.api.core.http.HttpRequestBody +import com.courier.api.core.http.HttpResponse +import com.courier.api.errors.CourierIoException +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 CourierIoException("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(CourierIoException("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("COURIER_LOG")?.lowercase()) { + "info" -> HttpLoggingInterceptor.Level.BASIC + "debug" -> HttpLoggingInterceptor.Level.BODY + else -> null + } + if (logLevel != null) { + clientBuilder.addNetworkInterceptor( + HttpLoggingInterceptor().setLevel(logLevel).apply { redactHeader("Authorization") } + ) + } + + 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/courier-java-core/build.gradle.kts b/courier-java-core/build.gradle.kts new file mode 100644 index 00000000..d31e4b11 --- /dev/null +++ b/courier-java-core/build.gradle.kts @@ -0,0 +1,41 @@ +plugins { + id("courier.kotlin") + id("courier.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(":courier-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/courier-java-core/src/main/kotlin/com/courier/api/client/CourierClient.kt b/courier-java-core/src/main/kotlin/com/courier/api/client/CourierClient.kt new file mode 100644 index 00000000..40eafc21 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/client/CourierClient.kt @@ -0,0 +1,147 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.client + +import com.courier.api.core.ClientOptions +import com.courier.api.services.blocking.AudienceService +import com.courier.api.services.blocking.AuditEventService +import com.courier.api.services.blocking.AuthService +import com.courier.api.services.blocking.AutomationService +import com.courier.api.services.blocking.BrandService +import com.courier.api.services.blocking.BulkService +import com.courier.api.services.blocking.InboundService +import com.courier.api.services.blocking.ListService +import com.courier.api.services.blocking.MessageService +import com.courier.api.services.blocking.NotificationService +import com.courier.api.services.blocking.ProfileService +import com.courier.api.services.blocking.RequestService +import com.courier.api.services.blocking.SendService +import com.courier.api.services.blocking.TenantService +import com.courier.api.services.blocking.TranslationService +import com.courier.api.services.blocking.UserService +import java.util.function.Consumer + +/** + * A client for interacting with the Courier 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 CourierClient { + + /** + * 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(): CourierClientAsync + + /** + * 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): CourierClient + + fun send(): SendService + + fun tenants(): TenantService + + fun audiences(): AudienceService + + fun bulk(): BulkService + + fun users(): UserService + + fun auditEvents(): AuditEventService + + fun automations(): AutomationService + + fun brands(): BrandService + + fun lists(): ListService + + fun messages(): MessageService + + fun notifications(): NotificationService + + fun auth(): AuthService + + fun inbound(): InboundService + + fun requests(): RequestService + + fun profiles(): ProfileService + + fun translations(): TranslationService + + /** + * 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 [CourierClient] 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): CourierClient.WithRawResponse + + fun send(): SendService.WithRawResponse + + fun tenants(): TenantService.WithRawResponse + + fun audiences(): AudienceService.WithRawResponse + + fun bulk(): BulkService.WithRawResponse + + fun users(): UserService.WithRawResponse + + fun auditEvents(): AuditEventService.WithRawResponse + + fun automations(): AutomationService.WithRawResponse + + fun brands(): BrandService.WithRawResponse + + fun lists(): ListService.WithRawResponse + + fun messages(): MessageService.WithRawResponse + + fun notifications(): NotificationService.WithRawResponse + + fun auth(): AuthService.WithRawResponse + + fun inbound(): InboundService.WithRawResponse + + fun requests(): RequestService.WithRawResponse + + fun profiles(): ProfileService.WithRawResponse + + fun translations(): TranslationService.WithRawResponse + } +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/client/CourierClientAsync.kt b/courier-java-core/src/main/kotlin/com/courier/api/client/CourierClientAsync.kt new file mode 100644 index 00000000..ba61d964 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/client/CourierClientAsync.kt @@ -0,0 +1,151 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.client + +import com.courier.api.core.ClientOptions +import com.courier.api.services.async.AudienceServiceAsync +import com.courier.api.services.async.AuditEventServiceAsync +import com.courier.api.services.async.AuthServiceAsync +import com.courier.api.services.async.AutomationServiceAsync +import com.courier.api.services.async.BrandServiceAsync +import com.courier.api.services.async.BulkServiceAsync +import com.courier.api.services.async.InboundServiceAsync +import com.courier.api.services.async.ListServiceAsync +import com.courier.api.services.async.MessageServiceAsync +import com.courier.api.services.async.NotificationServiceAsync +import com.courier.api.services.async.ProfileServiceAsync +import com.courier.api.services.async.RequestServiceAsync +import com.courier.api.services.async.SendServiceAsync +import com.courier.api.services.async.TenantServiceAsync +import com.courier.api.services.async.TranslationServiceAsync +import com.courier.api.services.async.UserServiceAsync +import java.util.function.Consumer + +/** + * A client for interacting with the Courier 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 CourierClientAsync { + + /** + * 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(): CourierClient + + /** + * 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): CourierClientAsync + + fun send(): SendServiceAsync + + fun tenants(): TenantServiceAsync + + fun audiences(): AudienceServiceAsync + + fun bulk(): BulkServiceAsync + + fun users(): UserServiceAsync + + fun auditEvents(): AuditEventServiceAsync + + fun automations(): AutomationServiceAsync + + fun brands(): BrandServiceAsync + + fun lists(): ListServiceAsync + + fun messages(): MessageServiceAsync + + fun notifications(): NotificationServiceAsync + + fun auth(): AuthServiceAsync + + fun inbound(): InboundServiceAsync + + fun requests(): RequestServiceAsync + + fun profiles(): ProfileServiceAsync + + fun translations(): TranslationServiceAsync + + /** + * 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 [CourierClientAsync] 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 + ): CourierClientAsync.WithRawResponse + + fun send(): SendServiceAsync.WithRawResponse + + fun tenants(): TenantServiceAsync.WithRawResponse + + fun audiences(): AudienceServiceAsync.WithRawResponse + + fun bulk(): BulkServiceAsync.WithRawResponse + + fun users(): UserServiceAsync.WithRawResponse + + fun auditEvents(): AuditEventServiceAsync.WithRawResponse + + fun automations(): AutomationServiceAsync.WithRawResponse + + fun brands(): BrandServiceAsync.WithRawResponse + + fun lists(): ListServiceAsync.WithRawResponse + + fun messages(): MessageServiceAsync.WithRawResponse + + fun notifications(): NotificationServiceAsync.WithRawResponse + + fun auth(): AuthServiceAsync.WithRawResponse + + fun inbound(): InboundServiceAsync.WithRawResponse + + fun requests(): RequestServiceAsync.WithRawResponse + + fun profiles(): ProfileServiceAsync.WithRawResponse + + fun translations(): TranslationServiceAsync.WithRawResponse + } +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/client/CourierClientAsyncImpl.kt b/courier-java-core/src/main/kotlin/com/courier/api/client/CourierClientAsyncImpl.kt new file mode 100644 index 00000000..a202cd8d --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/client/CourierClientAsyncImpl.kt @@ -0,0 +1,259 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.client + +import com.courier.api.core.ClientOptions +import com.courier.api.core.getPackageVersion +import com.courier.api.services.async.AudienceServiceAsync +import com.courier.api.services.async.AudienceServiceAsyncImpl +import com.courier.api.services.async.AuditEventServiceAsync +import com.courier.api.services.async.AuditEventServiceAsyncImpl +import com.courier.api.services.async.AuthServiceAsync +import com.courier.api.services.async.AuthServiceAsyncImpl +import com.courier.api.services.async.AutomationServiceAsync +import com.courier.api.services.async.AutomationServiceAsyncImpl +import com.courier.api.services.async.BrandServiceAsync +import com.courier.api.services.async.BrandServiceAsyncImpl +import com.courier.api.services.async.BulkServiceAsync +import com.courier.api.services.async.BulkServiceAsyncImpl +import com.courier.api.services.async.InboundServiceAsync +import com.courier.api.services.async.InboundServiceAsyncImpl +import com.courier.api.services.async.ListServiceAsync +import com.courier.api.services.async.ListServiceAsyncImpl +import com.courier.api.services.async.MessageServiceAsync +import com.courier.api.services.async.MessageServiceAsyncImpl +import com.courier.api.services.async.NotificationServiceAsync +import com.courier.api.services.async.NotificationServiceAsyncImpl +import com.courier.api.services.async.ProfileServiceAsync +import com.courier.api.services.async.ProfileServiceAsyncImpl +import com.courier.api.services.async.RequestServiceAsync +import com.courier.api.services.async.RequestServiceAsyncImpl +import com.courier.api.services.async.SendServiceAsync +import com.courier.api.services.async.SendServiceAsyncImpl +import com.courier.api.services.async.TenantServiceAsync +import com.courier.api.services.async.TenantServiceAsyncImpl +import com.courier.api.services.async.TranslationServiceAsync +import com.courier.api.services.async.TranslationServiceAsyncImpl +import com.courier.api.services.async.UserServiceAsync +import com.courier.api.services.async.UserServiceAsyncImpl +import java.util.function.Consumer + +class CourierClientAsyncImpl(private val clientOptions: ClientOptions) : CourierClientAsync { + + 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: CourierClient by lazy { CourierClientImpl(clientOptions) } + + private val withRawResponse: CourierClientAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + private val send: SendServiceAsync by lazy { SendServiceAsyncImpl(clientOptionsWithUserAgent) } + + private val tenants: TenantServiceAsync by lazy { + TenantServiceAsyncImpl(clientOptionsWithUserAgent) + } + + private val audiences: AudienceServiceAsync by lazy { + AudienceServiceAsyncImpl(clientOptionsWithUserAgent) + } + + private val bulk: BulkServiceAsync by lazy { BulkServiceAsyncImpl(clientOptionsWithUserAgent) } + + private val users: UserServiceAsync by lazy { UserServiceAsyncImpl(clientOptionsWithUserAgent) } + + private val auditEvents: AuditEventServiceAsync by lazy { + AuditEventServiceAsyncImpl(clientOptionsWithUserAgent) + } + + private val automations: AutomationServiceAsync by lazy { + AutomationServiceAsyncImpl(clientOptionsWithUserAgent) + } + + private val brands: BrandServiceAsync by lazy { + BrandServiceAsyncImpl(clientOptionsWithUserAgent) + } + + private val lists: ListServiceAsync by lazy { ListServiceAsyncImpl(clientOptionsWithUserAgent) } + + private val messages: MessageServiceAsync by lazy { + MessageServiceAsyncImpl(clientOptionsWithUserAgent) + } + + private val notifications: NotificationServiceAsync by lazy { + NotificationServiceAsyncImpl(clientOptionsWithUserAgent) + } + + private val auth: AuthServiceAsync by lazy { AuthServiceAsyncImpl(clientOptionsWithUserAgent) } + + private val inbound: InboundServiceAsync by lazy { + InboundServiceAsyncImpl(clientOptionsWithUserAgent) + } + + private val requests: RequestServiceAsync by lazy { + RequestServiceAsyncImpl(clientOptionsWithUserAgent) + } + + private val profiles: ProfileServiceAsync by lazy { + ProfileServiceAsyncImpl(clientOptionsWithUserAgent) + } + + private val translations: TranslationServiceAsync by lazy { + TranslationServiceAsyncImpl(clientOptionsWithUserAgent) + } + + override fun sync(): CourierClient = sync + + override fun withRawResponse(): CourierClientAsync.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): CourierClientAsync = + CourierClientAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun send(): SendServiceAsync = send + + override fun tenants(): TenantServiceAsync = tenants + + override fun audiences(): AudienceServiceAsync = audiences + + override fun bulk(): BulkServiceAsync = bulk + + override fun users(): UserServiceAsync = users + + override fun auditEvents(): AuditEventServiceAsync = auditEvents + + override fun automations(): AutomationServiceAsync = automations + + override fun brands(): BrandServiceAsync = brands + + override fun lists(): ListServiceAsync = lists + + override fun messages(): MessageServiceAsync = messages + + override fun notifications(): NotificationServiceAsync = notifications + + override fun auth(): AuthServiceAsync = auth + + override fun inbound(): InboundServiceAsync = inbound + + override fun requests(): RequestServiceAsync = requests + + override fun profiles(): ProfileServiceAsync = profiles + + override fun translations(): TranslationServiceAsync = translations + + override fun close() = clientOptions.close() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + CourierClientAsync.WithRawResponse { + + private val send: SendServiceAsync.WithRawResponse by lazy { + SendServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val tenants: TenantServiceAsync.WithRawResponse by lazy { + TenantServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val audiences: AudienceServiceAsync.WithRawResponse by lazy { + AudienceServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val bulk: BulkServiceAsync.WithRawResponse by lazy { + BulkServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val users: UserServiceAsync.WithRawResponse by lazy { + UserServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val auditEvents: AuditEventServiceAsync.WithRawResponse by lazy { + AuditEventServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val automations: AutomationServiceAsync.WithRawResponse by lazy { + AutomationServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val brands: BrandServiceAsync.WithRawResponse by lazy { + BrandServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val lists: ListServiceAsync.WithRawResponse by lazy { + ListServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val messages: MessageServiceAsync.WithRawResponse by lazy { + MessageServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val notifications: NotificationServiceAsync.WithRawResponse by lazy { + NotificationServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val auth: AuthServiceAsync.WithRawResponse by lazy { + AuthServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val inbound: InboundServiceAsync.WithRawResponse by lazy { + InboundServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val requests: RequestServiceAsync.WithRawResponse by lazy { + RequestServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val profiles: ProfileServiceAsync.WithRawResponse by lazy { + ProfileServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val translations: TranslationServiceAsync.WithRawResponse by lazy { + TranslationServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + override fun withOptions( + modifier: Consumer + ): CourierClientAsync.WithRawResponse = + CourierClientAsyncImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + override fun send(): SendServiceAsync.WithRawResponse = send + + override fun tenants(): TenantServiceAsync.WithRawResponse = tenants + + override fun audiences(): AudienceServiceAsync.WithRawResponse = audiences + + override fun bulk(): BulkServiceAsync.WithRawResponse = bulk + + override fun users(): UserServiceAsync.WithRawResponse = users + + override fun auditEvents(): AuditEventServiceAsync.WithRawResponse = auditEvents + + override fun automations(): AutomationServiceAsync.WithRawResponse = automations + + override fun brands(): BrandServiceAsync.WithRawResponse = brands + + override fun lists(): ListServiceAsync.WithRawResponse = lists + + override fun messages(): MessageServiceAsync.WithRawResponse = messages + + override fun notifications(): NotificationServiceAsync.WithRawResponse = notifications + + override fun auth(): AuthServiceAsync.WithRawResponse = auth + + override fun inbound(): InboundServiceAsync.WithRawResponse = inbound + + override fun requests(): RequestServiceAsync.WithRawResponse = requests + + override fun profiles(): ProfileServiceAsync.WithRawResponse = profiles + + override fun translations(): TranslationServiceAsync.WithRawResponse = translations + } +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/client/CourierClientImpl.kt b/courier-java-core/src/main/kotlin/com/courier/api/client/CourierClientImpl.kt new file mode 100644 index 00000000..1c35f756 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/client/CourierClientImpl.kt @@ -0,0 +1,247 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.client + +import com.courier.api.core.ClientOptions +import com.courier.api.core.getPackageVersion +import com.courier.api.services.blocking.AudienceService +import com.courier.api.services.blocking.AudienceServiceImpl +import com.courier.api.services.blocking.AuditEventService +import com.courier.api.services.blocking.AuditEventServiceImpl +import com.courier.api.services.blocking.AuthService +import com.courier.api.services.blocking.AuthServiceImpl +import com.courier.api.services.blocking.AutomationService +import com.courier.api.services.blocking.AutomationServiceImpl +import com.courier.api.services.blocking.BrandService +import com.courier.api.services.blocking.BrandServiceImpl +import com.courier.api.services.blocking.BulkService +import com.courier.api.services.blocking.BulkServiceImpl +import com.courier.api.services.blocking.InboundService +import com.courier.api.services.blocking.InboundServiceImpl +import com.courier.api.services.blocking.ListService +import com.courier.api.services.blocking.ListServiceImpl +import com.courier.api.services.blocking.MessageService +import com.courier.api.services.blocking.MessageServiceImpl +import com.courier.api.services.blocking.NotificationService +import com.courier.api.services.blocking.NotificationServiceImpl +import com.courier.api.services.blocking.ProfileService +import com.courier.api.services.blocking.ProfileServiceImpl +import com.courier.api.services.blocking.RequestService +import com.courier.api.services.blocking.RequestServiceImpl +import com.courier.api.services.blocking.SendService +import com.courier.api.services.blocking.SendServiceImpl +import com.courier.api.services.blocking.TenantService +import com.courier.api.services.blocking.TenantServiceImpl +import com.courier.api.services.blocking.TranslationService +import com.courier.api.services.blocking.TranslationServiceImpl +import com.courier.api.services.blocking.UserService +import com.courier.api.services.blocking.UserServiceImpl +import java.util.function.Consumer + +class CourierClientImpl(private val clientOptions: ClientOptions) : CourierClient { + + 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: CourierClientAsync by lazy { CourierClientAsyncImpl(clientOptions) } + + private val withRawResponse: CourierClient.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + private val send: SendService by lazy { SendServiceImpl(clientOptionsWithUserAgent) } + + private val tenants: TenantService by lazy { TenantServiceImpl(clientOptionsWithUserAgent) } + + private val audiences: AudienceService by lazy { + AudienceServiceImpl(clientOptionsWithUserAgent) + } + + private val bulk: BulkService by lazy { BulkServiceImpl(clientOptionsWithUserAgent) } + + private val users: UserService by lazy { UserServiceImpl(clientOptionsWithUserAgent) } + + private val auditEvents: AuditEventService by lazy { + AuditEventServiceImpl(clientOptionsWithUserAgent) + } + + private val automations: AutomationService by lazy { + AutomationServiceImpl(clientOptionsWithUserAgent) + } + + private val brands: BrandService by lazy { BrandServiceImpl(clientOptionsWithUserAgent) } + + private val lists: ListService by lazy { ListServiceImpl(clientOptionsWithUserAgent) } + + private val messages: MessageService by lazy { MessageServiceImpl(clientOptionsWithUserAgent) } + + private val notifications: NotificationService by lazy { + NotificationServiceImpl(clientOptionsWithUserAgent) + } + + private val auth: AuthService by lazy { AuthServiceImpl(clientOptionsWithUserAgent) } + + private val inbound: InboundService by lazy { InboundServiceImpl(clientOptionsWithUserAgent) } + + private val requests: RequestService by lazy { RequestServiceImpl(clientOptionsWithUserAgent) } + + private val profiles: ProfileService by lazy { ProfileServiceImpl(clientOptionsWithUserAgent) } + + private val translations: TranslationService by lazy { + TranslationServiceImpl(clientOptionsWithUserAgent) + } + + override fun async(): CourierClientAsync = async + + override fun withRawResponse(): CourierClient.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): CourierClient = + CourierClientImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun send(): SendService = send + + override fun tenants(): TenantService = tenants + + override fun audiences(): AudienceService = audiences + + override fun bulk(): BulkService = bulk + + override fun users(): UserService = users + + override fun auditEvents(): AuditEventService = auditEvents + + override fun automations(): AutomationService = automations + + override fun brands(): BrandService = brands + + override fun lists(): ListService = lists + + override fun messages(): MessageService = messages + + override fun notifications(): NotificationService = notifications + + override fun auth(): AuthService = auth + + override fun inbound(): InboundService = inbound + + override fun requests(): RequestService = requests + + override fun profiles(): ProfileService = profiles + + override fun translations(): TranslationService = translations + + override fun close() = clientOptions.close() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + CourierClient.WithRawResponse { + + private val send: SendService.WithRawResponse by lazy { + SendServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val tenants: TenantService.WithRawResponse by lazy { + TenantServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val audiences: AudienceService.WithRawResponse by lazy { + AudienceServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val bulk: BulkService.WithRawResponse by lazy { + BulkServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val users: UserService.WithRawResponse by lazy { + UserServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val auditEvents: AuditEventService.WithRawResponse by lazy { + AuditEventServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val automations: AutomationService.WithRawResponse by lazy { + AutomationServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val brands: BrandService.WithRawResponse by lazy { + BrandServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val lists: ListService.WithRawResponse by lazy { + ListServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val messages: MessageService.WithRawResponse by lazy { + MessageServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val notifications: NotificationService.WithRawResponse by lazy { + NotificationServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val auth: AuthService.WithRawResponse by lazy { + AuthServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val inbound: InboundService.WithRawResponse by lazy { + InboundServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val requests: RequestService.WithRawResponse by lazy { + RequestServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val profiles: ProfileService.WithRawResponse by lazy { + ProfileServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val translations: TranslationService.WithRawResponse by lazy { + TranslationServiceImpl.WithRawResponseImpl(clientOptions) + } + + override fun withOptions( + modifier: Consumer + ): CourierClient.WithRawResponse = + CourierClientImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + override fun send(): SendService.WithRawResponse = send + + override fun tenants(): TenantService.WithRawResponse = tenants + + override fun audiences(): AudienceService.WithRawResponse = audiences + + override fun bulk(): BulkService.WithRawResponse = bulk + + override fun users(): UserService.WithRawResponse = users + + override fun auditEvents(): AuditEventService.WithRawResponse = auditEvents + + override fun automations(): AutomationService.WithRawResponse = automations + + override fun brands(): BrandService.WithRawResponse = brands + + override fun lists(): ListService.WithRawResponse = lists + + override fun messages(): MessageService.WithRawResponse = messages + + override fun notifications(): NotificationService.WithRawResponse = notifications + + override fun auth(): AuthService.WithRawResponse = auth + + override fun inbound(): InboundService.WithRawResponse = inbound + + override fun requests(): RequestService.WithRawResponse = requests + + override fun profiles(): ProfileService.WithRawResponse = profiles + + override fun translations(): TranslationService.WithRawResponse = translations + } +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/core/BaseDeserializer.kt b/courier-java-core/src/main/kotlin/com/courier/api/core/BaseDeserializer.kt new file mode 100644 index 00000000..6210d0dd --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/core/BaseDeserializer.kt @@ -0,0 +1,44 @@ +package com.courier.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/courier-java-core/src/main/kotlin/com/courier/api/core/BaseSerializer.kt b/courier-java-core/src/main/kotlin/com/courier/api/core/BaseSerializer.kt new file mode 100644 index 00000000..b62dd939 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/core/BaseSerializer.kt @@ -0,0 +1,6 @@ +package com.courier.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/courier-java-core/src/main/kotlin/com/courier/api/core/Check.kt b/courier-java-core/src/main/kotlin/com/courier/api/core/Check.kt new file mode 100644 index 00000000..fee5b0d4 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/core/Check.kt @@ -0,0 +1,96 @@ +@file:JvmName("Check") + +package com.courier.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/trycourier/courier-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/courier-java-core/src/main/kotlin/com/courier/api/core/ClientOptions.kt b/courier-java-core/src/main/kotlin/com/courier/api/core/ClientOptions.kt new file mode 100644 index 00000000..232898e7 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/core/ClientOptions.kt @@ -0,0 +1,450 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.core + +import com.courier.api.core.http.Headers +import com.courier.api.core.http.HttpClient +import com.courier.api.core.http.PhantomReachableClosingHttpClient +import com.courier.api.core.http.QueryParams +import com.courier.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 `courier-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, + /** + * 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.courier.api.core.jsonMapper]. The default is usually sufficient and 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. + * + * 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, + @get:JvmName("apiKey") val apiKey: String, +) { + + init { + if (checkJacksonVersionCompatibility) { + checkJacksonVersionCompatibility() + } + } + + /** + * The base URL to use for every request. + * + * Defaults to the production environment: `https://api.courier.com`. + */ + fun baseUrl(): String = baseUrl ?: PRODUCTION_URL + + fun toBuilder() = Builder().from(this) + + companion object { + + const val PRODUCTION_URL = "https://api.courier.com" + + /** + * 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 sleeper: Sleeper? = null + 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 + sleeper = clientOptions.sleeper + 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 `courier-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) + } + + /** + * 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.courier.api.core.jsonMapper]. The default is usually sufficient and + * rarely needs to be overridden. + */ + 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. + * + * 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://api.courier.com`. + */ + 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 } + + 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` |`courier.apiKey` |`COURIER_API_KEY` |true |- | + * |`baseUrl`|`courier.baseUrl`|`COURIER_BASE_URL` |true |`"https://api.courier.com"`| + * + * System properties take precedence over environment variables. + */ + fun fromEnv() = apply { + (System.getProperty("courier.baseUrl") ?: System.getenv("COURIER_BASE_URL"))?.let { + baseUrl(it) + } + (System.getProperty("courier.apiKey") ?: System.getenv("COURIER_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 sleeper = sleeper ?: PhantomReachableSleeper(DefaultSleeper()) + 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("Authorization", "Bearer $it") + } + } + headers.replaceAll(this.headers.build()) + queryParams.replaceAll(this.queryParams.build()) + + return ClientOptions( + httpClient, + RetryingHttpClient.builder() + .httpClient(httpClient) + .sleeper(sleeper) + .clock(clock) + .maxRetries(maxRetries) + .build(), + checkJacksonVersionCompatibility, + jsonMapper, + sleeper, + clock, + baseUrl, + headers.build(), + queryParams.build(), + responseValidation, + timeout, + maxRetries, + apiKey, + ) + } + } + + /** + * 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() + sleeper.close() + } +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/core/DefaultSleeper.kt b/courier-java-core/src/main/kotlin/com/courier/api/core/DefaultSleeper.kt new file mode 100644 index 00000000..e068e204 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/core/DefaultSleeper.kt @@ -0,0 +1,28 @@ +package com.courier.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/courier-java-core/src/main/kotlin/com/courier/api/core/ObjectMappers.kt b/courier-java-core/src/main/kotlin/com/courier/api/core/ObjectMappers.kt new file mode 100644 index 00000000..5cfc46de --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/core/ObjectMappers.kt @@ -0,0 +1,167 @@ +@file:JvmName("ObjectMappers") + +package com.courier.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/courier-java-core/src/main/kotlin/com/courier/api/core/Params.kt b/courier-java-core/src/main/kotlin/com/courier/api/core/Params.kt new file mode 100644 index 00000000..a04c55b9 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/core/Params.kt @@ -0,0 +1,16 @@ +package com.courier.api.core + +import com.courier.api.core.http.Headers +import com.courier.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/courier-java-core/src/main/kotlin/com/courier/api/core/PhantomReachable.kt b/courier-java-core/src/main/kotlin/com/courier/api/core/PhantomReachable.kt new file mode 100644 index 00000000..42ae140e --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/core/PhantomReachable.kt @@ -0,0 +1,56 @@ +@file:JvmName("PhantomReachable") + +package com.courier.api.core + +import com.courier.api.errors.CourierException +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 CourierException("Unexpected reflective invocation failure", e) + } + } + } catch (e: ReflectiveOperationException) { + // We're running Java 8, which has no Cleaner. + null + } +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/core/PhantomReachableExecutorService.kt b/courier-java-core/src/main/kotlin/com/courier/api/core/PhantomReachableExecutorService.kt new file mode 100644 index 00000000..20e6c410 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/core/PhantomReachableExecutorService.kt @@ -0,0 +1,58 @@ +package com.courier.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) +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/core/PhantomReachableSleeper.kt b/courier-java-core/src/main/kotlin/com/courier/api/core/PhantomReachableSleeper.kt new file mode 100644 index 00000000..6af9d159 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/core/PhantomReachableSleeper.kt @@ -0,0 +1,23 @@ +package com.courier.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/courier-java-core/src/main/kotlin/com/courier/api/core/PrepareRequest.kt b/courier-java-core/src/main/kotlin/com/courier/api/core/PrepareRequest.kt new file mode 100644 index 00000000..0864d52b --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/core/PrepareRequest.kt @@ -0,0 +1,24 @@ +@file:JvmName("PrepareRequest") + +package com.courier.api.core + +import com.courier.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/courier-java-core/src/main/kotlin/com/courier/api/core/Properties.kt b/courier-java-core/src/main/kotlin/com/courier/api/core/Properties.kt new file mode 100644 index 00000000..e2c8c5f6 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/core/Properties.kt @@ -0,0 +1,42 @@ +@file:JvmName("Properties") + +package com.courier.api.core + +import com.courier.api.client.CourierClient + +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 = + CourierClient::class.java.`package`.implementationVersion ?: "unknown" + +fun getJavaVersion(): String = System.getProperty("java.version", "unknown") diff --git a/courier-java-core/src/main/kotlin/com/courier/api/core/RequestOptions.kt b/courier-java-core/src/main/kotlin/com/courier/api/core/RequestOptions.kt new file mode 100644 index 00000000..40194eea --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/core/RequestOptions.kt @@ -0,0 +1,46 @@ +package com.courier.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/courier-java-core/src/main/kotlin/com/courier/api/core/Sleeper.kt b/courier-java-core/src/main/kotlin/com/courier/api/core/Sleeper.kt new file mode 100644 index 00000000..3289f942 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/core/Sleeper.kt @@ -0,0 +1,21 @@ +package com.courier.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/courier-java-core/src/main/kotlin/com/courier/api/core/Timeout.kt b/courier-java-core/src/main/kotlin/com/courier/api/core/Timeout.kt new file mode 100644 index 00000000..614a6434 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/core/Timeout.kt @@ -0,0 +1,171 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.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/courier-java-core/src/main/kotlin/com/courier/api/core/Utils.kt b/courier-java-core/src/main/kotlin/com/courier/api/core/Utils.kt new file mode 100644 index 00000000..cac76471 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/core/Utils.kt @@ -0,0 +1,115 @@ +@file:JvmName("Utils") + +package com.courier.api.core + +import com.courier.api.errors.CourierInvalidDataException +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 CourierInvalidDataException("`${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/courier-java-core/src/main/kotlin/com/courier/api/core/Values.kt b/courier-java-core/src/main/kotlin/com/courier/api/core/Values.kt new file mode 100644 index 00000000..4017bb76 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/core/Values.kt @@ -0,0 +1,723 @@ +package com.courier.api.core + +import com.courier.api.errors.CourierInvalidDataException +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 { CourierInvalidDataException("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 CourierInvalidDataException("`$name` is not set") + is JsonNull -> throw CourierInvalidDataException("`$name` is null") + else -> throw CourierInvalidDataException("`$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 CourierInvalidDataException("`$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/courier-java-core/src/main/kotlin/com/courier/api/core/handlers/EmptyHandler.kt b/courier-java-core/src/main/kotlin/com/courier/api/core/handlers/EmptyHandler.kt new file mode 100644 index 00000000..e4628b3a --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/core/handlers/EmptyHandler.kt @@ -0,0 +1,12 @@ +@file:JvmName("EmptyHandler") + +package com.courier.api.core.handlers + +import com.courier.api.core.http.HttpResponse +import com.courier.api.core.http.HttpResponse.Handler + +@JvmSynthetic internal fun emptyHandler(): Handler = EmptyHandlerInternal + +private object EmptyHandlerInternal : Handler { + override fun handle(response: HttpResponse): Void? = null +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/core/handlers/ErrorHandler.kt b/courier-java-core/src/main/kotlin/com/courier/api/core/handlers/ErrorHandler.kt new file mode 100644 index 00000000..111485ae --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/core/handlers/ErrorHandler.kt @@ -0,0 +1,84 @@ +// File generated from our OpenAPI spec by Stainless. + +@file:JvmName("ErrorHandler") + +package com.courier.api.core.handlers + +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.http.HttpResponse +import com.courier.api.core.http.HttpResponse.Handler +import com.courier.api.errors.BadRequestException +import com.courier.api.errors.InternalServerException +import com.courier.api.errors.NotFoundException +import com.courier.api.errors.PermissionDeniedException +import com.courier.api.errors.RateLimitException +import com.courier.api.errors.UnauthorizedException +import com.courier.api.errors.UnexpectedStatusCodeException +import com.courier.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/courier-java-core/src/main/kotlin/com/courier/api/core/handlers/JsonHandler.kt b/courier-java-core/src/main/kotlin/com/courier/api/core/handlers/JsonHandler.kt new file mode 100644 index 00000000..ec50c983 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/core/handlers/JsonHandler.kt @@ -0,0 +1,20 @@ +@file:JvmName("JsonHandler") + +package com.courier.api.core.handlers + +import com.courier.api.core.http.HttpResponse +import com.courier.api.core.http.HttpResponse.Handler +import com.courier.api.errors.CourierInvalidDataException +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 CourierInvalidDataException("Error reading response", e) + } + } diff --git a/courier-java-core/src/main/kotlin/com/courier/api/core/handlers/StringHandler.kt b/courier-java-core/src/main/kotlin/com/courier/api/core/handlers/StringHandler.kt new file mode 100644 index 00000000..fb961c6b --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/core/handlers/StringHandler.kt @@ -0,0 +1,13 @@ +@file:JvmName("StringHandler") + +package com.courier.api.core.handlers + +import com.courier.api.core.http.HttpResponse +import com.courier.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/courier-java-core/src/main/kotlin/com/courier/api/core/http/AsyncStreamResponse.kt b/courier-java-core/src/main/kotlin/com/courier/api/core/http/AsyncStreamResponse.kt new file mode 100644 index 00000000..8776a843 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/core/http/AsyncStreamResponse.kt @@ -0,0 +1,157 @@ +package com.courier.api.core.http + +import com.courier.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/courier-java-core/src/main/kotlin/com/courier/api/core/http/Headers.kt b/courier-java-core/src/main/kotlin/com/courier/api/core/http/Headers.kt new file mode 100644 index 00000000..38cb1932 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/core/http/Headers.kt @@ -0,0 +1,115 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.core.http + +import com.courier.api.core.JsonArray +import com.courier.api.core.JsonBoolean +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonNull +import com.courier.api.core.JsonNumber +import com.courier.api.core.JsonObject +import com.courier.api.core.JsonString +import com.courier.api.core.JsonValue +import com.courier.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/courier-java-core/src/main/kotlin/com/courier/api/core/http/HttpClient.kt b/courier-java-core/src/main/kotlin/com/courier/api/core/http/HttpClient.kt new file mode 100644 index 00000000..edf43271 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/core/http/HttpClient.kt @@ -0,0 +1,26 @@ +package com.courier.api.core.http + +import com.courier.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/courier-java-core/src/main/kotlin/com/courier/api/core/http/HttpMethod.kt b/courier-java-core/src/main/kotlin/com/courier/api/core/http/HttpMethod.kt new file mode 100644 index 00000000..bee49976 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/core/http/HttpMethod.kt @@ -0,0 +1,13 @@ +package com.courier.api.core.http + +enum class HttpMethod { + GET, + HEAD, + POST, + PUT, + DELETE, + CONNECT, + OPTIONS, + TRACE, + PATCH, +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/core/http/HttpRequest.kt b/courier-java-core/src/main/kotlin/com/courier/api/core/http/HttpRequest.kt new file mode 100644 index 00000000..f9459ab0 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/core/http/HttpRequest.kt @@ -0,0 +1,146 @@ +package com.courier.api.core.http + +import com.courier.api.core.checkRequired +import com.courier.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/courier-java-core/src/main/kotlin/com/courier/api/core/http/HttpRequestBodies.kt b/courier-java-core/src/main/kotlin/com/courier/api/core/http/HttpRequestBodies.kt new file mode 100644 index 00000000..88592711 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/core/http/HttpRequestBodies.kt @@ -0,0 +1,128 @@ +// File generated from our OpenAPI spec by Stainless. + +@file:JvmName("HttpRequestBodies") + +package com.courier.api.core.http + +import com.courier.api.core.MultipartField +import com.courier.api.errors.CourierInvalidDataException +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 CourierInvalidDataException( + "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 CourierInvalidDataException("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/courier-java-core/src/main/kotlin/com/courier/api/core/http/HttpRequestBody.kt b/courier-java-core/src/main/kotlin/com/courier/api/core/http/HttpRequestBody.kt new file mode 100644 index 00000000..941c489c --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/core/http/HttpRequestBody.kt @@ -0,0 +1,25 @@ +package com.courier.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/courier-java-core/src/main/kotlin/com/courier/api/core/http/HttpResponse.kt b/courier-java-core/src/main/kotlin/com/courier/api/core/http/HttpResponse.kt new file mode 100644 index 00000000..549fb372 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/core/http/HttpResponse.kt @@ -0,0 +1,22 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.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/courier-java-core/src/main/kotlin/com/courier/api/core/http/HttpResponseFor.kt b/courier-java-core/src/main/kotlin/com/courier/api/core/http/HttpResponseFor.kt new file mode 100644 index 00000000..a3a4eabe --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/core/http/HttpResponseFor.kt @@ -0,0 +1,25 @@ +package com.courier.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/courier-java-core/src/main/kotlin/com/courier/api/core/http/PhantomReachableClosingAsyncStreamResponse.kt b/courier-java-core/src/main/kotlin/com/courier/api/core/http/PhantomReachableClosingAsyncStreamResponse.kt new file mode 100644 index 00000000..9b145b29 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/core/http/PhantomReachableClosingAsyncStreamResponse.kt @@ -0,0 +1,56 @@ +package com.courier.api.core.http + +import com.courier.api.core.closeWhenPhantomReachable +import com.courier.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/courier-java-core/src/main/kotlin/com/courier/api/core/http/PhantomReachableClosingHttpClient.kt b/courier-java-core/src/main/kotlin/com/courier/api/core/http/PhantomReachableClosingHttpClient.kt new file mode 100644 index 00000000..d94ef4df --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/core/http/PhantomReachableClosingHttpClient.kt @@ -0,0 +1,26 @@ +package com.courier.api.core.http + +import com.courier.api.core.RequestOptions +import com.courier.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/courier-java-core/src/main/kotlin/com/courier/api/core/http/PhantomReachableClosingStreamResponse.kt b/courier-java-core/src/main/kotlin/com/courier/api/core/http/PhantomReachableClosingStreamResponse.kt new file mode 100644 index 00000000..fb270e74 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/core/http/PhantomReachableClosingStreamResponse.kt @@ -0,0 +1,21 @@ +package com.courier.api.core.http + +import com.courier.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/courier-java-core/src/main/kotlin/com/courier/api/core/http/QueryParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/core/http/QueryParams.kt new file mode 100644 index 00000000..c898967c --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/core/http/QueryParams.kt @@ -0,0 +1,129 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.core.http + +import com.courier.api.core.JsonArray +import com.courier.api.core.JsonBoolean +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonNull +import com.courier.api.core.JsonNumber +import com.courier.api.core.JsonObject +import com.courier.api.core.JsonString +import com.courier.api.core.JsonValue +import com.courier.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/courier-java-core/src/main/kotlin/com/courier/api/core/http/RetryingHttpClient.kt b/courier-java-core/src/main/kotlin/com/courier/api/core/http/RetryingHttpClient.kt new file mode 100644 index 00000000..61bb8900 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/core/http/RetryingHttpClient.kt @@ -0,0 +1,265 @@ +package com.courier.api.core.http + +import com.courier.api.core.DefaultSleeper +import com.courier.api.core.RequestOptions +import com.courier.api.core.Sleeper +import com.courier.api.core.checkRequired +import com.courier.api.errors.CourierIoException +import com.courier.api.errors.CourierRetryableException +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.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() + sleeper.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 CourierIoException || + throwable is CourierRetryableException + + 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? = 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 } + + 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 ?: DefaultSleeper(), + clock, + maxRetries, + idempotencyHeader, + ) + } +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/core/http/StreamResponse.kt b/courier-java-core/src/main/kotlin/com/courier/api/core/http/StreamResponse.kt new file mode 100644 index 00000000..244d3313 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/core/http/StreamResponse.kt @@ -0,0 +1,19 @@ +package com.courier.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/courier-java-core/src/main/kotlin/com/courier/api/errors/BadRequestException.kt b/courier-java-core/src/main/kotlin/com/courier/api/errors/BadRequestException.kt new file mode 100644 index 00000000..0c7b3f67 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/errors/BadRequestException.kt @@ -0,0 +1,80 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.errors + +import com.courier.api.core.JsonValue +import com.courier.api.core.checkRequired +import com.courier.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?) : + CourierServiceException("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/courier-java-core/src/main/kotlin/com/courier/api/errors/CourierException.kt b/courier-java-core/src/main/kotlin/com/courier/api/errors/CourierException.kt new file mode 100644 index 00000000..9dca641e --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/errors/CourierException.kt @@ -0,0 +1,5 @@ +package com.courier.api.errors + +open class CourierException +@JvmOverloads +constructor(message: String? = null, cause: Throwable? = null) : RuntimeException(message, cause) diff --git a/courier-java-core/src/main/kotlin/com/courier/api/errors/CourierInvalidDataException.kt b/courier-java-core/src/main/kotlin/com/courier/api/errors/CourierInvalidDataException.kt new file mode 100644 index 00000000..31f21175 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/errors/CourierInvalidDataException.kt @@ -0,0 +1,5 @@ +package com.courier.api.errors + +class CourierInvalidDataException +@JvmOverloads +constructor(message: String? = null, cause: Throwable? = null) : CourierException(message, cause) diff --git a/courier-java-core/src/main/kotlin/com/courier/api/errors/CourierIoException.kt b/courier-java-core/src/main/kotlin/com/courier/api/errors/CourierIoException.kt new file mode 100644 index 00000000..dab8bcbd --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/errors/CourierIoException.kt @@ -0,0 +1,5 @@ +package com.courier.api.errors + +class CourierIoException +@JvmOverloads +constructor(message: String? = null, cause: Throwable? = null) : CourierException(message, cause) diff --git a/courier-java-core/src/main/kotlin/com/courier/api/errors/CourierRetryableException.kt b/courier-java-core/src/main/kotlin/com/courier/api/errors/CourierRetryableException.kt new file mode 100644 index 00000000..cb6e816a --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/errors/CourierRetryableException.kt @@ -0,0 +1,14 @@ +package com.courier.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 CourierRetryableException +@JvmOverloads +constructor(message: String? = null, cause: Throwable? = null) : CourierException(message, cause) diff --git a/courier-java-core/src/main/kotlin/com/courier/api/errors/CourierServiceException.kt b/courier-java-core/src/main/kotlin/com/courier/api/errors/CourierServiceException.kt new file mode 100644 index 00000000..0455ff6a --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/errors/CourierServiceException.kt @@ -0,0 +1,17 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.errors + +import com.courier.api.core.JsonValue +import com.courier.api.core.http.Headers + +abstract class CourierServiceException +protected constructor(message: String, cause: Throwable? = null) : + CourierException(message, cause) { + + abstract fun statusCode(): Int + + abstract fun headers(): Headers + + abstract fun body(): JsonValue +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/errors/InternalServerException.kt b/courier-java-core/src/main/kotlin/com/courier/api/errors/InternalServerException.kt new file mode 100644 index 00000000..70575e38 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/errors/InternalServerException.kt @@ -0,0 +1,91 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.errors + +import com.courier.api.core.JsonValue +import com.courier.api.core.checkRequired +import com.courier.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?, +) : CourierServiceException("$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/courier-java-core/src/main/kotlin/com/courier/api/errors/NotFoundException.kt b/courier-java-core/src/main/kotlin/com/courier/api/errors/NotFoundException.kt new file mode 100644 index 00000000..b575d286 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/errors/NotFoundException.kt @@ -0,0 +1,76 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.errors + +import com.courier.api.core.JsonValue +import com.courier.api.core.checkRequired +import com.courier.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?) : + CourierServiceException("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/courier-java-core/src/main/kotlin/com/courier/api/errors/PermissionDeniedException.kt b/courier-java-core/src/main/kotlin/com/courier/api/errors/PermissionDeniedException.kt new file mode 100644 index 00000000..59bed2ff --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/errors/PermissionDeniedException.kt @@ -0,0 +1,80 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.errors + +import com.courier.api.core.JsonValue +import com.courier.api.core.checkRequired +import com.courier.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?) : + CourierServiceException("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/courier-java-core/src/main/kotlin/com/courier/api/errors/RateLimitException.kt b/courier-java-core/src/main/kotlin/com/courier/api/errors/RateLimitException.kt new file mode 100644 index 00000000..d302deaa --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/errors/RateLimitException.kt @@ -0,0 +1,80 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.errors + +import com.courier.api.core.JsonValue +import com.courier.api.core.checkRequired +import com.courier.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?) : + CourierServiceException("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/courier-java-core/src/main/kotlin/com/courier/api/errors/UnauthorizedException.kt b/courier-java-core/src/main/kotlin/com/courier/api/errors/UnauthorizedException.kt new file mode 100644 index 00000000..02ada94b --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/errors/UnauthorizedException.kt @@ -0,0 +1,80 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.errors + +import com.courier.api.core.JsonValue +import com.courier.api.core.checkRequired +import com.courier.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?) : + CourierServiceException("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/courier-java-core/src/main/kotlin/com/courier/api/errors/UnexpectedStatusCodeException.kt b/courier-java-core/src/main/kotlin/com/courier/api/errors/UnexpectedStatusCodeException.kt new file mode 100644 index 00000000..2dbe1a0d --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/errors/UnexpectedStatusCodeException.kt @@ -0,0 +1,92 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.errors + +import com.courier.api.core.JsonValue +import com.courier.api.core.checkRequired +import com.courier.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?, +) : CourierServiceException("$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/courier-java-core/src/main/kotlin/com/courier/api/errors/UnprocessableEntityException.kt b/courier-java-core/src/main/kotlin/com/courier/api/errors/UnprocessableEntityException.kt new file mode 100644 index 00000000..ea689066 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/errors/UnprocessableEntityException.kt @@ -0,0 +1,80 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.errors + +import com.courier.api.core.JsonValue +import com.courier.api.core.checkRequired +import com.courier.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?) : + CourierServiceException("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/courier-java-core/src/main/kotlin/com/courier/api/models/ChannelPreference.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/ChannelPreference.kt new file mode 100644 index 00000000..d00617ac --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/ChannelPreference.kt @@ -0,0 +1,177 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkRequired +import com.courier.api.errors.CourierInvalidDataException +import com.courier.api.models.tenants.defaultpreferences.items.ChannelClassification +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 kotlin.jvm.optionals.getOrNull + +class ChannelPreference +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val channel: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("channel") + @ExcludeMissing + channel: JsonField = JsonMissing.of() + ) : this(channel, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 channel(): ChannelClassification = channel.getRequired("channel") + + /** + * Returns the raw JSON value of [channel]. + * + * Unlike [channel], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("channel") + @ExcludeMissing + fun _channel(): JsonField = channel + + @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 [ChannelPreference]. + * + * The following fields are required: + * ```java + * .channel() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ChannelPreference]. */ + class Builder internal constructor() { + + private var channel: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(channelPreference: ChannelPreference) = apply { + channel = channelPreference.channel + additionalProperties = channelPreference.additionalProperties.toMutableMap() + } + + fun channel(channel: ChannelClassification) = channel(JsonField.of(channel)) + + /** + * Sets [Builder.channel] to an arbitrary JSON value. + * + * You should usually call [Builder.channel] with a well-typed [ChannelClassification] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun channel(channel: JsonField) = apply { this.channel = channel } + + 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 [ChannelPreference]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .channel() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ChannelPreference = + ChannelPreference( + checkRequired("channel", channel), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): ChannelPreference = apply { + if (validated) { + return@apply + } + + channel().validate() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = (channel.asKnown().getOrNull()?.validity() ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ChannelPreference && + channel == other.channel && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(channel, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ChannelPreference{channel=$channel, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/Rule.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/Rule.kt new file mode 100644 index 00000000..86c8d646 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/Rule.kt @@ -0,0 +1,203 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkRequired +import com.courier.api.errors.CourierInvalidDataException +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 Rule +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val until: JsonField, + private val start: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("until") @ExcludeMissing until: JsonField = JsonMissing.of(), + @JsonProperty("start") @ExcludeMissing start: JsonField = JsonMissing.of(), + ) : this(until, start, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 until(): String = until.getRequired("until") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun start(): Optional = start.getOptional("start") + + /** + * Returns the raw JSON value of [until]. + * + * Unlike [until], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("until") @ExcludeMissing fun _until(): JsonField = until + + /** + * Returns the raw JSON value of [start]. + * + * Unlike [start], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("start") @ExcludeMissing fun _start(): JsonField = start + + @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 [Rule]. + * + * The following fields are required: + * ```java + * .until() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Rule]. */ + class Builder internal constructor() { + + private var until: JsonField? = null + private var start: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(rule: Rule) = apply { + until = rule.until + start = rule.start + additionalProperties = rule.additionalProperties.toMutableMap() + } + + fun until(until: String) = until(JsonField.of(until)) + + /** + * Sets [Builder.until] to an arbitrary JSON value. + * + * You should usually call [Builder.until] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun until(until: JsonField) = apply { this.until = until } + + fun start(start: String?) = start(JsonField.ofNullable(start)) + + /** Alias for calling [Builder.start] with `start.orElse(null)`. */ + fun start(start: Optional) = start(start.getOrNull()) + + /** + * Sets [Builder.start] to an arbitrary JSON value. + * + * You should usually call [Builder.start] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun start(start: JsonField) = apply { this.start = start } + + 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 [Rule]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .until() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Rule = + Rule(checkRequired("until", until), start, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Rule = apply { + if (validated) { + return@apply + } + + until() + start() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (until.asKnown().isPresent) 1 else 0) + (if (start.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Rule && + until == other.until && + start == other.start && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(until, start, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Rule{until=$until, start=$start, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/audiences/Audience.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/audiences/Audience.kt new file mode 100644 index 00000000..265d41e2 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/audiences/Audience.kt @@ -0,0 +1,364 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.audiences + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkRequired +import com.courier.api.errors.CourierInvalidDataException +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 kotlin.jvm.optionals.getOrNull + +class Audience +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val id: JsonField, + private val createdAt: JsonField, + private val description: JsonField, + private val filter: JsonField, + private val name: JsonField, + private val updatedAt: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("created_at") @ExcludeMissing createdAt: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + description: JsonField = JsonMissing.of(), + @JsonProperty("filter") @ExcludeMissing filter: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("updated_at") @ExcludeMissing updatedAt: JsonField = JsonMissing.of(), + ) : this(id, createdAt, description, filter, name, updatedAt, mutableMapOf()) + + /** + * A unique identifier representing the audience_id + * + * @throws CourierInvalidDataException 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 id(): String = id.getRequired("id") + + /** + * @throws CourierInvalidDataException 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 createdAt(): String = createdAt.getRequired("created_at") + + /** + * A description of the audience + * + * @throws CourierInvalidDataException 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 description(): String = description.getRequired("description") + + /** + * The operator to use for filtering + * + * @throws CourierInvalidDataException 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 filter(): Filter = filter.getRequired("filter") + + /** + * The name of the audience + * + * @throws CourierInvalidDataException 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 name(): String = name.getRequired("name") + + /** + * @throws CourierInvalidDataException 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 updatedAt(): String = updatedAt.getRequired("updated_at") + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + /** + * 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 [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 [filter]. + * + * Unlike [filter], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("filter") @ExcludeMissing fun _filter(): JsonField = filter + + /** + * 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 [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 [Audience]. + * + * The following fields are required: + * ```java + * .id() + * .createdAt() + * .description() + * .filter() + * .name() + * .updatedAt() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Audience]. */ + class Builder internal constructor() { + + private var id: JsonField? = null + private var createdAt: JsonField? = null + private var description: JsonField? = null + private var filter: JsonField? = null + private var name: JsonField? = null + private var updatedAt: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(audience: Audience) = apply { + id = audience.id + createdAt = audience.createdAt + description = audience.description + filter = audience.filter + name = audience.name + updatedAt = audience.updatedAt + additionalProperties = audience.additionalProperties.toMutableMap() + } + + /** A unique identifier representing the audience_id */ + fun id(id: String) = id(JsonField.of(id)) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun id(id: JsonField) = apply { this.id = id } + + fun createdAt(createdAt: String) = createdAt(JsonField.of(createdAt)) + + /** + * Sets [Builder.createdAt] to an arbitrary JSON value. + * + * You should usually call [Builder.createdAt] with a well-typed [String] 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 } + + /** A description of the audience */ + 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 } + + /** The operator to use for filtering */ + fun filter(filter: Filter) = filter(JsonField.of(filter)) + + /** + * Sets [Builder.filter] to an arbitrary JSON value. + * + * You should usually call [Builder.filter] with a well-typed [Filter] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun filter(filter: JsonField) = apply { this.filter = filter } + + /** Alias for calling [filter] with `Filter.ofUnionMember0(unionMember0)`. */ + fun filter(unionMember0: Filter.UnionMember0) = filter(Filter.ofUnionMember0(unionMember0)) + + /** Alias for calling [filter] with `Filter.ofNestedFilterConfig(nestedFilterConfig)`. */ + fun filter(nestedFilterConfig: NestedFilterConfig) = + filter(Filter.ofNestedFilterConfig(nestedFilterConfig)) + + /** The name of the audience */ + 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 } + + fun updatedAt(updatedAt: String) = updatedAt(JsonField.of(updatedAt)) + + /** + * Sets [Builder.updatedAt] to an arbitrary JSON value. + * + * You should usually call [Builder.updatedAt] with a well-typed [String] 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 [Audience]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .createdAt() + * .description() + * .filter() + * .name() + * .updatedAt() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Audience = + Audience( + checkRequired("id", id), + checkRequired("createdAt", createdAt), + checkRequired("description", description), + checkRequired("filter", filter), + checkRequired("name", name), + checkRequired("updatedAt", updatedAt), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Audience = apply { + if (validated) { + return@apply + } + + id() + createdAt() + description() + filter().validate() + name() + updatedAt() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (id.asKnown().isPresent) 1 else 0) + + (if (createdAt.asKnown().isPresent) 1 else 0) + + (if (description.asKnown().isPresent) 1 else 0) + + (filter.asKnown().getOrNull()?.validity() ?: 0) + + (if (name.asKnown().isPresent) 1 else 0) + + (if (updatedAt.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Audience && + id == other.id && + createdAt == other.createdAt && + description == other.description && + filter == other.filter && + name == other.name && + updatedAt == other.updatedAt && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(id, createdAt, description, filter, name, updatedAt, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Audience{id=$id, createdAt=$createdAt, description=$description, filter=$filter, name=$name, updatedAt=$updatedAt, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/audiences/AudienceDeleteParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/audiences/AudienceDeleteParams.kt new file mode 100644 index 00000000..913ee5cb --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/audiences/AudienceDeleteParams.kt @@ -0,0 +1,229 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.audiences + +import com.courier.api.core.JsonValue +import com.courier.api.core.Params +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import com.courier.api.core.toImmutable +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Deletes the specified audience. */ +class AudienceDeleteParams +private constructor( + private val audienceId: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, + private val additionalBodyProperties: Map, +) : Params { + + fun audienceId(): Optional = Optional.ofNullable(audienceId) + + /** 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(): AudienceDeleteParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [AudienceDeleteParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AudienceDeleteParams]. */ + class Builder internal constructor() { + + private var audienceId: 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(audienceDeleteParams: AudienceDeleteParams) = apply { + audienceId = audienceDeleteParams.audienceId + additionalHeaders = audienceDeleteParams.additionalHeaders.toBuilder() + additionalQueryParams = audienceDeleteParams.additionalQueryParams.toBuilder() + additionalBodyProperties = audienceDeleteParams.additionalBodyProperties.toMutableMap() + } + + fun audienceId(audienceId: String?) = apply { this.audienceId = audienceId } + + /** Alias for calling [Builder.audienceId] with `audienceId.orElse(null)`. */ + fun audienceId(audienceId: Optional) = audienceId(audienceId.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 [AudienceDeleteParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): AudienceDeleteParams = + AudienceDeleteParams( + audienceId, + additionalHeaders.build(), + additionalQueryParams.build(), + additionalBodyProperties.toImmutable(), + ) + } + + fun _body(): Optional> = + Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) + + fun _pathParam(index: Int): String = + when (index) { + 0 -> audienceId ?: "" + 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 AudienceDeleteParams && + audienceId == other.audienceId && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams && + additionalBodyProperties == other.additionalBodyProperties + } + + override fun hashCode(): Int = + Objects.hash(audienceId, additionalHeaders, additionalQueryParams, additionalBodyProperties) + + override fun toString() = + "AudienceDeleteParams{audienceId=$audienceId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/audiences/AudienceListMembersParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/audiences/AudienceListMembersParams.kt new file mode 100644 index 00000000..828b67d6 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/audiences/AudienceListMembersParams.kt @@ -0,0 +1,216 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.audiences + +import com.courier.api.core.Params +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Get list of members of an audience. */ +class AudienceListMembersParams +private constructor( + private val audienceId: String?, + private val cursor: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun audienceId(): Optional = Optional.ofNullable(audienceId) + + /** A unique identifier that allows for fetching the next set of members */ + fun cursor(): Optional = Optional.ofNullable(cursor) + + /** 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(): AudienceListMembersParams = builder().build() + + /** + * Returns a mutable builder for constructing an instance of [AudienceListMembersParams]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AudienceListMembersParams]. */ + class Builder internal constructor() { + + private var audienceId: String? = null + private var cursor: String? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(audienceListMembersParams: AudienceListMembersParams) = apply { + audienceId = audienceListMembersParams.audienceId + cursor = audienceListMembersParams.cursor + additionalHeaders = audienceListMembersParams.additionalHeaders.toBuilder() + additionalQueryParams = audienceListMembersParams.additionalQueryParams.toBuilder() + } + + fun audienceId(audienceId: String?) = apply { this.audienceId = audienceId } + + /** Alias for calling [Builder.audienceId] with `audienceId.orElse(null)`. */ + fun audienceId(audienceId: Optional) = audienceId(audienceId.getOrNull()) + + /** A unique identifier that allows for fetching the next set of members */ + fun cursor(cursor: String?) = apply { this.cursor = cursor } + + /** Alias for calling [Builder.cursor] with `cursor.orElse(null)`. */ + fun cursor(cursor: Optional) = cursor(cursor.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 [AudienceListMembersParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): AudienceListMembersParams = + AudienceListMembersParams( + audienceId, + cursor, + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _pathParam(index: Int): String = + when (index) { + 0 -> audienceId ?: "" + else -> "" + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + cursor?.let { put("cursor", it) } + putAll(additionalQueryParams) + } + .build() + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AudienceListMembersParams && + audienceId == other.audienceId && + cursor == other.cursor && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(audienceId, cursor, additionalHeaders, additionalQueryParams) + + override fun toString() = + "AudienceListMembersParams{audienceId=$audienceId, cursor=$cursor, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/audiences/AudienceListMembersResponse.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/audiences/AudienceListMembersResponse.kt new file mode 100644 index 00000000..3f048565 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/audiences/AudienceListMembersResponse.kt @@ -0,0 +1,538 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.audiences + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkKnown +import com.courier.api.core.checkRequired +import com.courier.api.core.toImmutable +import com.courier.api.errors.CourierInvalidDataException +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 kotlin.jvm.optionals.getOrNull + +class AudienceListMembersResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val items: JsonField>, + private val paging: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("items") @ExcludeMissing items: JsonField> = JsonMissing.of(), + @JsonProperty("paging") @ExcludeMissing paging: JsonField = JsonMissing.of(), + ) : this(items, paging, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 items(): List = items.getRequired("items") + + /** + * @throws CourierInvalidDataException 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 paging(): Paging = paging.getRequired("paging") + + /** + * Returns the raw JSON value of [items]. + * + * Unlike [items], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("items") @ExcludeMissing fun _items(): JsonField> = items + + /** + * Returns the raw JSON value of [paging]. + * + * Unlike [paging], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("paging") @ExcludeMissing fun _paging(): JsonField = paging + + @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 [AudienceListMembersResponse]. + * + * The following fields are required: + * ```java + * .items() + * .paging() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AudienceListMembersResponse]. */ + class Builder internal constructor() { + + private var items: JsonField>? = null + private var paging: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(audienceListMembersResponse: AudienceListMembersResponse) = apply { + items = audienceListMembersResponse.items.map { it.toMutableList() } + paging = audienceListMembersResponse.paging + additionalProperties = audienceListMembersResponse.additionalProperties.toMutableMap() + } + + fun items(items: List) = items(JsonField.of(items)) + + /** + * Sets [Builder.items] to an arbitrary JSON value. + * + * You should usually call [Builder.items] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun items(items: JsonField>) = apply { + this.items = items.map { it.toMutableList() } + } + + /** + * Adds a single [Item] to [items]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addItem(item: Item) = apply { + items = + (items ?: JsonField.of(mutableListOf())).also { checkKnown("items", it).add(item) } + } + + fun paging(paging: Paging) = paging(JsonField.of(paging)) + + /** + * Sets [Builder.paging] to an arbitrary JSON value. + * + * You should usually call [Builder.paging] with a well-typed [Paging] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun paging(paging: JsonField) = apply { this.paging = paging } + + 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 [AudienceListMembersResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .items() + * .paging() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): AudienceListMembersResponse = + AudienceListMembersResponse( + checkRequired("items", items).map { it.toImmutable() }, + checkRequired("paging", paging), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): AudienceListMembersResponse = apply { + if (validated) { + return@apply + } + + items().forEach { it.validate() } + paging().validate() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (items.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (paging.asKnown().getOrNull()?.validity() ?: 0) + + class Item + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val addedAt: JsonField, + private val audienceId: JsonField, + private val audienceVersion: JsonField, + private val memberId: JsonField, + private val reason: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("added_at") @ExcludeMissing addedAt: JsonField = JsonMissing.of(), + @JsonProperty("audience_id") + @ExcludeMissing + audienceId: JsonField = JsonMissing.of(), + @JsonProperty("audience_version") + @ExcludeMissing + audienceVersion: JsonField = JsonMissing.of(), + @JsonProperty("member_id") + @ExcludeMissing + memberId: JsonField = JsonMissing.of(), + @JsonProperty("reason") @ExcludeMissing reason: JsonField = JsonMissing.of(), + ) : this(addedAt, audienceId, audienceVersion, memberId, reason, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 addedAt(): String = addedAt.getRequired("added_at") + + /** + * @throws CourierInvalidDataException 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 audienceId(): String = audienceId.getRequired("audience_id") + + /** + * @throws CourierInvalidDataException 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 audienceVersion(): Long = audienceVersion.getRequired("audience_version") + + /** + * @throws CourierInvalidDataException 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 memberId(): String = memberId.getRequired("member_id") + + /** + * @throws CourierInvalidDataException 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 reason(): String = reason.getRequired("reason") + + /** + * Returns the raw JSON value of [addedAt]. + * + * Unlike [addedAt], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("added_at") @ExcludeMissing fun _addedAt(): JsonField = addedAt + + /** + * Returns the raw JSON value of [audienceId]. + * + * Unlike [audienceId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("audience_id") + @ExcludeMissing + fun _audienceId(): JsonField = audienceId + + /** + * Returns the raw JSON value of [audienceVersion]. + * + * Unlike [audienceVersion], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("audience_version") + @ExcludeMissing + fun _audienceVersion(): JsonField = audienceVersion + + /** + * Returns the raw JSON value of [memberId]. + * + * Unlike [memberId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("member_id") @ExcludeMissing fun _memberId(): JsonField = memberId + + /** + * Returns the raw JSON value of [reason]. + * + * Unlike [reason], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("reason") @ExcludeMissing fun _reason(): JsonField = reason + + @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 [Item]. + * + * The following fields are required: + * ```java + * .addedAt() + * .audienceId() + * .audienceVersion() + * .memberId() + * .reason() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Item]. */ + class Builder internal constructor() { + + private var addedAt: JsonField? = null + private var audienceId: JsonField? = null + private var audienceVersion: JsonField? = null + private var memberId: JsonField? = null + private var reason: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(item: Item) = apply { + addedAt = item.addedAt + audienceId = item.audienceId + audienceVersion = item.audienceVersion + memberId = item.memberId + reason = item.reason + additionalProperties = item.additionalProperties.toMutableMap() + } + + fun addedAt(addedAt: String) = addedAt(JsonField.of(addedAt)) + + /** + * Sets [Builder.addedAt] to an arbitrary JSON value. + * + * You should usually call [Builder.addedAt] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun addedAt(addedAt: JsonField) = apply { this.addedAt = addedAt } + + fun audienceId(audienceId: String) = audienceId(JsonField.of(audienceId)) + + /** + * Sets [Builder.audienceId] to an arbitrary JSON value. + * + * You should usually call [Builder.audienceId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun audienceId(audienceId: JsonField) = apply { this.audienceId = audienceId } + + fun audienceVersion(audienceVersion: Long) = + audienceVersion(JsonField.of(audienceVersion)) + + /** + * Sets [Builder.audienceVersion] to an arbitrary JSON value. + * + * You should usually call [Builder.audienceVersion] with a well-typed [Long] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun audienceVersion(audienceVersion: JsonField) = apply { + this.audienceVersion = audienceVersion + } + + fun memberId(memberId: String) = memberId(JsonField.of(memberId)) + + /** + * Sets [Builder.memberId] to an arbitrary JSON value. + * + * You should usually call [Builder.memberId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun memberId(memberId: JsonField) = apply { this.memberId = memberId } + + fun reason(reason: String) = reason(JsonField.of(reason)) + + /** + * Sets [Builder.reason] to an arbitrary JSON value. + * + * You should usually call [Builder.reason] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun reason(reason: JsonField) = apply { this.reason = reason } + + 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 [Item]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .addedAt() + * .audienceId() + * .audienceVersion() + * .memberId() + * .reason() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Item = + Item( + checkRequired("addedAt", addedAt), + checkRequired("audienceId", audienceId), + checkRequired("audienceVersion", audienceVersion), + checkRequired("memberId", memberId), + checkRequired("reason", reason), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Item = apply { + if (validated) { + return@apply + } + + addedAt() + audienceId() + audienceVersion() + memberId() + reason() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (addedAt.asKnown().isPresent) 1 else 0) + + (if (audienceId.asKnown().isPresent) 1 else 0) + + (if (audienceVersion.asKnown().isPresent) 1 else 0) + + (if (memberId.asKnown().isPresent) 1 else 0) + + (if (reason.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Item && + addedAt == other.addedAt && + audienceId == other.audienceId && + audienceVersion == other.audienceVersion && + memberId == other.memberId && + reason == other.reason && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + addedAt, + audienceId, + audienceVersion, + memberId, + reason, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Item{addedAt=$addedAt, audienceId=$audienceId, audienceVersion=$audienceVersion, memberId=$memberId, reason=$reason, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AudienceListMembersResponse && + items == other.items && + paging == other.paging && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(items, paging, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AudienceListMembersResponse{items=$items, paging=$paging, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/audiences/AudienceListParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/audiences/AudienceListParams.kt new file mode 100644 index 00000000..da6a10dc --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/audiences/AudienceListParams.kt @@ -0,0 +1,191 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.audiences + +import com.courier.api.core.Params +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Get the audiences associated with the authorization token. */ +class AudienceListParams +private constructor( + private val cursor: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** A unique identifier that allows for fetching the next set of audiences */ + fun cursor(): Optional = Optional.ofNullable(cursor) + + /** 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(): AudienceListParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [AudienceListParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AudienceListParams]. */ + class Builder internal constructor() { + + private var cursor: String? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(audienceListParams: AudienceListParams) = apply { + cursor = audienceListParams.cursor + additionalHeaders = audienceListParams.additionalHeaders.toBuilder() + additionalQueryParams = audienceListParams.additionalQueryParams.toBuilder() + } + + /** A unique identifier that allows for fetching the next set of audiences */ + fun cursor(cursor: String?) = apply { this.cursor = cursor } + + /** Alias for calling [Builder.cursor] with `cursor.orElse(null)`. */ + fun cursor(cursor: Optional) = cursor(cursor.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 [AudienceListParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): AudienceListParams = + AudienceListParams(cursor, additionalHeaders.build(), additionalQueryParams.build()) + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + cursor?.let { put("cursor", it) } + putAll(additionalQueryParams) + } + .build() + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AudienceListParams && + cursor == other.cursor && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = Objects.hash(cursor, additionalHeaders, additionalQueryParams) + + override fun toString() = + "AudienceListParams{cursor=$cursor, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/audiences/AudienceListResponse.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/audiences/AudienceListResponse.kt new file mode 100644 index 00000000..63852dcc --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/audiences/AudienceListResponse.kt @@ -0,0 +1,221 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.audiences + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkKnown +import com.courier.api.core.checkRequired +import com.courier.api.core.toImmutable +import com.courier.api.errors.CourierInvalidDataException +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 kotlin.jvm.optionals.getOrNull + +class AudienceListResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val items: JsonField>, + private val paging: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("items") @ExcludeMissing items: JsonField> = JsonMissing.of(), + @JsonProperty("paging") @ExcludeMissing paging: JsonField = JsonMissing.of(), + ) : this(items, paging, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 items(): List = items.getRequired("items") + + /** + * @throws CourierInvalidDataException 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 paging(): Paging = paging.getRequired("paging") + + /** + * Returns the raw JSON value of [items]. + * + * Unlike [items], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("items") @ExcludeMissing fun _items(): JsonField> = items + + /** + * Returns the raw JSON value of [paging]. + * + * Unlike [paging], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("paging") @ExcludeMissing fun _paging(): JsonField = paging + + @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 [AudienceListResponse]. + * + * The following fields are required: + * ```java + * .items() + * .paging() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AudienceListResponse]. */ + class Builder internal constructor() { + + private var items: JsonField>? = null + private var paging: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(audienceListResponse: AudienceListResponse) = apply { + items = audienceListResponse.items.map { it.toMutableList() } + paging = audienceListResponse.paging + additionalProperties = audienceListResponse.additionalProperties.toMutableMap() + } + + fun items(items: List) = items(JsonField.of(items)) + + /** + * Sets [Builder.items] to an arbitrary JSON value. + * + * You should usually call [Builder.items] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun items(items: JsonField>) = apply { + this.items = items.map { it.toMutableList() } + } + + /** + * Adds a single [Audience] to [items]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addItem(item: Audience) = apply { + items = + (items ?: JsonField.of(mutableListOf())).also { checkKnown("items", it).add(item) } + } + + fun paging(paging: Paging) = paging(JsonField.of(paging)) + + /** + * Sets [Builder.paging] to an arbitrary JSON value. + * + * You should usually call [Builder.paging] with a well-typed [Paging] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun paging(paging: JsonField) = apply { this.paging = paging } + + 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 [AudienceListResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .items() + * .paging() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): AudienceListResponse = + AudienceListResponse( + checkRequired("items", items).map { it.toImmutable() }, + checkRequired("paging", paging), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): AudienceListResponse = apply { + if (validated) { + return@apply + } + + items().forEach { it.validate() } + paging().validate() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (items.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (paging.asKnown().getOrNull()?.validity() ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AudienceListResponse && + items == other.items && + paging == other.paging && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(items, paging, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AudienceListResponse{items=$items, paging=$paging, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/audiences/AudienceRetrieveParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/audiences/AudienceRetrieveParams.kt new file mode 100644 index 00000000..af099647 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/audiences/AudienceRetrieveParams.kt @@ -0,0 +1,194 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.audiences + +import com.courier.api.core.Params +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Returns the specified audience by id. */ +class AudienceRetrieveParams +private constructor( + private val audienceId: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun audienceId(): Optional = Optional.ofNullable(audienceId) + + /** 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(): AudienceRetrieveParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [AudienceRetrieveParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AudienceRetrieveParams]. */ + class Builder internal constructor() { + + private var audienceId: String? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(audienceRetrieveParams: AudienceRetrieveParams) = apply { + audienceId = audienceRetrieveParams.audienceId + additionalHeaders = audienceRetrieveParams.additionalHeaders.toBuilder() + additionalQueryParams = audienceRetrieveParams.additionalQueryParams.toBuilder() + } + + fun audienceId(audienceId: String?) = apply { this.audienceId = audienceId } + + /** Alias for calling [Builder.audienceId] with `audienceId.orElse(null)`. */ + fun audienceId(audienceId: Optional) = audienceId(audienceId.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 [AudienceRetrieveParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): AudienceRetrieveParams = + AudienceRetrieveParams( + audienceId, + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _pathParam(index: Int): String = + when (index) { + 0 -> audienceId ?: "" + 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 AudienceRetrieveParams && + audienceId == other.audienceId && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(audienceId, additionalHeaders, additionalQueryParams) + + override fun toString() = + "AudienceRetrieveParams{audienceId=$audienceId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/audiences/AudienceUpdateParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/audiences/AudienceUpdateParams.kt new file mode 100644 index 00000000..6aabb901 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/audiences/AudienceUpdateParams.kt @@ -0,0 +1,577 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.audiences + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.Params +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import com.courier.api.errors.CourierInvalidDataException +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 + +/** Creates or updates audience. */ +class AudienceUpdateParams +private constructor( + private val audienceId: String?, + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun audienceId(): Optional = Optional.ofNullable(audienceId) + + /** + * A description of the audience + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = body.description() + + /** + * The operator to use for filtering + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun filter(): Optional = body.filter() + + /** + * The name of the audience + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun name(): Optional = body.name() + + /** + * Returns the raw JSON value of [description]. + * + * Unlike [description], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _description(): JsonField = body._description() + + /** + * Returns the raw JSON value of [filter]. + * + * Unlike [filter], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _filter(): JsonField = body._filter() + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _name(): JsonField = body._name() + + 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(): AudienceUpdateParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [AudienceUpdateParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AudienceUpdateParams]. */ + class Builder internal constructor() { + + private var audienceId: 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(audienceUpdateParams: AudienceUpdateParams) = apply { + audienceId = audienceUpdateParams.audienceId + body = audienceUpdateParams.body.toBuilder() + additionalHeaders = audienceUpdateParams.additionalHeaders.toBuilder() + additionalQueryParams = audienceUpdateParams.additionalQueryParams.toBuilder() + } + + fun audienceId(audienceId: String?) = apply { this.audienceId = audienceId } + + /** Alias for calling [Builder.audienceId] with `audienceId.orElse(null)`. */ + fun audienceId(audienceId: Optional) = audienceId(audienceId.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: + * - [description] + * - [filter] + * - [name] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + /** A description of the audience */ + fun description(description: String?) = apply { body.description(description) } + + /** Alias for calling [Builder.description] with `description.orElse(null)`. */ + fun description(description: Optional) = description(description.getOrNull()) + + /** + * 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 { body.description(description) } + + /** The operator to use for filtering */ + fun filter(filter: Filter?) = apply { body.filter(filter) } + + /** Alias for calling [Builder.filter] with `filter.orElse(null)`. */ + fun filter(filter: Optional) = filter(filter.getOrNull()) + + /** + * Sets [Builder.filter] to an arbitrary JSON value. + * + * You should usually call [Builder.filter] with a well-typed [Filter] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun filter(filter: JsonField) = apply { body.filter(filter) } + + /** Alias for calling [filter] with `Filter.ofUnionMember0(unionMember0)`. */ + fun filter(unionMember0: Filter.UnionMember0) = apply { body.filter(unionMember0) } + + /** Alias for calling [filter] with `Filter.ofNestedFilterConfig(nestedFilterConfig)`. */ + fun filter(nestedFilterConfig: NestedFilterConfig) = apply { + body.filter(nestedFilterConfig) + } + + /** The name of the audience */ + fun name(name: String?) = apply { body.name(name) } + + /** Alias for calling [Builder.name] with `name.orElse(null)`. */ + fun name(name: Optional) = name(name.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 { body.name(name) } + + 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 [AudienceUpdateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): AudienceUpdateParams = + AudienceUpdateParams( + audienceId, + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): Body = body + + fun _pathParam(index: Int): String = + when (index) { + 0 -> audienceId ?: "" + else -> "" + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + class Body + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val description: JsonField, + private val filter: JsonField, + private val name: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("description") + @ExcludeMissing + description: JsonField = JsonMissing.of(), + @JsonProperty("filter") @ExcludeMissing filter: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + ) : this(description, filter, name, mutableMapOf()) + + /** + * A description of the audience + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = description.getOptional("description") + + /** + * The operator to use for filtering + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun filter(): Optional = filter.getOptional("filter") + + /** + * The name of the audience + * + * @throws CourierInvalidDataException 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 [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 [filter]. + * + * Unlike [filter], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("filter") @ExcludeMissing fun _filter(): JsonField = filter + + /** + * 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 + + @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 description: JsonField = JsonMissing.of() + private var filter: JsonField = JsonMissing.of() + private var name: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + description = body.description + filter = body.filter + name = body.name + additionalProperties = body.additionalProperties.toMutableMap() + } + + /** A description of the audience */ + fun description(description: String?) = description(JsonField.ofNullable(description)) + + /** Alias for calling [Builder.description] with `description.orElse(null)`. */ + fun description(description: Optional) = description(description.getOrNull()) + + /** + * 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 + } + + /** The operator to use for filtering */ + fun filter(filter: Filter?) = filter(JsonField.ofNullable(filter)) + + /** Alias for calling [Builder.filter] with `filter.orElse(null)`. */ + fun filter(filter: Optional) = filter(filter.getOrNull()) + + /** + * Sets [Builder.filter] to an arbitrary JSON value. + * + * You should usually call [Builder.filter] with a well-typed [Filter] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun filter(filter: JsonField) = apply { this.filter = filter } + + /** Alias for calling [filter] with `Filter.ofUnionMember0(unionMember0)`. */ + fun filter(unionMember0: Filter.UnionMember0) = + filter(Filter.ofUnionMember0(unionMember0)) + + /** + * Alias for calling [filter] with `Filter.ofNestedFilterConfig(nestedFilterConfig)`. + */ + fun filter(nestedFilterConfig: NestedFilterConfig) = + filter(Filter.ofNestedFilterConfig(nestedFilterConfig)) + + /** The name of the audience */ + fun name(name: String?) = name(JsonField.ofNullable(name)) + + /** Alias for calling [Builder.name] with `name.orElse(null)`. */ + fun name(name: Optional) = name(name.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 } + + 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(description, filter, name, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + description() + filter().ifPresent { it.validate() } + name() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (description.asKnown().isPresent) 1 else 0) + + (filter.asKnown().getOrNull()?.validity() ?: 0) + + (if (name.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + description == other.description && + filter == other.filter && + name == other.name && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(description, filter, name, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{description=$description, filter=$filter, name=$name, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AudienceUpdateParams && + audienceId == other.audienceId && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(audienceId, body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "AudienceUpdateParams{audienceId=$audienceId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/audiences/AudienceUpdateResponse.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/audiences/AudienceUpdateResponse.kt new file mode 100644 index 00000000..103d0ec4 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/audiences/AudienceUpdateResponse.kt @@ -0,0 +1,172 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.audiences + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkRequired +import com.courier.api.errors.CourierInvalidDataException +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 kotlin.jvm.optionals.getOrNull + +class AudienceUpdateResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val audience: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("audience") @ExcludeMissing audience: JsonField = JsonMissing.of() + ) : this(audience, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 audience(): Audience = audience.getRequired("audience") + + /** + * Returns the raw JSON value of [audience]. + * + * Unlike [audience], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("audience") @ExcludeMissing fun _audience(): JsonField = audience + + @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 [AudienceUpdateResponse]. + * + * The following fields are required: + * ```java + * .audience() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AudienceUpdateResponse]. */ + class Builder internal constructor() { + + private var audience: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(audienceUpdateResponse: AudienceUpdateResponse) = apply { + audience = audienceUpdateResponse.audience + additionalProperties = audienceUpdateResponse.additionalProperties.toMutableMap() + } + + fun audience(audience: Audience) = audience(JsonField.of(audience)) + + /** + * Sets [Builder.audience] to an arbitrary JSON value. + * + * You should usually call [Builder.audience] with a well-typed [Audience] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun audience(audience: JsonField) = apply { this.audience = audience } + + 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 [AudienceUpdateResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .audience() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): AudienceUpdateResponse = + AudienceUpdateResponse( + checkRequired("audience", audience), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): AudienceUpdateResponse = apply { + if (validated) { + return@apply + } + + audience().validate() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = (audience.asKnown().getOrNull()?.validity() ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AudienceUpdateResponse && + audience == other.audience && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(audience, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AudienceUpdateResponse{audience=$audience, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/audiences/Filter.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/audiences/Filter.kt new file mode 100644 index 00000000..80e05a56 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/audiences/Filter.kt @@ -0,0 +1,660 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.audiences + +import com.courier.api.core.BaseDeserializer +import com.courier.api.core.BaseSerializer +import com.courier.api.core.Enum +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.allMaxBy +import com.courier.api.core.checkRequired +import com.courier.api.core.getOrThrow +import com.courier.api.errors.CourierInvalidDataException +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 com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.ObjectCodec +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.module.kotlin.jacksonTypeRef +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** The operator to use for filtering */ +@JsonDeserialize(using = Filter.Deserializer::class) +@JsonSerialize(using = Filter.Serializer::class) +class Filter +private constructor( + private val unionMember0: UnionMember0? = null, + private val nestedFilterConfig: NestedFilterConfig? = null, + private val _json: JsonValue? = null, +) { + + fun unionMember0(): Optional = Optional.ofNullable(unionMember0) + + /** The operator to use for filtering */ + fun nestedFilterConfig(): Optional = Optional.ofNullable(nestedFilterConfig) + + fun isUnionMember0(): Boolean = unionMember0 != null + + fun isNestedFilterConfig(): Boolean = nestedFilterConfig != null + + fun asUnionMember0(): UnionMember0 = unionMember0.getOrThrow("unionMember0") + + /** The operator to use for filtering */ + fun asNestedFilterConfig(): NestedFilterConfig = + nestedFilterConfig.getOrThrow("nestedFilterConfig") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T = + when { + unionMember0 != null -> visitor.visitUnionMember0(unionMember0) + nestedFilterConfig != null -> visitor.visitNestedFilterConfig(nestedFilterConfig) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + fun validate(): Filter = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitUnionMember0(unionMember0: UnionMember0) { + unionMember0.validate() + } + + override fun visitNestedFilterConfig(nestedFilterConfig: NestedFilterConfig) { + nestedFilterConfig.validate() + } + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + accept( + object : Visitor { + override fun visitUnionMember0(unionMember0: UnionMember0) = unionMember0.validity() + + override fun visitNestedFilterConfig(nestedFilterConfig: NestedFilterConfig) = + nestedFilterConfig.validity() + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Filter && + unionMember0 == other.unionMember0 && + nestedFilterConfig == other.nestedFilterConfig + } + + override fun hashCode(): Int = Objects.hash(unionMember0, nestedFilterConfig) + + override fun toString(): String = + when { + unionMember0 != null -> "Filter{unionMember0=$unionMember0}" + nestedFilterConfig != null -> "Filter{nestedFilterConfig=$nestedFilterConfig}" + _json != null -> "Filter{_unknown=$_json}" + else -> throw IllegalStateException("Invalid Filter") + } + + companion object { + + @JvmStatic + fun ofUnionMember0(unionMember0: UnionMember0) = Filter(unionMember0 = unionMember0) + + /** The operator to use for filtering */ + @JvmStatic + fun ofNestedFilterConfig(nestedFilterConfig: NestedFilterConfig) = + Filter(nestedFilterConfig = nestedFilterConfig) + } + + /** An interface that defines how to map each variant of [Filter] to a value of type [T]. */ + interface Visitor { + + fun visitUnionMember0(unionMember0: UnionMember0): T + + /** The operator to use for filtering */ + fun visitNestedFilterConfig(nestedFilterConfig: NestedFilterConfig): T + + /** + * Maps an unknown variant of [Filter] to a value of type [T]. + * + * An instance of [Filter] can contain an unknown variant if it was deserialized from data + * that doesn't match any known variant. For example, if the SDK is on an older version than + * the API, then the API may respond with new variants that the SDK is unaware of. + * + * @throws CourierInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw CourierInvalidDataException("Unknown Filter: $json") + } + } + + internal class Deserializer : BaseDeserializer(Filter::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): Filter { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef())?.let { + Filter(unionMember0 = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + Filter(nestedFilterConfig = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible with all + // the possible variants (e.g. deserializing from boolean). + 0 -> Filter(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the first + // completely valid match, or simply the first match if none are completely valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : BaseSerializer(Filter::class) { + + override fun serialize( + value: Filter, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.unionMember0 != null -> generator.writeObject(value.unionMember0) + value.nestedFilterConfig != null -> generator.writeObject(value.nestedFilterConfig) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid Filter") + } + } + } + + class UnionMember0 + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val operator: JsonField, + private val path: JsonField, + private val value: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("operator") + @ExcludeMissing + operator: JsonField = JsonMissing.of(), + @JsonProperty("path") @ExcludeMissing path: JsonField = JsonMissing.of(), + @JsonProperty("value") @ExcludeMissing value: JsonField = JsonMissing.of(), + ) : this(operator, path, value, mutableMapOf()) + + /** + * The operator to use for filtering + * + * @throws CourierInvalidDataException 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 operator(): Operator = operator.getRequired("operator") + + /** + * The attribe name from profile whose value will be operated against the filter value + * + * @throws CourierInvalidDataException 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 path(): String = path.getRequired("path") + + /** + * The value to use for filtering + * + * @throws CourierInvalidDataException 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 value(): String = value.getRequired("value") + + /** + * Returns the raw JSON value of [operator]. + * + * Unlike [operator], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("operator") @ExcludeMissing fun _operator(): JsonField = operator + + /** + * 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 [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 [UnionMember0]. + * + * The following fields are required: + * ```java + * .operator() + * .path() + * .value() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [UnionMember0]. */ + class Builder internal constructor() { + + private var operator: JsonField? = null + private var path: JsonField? = null + private var value: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(unionMember0: UnionMember0) = apply { + operator = unionMember0.operator + path = unionMember0.path + value = unionMember0.value + additionalProperties = unionMember0.additionalProperties.toMutableMap() + } + + /** The operator to use for filtering */ + fun operator(operator: Operator) = operator(JsonField.of(operator)) + + /** + * Sets [Builder.operator] to an arbitrary JSON value. + * + * You should usually call [Builder.operator] with a well-typed [Operator] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun operator(operator: JsonField) = apply { this.operator = operator } + + /** + * The attribe name from profile whose value will be operated against the filter value + */ + 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 } + + /** The value to use for filtering */ + fun value(value: String) = value(JsonField.of(value)) + + /** + * Sets [Builder.value] to an arbitrary JSON value. + * + * You should usually call [Builder.value] 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 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 [UnionMember0]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .operator() + * .path() + * .value() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): UnionMember0 = + UnionMember0( + checkRequired("operator", operator), + checkRequired("path", path), + checkRequired("value", value), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): UnionMember0 = apply { + if (validated) { + return@apply + } + + operator().validate() + path() + value() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (operator.asKnown().getOrNull()?.validity() ?: 0) + + (if (path.asKnown().isPresent) 1 else 0) + + (if (value.asKnown().isPresent) 1 else 0) + + /** The operator to use for filtering */ + class Operator @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 ENDS_WITH = of("ENDS_WITH") + + @JvmField val EQ = of("EQ") + + @JvmField val EXISTS = of("EXISTS") + + @JvmField val GT = of("GT") + + @JvmField val GTE = of("GTE") + + @JvmField val INCLUDES = of("INCLUDES") + + @JvmField val IS_AFTER = of("IS_AFTER") + + @JvmField val IS_BEFORE = of("IS_BEFORE") + + @JvmField val LT = of("LT") + + @JvmField val LTE = of("LTE") + + @JvmField val NEQ = of("NEQ") + + @JvmField val OMIT = of("OMIT") + + @JvmField val STARTS_WITH = of("STARTS_WITH") + + @JvmField val AND = of("AND") + + @JvmField val OR = of("OR") + + @JvmStatic fun of(value: String) = Operator(JsonField.of(value)) + } + + /** An enum containing [Operator]'s known values. */ + enum class Known { + ENDS_WITH, + EQ, + EXISTS, + GT, + GTE, + INCLUDES, + IS_AFTER, + IS_BEFORE, + LT, + LTE, + NEQ, + OMIT, + STARTS_WITH, + AND, + OR, + } + + /** + * An enum containing [Operator]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Operator] 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 { + ENDS_WITH, + EQ, + EXISTS, + GT, + GTE, + INCLUDES, + IS_AFTER, + IS_BEFORE, + LT, + LTE, + NEQ, + OMIT, + STARTS_WITH, + AND, + OR, + /** + * An enum member indicating that [Operator] 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) { + ENDS_WITH -> Value.ENDS_WITH + EQ -> Value.EQ + EXISTS -> Value.EXISTS + GT -> Value.GT + GTE -> Value.GTE + INCLUDES -> Value.INCLUDES + IS_AFTER -> Value.IS_AFTER + IS_BEFORE -> Value.IS_BEFORE + LT -> Value.LT + LTE -> Value.LTE + NEQ -> Value.NEQ + OMIT -> Value.OMIT + STARTS_WITH -> Value.STARTS_WITH + AND -> Value.AND + OR -> Value.OR + 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 CourierInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + ENDS_WITH -> Known.ENDS_WITH + EQ -> Known.EQ + EXISTS -> Known.EXISTS + GT -> Known.GT + GTE -> Known.GTE + INCLUDES -> Known.INCLUDES + IS_AFTER -> Known.IS_AFTER + IS_BEFORE -> Known.IS_BEFORE + LT -> Known.LT + LTE -> Known.LTE + NEQ -> Known.NEQ + OMIT -> Known.OMIT + STARTS_WITH -> Known.STARTS_WITH + AND -> Known.AND + OR -> Known.OR + else -> throw CourierInvalidDataException("Unknown Operator: $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 CourierInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CourierInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): Operator = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Operator && 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 UnionMember0 && + operator == other.operator && + path == other.path && + value == other.value && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(operator, path, value, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "UnionMember0{operator=$operator, path=$path, value=$value, additionalProperties=$additionalProperties}" + } +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/audiences/FilterConfig.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/audiences/FilterConfig.kt new file mode 100644 index 00000000..d48f3590 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/audiences/FilterConfig.kt @@ -0,0 +1,656 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.audiences + +import com.courier.api.core.BaseDeserializer +import com.courier.api.core.BaseSerializer +import com.courier.api.core.Enum +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.allMaxBy +import com.courier.api.core.checkRequired +import com.courier.api.core.getOrThrow +import com.courier.api.errors.CourierInvalidDataException +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 com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.ObjectCodec +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.module.kotlin.jacksonTypeRef +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** The operator to use for filtering */ +@JsonDeserialize(using = FilterConfig.Deserializer::class) +@JsonSerialize(using = FilterConfig.Serializer::class) +class FilterConfig +private constructor( + private val unionMember0: UnionMember0? = null, + private val nested: NestedFilterConfig? = null, + private val _json: JsonValue? = null, +) { + + fun unionMember0(): Optional = Optional.ofNullable(unionMember0) + + /** The operator to use for filtering */ + fun nested(): Optional = Optional.ofNullable(nested) + + fun isUnionMember0(): Boolean = unionMember0 != null + + fun isNested(): Boolean = nested != null + + fun asUnionMember0(): UnionMember0 = unionMember0.getOrThrow("unionMember0") + + /** The operator to use for filtering */ + fun asNested(): NestedFilterConfig = nested.getOrThrow("nested") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T = + when { + unionMember0 != null -> visitor.visitUnionMember0(unionMember0) + nested != null -> visitor.visitNested(nested) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + fun validate(): FilterConfig = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitUnionMember0(unionMember0: UnionMember0) { + unionMember0.validate() + } + + override fun visitNested(nested: NestedFilterConfig) { + nested.validate() + } + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + accept( + object : Visitor { + override fun visitUnionMember0(unionMember0: UnionMember0) = unionMember0.validity() + + override fun visitNested(nested: NestedFilterConfig) = nested.validity() + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is FilterConfig && unionMember0 == other.unionMember0 && nested == other.nested + } + + override fun hashCode(): Int = Objects.hash(unionMember0, nested) + + override fun toString(): String = + when { + unionMember0 != null -> "FilterConfig{unionMember0=$unionMember0}" + nested != null -> "FilterConfig{nested=$nested}" + _json != null -> "FilterConfig{_unknown=$_json}" + else -> throw IllegalStateException("Invalid FilterConfig") + } + + companion object { + + @JvmStatic + fun ofUnionMember0(unionMember0: UnionMember0) = FilterConfig(unionMember0 = unionMember0) + + /** The operator to use for filtering */ + @JvmStatic fun ofNested(nested: NestedFilterConfig) = FilterConfig(nested = nested) + } + + /** + * An interface that defines how to map each variant of [FilterConfig] to a value of type [T]. + */ + interface Visitor { + + fun visitUnionMember0(unionMember0: UnionMember0): T + + /** The operator to use for filtering */ + fun visitNested(nested: NestedFilterConfig): T + + /** + * Maps an unknown variant of [FilterConfig] to a value of type [T]. + * + * An instance of [FilterConfig] can contain an unknown variant if it was deserialized from + * data that doesn't match any known variant. For example, if the SDK is on an older version + * than the API, then the API may respond with new variants that the SDK is unaware of. + * + * @throws CourierInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw CourierInvalidDataException("Unknown FilterConfig: $json") + } + } + + internal class Deserializer : BaseDeserializer(FilterConfig::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): FilterConfig { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef())?.let { + FilterConfig(unionMember0 = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + FilterConfig(nested = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible with all + // the possible variants (e.g. deserializing from boolean). + 0 -> FilterConfig(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the first + // completely valid match, or simply the first match if none are completely valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : BaseSerializer(FilterConfig::class) { + + override fun serialize( + value: FilterConfig, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.unionMember0 != null -> generator.writeObject(value.unionMember0) + value.nested != null -> generator.writeObject(value.nested) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid FilterConfig") + } + } + } + + class UnionMember0 + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val operator: JsonField, + private val path: JsonField, + private val value: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("operator") + @ExcludeMissing + operator: JsonField = JsonMissing.of(), + @JsonProperty("path") @ExcludeMissing path: JsonField = JsonMissing.of(), + @JsonProperty("value") @ExcludeMissing value: JsonField = JsonMissing.of(), + ) : this(operator, path, value, mutableMapOf()) + + /** + * The operator to use for filtering + * + * @throws CourierInvalidDataException 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 operator(): Operator = operator.getRequired("operator") + + /** + * The attribe name from profile whose value will be operated against the filter value + * + * @throws CourierInvalidDataException 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 path(): String = path.getRequired("path") + + /** + * The value to use for filtering + * + * @throws CourierInvalidDataException 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 value(): String = value.getRequired("value") + + /** + * Returns the raw JSON value of [operator]. + * + * Unlike [operator], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("operator") @ExcludeMissing fun _operator(): JsonField = operator + + /** + * 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 [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 [UnionMember0]. + * + * The following fields are required: + * ```java + * .operator() + * .path() + * .value() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [UnionMember0]. */ + class Builder internal constructor() { + + private var operator: JsonField? = null + private var path: JsonField? = null + private var value: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(unionMember0: UnionMember0) = apply { + operator = unionMember0.operator + path = unionMember0.path + value = unionMember0.value + additionalProperties = unionMember0.additionalProperties.toMutableMap() + } + + /** The operator to use for filtering */ + fun operator(operator: Operator) = operator(JsonField.of(operator)) + + /** + * Sets [Builder.operator] to an arbitrary JSON value. + * + * You should usually call [Builder.operator] with a well-typed [Operator] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun operator(operator: JsonField) = apply { this.operator = operator } + + /** + * The attribe name from profile whose value will be operated against the filter value + */ + 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 } + + /** The value to use for filtering */ + fun value(value: String) = value(JsonField.of(value)) + + /** + * Sets [Builder.value] to an arbitrary JSON value. + * + * You should usually call [Builder.value] 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 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 [UnionMember0]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .operator() + * .path() + * .value() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): UnionMember0 = + UnionMember0( + checkRequired("operator", operator), + checkRequired("path", path), + checkRequired("value", value), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): UnionMember0 = apply { + if (validated) { + return@apply + } + + operator().validate() + path() + value() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (operator.asKnown().getOrNull()?.validity() ?: 0) + + (if (path.asKnown().isPresent) 1 else 0) + + (if (value.asKnown().isPresent) 1 else 0) + + /** The operator to use for filtering */ + class Operator @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 ENDS_WITH = of("ENDS_WITH") + + @JvmField val EQ = of("EQ") + + @JvmField val EXISTS = of("EXISTS") + + @JvmField val GT = of("GT") + + @JvmField val GTE = of("GTE") + + @JvmField val INCLUDES = of("INCLUDES") + + @JvmField val IS_AFTER = of("IS_AFTER") + + @JvmField val IS_BEFORE = of("IS_BEFORE") + + @JvmField val LT = of("LT") + + @JvmField val LTE = of("LTE") + + @JvmField val NEQ = of("NEQ") + + @JvmField val OMIT = of("OMIT") + + @JvmField val STARTS_WITH = of("STARTS_WITH") + + @JvmField val AND = of("AND") + + @JvmField val OR = of("OR") + + @JvmStatic fun of(value: String) = Operator(JsonField.of(value)) + } + + /** An enum containing [Operator]'s known values. */ + enum class Known { + ENDS_WITH, + EQ, + EXISTS, + GT, + GTE, + INCLUDES, + IS_AFTER, + IS_BEFORE, + LT, + LTE, + NEQ, + OMIT, + STARTS_WITH, + AND, + OR, + } + + /** + * An enum containing [Operator]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Operator] 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 { + ENDS_WITH, + EQ, + EXISTS, + GT, + GTE, + INCLUDES, + IS_AFTER, + IS_BEFORE, + LT, + LTE, + NEQ, + OMIT, + STARTS_WITH, + AND, + OR, + /** + * An enum member indicating that [Operator] 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) { + ENDS_WITH -> Value.ENDS_WITH + EQ -> Value.EQ + EXISTS -> Value.EXISTS + GT -> Value.GT + GTE -> Value.GTE + INCLUDES -> Value.INCLUDES + IS_AFTER -> Value.IS_AFTER + IS_BEFORE -> Value.IS_BEFORE + LT -> Value.LT + LTE -> Value.LTE + NEQ -> Value.NEQ + OMIT -> Value.OMIT + STARTS_WITH -> Value.STARTS_WITH + AND -> Value.AND + OR -> Value.OR + 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 CourierInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + ENDS_WITH -> Known.ENDS_WITH + EQ -> Known.EQ + EXISTS -> Known.EXISTS + GT -> Known.GT + GTE -> Known.GTE + INCLUDES -> Known.INCLUDES + IS_AFTER -> Known.IS_AFTER + IS_BEFORE -> Known.IS_BEFORE + LT -> Known.LT + LTE -> Known.LTE + NEQ -> Known.NEQ + OMIT -> Known.OMIT + STARTS_WITH -> Known.STARTS_WITH + AND -> Known.AND + OR -> Known.OR + else -> throw CourierInvalidDataException("Unknown Operator: $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 CourierInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CourierInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): Operator = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Operator && 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 UnionMember0 && + operator == other.operator && + path == other.path && + value == other.value && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(operator, path, value, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "UnionMember0{operator=$operator, path=$path, value=$value, additionalProperties=$additionalProperties}" + } +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/audiences/NestedFilterConfig.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/audiences/NestedFilterConfig.kt new file mode 100644 index 00000000..441d786d --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/audiences/NestedFilterConfig.kt @@ -0,0 +1,439 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.audiences + +import com.courier.api.core.Enum +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkKnown +import com.courier.api.core.checkRequired +import com.courier.api.core.toImmutable +import com.courier.api.errors.CourierInvalidDataException +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 kotlin.jvm.optionals.getOrNull + +class NestedFilterConfig +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val operator: JsonField, + private val rules: JsonField>, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("operator") @ExcludeMissing operator: JsonField = JsonMissing.of(), + @JsonProperty("rules") + @ExcludeMissing + rules: JsonField> = JsonMissing.of(), + ) : this(operator, rules, mutableMapOf()) + + /** + * The operator to use for filtering + * + * @throws CourierInvalidDataException 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 operator(): Operator = operator.getRequired("operator") + + /** + * @throws CourierInvalidDataException 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 rules(): List = rules.getRequired("rules") + + /** + * Returns the raw JSON value of [operator]. + * + * Unlike [operator], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("operator") @ExcludeMissing fun _operator(): JsonField = operator + + /** + * Returns the raw JSON value of [rules]. + * + * Unlike [rules], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("rules") @ExcludeMissing fun _rules(): JsonField> = rules + + @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 [NestedFilterConfig]. + * + * The following fields are required: + * ```java + * .operator() + * .rules() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [NestedFilterConfig]. */ + class Builder internal constructor() { + + private var operator: JsonField? = null + private var rules: JsonField>? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(nestedFilterConfig: NestedFilterConfig) = apply { + operator = nestedFilterConfig.operator + rules = nestedFilterConfig.rules.map { it.toMutableList() } + additionalProperties = nestedFilterConfig.additionalProperties.toMutableMap() + } + + /** The operator to use for filtering */ + fun operator(operator: Operator) = operator(JsonField.of(operator)) + + /** + * Sets [Builder.operator] to an arbitrary JSON value. + * + * You should usually call [Builder.operator] with a well-typed [Operator] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun operator(operator: JsonField) = apply { this.operator = operator } + + fun rules(rules: List) = rules(JsonField.of(rules)) + + /** + * Sets [Builder.rules] to an arbitrary JSON value. + * + * You should usually call [Builder.rules] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun rules(rules: JsonField>) = apply { + this.rules = rules.map { it.toMutableList() } + } + + /** + * Adds a single [FilterConfig] to [rules]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addRule(rule: FilterConfig) = apply { + rules = + (rules ?: JsonField.of(mutableListOf())).also { checkKnown("rules", it).add(rule) } + } + + /** Alias for calling [addRule] with `FilterConfig.ofUnionMember0(unionMember0)`. */ + fun addRule(unionMember0: FilterConfig.UnionMember0) = + addRule(FilterConfig.ofUnionMember0(unionMember0)) + + /** Alias for calling [addRule] with `FilterConfig.ofNested(nested)`. */ + fun addRule(nested: NestedFilterConfig) = addRule(FilterConfig.ofNested(nested)) + + 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 [NestedFilterConfig]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .operator() + * .rules() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): NestedFilterConfig = + NestedFilterConfig( + checkRequired("operator", operator), + checkRequired("rules", rules).map { it.toImmutable() }, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): NestedFilterConfig = apply { + if (validated) { + return@apply + } + + operator().validate() + rules().forEach { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (operator.asKnown().getOrNull()?.validity() ?: 0) + + (rules.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + /** The operator to use for filtering */ + class Operator @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 ENDS_WITH = of("ENDS_WITH") + + @JvmField val EQ = of("EQ") + + @JvmField val EXISTS = of("EXISTS") + + @JvmField val GT = of("GT") + + @JvmField val GTE = of("GTE") + + @JvmField val INCLUDES = of("INCLUDES") + + @JvmField val IS_AFTER = of("IS_AFTER") + + @JvmField val IS_BEFORE = of("IS_BEFORE") + + @JvmField val LT = of("LT") + + @JvmField val LTE = of("LTE") + + @JvmField val NEQ = of("NEQ") + + @JvmField val OMIT = of("OMIT") + + @JvmField val STARTS_WITH = of("STARTS_WITH") + + @JvmField val AND = of("AND") + + @JvmField val OR = of("OR") + + @JvmStatic fun of(value: String) = Operator(JsonField.of(value)) + } + + /** An enum containing [Operator]'s known values. */ + enum class Known { + ENDS_WITH, + EQ, + EXISTS, + GT, + GTE, + INCLUDES, + IS_AFTER, + IS_BEFORE, + LT, + LTE, + NEQ, + OMIT, + STARTS_WITH, + AND, + OR, + } + + /** + * An enum containing [Operator]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Operator] 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 { + ENDS_WITH, + EQ, + EXISTS, + GT, + GTE, + INCLUDES, + IS_AFTER, + IS_BEFORE, + LT, + LTE, + NEQ, + OMIT, + STARTS_WITH, + AND, + OR, + /** An enum member indicating that [Operator] 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) { + ENDS_WITH -> Value.ENDS_WITH + EQ -> Value.EQ + EXISTS -> Value.EXISTS + GT -> Value.GT + GTE -> Value.GTE + INCLUDES -> Value.INCLUDES + IS_AFTER -> Value.IS_AFTER + IS_BEFORE -> Value.IS_BEFORE + LT -> Value.LT + LTE -> Value.LTE + NEQ -> Value.NEQ + OMIT -> Value.OMIT + STARTS_WITH -> Value.STARTS_WITH + AND -> Value.AND + OR -> Value.OR + 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 CourierInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + ENDS_WITH -> Known.ENDS_WITH + EQ -> Known.EQ + EXISTS -> Known.EXISTS + GT -> Known.GT + GTE -> Known.GTE + INCLUDES -> Known.INCLUDES + IS_AFTER -> Known.IS_AFTER + IS_BEFORE -> Known.IS_BEFORE + LT -> Known.LT + LTE -> Known.LTE + NEQ -> Known.NEQ + OMIT -> Known.OMIT + STARTS_WITH -> Known.STARTS_WITH + AND -> Known.AND + OR -> Known.OR + else -> throw CourierInvalidDataException("Unknown Operator: $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 CourierInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { CourierInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + fun validate(): Operator = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Operator && 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 NestedFilterConfig && + operator == other.operator && + rules == other.rules && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(operator, rules, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "NestedFilterConfig{operator=$operator, rules=$rules, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/audiences/Paging.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/audiences/Paging.kt new file mode 100644 index 00000000..c4aa366b --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/audiences/Paging.kt @@ -0,0 +1,203 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.audiences + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkRequired +import com.courier.api.errors.CourierInvalidDataException +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 Paging +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val more: JsonField, + private val cursor: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("more") @ExcludeMissing more: JsonField = JsonMissing.of(), + @JsonProperty("cursor") @ExcludeMissing cursor: JsonField = JsonMissing.of(), + ) : this(more, cursor, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 more(): Boolean = more.getRequired("more") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun cursor(): Optional = cursor.getOptional("cursor") + + /** + * Returns the raw JSON value of [more]. + * + * Unlike [more], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("more") @ExcludeMissing fun _more(): JsonField = more + + /** + * Returns the raw JSON value of [cursor]. + * + * Unlike [cursor], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("cursor") @ExcludeMissing fun _cursor(): JsonField = cursor + + @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 [Paging]. + * + * The following fields are required: + * ```java + * .more() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Paging]. */ + class Builder internal constructor() { + + private var more: JsonField? = null + private var cursor: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(paging: Paging) = apply { + more = paging.more + cursor = paging.cursor + additionalProperties = paging.additionalProperties.toMutableMap() + } + + fun more(more: Boolean) = more(JsonField.of(more)) + + /** + * Sets [Builder.more] to an arbitrary JSON value. + * + * You should usually call [Builder.more] with a well-typed [Boolean] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun more(more: JsonField) = apply { this.more = more } + + fun cursor(cursor: String?) = cursor(JsonField.ofNullable(cursor)) + + /** Alias for calling [Builder.cursor] with `cursor.orElse(null)`. */ + fun cursor(cursor: Optional) = cursor(cursor.getOrNull()) + + /** + * Sets [Builder.cursor] to an arbitrary JSON value. + * + * You should usually call [Builder.cursor] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun cursor(cursor: JsonField) = apply { this.cursor = cursor } + + 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 [Paging]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .more() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Paging = + Paging(checkRequired("more", more), cursor, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Paging = apply { + if (validated) { + return@apply + } + + more() + cursor() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (more.asKnown().isPresent) 1 else 0) + (if (cursor.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Paging && + more == other.more && + cursor == other.cursor && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(more, cursor, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Paging{more=$more, cursor=$cursor, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/auditevents/AuditEvent.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/auditevents/AuditEvent.kt new file mode 100644 index 00000000..b8c007e5 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/auditevents/AuditEvent.kt @@ -0,0 +1,537 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.auditevents + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkRequired +import com.courier.api.errors.CourierInvalidDataException +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 AuditEvent +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val actor: JsonField, + private val auditEventId: JsonField, + private val source: JsonField, + private val target: JsonField, + private val timestamp: JsonField, + private val type: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("actor") @ExcludeMissing actor: JsonField = JsonMissing.of(), + @JsonProperty("auditEventId") + @ExcludeMissing + auditEventId: JsonField = JsonMissing.of(), + @JsonProperty("source") @ExcludeMissing source: JsonField = JsonMissing.of(), + @JsonProperty("target") @ExcludeMissing target: JsonField = JsonMissing.of(), + @JsonProperty("timestamp") @ExcludeMissing timestamp: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), + ) : this(actor, auditEventId, source, target, timestamp, type, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 actor(): Actor = actor.getRequired("actor") + + /** + * @throws CourierInvalidDataException 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 auditEventId(): String = auditEventId.getRequired("auditEventId") + + /** + * @throws CourierInvalidDataException 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 source(): String = source.getRequired("source") + + /** + * @throws CourierInvalidDataException 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 target(): String = target.getRequired("target") + + /** + * @throws CourierInvalidDataException 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 timestamp(): String = timestamp.getRequired("timestamp") + + /** + * @throws CourierInvalidDataException 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 type(): String = type.getRequired("type") + + /** + * Returns the raw JSON value of [actor]. + * + * Unlike [actor], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("actor") @ExcludeMissing fun _actor(): JsonField = actor + + /** + * Returns the raw JSON value of [auditEventId]. + * + * Unlike [auditEventId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("auditEventId") + @ExcludeMissing + fun _auditEventId(): JsonField = auditEventId + + /** + * Returns the raw JSON value of [source]. + * + * Unlike [source], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("source") @ExcludeMissing fun _source(): JsonField = source + + /** + * Returns the raw JSON value of [target]. + * + * Unlike [target], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("target") @ExcludeMissing fun _target(): JsonField = target + + /** + * 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 + + /** + * 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 + + @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 [AuditEvent]. + * + * The following fields are required: + * ```java + * .actor() + * .auditEventId() + * .source() + * .target() + * .timestamp() + * .type() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AuditEvent]. */ + class Builder internal constructor() { + + private var actor: JsonField? = null + private var auditEventId: JsonField? = null + private var source: JsonField? = null + private var target: JsonField? = null + private var timestamp: JsonField? = null + private var type: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(auditEvent: AuditEvent) = apply { + actor = auditEvent.actor + auditEventId = auditEvent.auditEventId + source = auditEvent.source + target = auditEvent.target + timestamp = auditEvent.timestamp + type = auditEvent.type + additionalProperties = auditEvent.additionalProperties.toMutableMap() + } + + fun actor(actor: Actor) = actor(JsonField.of(actor)) + + /** + * Sets [Builder.actor] to an arbitrary JSON value. + * + * You should usually call [Builder.actor] with a well-typed [Actor] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun actor(actor: JsonField) = apply { this.actor = actor } + + fun auditEventId(auditEventId: String) = auditEventId(JsonField.of(auditEventId)) + + /** + * Sets [Builder.auditEventId] to an arbitrary JSON value. + * + * You should usually call [Builder.auditEventId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun auditEventId(auditEventId: JsonField) = apply { + this.auditEventId = auditEventId + } + + fun source(source: String) = source(JsonField.of(source)) + + /** + * Sets [Builder.source] to an arbitrary JSON value. + * + * You should usually call [Builder.source] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun source(source: JsonField) = apply { this.source = source } + + fun target(target: String) = target(JsonField.of(target)) + + /** + * Sets [Builder.target] to an arbitrary JSON value. + * + * You should usually call [Builder.target] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun target(target: JsonField) = apply { this.target = target } + + fun timestamp(timestamp: String) = timestamp(JsonField.of(timestamp)) + + /** + * Sets [Builder.timestamp] to an arbitrary JSON value. + * + * You should usually call [Builder.timestamp] with a well-typed [String] 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 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 } + + 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 [AuditEvent]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .actor() + * .auditEventId() + * .source() + * .target() + * .timestamp() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): AuditEvent = + AuditEvent( + checkRequired("actor", actor), + checkRequired("auditEventId", auditEventId), + checkRequired("source", source), + checkRequired("target", target), + checkRequired("timestamp", timestamp), + checkRequired("type", type), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): AuditEvent = apply { + if (validated) { + return@apply + } + + actor().validate() + auditEventId() + source() + target() + timestamp() + type() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (actor.asKnown().getOrNull()?.validity() ?: 0) + + (if (auditEventId.asKnown().isPresent) 1 else 0) + + (if (source.asKnown().isPresent) 1 else 0) + + (if (target.asKnown().isPresent) 1 else 0) + + (if (timestamp.asKnown().isPresent) 1 else 0) + + (if (type.asKnown().isPresent) 1 else 0) + + class Actor + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val id: JsonField, + private val email: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("email") @ExcludeMissing email: JsonField = JsonMissing.of(), + ) : this(id, email, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 id(): String = id.getRequired("id") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun email(): Optional = email.getOptional("email") + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + /** + * 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 + + @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 [Actor]. + * + * The following fields are required: + * ```java + * .id() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Actor]. */ + class Builder internal constructor() { + + private var id: JsonField? = null + private var email: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(actor: Actor) = apply { + id = actor.id + email = actor.email + additionalProperties = actor.additionalProperties.toMutableMap() + } + + fun id(id: String) = id(JsonField.of(id)) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun id(id: JsonField) = apply { this.id = id } + + fun email(email: String?) = email(JsonField.ofNullable(email)) + + /** Alias for calling [Builder.email] with `email.orElse(null)`. */ + fun email(email: Optional) = email(email.getOrNull()) + + /** + * 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 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 [Actor]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Actor = + Actor(checkRequired("id", id), email, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Actor = apply { + if (validated) { + return@apply + } + + id() + email() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (id.asKnown().isPresent) 1 else 0) + (if (email.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Actor && + id == other.id && + email == other.email && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(id, email, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Actor{id=$id, email=$email, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AuditEvent && + actor == other.actor && + auditEventId == other.auditEventId && + source == other.source && + target == other.target && + timestamp == other.timestamp && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(actor, auditEventId, source, target, timestamp, type, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AuditEvent{actor=$actor, auditEventId=$auditEventId, source=$source, target=$target, timestamp=$timestamp, type=$type, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/auditevents/AuditEventListParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/auditevents/AuditEventListParams.kt new file mode 100644 index 00000000..4ae23645 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/auditevents/AuditEventListParams.kt @@ -0,0 +1,191 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.auditevents + +import com.courier.api.core.Params +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Fetch the list of audit events */ +class AuditEventListParams +private constructor( + private val cursor: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** A unique identifier that allows for fetching the next set of audit events. */ + fun cursor(): Optional = Optional.ofNullable(cursor) + + /** 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(): AuditEventListParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [AuditEventListParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AuditEventListParams]. */ + class Builder internal constructor() { + + private var cursor: String? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(auditEventListParams: AuditEventListParams) = apply { + cursor = auditEventListParams.cursor + additionalHeaders = auditEventListParams.additionalHeaders.toBuilder() + additionalQueryParams = auditEventListParams.additionalQueryParams.toBuilder() + } + + /** A unique identifier that allows for fetching the next set of audit events. */ + fun cursor(cursor: String?) = apply { this.cursor = cursor } + + /** Alias for calling [Builder.cursor] with `cursor.orElse(null)`. */ + fun cursor(cursor: Optional) = cursor(cursor.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 [AuditEventListParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): AuditEventListParams = + AuditEventListParams(cursor, additionalHeaders.build(), additionalQueryParams.build()) + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + cursor?.let { put("cursor", it) } + putAll(additionalQueryParams) + } + .build() + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AuditEventListParams && + cursor == other.cursor && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = Objects.hash(cursor, additionalHeaders, additionalQueryParams) + + override fun toString() = + "AuditEventListParams{cursor=$cursor, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/auditevents/AuditEventListResponse.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/auditevents/AuditEventListResponse.kt new file mode 100644 index 00000000..d5382159 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/auditevents/AuditEventListResponse.kt @@ -0,0 +1,226 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.auditevents + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkKnown +import com.courier.api.core.checkRequired +import com.courier.api.core.toImmutable +import com.courier.api.errors.CourierInvalidDataException +import com.courier.api.models.audiences.Paging +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 kotlin.jvm.optionals.getOrNull + +class AuditEventListResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val paging: JsonField, + private val results: JsonField>, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("paging") @ExcludeMissing paging: JsonField = JsonMissing.of(), + @JsonProperty("results") + @ExcludeMissing + results: JsonField> = JsonMissing.of(), + ) : this(paging, results, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 paging(): Paging = paging.getRequired("paging") + + /** + * @throws CourierInvalidDataException 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 results(): List = results.getRequired("results") + + /** + * Returns the raw JSON value of [paging]. + * + * Unlike [paging], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("paging") @ExcludeMissing fun _paging(): JsonField = paging + + /** + * Returns the raw JSON value of [results]. + * + * Unlike [results], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("results") @ExcludeMissing fun _results(): JsonField> = results + + @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 [AuditEventListResponse]. + * + * The following fields are required: + * ```java + * .paging() + * .results() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AuditEventListResponse]. */ + class Builder internal constructor() { + + private var paging: JsonField? = null + private var results: JsonField>? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(auditEventListResponse: AuditEventListResponse) = apply { + paging = auditEventListResponse.paging + results = auditEventListResponse.results.map { it.toMutableList() } + additionalProperties = auditEventListResponse.additionalProperties.toMutableMap() + } + + fun paging(paging: Paging) = paging(JsonField.of(paging)) + + /** + * Sets [Builder.paging] to an arbitrary JSON value. + * + * You should usually call [Builder.paging] with a well-typed [Paging] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun paging(paging: JsonField) = apply { this.paging = paging } + + fun results(results: List) = results(JsonField.of(results)) + + /** + * Sets [Builder.results] to an arbitrary JSON value. + * + * You should usually call [Builder.results] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun results(results: JsonField>) = apply { + this.results = results.map { it.toMutableList() } + } + + /** + * Adds a single [AuditEvent] to [results]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addResult(result: AuditEvent) = apply { + results = + (results ?: JsonField.of(mutableListOf())).also { + checkKnown("results", it).add(result) + } + } + + 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 [AuditEventListResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .paging() + * .results() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): AuditEventListResponse = + AuditEventListResponse( + checkRequired("paging", paging), + checkRequired("results", results).map { it.toImmutable() }, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): AuditEventListResponse = apply { + if (validated) { + return@apply + } + + paging().validate() + results().forEach { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (paging.asKnown().getOrNull()?.validity() ?: 0) + + (results.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AuditEventListResponse && + paging == other.paging && + results == other.results && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(paging, results, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AuditEventListResponse{paging=$paging, results=$results, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/auditevents/AuditEventRetrieveParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/auditevents/AuditEventRetrieveParams.kt new file mode 100644 index 00000000..cfe342b4 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/auditevents/AuditEventRetrieveParams.kt @@ -0,0 +1,194 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.auditevents + +import com.courier.api.core.Params +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Fetch a specific audit event by ID. */ +class AuditEventRetrieveParams +private constructor( + private val auditEventId: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun auditEventId(): Optional = Optional.ofNullable(auditEventId) + + /** 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(): AuditEventRetrieveParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [AuditEventRetrieveParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AuditEventRetrieveParams]. */ + class Builder internal constructor() { + + private var auditEventId: String? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(auditEventRetrieveParams: AuditEventRetrieveParams) = apply { + auditEventId = auditEventRetrieveParams.auditEventId + additionalHeaders = auditEventRetrieveParams.additionalHeaders.toBuilder() + additionalQueryParams = auditEventRetrieveParams.additionalQueryParams.toBuilder() + } + + fun auditEventId(auditEventId: String?) = apply { this.auditEventId = auditEventId } + + /** Alias for calling [Builder.auditEventId] with `auditEventId.orElse(null)`. */ + fun auditEventId(auditEventId: Optional) = auditEventId(auditEventId.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 [AuditEventRetrieveParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): AuditEventRetrieveParams = + AuditEventRetrieveParams( + auditEventId, + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _pathParam(index: Int): String = + when (index) { + 0 -> auditEventId ?: "" + 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 AuditEventRetrieveParams && + auditEventId == other.auditEventId && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(auditEventId, additionalHeaders, additionalQueryParams) + + override fun toString() = + "AuditEventRetrieveParams{auditEventId=$auditEventId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/auth/AuthIssueTokenParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/auth/AuthIssueTokenParams.kt new file mode 100644 index 00000000..62d595ac --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/auth/AuthIssueTokenParams.kt @@ -0,0 +1,477 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.auth + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.Params +import com.courier.api.core.checkRequired +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import com.courier.api.errors.CourierInvalidDataException +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 + +/** Returns a new access token. */ +class AuthIssueTokenParams +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * @throws CourierInvalidDataException 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 expiresIn(): String = body.expiresIn() + + /** + * @throws CourierInvalidDataException 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 scope(): String = body.scope() + + /** + * Returns the raw JSON value of [expiresIn]. + * + * Unlike [expiresIn], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _expiresIn(): JsonField = body._expiresIn() + + /** + * Returns the raw JSON value of [scope]. + * + * Unlike [scope], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _scope(): JsonField = body._scope() + + 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 [AuthIssueTokenParams]. + * + * The following fields are required: + * ```java + * .expiresIn() + * .scope() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AuthIssueTokenParams]. */ + 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(authIssueTokenParams: AuthIssueTokenParams) = apply { + body = authIssueTokenParams.body.toBuilder() + additionalHeaders = authIssueTokenParams.additionalHeaders.toBuilder() + additionalQueryParams = authIssueTokenParams.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: + * - [expiresIn] + * - [scope] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + fun expiresIn(expiresIn: String) = apply { body.expiresIn(expiresIn) } + + /** + * Sets [Builder.expiresIn] to an arbitrary JSON value. + * + * You should usually call [Builder.expiresIn] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun expiresIn(expiresIn: JsonField) = apply { body.expiresIn(expiresIn) } + + fun scope(scope: String) = apply { body.scope(scope) } + + /** + * Sets [Builder.scope] to an arbitrary JSON value. + * + * You should usually call [Builder.scope] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun scope(scope: JsonField) = apply { body.scope(scope) } + + 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 [AuthIssueTokenParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .expiresIn() + * .scope() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): AuthIssueTokenParams = + AuthIssueTokenParams( + 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 expiresIn: JsonField, + private val scope: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("expires_in") + @ExcludeMissing + expiresIn: JsonField = JsonMissing.of(), + @JsonProperty("scope") @ExcludeMissing scope: JsonField = JsonMissing.of(), + ) : this(expiresIn, scope, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 expiresIn(): String = expiresIn.getRequired("expires_in") + + /** + * @throws CourierInvalidDataException 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 scope(): String = scope.getRequired("scope") + + /** + * 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 [scope]. + * + * Unlike [scope], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("scope") @ExcludeMissing fun _scope(): JsonField = scope + + @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 + * .expiresIn() + * .scope() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var expiresIn: JsonField? = null + private var scope: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + expiresIn = body.expiresIn + scope = body.scope + additionalProperties = body.additionalProperties.toMutableMap() + } + + fun expiresIn(expiresIn: String) = expiresIn(JsonField.of(expiresIn)) + + /** + * Sets [Builder.expiresIn] to an arbitrary JSON value. + * + * You should usually call [Builder.expiresIn] with a well-typed [String] 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 } + + fun scope(scope: String) = scope(JsonField.of(scope)) + + /** + * Sets [Builder.scope] to an arbitrary JSON value. + * + * You should usually call [Builder.scope] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun scope(scope: JsonField) = apply { this.scope = scope } + + 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 + * .expiresIn() + * .scope() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("expiresIn", expiresIn), + checkRequired("scope", scope), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + expiresIn() + scope() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (scope.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + expiresIn == other.expiresIn && + scope == other.scope && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(expiresIn, scope, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{expiresIn=$expiresIn, scope=$scope, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AuthIssueTokenParams && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = Objects.hash(body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "AuthIssueTokenParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/auth/AuthIssueTokenResponse.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/auth/AuthIssueTokenResponse.kt new file mode 100644 index 00000000..6bc3c1ea --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/auth/AuthIssueTokenResponse.kt @@ -0,0 +1,170 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.auth + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkRequired +import com.courier.api.errors.CourierInvalidDataException +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 + +class AuthIssueTokenResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val token: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("token") @ExcludeMissing token: JsonField = JsonMissing.of() + ) : this(token, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 token(): String = token.getRequired("token") + + /** + * Returns the raw JSON value of [token]. + * + * Unlike [token], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("token") @ExcludeMissing fun _token(): JsonField = token + + @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 [AuthIssueTokenResponse]. + * + * The following fields are required: + * ```java + * .token() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AuthIssueTokenResponse]. */ + class Builder internal constructor() { + + private var token: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(authIssueTokenResponse: AuthIssueTokenResponse) = apply { + token = authIssueTokenResponse.token + additionalProperties = authIssueTokenResponse.additionalProperties.toMutableMap() + } + + fun token(token: String) = token(JsonField.of(token)) + + /** + * Sets [Builder.token] to an arbitrary JSON value. + * + * You should usually call [Builder.token] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun token(token: JsonField) = apply { this.token = token } + + 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 [AuthIssueTokenResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .token() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): AuthIssueTokenResponse = + AuthIssueTokenResponse( + checkRequired("token", token), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): AuthIssueTokenResponse = apply { + if (validated) { + return@apply + } + + token() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (token.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AuthIssueTokenResponse && + token == other.token && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(token, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AuthIssueTokenResponse{token=$token, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/automations/invoke/AutomationInvokeResponse.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/automations/invoke/AutomationInvokeResponse.kt new file mode 100644 index 00000000..716707c1 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/automations/invoke/AutomationInvokeResponse.kt @@ -0,0 +1,170 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.automations.invoke + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkRequired +import com.courier.api.errors.CourierInvalidDataException +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 + +class AutomationInvokeResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val runId: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("runId") @ExcludeMissing runId: JsonField = JsonMissing.of() + ) : this(runId, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 runId(): String = runId.getRequired("runId") + + /** + * Returns the raw JSON value of [runId]. + * + * Unlike [runId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("runId") @ExcludeMissing fun _runId(): JsonField = runId + + @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 [AutomationInvokeResponse]. + * + * The following fields are required: + * ```java + * .runId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AutomationInvokeResponse]. */ + class Builder internal constructor() { + + private var runId: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(automationInvokeResponse: AutomationInvokeResponse) = apply { + runId = automationInvokeResponse.runId + additionalProperties = automationInvokeResponse.additionalProperties.toMutableMap() + } + + fun runId(runId: String) = runId(JsonField.of(runId)) + + /** + * Sets [Builder.runId] to an arbitrary JSON value. + * + * You should usually call [Builder.runId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun runId(runId: JsonField) = apply { this.runId = runId } + + 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 [AutomationInvokeResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .runId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): AutomationInvokeResponse = + AutomationInvokeResponse( + checkRequired("runId", runId), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): AutomationInvokeResponse = apply { + if (validated) { + return@apply + } + + runId() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (runId.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AutomationInvokeResponse && + runId == other.runId && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(runId, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AutomationInvokeResponse{runId=$runId, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/automations/invoke/InvokeInvokeAdHocParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/automations/invoke/InvokeInvokeAdHocParams.kt new file mode 100644 index 00000000..568b95ff --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/automations/invoke/InvokeInvokeAdHocParams.kt @@ -0,0 +1,5597 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.automations.invoke + +import com.courier.api.core.BaseDeserializer +import com.courier.api.core.BaseSerializer +import com.courier.api.core.Enum +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.Params +import com.courier.api.core.allMaxBy +import com.courier.api.core.checkKnown +import com.courier.api.core.checkRequired +import com.courier.api.core.getOrThrow +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import com.courier.api.core.toImmutable +import com.courier.api.errors.CourierInvalidDataException +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 com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.ObjectCodec +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.module.kotlin.jacksonTypeRef +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * Invoke an ad hoc automation run. This endpoint accepts a JSON payload with a series of automation + * steps. For information about what steps are available, checkout the ad hoc automation guide + * [here](https://www.courier.com/docs/automations/steps/). + */ +class InvokeInvokeAdHocParams +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * @throws CourierInvalidDataException 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 automation(): Automation = body.automation() + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun brand(): Optional = body.brand() + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun data(): Optional = body.data() + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun profile(): Optional = body.profile() + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun recipient(): Optional = body.recipient() + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun template(): Optional = body.template() + + /** + * Returns the raw JSON value of [automation]. + * + * Unlike [automation], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _automation(): JsonField = body._automation() + + /** + * Returns the raw JSON value of [brand]. + * + * Unlike [brand], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _brand(): JsonField = body._brand() + + /** + * Returns the raw JSON value of [data]. + * + * Unlike [data], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _data(): JsonField = body._data() + + /** + * Returns the raw JSON value of [profile]. + * + * Unlike [profile], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _profile(): JsonField = body._profile() + + /** + * Returns the raw JSON value of [recipient]. + * + * Unlike [recipient], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _recipient(): JsonField = body._recipient() + + /** + * Returns the raw JSON value of [template]. + * + * Unlike [template], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _template(): JsonField = body._template() + + 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 [InvokeInvokeAdHocParams]. + * + * The following fields are required: + * ```java + * .automation() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [InvokeInvokeAdHocParams]. */ + 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(invokeInvokeAdHocParams: InvokeInvokeAdHocParams) = apply { + body = invokeInvokeAdHocParams.body.toBuilder() + additionalHeaders = invokeInvokeAdHocParams.additionalHeaders.toBuilder() + additionalQueryParams = invokeInvokeAdHocParams.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: + * - [automation] + * - [brand] + * - [data] + * - [profile] + * - [recipient] + * - etc. + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + fun automation(automation: Automation) = apply { body.automation(automation) } + + /** + * Sets [Builder.automation] to an arbitrary JSON value. + * + * You should usually call [Builder.automation] with a well-typed [Automation] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun automation(automation: JsonField) = apply { body.automation(automation) } + + fun brand(brand: String?) = apply { body.brand(brand) } + + /** Alias for calling [Builder.brand] with `brand.orElse(null)`. */ + fun brand(brand: Optional) = brand(brand.getOrNull()) + + /** + * Sets [Builder.brand] to an arbitrary JSON value. + * + * You should usually call [Builder.brand] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun brand(brand: JsonField) = apply { body.brand(brand) } + + fun data(data: Data?) = apply { body.data(data) } + + /** Alias for calling [Builder.data] with `data.orElse(null)`. */ + fun data(data: Optional) = data(data.getOrNull()) + + /** + * 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 { body.data(data) } + + fun profile(profile: Profile?) = apply { body.profile(profile) } + + /** Alias for calling [Builder.profile] with `profile.orElse(null)`. */ + fun profile(profile: Optional) = profile(profile.getOrNull()) + + /** + * Sets [Builder.profile] to an arbitrary JSON value. + * + * You should usually call [Builder.profile] with a well-typed [Profile] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun profile(profile: JsonField) = apply { body.profile(profile) } + + fun recipient(recipient: String?) = apply { body.recipient(recipient) } + + /** Alias for calling [Builder.recipient] with `recipient.orElse(null)`. */ + fun recipient(recipient: Optional) = recipient(recipient.getOrNull()) + + /** + * Sets [Builder.recipient] to an arbitrary JSON value. + * + * You should usually call [Builder.recipient] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun recipient(recipient: JsonField) = apply { body.recipient(recipient) } + + fun template(template: String?) = apply { body.template(template) } + + /** Alias for calling [Builder.template] with `template.orElse(null)`. */ + fun template(template: Optional) = template(template.getOrNull()) + + /** + * Sets [Builder.template] to an arbitrary JSON value. + * + * You should usually call [Builder.template] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun template(template: JsonField) = apply { body.template(template) } + + 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 [InvokeInvokeAdHocParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .automation() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): InvokeInvokeAdHocParams = + InvokeInvokeAdHocParams( + 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 automation: JsonField, + private val brand: JsonField, + private val data: JsonField, + private val profile: JsonField, + private val recipient: JsonField, + private val template: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("automation") + @ExcludeMissing + automation: JsonField = JsonMissing.of(), + @JsonProperty("brand") @ExcludeMissing brand: JsonField = JsonMissing.of(), + @JsonProperty("data") @ExcludeMissing data: JsonField = JsonMissing.of(), + @JsonProperty("profile") @ExcludeMissing profile: JsonField = JsonMissing.of(), + @JsonProperty("recipient") + @ExcludeMissing + recipient: JsonField = JsonMissing.of(), + @JsonProperty("template") @ExcludeMissing template: JsonField = JsonMissing.of(), + ) : this(automation, brand, data, profile, recipient, template, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 automation(): Automation = automation.getRequired("automation") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun brand(): Optional = brand.getOptional("brand") + + /** + * @throws CourierInvalidDataException 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 CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun profile(): Optional = profile.getOptional("profile") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun recipient(): Optional = recipient.getOptional("recipient") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun template(): Optional = template.getOptional("template") + + /** + * Returns the raw JSON value of [automation]. + * + * Unlike [automation], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("automation") + @ExcludeMissing + fun _automation(): JsonField = automation + + /** + * Returns the raw JSON value of [brand]. + * + * Unlike [brand], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("brand") @ExcludeMissing fun _brand(): JsonField = brand + + /** + * 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 [profile]. + * + * Unlike [profile], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("profile") @ExcludeMissing fun _profile(): JsonField = profile + + /** + * Returns the raw JSON value of [recipient]. + * + * Unlike [recipient], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("recipient") @ExcludeMissing fun _recipient(): JsonField = recipient + + /** + * Returns the raw JSON value of [template]. + * + * Unlike [template], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("template") @ExcludeMissing fun _template(): JsonField = template + + @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 + * .automation() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var automation: JsonField? = null + private var brand: JsonField = JsonMissing.of() + private var data: JsonField = JsonMissing.of() + private var profile: JsonField = JsonMissing.of() + private var recipient: JsonField = JsonMissing.of() + private var template: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + automation = body.automation + brand = body.brand + data = body.data + profile = body.profile + recipient = body.recipient + template = body.template + additionalProperties = body.additionalProperties.toMutableMap() + } + + fun automation(automation: Automation) = automation(JsonField.of(automation)) + + /** + * Sets [Builder.automation] to an arbitrary JSON value. + * + * You should usually call [Builder.automation] with a well-typed [Automation] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun automation(automation: JsonField) = apply { + this.automation = automation + } + + fun brand(brand: String?) = brand(JsonField.ofNullable(brand)) + + /** Alias for calling [Builder.brand] with `brand.orElse(null)`. */ + fun brand(brand: Optional) = brand(brand.getOrNull()) + + /** + * Sets [Builder.brand] to an arbitrary JSON value. + * + * You should usually call [Builder.brand] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun brand(brand: JsonField) = apply { this.brand = brand } + + fun data(data: Data?) = data(JsonField.ofNullable(data)) + + /** Alias for calling [Builder.data] with `data.orElse(null)`. */ + fun data(data: Optional) = data(data.getOrNull()) + + /** + * 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 profile(profile: Profile?) = profile(JsonField.ofNullable(profile)) + + /** Alias for calling [Builder.profile] with `profile.orElse(null)`. */ + fun profile(profile: Optional) = profile(profile.getOrNull()) + + /** + * Sets [Builder.profile] to an arbitrary JSON value. + * + * You should usually call [Builder.profile] with a well-typed [Profile] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun profile(profile: JsonField) = apply { this.profile = profile } + + fun recipient(recipient: String?) = recipient(JsonField.ofNullable(recipient)) + + /** Alias for calling [Builder.recipient] with `recipient.orElse(null)`. */ + fun recipient(recipient: Optional) = recipient(recipient.getOrNull()) + + /** + * Sets [Builder.recipient] to an arbitrary JSON value. + * + * You should usually call [Builder.recipient] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun recipient(recipient: JsonField) = apply { this.recipient = recipient } + + fun template(template: String?) = template(JsonField.ofNullable(template)) + + /** Alias for calling [Builder.template] with `template.orElse(null)`. */ + fun template(template: Optional) = template(template.getOrNull()) + + /** + * Sets [Builder.template] to an arbitrary JSON value. + * + * You should usually call [Builder.template] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun template(template: JsonField) = apply { this.template = template } + + 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 + * .automation() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("automation", automation), + brand, + data, + profile, + recipient, + template, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + automation().validate() + brand() + data().ifPresent { it.validate() } + profile().ifPresent { it.validate() } + recipient() + template() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (automation.asKnown().getOrNull()?.validity() ?: 0) + + (if (brand.asKnown().isPresent) 1 else 0) + + (data.asKnown().getOrNull()?.validity() ?: 0) + + (profile.asKnown().getOrNull()?.validity() ?: 0) + + (if (recipient.asKnown().isPresent) 1 else 0) + + (if (template.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + automation == other.automation && + brand == other.brand && + data == other.data && + profile == other.profile && + recipient == other.recipient && + template == other.template && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + automation, + brand, + data, + profile, + recipient, + template, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{automation=$automation, brand=$brand, data=$data, profile=$profile, recipient=$recipient, template=$template, additionalProperties=$additionalProperties}" + } + + class Automation + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val steps: JsonField>, + private val cancelationToken: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("steps") @ExcludeMissing steps: JsonField> = JsonMissing.of(), + @JsonProperty("cancelation_token") + @ExcludeMissing + cancelationToken: JsonField = JsonMissing.of(), + ) : this(steps, cancelationToken, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 steps(): List = steps.getRequired("steps") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun cancelationToken(): Optional = cancelationToken.getOptional("cancelation_token") + + /** + * Returns the raw JSON value of [steps]. + * + * Unlike [steps], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("steps") @ExcludeMissing fun _steps(): JsonField> = steps + + /** + * Returns the raw JSON value of [cancelationToken]. + * + * Unlike [cancelationToken], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("cancelation_token") + @ExcludeMissing + fun _cancelationToken(): JsonField = cancelationToken + + @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 [Automation]. + * + * The following fields are required: + * ```java + * .steps() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Automation]. */ + class Builder internal constructor() { + + private var steps: JsonField>? = null + private var cancelationToken: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(automation: Automation) = apply { + steps = automation.steps.map { it.toMutableList() } + cancelationToken = automation.cancelationToken + additionalProperties = automation.additionalProperties.toMutableMap() + } + + fun steps(steps: List) = steps(JsonField.of(steps)) + + /** + * Sets [Builder.steps] to an arbitrary JSON value. + * + * You should usually call [Builder.steps] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun steps(steps: JsonField>) = apply { + this.steps = steps.map { it.toMutableList() } + } + + /** + * Adds a single [Step] to [steps]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addStep(step: Step) = apply { + steps = + (steps ?: JsonField.of(mutableListOf())).also { + checkKnown("steps", it).add(step) + } + } + + /** Alias for calling [addStep] with `Step.ofAutomationDelay(automationDelay)`. */ + fun addStep(automationDelay: Step.AutomationDelayStep) = + addStep(Step.ofAutomationDelay(automationDelay)) + + /** Alias for calling [addStep] with `Step.ofAutomationSend(automationSend)`. */ + fun addStep(automationSend: Step.AutomationSendStep) = + addStep(Step.ofAutomationSend(automationSend)) + + /** Alias for calling [addStep] with `Step.ofAutomationSendList(automationSendList)`. */ + fun addStep(automationSendList: Step.AutomationSendListStep) = + addStep(Step.ofAutomationSendList(automationSendList)) + + /** + * Alias for calling [addStep] with + * `Step.ofAutomationUpdateProfile(automationUpdateProfile)`. + */ + fun addStep(automationUpdateProfile: Step.AutomationUpdateProfileStep) = + addStep(Step.ofAutomationUpdateProfile(automationUpdateProfile)) + + /** Alias for calling [addStep] with `Step.ofAutomationCancel(automationCancel)`. */ + fun addStep(automationCancel: Step.AutomationCancelStep) = + addStep(Step.ofAutomationCancel(automationCancel)) + + /** + * Alias for calling [addStep] with `Step.ofAutomationFetchData(automationFetchData)`. + */ + fun addStep(automationFetchData: Step.AutomationFetchDataStep) = + addStep(Step.ofAutomationFetchData(automationFetchData)) + + /** Alias for calling [addStep] with `Step.ofAutomationInvoke(automationInvoke)`. */ + fun addStep(automationInvoke: Step.AutomationInvokeStep) = + addStep(Step.ofAutomationInvoke(automationInvoke)) + + fun cancelationToken(cancelationToken: String?) = + cancelationToken(JsonField.ofNullable(cancelationToken)) + + /** + * Alias for calling [Builder.cancelationToken] with `cancelationToken.orElse(null)`. + */ + fun cancelationToken(cancelationToken: Optional) = + cancelationToken(cancelationToken.getOrNull()) + + /** + * Sets [Builder.cancelationToken] to an arbitrary JSON value. + * + * You should usually call [Builder.cancelationToken] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun cancelationToken(cancelationToken: JsonField) = apply { + this.cancelationToken = cancelationToken + } + + 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 [Automation]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .steps() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Automation = + Automation( + checkRequired("steps", steps).map { it.toImmutable() }, + cancelationToken, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Automation = apply { + if (validated) { + return@apply + } + + steps().forEach { it.validate() } + cancelationToken() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (steps.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (cancelationToken.asKnown().isPresent) 1 else 0) + + @JsonDeserialize(using = Step.Deserializer::class) + @JsonSerialize(using = Step.Serializer::class) + class Step + private constructor( + private val automationDelay: AutomationDelayStep? = null, + private val automationSend: AutomationSendStep? = null, + private val automationSendList: AutomationSendListStep? = null, + private val automationUpdateProfile: AutomationUpdateProfileStep? = null, + private val automationCancel: AutomationCancelStep? = null, + private val automationFetchData: AutomationFetchDataStep? = null, + private val automationInvoke: AutomationInvokeStep? = null, + private val _json: JsonValue? = null, + ) { + + fun automationDelay(): Optional = + Optional.ofNullable(automationDelay) + + fun automationSend(): Optional = Optional.ofNullable(automationSend) + + fun automationSendList(): Optional = + Optional.ofNullable(automationSendList) + + fun automationUpdateProfile(): Optional = + Optional.ofNullable(automationUpdateProfile) + + fun automationCancel(): Optional = + Optional.ofNullable(automationCancel) + + fun automationFetchData(): Optional = + Optional.ofNullable(automationFetchData) + + fun automationInvoke(): Optional = + Optional.ofNullable(automationInvoke) + + fun isAutomationDelay(): Boolean = automationDelay != null + + fun isAutomationSend(): Boolean = automationSend != null + + fun isAutomationSendList(): Boolean = automationSendList != null + + fun isAutomationUpdateProfile(): Boolean = automationUpdateProfile != null + + fun isAutomationCancel(): Boolean = automationCancel != null + + fun isAutomationFetchData(): Boolean = automationFetchData != null + + fun isAutomationInvoke(): Boolean = automationInvoke != null + + fun asAutomationDelay(): AutomationDelayStep = + automationDelay.getOrThrow("automationDelay") + + fun asAutomationSend(): AutomationSendStep = automationSend.getOrThrow("automationSend") + + fun asAutomationSendList(): AutomationSendListStep = + automationSendList.getOrThrow("automationSendList") + + fun asAutomationUpdateProfile(): AutomationUpdateProfileStep = + automationUpdateProfile.getOrThrow("automationUpdateProfile") + + fun asAutomationCancel(): AutomationCancelStep = + automationCancel.getOrThrow("automationCancel") + + fun asAutomationFetchData(): AutomationFetchDataStep = + automationFetchData.getOrThrow("automationFetchData") + + fun asAutomationInvoke(): AutomationInvokeStep = + automationInvoke.getOrThrow("automationInvoke") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T = + when { + automationDelay != null -> visitor.visitAutomationDelay(automationDelay) + automationSend != null -> visitor.visitAutomationSend(automationSend) + automationSendList != null -> + visitor.visitAutomationSendList(automationSendList) + automationUpdateProfile != null -> + visitor.visitAutomationUpdateProfile(automationUpdateProfile) + automationCancel != null -> visitor.visitAutomationCancel(automationCancel) + automationFetchData != null -> + visitor.visitAutomationFetchData(automationFetchData) + automationInvoke != null -> visitor.visitAutomationInvoke(automationInvoke) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + fun validate(): Step = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitAutomationDelay(automationDelay: AutomationDelayStep) { + automationDelay.validate() + } + + override fun visitAutomationSend(automationSend: AutomationSendStep) { + automationSend.validate() + } + + override fun visitAutomationSendList( + automationSendList: AutomationSendListStep + ) { + automationSendList.validate() + } + + override fun visitAutomationUpdateProfile( + automationUpdateProfile: AutomationUpdateProfileStep + ) { + automationUpdateProfile.validate() + } + + override fun visitAutomationCancel(automationCancel: AutomationCancelStep) { + automationCancel.validate() + } + + override fun visitAutomationFetchData( + automationFetchData: AutomationFetchDataStep + ) { + automationFetchData.validate() + } + + override fun visitAutomationInvoke(automationInvoke: AutomationInvokeStep) { + automationInvoke.validate() + } + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + accept( + object : Visitor { + override fun visitAutomationDelay(automationDelay: AutomationDelayStep) = + automationDelay.validity() + + override fun visitAutomationSend(automationSend: AutomationSendStep) = + automationSend.validity() + + override fun visitAutomationSendList( + automationSendList: AutomationSendListStep + ) = automationSendList.validity() + + override fun visitAutomationUpdateProfile( + automationUpdateProfile: AutomationUpdateProfileStep + ) = automationUpdateProfile.validity() + + override fun visitAutomationCancel(automationCancel: AutomationCancelStep) = + automationCancel.validity() + + override fun visitAutomationFetchData( + automationFetchData: AutomationFetchDataStep + ) = automationFetchData.validity() + + override fun visitAutomationInvoke(automationInvoke: AutomationInvokeStep) = + automationInvoke.validity() + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Step && + automationDelay == other.automationDelay && + automationSend == other.automationSend && + automationSendList == other.automationSendList && + automationUpdateProfile == other.automationUpdateProfile && + automationCancel == other.automationCancel && + automationFetchData == other.automationFetchData && + automationInvoke == other.automationInvoke + } + + override fun hashCode(): Int = + Objects.hash( + automationDelay, + automationSend, + automationSendList, + automationUpdateProfile, + automationCancel, + automationFetchData, + automationInvoke, + ) + + override fun toString(): String = + when { + automationDelay != null -> "Step{automationDelay=$automationDelay}" + automationSend != null -> "Step{automationSend=$automationSend}" + automationSendList != null -> "Step{automationSendList=$automationSendList}" + automationUpdateProfile != null -> + "Step{automationUpdateProfile=$automationUpdateProfile}" + automationCancel != null -> "Step{automationCancel=$automationCancel}" + automationFetchData != null -> "Step{automationFetchData=$automationFetchData}" + automationInvoke != null -> "Step{automationInvoke=$automationInvoke}" + _json != null -> "Step{_unknown=$_json}" + else -> throw IllegalStateException("Invalid Step") + } + + companion object { + + @JvmStatic + fun ofAutomationDelay(automationDelay: AutomationDelayStep) = + Step(automationDelay = automationDelay) + + @JvmStatic + fun ofAutomationSend(automationSend: AutomationSendStep) = + Step(automationSend = automationSend) + + @JvmStatic + fun ofAutomationSendList(automationSendList: AutomationSendListStep) = + Step(automationSendList = automationSendList) + + @JvmStatic + fun ofAutomationUpdateProfile( + automationUpdateProfile: AutomationUpdateProfileStep + ) = Step(automationUpdateProfile = automationUpdateProfile) + + @JvmStatic + fun ofAutomationCancel(automationCancel: AutomationCancelStep) = + Step(automationCancel = automationCancel) + + @JvmStatic + fun ofAutomationFetchData(automationFetchData: AutomationFetchDataStep) = + Step(automationFetchData = automationFetchData) + + @JvmStatic + fun ofAutomationInvoke(automationInvoke: AutomationInvokeStep) = + Step(automationInvoke = automationInvoke) + } + + /** + * An interface that defines how to map each variant of [Step] to a value of type [T]. + */ + interface Visitor { + + fun visitAutomationDelay(automationDelay: AutomationDelayStep): T + + fun visitAutomationSend(automationSend: AutomationSendStep): T + + fun visitAutomationSendList(automationSendList: AutomationSendListStep): T + + fun visitAutomationUpdateProfile( + automationUpdateProfile: AutomationUpdateProfileStep + ): T + + fun visitAutomationCancel(automationCancel: AutomationCancelStep): T + + fun visitAutomationFetchData(automationFetchData: AutomationFetchDataStep): T + + fun visitAutomationInvoke(automationInvoke: AutomationInvokeStep): T + + /** + * Maps an unknown variant of [Step] to a value of type [T]. + * + * An instance of [Step] can contain an unknown variant if it was deserialized from + * data that doesn't match any known variant. For example, if the SDK is on an older + * version than the API, then the API may respond with new variants that the SDK is + * unaware of. + * + * @throws CourierInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw CourierInvalidDataException("Unknown Step: $json") + } + } + + internal class Deserializer : BaseDeserializer(Step::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): Step { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef())?.let { + Step(automationDelay = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + Step(automationSend = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef()) + ?.let { Step(automationSendList = it, _json = json) }, + tryDeserialize(node, jacksonTypeRef()) + ?.let { Step(automationUpdateProfile = it, _json = json) }, + tryDeserialize(node, jacksonTypeRef())?.let { + Step(automationCancel = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef()) + ?.let { Step(automationFetchData = it, _json = json) }, + tryDeserialize(node, jacksonTypeRef())?.let { + Step(automationInvoke = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible + // with all the possible variants (e.g. deserializing from boolean). + 0 -> Step(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the + // first completely valid match, or simply the first match if none are + // completely valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : BaseSerializer(Step::class) { + + override fun serialize( + value: Step, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.automationDelay != null -> + generator.writeObject(value.automationDelay) + value.automationSend != null -> generator.writeObject(value.automationSend) + value.automationSendList != null -> + generator.writeObject(value.automationSendList) + value.automationUpdateProfile != null -> + generator.writeObject(value.automationUpdateProfile) + value.automationCancel != null -> + generator.writeObject(value.automationCancel) + value.automationFetchData != null -> + generator.writeObject(value.automationFetchData) + value.automationInvoke != null -> + generator.writeObject(value.automationInvoke) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid Step") + } + } + } + + class AutomationDelayStep + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val action: JsonField, + private val duration: JsonField, + private val until: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("action") + @ExcludeMissing + action: JsonField = JsonMissing.of(), + @JsonProperty("duration") + @ExcludeMissing + duration: JsonField = JsonMissing.of(), + @JsonProperty("until") + @ExcludeMissing + until: JsonField = JsonMissing.of(), + ) : this(action, duration, until, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 action(): Action = action.getRequired("action") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun duration(): Optional = duration.getOptional("duration") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun until(): Optional = until.getOptional("until") + + /** + * Returns the raw JSON value of [action]. + * + * Unlike [action], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("action") @ExcludeMissing fun _action(): JsonField = action + + /** + * Returns the raw JSON value of [duration]. + * + * Unlike [duration], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("duration") + @ExcludeMissing + fun _duration(): JsonField = duration + + /** + * Returns the raw JSON value of [until]. + * + * Unlike [until], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("until") @ExcludeMissing fun _until(): JsonField = until + + @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 + * [AutomationDelayStep]. + * + * The following fields are required: + * ```java + * .action() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AutomationDelayStep]. */ + class Builder internal constructor() { + + private var action: JsonField? = null + private var duration: JsonField = JsonMissing.of() + private var until: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(automationDelayStep: AutomationDelayStep) = apply { + action = automationDelayStep.action + duration = automationDelayStep.duration + until = automationDelayStep.until + additionalProperties = + automationDelayStep.additionalProperties.toMutableMap() + } + + fun action(action: Action) = action(JsonField.of(action)) + + /** + * Sets [Builder.action] to an arbitrary JSON value. + * + * You should usually call [Builder.action] with a well-typed [Action] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun action(action: JsonField) = apply { this.action = action } + + fun duration(duration: String?) = duration(JsonField.ofNullable(duration)) + + /** Alias for calling [Builder.duration] with `duration.orElse(null)`. */ + fun duration(duration: Optional) = duration(duration.getOrNull()) + + /** + * Sets [Builder.duration] to an arbitrary JSON value. + * + * You should usually call [Builder.duration] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun duration(duration: JsonField) = apply { this.duration = duration } + + fun until(until: String?) = until(JsonField.ofNullable(until)) + + /** Alias for calling [Builder.until] with `until.orElse(null)`. */ + fun until(until: Optional) = until(until.getOrNull()) + + /** + * Sets [Builder.until] to an arbitrary JSON value. + * + * You should usually call [Builder.until] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun until(until: JsonField) = apply { this.until = until } + + 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 [AutomationDelayStep]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .action() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): AutomationDelayStep = + AutomationDelayStep( + checkRequired("action", action), + duration, + until, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): AutomationDelayStep = apply { + if (validated) { + return@apply + } + + action().validate() + duration() + until() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (action.asKnown().getOrNull()?.validity() ?: 0) + + (if (duration.asKnown().isPresent) 1 else 0) + + (if (until.asKnown().isPresent) 1 else 0) + + class Action + @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 DELAY = of("delay") + + @JvmStatic fun of(value: String) = Action(JsonField.of(value)) + } + + /** An enum containing [Action]'s known values. */ + enum class Known { + DELAY + } + + /** + * An enum containing [Action]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Action] 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 { + DELAY, + /** + * An enum member indicating that [Action] 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) { + DELAY -> Value.DELAY + 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 CourierInvalidDataException if this class instance's value is a not a + * known member. + */ + fun known(): Known = + when (this) { + DELAY -> Known.DELAY + else -> throw CourierInvalidDataException("Unknown Action: $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 CourierInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CourierInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): Action = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Action && 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 AutomationDelayStep && + action == other.action && + duration == other.duration && + until == other.until && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(action, duration, until, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AutomationDelayStep{action=$action, duration=$duration, until=$until, additionalProperties=$additionalProperties}" + } + + class AutomationSendStep + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val action: JsonField, + private val brand: JsonField, + private val data: JsonField, + private val profile: JsonField, + private val recipient: JsonField, + private val template: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("action") + @ExcludeMissing + action: JsonField = JsonMissing.of(), + @JsonProperty("brand") + @ExcludeMissing + brand: JsonField = JsonMissing.of(), + @JsonProperty("data") @ExcludeMissing data: JsonField = JsonMissing.of(), + @JsonProperty("profile") + @ExcludeMissing + profile: JsonField = JsonMissing.of(), + @JsonProperty("recipient") + @ExcludeMissing + recipient: JsonField = JsonMissing.of(), + @JsonProperty("template") + @ExcludeMissing + template: JsonField = JsonMissing.of(), + ) : this(action, brand, data, profile, recipient, template, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 action(): Action = action.getRequired("action") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun brand(): Optional = brand.getOptional("brand") + + /** + * @throws CourierInvalidDataException 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 CourierInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun profile(): Optional = profile.getOptional("profile") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun recipient(): Optional = recipient.getOptional("recipient") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun template(): Optional = template.getOptional("template") + + /** + * Returns the raw JSON value of [action]. + * + * Unlike [action], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("action") @ExcludeMissing fun _action(): JsonField = action + + /** + * Returns the raw JSON value of [brand]. + * + * Unlike [brand], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("brand") @ExcludeMissing fun _brand(): JsonField = brand + + /** + * 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 [profile]. + * + * Unlike [profile], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("profile") + @ExcludeMissing + fun _profile(): JsonField = profile + + /** + * Returns the raw JSON value of [recipient]. + * + * Unlike [recipient], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("recipient") + @ExcludeMissing + fun _recipient(): JsonField = recipient + + /** + * Returns the raw JSON value of [template]. + * + * Unlike [template], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("template") + @ExcludeMissing + fun _template(): JsonField = template + + @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 + * [AutomationSendStep]. + * + * The following fields are required: + * ```java + * .action() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AutomationSendStep]. */ + class Builder internal constructor() { + + private var action: JsonField? = null + private var brand: JsonField = JsonMissing.of() + private var data: JsonField = JsonMissing.of() + private var profile: JsonField = JsonMissing.of() + private var recipient: JsonField = JsonMissing.of() + private var template: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(automationSendStep: AutomationSendStep) = apply { + action = automationSendStep.action + brand = automationSendStep.brand + data = automationSendStep.data + profile = automationSendStep.profile + recipient = automationSendStep.recipient + template = automationSendStep.template + additionalProperties = + automationSendStep.additionalProperties.toMutableMap() + } + + fun action(action: Action) = action(JsonField.of(action)) + + /** + * Sets [Builder.action] to an arbitrary JSON value. + * + * You should usually call [Builder.action] with a well-typed [Action] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun action(action: JsonField) = apply { this.action = action } + + fun brand(brand: String?) = brand(JsonField.ofNullable(brand)) + + /** Alias for calling [Builder.brand] with `brand.orElse(null)`. */ + fun brand(brand: Optional) = brand(brand.getOrNull()) + + /** + * Sets [Builder.brand] to an arbitrary JSON value. + * + * You should usually call [Builder.brand] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun brand(brand: JsonField) = apply { this.brand = brand } + + fun data(data: Data?) = data(JsonField.ofNullable(data)) + + /** Alias for calling [Builder.data] with `data.orElse(null)`. */ + fun data(data: Optional) = data(data.getOrNull()) + + /** + * 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 profile(profile: Profile?) = profile(JsonField.ofNullable(profile)) + + /** Alias for calling [Builder.profile] with `profile.orElse(null)`. */ + fun profile(profile: Optional) = profile(profile.getOrNull()) + + /** + * Sets [Builder.profile] to an arbitrary JSON value. + * + * You should usually call [Builder.profile] with a well-typed [Profile] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun profile(profile: JsonField) = apply { this.profile = profile } + + fun recipient(recipient: String?) = recipient(JsonField.ofNullable(recipient)) + + /** Alias for calling [Builder.recipient] with `recipient.orElse(null)`. */ + fun recipient(recipient: Optional) = recipient(recipient.getOrNull()) + + /** + * Sets [Builder.recipient] to an arbitrary JSON value. + * + * You should usually call [Builder.recipient] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun recipient(recipient: JsonField) = apply { + this.recipient = recipient + } + + fun template(template: String?) = template(JsonField.ofNullable(template)) + + /** Alias for calling [Builder.template] with `template.orElse(null)`. */ + fun template(template: Optional) = template(template.getOrNull()) + + /** + * Sets [Builder.template] to an arbitrary JSON value. + * + * You should usually call [Builder.template] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun template(template: JsonField) = apply { this.template = template } + + 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 [AutomationSendStep]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .action() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): AutomationSendStep = + AutomationSendStep( + checkRequired("action", action), + brand, + data, + profile, + recipient, + template, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): AutomationSendStep = apply { + if (validated) { + return@apply + } + + action().validate() + brand() + data().ifPresent { it.validate() } + profile().ifPresent { it.validate() } + recipient() + template() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (action.asKnown().getOrNull()?.validity() ?: 0) + + (if (brand.asKnown().isPresent) 1 else 0) + + (data.asKnown().getOrNull()?.validity() ?: 0) + + (profile.asKnown().getOrNull()?.validity() ?: 0) + + (if (recipient.asKnown().isPresent) 1 else 0) + + (if (template.asKnown().isPresent) 1 else 0) + + class Action + @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 SEND = of("send") + + @JvmStatic fun of(value: String) = Action(JsonField.of(value)) + } + + /** An enum containing [Action]'s known values. */ + enum class Known { + SEND + } + + /** + * An enum containing [Action]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Action] 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 { + SEND, + /** + * An enum member indicating that [Action] 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) { + SEND -> Value.SEND + 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 CourierInvalidDataException if this class instance's value is a not a + * known member. + */ + fun known(): Known = + when (this) { + SEND -> Known.SEND + else -> throw CourierInvalidDataException("Unknown Action: $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 CourierInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CourierInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): Action = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Action && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + class Data + @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 [Data]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Data]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = + mutableMapOf() + + @JvmSynthetic + internal fun from(data: Data) = apply { + additionalProperties = data.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 [Data]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Data = Data(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): Data = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Data && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Data{additionalProperties=$additionalProperties}" + } + + class Profile + @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 [Profile]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Profile]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = + mutableMapOf() + + @JvmSynthetic + internal fun from(profile: Profile) = apply { + additionalProperties = profile.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 [Profile]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Profile = Profile(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): Profile = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Profile && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Profile{additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AutomationSendStep && + action == other.action && + brand == other.brand && + data == other.data && + profile == other.profile && + recipient == other.recipient && + template == other.template && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + action, + brand, + data, + profile, + recipient, + template, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AutomationSendStep{action=$action, brand=$brand, data=$data, profile=$profile, recipient=$recipient, template=$template, additionalProperties=$additionalProperties}" + } + + class AutomationSendListStep + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val action: JsonField, + private val list: JsonField, + private val brand: JsonField, + private val data: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("action") + @ExcludeMissing + action: JsonField = JsonMissing.of(), + @JsonProperty("list") + @ExcludeMissing + list: JsonField = JsonMissing.of(), + @JsonProperty("brand") + @ExcludeMissing + brand: JsonField = JsonMissing.of(), + @JsonProperty("data") @ExcludeMissing data: JsonField = JsonMissing.of(), + ) : this(action, list, brand, data, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 action(): Action = action.getRequired("action") + + /** + * @throws CourierInvalidDataException 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 list(): String = list.getRequired("list") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun brand(): Optional = brand.getOptional("brand") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun data(): Optional = data.getOptional("data") + + /** + * Returns the raw JSON value of [action]. + * + * Unlike [action], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("action") @ExcludeMissing fun _action(): JsonField = action + + /** + * Returns the raw JSON value of [list]. + * + * Unlike [list], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("list") @ExcludeMissing fun _list(): JsonField = list + + /** + * Returns the raw JSON value of [brand]. + * + * Unlike [brand], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("brand") @ExcludeMissing fun _brand(): JsonField = brand + + /** + * 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 + + @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 + * [AutomationSendListStep]. + * + * The following fields are required: + * ```java + * .action() + * .list() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AutomationSendListStep]. */ + class Builder internal constructor() { + + private var action: JsonField? = null + private var list: JsonField? = null + private var brand: JsonField = JsonMissing.of() + private var data: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(automationSendListStep: AutomationSendListStep) = apply { + action = automationSendListStep.action + list = automationSendListStep.list + brand = automationSendListStep.brand + data = automationSendListStep.data + additionalProperties = + automationSendListStep.additionalProperties.toMutableMap() + } + + fun action(action: Action) = action(JsonField.of(action)) + + /** + * Sets [Builder.action] to an arbitrary JSON value. + * + * You should usually call [Builder.action] with a well-typed [Action] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun action(action: JsonField) = apply { this.action = action } + + fun list(list: String) = list(JsonField.of(list)) + + /** + * Sets [Builder.list] to an arbitrary JSON value. + * + * You should usually call [Builder.list] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun list(list: JsonField) = apply { this.list = list } + + fun brand(brand: String?) = brand(JsonField.ofNullable(brand)) + + /** Alias for calling [Builder.brand] with `brand.orElse(null)`. */ + fun brand(brand: Optional) = brand(brand.getOrNull()) + + /** + * Sets [Builder.brand] to an arbitrary JSON value. + * + * You should usually call [Builder.brand] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun brand(brand: JsonField) = apply { this.brand = brand } + + fun data(data: Data?) = data(JsonField.ofNullable(data)) + + /** Alias for calling [Builder.data] with `data.orElse(null)`. */ + fun data(data: Optional) = data(data.getOrNull()) + + /** + * 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 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 [AutomationSendListStep]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .action() + * .list() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): AutomationSendListStep = + AutomationSendListStep( + checkRequired("action", action), + checkRequired("list", list), + brand, + data, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): AutomationSendListStep = apply { + if (validated) { + return@apply + } + + action().validate() + list() + brand() + data().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (action.asKnown().getOrNull()?.validity() ?: 0) + + (if (list.asKnown().isPresent) 1 else 0) + + (if (brand.asKnown().isPresent) 1 else 0) + + (data.asKnown().getOrNull()?.validity() ?: 0) + + class Action + @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 SEND_LIST = of("send-list") + + @JvmStatic fun of(value: String) = Action(JsonField.of(value)) + } + + /** An enum containing [Action]'s known values. */ + enum class Known { + SEND_LIST + } + + /** + * An enum containing [Action]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Action] 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 { + SEND_LIST, + /** + * An enum member indicating that [Action] 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) { + SEND_LIST -> Value.SEND_LIST + 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 CourierInvalidDataException if this class instance's value is a not a + * known member. + */ + fun known(): Known = + when (this) { + SEND_LIST -> Known.SEND_LIST + else -> throw CourierInvalidDataException("Unknown Action: $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 CourierInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CourierInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): Action = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Action && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + class Data + @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 [Data]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Data]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = + mutableMapOf() + + @JvmSynthetic + internal fun from(data: Data) = apply { + additionalProperties = data.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 [Data]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Data = Data(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): Data = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Data && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Data{additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AutomationSendListStep && + action == other.action && + list == other.list && + brand == other.brand && + data == other.data && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(action, list, brand, data, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AutomationSendListStep{action=$action, list=$list, brand=$brand, data=$data, additionalProperties=$additionalProperties}" + } + + class AutomationUpdateProfileStep + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val action: JsonField, + private val profile: JsonField, + private val merge: JsonField, + private val recipientId: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("action") + @ExcludeMissing + action: JsonField = JsonMissing.of(), + @JsonProperty("profile") + @ExcludeMissing + profile: JsonField = JsonMissing.of(), + @JsonProperty("merge") + @ExcludeMissing + merge: JsonField = JsonMissing.of(), + @JsonProperty("recipient_id") + @ExcludeMissing + recipientId: JsonField = JsonMissing.of(), + ) : this(action, profile, merge, recipientId, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 action(): Action = action.getRequired("action") + + /** + * @throws CourierInvalidDataException 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 profile(): Profile = profile.getRequired("profile") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun merge(): Optional = merge.getOptional("merge") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun recipientId(): Optional = recipientId.getOptional("recipient_id") + + /** + * Returns the raw JSON value of [action]. + * + * Unlike [action], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("action") @ExcludeMissing fun _action(): JsonField = action + + /** + * Returns the raw JSON value of [profile]. + * + * Unlike [profile], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("profile") + @ExcludeMissing + fun _profile(): JsonField = profile + + /** + * Returns the raw JSON value of [merge]. + * + * Unlike [merge], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("merge") @ExcludeMissing fun _merge(): JsonField = merge + + /** + * Returns the raw JSON value of [recipientId]. + * + * Unlike [recipientId], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("recipient_id") + @ExcludeMissing + fun _recipientId(): JsonField = recipientId + + @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 + * [AutomationUpdateProfileStep]. + * + * The following fields are required: + * ```java + * .action() + * .profile() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AutomationUpdateProfileStep]. */ + class Builder internal constructor() { + + private var action: JsonField? = null + private var profile: JsonField? = null + private var merge: JsonField = JsonMissing.of() + private var recipientId: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(automationUpdateProfileStep: AutomationUpdateProfileStep) = + apply { + action = automationUpdateProfileStep.action + profile = automationUpdateProfileStep.profile + merge = automationUpdateProfileStep.merge + recipientId = automationUpdateProfileStep.recipientId + additionalProperties = + automationUpdateProfileStep.additionalProperties.toMutableMap() + } + + fun action(action: Action) = action(JsonField.of(action)) + + /** + * Sets [Builder.action] to an arbitrary JSON value. + * + * You should usually call [Builder.action] with a well-typed [Action] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun action(action: JsonField) = apply { this.action = action } + + fun profile(profile: Profile) = profile(JsonField.of(profile)) + + /** + * Sets [Builder.profile] to an arbitrary JSON value. + * + * You should usually call [Builder.profile] with a well-typed [Profile] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun profile(profile: JsonField) = apply { this.profile = profile } + + fun merge(merge: Merge?) = merge(JsonField.ofNullable(merge)) + + /** Alias for calling [Builder.merge] with `merge.orElse(null)`. */ + fun merge(merge: Optional) = merge(merge.getOrNull()) + + /** + * Sets [Builder.merge] to an arbitrary JSON value. + * + * You should usually call [Builder.merge] with a well-typed [Merge] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun merge(merge: JsonField) = apply { this.merge = merge } + + fun recipientId(recipientId: String?) = + recipientId(JsonField.ofNullable(recipientId)) + + /** Alias for calling [Builder.recipientId] with `recipientId.orElse(null)`. */ + fun recipientId(recipientId: Optional) = + recipientId(recipientId.getOrNull()) + + /** + * Sets [Builder.recipientId] to an arbitrary JSON value. + * + * You should usually call [Builder.recipientId] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun recipientId(recipientId: JsonField) = apply { + this.recipientId = recipientId + } + + 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 [AutomationUpdateProfileStep]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .action() + * .profile() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): AutomationUpdateProfileStep = + AutomationUpdateProfileStep( + checkRequired("action", action), + checkRequired("profile", profile), + merge, + recipientId, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): AutomationUpdateProfileStep = apply { + if (validated) { + return@apply + } + + action().validate() + profile().validate() + merge().ifPresent { it.validate() } + recipientId() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (action.asKnown().getOrNull()?.validity() ?: 0) + + (profile.asKnown().getOrNull()?.validity() ?: 0) + + (merge.asKnown().getOrNull()?.validity() ?: 0) + + (if (recipientId.asKnown().isPresent) 1 else 0) + + class Action + @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 UPDATE_PROFILE = of("update-profile") + + @JvmStatic fun of(value: String) = Action(JsonField.of(value)) + } + + /** An enum containing [Action]'s known values. */ + enum class Known { + UPDATE_PROFILE + } + + /** + * An enum containing [Action]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Action] 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 { + UPDATE_PROFILE, + /** + * An enum member indicating that [Action] 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) { + UPDATE_PROFILE -> Value.UPDATE_PROFILE + 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 CourierInvalidDataException if this class instance's value is a not a + * known member. + */ + fun known(): Known = + when (this) { + UPDATE_PROFILE -> Known.UPDATE_PROFILE + else -> throw CourierInvalidDataException("Unknown Action: $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 CourierInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CourierInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): Action = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Action && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + class Profile + @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 [Profile]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Profile]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = + mutableMapOf() + + @JvmSynthetic + internal fun from(profile: Profile) = apply { + additionalProperties = profile.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 [Profile]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Profile = Profile(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): Profile = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Profile && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Profile{additionalProperties=$additionalProperties}" + } + + class Merge @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 NONE = of("none") + + @JvmField val OVERWRITE = of("overwrite") + + @JvmField val SOFT_MERGE = of("soft-merge") + + @JvmField val REPLACE = of("replace") + + @JvmStatic fun of(value: String) = Merge(JsonField.of(value)) + } + + /** An enum containing [Merge]'s known values. */ + enum class Known { + NONE, + OVERWRITE, + SOFT_MERGE, + REPLACE, + } + + /** + * An enum containing [Merge]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Merge] 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 { + NONE, + OVERWRITE, + SOFT_MERGE, + REPLACE, + /** + * An enum member indicating that [Merge] 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) { + NONE -> Value.NONE + OVERWRITE -> Value.OVERWRITE + SOFT_MERGE -> Value.SOFT_MERGE + REPLACE -> Value.REPLACE + 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 CourierInvalidDataException if this class instance's value is a not a + * known member. + */ + fun known(): Known = + when (this) { + NONE -> Known.NONE + OVERWRITE -> Known.OVERWRITE + SOFT_MERGE -> Known.SOFT_MERGE + REPLACE -> Known.REPLACE + else -> throw CourierInvalidDataException("Unknown Merge: $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 CourierInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CourierInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): Merge = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Merge && 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 AutomationUpdateProfileStep && + action == other.action && + profile == other.profile && + merge == other.merge && + recipientId == other.recipientId && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(action, profile, merge, recipientId, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AutomationUpdateProfileStep{action=$action, profile=$profile, merge=$merge, recipientId=$recipientId, additionalProperties=$additionalProperties}" + } + + class AutomationCancelStep + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val action: JsonField, + private val cancelationToken: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("action") + @ExcludeMissing + action: JsonField = JsonMissing.of(), + @JsonProperty("cancelation_token") + @ExcludeMissing + cancelationToken: JsonField = JsonMissing.of(), + ) : this(action, cancelationToken, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 action(): Action = action.getRequired("action") + + /** + * @throws CourierInvalidDataException 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 cancelationToken(): String = cancelationToken.getRequired("cancelation_token") + + /** + * Returns the raw JSON value of [action]. + * + * Unlike [action], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("action") @ExcludeMissing fun _action(): JsonField = action + + /** + * Returns the raw JSON value of [cancelationToken]. + * + * Unlike [cancelationToken], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("cancelation_token") + @ExcludeMissing + fun _cancelationToken(): JsonField = cancelationToken + + @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 + * [AutomationCancelStep]. + * + * The following fields are required: + * ```java + * .action() + * .cancelationToken() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AutomationCancelStep]. */ + class Builder internal constructor() { + + private var action: JsonField? = null + private var cancelationToken: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(automationCancelStep: AutomationCancelStep) = apply { + action = automationCancelStep.action + cancelationToken = automationCancelStep.cancelationToken + additionalProperties = + automationCancelStep.additionalProperties.toMutableMap() + } + + fun action(action: Action) = action(JsonField.of(action)) + + /** + * Sets [Builder.action] to an arbitrary JSON value. + * + * You should usually call [Builder.action] with a well-typed [Action] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun action(action: JsonField) = apply { this.action = action } + + fun cancelationToken(cancelationToken: String) = + cancelationToken(JsonField.of(cancelationToken)) + + /** + * Sets [Builder.cancelationToken] to an arbitrary JSON value. + * + * You should usually call [Builder.cancelationToken] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun cancelationToken(cancelationToken: JsonField) = apply { + this.cancelationToken = cancelationToken + } + + 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 [AutomationCancelStep]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .action() + * .cancelationToken() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): AutomationCancelStep = + AutomationCancelStep( + checkRequired("action", action), + checkRequired("cancelationToken", cancelationToken), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): AutomationCancelStep = apply { + if (validated) { + return@apply + } + + action().validate() + cancelationToken() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (action.asKnown().getOrNull()?.validity() ?: 0) + + (if (cancelationToken.asKnown().isPresent) 1 else 0) + + class Action + @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 CANCEL = of("cancel") + + @JvmStatic fun of(value: String) = Action(JsonField.of(value)) + } + + /** An enum containing [Action]'s known values. */ + enum class Known { + CANCEL + } + + /** + * An enum containing [Action]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Action] 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 { + CANCEL, + /** + * An enum member indicating that [Action] 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) { + CANCEL -> Value.CANCEL + 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 CourierInvalidDataException if this class instance's value is a not a + * known member. + */ + fun known(): Known = + when (this) { + CANCEL -> Known.CANCEL + else -> throw CourierInvalidDataException("Unknown Action: $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 CourierInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CourierInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): Action = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Action && 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 AutomationCancelStep && + action == other.action && + cancelationToken == other.cancelationToken && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(action, cancelationToken, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AutomationCancelStep{action=$action, cancelationToken=$cancelationToken, additionalProperties=$additionalProperties}" + } + + class AutomationFetchDataStep + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val action: JsonField, + private val webhook: JsonField, + private val mergeStrategy: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("action") + @ExcludeMissing + action: JsonField = JsonMissing.of(), + @JsonProperty("webhook") + @ExcludeMissing + webhook: JsonField = JsonMissing.of(), + @JsonProperty("merge_strategy") + @ExcludeMissing + mergeStrategy: JsonField = JsonMissing.of(), + ) : this(action, webhook, mergeStrategy, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 action(): Action = action.getRequired("action") + + /** + * @throws CourierInvalidDataException 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 webhook(): Webhook = webhook.getRequired("webhook") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun mergeStrategy(): Optional = + mergeStrategy.getOptional("merge_strategy") + + /** + * Returns the raw JSON value of [action]. + * + * Unlike [action], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("action") @ExcludeMissing fun _action(): JsonField = action + + /** + * Returns the raw JSON value of [webhook]. + * + * Unlike [webhook], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("webhook") + @ExcludeMissing + fun _webhook(): JsonField = webhook + + /** + * Returns the raw JSON value of [mergeStrategy]. + * + * Unlike [mergeStrategy], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("merge_strategy") + @ExcludeMissing + fun _mergeStrategy(): JsonField = mergeStrategy + + @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 + * [AutomationFetchDataStep]. + * + * The following fields are required: + * ```java + * .action() + * .webhook() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AutomationFetchDataStep]. */ + class Builder internal constructor() { + + private var action: JsonField? = null + private var webhook: JsonField? = null + private var mergeStrategy: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(automationFetchDataStep: AutomationFetchDataStep) = apply { + action = automationFetchDataStep.action + webhook = automationFetchDataStep.webhook + mergeStrategy = automationFetchDataStep.mergeStrategy + additionalProperties = + automationFetchDataStep.additionalProperties.toMutableMap() + } + + fun action(action: Action) = action(JsonField.of(action)) + + /** + * Sets [Builder.action] to an arbitrary JSON value. + * + * You should usually call [Builder.action] with a well-typed [Action] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun action(action: JsonField) = apply { this.action = action } + + fun webhook(webhook: Webhook) = webhook(JsonField.of(webhook)) + + /** + * Sets [Builder.webhook] to an arbitrary JSON value. + * + * You should usually call [Builder.webhook] with a well-typed [Webhook] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun webhook(webhook: JsonField) = apply { this.webhook = webhook } + + fun mergeStrategy(mergeStrategy: MergeStrategy?) = + mergeStrategy(JsonField.ofNullable(mergeStrategy)) + + /** + * Alias for calling [Builder.mergeStrategy] with `mergeStrategy.orElse(null)`. + */ + fun mergeStrategy(mergeStrategy: Optional) = + mergeStrategy(mergeStrategy.getOrNull()) + + /** + * Sets [Builder.mergeStrategy] to an arbitrary JSON value. + * + * You should usually call [Builder.mergeStrategy] with a well-typed + * [MergeStrategy] value instead. This method is primarily for setting the field + * to an undocumented or not yet supported value. + */ + fun mergeStrategy(mergeStrategy: JsonField) = apply { + this.mergeStrategy = mergeStrategy + } + + 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 [AutomationFetchDataStep]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .action() + * .webhook() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): AutomationFetchDataStep = + AutomationFetchDataStep( + checkRequired("action", action), + checkRequired("webhook", webhook), + mergeStrategy, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): AutomationFetchDataStep = apply { + if (validated) { + return@apply + } + + action().validate() + webhook().validate() + mergeStrategy().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (action.asKnown().getOrNull()?.validity() ?: 0) + + (webhook.asKnown().getOrNull()?.validity() ?: 0) + + (mergeStrategy.asKnown().getOrNull()?.validity() ?: 0) + + class Action + @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 FETCH_DATA = of("fetch-data") + + @JvmStatic fun of(value: String) = Action(JsonField.of(value)) + } + + /** An enum containing [Action]'s known values. */ + enum class Known { + FETCH_DATA + } + + /** + * An enum containing [Action]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Action] 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 { + FETCH_DATA, + /** + * An enum member indicating that [Action] 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) { + FETCH_DATA -> Value.FETCH_DATA + 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 CourierInvalidDataException if this class instance's value is a not a + * known member. + */ + fun known(): Known = + when (this) { + FETCH_DATA -> Known.FETCH_DATA + else -> throw CourierInvalidDataException("Unknown Action: $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 CourierInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CourierInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): Action = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Action && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + class Webhook + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val method: JsonField, + private val url: JsonField, + private val body: JsonField, + private val headers: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("method") + @ExcludeMissing + method: JsonField = JsonMissing.of(), + @JsonProperty("url") + @ExcludeMissing + url: JsonField = JsonMissing.of(), + @JsonProperty("body") + @ExcludeMissing + body: JsonField = JsonMissing.of(), + @JsonProperty("headers") + @ExcludeMissing + headers: JsonField = JsonMissing.of(), + ) : this(method, url, body, headers, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 method(): Method = method.getRequired("method") + + /** + * @throws CourierInvalidDataException 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 url(): String = url.getRequired("url") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun body(): Optional = body.getOptional("body") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun headers(): Optional = headers.getOptional("headers") + + /** + * Returns the raw JSON value of [method]. + * + * Unlike [method], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("method") + @ExcludeMissing + fun _method(): JsonField = method + + /** + * 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 + + /** + * Returns the raw JSON value of [body]. + * + * Unlike [body], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("body") @ExcludeMissing fun _body(): JsonField = body + + /** + * Returns the raw JSON value of [headers]. + * + * Unlike [headers], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("headers") + @ExcludeMissing + fun _headers(): JsonField = headers + + @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 [Webhook]. + * + * The following fields are required: + * ```java + * .method() + * .url() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Webhook]. */ + class Builder internal constructor() { + + private var method: JsonField? = null + private var url: JsonField? = null + private var body: JsonField = JsonMissing.of() + private var headers: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = + mutableMapOf() + + @JvmSynthetic + internal fun from(webhook: Webhook) = apply { + method = webhook.method + url = webhook.url + body = webhook.body + headers = webhook.headers + additionalProperties = webhook.additionalProperties.toMutableMap() + } + + fun method(method: Method) = method(JsonField.of(method)) + + /** + * Sets [Builder.method] to an arbitrary JSON value. + * + * You should usually call [Builder.method] with a well-typed [Method] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun method(method: JsonField) = apply { this.method = method } + + 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 body(body: String?) = body(JsonField.ofNullable(body)) + + /** Alias for calling [Builder.body] with `body.orElse(null)`. */ + fun body(body: Optional) = body(body.getOrNull()) + + /** + * Sets [Builder.body] to an arbitrary JSON value. + * + * You should usually call [Builder.body] with a well-typed [String] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun body(body: JsonField) = apply { this.body = body } + + fun headers(headers: Headers?) = headers(JsonField.ofNullable(headers)) + + /** Alias for calling [Builder.headers] with `headers.orElse(null)`. */ + fun headers(headers: Optional) = headers(headers.getOrNull()) + + /** + * Sets [Builder.headers] to an arbitrary JSON value. + * + * You should usually call [Builder.headers] with a well-typed [Headers] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun headers(headers: JsonField) = apply { this.headers = headers } + + 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 [Webhook]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .method() + * .url() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Webhook = + Webhook( + checkRequired("method", method), + checkRequired("url", url), + body, + headers, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Webhook = apply { + if (validated) { + return@apply + } + + method().validate() + url() + body() + headers().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (method.asKnown().getOrNull()?.validity() ?: 0) + + (if (url.asKnown().isPresent) 1 else 0) + + (if (body.asKnown().isPresent) 1 else 0) + + (headers.asKnown().getOrNull()?.validity() ?: 0) + + class Method + @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 GET = of("GET") + + @JvmField val POST = of("POST") + + @JvmField val PUT = of("PUT") + + @JvmField val PATCH = of("PATCH") + + @JvmField val DELETE = of("DELETE") + + @JvmStatic fun of(value: String) = Method(JsonField.of(value)) + } + + /** An enum containing [Method]'s known values. */ + enum class Known { + GET, + POST, + PUT, + PATCH, + DELETE, + } + + /** + * An enum containing [Method]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [Method] 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 { + GET, + POST, + PUT, + PATCH, + DELETE, + /** + * An enum member indicating that [Method] 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) { + GET -> Value.GET + POST -> Value.POST + PUT -> Value.PUT + PATCH -> Value.PATCH + DELETE -> Value.DELETE + 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 CourierInvalidDataException if this class instance's value is a + * not a known member. + */ + fun known(): Known = + when (this) { + GET -> Known.GET + POST -> Known.POST + PUT -> Known.PUT + PATCH -> Known.PATCH + DELETE -> Known.DELETE + else -> throw CourierInvalidDataException("Unknown Method: $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 CourierInvalidDataException if this class instance's value does + * not have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CourierInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): Method = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Method && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + class Headers + @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 [Headers]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Headers]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = + mutableMapOf() + + @JvmSynthetic + internal fun from(headers: Headers) = apply { + additionalProperties = headers.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 [Headers]. + * + * Further updates to this [Builder] will not mutate the returned + * instance. + */ + fun build(): Headers = Headers(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): Headers = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Headers && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Headers{additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Webhook && + method == other.method && + url == other.url && + body == other.body && + headers == other.headers && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(method, url, body, headers, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Webhook{method=$method, url=$url, body=$body, headers=$headers, additionalProperties=$additionalProperties}" + } + + class MergeStrategy + @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 REPLACE = of("replace") + + @JvmField val OVERWRITE = of("overwrite") + + @JvmField val SOFT_MERGE = of("soft-merge") + + @JvmStatic fun of(value: String) = MergeStrategy(JsonField.of(value)) + } + + /** An enum containing [MergeStrategy]'s known values. */ + enum class Known { + REPLACE, + OVERWRITE, + SOFT_MERGE, + } + + /** + * An enum containing [MergeStrategy]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [MergeStrategy] 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 { + REPLACE, + OVERWRITE, + SOFT_MERGE, + /** + * An enum member indicating that [MergeStrategy] 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) { + REPLACE -> Value.REPLACE + OVERWRITE -> Value.OVERWRITE + SOFT_MERGE -> Value.SOFT_MERGE + 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 CourierInvalidDataException if this class instance's value is a not a + * known member. + */ + fun known(): Known = + when (this) { + REPLACE -> Known.REPLACE + OVERWRITE -> Known.OVERWRITE + SOFT_MERGE -> Known.SOFT_MERGE + else -> + throw CourierInvalidDataException("Unknown MergeStrategy: $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 CourierInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CourierInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): MergeStrategy = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 MergeStrategy && 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 AutomationFetchDataStep && + action == other.action && + webhook == other.webhook && + mergeStrategy == other.mergeStrategy && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(action, webhook, mergeStrategy, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AutomationFetchDataStep{action=$action, webhook=$webhook, mergeStrategy=$mergeStrategy, additionalProperties=$additionalProperties}" + } + + class AutomationInvokeStep + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val action: JsonField, + private val template: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("action") + @ExcludeMissing + action: JsonField = JsonMissing.of(), + @JsonProperty("template") + @ExcludeMissing + template: JsonField = JsonMissing.of(), + ) : this(action, template, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 action(): Action = action.getRequired("action") + + /** + * @throws CourierInvalidDataException 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 template(): String = template.getRequired("template") + + /** + * Returns the raw JSON value of [action]. + * + * Unlike [action], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("action") @ExcludeMissing fun _action(): JsonField = action + + /** + * Returns the raw JSON value of [template]. + * + * Unlike [template], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("template") + @ExcludeMissing + fun _template(): JsonField = template + + @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 + * [AutomationInvokeStep]. + * + * The following fields are required: + * ```java + * .action() + * .template() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AutomationInvokeStep]. */ + class Builder internal constructor() { + + private var action: JsonField? = null + private var template: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(automationInvokeStep: AutomationInvokeStep) = apply { + action = automationInvokeStep.action + template = automationInvokeStep.template + additionalProperties = + automationInvokeStep.additionalProperties.toMutableMap() + } + + fun action(action: Action) = action(JsonField.of(action)) + + /** + * Sets [Builder.action] to an arbitrary JSON value. + * + * You should usually call [Builder.action] with a well-typed [Action] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun action(action: JsonField) = apply { this.action = action } + + fun template(template: String) = template(JsonField.of(template)) + + /** + * Sets [Builder.template] to an arbitrary JSON value. + * + * You should usually call [Builder.template] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun template(template: JsonField) = apply { this.template = template } + + 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 [AutomationInvokeStep]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .action() + * .template() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): AutomationInvokeStep = + AutomationInvokeStep( + checkRequired("action", action), + checkRequired("template", template), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): AutomationInvokeStep = apply { + if (validated) { + return@apply + } + + action().validate() + template() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (action.asKnown().getOrNull()?.validity() ?: 0) + + (if (template.asKnown().isPresent) 1 else 0) + + class Action + @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 INVOKE = of("invoke") + + @JvmStatic fun of(value: String) = Action(JsonField.of(value)) + } + + /** An enum containing [Action]'s known values. */ + enum class Known { + INVOKE + } + + /** + * An enum containing [Action]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Action] 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 { + INVOKE, + /** + * An enum member indicating that [Action] 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) { + INVOKE -> Value.INVOKE + 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 CourierInvalidDataException if this class instance's value is a not a + * known member. + */ + fun known(): Known = + when (this) { + INVOKE -> Known.INVOKE + else -> throw CourierInvalidDataException("Unknown Action: $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 CourierInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CourierInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): Action = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Action && 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 AutomationInvokeStep && + action == other.action && + template == other.template && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(action, template, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AutomationInvokeStep{action=$action, template=$template, additionalProperties=$additionalProperties}" + } + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Automation && + steps == other.steps && + cancelationToken == other.cancelationToken && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(steps, cancelationToken, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Automation{steps=$steps, cancelationToken=$cancelationToken, additionalProperties=$additionalProperties}" + } + + class Data + @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 [Data]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Data]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(data: Data) = apply { + additionalProperties = data.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 [Data]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Data = Data(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): Data = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Data && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Data{additionalProperties=$additionalProperties}" + } + + class Profile + @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 [Profile]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Profile]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(profile: Profile) = apply { + additionalProperties = profile.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 [Profile]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Profile = Profile(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): Profile = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Profile && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Profile{additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is InvokeInvokeAdHocParams && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = Objects.hash(body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "InvokeInvokeAdHocParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/automations/invoke/InvokeInvokeByTemplateParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/automations/invoke/InvokeInvokeByTemplateParams.kt new file mode 100644 index 00000000..8f6660c7 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/automations/invoke/InvokeInvokeByTemplateParams.kt @@ -0,0 +1,894 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.automations.invoke + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.Params +import com.courier.api.core.checkRequired +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import com.courier.api.core.toImmutable +import com.courier.api.errors.CourierInvalidDataException +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 + +/** Invoke an automation run from an automation template. */ +class InvokeInvokeByTemplateParams +private constructor( + private val templateId: String?, + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun templateId(): Optional = Optional.ofNullable(templateId) + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun recipient(): Optional = body.recipient() + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun brand(): Optional = body.brand() + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun data(): Optional = body.data() + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun profile(): Optional = body.profile() + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun template(): Optional = body.template() + + /** + * Returns the raw JSON value of [recipient]. + * + * Unlike [recipient], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _recipient(): JsonField = body._recipient() + + /** + * Returns the raw JSON value of [brand]. + * + * Unlike [brand], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _brand(): JsonField = body._brand() + + /** + * Returns the raw JSON value of [data]. + * + * Unlike [data], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _data(): JsonField = body._data() + + /** + * Returns the raw JSON value of [profile]. + * + * Unlike [profile], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _profile(): JsonField = body._profile() + + /** + * Returns the raw JSON value of [template]. + * + * Unlike [template], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _template(): JsonField = body._template() + + 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 [InvokeInvokeByTemplateParams]. + * + * The following fields are required: + * ```java + * .recipient() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [InvokeInvokeByTemplateParams]. */ + class Builder internal constructor() { + + private var templateId: 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(invokeInvokeByTemplateParams: InvokeInvokeByTemplateParams) = apply { + templateId = invokeInvokeByTemplateParams.templateId + body = invokeInvokeByTemplateParams.body.toBuilder() + additionalHeaders = invokeInvokeByTemplateParams.additionalHeaders.toBuilder() + additionalQueryParams = invokeInvokeByTemplateParams.additionalQueryParams.toBuilder() + } + + fun templateId(templateId: String?) = apply { this.templateId = templateId } + + /** Alias for calling [Builder.templateId] with `templateId.orElse(null)`. */ + fun templateId(templateId: Optional) = templateId(templateId.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: + * - [recipient] + * - [brand] + * - [data] + * - [profile] + * - [template] + * - etc. + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + fun recipient(recipient: String?) = apply { body.recipient(recipient) } + + /** Alias for calling [Builder.recipient] with `recipient.orElse(null)`. */ + fun recipient(recipient: Optional) = recipient(recipient.getOrNull()) + + /** + * Sets [Builder.recipient] to an arbitrary JSON value. + * + * You should usually call [Builder.recipient] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun recipient(recipient: JsonField) = apply { body.recipient(recipient) } + + fun brand(brand: String?) = apply { body.brand(brand) } + + /** Alias for calling [Builder.brand] with `brand.orElse(null)`. */ + fun brand(brand: Optional) = brand(brand.getOrNull()) + + /** + * Sets [Builder.brand] to an arbitrary JSON value. + * + * You should usually call [Builder.brand] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun brand(brand: JsonField) = apply { body.brand(brand) } + + fun data(data: Data?) = apply { body.data(data) } + + /** Alias for calling [Builder.data] with `data.orElse(null)`. */ + fun data(data: Optional) = data(data.getOrNull()) + + /** + * 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 { body.data(data) } + + fun profile(profile: Profile?) = apply { body.profile(profile) } + + /** Alias for calling [Builder.profile] with `profile.orElse(null)`. */ + fun profile(profile: Optional) = profile(profile.getOrNull()) + + /** + * Sets [Builder.profile] to an arbitrary JSON value. + * + * You should usually call [Builder.profile] with a well-typed [Profile] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun profile(profile: JsonField) = apply { body.profile(profile) } + + fun template(template: String?) = apply { body.template(template) } + + /** Alias for calling [Builder.template] with `template.orElse(null)`. */ + fun template(template: Optional) = template(template.getOrNull()) + + /** + * Sets [Builder.template] to an arbitrary JSON value. + * + * You should usually call [Builder.template] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun template(template: JsonField) = apply { body.template(template) } + + 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 [InvokeInvokeByTemplateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .recipient() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): InvokeInvokeByTemplateParams = + InvokeInvokeByTemplateParams( + templateId, + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): Body = body + + fun _pathParam(index: Int): String = + when (index) { + 0 -> templateId ?: "" + else -> "" + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + class Body + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val recipient: JsonField, + private val brand: JsonField, + private val data: JsonField, + private val profile: JsonField, + private val template: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("recipient") + @ExcludeMissing + recipient: JsonField = JsonMissing.of(), + @JsonProperty("brand") @ExcludeMissing brand: JsonField = JsonMissing.of(), + @JsonProperty("data") @ExcludeMissing data: JsonField = JsonMissing.of(), + @JsonProperty("profile") @ExcludeMissing profile: JsonField = JsonMissing.of(), + @JsonProperty("template") @ExcludeMissing template: JsonField = JsonMissing.of(), + ) : this(recipient, brand, data, profile, template, mutableMapOf()) + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun recipient(): Optional = recipient.getOptional("recipient") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun brand(): Optional = brand.getOptional("brand") + + /** + * @throws CourierInvalidDataException 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 CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun profile(): Optional = profile.getOptional("profile") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun template(): Optional = template.getOptional("template") + + /** + * Returns the raw JSON value of [recipient]. + * + * Unlike [recipient], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("recipient") @ExcludeMissing fun _recipient(): JsonField = recipient + + /** + * Returns the raw JSON value of [brand]. + * + * Unlike [brand], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("brand") @ExcludeMissing fun _brand(): JsonField = brand + + /** + * 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 [profile]. + * + * Unlike [profile], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("profile") @ExcludeMissing fun _profile(): JsonField = profile + + /** + * Returns the raw JSON value of [template]. + * + * Unlike [template], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("template") @ExcludeMissing fun _template(): JsonField = template + + @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 + * .recipient() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var recipient: JsonField? = null + private var brand: JsonField = JsonMissing.of() + private var data: JsonField = JsonMissing.of() + private var profile: JsonField = JsonMissing.of() + private var template: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + recipient = body.recipient + brand = body.brand + data = body.data + profile = body.profile + template = body.template + additionalProperties = body.additionalProperties.toMutableMap() + } + + fun recipient(recipient: String?) = recipient(JsonField.ofNullable(recipient)) + + /** Alias for calling [Builder.recipient] with `recipient.orElse(null)`. */ + fun recipient(recipient: Optional) = recipient(recipient.getOrNull()) + + /** + * Sets [Builder.recipient] to an arbitrary JSON value. + * + * You should usually call [Builder.recipient] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun recipient(recipient: JsonField) = apply { this.recipient = recipient } + + fun brand(brand: String?) = brand(JsonField.ofNullable(brand)) + + /** Alias for calling [Builder.brand] with `brand.orElse(null)`. */ + fun brand(brand: Optional) = brand(brand.getOrNull()) + + /** + * Sets [Builder.brand] to an arbitrary JSON value. + * + * You should usually call [Builder.brand] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun brand(brand: JsonField) = apply { this.brand = brand } + + fun data(data: Data?) = data(JsonField.ofNullable(data)) + + /** Alias for calling [Builder.data] with `data.orElse(null)`. */ + fun data(data: Optional) = data(data.getOrNull()) + + /** + * 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 profile(profile: Profile?) = profile(JsonField.ofNullable(profile)) + + /** Alias for calling [Builder.profile] with `profile.orElse(null)`. */ + fun profile(profile: Optional) = profile(profile.getOrNull()) + + /** + * Sets [Builder.profile] to an arbitrary JSON value. + * + * You should usually call [Builder.profile] with a well-typed [Profile] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun profile(profile: JsonField) = apply { this.profile = profile } + + fun template(template: String?) = template(JsonField.ofNullable(template)) + + /** Alias for calling [Builder.template] with `template.orElse(null)`. */ + fun template(template: Optional) = template(template.getOrNull()) + + /** + * Sets [Builder.template] to an arbitrary JSON value. + * + * You should usually call [Builder.template] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun template(template: JsonField) = apply { this.template = template } + + 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 + * .recipient() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("recipient", recipient), + brand, + data, + profile, + template, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + recipient() + brand() + data().ifPresent { it.validate() } + profile().ifPresent { it.validate() } + template() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (recipient.asKnown().isPresent) 1 else 0) + + (if (brand.asKnown().isPresent) 1 else 0) + + (data.asKnown().getOrNull()?.validity() ?: 0) + + (profile.asKnown().getOrNull()?.validity() ?: 0) + + (if (template.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + recipient == other.recipient && + brand == other.brand && + data == other.data && + profile == other.profile && + template == other.template && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(recipient, brand, data, profile, template, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{recipient=$recipient, brand=$brand, data=$data, profile=$profile, template=$template, additionalProperties=$additionalProperties}" + } + + class Data + @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 [Data]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Data]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(data: Data) = apply { + additionalProperties = data.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 [Data]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Data = Data(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): Data = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Data && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Data{additionalProperties=$additionalProperties}" + } + + class Profile + @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 [Profile]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Profile]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(profile: Profile) = apply { + additionalProperties = profile.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 [Profile]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Profile = Profile(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): Profile = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Profile && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Profile{additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is InvokeInvokeByTemplateParams && + templateId == other.templateId && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(templateId, body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "InvokeInvokeByTemplateParams{templateId=$templateId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/brands/Brand.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/brands/Brand.kt new file mode 100644 index 00000000..ef93ad9e --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/brands/Brand.kt @@ -0,0 +1,434 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.brands + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkRequired +import com.courier.api.errors.CourierInvalidDataException +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 Brand +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val id: JsonField, + private val created: JsonField, + private val name: JsonField, + private val updated: JsonField, + private val published: JsonField, + private val settings: JsonField, + private val snippets: JsonField, + private val version: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("created") @ExcludeMissing created: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("updated") @ExcludeMissing updated: JsonField = JsonMissing.of(), + @JsonProperty("published") @ExcludeMissing published: JsonField = JsonMissing.of(), + @JsonProperty("settings") + @ExcludeMissing + settings: JsonField = JsonMissing.of(), + @JsonProperty("snippets") + @ExcludeMissing + snippets: JsonField = JsonMissing.of(), + @JsonProperty("version") @ExcludeMissing version: JsonField = JsonMissing.of(), + ) : this(id, created, name, updated, published, settings, snippets, version, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 id(): String = id.getRequired("id") + + /** + * @throws CourierInvalidDataException 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 created(): Long = created.getRequired("created") + + /** + * @throws CourierInvalidDataException 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 name(): String = name.getRequired("name") + + /** + * @throws CourierInvalidDataException 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 updated(): Long = updated.getRequired("updated") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun published(): Optional = published.getOptional("published") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun settings(): Optional = settings.getOptional("settings") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun snippets(): Optional = snippets.getOptional("snippets") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun version(): Optional = version.getOptional("version") + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + /** + * Returns the raw JSON value of [created]. + * + * Unlike [created], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created") @ExcludeMissing fun _created(): JsonField = created + + /** + * 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 [updated]. + * + * Unlike [updated], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("updated") @ExcludeMissing fun _updated(): JsonField = updated + + /** + * Returns the raw JSON value of [published]. + * + * Unlike [published], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("published") @ExcludeMissing fun _published(): JsonField = published + + /** + * Returns the raw JSON value of [settings]. + * + * Unlike [settings], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("settings") @ExcludeMissing fun _settings(): JsonField = settings + + /** + * Returns the raw JSON value of [snippets]. + * + * Unlike [snippets], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("snippets") @ExcludeMissing fun _snippets(): JsonField = snippets + + /** + * Returns the raw JSON value of [version]. + * + * Unlike [version], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("version") @ExcludeMissing fun _version(): JsonField = version + + @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 [Brand]. + * + * The following fields are required: + * ```java + * .id() + * .created() + * .name() + * .updated() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Brand]. */ + class Builder internal constructor() { + + private var id: JsonField? = null + private var created: JsonField? = null + private var name: JsonField? = null + private var updated: JsonField? = null + private var published: JsonField = JsonMissing.of() + private var settings: JsonField = JsonMissing.of() + private var snippets: JsonField = JsonMissing.of() + private var version: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(brand: Brand) = apply { + id = brand.id + created = brand.created + name = brand.name + updated = brand.updated + published = brand.published + settings = brand.settings + snippets = brand.snippets + version = brand.version + additionalProperties = brand.additionalProperties.toMutableMap() + } + + fun id(id: String) = id(JsonField.of(id)) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun id(id: JsonField) = apply { this.id = id } + + fun created(created: Long) = created(JsonField.of(created)) + + /** + * Sets [Builder.created] to an arbitrary JSON value. + * + * You should usually call [Builder.created] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun created(created: JsonField) = apply { this.created = created } + + 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 } + + fun updated(updated: Long) = updated(JsonField.of(updated)) + + /** + * Sets [Builder.updated] to an arbitrary JSON value. + * + * You should usually call [Builder.updated] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun updated(updated: JsonField) = apply { this.updated = updated } + + fun published(published: Long?) = published(JsonField.ofNullable(published)) + + /** + * Alias for [Builder.published]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun published(published: Long) = published(published as Long?) + + /** Alias for calling [Builder.published] with `published.orElse(null)`. */ + fun published(published: Optional) = published(published.getOrNull()) + + /** + * Sets [Builder.published] to an arbitrary JSON value. + * + * You should usually call [Builder.published] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun published(published: JsonField) = apply { this.published = published } + + fun settings(settings: BrandSettings?) = settings(JsonField.ofNullable(settings)) + + /** Alias for calling [Builder.settings] with `settings.orElse(null)`. */ + fun settings(settings: Optional) = settings(settings.getOrNull()) + + /** + * Sets [Builder.settings] to an arbitrary JSON value. + * + * You should usually call [Builder.settings] with a well-typed [BrandSettings] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun settings(settings: JsonField) = apply { this.settings = settings } + + fun snippets(snippets: BrandSnippets?) = snippets(JsonField.ofNullable(snippets)) + + /** Alias for calling [Builder.snippets] with `snippets.orElse(null)`. */ + fun snippets(snippets: Optional) = snippets(snippets.getOrNull()) + + /** + * Sets [Builder.snippets] to an arbitrary JSON value. + * + * You should usually call [Builder.snippets] with a well-typed [BrandSnippets] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun snippets(snippets: JsonField) = apply { this.snippets = snippets } + + fun version(version: String?) = version(JsonField.ofNullable(version)) + + /** Alias for calling [Builder.version] with `version.orElse(null)`. */ + fun version(version: Optional) = version(version.getOrNull()) + + /** + * Sets [Builder.version] to an arbitrary JSON value. + * + * You should usually call [Builder.version] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun version(version: JsonField) = apply { this.version = version } + + 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 [Brand]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .created() + * .name() + * .updated() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Brand = + Brand( + checkRequired("id", id), + checkRequired("created", created), + checkRequired("name", name), + checkRequired("updated", updated), + published, + settings, + snippets, + version, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Brand = apply { + if (validated) { + return@apply + } + + id() + created() + name() + updated() + published() + settings().ifPresent { it.validate() } + snippets().ifPresent { it.validate() } + version() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (id.asKnown().isPresent) 1 else 0) + + (if (created.asKnown().isPresent) 1 else 0) + + (if (name.asKnown().isPresent) 1 else 0) + + (if (updated.asKnown().isPresent) 1 else 0) + + (if (published.asKnown().isPresent) 1 else 0) + + (settings.asKnown().getOrNull()?.validity() ?: 0) + + (snippets.asKnown().getOrNull()?.validity() ?: 0) + + (if (version.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Brand && + id == other.id && + created == other.created && + name == other.name && + updated == other.updated && + published == other.published && + settings == other.settings && + snippets == other.snippets && + version == other.version && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + id, + created, + name, + updated, + published, + settings, + snippets, + version, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Brand{id=$id, created=$created, name=$name, updated=$updated, published=$published, settings=$settings, snippets=$snippets, version=$version, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/brands/BrandColors.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/brands/BrandColors.kt new file mode 100644 index 00000000..2a1b3784 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/brands/BrandColors.kt @@ -0,0 +1,192 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.brands + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.errors.CourierInvalidDataException +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 BrandColors +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val primary: JsonField, + private val secondary: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("primary") @ExcludeMissing primary: JsonField = JsonMissing.of(), + @JsonProperty("secondary") @ExcludeMissing secondary: JsonField = JsonMissing.of(), + ) : this(primary, secondary, mutableMapOf()) + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun primary(): Optional = primary.getOptional("primary") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun secondary(): Optional = secondary.getOptional("secondary") + + /** + * Returns the raw JSON value of [primary]. + * + * Unlike [primary], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("primary") @ExcludeMissing fun _primary(): JsonField = primary + + /** + * Returns the raw JSON value of [secondary]. + * + * Unlike [secondary], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("secondary") @ExcludeMissing fun _secondary(): JsonField = secondary + + @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 [BrandColors]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [BrandColors]. */ + class Builder internal constructor() { + + private var primary: JsonField = JsonMissing.of() + private var secondary: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(brandColors: BrandColors) = apply { + primary = brandColors.primary + secondary = brandColors.secondary + additionalProperties = brandColors.additionalProperties.toMutableMap() + } + + fun primary(primary: String?) = primary(JsonField.ofNullable(primary)) + + /** Alias for calling [Builder.primary] with `primary.orElse(null)`. */ + fun primary(primary: Optional) = primary(primary.getOrNull()) + + /** + * Sets [Builder.primary] to an arbitrary JSON value. + * + * You should usually call [Builder.primary] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun primary(primary: JsonField) = apply { this.primary = primary } + + fun secondary(secondary: String?) = secondary(JsonField.ofNullable(secondary)) + + /** Alias for calling [Builder.secondary] with `secondary.orElse(null)`. */ + fun secondary(secondary: Optional) = secondary(secondary.getOrNull()) + + /** + * Sets [Builder.secondary] to an arbitrary JSON value. + * + * You should usually call [Builder.secondary] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun secondary(secondary: JsonField) = apply { this.secondary = secondary } + + 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 [BrandColors]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): BrandColors = + BrandColors(primary, secondary, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): BrandColors = apply { + if (validated) { + return@apply + } + + primary() + secondary() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (primary.asKnown().isPresent) 1 else 0) + (if (secondary.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is BrandColors && + primary == other.primary && + secondary == other.secondary && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(primary, secondary, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "BrandColors{primary=$primary, secondary=$secondary, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/brands/BrandCreateParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/brands/BrandCreateParams.kt new file mode 100644 index 00000000..679e5bf3 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/brands/BrandCreateParams.kt @@ -0,0 +1,614 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.brands + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.Params +import com.courier.api.core.checkRequired +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import com.courier.api.errors.CourierInvalidDataException +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 new brand */ +class BrandCreateParams +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * @throws CourierInvalidDataException 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 name(): String = body.name() + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun id(): Optional = body.id() + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun settings(): Optional = body.settings() + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun snippets(): Optional = body.snippets() + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _name(): JsonField = body._name() + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _id(): JsonField = body._id() + + /** + * Returns the raw JSON value of [settings]. + * + * Unlike [settings], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _settings(): JsonField = body._settings() + + /** + * Returns the raw JSON value of [snippets]. + * + * Unlike [snippets], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _snippets(): JsonField = body._snippets() + + 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 [BrandCreateParams]. + * + * The following fields are required: + * ```java + * .name() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [BrandCreateParams]. */ + 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(brandCreateParams: BrandCreateParams) = apply { + body = brandCreateParams.body.toBuilder() + additionalHeaders = brandCreateParams.additionalHeaders.toBuilder() + additionalQueryParams = brandCreateParams.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: + * - [name] + * - [id] + * - [settings] + * - [snippets] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + fun name(name: String) = apply { body.name(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 { body.name(name) } + + fun id(id: String?) = apply { body.id(id) } + + /** Alias for calling [Builder.id] with `id.orElse(null)`. */ + fun id(id: Optional) = id(id.getOrNull()) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun id(id: JsonField) = apply { body.id(id) } + + fun settings(settings: BrandSettings?) = apply { body.settings(settings) } + + /** Alias for calling [Builder.settings] with `settings.orElse(null)`. */ + fun settings(settings: Optional) = settings(settings.getOrNull()) + + /** + * Sets [Builder.settings] to an arbitrary JSON value. + * + * You should usually call [Builder.settings] with a well-typed [BrandSettings] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun settings(settings: JsonField) = apply { body.settings(settings) } + + fun snippets(snippets: BrandSnippets?) = apply { body.snippets(snippets) } + + /** Alias for calling [Builder.snippets] with `snippets.orElse(null)`. */ + fun snippets(snippets: Optional) = snippets(snippets.getOrNull()) + + /** + * Sets [Builder.snippets] to an arbitrary JSON value. + * + * You should usually call [Builder.snippets] with a well-typed [BrandSnippets] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun snippets(snippets: JsonField) = apply { body.snippets(snippets) } + + 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 [BrandCreateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .name() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): BrandCreateParams = + BrandCreateParams( + 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 name: JsonField, + private val id: JsonField, + private val settings: JsonField, + private val snippets: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("settings") + @ExcludeMissing + settings: JsonField = JsonMissing.of(), + @JsonProperty("snippets") + @ExcludeMissing + snippets: JsonField = JsonMissing.of(), + ) : this(name, id, settings, snippets, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 name(): String = name.getRequired("name") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun id(): Optional = id.getOptional("id") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun settings(): Optional = settings.getOptional("settings") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun snippets(): Optional = snippets.getOptional("snippets") + + /** + * 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 [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + /** + * Returns the raw JSON value of [settings]. + * + * Unlike [settings], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("settings") + @ExcludeMissing + fun _settings(): JsonField = settings + + /** + * Returns the raw JSON value of [snippets]. + * + * Unlike [snippets], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("snippets") + @ExcludeMissing + fun _snippets(): JsonField = snippets + + @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 + * .name() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var name: JsonField? = null + private var id: JsonField = JsonMissing.of() + private var settings: JsonField = JsonMissing.of() + private var snippets: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + name = body.name + id = body.id + settings = body.settings + snippets = body.snippets + additionalProperties = body.additionalProperties.toMutableMap() + } + + 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 } + + fun id(id: String?) = id(JsonField.ofNullable(id)) + + /** Alias for calling [Builder.id] with `id.orElse(null)`. */ + fun id(id: Optional) = id(id.getOrNull()) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun id(id: JsonField) = apply { this.id = id } + + fun settings(settings: BrandSettings?) = settings(JsonField.ofNullable(settings)) + + /** Alias for calling [Builder.settings] with `settings.orElse(null)`. */ + fun settings(settings: Optional) = settings(settings.getOrNull()) + + /** + * Sets [Builder.settings] to an arbitrary JSON value. + * + * You should usually call [Builder.settings] with a well-typed [BrandSettings] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun settings(settings: JsonField) = apply { this.settings = settings } + + fun snippets(snippets: BrandSnippets?) = snippets(JsonField.ofNullable(snippets)) + + /** Alias for calling [Builder.snippets] with `snippets.orElse(null)`. */ + fun snippets(snippets: Optional) = snippets(snippets.getOrNull()) + + /** + * Sets [Builder.snippets] to an arbitrary JSON value. + * + * You should usually call [Builder.snippets] with a well-typed [BrandSnippets] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun snippets(snippets: JsonField) = apply { this.snippets = snippets } + + 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 + * .name() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("name", name), + id, + settings, + snippets, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + name() + id() + settings().ifPresent { it.validate() } + snippets().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (id.asKnown().isPresent) 1 else 0) + + (settings.asKnown().getOrNull()?.validity() ?: 0) + + (snippets.asKnown().getOrNull()?.validity() ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + name == other.name && + id == other.id && + settings == other.settings && + snippets == other.snippets && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(name, id, settings, snippets, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{name=$name, id=$id, settings=$settings, snippets=$snippets, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is BrandCreateParams && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = Objects.hash(body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "BrandCreateParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/brands/BrandDeleteParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/brands/BrandDeleteParams.kt new file mode 100644 index 00000000..bc296c46 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/brands/BrandDeleteParams.kt @@ -0,0 +1,229 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.brands + +import com.courier.api.core.JsonValue +import com.courier.api.core.Params +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import com.courier.api.core.toImmutable +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Delete a brand by brand ID. */ +class BrandDeleteParams +private constructor( + private val brandId: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, + private val additionalBodyProperties: Map, +) : Params { + + fun brandId(): Optional = Optional.ofNullable(brandId) + + /** 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(): BrandDeleteParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [BrandDeleteParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [BrandDeleteParams]. */ + class Builder internal constructor() { + + private var brandId: 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(brandDeleteParams: BrandDeleteParams) = apply { + brandId = brandDeleteParams.brandId + additionalHeaders = brandDeleteParams.additionalHeaders.toBuilder() + additionalQueryParams = brandDeleteParams.additionalQueryParams.toBuilder() + additionalBodyProperties = brandDeleteParams.additionalBodyProperties.toMutableMap() + } + + fun brandId(brandId: String?) = apply { this.brandId = brandId } + + /** Alias for calling [Builder.brandId] with `brandId.orElse(null)`. */ + fun brandId(brandId: Optional) = brandId(brandId.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 [BrandDeleteParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): BrandDeleteParams = + BrandDeleteParams( + brandId, + additionalHeaders.build(), + additionalQueryParams.build(), + additionalBodyProperties.toImmutable(), + ) + } + + fun _body(): Optional> = + Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) + + fun _pathParam(index: Int): String = + when (index) { + 0 -> brandId ?: "" + 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 BrandDeleteParams && + brandId == other.brandId && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams && + additionalBodyProperties == other.additionalBodyProperties + } + + override fun hashCode(): Int = + Objects.hash(brandId, additionalHeaders, additionalQueryParams, additionalBodyProperties) + + override fun toString() = + "BrandDeleteParams{brandId=$brandId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/brands/BrandListParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/brands/BrandListParams.kt new file mode 100644 index 00000000..6146a079 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/brands/BrandListParams.kt @@ -0,0 +1,191 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.brands + +import com.courier.api.core.Params +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Get the list of brands. */ +class BrandListParams +private constructor( + private val cursor: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** A unique identifier that allows for fetching the next set of brands. */ + fun cursor(): Optional = Optional.ofNullable(cursor) + + /** 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(): BrandListParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [BrandListParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [BrandListParams]. */ + class Builder internal constructor() { + + private var cursor: String? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(brandListParams: BrandListParams) = apply { + cursor = brandListParams.cursor + additionalHeaders = brandListParams.additionalHeaders.toBuilder() + additionalQueryParams = brandListParams.additionalQueryParams.toBuilder() + } + + /** A unique identifier that allows for fetching the next set of brands. */ + fun cursor(cursor: String?) = apply { this.cursor = cursor } + + /** Alias for calling [Builder.cursor] with `cursor.orElse(null)`. */ + fun cursor(cursor: Optional) = cursor(cursor.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 [BrandListParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): BrandListParams = + BrandListParams(cursor, additionalHeaders.build(), additionalQueryParams.build()) + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + cursor?.let { put("cursor", it) } + putAll(additionalQueryParams) + } + .build() + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is BrandListParams && + cursor == other.cursor && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = Objects.hash(cursor, additionalHeaders, additionalQueryParams) + + override fun toString() = + "BrandListParams{cursor=$cursor, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/brands/BrandListResponse.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/brands/BrandListResponse.kt new file mode 100644 index 00000000..05cb87ae --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/brands/BrandListResponse.kt @@ -0,0 +1,224 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.brands + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkKnown +import com.courier.api.core.checkRequired +import com.courier.api.core.toImmutable +import com.courier.api.errors.CourierInvalidDataException +import com.courier.api.models.audiences.Paging +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 kotlin.jvm.optionals.getOrNull + +class BrandListResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val paging: JsonField, + private val results: JsonField>, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("paging") @ExcludeMissing paging: JsonField = JsonMissing.of(), + @JsonProperty("results") @ExcludeMissing results: JsonField> = JsonMissing.of(), + ) : this(paging, results, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 paging(): Paging = paging.getRequired("paging") + + /** + * @throws CourierInvalidDataException 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 results(): List = results.getRequired("results") + + /** + * Returns the raw JSON value of [paging]. + * + * Unlike [paging], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("paging") @ExcludeMissing fun _paging(): JsonField = paging + + /** + * Returns the raw JSON value of [results]. + * + * Unlike [results], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("results") @ExcludeMissing fun _results(): JsonField> = results + + @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 [BrandListResponse]. + * + * The following fields are required: + * ```java + * .paging() + * .results() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [BrandListResponse]. */ + class Builder internal constructor() { + + private var paging: JsonField? = null + private var results: JsonField>? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(brandListResponse: BrandListResponse) = apply { + paging = brandListResponse.paging + results = brandListResponse.results.map { it.toMutableList() } + additionalProperties = brandListResponse.additionalProperties.toMutableMap() + } + + fun paging(paging: Paging) = paging(JsonField.of(paging)) + + /** + * Sets [Builder.paging] to an arbitrary JSON value. + * + * You should usually call [Builder.paging] with a well-typed [Paging] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun paging(paging: JsonField) = apply { this.paging = paging } + + fun results(results: List) = results(JsonField.of(results)) + + /** + * Sets [Builder.results] to an arbitrary JSON value. + * + * You should usually call [Builder.results] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun results(results: JsonField>) = apply { + this.results = results.map { it.toMutableList() } + } + + /** + * Adds a single [Brand] to [results]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addResult(result: Brand) = apply { + results = + (results ?: JsonField.of(mutableListOf())).also { + checkKnown("results", it).add(result) + } + } + + 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 [BrandListResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .paging() + * .results() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): BrandListResponse = + BrandListResponse( + checkRequired("paging", paging), + checkRequired("results", results).map { it.toImmutable() }, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): BrandListResponse = apply { + if (validated) { + return@apply + } + + paging().validate() + results().forEach { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (paging.asKnown().getOrNull()?.validity() ?: 0) + + (results.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is BrandListResponse && + paging == other.paging && + results == other.results && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(paging, results, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "BrandListResponse{paging=$paging, results=$results, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/brands/BrandRetrieveParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/brands/BrandRetrieveParams.kt new file mode 100644 index 00000000..22323e2b --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/brands/BrandRetrieveParams.kt @@ -0,0 +1,189 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.brands + +import com.courier.api.core.Params +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Fetch a specific brand by brand ID. */ +class BrandRetrieveParams +private constructor( + private val brandId: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun brandId(): Optional = Optional.ofNullable(brandId) + + /** 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(): BrandRetrieveParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [BrandRetrieveParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [BrandRetrieveParams]. */ + class Builder internal constructor() { + + private var brandId: String? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(brandRetrieveParams: BrandRetrieveParams) = apply { + brandId = brandRetrieveParams.brandId + additionalHeaders = brandRetrieveParams.additionalHeaders.toBuilder() + additionalQueryParams = brandRetrieveParams.additionalQueryParams.toBuilder() + } + + fun brandId(brandId: String?) = apply { this.brandId = brandId } + + /** Alias for calling [Builder.brandId] with `brandId.orElse(null)`. */ + fun brandId(brandId: Optional) = brandId(brandId.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 [BrandRetrieveParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): BrandRetrieveParams = + BrandRetrieveParams(brandId, additionalHeaders.build(), additionalQueryParams.build()) + } + + fun _pathParam(index: Int): String = + when (index) { + 0 -> brandId ?: "" + 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 BrandRetrieveParams && + brandId == other.brandId && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = Objects.hash(brandId, additionalHeaders, additionalQueryParams) + + override fun toString() = + "BrandRetrieveParams{brandId=$brandId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/brands/BrandSettings.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/brands/BrandSettings.kt new file mode 100644 index 00000000..98f45d88 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/brands/BrandSettings.kt @@ -0,0 +1,232 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.brands + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.errors.CourierInvalidDataException +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 BrandSettings +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val colors: JsonField, + private val email: JsonField, + private val inapp: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("colors") @ExcludeMissing colors: JsonField = JsonMissing.of(), + @JsonProperty("email") + @ExcludeMissing + email: JsonField = JsonMissing.of(), + @JsonProperty("inapp") + @ExcludeMissing + inapp: JsonField = JsonMissing.of(), + ) : this(colors, email, inapp, mutableMapOf()) + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun colors(): Optional = colors.getOptional("colors") + + /** + * @throws CourierInvalidDataException 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 CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun inapp(): Optional = inapp.getOptional("inapp") + + /** + * Returns the raw JSON value of [colors]. + * + * Unlike [colors], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("colors") @ExcludeMissing fun _colors(): JsonField = colors + + /** + * 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 [inapp]. + * + * Unlike [inapp], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("inapp") @ExcludeMissing fun _inapp(): JsonField = inapp + + @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 [BrandSettings]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [BrandSettings]. */ + class Builder internal constructor() { + + private var colors: JsonField = JsonMissing.of() + private var email: JsonField = JsonMissing.of() + private var inapp: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(brandSettings: BrandSettings) = apply { + colors = brandSettings.colors + email = brandSettings.email + inapp = brandSettings.inapp + additionalProperties = brandSettings.additionalProperties.toMutableMap() + } + + fun colors(colors: BrandColors?) = colors(JsonField.ofNullable(colors)) + + /** Alias for calling [Builder.colors] with `colors.orElse(null)`. */ + fun colors(colors: Optional) = colors(colors.getOrNull()) + + /** + * Sets [Builder.colors] to an arbitrary JSON value. + * + * You should usually call [Builder.colors] with a well-typed [BrandColors] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun colors(colors: JsonField) = apply { this.colors = colors } + + fun email(email: BrandSettingsEmail?) = email(JsonField.ofNullable(email)) + + /** Alias for calling [Builder.email] with `email.orElse(null)`. */ + fun email(email: Optional) = email(email.getOrNull()) + + /** + * Sets [Builder.email] to an arbitrary JSON value. + * + * You should usually call [Builder.email] with a well-typed [BrandSettingsEmail] 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 inapp(inapp: BrandSettingsInApp?) = inapp(JsonField.ofNullable(inapp)) + + /** Alias for calling [Builder.inapp] with `inapp.orElse(null)`. */ + fun inapp(inapp: Optional) = inapp(inapp.getOrNull()) + + /** + * Sets [Builder.inapp] to an arbitrary JSON value. + * + * You should usually call [Builder.inapp] with a well-typed [BrandSettingsInApp] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun inapp(inapp: JsonField) = apply { this.inapp = inapp } + + 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 [BrandSettings]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): BrandSettings = + BrandSettings(colors, email, inapp, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): BrandSettings = apply { + if (validated) { + return@apply + } + + colors().ifPresent { it.validate() } + email().ifPresent { it.validate() } + inapp().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (colors.asKnown().getOrNull()?.validity() ?: 0) + + (email.asKnown().getOrNull()?.validity() ?: 0) + + (inapp.asKnown().getOrNull()?.validity() ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is BrandSettings && + colors == other.colors && + email == other.email && + inapp == other.inapp && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(colors, email, inapp, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "BrandSettings{colors=$colors, email=$email, inapp=$inapp, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/brands/BrandSettingsEmail.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/brands/BrandSettingsEmail.kt new file mode 100644 index 00000000..8178b62e --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/brands/BrandSettingsEmail.kt @@ -0,0 +1,841 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.brands + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkRequired +import com.courier.api.errors.CourierInvalidDataException +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 BrandSettingsEmail +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val footer: JsonField, + private val head: JsonField, + private val header: JsonField, + private val templateOverride: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("footer") @ExcludeMissing footer: JsonField = JsonMissing.of(), + @JsonProperty("head") @ExcludeMissing head: JsonField = JsonMissing.of(), + @JsonProperty("header") @ExcludeMissing header: JsonField = JsonMissing.of(), + @JsonProperty("templateOverride") + @ExcludeMissing + templateOverride: JsonField = JsonMissing.of(), + ) : this(footer, head, header, templateOverride, mutableMapOf()) + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun footer(): Optional = footer.getOptional("footer") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun head(): Optional = head.getOptional("head") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun header(): Optional = header.getOptional("header") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun templateOverride(): Optional = + templateOverride.getOptional("templateOverride") + + /** + * Returns the raw JSON value of [footer]. + * + * Unlike [footer], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("footer") @ExcludeMissing fun _footer(): JsonField = footer + + /** + * Returns the raw JSON value of [head]. + * + * Unlike [head], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("head") @ExcludeMissing fun _head(): JsonField = head + + /** + * Returns the raw JSON value of [header]. + * + * Unlike [header], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("header") @ExcludeMissing fun _header(): JsonField = header + + /** + * Returns the raw JSON value of [templateOverride]. + * + * Unlike [templateOverride], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("templateOverride") + @ExcludeMissing + fun _templateOverride(): JsonField = templateOverride + + @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 [BrandSettingsEmail]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [BrandSettingsEmail]. */ + class Builder internal constructor() { + + private var footer: JsonField = JsonMissing.of() + private var head: JsonField = JsonMissing.of() + private var header: JsonField = JsonMissing.of() + private var templateOverride: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(brandSettingsEmail: BrandSettingsEmail) = apply { + footer = brandSettingsEmail.footer + head = brandSettingsEmail.head + header = brandSettingsEmail.header + templateOverride = brandSettingsEmail.templateOverride + additionalProperties = brandSettingsEmail.additionalProperties.toMutableMap() + } + + fun footer(footer: EmailFooter?) = footer(JsonField.ofNullable(footer)) + + /** Alias for calling [Builder.footer] with `footer.orElse(null)`. */ + fun footer(footer: Optional) = footer(footer.getOrNull()) + + /** + * Sets [Builder.footer] to an arbitrary JSON value. + * + * You should usually call [Builder.footer] with a well-typed [EmailFooter] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun footer(footer: JsonField) = apply { this.footer = footer } + + fun head(head: EmailHead?) = head(JsonField.ofNullable(head)) + + /** Alias for calling [Builder.head] with `head.orElse(null)`. */ + fun head(head: Optional) = head(head.getOrNull()) + + /** + * Sets [Builder.head] to an arbitrary JSON value. + * + * You should usually call [Builder.head] with a well-typed [EmailHead] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun head(head: JsonField) = apply { this.head = head } + + fun header(header: EmailHeader?) = header(JsonField.ofNullable(header)) + + /** Alias for calling [Builder.header] with `header.orElse(null)`. */ + fun header(header: Optional) = header(header.getOrNull()) + + /** + * Sets [Builder.header] to an arbitrary JSON value. + * + * You should usually call [Builder.header] with a well-typed [EmailHeader] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun header(header: JsonField) = apply { this.header = header } + + fun templateOverride(templateOverride: TemplateOverride?) = + templateOverride(JsonField.ofNullable(templateOverride)) + + /** Alias for calling [Builder.templateOverride] with `templateOverride.orElse(null)`. */ + fun templateOverride(templateOverride: Optional) = + templateOverride(templateOverride.getOrNull()) + + /** + * Sets [Builder.templateOverride] to an arbitrary JSON value. + * + * You should usually call [Builder.templateOverride] with a well-typed [TemplateOverride] + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun templateOverride(templateOverride: JsonField) = apply { + this.templateOverride = templateOverride + } + + 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 [BrandSettingsEmail]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): BrandSettingsEmail = + BrandSettingsEmail( + footer, + head, + header, + templateOverride, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): BrandSettingsEmail = apply { + if (validated) { + return@apply + } + + footer().ifPresent { it.validate() } + head().ifPresent { it.validate() } + header().ifPresent { it.validate() } + templateOverride().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (footer.asKnown().getOrNull()?.validity() ?: 0) + + (head.asKnown().getOrNull()?.validity() ?: 0) + + (header.asKnown().getOrNull()?.validity() ?: 0) + + (templateOverride.asKnown().getOrNull()?.validity() ?: 0) + + class TemplateOverride + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val enabled: JsonField, + private val backgroundColor: JsonField, + private val blocksBackgroundColor: JsonField, + private val footer: JsonField, + private val head: JsonField, + private val header: JsonField, + private val width: JsonField, + private val mjml: JsonField, + private val footerBackgroundColor: JsonField, + private val footerFullWidth: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("enabled") @ExcludeMissing enabled: JsonField = JsonMissing.of(), + @JsonProperty("backgroundColor") + @ExcludeMissing + backgroundColor: JsonField = JsonMissing.of(), + @JsonProperty("blocksBackgroundColor") + @ExcludeMissing + blocksBackgroundColor: JsonField = JsonMissing.of(), + @JsonProperty("footer") @ExcludeMissing footer: JsonField = JsonMissing.of(), + @JsonProperty("head") @ExcludeMissing head: JsonField = JsonMissing.of(), + @JsonProperty("header") @ExcludeMissing header: JsonField = JsonMissing.of(), + @JsonProperty("width") @ExcludeMissing width: JsonField = JsonMissing.of(), + @JsonProperty("mjml") @ExcludeMissing mjml: JsonField = JsonMissing.of(), + @JsonProperty("footerBackgroundColor") + @ExcludeMissing + footerBackgroundColor: JsonField = JsonMissing.of(), + @JsonProperty("footerFullWidth") + @ExcludeMissing + footerFullWidth: JsonField = JsonMissing.of(), + ) : this( + enabled, + backgroundColor, + blocksBackgroundColor, + footer, + head, + header, + width, + mjml, + footerBackgroundColor, + footerFullWidth, + mutableMapOf(), + ) + + fun toBrandTemplate(): BrandTemplate = + BrandTemplate.builder() + .enabled(enabled) + .backgroundColor(backgroundColor) + .blocksBackgroundColor(blocksBackgroundColor) + .footer(footer) + .head(head) + .header(header) + .width(width) + .build() + + /** + * @throws CourierInvalidDataException 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 enabled(): Boolean = enabled.getRequired("enabled") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun backgroundColor(): Optional = backgroundColor.getOptional("backgroundColor") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun blocksBackgroundColor(): Optional = + blocksBackgroundColor.getOptional("blocksBackgroundColor") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun footer(): Optional = footer.getOptional("footer") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun head(): Optional = head.getOptional("head") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun header(): Optional = header.getOptional("header") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun width(): Optional = width.getOptional("width") + + /** + * @throws CourierInvalidDataException 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 mjml(): BrandTemplate = mjml.getRequired("mjml") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun footerBackgroundColor(): Optional = + footerBackgroundColor.getOptional("footerBackgroundColor") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun footerFullWidth(): Optional = footerFullWidth.getOptional("footerFullWidth") + + /** + * Returns the raw JSON value of [enabled]. + * + * Unlike [enabled], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("enabled") @ExcludeMissing fun _enabled(): JsonField = enabled + + /** + * Returns the raw JSON value of [backgroundColor]. + * + * Unlike [backgroundColor], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("backgroundColor") + @ExcludeMissing + fun _backgroundColor(): JsonField = backgroundColor + + /** + * Returns the raw JSON value of [blocksBackgroundColor]. + * + * Unlike [blocksBackgroundColor], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("blocksBackgroundColor") + @ExcludeMissing + fun _blocksBackgroundColor(): JsonField = blocksBackgroundColor + + /** + * Returns the raw JSON value of [footer]. + * + * Unlike [footer], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("footer") @ExcludeMissing fun _footer(): JsonField = footer + + /** + * Returns the raw JSON value of [head]. + * + * Unlike [head], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("head") @ExcludeMissing fun _head(): JsonField = head + + /** + * Returns the raw JSON value of [header]. + * + * Unlike [header], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("header") @ExcludeMissing fun _header(): JsonField = header + + /** + * Returns the raw JSON value of [width]. + * + * Unlike [width], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("width") @ExcludeMissing fun _width(): JsonField = width + + /** + * Returns the raw JSON value of [mjml]. + * + * Unlike [mjml], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("mjml") @ExcludeMissing fun _mjml(): JsonField = mjml + + /** + * Returns the raw JSON value of [footerBackgroundColor]. + * + * Unlike [footerBackgroundColor], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("footerBackgroundColor") + @ExcludeMissing + fun _footerBackgroundColor(): JsonField = footerBackgroundColor + + /** + * Returns the raw JSON value of [footerFullWidth]. + * + * Unlike [footerFullWidth], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("footerFullWidth") + @ExcludeMissing + fun _footerFullWidth(): JsonField = footerFullWidth + + @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 [TemplateOverride]. + * + * The following fields are required: + * ```java + * .enabled() + * .mjml() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [TemplateOverride]. */ + class Builder internal constructor() { + + private var enabled: JsonField? = null + private var backgroundColor: JsonField = JsonMissing.of() + private var blocksBackgroundColor: JsonField = JsonMissing.of() + private var footer: JsonField = JsonMissing.of() + private var head: JsonField = JsonMissing.of() + private var header: JsonField = JsonMissing.of() + private var width: JsonField = JsonMissing.of() + private var mjml: JsonField? = null + private var footerBackgroundColor: JsonField = JsonMissing.of() + private var footerFullWidth: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(templateOverride: TemplateOverride) = apply { + enabled = templateOverride.enabled + backgroundColor = templateOverride.backgroundColor + blocksBackgroundColor = templateOverride.blocksBackgroundColor + footer = templateOverride.footer + head = templateOverride.head + header = templateOverride.header + width = templateOverride.width + mjml = templateOverride.mjml + footerBackgroundColor = templateOverride.footerBackgroundColor + footerFullWidth = templateOverride.footerFullWidth + additionalProperties = templateOverride.additionalProperties.toMutableMap() + } + + fun enabled(enabled: Boolean) = enabled(JsonField.of(enabled)) + + /** + * Sets [Builder.enabled] to an arbitrary JSON value. + * + * You should usually call [Builder.enabled] with a well-typed [Boolean] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun enabled(enabled: JsonField) = apply { this.enabled = enabled } + + fun backgroundColor(backgroundColor: String?) = + backgroundColor(JsonField.ofNullable(backgroundColor)) + + /** Alias for calling [Builder.backgroundColor] with `backgroundColor.orElse(null)`. */ + fun backgroundColor(backgroundColor: Optional) = + backgroundColor(backgroundColor.getOrNull()) + + /** + * Sets [Builder.backgroundColor] to an arbitrary JSON value. + * + * You should usually call [Builder.backgroundColor] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun backgroundColor(backgroundColor: JsonField) = apply { + this.backgroundColor = backgroundColor + } + + fun blocksBackgroundColor(blocksBackgroundColor: String?) = + blocksBackgroundColor(JsonField.ofNullable(blocksBackgroundColor)) + + /** + * Alias for calling [Builder.blocksBackgroundColor] with + * `blocksBackgroundColor.orElse(null)`. + */ + fun blocksBackgroundColor(blocksBackgroundColor: Optional) = + blocksBackgroundColor(blocksBackgroundColor.getOrNull()) + + /** + * Sets [Builder.blocksBackgroundColor] to an arbitrary JSON value. + * + * You should usually call [Builder.blocksBackgroundColor] with a well-typed [String] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun blocksBackgroundColor(blocksBackgroundColor: JsonField) = apply { + this.blocksBackgroundColor = blocksBackgroundColor + } + + fun footer(footer: String?) = footer(JsonField.ofNullable(footer)) + + /** Alias for calling [Builder.footer] with `footer.orElse(null)`. */ + fun footer(footer: Optional) = footer(footer.getOrNull()) + + /** + * Sets [Builder.footer] to an arbitrary JSON value. + * + * You should usually call [Builder.footer] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun footer(footer: JsonField) = apply { this.footer = footer } + + fun head(head: String?) = head(JsonField.ofNullable(head)) + + /** Alias for calling [Builder.head] with `head.orElse(null)`. */ + fun head(head: Optional) = head(head.getOrNull()) + + /** + * Sets [Builder.head] to an arbitrary JSON value. + * + * You should usually call [Builder.head] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun head(head: JsonField) = apply { this.head = head } + + fun header(header: String?) = header(JsonField.ofNullable(header)) + + /** Alias for calling [Builder.header] with `header.orElse(null)`. */ + fun header(header: Optional) = header(header.getOrNull()) + + /** + * Sets [Builder.header] to an arbitrary JSON value. + * + * You should usually call [Builder.header] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun header(header: JsonField) = apply { this.header = header } + + fun width(width: String?) = width(JsonField.ofNullable(width)) + + /** Alias for calling [Builder.width] with `width.orElse(null)`. */ + fun width(width: Optional) = width(width.getOrNull()) + + /** + * Sets [Builder.width] to an arbitrary JSON value. + * + * You should usually call [Builder.width] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun width(width: JsonField) = apply { this.width = width } + + fun mjml(mjml: BrandTemplate) = mjml(JsonField.of(mjml)) + + /** + * Sets [Builder.mjml] to an arbitrary JSON value. + * + * You should usually call [Builder.mjml] with a well-typed [BrandTemplate] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun mjml(mjml: JsonField) = apply { this.mjml = mjml } + + fun footerBackgroundColor(footerBackgroundColor: String?) = + footerBackgroundColor(JsonField.ofNullable(footerBackgroundColor)) + + /** + * Alias for calling [Builder.footerBackgroundColor] with + * `footerBackgroundColor.orElse(null)`. + */ + fun footerBackgroundColor(footerBackgroundColor: Optional) = + footerBackgroundColor(footerBackgroundColor.getOrNull()) + + /** + * Sets [Builder.footerBackgroundColor] to an arbitrary JSON value. + * + * You should usually call [Builder.footerBackgroundColor] with a well-typed [String] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun footerBackgroundColor(footerBackgroundColor: JsonField) = apply { + this.footerBackgroundColor = footerBackgroundColor + } + + fun footerFullWidth(footerFullWidth: Boolean?) = + footerFullWidth(JsonField.ofNullable(footerFullWidth)) + + /** + * Alias for [Builder.footerFullWidth]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun footerFullWidth(footerFullWidth: Boolean) = + footerFullWidth(footerFullWidth as Boolean?) + + /** Alias for calling [Builder.footerFullWidth] with `footerFullWidth.orElse(null)`. */ + fun footerFullWidth(footerFullWidth: Optional) = + footerFullWidth(footerFullWidth.getOrNull()) + + /** + * Sets [Builder.footerFullWidth] to an arbitrary JSON value. + * + * You should usually call [Builder.footerFullWidth] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun footerFullWidth(footerFullWidth: JsonField) = apply { + this.footerFullWidth = footerFullWidth + } + + 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 [TemplateOverride]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .enabled() + * .mjml() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): TemplateOverride = + TemplateOverride( + checkRequired("enabled", enabled), + backgroundColor, + blocksBackgroundColor, + footer, + head, + header, + width, + checkRequired("mjml", mjml), + footerBackgroundColor, + footerFullWidth, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): TemplateOverride = apply { + if (validated) { + return@apply + } + + enabled() + backgroundColor() + blocksBackgroundColor() + footer() + head() + header() + width() + mjml().validate() + footerBackgroundColor() + footerFullWidth() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (enabled.asKnown().isPresent) 1 else 0) + + (if (backgroundColor.asKnown().isPresent) 1 else 0) + + (if (blocksBackgroundColor.asKnown().isPresent) 1 else 0) + + (if (footer.asKnown().isPresent) 1 else 0) + + (if (head.asKnown().isPresent) 1 else 0) + + (if (header.asKnown().isPresent) 1 else 0) + + (if (width.asKnown().isPresent) 1 else 0) + + (mjml.asKnown().getOrNull()?.validity() ?: 0) + + (if (footerBackgroundColor.asKnown().isPresent) 1 else 0) + + (if (footerFullWidth.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is TemplateOverride && + enabled == other.enabled && + backgroundColor == other.backgroundColor && + blocksBackgroundColor == other.blocksBackgroundColor && + footer == other.footer && + head == other.head && + header == other.header && + width == other.width && + mjml == other.mjml && + footerBackgroundColor == other.footerBackgroundColor && + footerFullWidth == other.footerFullWidth && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + enabled, + backgroundColor, + blocksBackgroundColor, + footer, + head, + header, + width, + mjml, + footerBackgroundColor, + footerFullWidth, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "TemplateOverride{enabled=$enabled, backgroundColor=$backgroundColor, blocksBackgroundColor=$blocksBackgroundColor, footer=$footer, head=$head, header=$header, width=$width, mjml=$mjml, footerBackgroundColor=$footerBackgroundColor, footerFullWidth=$footerFullWidth, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is BrandSettingsEmail && + footer == other.footer && + head == other.head && + header == other.header && + templateOverride == other.templateOverride && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(footer, head, header, templateOverride, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "BrandSettingsEmail{footer=$footer, head=$head, header=$header, templateOverride=$templateOverride, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/brands/BrandSettingsInApp.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/brands/BrandSettingsInApp.kt new file mode 100644 index 00000000..150c03a4 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/brands/BrandSettingsInApp.kt @@ -0,0 +1,580 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.brands + +import com.courier.api.core.Enum +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkRequired +import com.courier.api.errors.CourierInvalidDataException +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 BrandSettingsInApp +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val colors: JsonField, + private val icons: JsonField, + private val widgetBackground: JsonField, + private val borderRadius: JsonField, + private val disableMessageIcon: JsonField, + private val fontFamily: JsonField, + private val placement: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("colors") @ExcludeMissing colors: JsonField = JsonMissing.of(), + @JsonProperty("icons") @ExcludeMissing icons: JsonField = JsonMissing.of(), + @JsonProperty("widgetBackground") + @ExcludeMissing + widgetBackground: JsonField = JsonMissing.of(), + @JsonProperty("borderRadius") + @ExcludeMissing + borderRadius: JsonField = JsonMissing.of(), + @JsonProperty("disableMessageIcon") + @ExcludeMissing + disableMessageIcon: JsonField = JsonMissing.of(), + @JsonProperty("fontFamily") + @ExcludeMissing + fontFamily: JsonField = JsonMissing.of(), + @JsonProperty("placement") + @ExcludeMissing + placement: JsonField = JsonMissing.of(), + ) : this( + colors, + icons, + widgetBackground, + borderRadius, + disableMessageIcon, + fontFamily, + placement, + mutableMapOf(), + ) + + /** + * @throws CourierInvalidDataException 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 colors(): BrandColors = colors.getRequired("colors") + + /** + * @throws CourierInvalidDataException 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 icons(): Icons = icons.getRequired("icons") + + /** + * @throws CourierInvalidDataException 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 widgetBackground(): WidgetBackground = widgetBackground.getRequired("widgetBackground") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun borderRadius(): Optional = borderRadius.getOptional("borderRadius") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun disableMessageIcon(): Optional = + disableMessageIcon.getOptional("disableMessageIcon") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun fontFamily(): Optional = fontFamily.getOptional("fontFamily") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun placement(): Optional = placement.getOptional("placement") + + /** + * Returns the raw JSON value of [colors]. + * + * Unlike [colors], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("colors") @ExcludeMissing fun _colors(): JsonField = colors + + /** + * Returns the raw JSON value of [icons]. + * + * Unlike [icons], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("icons") @ExcludeMissing fun _icons(): JsonField = icons + + /** + * Returns the raw JSON value of [widgetBackground]. + * + * Unlike [widgetBackground], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("widgetBackground") + @ExcludeMissing + fun _widgetBackground(): JsonField = widgetBackground + + /** + * Returns the raw JSON value of [borderRadius]. + * + * Unlike [borderRadius], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("borderRadius") + @ExcludeMissing + fun _borderRadius(): JsonField = borderRadius + + /** + * Returns the raw JSON value of [disableMessageIcon]. + * + * Unlike [disableMessageIcon], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("disableMessageIcon") + @ExcludeMissing + fun _disableMessageIcon(): JsonField = disableMessageIcon + + /** + * Returns the raw JSON value of [fontFamily]. + * + * Unlike [fontFamily], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("fontFamily") @ExcludeMissing fun _fontFamily(): JsonField = fontFamily + + /** + * Returns the raw JSON value of [placement]. + * + * Unlike [placement], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("placement") @ExcludeMissing fun _placement(): JsonField = placement + + @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 [BrandSettingsInApp]. + * + * The following fields are required: + * ```java + * .colors() + * .icons() + * .widgetBackground() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [BrandSettingsInApp]. */ + class Builder internal constructor() { + + private var colors: JsonField? = null + private var icons: JsonField? = null + private var widgetBackground: JsonField? = null + private var borderRadius: JsonField = JsonMissing.of() + private var disableMessageIcon: JsonField = JsonMissing.of() + private var fontFamily: JsonField = JsonMissing.of() + private var placement: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(brandSettingsInApp: BrandSettingsInApp) = apply { + colors = brandSettingsInApp.colors + icons = brandSettingsInApp.icons + widgetBackground = brandSettingsInApp.widgetBackground + borderRadius = brandSettingsInApp.borderRadius + disableMessageIcon = brandSettingsInApp.disableMessageIcon + fontFamily = brandSettingsInApp.fontFamily + placement = brandSettingsInApp.placement + additionalProperties = brandSettingsInApp.additionalProperties.toMutableMap() + } + + fun colors(colors: BrandColors) = colors(JsonField.of(colors)) + + /** + * Sets [Builder.colors] to an arbitrary JSON value. + * + * You should usually call [Builder.colors] with a well-typed [BrandColors] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun colors(colors: JsonField) = apply { this.colors = colors } + + fun icons(icons: Icons) = icons(JsonField.of(icons)) + + /** + * Sets [Builder.icons] to an arbitrary JSON value. + * + * You should usually call [Builder.icons] with a well-typed [Icons] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun icons(icons: JsonField) = apply { this.icons = icons } + + fun widgetBackground(widgetBackground: WidgetBackground) = + widgetBackground(JsonField.of(widgetBackground)) + + /** + * Sets [Builder.widgetBackground] to an arbitrary JSON value. + * + * You should usually call [Builder.widgetBackground] with a well-typed [WidgetBackground] + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun widgetBackground(widgetBackground: JsonField) = apply { + this.widgetBackground = widgetBackground + } + + fun borderRadius(borderRadius: String?) = borderRadius(JsonField.ofNullable(borderRadius)) + + /** Alias for calling [Builder.borderRadius] with `borderRadius.orElse(null)`. */ + fun borderRadius(borderRadius: Optional) = borderRadius(borderRadius.getOrNull()) + + /** + * Sets [Builder.borderRadius] to an arbitrary JSON value. + * + * You should usually call [Builder.borderRadius] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun borderRadius(borderRadius: JsonField) = apply { + this.borderRadius = borderRadius + } + + fun disableMessageIcon(disableMessageIcon: Boolean?) = + disableMessageIcon(JsonField.ofNullable(disableMessageIcon)) + + /** + * Alias for [Builder.disableMessageIcon]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun disableMessageIcon(disableMessageIcon: Boolean) = + disableMessageIcon(disableMessageIcon as Boolean?) + + /** + * Alias for calling [Builder.disableMessageIcon] with `disableMessageIcon.orElse(null)`. + */ + fun disableMessageIcon(disableMessageIcon: Optional) = + disableMessageIcon(disableMessageIcon.getOrNull()) + + /** + * Sets [Builder.disableMessageIcon] to an arbitrary JSON value. + * + * You should usually call [Builder.disableMessageIcon] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun disableMessageIcon(disableMessageIcon: JsonField) = apply { + this.disableMessageIcon = disableMessageIcon + } + + fun fontFamily(fontFamily: String?) = fontFamily(JsonField.ofNullable(fontFamily)) + + /** Alias for calling [Builder.fontFamily] with `fontFamily.orElse(null)`. */ + fun fontFamily(fontFamily: Optional) = fontFamily(fontFamily.getOrNull()) + + /** + * Sets [Builder.fontFamily] to an arbitrary JSON value. + * + * You should usually call [Builder.fontFamily] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun fontFamily(fontFamily: JsonField) = apply { this.fontFamily = fontFamily } + + fun placement(placement: Placement?) = placement(JsonField.ofNullable(placement)) + + /** Alias for calling [Builder.placement] with `placement.orElse(null)`. */ + fun placement(placement: Optional) = placement(placement.getOrNull()) + + /** + * Sets [Builder.placement] to an arbitrary JSON value. + * + * You should usually call [Builder.placement] with a well-typed [Placement] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun placement(placement: JsonField) = apply { this.placement = placement } + + 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 [BrandSettingsInApp]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .colors() + * .icons() + * .widgetBackground() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): BrandSettingsInApp = + BrandSettingsInApp( + checkRequired("colors", colors), + checkRequired("icons", icons), + checkRequired("widgetBackground", widgetBackground), + borderRadius, + disableMessageIcon, + fontFamily, + placement, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): BrandSettingsInApp = apply { + if (validated) { + return@apply + } + + colors().validate() + icons().validate() + widgetBackground().validate() + borderRadius() + disableMessageIcon() + fontFamily() + placement().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (colors.asKnown().getOrNull()?.validity() ?: 0) + + (icons.asKnown().getOrNull()?.validity() ?: 0) + + (widgetBackground.asKnown().getOrNull()?.validity() ?: 0) + + (if (borderRadius.asKnown().isPresent) 1 else 0) + + (if (disableMessageIcon.asKnown().isPresent) 1 else 0) + + (if (fontFamily.asKnown().isPresent) 1 else 0) + + (placement.asKnown().getOrNull()?.validity() ?: 0) + + class Placement @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 TOP = of("top") + + @JvmField val BOTTOM = of("bottom") + + @JvmField val LEFT = of("left") + + @JvmField val RIGHT = of("right") + + @JvmStatic fun of(value: String) = Placement(JsonField.of(value)) + } + + /** An enum containing [Placement]'s known values. */ + enum class Known { + TOP, + BOTTOM, + LEFT, + RIGHT, + } + + /** + * An enum containing [Placement]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Placement] 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 { + TOP, + BOTTOM, + LEFT, + RIGHT, + /** + * An enum member indicating that [Placement] 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) { + TOP -> Value.TOP + BOTTOM -> Value.BOTTOM + LEFT -> Value.LEFT + RIGHT -> Value.RIGHT + 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 CourierInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + TOP -> Known.TOP + BOTTOM -> Known.BOTTOM + LEFT -> Known.LEFT + RIGHT -> Known.RIGHT + else -> throw CourierInvalidDataException("Unknown Placement: $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 CourierInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { CourierInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + fun validate(): Placement = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Placement && 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 BrandSettingsInApp && + colors == other.colors && + icons == other.icons && + widgetBackground == other.widgetBackground && + borderRadius == other.borderRadius && + disableMessageIcon == other.disableMessageIcon && + fontFamily == other.fontFamily && + placement == other.placement && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + colors, + icons, + widgetBackground, + borderRadius, + disableMessageIcon, + fontFamily, + placement, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "BrandSettingsInApp{colors=$colors, icons=$icons, widgetBackground=$widgetBackground, borderRadius=$borderRadius, disableMessageIcon=$disableMessageIcon, fontFamily=$fontFamily, placement=$placement, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/brands/BrandSnippet.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/brands/BrandSnippet.kt new file mode 100644 index 00000000..6bdb99f1 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/brands/BrandSnippet.kt @@ -0,0 +1,204 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.brands + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkRequired +import com.courier.api.errors.CourierInvalidDataException +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 + +class BrandSnippet +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val name: JsonField, + private val value: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("value") @ExcludeMissing value: JsonField = JsonMissing.of(), + ) : this(name, value, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 name(): String = name.getRequired("name") + + /** + * @throws CourierInvalidDataException 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 value(): String = value.getRequired("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 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 [BrandSnippet]. + * + * The following fields are required: + * ```java + * .name() + * .value() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [BrandSnippet]. */ + class Builder internal constructor() { + + private var name: JsonField? = null + private var value: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(brandSnippet: BrandSnippet) = apply { + name = brandSnippet.name + value = brandSnippet.value + additionalProperties = brandSnippet.additionalProperties.toMutableMap() + } + + 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 } + + fun value(value: String) = value(JsonField.of(value)) + + /** + * Sets [Builder.value] to an arbitrary JSON value. + * + * You should usually call [Builder.value] 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 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 [BrandSnippet]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .name() + * .value() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): BrandSnippet = + BrandSnippet( + checkRequired("name", name), + checkRequired("value", value), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): BrandSnippet = apply { + if (validated) { + return@apply + } + + name() + value() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (value.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is BrandSnippet && + name == other.name && + value == other.value && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(name, value, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "BrandSnippet{name=$name, value=$value, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/brands/BrandSnippets.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/brands/BrandSnippets.kt new file mode 100644 index 00000000..e60f2af3 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/brands/BrandSnippets.kt @@ -0,0 +1,179 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.brands + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkKnown +import com.courier.api.core.toImmutable +import com.courier.api.errors.CourierInvalidDataException +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 BrandSnippets +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val items: JsonField>, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("items") + @ExcludeMissing + items: JsonField> = JsonMissing.of() + ) : this(items, mutableMapOf()) + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun items(): Optional> = items.getOptional("items") + + /** + * Returns the raw JSON value of [items]. + * + * Unlike [items], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("items") @ExcludeMissing fun _items(): JsonField> = items + + @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 [BrandSnippets]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [BrandSnippets]. */ + class Builder internal constructor() { + + private var items: JsonField>? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(brandSnippets: BrandSnippets) = apply { + items = brandSnippets.items.map { it.toMutableList() } + additionalProperties = brandSnippets.additionalProperties.toMutableMap() + } + + fun items(items: List?) = items(JsonField.ofNullable(items)) + + /** Alias for calling [Builder.items] with `items.orElse(null)`. */ + fun items(items: Optional>) = items(items.getOrNull()) + + /** + * Sets [Builder.items] to an arbitrary JSON value. + * + * You should usually call [Builder.items] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun items(items: JsonField>) = apply { + this.items = items.map { it.toMutableList() } + } + + /** + * Adds a single [BrandSnippet] to [items]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addItem(item: BrandSnippet) = apply { + items = + (items ?: JsonField.of(mutableListOf())).also { checkKnown("items", it).add(item) } + } + + 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 [BrandSnippets]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): BrandSnippets = + BrandSnippets( + (items ?: JsonMissing.of()).map { it.toImmutable() }, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): BrandSnippets = apply { + if (validated) { + return@apply + } + + items().ifPresent { it.forEach { it.validate() } } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (items.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is BrandSnippets && + items == other.items && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(items, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "BrandSnippets{items=$items, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/brands/BrandTemplate.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/brands/BrandTemplate.kt new file mode 100644 index 00000000..1e6ee975 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/brands/BrandTemplate.kt @@ -0,0 +1,421 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.brands + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkRequired +import com.courier.api.errors.CourierInvalidDataException +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 BrandTemplate +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val enabled: JsonField, + private val backgroundColor: JsonField, + private val blocksBackgroundColor: JsonField, + private val footer: JsonField, + private val head: JsonField, + private val header: JsonField, + private val width: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("enabled") @ExcludeMissing enabled: JsonField = JsonMissing.of(), + @JsonProperty("backgroundColor") + @ExcludeMissing + backgroundColor: JsonField = JsonMissing.of(), + @JsonProperty("blocksBackgroundColor") + @ExcludeMissing + blocksBackgroundColor: JsonField = JsonMissing.of(), + @JsonProperty("footer") @ExcludeMissing footer: JsonField = JsonMissing.of(), + @JsonProperty("head") @ExcludeMissing head: JsonField = JsonMissing.of(), + @JsonProperty("header") @ExcludeMissing header: JsonField = JsonMissing.of(), + @JsonProperty("width") @ExcludeMissing width: JsonField = JsonMissing.of(), + ) : this( + enabled, + backgroundColor, + blocksBackgroundColor, + footer, + head, + header, + width, + mutableMapOf(), + ) + + /** + * @throws CourierInvalidDataException 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 enabled(): Boolean = enabled.getRequired("enabled") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun backgroundColor(): Optional = backgroundColor.getOptional("backgroundColor") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun blocksBackgroundColor(): Optional = + blocksBackgroundColor.getOptional("blocksBackgroundColor") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun footer(): Optional = footer.getOptional("footer") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun head(): Optional = head.getOptional("head") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun header(): Optional = header.getOptional("header") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun width(): Optional = width.getOptional("width") + + /** + * Returns the raw JSON value of [enabled]. + * + * Unlike [enabled], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("enabled") @ExcludeMissing fun _enabled(): JsonField = enabled + + /** + * Returns the raw JSON value of [backgroundColor]. + * + * Unlike [backgroundColor], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("backgroundColor") + @ExcludeMissing + fun _backgroundColor(): JsonField = backgroundColor + + /** + * Returns the raw JSON value of [blocksBackgroundColor]. + * + * Unlike [blocksBackgroundColor], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("blocksBackgroundColor") + @ExcludeMissing + fun _blocksBackgroundColor(): JsonField = blocksBackgroundColor + + /** + * Returns the raw JSON value of [footer]. + * + * Unlike [footer], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("footer") @ExcludeMissing fun _footer(): JsonField = footer + + /** + * Returns the raw JSON value of [head]. + * + * Unlike [head], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("head") @ExcludeMissing fun _head(): JsonField = head + + /** + * Returns the raw JSON value of [header]. + * + * Unlike [header], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("header") @ExcludeMissing fun _header(): JsonField = header + + /** + * Returns the raw JSON value of [width]. + * + * Unlike [width], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("width") @ExcludeMissing fun _width(): JsonField = width + + @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 [BrandTemplate]. + * + * The following fields are required: + * ```java + * .enabled() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [BrandTemplate]. */ + class Builder internal constructor() { + + private var enabled: JsonField? = null + private var backgroundColor: JsonField = JsonMissing.of() + private var blocksBackgroundColor: JsonField = JsonMissing.of() + private var footer: JsonField = JsonMissing.of() + private var head: JsonField = JsonMissing.of() + private var header: JsonField = JsonMissing.of() + private var width: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(brandTemplate: BrandTemplate) = apply { + enabled = brandTemplate.enabled + backgroundColor = brandTemplate.backgroundColor + blocksBackgroundColor = brandTemplate.blocksBackgroundColor + footer = brandTemplate.footer + head = brandTemplate.head + header = brandTemplate.header + width = brandTemplate.width + additionalProperties = brandTemplate.additionalProperties.toMutableMap() + } + + fun enabled(enabled: Boolean) = enabled(JsonField.of(enabled)) + + /** + * Sets [Builder.enabled] to an arbitrary JSON value. + * + * You should usually call [Builder.enabled] with a well-typed [Boolean] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun enabled(enabled: JsonField) = apply { this.enabled = enabled } + + fun backgroundColor(backgroundColor: String?) = + backgroundColor(JsonField.ofNullable(backgroundColor)) + + /** Alias for calling [Builder.backgroundColor] with `backgroundColor.orElse(null)`. */ + fun backgroundColor(backgroundColor: Optional) = + backgroundColor(backgroundColor.getOrNull()) + + /** + * Sets [Builder.backgroundColor] to an arbitrary JSON value. + * + * You should usually call [Builder.backgroundColor] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun backgroundColor(backgroundColor: JsonField) = apply { + this.backgroundColor = backgroundColor + } + + fun blocksBackgroundColor(blocksBackgroundColor: String?) = + blocksBackgroundColor(JsonField.ofNullable(blocksBackgroundColor)) + + /** + * Alias for calling [Builder.blocksBackgroundColor] with + * `blocksBackgroundColor.orElse(null)`. + */ + fun blocksBackgroundColor(blocksBackgroundColor: Optional) = + blocksBackgroundColor(blocksBackgroundColor.getOrNull()) + + /** + * Sets [Builder.blocksBackgroundColor] to an arbitrary JSON value. + * + * You should usually call [Builder.blocksBackgroundColor] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun blocksBackgroundColor(blocksBackgroundColor: JsonField) = apply { + this.blocksBackgroundColor = blocksBackgroundColor + } + + fun footer(footer: String?) = footer(JsonField.ofNullable(footer)) + + /** Alias for calling [Builder.footer] with `footer.orElse(null)`. */ + fun footer(footer: Optional) = footer(footer.getOrNull()) + + /** + * Sets [Builder.footer] to an arbitrary JSON value. + * + * You should usually call [Builder.footer] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun footer(footer: JsonField) = apply { this.footer = footer } + + fun head(head: String?) = head(JsonField.ofNullable(head)) + + /** Alias for calling [Builder.head] with `head.orElse(null)`. */ + fun head(head: Optional) = head(head.getOrNull()) + + /** + * Sets [Builder.head] to an arbitrary JSON value. + * + * You should usually call [Builder.head] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun head(head: JsonField) = apply { this.head = head } + + fun header(header: String?) = header(JsonField.ofNullable(header)) + + /** Alias for calling [Builder.header] with `header.orElse(null)`. */ + fun header(header: Optional) = header(header.getOrNull()) + + /** + * Sets [Builder.header] to an arbitrary JSON value. + * + * You should usually call [Builder.header] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun header(header: JsonField) = apply { this.header = header } + + fun width(width: String?) = width(JsonField.ofNullable(width)) + + /** Alias for calling [Builder.width] with `width.orElse(null)`. */ + fun width(width: Optional) = width(width.getOrNull()) + + /** + * Sets [Builder.width] to an arbitrary JSON value. + * + * You should usually call [Builder.width] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun width(width: JsonField) = apply { this.width = width } + + 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 [BrandTemplate]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .enabled() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): BrandTemplate = + BrandTemplate( + checkRequired("enabled", enabled), + backgroundColor, + blocksBackgroundColor, + footer, + head, + header, + width, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): BrandTemplate = apply { + if (validated) { + return@apply + } + + enabled() + backgroundColor() + blocksBackgroundColor() + footer() + head() + header() + width() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (enabled.asKnown().isPresent) 1 else 0) + + (if (backgroundColor.asKnown().isPresent) 1 else 0) + + (if (blocksBackgroundColor.asKnown().isPresent) 1 else 0) + + (if (footer.asKnown().isPresent) 1 else 0) + + (if (head.asKnown().isPresent) 1 else 0) + + (if (header.asKnown().isPresent) 1 else 0) + + (if (width.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is BrandTemplate && + enabled == other.enabled && + backgroundColor == other.backgroundColor && + blocksBackgroundColor == other.blocksBackgroundColor && + footer == other.footer && + head == other.head && + header == other.header && + width == other.width && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + enabled, + backgroundColor, + blocksBackgroundColor, + footer, + head, + header, + width, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "BrandTemplate{enabled=$enabled, backgroundColor=$backgroundColor, blocksBackgroundColor=$blocksBackgroundColor, footer=$footer, head=$head, header=$header, width=$width, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/brands/BrandUpdateParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/brands/BrandUpdateParams.kt new file mode 100644 index 00000000..491dbdd5 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/brands/BrandUpdateParams.kt @@ -0,0 +1,577 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.brands + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.Params +import com.courier.api.core.checkRequired +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import com.courier.api.errors.CourierInvalidDataException +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 + +/** Replace an existing brand with the supplied values. */ +class BrandUpdateParams +private constructor( + private val brandId: String?, + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun brandId(): Optional = Optional.ofNullable(brandId) + + /** + * The name of the brand. + * + * @throws CourierInvalidDataException 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 name(): String = body.name() + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun settings(): Optional = body.settings() + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun snippets(): Optional = body.snippets() + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _name(): JsonField = body._name() + + /** + * Returns the raw JSON value of [settings]. + * + * Unlike [settings], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _settings(): JsonField = body._settings() + + /** + * Returns the raw JSON value of [snippets]. + * + * Unlike [snippets], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _snippets(): JsonField = body._snippets() + + 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 [BrandUpdateParams]. + * + * The following fields are required: + * ```java + * .name() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [BrandUpdateParams]. */ + class Builder internal constructor() { + + private var brandId: 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(brandUpdateParams: BrandUpdateParams) = apply { + brandId = brandUpdateParams.brandId + body = brandUpdateParams.body.toBuilder() + additionalHeaders = brandUpdateParams.additionalHeaders.toBuilder() + additionalQueryParams = brandUpdateParams.additionalQueryParams.toBuilder() + } + + fun brandId(brandId: String?) = apply { this.brandId = brandId } + + /** Alias for calling [Builder.brandId] with `brandId.orElse(null)`. */ + fun brandId(brandId: Optional) = brandId(brandId.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: + * - [name] + * - [settings] + * - [snippets] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + /** The name of the brand. */ + fun name(name: String) = apply { body.name(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 { body.name(name) } + + fun settings(settings: BrandSettings?) = apply { body.settings(settings) } + + /** Alias for calling [Builder.settings] with `settings.orElse(null)`. */ + fun settings(settings: Optional) = settings(settings.getOrNull()) + + /** + * Sets [Builder.settings] to an arbitrary JSON value. + * + * You should usually call [Builder.settings] with a well-typed [BrandSettings] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun settings(settings: JsonField) = apply { body.settings(settings) } + + fun snippets(snippets: BrandSnippets?) = apply { body.snippets(snippets) } + + /** Alias for calling [Builder.snippets] with `snippets.orElse(null)`. */ + fun snippets(snippets: Optional) = snippets(snippets.getOrNull()) + + /** + * Sets [Builder.snippets] to an arbitrary JSON value. + * + * You should usually call [Builder.snippets] with a well-typed [BrandSnippets] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun snippets(snippets: JsonField) = apply { body.snippets(snippets) } + + 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 [BrandUpdateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .name() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): BrandUpdateParams = + BrandUpdateParams( + brandId, + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): Body = body + + fun _pathParam(index: Int): String = + when (index) { + 0 -> brandId ?: "" + else -> "" + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + class Body + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val name: JsonField, + private val settings: JsonField, + private val snippets: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("settings") + @ExcludeMissing + settings: JsonField = JsonMissing.of(), + @JsonProperty("snippets") + @ExcludeMissing + snippets: JsonField = JsonMissing.of(), + ) : this(name, settings, snippets, mutableMapOf()) + + /** + * The name of the brand. + * + * @throws CourierInvalidDataException 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 name(): String = name.getRequired("name") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun settings(): Optional = settings.getOptional("settings") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun snippets(): Optional = snippets.getOptional("snippets") + + /** + * 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 [settings]. + * + * Unlike [settings], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("settings") + @ExcludeMissing + fun _settings(): JsonField = settings + + /** + * Returns the raw JSON value of [snippets]. + * + * Unlike [snippets], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("snippets") + @ExcludeMissing + fun _snippets(): JsonField = snippets + + @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 + * .name() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var name: JsonField? = null + private var settings: JsonField = JsonMissing.of() + private var snippets: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + name = body.name + settings = body.settings + snippets = body.snippets + additionalProperties = body.additionalProperties.toMutableMap() + } + + /** The name of the brand. */ + 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 } + + fun settings(settings: BrandSettings?) = settings(JsonField.ofNullable(settings)) + + /** Alias for calling [Builder.settings] with `settings.orElse(null)`. */ + fun settings(settings: Optional) = settings(settings.getOrNull()) + + /** + * Sets [Builder.settings] to an arbitrary JSON value. + * + * You should usually call [Builder.settings] with a well-typed [BrandSettings] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun settings(settings: JsonField) = apply { this.settings = settings } + + fun snippets(snippets: BrandSnippets?) = snippets(JsonField.ofNullable(snippets)) + + /** Alias for calling [Builder.snippets] with `snippets.orElse(null)`. */ + fun snippets(snippets: Optional) = snippets(snippets.getOrNull()) + + /** + * Sets [Builder.snippets] to an arbitrary JSON value. + * + * You should usually call [Builder.snippets] with a well-typed [BrandSnippets] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun snippets(snippets: JsonField) = apply { this.snippets = snippets } + + 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 + * .name() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("name", name), + settings, + snippets, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + name() + settings().ifPresent { it.validate() } + snippets().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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) + + (settings.asKnown().getOrNull()?.validity() ?: 0) + + (snippets.asKnown().getOrNull()?.validity() ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + name == other.name && + settings == other.settings && + snippets == other.snippets && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(name, settings, snippets, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{name=$name, settings=$settings, snippets=$snippets, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is BrandUpdateParams && + brandId == other.brandId && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(brandId, body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "BrandUpdateParams{brandId=$brandId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/brands/EmailFooter.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/brands/EmailFooter.kt new file mode 100644 index 00000000..b491febf --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/brands/EmailFooter.kt @@ -0,0 +1,210 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.brands + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.errors.CourierInvalidDataException +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 EmailFooter +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val content: JsonField, + private val inheritDefault: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("content") @ExcludeMissing content: JsonField = JsonMissing.of(), + @JsonProperty("inheritDefault") + @ExcludeMissing + inheritDefault: JsonField = JsonMissing.of(), + ) : this(content, inheritDefault, mutableMapOf()) + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun content(): Optional = content.getOptional("content") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun inheritDefault(): Optional = inheritDefault.getOptional("inheritDefault") + + /** + * Returns the raw JSON value of [content]. + * + * Unlike [content], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("content") @ExcludeMissing fun _content(): JsonField = content + + /** + * Returns the raw JSON value of [inheritDefault]. + * + * Unlike [inheritDefault], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("inheritDefault") + @ExcludeMissing + fun _inheritDefault(): JsonField = inheritDefault + + @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 [EmailFooter]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [EmailFooter]. */ + class Builder internal constructor() { + + private var content: JsonField = JsonMissing.of() + private var inheritDefault: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(emailFooter: EmailFooter) = apply { + content = emailFooter.content + inheritDefault = emailFooter.inheritDefault + additionalProperties = emailFooter.additionalProperties.toMutableMap() + } + + fun content(content: String?) = content(JsonField.ofNullable(content)) + + /** Alias for calling [Builder.content] with `content.orElse(null)`. */ + fun content(content: Optional) = content(content.getOrNull()) + + /** + * Sets [Builder.content] to an arbitrary JSON value. + * + * You should usually call [Builder.content] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun content(content: JsonField) = apply { this.content = content } + + fun inheritDefault(inheritDefault: Boolean?) = + inheritDefault(JsonField.ofNullable(inheritDefault)) + + /** + * Alias for [Builder.inheritDefault]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun inheritDefault(inheritDefault: Boolean) = inheritDefault(inheritDefault as Boolean?) + + /** Alias for calling [Builder.inheritDefault] with `inheritDefault.orElse(null)`. */ + fun inheritDefault(inheritDefault: Optional) = + inheritDefault(inheritDefault.getOrNull()) + + /** + * Sets [Builder.inheritDefault] to an arbitrary JSON value. + * + * You should usually call [Builder.inheritDefault] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun inheritDefault(inheritDefault: JsonField) = apply { + this.inheritDefault = inheritDefault + } + + 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 [EmailFooter]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): EmailFooter = + EmailFooter(content, inheritDefault, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): EmailFooter = apply { + if (validated) { + return@apply + } + + content() + inheritDefault() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (content.asKnown().isPresent) 1 else 0) + + (if (inheritDefault.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is EmailFooter && + content == other.content && + inheritDefault == other.inheritDefault && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(content, inheritDefault, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "EmailFooter{content=$content, inheritDefault=$inheritDefault, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/brands/EmailHead.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/brands/EmailHead.kt new file mode 100644 index 00000000..87b6f146 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/brands/EmailHead.kt @@ -0,0 +1,217 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.brands + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkRequired +import com.courier.api.errors.CourierInvalidDataException +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 EmailHead +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val inheritDefault: JsonField, + private val content: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("inheritDefault") + @ExcludeMissing + inheritDefault: JsonField = JsonMissing.of(), + @JsonProperty("content") @ExcludeMissing content: JsonField = JsonMissing.of(), + ) : this(inheritDefault, content, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 inheritDefault(): Boolean = inheritDefault.getRequired("inheritDefault") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun content(): Optional = content.getOptional("content") + + /** + * Returns the raw JSON value of [inheritDefault]. + * + * Unlike [inheritDefault], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("inheritDefault") + @ExcludeMissing + fun _inheritDefault(): JsonField = inheritDefault + + /** + * Returns the raw JSON value of [content]. + * + * Unlike [content], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("content") @ExcludeMissing fun _content(): JsonField = content + + @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 [EmailHead]. + * + * The following fields are required: + * ```java + * .inheritDefault() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [EmailHead]. */ + class Builder internal constructor() { + + private var inheritDefault: JsonField? = null + private var content: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(emailHead: EmailHead) = apply { + inheritDefault = emailHead.inheritDefault + content = emailHead.content + additionalProperties = emailHead.additionalProperties.toMutableMap() + } + + fun inheritDefault(inheritDefault: Boolean) = inheritDefault(JsonField.of(inheritDefault)) + + /** + * Sets [Builder.inheritDefault] to an arbitrary JSON value. + * + * You should usually call [Builder.inheritDefault] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun inheritDefault(inheritDefault: JsonField) = apply { + this.inheritDefault = inheritDefault + } + + fun content(content: String?) = content(JsonField.ofNullable(content)) + + /** Alias for calling [Builder.content] with `content.orElse(null)`. */ + fun content(content: Optional) = content(content.getOrNull()) + + /** + * Sets [Builder.content] to an arbitrary JSON value. + * + * You should usually call [Builder.content] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun content(content: JsonField) = apply { this.content = content } + + 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 [EmailHead]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .inheritDefault() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): EmailHead = + EmailHead( + checkRequired("inheritDefault", inheritDefault), + content, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): EmailHead = apply { + if (validated) { + return@apply + } + + inheritDefault() + content() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (inheritDefault.asKnown().isPresent) 1 else 0) + + (if (content.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is EmailHead && + inheritDefault == other.inheritDefault && + content == other.content && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(inheritDefault, content, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "EmailHead{inheritDefault=$inheritDefault, content=$content, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/brands/EmailHeader.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/brands/EmailHeader.kt new file mode 100644 index 00000000..13650f72 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/brands/EmailHeader.kt @@ -0,0 +1,260 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.brands + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkRequired +import com.courier.api.errors.CourierInvalidDataException +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 EmailHeader +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val logo: JsonField, + private val barColor: JsonField, + private val inheritDefault: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("logo") @ExcludeMissing logo: JsonField = JsonMissing.of(), + @JsonProperty("barColor") @ExcludeMissing barColor: JsonField = JsonMissing.of(), + @JsonProperty("inheritDefault") + @ExcludeMissing + inheritDefault: JsonField = JsonMissing.of(), + ) : this(logo, barColor, inheritDefault, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 logo(): Logo = logo.getRequired("logo") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun barColor(): Optional = barColor.getOptional("barColor") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun inheritDefault(): Optional = inheritDefault.getOptional("inheritDefault") + + /** + * Returns the raw JSON value of [logo]. + * + * Unlike [logo], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("logo") @ExcludeMissing fun _logo(): JsonField = logo + + /** + * Returns the raw JSON value of [barColor]. + * + * Unlike [barColor], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("barColor") @ExcludeMissing fun _barColor(): JsonField = barColor + + /** + * Returns the raw JSON value of [inheritDefault]. + * + * Unlike [inheritDefault], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("inheritDefault") + @ExcludeMissing + fun _inheritDefault(): JsonField = inheritDefault + + @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 [EmailHeader]. + * + * The following fields are required: + * ```java + * .logo() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [EmailHeader]. */ + class Builder internal constructor() { + + private var logo: JsonField? = null + private var barColor: JsonField = JsonMissing.of() + private var inheritDefault: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(emailHeader: EmailHeader) = apply { + logo = emailHeader.logo + barColor = emailHeader.barColor + inheritDefault = emailHeader.inheritDefault + additionalProperties = emailHeader.additionalProperties.toMutableMap() + } + + fun logo(logo: Logo) = logo(JsonField.of(logo)) + + /** + * Sets [Builder.logo] to an arbitrary JSON value. + * + * You should usually call [Builder.logo] with a well-typed [Logo] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun logo(logo: JsonField) = apply { this.logo = logo } + + fun barColor(barColor: String?) = barColor(JsonField.ofNullable(barColor)) + + /** Alias for calling [Builder.barColor] with `barColor.orElse(null)`. */ + fun barColor(barColor: Optional) = barColor(barColor.getOrNull()) + + /** + * Sets [Builder.barColor] to an arbitrary JSON value. + * + * You should usually call [Builder.barColor] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun barColor(barColor: JsonField) = apply { this.barColor = barColor } + + fun inheritDefault(inheritDefault: Boolean?) = + inheritDefault(JsonField.ofNullable(inheritDefault)) + + /** + * Alias for [Builder.inheritDefault]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun inheritDefault(inheritDefault: Boolean) = inheritDefault(inheritDefault as Boolean?) + + /** Alias for calling [Builder.inheritDefault] with `inheritDefault.orElse(null)`. */ + fun inheritDefault(inheritDefault: Optional) = + inheritDefault(inheritDefault.getOrNull()) + + /** + * Sets [Builder.inheritDefault] to an arbitrary JSON value. + * + * You should usually call [Builder.inheritDefault] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun inheritDefault(inheritDefault: JsonField) = apply { + this.inheritDefault = inheritDefault + } + + 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 [EmailHeader]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .logo() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): EmailHeader = + EmailHeader( + checkRequired("logo", logo), + barColor, + inheritDefault, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): EmailHeader = apply { + if (validated) { + return@apply + } + + logo().validate() + barColor() + inheritDefault() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (logo.asKnown().getOrNull()?.validity() ?: 0) + + (if (barColor.asKnown().isPresent) 1 else 0) + + (if (inheritDefault.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is EmailHeader && + logo == other.logo && + barColor == other.barColor && + inheritDefault == other.inheritDefault && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(logo, barColor, inheritDefault, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "EmailHeader{logo=$logo, barColor=$barColor, inheritDefault=$inheritDefault, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/brands/Icons.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/brands/Icons.kt new file mode 100644 index 00000000..ba02403b --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/brands/Icons.kt @@ -0,0 +1,190 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.brands + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.errors.CourierInvalidDataException +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 Icons +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val bell: JsonField, + private val message: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("bell") @ExcludeMissing bell: JsonField = JsonMissing.of(), + @JsonProperty("message") @ExcludeMissing message: JsonField = JsonMissing.of(), + ) : this(bell, message, mutableMapOf()) + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun bell(): Optional = bell.getOptional("bell") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun message(): Optional = message.getOptional("message") + + /** + * Returns the raw JSON value of [bell]. + * + * Unlike [bell], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("bell") @ExcludeMissing fun _bell(): JsonField = bell + + /** + * Returns the raw JSON value of [message]. + * + * Unlike [message], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("message") @ExcludeMissing fun _message(): JsonField = message + + @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 [Icons]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Icons]. */ + class Builder internal constructor() { + + private var bell: JsonField = JsonMissing.of() + private var message: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(icons: Icons) = apply { + bell = icons.bell + message = icons.message + additionalProperties = icons.additionalProperties.toMutableMap() + } + + fun bell(bell: String?) = bell(JsonField.ofNullable(bell)) + + /** Alias for calling [Builder.bell] with `bell.orElse(null)`. */ + fun bell(bell: Optional) = bell(bell.getOrNull()) + + /** + * Sets [Builder.bell] to an arbitrary JSON value. + * + * You should usually call [Builder.bell] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun bell(bell: JsonField) = apply { this.bell = bell } + + fun message(message: String?) = message(JsonField.ofNullable(message)) + + /** Alias for calling [Builder.message] with `message.orElse(null)`. */ + fun message(message: Optional) = message(message.getOrNull()) + + /** + * Sets [Builder.message] to an arbitrary JSON value. + * + * You should usually call [Builder.message] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun message(message: JsonField) = apply { this.message = message } + + 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 [Icons]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Icons = Icons(bell, message, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Icons = apply { + if (validated) { + return@apply + } + + bell() + message() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (bell.asKnown().isPresent) 1 else 0) + (if (message.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Icons && + bell == other.bell && + message == other.message && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(bell, message, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Icons{bell=$bell, message=$message, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/brands/Logo.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/brands/Logo.kt new file mode 100644 index 00000000..291bcab0 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/brands/Logo.kt @@ -0,0 +1,190 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.brands + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.errors.CourierInvalidDataException +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 Logo +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val href: JsonField, + private val image: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("href") @ExcludeMissing href: JsonField = JsonMissing.of(), + @JsonProperty("image") @ExcludeMissing image: JsonField = JsonMissing.of(), + ) : this(href, image, mutableMapOf()) + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun href(): Optional = href.getOptional("href") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun image(): Optional = image.getOptional("image") + + /** + * Returns the raw JSON value of [href]. + * + * Unlike [href], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("href") @ExcludeMissing fun _href(): JsonField = href + + /** + * Returns the raw JSON value of [image]. + * + * Unlike [image], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("image") @ExcludeMissing fun _image(): JsonField = image + + @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 [Logo]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Logo]. */ + class Builder internal constructor() { + + private var href: JsonField = JsonMissing.of() + private var image: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(logo: Logo) = apply { + href = logo.href + image = logo.image + additionalProperties = logo.additionalProperties.toMutableMap() + } + + fun href(href: String?) = href(JsonField.ofNullable(href)) + + /** Alias for calling [Builder.href] with `href.orElse(null)`. */ + fun href(href: Optional) = href(href.getOrNull()) + + /** + * Sets [Builder.href] to an arbitrary JSON value. + * + * You should usually call [Builder.href] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun href(href: JsonField) = apply { this.href = href } + + fun image(image: String?) = image(JsonField.ofNullable(image)) + + /** Alias for calling [Builder.image] with `image.orElse(null)`. */ + fun image(image: Optional) = image(image.getOrNull()) + + /** + * Sets [Builder.image] to an arbitrary JSON value. + * + * You should usually call [Builder.image] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun image(image: JsonField) = apply { this.image = image } + + 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 [Logo]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Logo = Logo(href, image, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Logo = apply { + if (validated) { + return@apply + } + + href() + image() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (href.asKnown().isPresent) 1 else 0) + (if (image.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Logo && + href == other.href && + image == other.image && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(href, image, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Logo{href=$href, image=$image, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/brands/WidgetBackground.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/brands/WidgetBackground.kt new file mode 100644 index 00000000..827dfda6 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/brands/WidgetBackground.kt @@ -0,0 +1,195 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.brands + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.errors.CourierInvalidDataException +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 WidgetBackground +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val bottomColor: JsonField, + private val topColor: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("bottomColor") + @ExcludeMissing + bottomColor: JsonField = JsonMissing.of(), + @JsonProperty("topColor") @ExcludeMissing topColor: JsonField = JsonMissing.of(), + ) : this(bottomColor, topColor, mutableMapOf()) + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun bottomColor(): Optional = bottomColor.getOptional("bottomColor") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun topColor(): Optional = topColor.getOptional("topColor") + + /** + * Returns the raw JSON value of [bottomColor]. + * + * Unlike [bottomColor], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("bottomColor") @ExcludeMissing fun _bottomColor(): JsonField = bottomColor + + /** + * Returns the raw JSON value of [topColor]. + * + * Unlike [topColor], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("topColor") @ExcludeMissing fun _topColor(): JsonField = topColor + + @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 [WidgetBackground]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [WidgetBackground]. */ + class Builder internal constructor() { + + private var bottomColor: JsonField = JsonMissing.of() + private var topColor: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(widgetBackground: WidgetBackground) = apply { + bottomColor = widgetBackground.bottomColor + topColor = widgetBackground.topColor + additionalProperties = widgetBackground.additionalProperties.toMutableMap() + } + + fun bottomColor(bottomColor: String?) = bottomColor(JsonField.ofNullable(bottomColor)) + + /** Alias for calling [Builder.bottomColor] with `bottomColor.orElse(null)`. */ + fun bottomColor(bottomColor: Optional) = bottomColor(bottomColor.getOrNull()) + + /** + * Sets [Builder.bottomColor] to an arbitrary JSON value. + * + * You should usually call [Builder.bottomColor] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun bottomColor(bottomColor: JsonField) = apply { this.bottomColor = bottomColor } + + fun topColor(topColor: String?) = topColor(JsonField.ofNullable(topColor)) + + /** Alias for calling [Builder.topColor] with `topColor.orElse(null)`. */ + fun topColor(topColor: Optional) = topColor(topColor.getOrNull()) + + /** + * Sets [Builder.topColor] to an arbitrary JSON value. + * + * You should usually call [Builder.topColor] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun topColor(topColor: JsonField) = apply { this.topColor = topColor } + + 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 [WidgetBackground]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): WidgetBackground = + WidgetBackground(bottomColor, topColor, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): WidgetBackground = apply { + if (validated) { + return@apply + } + + bottomColor() + topColor() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (bottomColor.asKnown().isPresent) 1 else 0) + + (if (topColor.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is WidgetBackground && + bottomColor == other.bottomColor && + topColor == other.topColor && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(bottomColor, topColor, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "WidgetBackground{bottomColor=$bottomColor, topColor=$topColor, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/bulk/BulkAddUsersParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/bulk/BulkAddUsersParams.kt new file mode 100644 index 00000000..8dcca0d7 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/bulk/BulkAddUsersParams.kt @@ -0,0 +1,462 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.bulk + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.Params +import com.courier.api.core.checkKnown +import com.courier.api.core.checkRequired +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import com.courier.api.core.toImmutable +import com.courier.api.errors.CourierInvalidDataException +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 + +/** Ingest user data into a Bulk Job */ +class BulkAddUsersParams +private constructor( + private val jobId: String?, + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun jobId(): Optional = Optional.ofNullable(jobId) + + /** + * @throws CourierInvalidDataException 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 users(): List = body.users() + + /** + * Returns the raw JSON value of [users]. + * + * Unlike [users], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _users(): JsonField> = body._users() + + 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 [BulkAddUsersParams]. + * + * The following fields are required: + * ```java + * .users() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [BulkAddUsersParams]. */ + class Builder internal constructor() { + + private var jobId: 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(bulkAddUsersParams: BulkAddUsersParams) = apply { + jobId = bulkAddUsersParams.jobId + body = bulkAddUsersParams.body.toBuilder() + additionalHeaders = bulkAddUsersParams.additionalHeaders.toBuilder() + additionalQueryParams = bulkAddUsersParams.additionalQueryParams.toBuilder() + } + + fun jobId(jobId: String?) = apply { this.jobId = jobId } + + /** Alias for calling [Builder.jobId] with `jobId.orElse(null)`. */ + fun jobId(jobId: Optional) = jobId(jobId.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: + * - [users] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + fun users(users: List) = apply { body.users(users) } + + /** + * Sets [Builder.users] to an arbitrary JSON value. + * + * You should usually call [Builder.users] with a well-typed `List` + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun users(users: JsonField>) = apply { body.users(users) } + + /** + * Adds a single [InboundBulkMessageUser] to [users]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addUser(user: InboundBulkMessageUser) = apply { body.addUser(user) } + + 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 [BulkAddUsersParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .users() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): BulkAddUsersParams = + BulkAddUsersParams( + jobId, + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): Body = body + + fun _pathParam(index: Int): String = + when (index) { + 0 -> jobId ?: "" + else -> "" + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + class Body + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val users: JsonField>, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("users") + @ExcludeMissing + users: JsonField> = JsonMissing.of() + ) : this(users, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 users(): List = users.getRequired("users") + + /** + * Returns the raw JSON value of [users]. + * + * Unlike [users], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("users") + @ExcludeMissing + fun _users(): JsonField> = users + + @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 + * .users() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var users: JsonField>? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + users = body.users.map { it.toMutableList() } + additionalProperties = body.additionalProperties.toMutableMap() + } + + fun users(users: List) = users(JsonField.of(users)) + + /** + * Sets [Builder.users] to an arbitrary JSON value. + * + * You should usually call [Builder.users] with a well-typed + * `List` value instead. This method is primarily for setting + * the field to an undocumented or not yet supported value. + */ + fun users(users: JsonField>) = apply { + this.users = users.map { it.toMutableList() } + } + + /** + * Adds a single [InboundBulkMessageUser] to [users]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addUser(user: InboundBulkMessageUser) = apply { + users = + (users ?: JsonField.of(mutableListOf())).also { + checkKnown("users", it).add(user) + } + } + + 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 + * .users() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("users", users).map { it.toImmutable() }, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + users().forEach { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (users.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + users == other.users && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(users, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Body{users=$users, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is BulkAddUsersParams && + jobId == other.jobId && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(jobId, body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "BulkAddUsersParams{jobId=$jobId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/bulk/BulkCreateJobParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/bulk/BulkCreateJobParams.kt new file mode 100644 index 00000000..50939acb --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/bulk/BulkCreateJobParams.kt @@ -0,0 +1,434 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.bulk + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.Params +import com.courier.api.core.checkRequired +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import com.courier.api.errors.CourierInvalidDataException +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 kotlin.jvm.optionals.getOrNull + +/** Create a bulk job */ +class BulkCreateJobParams +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * @throws CourierInvalidDataException 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 message(): InboundBulkMessage = body.message() + + /** + * Returns the raw JSON value of [message]. + * + * Unlike [message], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _message(): JsonField = body._message() + + 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 [BulkCreateJobParams]. + * + * The following fields are required: + * ```java + * .message() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [BulkCreateJobParams]. */ + 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(bulkCreateJobParams: BulkCreateJobParams) = apply { + body = bulkCreateJobParams.body.toBuilder() + additionalHeaders = bulkCreateJobParams.additionalHeaders.toBuilder() + additionalQueryParams = bulkCreateJobParams.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: + * - [message] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + fun message(message: InboundBulkMessage) = apply { body.message(message) } + + /** + * Sets [Builder.message] to an arbitrary JSON value. + * + * You should usually call [Builder.message] with a well-typed [InboundBulkMessage] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun message(message: JsonField) = apply { body.message(message) } + + /** Alias for calling [message] with `InboundBulkMessage.ofTemplate(template)`. */ + fun message(template: InboundBulkMessage.InboundBulkTemplateMessage) = apply { + body.message(template) + } + + /** Alias for calling [message] with `InboundBulkMessage.ofContent(content)`. */ + fun message(content: InboundBulkMessage.InboundBulkContentMessage) = apply { + body.message(content) + } + + 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 [BulkCreateJobParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .message() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): BulkCreateJobParams = + BulkCreateJobParams( + 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 message: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("message") + @ExcludeMissing + message: JsonField = JsonMissing.of() + ) : this(message, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 message(): InboundBulkMessage = message.getRequired("message") + + /** + * Returns the raw JSON value of [message]. + * + * Unlike [message], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("message") + @ExcludeMissing + fun _message(): JsonField = message + + @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 + * .message() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var message: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + message = body.message + additionalProperties = body.additionalProperties.toMutableMap() + } + + fun message(message: InboundBulkMessage) = message(JsonField.of(message)) + + /** + * Sets [Builder.message] to an arbitrary JSON value. + * + * You should usually call [Builder.message] with a well-typed [InboundBulkMessage] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun message(message: JsonField) = apply { this.message = message } + + /** Alias for calling [message] with `InboundBulkMessage.ofTemplate(template)`. */ + fun message(template: InboundBulkMessage.InboundBulkTemplateMessage) = + message(InboundBulkMessage.ofTemplate(template)) + + /** Alias for calling [message] with `InboundBulkMessage.ofContent(content)`. */ + fun message(content: InboundBulkMessage.InboundBulkContentMessage) = + message(InboundBulkMessage.ofContent(content)) + + 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 + * .message() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body(checkRequired("message", message), additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + message().validate() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = (message.asKnown().getOrNull()?.validity() ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + message == other.message && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(message, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{message=$message, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is BulkCreateJobParams && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = Objects.hash(body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "BulkCreateJobParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/bulk/BulkCreateJobResponse.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/bulk/BulkCreateJobResponse.kt new file mode 100644 index 00000000..d3535854 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/bulk/BulkCreateJobResponse.kt @@ -0,0 +1,170 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.bulk + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkRequired +import com.courier.api.errors.CourierInvalidDataException +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 + +class BulkCreateJobResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val jobId: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("jobId") @ExcludeMissing jobId: JsonField = JsonMissing.of() + ) : this(jobId, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 jobId(): String = jobId.getRequired("jobId") + + /** + * Returns the raw JSON value of [jobId]. + * + * Unlike [jobId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("jobId") @ExcludeMissing fun _jobId(): JsonField = jobId + + @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 [BulkCreateJobResponse]. + * + * The following fields are required: + * ```java + * .jobId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [BulkCreateJobResponse]. */ + class Builder internal constructor() { + + private var jobId: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(bulkCreateJobResponse: BulkCreateJobResponse) = apply { + jobId = bulkCreateJobResponse.jobId + additionalProperties = bulkCreateJobResponse.additionalProperties.toMutableMap() + } + + fun jobId(jobId: String) = jobId(JsonField.of(jobId)) + + /** + * Sets [Builder.jobId] to an arbitrary JSON value. + * + * You should usually call [Builder.jobId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun jobId(jobId: JsonField) = apply { this.jobId = jobId } + + 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 [BulkCreateJobResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .jobId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): BulkCreateJobResponse = + BulkCreateJobResponse( + checkRequired("jobId", jobId), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): BulkCreateJobResponse = apply { + if (validated) { + return@apply + } + + jobId() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (jobId.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is BulkCreateJobResponse && + jobId == other.jobId && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(jobId, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "BulkCreateJobResponse{jobId=$jobId, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/bulk/BulkListUsersParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/bulk/BulkListUsersParams.kt new file mode 100644 index 00000000..dbfe2ab0 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/bulk/BulkListUsersParams.kt @@ -0,0 +1,216 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.bulk + +import com.courier.api.core.Params +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Get Bulk Job Users */ +class BulkListUsersParams +private constructor( + private val jobId: String?, + private val cursor: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun jobId(): Optional = Optional.ofNullable(jobId) + + /** A unique identifier that allows for fetching the next set of users added to the bulk job */ + fun cursor(): Optional = Optional.ofNullable(cursor) + + /** 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(): BulkListUsersParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [BulkListUsersParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [BulkListUsersParams]. */ + class Builder internal constructor() { + + private var jobId: String? = null + private var cursor: String? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(bulkListUsersParams: BulkListUsersParams) = apply { + jobId = bulkListUsersParams.jobId + cursor = bulkListUsersParams.cursor + additionalHeaders = bulkListUsersParams.additionalHeaders.toBuilder() + additionalQueryParams = bulkListUsersParams.additionalQueryParams.toBuilder() + } + + fun jobId(jobId: String?) = apply { this.jobId = jobId } + + /** Alias for calling [Builder.jobId] with `jobId.orElse(null)`. */ + fun jobId(jobId: Optional) = jobId(jobId.getOrNull()) + + /** + * A unique identifier that allows for fetching the next set of users added to the bulk job + */ + fun cursor(cursor: String?) = apply { this.cursor = cursor } + + /** Alias for calling [Builder.cursor] with `cursor.orElse(null)`. */ + fun cursor(cursor: Optional) = cursor(cursor.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 [BulkListUsersParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): BulkListUsersParams = + BulkListUsersParams( + jobId, + cursor, + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _pathParam(index: Int): String = + when (index) { + 0 -> jobId ?: "" + else -> "" + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + cursor?.let { put("cursor", it) } + putAll(additionalQueryParams) + } + .build() + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is BulkListUsersParams && + jobId == other.jobId && + cursor == other.cursor && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(jobId, cursor, additionalHeaders, additionalQueryParams) + + override fun toString() = + "BulkListUsersParams{jobId=$jobId, cursor=$cursor, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/bulk/BulkListUsersResponse.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/bulk/BulkListUsersResponse.kt new file mode 100644 index 00000000..7647e244 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/bulk/BulkListUsersResponse.kt @@ -0,0 +1,710 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.bulk + +import com.courier.api.core.Enum +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkKnown +import com.courier.api.core.checkRequired +import com.courier.api.core.toImmutable +import com.courier.api.errors.CourierInvalidDataException +import com.courier.api.models.audiences.Paging +import com.courier.api.models.lists.subscriptions.RecipientPreferences +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 BulkListUsersResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val items: JsonField>, + private val paging: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("items") @ExcludeMissing items: JsonField> = JsonMissing.of(), + @JsonProperty("paging") @ExcludeMissing paging: JsonField = JsonMissing.of(), + ) : this(items, paging, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 items(): List = items.getRequired("items") + + /** + * @throws CourierInvalidDataException 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 paging(): Paging = paging.getRequired("paging") + + /** + * Returns the raw JSON value of [items]. + * + * Unlike [items], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("items") @ExcludeMissing fun _items(): JsonField> = items + + /** + * Returns the raw JSON value of [paging]. + * + * Unlike [paging], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("paging") @ExcludeMissing fun _paging(): JsonField = paging + + @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 [BulkListUsersResponse]. + * + * The following fields are required: + * ```java + * .items() + * .paging() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [BulkListUsersResponse]. */ + class Builder internal constructor() { + + private var items: JsonField>? = null + private var paging: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(bulkListUsersResponse: BulkListUsersResponse) = apply { + items = bulkListUsersResponse.items.map { it.toMutableList() } + paging = bulkListUsersResponse.paging + additionalProperties = bulkListUsersResponse.additionalProperties.toMutableMap() + } + + fun items(items: List) = items(JsonField.of(items)) + + /** + * Sets [Builder.items] to an arbitrary JSON value. + * + * You should usually call [Builder.items] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun items(items: JsonField>) = apply { + this.items = items.map { it.toMutableList() } + } + + /** + * Adds a single [Item] to [items]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addItem(item: Item) = apply { + items = + (items ?: JsonField.of(mutableListOf())).also { checkKnown("items", it).add(item) } + } + + fun paging(paging: Paging) = paging(JsonField.of(paging)) + + /** + * Sets [Builder.paging] to an arbitrary JSON value. + * + * You should usually call [Builder.paging] with a well-typed [Paging] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun paging(paging: JsonField) = apply { this.paging = paging } + + 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 [BulkListUsersResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .items() + * .paging() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): BulkListUsersResponse = + BulkListUsersResponse( + checkRequired("items", items).map { it.toImmutable() }, + checkRequired("paging", paging), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): BulkListUsersResponse = apply { + if (validated) { + return@apply + } + + items().forEach { it.validate() } + paging().validate() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (items.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (paging.asKnown().getOrNull()?.validity() ?: 0) + + class Item + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val data: JsonValue, + private val preferences: JsonField, + private val profile: JsonValue, + private val recipient: JsonField, + private val to: JsonField, + private val status: JsonField, + private val messageId: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("data") @ExcludeMissing data: JsonValue = JsonMissing.of(), + @JsonProperty("preferences") + @ExcludeMissing + preferences: JsonField = JsonMissing.of(), + @JsonProperty("profile") @ExcludeMissing profile: JsonValue = JsonMissing.of(), + @JsonProperty("recipient") + @ExcludeMissing + recipient: JsonField = JsonMissing.of(), + @JsonProperty("to") @ExcludeMissing to: JsonField = JsonMissing.of(), + @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(), + @JsonProperty("messageId") + @ExcludeMissing + messageId: JsonField = JsonMissing.of(), + ) : this(data, preferences, profile, recipient, to, status, messageId, mutableMapOf()) + + fun toInboundBulkMessageUser(): InboundBulkMessageUser = + InboundBulkMessageUser.builder() + .data(data) + .preferences(preferences) + .profile(profile) + .recipient(recipient) + .to(to) + .build() + + @JsonProperty("data") @ExcludeMissing fun _data(): JsonValue = data + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun preferences(): Optional = preferences.getOptional("preferences") + + @JsonProperty("profile") @ExcludeMissing fun _profile(): JsonValue = profile + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun recipient(): Optional = recipient.getOptional("recipient") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun to(): Optional = to.getOptional("to") + + /** + * @throws CourierInvalidDataException 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 status(): Status = status.getRequired("status") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun messageId(): Optional = messageId.getOptional("messageId") + + /** + * Returns the raw JSON value of [preferences]. + * + * Unlike [preferences], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("preferences") + @ExcludeMissing + fun _preferences(): JsonField = preferences + + /** + * Returns the raw JSON value of [recipient]. + * + * Unlike [recipient], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("recipient") @ExcludeMissing fun _recipient(): JsonField = recipient + + /** + * 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 + + /** + * 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 [messageId]. + * + * Unlike [messageId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("messageId") @ExcludeMissing fun _messageId(): JsonField = messageId + + @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 [Item]. + * + * The following fields are required: + * ```java + * .status() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Item]. */ + class Builder internal constructor() { + + private var data: JsonValue = JsonMissing.of() + private var preferences: JsonField = JsonMissing.of() + private var profile: JsonValue = JsonMissing.of() + private var recipient: JsonField = JsonMissing.of() + private var to: JsonField = JsonMissing.of() + private var status: JsonField? = null + private var messageId: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(item: Item) = apply { + data = item.data + preferences = item.preferences + profile = item.profile + recipient = item.recipient + to = item.to + status = item.status + messageId = item.messageId + additionalProperties = item.additionalProperties.toMutableMap() + } + + fun data(data: JsonValue) = apply { this.data = data } + + fun preferences(preferences: RecipientPreferences?) = + preferences(JsonField.ofNullable(preferences)) + + /** Alias for calling [Builder.preferences] with `preferences.orElse(null)`. */ + fun preferences(preferences: Optional) = + preferences(preferences.getOrNull()) + + /** + * Sets [Builder.preferences] to an arbitrary JSON value. + * + * You should usually call [Builder.preferences] with a well-typed + * [RecipientPreferences] value instead. This method is primarily for setting the field + * to an undocumented or not yet supported value. + */ + fun preferences(preferences: JsonField) = apply { + this.preferences = preferences + } + + fun profile(profile: JsonValue) = apply { this.profile = profile } + + fun recipient(recipient: String?) = recipient(JsonField.ofNullable(recipient)) + + /** Alias for calling [Builder.recipient] with `recipient.orElse(null)`. */ + fun recipient(recipient: Optional) = recipient(recipient.getOrNull()) + + /** + * Sets [Builder.recipient] to an arbitrary JSON value. + * + * You should usually call [Builder.recipient] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun recipient(recipient: JsonField) = apply { this.recipient = recipient } + + fun to(to: UserRecipient?) = to(JsonField.ofNullable(to)) + + /** Alias for calling [Builder.to] with `to.orElse(null)`. */ + fun to(to: Optional) = to(to.getOrNull()) + + /** + * Sets [Builder.to] to an arbitrary JSON value. + * + * You should usually call [Builder.to] with a well-typed [UserRecipient] 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 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 } + + fun messageId(messageId: String?) = messageId(JsonField.ofNullable(messageId)) + + /** Alias for calling [Builder.messageId] with `messageId.orElse(null)`. */ + fun messageId(messageId: Optional) = messageId(messageId.getOrNull()) + + /** + * 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 } + + 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 [Item]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .status() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Item = + Item( + data, + preferences, + profile, + recipient, + to, + checkRequired("status", status), + messageId, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Item = apply { + if (validated) { + return@apply + } + + preferences().ifPresent { it.validate() } + recipient() + to().ifPresent { it.validate() } + status().validate() + messageId() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (preferences.asKnown().getOrNull()?.validity() ?: 0) + + (if (recipient.asKnown().isPresent) 1 else 0) + + (to.asKnown().getOrNull()?.validity() ?: 0) + + (status.asKnown().getOrNull()?.validity() ?: 0) + + (if (messageId.asKnown().isPresent) 1 else 0) + + 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 PENDING = of("PENDING") + + @JvmField val ENQUEUED = of("ENQUEUED") + + @JvmField val ERROR = of("ERROR") + + @JvmStatic fun of(value: String) = Status(JsonField.of(value)) + } + + /** An enum containing [Status]'s known values. */ + enum class Known { + PENDING, + ENQUEUED, + ERROR, + } + + /** + * 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 { + PENDING, + ENQUEUED, + ERROR, + /** + * 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) { + PENDING -> Value.PENDING + ENQUEUED -> Value.ENQUEUED + ERROR -> Value.ERROR + 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 CourierInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + PENDING -> Known.PENDING + ENQUEUED -> Known.ENQUEUED + ERROR -> Known.ERROR + else -> throw CourierInvalidDataException("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 CourierInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CourierInvalidDataException("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: CourierInvalidDataException) { + 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 Item && + data == other.data && + preferences == other.preferences && + profile == other.profile && + recipient == other.recipient && + to == other.to && + status == other.status && + messageId == other.messageId && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + data, + preferences, + profile, + recipient, + to, + status, + messageId, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Item{data=$data, preferences=$preferences, profile=$profile, recipient=$recipient, to=$to, status=$status, messageId=$messageId, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is BulkListUsersResponse && + items == other.items && + paging == other.paging && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(items, paging, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "BulkListUsersResponse{items=$items, paging=$paging, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/bulk/BulkRetrieveJobParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/bulk/BulkRetrieveJobParams.kt new file mode 100644 index 00000000..f828a7c6 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/bulk/BulkRetrieveJobParams.kt @@ -0,0 +1,189 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.bulk + +import com.courier.api.core.Params +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Get a bulk job */ +class BulkRetrieveJobParams +private constructor( + private val jobId: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun jobId(): Optional = Optional.ofNullable(jobId) + + /** 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(): BulkRetrieveJobParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [BulkRetrieveJobParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [BulkRetrieveJobParams]. */ + class Builder internal constructor() { + + private var jobId: String? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(bulkRetrieveJobParams: BulkRetrieveJobParams) = apply { + jobId = bulkRetrieveJobParams.jobId + additionalHeaders = bulkRetrieveJobParams.additionalHeaders.toBuilder() + additionalQueryParams = bulkRetrieveJobParams.additionalQueryParams.toBuilder() + } + + fun jobId(jobId: String?) = apply { this.jobId = jobId } + + /** Alias for calling [Builder.jobId] with `jobId.orElse(null)`. */ + fun jobId(jobId: Optional) = jobId(jobId.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 [BulkRetrieveJobParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): BulkRetrieveJobParams = + BulkRetrieveJobParams(jobId, additionalHeaders.build(), additionalQueryParams.build()) + } + + fun _pathParam(index: Int): String = + when (index) { + 0 -> jobId ?: "" + 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 BulkRetrieveJobParams && + jobId == other.jobId && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = Objects.hash(jobId, additionalHeaders, additionalQueryParams) + + override fun toString() = + "BulkRetrieveJobParams{jobId=$jobId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/bulk/BulkRetrieveJobResponse.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/bulk/BulkRetrieveJobResponse.kt new file mode 100644 index 00000000..accbc285 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/bulk/BulkRetrieveJobResponse.kt @@ -0,0 +1,620 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.bulk + +import com.courier.api.core.Enum +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkRequired +import com.courier.api.errors.CourierInvalidDataException +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 kotlin.jvm.optionals.getOrNull + +class BulkRetrieveJobResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val job: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("job") @ExcludeMissing job: JsonField = JsonMissing.of() + ) : this(job, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 job(): Job = job.getRequired("job") + + /** + * Returns the raw JSON value of [job]. + * + * Unlike [job], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("job") @ExcludeMissing fun _job(): JsonField = job + + @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 [BulkRetrieveJobResponse]. + * + * The following fields are required: + * ```java + * .job() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [BulkRetrieveJobResponse]. */ + class Builder internal constructor() { + + private var job: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(bulkRetrieveJobResponse: BulkRetrieveJobResponse) = apply { + job = bulkRetrieveJobResponse.job + additionalProperties = bulkRetrieveJobResponse.additionalProperties.toMutableMap() + } + + fun job(job: Job) = job(JsonField.of(job)) + + /** + * Sets [Builder.job] to an arbitrary JSON value. + * + * You should usually call [Builder.job] with a well-typed [Job] value instead. This method + * is primarily for setting the field to an undocumented or not yet supported value. + */ + fun job(job: JsonField) = apply { this.job = job } + + 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 [BulkRetrieveJobResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .job() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): BulkRetrieveJobResponse = + BulkRetrieveJobResponse(checkRequired("job", job), additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): BulkRetrieveJobResponse = apply { + if (validated) { + return@apply + } + + job().validate() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = (job.asKnown().getOrNull()?.validity() ?: 0) + + class Job + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val definition: JsonField, + private val enqueued: JsonField, + private val failures: JsonField, + private val received: JsonField, + private val status: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("definition") + @ExcludeMissing + definition: JsonField = JsonMissing.of(), + @JsonProperty("enqueued") @ExcludeMissing enqueued: JsonField = JsonMissing.of(), + @JsonProperty("failures") @ExcludeMissing failures: JsonField = JsonMissing.of(), + @JsonProperty("received") @ExcludeMissing received: JsonField = JsonMissing.of(), + @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(), + ) : this(definition, enqueued, failures, received, status, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 definition(): InboundBulkMessage = definition.getRequired("definition") + + /** + * @throws CourierInvalidDataException 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 enqueued(): Long = enqueued.getRequired("enqueued") + + /** + * @throws CourierInvalidDataException 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 failures(): Long = failures.getRequired("failures") + + /** + * @throws CourierInvalidDataException 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 received(): Long = received.getRequired("received") + + /** + * @throws CourierInvalidDataException 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 status(): Status = status.getRequired("status") + + /** + * Returns the raw JSON value of [definition]. + * + * Unlike [definition], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("definition") + @ExcludeMissing + fun _definition(): JsonField = definition + + /** + * Returns the raw JSON value of [enqueued]. + * + * Unlike [enqueued], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("enqueued") @ExcludeMissing fun _enqueued(): JsonField = enqueued + + /** + * Returns the raw JSON value of [failures]. + * + * Unlike [failures], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("failures") @ExcludeMissing fun _failures(): JsonField = failures + + /** + * Returns the raw JSON value of [received]. + * + * Unlike [received], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("received") @ExcludeMissing fun _received(): JsonField = received + + /** + * 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 [Job]. + * + * The following fields are required: + * ```java + * .definition() + * .enqueued() + * .failures() + * .received() + * .status() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Job]. */ + class Builder internal constructor() { + + private var definition: JsonField? = null + private var enqueued: JsonField? = null + private var failures: JsonField? = null + private var received: JsonField? = null + private var status: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(job: Job) = apply { + definition = job.definition + enqueued = job.enqueued + failures = job.failures + received = job.received + status = job.status + additionalProperties = job.additionalProperties.toMutableMap() + } + + fun definition(definition: InboundBulkMessage) = definition(JsonField.of(definition)) + + /** + * Sets [Builder.definition] to an arbitrary JSON value. + * + * You should usually call [Builder.definition] with a well-typed [InboundBulkMessage] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun definition(definition: JsonField) = apply { + this.definition = definition + } + + /** Alias for calling [definition] with `InboundBulkMessage.ofTemplate(template)`. */ + fun definition(template: InboundBulkMessage.InboundBulkTemplateMessage) = + definition(InboundBulkMessage.ofTemplate(template)) + + /** Alias for calling [definition] with `InboundBulkMessage.ofContent(content)`. */ + fun definition(content: InboundBulkMessage.InboundBulkContentMessage) = + definition(InboundBulkMessage.ofContent(content)) + + fun enqueued(enqueued: Long) = enqueued(JsonField.of(enqueued)) + + /** + * Sets [Builder.enqueued] to an arbitrary JSON value. + * + * You should usually call [Builder.enqueued] with a well-typed [Long] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun enqueued(enqueued: JsonField) = apply { this.enqueued = enqueued } + + fun failures(failures: Long) = failures(JsonField.of(failures)) + + /** + * Sets [Builder.failures] to an arbitrary JSON value. + * + * You should usually call [Builder.failures] with a well-typed [Long] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun failures(failures: JsonField) = apply { this.failures = failures } + + fun received(received: Long) = received(JsonField.of(received)) + + /** + * Sets [Builder.received] to an arbitrary JSON value. + * + * You should usually call [Builder.received] with a well-typed [Long] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun received(received: JsonField) = apply { this.received = received } + + 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 } + + 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 [Job]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .definition() + * .enqueued() + * .failures() + * .received() + * .status() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Job = + Job( + checkRequired("definition", definition), + checkRequired("enqueued", enqueued), + checkRequired("failures", failures), + checkRequired("received", received), + checkRequired("status", status), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Job = apply { + if (validated) { + return@apply + } + + definition().validate() + enqueued() + failures() + received() + status().validate() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (definition.asKnown().getOrNull()?.validity() ?: 0) + + (if (enqueued.asKnown().isPresent) 1 else 0) + + (if (failures.asKnown().isPresent) 1 else 0) + + (if (received.asKnown().isPresent) 1 else 0) + + (status.asKnown().getOrNull()?.validity() ?: 0) + + 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 CREATED = of("CREATED") + + @JvmField val PROCESSING = of("PROCESSING") + + @JvmField val COMPLETED = of("COMPLETED") + + @JvmField val ERROR = of("ERROR") + + @JvmStatic fun of(value: String) = Status(JsonField.of(value)) + } + + /** An enum containing [Status]'s known values. */ + enum class Known { + CREATED, + PROCESSING, + COMPLETED, + ERROR, + } + + /** + * 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 { + CREATED, + PROCESSING, + COMPLETED, + ERROR, + /** + * 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) { + CREATED -> Value.CREATED + PROCESSING -> Value.PROCESSING + COMPLETED -> Value.COMPLETED + ERROR -> Value.ERROR + 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 CourierInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + CREATED -> Known.CREATED + PROCESSING -> Known.PROCESSING + COMPLETED -> Known.COMPLETED + ERROR -> Known.ERROR + else -> throw CourierInvalidDataException("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 CourierInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CourierInvalidDataException("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: CourierInvalidDataException) { + 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 Job && + definition == other.definition && + enqueued == other.enqueued && + failures == other.failures && + received == other.received && + status == other.status && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(definition, enqueued, failures, received, status, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Job{definition=$definition, enqueued=$enqueued, failures=$failures, received=$received, status=$status, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is BulkRetrieveJobResponse && + job == other.job && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(job, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "BulkRetrieveJobResponse{job=$job, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/bulk/BulkRunJobParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/bulk/BulkRunJobParams.kt new file mode 100644 index 00000000..4c90666c --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/bulk/BulkRunJobParams.kt @@ -0,0 +1,229 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.bulk + +import com.courier.api.core.JsonValue +import com.courier.api.core.Params +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import com.courier.api.core.toImmutable +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Run a bulk job */ +class BulkRunJobParams +private constructor( + private val jobId: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, + private val additionalBodyProperties: Map, +) : Params { + + fun jobId(): Optional = Optional.ofNullable(jobId) + + /** 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(): BulkRunJobParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [BulkRunJobParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [BulkRunJobParams]. */ + class Builder internal constructor() { + + private var jobId: 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(bulkRunJobParams: BulkRunJobParams) = apply { + jobId = bulkRunJobParams.jobId + additionalHeaders = bulkRunJobParams.additionalHeaders.toBuilder() + additionalQueryParams = bulkRunJobParams.additionalQueryParams.toBuilder() + additionalBodyProperties = bulkRunJobParams.additionalBodyProperties.toMutableMap() + } + + fun jobId(jobId: String?) = apply { this.jobId = jobId } + + /** Alias for calling [Builder.jobId] with `jobId.orElse(null)`. */ + fun jobId(jobId: Optional) = jobId(jobId.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 [BulkRunJobParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): BulkRunJobParams = + BulkRunJobParams( + jobId, + additionalHeaders.build(), + additionalQueryParams.build(), + additionalBodyProperties.toImmutable(), + ) + } + + fun _body(): Optional> = + Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) + + fun _pathParam(index: Int): String = + when (index) { + 0 -> jobId ?: "" + 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 BulkRunJobParams && + jobId == other.jobId && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams && + additionalBodyProperties == other.additionalBodyProperties + } + + override fun hashCode(): Int = + Objects.hash(jobId, additionalHeaders, additionalQueryParams, additionalBodyProperties) + + override fun toString() = + "BulkRunJobParams{jobId=$jobId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/bulk/InboundBulkMessage.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/bulk/InboundBulkMessage.kt new file mode 100644 index 00000000..79e3c79e --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/bulk/InboundBulkMessage.kt @@ -0,0 +1,1512 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.bulk + +import com.courier.api.core.BaseDeserializer +import com.courier.api.core.BaseSerializer +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.allMaxBy +import com.courier.api.core.checkRequired +import com.courier.api.core.getOrThrow +import com.courier.api.core.toImmutable +import com.courier.api.errors.CourierInvalidDataException +import com.courier.api.models.send.Content +import com.courier.api.models.tenants.templates.ElementalContent +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 com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.ObjectCodec +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.module.kotlin.jacksonTypeRef +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +@JsonDeserialize(using = InboundBulkMessage.Deserializer::class) +@JsonSerialize(using = InboundBulkMessage.Serializer::class) +class InboundBulkMessage +private constructor( + private val template: InboundBulkTemplateMessage? = null, + private val content: InboundBulkContentMessage? = null, + private val _json: JsonValue? = null, +) { + + fun template(): Optional = Optional.ofNullable(template) + + fun content(): Optional = Optional.ofNullable(content) + + fun isTemplate(): Boolean = template != null + + fun isContent(): Boolean = content != null + + fun asTemplate(): InboundBulkTemplateMessage = template.getOrThrow("template") + + fun asContent(): InboundBulkContentMessage = content.getOrThrow("content") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T = + when { + template != null -> visitor.visitTemplate(template) + content != null -> visitor.visitContent(content) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + fun validate(): InboundBulkMessage = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitTemplate(template: InboundBulkTemplateMessage) { + template.validate() + } + + override fun visitContent(content: InboundBulkContentMessage) { + content.validate() + } + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + accept( + object : Visitor { + override fun visitTemplate(template: InboundBulkTemplateMessage) = + template.validity() + + override fun visitContent(content: InboundBulkContentMessage) = content.validity() + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is InboundBulkMessage && template == other.template && content == other.content + } + + override fun hashCode(): Int = Objects.hash(template, content) + + override fun toString(): String = + when { + template != null -> "InboundBulkMessage{template=$template}" + content != null -> "InboundBulkMessage{content=$content}" + _json != null -> "InboundBulkMessage{_unknown=$_json}" + else -> throw IllegalStateException("Invalid InboundBulkMessage") + } + + companion object { + + @JvmStatic + fun ofTemplate(template: InboundBulkTemplateMessage) = + InboundBulkMessage(template = template) + + @JvmStatic + fun ofContent(content: InboundBulkContentMessage) = InboundBulkMessage(content = content) + } + + /** + * An interface that defines how to map each variant of [InboundBulkMessage] to a value of type + * [T]. + */ + interface Visitor { + + fun visitTemplate(template: InboundBulkTemplateMessage): T + + fun visitContent(content: InboundBulkContentMessage): T + + /** + * Maps an unknown variant of [InboundBulkMessage] to a value of type [T]. + * + * An instance of [InboundBulkMessage] can contain an unknown variant if it was deserialized + * from data that doesn't match any known variant. For example, if the SDK is on an older + * version than the API, then the API may respond with new variants that the SDK is unaware + * of. + * + * @throws CourierInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw CourierInvalidDataException("Unknown InboundBulkMessage: $json") + } + } + + internal class Deserializer : BaseDeserializer(InboundBulkMessage::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): InboundBulkMessage { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef())?.let { + InboundBulkMessage(template = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + InboundBulkMessage(content = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible with all + // the possible variants (e.g. deserializing from boolean). + 0 -> InboundBulkMessage(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the first + // completely valid match, or simply the first match if none are completely valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : BaseSerializer(InboundBulkMessage::class) { + + override fun serialize( + value: InboundBulkMessage, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.template != null -> generator.writeObject(value.template) + value.content != null -> generator.writeObject(value.content) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid InboundBulkMessage") + } + } + } + + class InboundBulkTemplateMessage + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val template: JsonField, + private val brand: JsonField, + private val data: JsonField, + private val event: JsonField, + private val locale: JsonField, + private val override: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("template") + @ExcludeMissing + template: JsonField = JsonMissing.of(), + @JsonProperty("brand") @ExcludeMissing brand: JsonField = JsonMissing.of(), + @JsonProperty("data") @ExcludeMissing data: JsonField = JsonMissing.of(), + @JsonProperty("event") @ExcludeMissing event: JsonField = JsonMissing.of(), + @JsonProperty("locale") @ExcludeMissing locale: JsonField = JsonMissing.of(), + @JsonProperty("override") + @ExcludeMissing + override: JsonField = JsonMissing.of(), + ) : this(template, brand, data, event, locale, override, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 template(): String = template.getRequired("template") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun brand(): Optional = brand.getOptional("brand") + + /** + * @throws CourierInvalidDataException 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 CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun event(): Optional = event.getOptional("event") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun locale(): Optional = locale.getOptional("locale") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun override(): Optional = override.getOptional("override") + + /** + * Returns the raw JSON value of [template]. + * + * Unlike [template], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("template") @ExcludeMissing fun _template(): JsonField = template + + /** + * Returns the raw JSON value of [brand]. + * + * Unlike [brand], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("brand") @ExcludeMissing fun _brand(): JsonField = brand + + /** + * 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 [event]. + * + * Unlike [event], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("event") @ExcludeMissing fun _event(): JsonField = event + + /** + * Returns the raw JSON value of [locale]. + * + * Unlike [locale], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("locale") @ExcludeMissing fun _locale(): JsonField = locale + + /** + * Returns the raw JSON value of [override]. + * + * Unlike [override], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("override") @ExcludeMissing fun _override(): JsonField = override + + @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 + * [InboundBulkTemplateMessage]. + * + * The following fields are required: + * ```java + * .template() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [InboundBulkTemplateMessage]. */ + class Builder internal constructor() { + + private var template: JsonField? = null + private var brand: JsonField = JsonMissing.of() + private var data: JsonField = JsonMissing.of() + private var event: JsonField = JsonMissing.of() + private var locale: JsonField = JsonMissing.of() + private var override: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(inboundBulkTemplateMessage: InboundBulkTemplateMessage) = apply { + template = inboundBulkTemplateMessage.template + brand = inboundBulkTemplateMessage.brand + data = inboundBulkTemplateMessage.data + event = inboundBulkTemplateMessage.event + locale = inboundBulkTemplateMessage.locale + override = inboundBulkTemplateMessage.override + additionalProperties = + inboundBulkTemplateMessage.additionalProperties.toMutableMap() + } + + fun template(template: String) = template(JsonField.of(template)) + + /** + * Sets [Builder.template] to an arbitrary JSON value. + * + * You should usually call [Builder.template] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun template(template: JsonField) = apply { this.template = template } + + fun brand(brand: String?) = brand(JsonField.ofNullable(brand)) + + /** Alias for calling [Builder.brand] with `brand.orElse(null)`. */ + fun brand(brand: Optional) = brand(brand.getOrNull()) + + /** + * Sets [Builder.brand] to an arbitrary JSON value. + * + * You should usually call [Builder.brand] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun brand(brand: JsonField) = apply { this.brand = brand } + + fun data(data: Data?) = data(JsonField.ofNullable(data)) + + /** Alias for calling [Builder.data] with `data.orElse(null)`. */ + fun data(data: Optional) = data(data.getOrNull()) + + /** + * 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 event(event: String?) = event(JsonField.ofNullable(event)) + + /** Alias for calling [Builder.event] with `event.orElse(null)`. */ + fun event(event: Optional) = event(event.getOrNull()) + + /** + * Sets [Builder.event] to an arbitrary JSON value. + * + * You should usually call [Builder.event] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun event(event: JsonField) = apply { this.event = event } + + fun locale(locale: Locale?) = locale(JsonField.ofNullable(locale)) + + /** Alias for calling [Builder.locale] with `locale.orElse(null)`. */ + fun locale(locale: Optional) = locale(locale.getOrNull()) + + /** + * Sets [Builder.locale] to an arbitrary JSON value. + * + * You should usually call [Builder.locale] with a well-typed [Locale] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun locale(locale: JsonField) = apply { this.locale = locale } + + fun override(override: Override?) = override(JsonField.ofNullable(override)) + + /** Alias for calling [Builder.override] with `override.orElse(null)`. */ + fun override(override: Optional) = override(override.getOrNull()) + + /** + * Sets [Builder.override] to an arbitrary JSON value. + * + * You should usually call [Builder.override] with a well-typed [Override] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun override(override: JsonField) = apply { this.override = override } + + 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 [InboundBulkTemplateMessage]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .template() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): InboundBulkTemplateMessage = + InboundBulkTemplateMessage( + checkRequired("template", template), + brand, + data, + event, + locale, + override, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): InboundBulkTemplateMessage = apply { + if (validated) { + return@apply + } + + template() + brand() + data().ifPresent { it.validate() } + event() + locale().ifPresent { it.validate() } + override().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (template.asKnown().isPresent) 1 else 0) + + (if (brand.asKnown().isPresent) 1 else 0) + + (data.asKnown().getOrNull()?.validity() ?: 0) + + (if (event.asKnown().isPresent) 1 else 0) + + (locale.asKnown().getOrNull()?.validity() ?: 0) + + (override.asKnown().getOrNull()?.validity() ?: 0) + + class Data + @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 [Data]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Data]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(data: Data) = apply { + additionalProperties = data.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 [Data]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Data = Data(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): Data = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Data && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Data{additionalProperties=$additionalProperties}" + } + + class Locale + @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 [Locale]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Locale]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(locale: Locale) = apply { + additionalProperties = locale.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 [Locale]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Locale = Locale(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): Locale = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Locale && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Locale{additionalProperties=$additionalProperties}" + } + + class Override + @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 [Override]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Override]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(override: Override) = apply { + additionalProperties = override.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 [Override]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Override = Override(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): Override = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Override && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Override{additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is InboundBulkTemplateMessage && + template == other.template && + brand == other.brand && + data == other.data && + event == other.event && + locale == other.locale && + override == other.override && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(template, brand, data, event, locale, override, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "InboundBulkTemplateMessage{template=$template, brand=$brand, data=$data, event=$event, locale=$locale, override=$override, additionalProperties=$additionalProperties}" + } + + class InboundBulkContentMessage + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val content: JsonField, + private val brand: JsonField, + private val data: JsonField, + private val event: JsonField, + private val locale: JsonField, + private val override: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("content") @ExcludeMissing content: JsonField = JsonMissing.of(), + @JsonProperty("brand") @ExcludeMissing brand: JsonField = JsonMissing.of(), + @JsonProperty("data") @ExcludeMissing data: JsonField = JsonMissing.of(), + @JsonProperty("event") @ExcludeMissing event: JsonField = JsonMissing.of(), + @JsonProperty("locale") @ExcludeMissing locale: JsonField = JsonMissing.of(), + @JsonProperty("override") + @ExcludeMissing + override: JsonField = JsonMissing.of(), + ) : this(content, brand, data, event, locale, override, mutableMapOf()) + + /** + * Syntactic sugar to provide a fast shorthand for Courier Elemental Blocks. + * + * @throws CourierInvalidDataException 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 content(): Content = content.getRequired("content") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun brand(): Optional = brand.getOptional("brand") + + /** + * @throws CourierInvalidDataException 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 CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun event(): Optional = event.getOptional("event") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun locale(): Optional = locale.getOptional("locale") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun override(): Optional = override.getOptional("override") + + /** + * Returns the raw JSON value of [content]. + * + * Unlike [content], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("content") @ExcludeMissing fun _content(): JsonField = content + + /** + * Returns the raw JSON value of [brand]. + * + * Unlike [brand], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("brand") @ExcludeMissing fun _brand(): JsonField = brand + + /** + * 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 [event]. + * + * Unlike [event], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("event") @ExcludeMissing fun _event(): JsonField = event + + /** + * Returns the raw JSON value of [locale]. + * + * Unlike [locale], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("locale") @ExcludeMissing fun _locale(): JsonField = locale + + /** + * Returns the raw JSON value of [override]. + * + * Unlike [override], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("override") @ExcludeMissing fun _override(): JsonField = override + + @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 + * [InboundBulkContentMessage]. + * + * The following fields are required: + * ```java + * .content() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [InboundBulkContentMessage]. */ + class Builder internal constructor() { + + private var content: JsonField? = null + private var brand: JsonField = JsonMissing.of() + private var data: JsonField = JsonMissing.of() + private var event: JsonField = JsonMissing.of() + private var locale: JsonField = JsonMissing.of() + private var override: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(inboundBulkContentMessage: InboundBulkContentMessage) = apply { + content = inboundBulkContentMessage.content + brand = inboundBulkContentMessage.brand + data = inboundBulkContentMessage.data + event = inboundBulkContentMessage.event + locale = inboundBulkContentMessage.locale + override = inboundBulkContentMessage.override + additionalProperties = inboundBulkContentMessage.additionalProperties.toMutableMap() + } + + /** Syntactic sugar to provide a fast shorthand for Courier Elemental Blocks. */ + fun content(content: Content) = content(JsonField.of(content)) + + /** + * Sets [Builder.content] to an arbitrary JSON value. + * + * You should usually call [Builder.content] with a well-typed [Content] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun content(content: JsonField) = apply { this.content = content } + + /** + * Alias for calling [content] with + * `Content.ofElementalContentSugar(elementalContentSugar)`. + */ + fun content(elementalContentSugar: Content.ElementalContentSugar) = + content(Content.ofElementalContentSugar(elementalContentSugar)) + + /** Alias for calling [content] with `Content.ofElemental(elemental)`. */ + fun content(elemental: ElementalContent) = content(Content.ofElemental(elemental)) + + fun brand(brand: String?) = brand(JsonField.ofNullable(brand)) + + /** Alias for calling [Builder.brand] with `brand.orElse(null)`. */ + fun brand(brand: Optional) = brand(brand.getOrNull()) + + /** + * Sets [Builder.brand] to an arbitrary JSON value. + * + * You should usually call [Builder.brand] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun brand(brand: JsonField) = apply { this.brand = brand } + + fun data(data: Data?) = data(JsonField.ofNullable(data)) + + /** Alias for calling [Builder.data] with `data.orElse(null)`. */ + fun data(data: Optional) = data(data.getOrNull()) + + /** + * 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 event(event: String?) = event(JsonField.ofNullable(event)) + + /** Alias for calling [Builder.event] with `event.orElse(null)`. */ + fun event(event: Optional) = event(event.getOrNull()) + + /** + * Sets [Builder.event] to an arbitrary JSON value. + * + * You should usually call [Builder.event] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun event(event: JsonField) = apply { this.event = event } + + fun locale(locale: Locale?) = locale(JsonField.ofNullable(locale)) + + /** Alias for calling [Builder.locale] with `locale.orElse(null)`. */ + fun locale(locale: Optional) = locale(locale.getOrNull()) + + /** + * Sets [Builder.locale] to an arbitrary JSON value. + * + * You should usually call [Builder.locale] with a well-typed [Locale] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun locale(locale: JsonField) = apply { this.locale = locale } + + fun override(override: Override?) = override(JsonField.ofNullable(override)) + + /** Alias for calling [Builder.override] with `override.orElse(null)`. */ + fun override(override: Optional) = override(override.getOrNull()) + + /** + * Sets [Builder.override] to an arbitrary JSON value. + * + * You should usually call [Builder.override] with a well-typed [Override] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun override(override: JsonField) = apply { this.override = override } + + 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 [InboundBulkContentMessage]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .content() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): InboundBulkContentMessage = + InboundBulkContentMessage( + checkRequired("content", content), + brand, + data, + event, + locale, + override, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): InboundBulkContentMessage = apply { + if (validated) { + return@apply + } + + content().validate() + brand() + data().ifPresent { it.validate() } + event() + locale().ifPresent { it.validate() } + override().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (content.asKnown().getOrNull()?.validity() ?: 0) + + (if (brand.asKnown().isPresent) 1 else 0) + + (data.asKnown().getOrNull()?.validity() ?: 0) + + (if (event.asKnown().isPresent) 1 else 0) + + (locale.asKnown().getOrNull()?.validity() ?: 0) + + (override.asKnown().getOrNull()?.validity() ?: 0) + + class Data + @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 [Data]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Data]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(data: Data) = apply { + additionalProperties = data.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 [Data]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Data = Data(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): Data = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Data && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Data{additionalProperties=$additionalProperties}" + } + + class Locale + @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 [Locale]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Locale]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(locale: Locale) = apply { + additionalProperties = locale.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 [Locale]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Locale = Locale(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): Locale = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Locale && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Locale{additionalProperties=$additionalProperties}" + } + + class Override + @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 [Override]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Override]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(override: Override) = apply { + additionalProperties = override.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 [Override]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Override = Override(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): Override = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Override && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Override{additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is InboundBulkContentMessage && + content == other.content && + brand == other.brand && + data == other.data && + event == other.event && + locale == other.locale && + override == other.override && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(content, brand, data, event, locale, override, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "InboundBulkContentMessage{content=$content, brand=$brand, data=$data, event=$event, locale=$locale, override=$override, additionalProperties=$additionalProperties}" + } +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/bulk/InboundBulkMessageUser.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/bulk/InboundBulkMessageUser.kt new file mode 100644 index 00000000..2ebcd6da --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/bulk/InboundBulkMessageUser.kt @@ -0,0 +1,264 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.bulk + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.errors.CourierInvalidDataException +import com.courier.api.models.lists.subscriptions.RecipientPreferences +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 InboundBulkMessageUser +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val data: JsonValue, + private val preferences: JsonField, + private val profile: JsonValue, + private val recipient: JsonField, + private val to: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("data") @ExcludeMissing data: JsonValue = JsonMissing.of(), + @JsonProperty("preferences") + @ExcludeMissing + preferences: JsonField = JsonMissing.of(), + @JsonProperty("profile") @ExcludeMissing profile: JsonValue = JsonMissing.of(), + @JsonProperty("recipient") @ExcludeMissing recipient: JsonField = JsonMissing.of(), + @JsonProperty("to") @ExcludeMissing to: JsonField = JsonMissing.of(), + ) : this(data, preferences, profile, recipient, to, mutableMapOf()) + + @JsonProperty("data") @ExcludeMissing fun _data(): JsonValue = data + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun preferences(): Optional = preferences.getOptional("preferences") + + @JsonProperty("profile") @ExcludeMissing fun _profile(): JsonValue = profile + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun recipient(): Optional = recipient.getOptional("recipient") + + /** + * @throws CourierInvalidDataException 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 [preferences]. + * + * Unlike [preferences], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("preferences") + @ExcludeMissing + fun _preferences(): JsonField = preferences + + /** + * Returns the raw JSON value of [recipient]. + * + * Unlike [recipient], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("recipient") @ExcludeMissing fun _recipient(): JsonField = recipient + + /** + * 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 [InboundBulkMessageUser]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [InboundBulkMessageUser]. */ + class Builder internal constructor() { + + private var data: JsonValue = JsonMissing.of() + private var preferences: JsonField = JsonMissing.of() + private var profile: JsonValue = JsonMissing.of() + private var recipient: JsonField = JsonMissing.of() + private var to: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(inboundBulkMessageUser: InboundBulkMessageUser) = apply { + data = inboundBulkMessageUser.data + preferences = inboundBulkMessageUser.preferences + profile = inboundBulkMessageUser.profile + recipient = inboundBulkMessageUser.recipient + to = inboundBulkMessageUser.to + additionalProperties = inboundBulkMessageUser.additionalProperties.toMutableMap() + } + + fun data(data: JsonValue) = apply { this.data = data } + + fun preferences(preferences: RecipientPreferences?) = + preferences(JsonField.ofNullable(preferences)) + + /** Alias for calling [Builder.preferences] with `preferences.orElse(null)`. */ + fun preferences(preferences: Optional) = + preferences(preferences.getOrNull()) + + /** + * Sets [Builder.preferences] to an arbitrary JSON value. + * + * You should usually call [Builder.preferences] with a well-typed [RecipientPreferences] + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun preferences(preferences: JsonField) = apply { + this.preferences = preferences + } + + fun profile(profile: JsonValue) = apply { this.profile = profile } + + fun recipient(recipient: String?) = recipient(JsonField.ofNullable(recipient)) + + /** Alias for calling [Builder.recipient] with `recipient.orElse(null)`. */ + fun recipient(recipient: Optional) = recipient(recipient.getOrNull()) + + /** + * Sets [Builder.recipient] to an arbitrary JSON value. + * + * You should usually call [Builder.recipient] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun recipient(recipient: JsonField) = apply { this.recipient = recipient } + + fun to(to: UserRecipient?) = to(JsonField.ofNullable(to)) + + /** Alias for calling [Builder.to] with `to.orElse(null)`. */ + fun to(to: Optional) = to(to.getOrNull()) + + /** + * Sets [Builder.to] to an arbitrary JSON value. + * + * You should usually call [Builder.to] with a well-typed [UserRecipient] 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 [InboundBulkMessageUser]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): InboundBulkMessageUser = + InboundBulkMessageUser( + data, + preferences, + profile, + recipient, + to, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): InboundBulkMessageUser = apply { + if (validated) { + return@apply + } + + preferences().ifPresent { it.validate() } + recipient() + to().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (preferences.asKnown().getOrNull()?.validity() ?: 0) + + (if (recipient.asKnown().isPresent) 1 else 0) + + (to.asKnown().getOrNull()?.validity() ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is InboundBulkMessageUser && + data == other.data && + preferences == other.preferences && + profile == other.profile && + recipient == other.recipient && + to == other.to && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(data, preferences, profile, recipient, to, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "InboundBulkMessageUser{data=$data, preferences=$preferences, profile=$profile, recipient=$recipient, to=$to, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/bulk/UserRecipient.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/bulk/UserRecipient.kt new file mode 100644 index 00000000..b55b337b --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/bulk/UserRecipient.kt @@ -0,0 +1,1040 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.bulk + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkRequired +import com.courier.api.core.toImmutable +import com.courier.api.errors.CourierInvalidDataException +import com.courier.api.models.send.MessageContext +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 UserRecipient +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val accountId: JsonField, + private val context: JsonField, + private val data: JsonField, + private val email: JsonField, + private val locale: JsonField, + private val phoneNumber: JsonField, + private val preferences: JsonField, + private val tenantId: JsonField, + private val userId: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("account_id") @ExcludeMissing accountId: JsonField = JsonMissing.of(), + @JsonProperty("context") + @ExcludeMissing + context: JsonField = JsonMissing.of(), + @JsonProperty("data") @ExcludeMissing data: JsonField = JsonMissing.of(), + @JsonProperty("email") @ExcludeMissing email: JsonField = JsonMissing.of(), + @JsonProperty("locale") @ExcludeMissing locale: JsonField = JsonMissing.of(), + @JsonProperty("phone_number") + @ExcludeMissing + phoneNumber: JsonField = JsonMissing.of(), + @JsonProperty("preferences") + @ExcludeMissing + preferences: JsonField = JsonMissing.of(), + @JsonProperty("tenant_id") @ExcludeMissing tenantId: JsonField = JsonMissing.of(), + @JsonProperty("user_id") @ExcludeMissing userId: JsonField = JsonMissing.of(), + ) : this( + accountId, + context, + data, + email, + locale, + phoneNumber, + preferences, + tenantId, + userId, + mutableMapOf(), + ) + + /** + * Use `tenant_id` instead. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun accountId(): Optional = accountId.getOptional("account_id") + + /** + * Context such as tenant_id to send the notification with. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun context(): Optional = context.getOptional("context") + + /** + * @throws CourierInvalidDataException 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 CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun email(): Optional = email.getOptional("email") + + /** + * The user's preferred ISO 639-1 language code. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun locale(): Optional = locale.getOptional("locale") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun phoneNumber(): Optional = phoneNumber.getOptional("phone_number") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun preferences(): Optional = preferences.getOptional("preferences") + + /** + * Tenant id. Will load brand, default preferences and base context data. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun tenantId(): Optional = tenantId.getOptional("tenant_id") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun userId(): Optional = userId.getOptional("user_id") + + /** + * Returns the raw JSON value of [accountId]. + * + * Unlike [accountId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("account_id") @ExcludeMissing fun _accountId(): JsonField = accountId + + /** + * Returns the raw JSON value of [context]. + * + * Unlike [context], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("context") @ExcludeMissing fun _context(): JsonField = context + + /** + * 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 [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 [locale]. + * + * Unlike [locale], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("locale") @ExcludeMissing fun _locale(): JsonField = locale + + /** + * Returns the raw JSON value of [phoneNumber]. + * + * Unlike [phoneNumber], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("phone_number") + @ExcludeMissing + fun _phoneNumber(): JsonField = phoneNumber + + /** + * Returns the raw JSON value of [preferences]. + * + * Unlike [preferences], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("preferences") + @ExcludeMissing + fun _preferences(): JsonField = preferences + + /** + * Returns the raw JSON value of [tenantId]. + * + * Unlike [tenantId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("tenant_id") @ExcludeMissing fun _tenantId(): JsonField = tenantId + + /** + * Returns the raw JSON value of [userId]. + * + * Unlike [userId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("user_id") @ExcludeMissing fun _userId(): JsonField = userId + + @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 [UserRecipient]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [UserRecipient]. */ + class Builder internal constructor() { + + private var accountId: JsonField = JsonMissing.of() + private var context: JsonField = JsonMissing.of() + private var data: JsonField = JsonMissing.of() + private var email: JsonField = JsonMissing.of() + private var locale: JsonField = JsonMissing.of() + private var phoneNumber: JsonField = JsonMissing.of() + private var preferences: JsonField = JsonMissing.of() + private var tenantId: JsonField = JsonMissing.of() + private var userId: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(userRecipient: UserRecipient) = apply { + accountId = userRecipient.accountId + context = userRecipient.context + data = userRecipient.data + email = userRecipient.email + locale = userRecipient.locale + phoneNumber = userRecipient.phoneNumber + preferences = userRecipient.preferences + tenantId = userRecipient.tenantId + userId = userRecipient.userId + additionalProperties = userRecipient.additionalProperties.toMutableMap() + } + + /** Use `tenant_id` instead. */ + fun accountId(accountId: String?) = accountId(JsonField.ofNullable(accountId)) + + /** Alias for calling [Builder.accountId] with `accountId.orElse(null)`. */ + fun accountId(accountId: Optional) = accountId(accountId.getOrNull()) + + /** + * Sets [Builder.accountId] to an arbitrary JSON value. + * + * You should usually call [Builder.accountId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun accountId(accountId: JsonField) = apply { this.accountId = accountId } + + /** Context such as tenant_id to send the notification with. */ + fun context(context: MessageContext?) = context(JsonField.ofNullable(context)) + + /** Alias for calling [Builder.context] with `context.orElse(null)`. */ + fun context(context: Optional) = context(context.getOrNull()) + + /** + * Sets [Builder.context] to an arbitrary JSON value. + * + * You should usually call [Builder.context] with a well-typed [MessageContext] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun context(context: JsonField) = apply { this.context = context } + + fun data(data: Data?) = data(JsonField.ofNullable(data)) + + /** Alias for calling [Builder.data] with `data.orElse(null)`. */ + fun data(data: Optional) = data(data.getOrNull()) + + /** + * 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 email(email: String?) = email(JsonField.ofNullable(email)) + + /** Alias for calling [Builder.email] with `email.orElse(null)`. */ + fun email(email: Optional) = email(email.getOrNull()) + + /** + * 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 } + + /** The user's preferred ISO 639-1 language code. */ + fun locale(locale: String?) = locale(JsonField.ofNullable(locale)) + + /** Alias for calling [Builder.locale] with `locale.orElse(null)`. */ + fun locale(locale: Optional) = locale(locale.getOrNull()) + + /** + * Sets [Builder.locale] to an arbitrary JSON value. + * + * You should usually call [Builder.locale] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun locale(locale: JsonField) = apply { this.locale = locale } + + fun phoneNumber(phoneNumber: String?) = phoneNumber(JsonField.ofNullable(phoneNumber)) + + /** Alias for calling [Builder.phoneNumber] with `phoneNumber.orElse(null)`. */ + fun phoneNumber(phoneNumber: Optional) = phoneNumber(phoneNumber.getOrNull()) + + /** + * Sets [Builder.phoneNumber] to an arbitrary JSON value. + * + * You should usually call [Builder.phoneNumber] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun phoneNumber(phoneNumber: JsonField) = apply { this.phoneNumber = phoneNumber } + + fun preferences(preferences: Preferences?) = preferences(JsonField.ofNullable(preferences)) + + /** Alias for calling [Builder.preferences] with `preferences.orElse(null)`. */ + fun preferences(preferences: Optional) = preferences(preferences.getOrNull()) + + /** + * Sets [Builder.preferences] to an arbitrary JSON value. + * + * You should usually call [Builder.preferences] with a well-typed [Preferences] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun preferences(preferences: JsonField) = apply { + this.preferences = preferences + } + + /** Tenant id. Will load brand, default preferences and base context data. */ + fun tenantId(tenantId: String?) = tenantId(JsonField.ofNullable(tenantId)) + + /** Alias for calling [Builder.tenantId] with `tenantId.orElse(null)`. */ + fun tenantId(tenantId: Optional) = tenantId(tenantId.getOrNull()) + + /** + * Sets [Builder.tenantId] to an arbitrary JSON value. + * + * You should usually call [Builder.tenantId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun tenantId(tenantId: JsonField) = apply { this.tenantId = tenantId } + + fun userId(userId: String?) = userId(JsonField.ofNullable(userId)) + + /** Alias for calling [Builder.userId] with `userId.orElse(null)`. */ + fun userId(userId: Optional) = userId(userId.getOrNull()) + + /** + * Sets [Builder.userId] to an arbitrary JSON value. + * + * You should usually call [Builder.userId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun userId(userId: JsonField) = apply { this.userId = userId } + + 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 [UserRecipient]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): UserRecipient = + UserRecipient( + accountId, + context, + data, + email, + locale, + phoneNumber, + preferences, + tenantId, + userId, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): UserRecipient = apply { + if (validated) { + return@apply + } + + accountId() + context().ifPresent { it.validate() } + data().ifPresent { it.validate() } + email() + locale() + phoneNumber() + preferences().ifPresent { it.validate() } + tenantId() + userId() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (accountId.asKnown().isPresent) 1 else 0) + + (context.asKnown().getOrNull()?.validity() ?: 0) + + (data.asKnown().getOrNull()?.validity() ?: 0) + + (if (email.asKnown().isPresent) 1 else 0) + + (if (locale.asKnown().isPresent) 1 else 0) + + (if (phoneNumber.asKnown().isPresent) 1 else 0) + + (preferences.asKnown().getOrNull()?.validity() ?: 0) + + (if (tenantId.asKnown().isPresent) 1 else 0) + + (if (userId.asKnown().isPresent) 1 else 0) + + class Data + @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 [Data]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Data]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(data: Data) = apply { + additionalProperties = data.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 [Data]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Data = Data(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): Data = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Data && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Data{additionalProperties=$additionalProperties}" + } + + class Preferences + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val notifications: JsonField, + private val categories: JsonField, + private val templateId: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("notifications") + @ExcludeMissing + notifications: JsonField = JsonMissing.of(), + @JsonProperty("categories") + @ExcludeMissing + categories: JsonField = JsonMissing.of(), + @JsonProperty("templateId") + @ExcludeMissing + templateId: JsonField = JsonMissing.of(), + ) : this(notifications, categories, templateId, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 notifications(): Notifications = notifications.getRequired("notifications") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun categories(): Optional = categories.getOptional("categories") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun templateId(): Optional = templateId.getOptional("templateId") + + /** + * Returns the raw JSON value of [notifications]. + * + * Unlike [notifications], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("notifications") + @ExcludeMissing + fun _notifications(): JsonField = notifications + + /** + * Returns the raw JSON value of [categories]. + * + * Unlike [categories], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("categories") + @ExcludeMissing + fun _categories(): JsonField = categories + + /** + * Returns the raw JSON value of [templateId]. + * + * Unlike [templateId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("templateId") + @ExcludeMissing + fun _templateId(): JsonField = templateId + + @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 [Preferences]. + * + * The following fields are required: + * ```java + * .notifications() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Preferences]. */ + class Builder internal constructor() { + + private var notifications: JsonField? = null + private var categories: JsonField = JsonMissing.of() + private var templateId: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(preferences: Preferences) = apply { + notifications = preferences.notifications + categories = preferences.categories + templateId = preferences.templateId + additionalProperties = preferences.additionalProperties.toMutableMap() + } + + fun notifications(notifications: Notifications) = + notifications(JsonField.of(notifications)) + + /** + * Sets [Builder.notifications] to an arbitrary JSON value. + * + * You should usually call [Builder.notifications] with a well-typed [Notifications] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun notifications(notifications: JsonField) = apply { + this.notifications = notifications + } + + fun categories(categories: Categories?) = categories(JsonField.ofNullable(categories)) + + /** Alias for calling [Builder.categories] with `categories.orElse(null)`. */ + fun categories(categories: Optional) = categories(categories.getOrNull()) + + /** + * Sets [Builder.categories] to an arbitrary JSON value. + * + * You should usually call [Builder.categories] with a well-typed [Categories] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun categories(categories: JsonField) = apply { + this.categories = categories + } + + fun templateId(templateId: String?) = templateId(JsonField.ofNullable(templateId)) + + /** Alias for calling [Builder.templateId] with `templateId.orElse(null)`. */ + fun templateId(templateId: Optional) = templateId(templateId.getOrNull()) + + /** + * Sets [Builder.templateId] to an arbitrary JSON value. + * + * You should usually call [Builder.templateId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun templateId(templateId: JsonField) = apply { this.templateId = templateId } + + 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 [Preferences]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .notifications() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Preferences = + Preferences( + checkRequired("notifications", notifications), + categories, + templateId, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Preferences = apply { + if (validated) { + return@apply + } + + notifications().validate() + categories().ifPresent { it.validate() } + templateId() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (notifications.asKnown().getOrNull()?.validity() ?: 0) + + (categories.asKnown().getOrNull()?.validity() ?: 0) + + (if (templateId.asKnown().isPresent) 1 else 0) + + class Notifications + @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 [Notifications]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Notifications]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(notifications: Notifications) = apply { + additionalProperties = notifications.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 [Notifications]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Notifications = Notifications(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): Notifications = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Notifications && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Notifications{additionalProperties=$additionalProperties}" + } + + class Categories + @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 [Categories]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Categories]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(categories: Categories) = apply { + additionalProperties = categories.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 [Categories]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Categories = Categories(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): Categories = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Categories && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Categories{additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Preferences && + notifications == other.notifications && + categories == other.categories && + templateId == other.templateId && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(notifications, categories, templateId, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Preferences{notifications=$notifications, categories=$categories, templateId=$templateId, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is UserRecipient && + accountId == other.accountId && + context == other.context && + data == other.data && + email == other.email && + locale == other.locale && + phoneNumber == other.phoneNumber && + preferences == other.preferences && + tenantId == other.tenantId && + userId == other.userId && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + accountId, + context, + data, + email, + locale, + phoneNumber, + preferences, + tenantId, + userId, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "UserRecipient{accountId=$accountId, context=$context, data=$data, email=$email, locale=$locale, phoneNumber=$phoneNumber, preferences=$preferences, tenantId=$tenantId, userId=$userId, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/inbound/InboundTrackEventParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/inbound/InboundTrackEventParams.kt new file mode 100644 index 00000000..8f548040 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/inbound/InboundTrackEventParams.kt @@ -0,0 +1,925 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.inbound + +import com.courier.api.core.Enum +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.Params +import com.courier.api.core.checkRequired +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import com.courier.api.core.toImmutable +import com.courier.api.errors.CourierInvalidDataException +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 + +/** Courier Track Event */ +class InboundTrackEventParams +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * A descriptive name of the event. This name will appear as a trigger in the Courier Automation + * Trigger node. + * + * @throws CourierInvalidDataException 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 event(): String = body.event() + + /** + * A required unique identifier that will be used to de-duplicate requests. If not unique, will + * respond with 409 Conflict status + * + * @throws CourierInvalidDataException 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 messageId(): String = body.messageId() + + /** + * @throws CourierInvalidDataException 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 properties(): Properties = body.properties() + + /** + * @throws CourierInvalidDataException 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 type(): Type = body.type() + + /** + * The user id associatiated with the track + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun userId(): Optional = body.userId() + + /** + * Returns the raw JSON value of [event]. + * + * Unlike [event], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _event(): JsonField = body._event() + + /** + * Returns the raw JSON value of [messageId]. + * + * Unlike [messageId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _messageId(): JsonField = body._messageId() + + /** + * Returns the raw JSON value of [properties]. + * + * Unlike [properties], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _properties(): JsonField = body._properties() + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _type(): JsonField = body._type() + + /** + * Returns the raw JSON value of [userId]. + * + * Unlike [userId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _userId(): JsonField = body._userId() + + 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 [InboundTrackEventParams]. + * + * The following fields are required: + * ```java + * .event() + * .messageId() + * .properties() + * .type() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [InboundTrackEventParams]. */ + 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(inboundTrackEventParams: InboundTrackEventParams) = apply { + body = inboundTrackEventParams.body.toBuilder() + additionalHeaders = inboundTrackEventParams.additionalHeaders.toBuilder() + additionalQueryParams = inboundTrackEventParams.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: + * - [event] + * - [messageId] + * - [properties] + * - [type] + * - [userId] + * - etc. + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + /** + * A descriptive name of the event. This name will appear as a trigger in the Courier + * Automation Trigger node. + */ + fun event(event: String) = apply { body.event(event) } + + /** + * Sets [Builder.event] to an arbitrary JSON value. + * + * You should usually call [Builder.event] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun event(event: JsonField) = apply { body.event(event) } + + /** + * A required unique identifier that will be used to de-duplicate requests. If not unique, + * will respond with 409 Conflict status + */ + fun messageId(messageId: String) = apply { body.messageId(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 { body.messageId(messageId) } + + fun properties(properties: Properties) = apply { body.properties(properties) } + + /** + * Sets [Builder.properties] to an arbitrary JSON value. + * + * You should usually call [Builder.properties] with a well-typed [Properties] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun properties(properties: JsonField) = apply { body.properties(properties) } + + fun type(type: Type) = apply { body.type(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 { body.type(type) } + + /** The user id associatiated with the track */ + fun userId(userId: String?) = apply { body.userId(userId) } + + /** Alias for calling [Builder.userId] with `userId.orElse(null)`. */ + fun userId(userId: Optional) = userId(userId.getOrNull()) + + /** + * Sets [Builder.userId] to an arbitrary JSON value. + * + * You should usually call [Builder.userId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun userId(userId: JsonField) = apply { body.userId(userId) } + + 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 [InboundTrackEventParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .event() + * .messageId() + * .properties() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): InboundTrackEventParams = + InboundTrackEventParams( + 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 event: JsonField, + private val messageId: JsonField, + private val properties: JsonField, + private val type: JsonField, + private val userId: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("event") @ExcludeMissing event: JsonField = JsonMissing.of(), + @JsonProperty("messageId") + @ExcludeMissing + messageId: JsonField = JsonMissing.of(), + @JsonProperty("properties") + @ExcludeMissing + properties: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), + @JsonProperty("userId") @ExcludeMissing userId: JsonField = JsonMissing.of(), + ) : this(event, messageId, properties, type, userId, mutableMapOf()) + + /** + * A descriptive name of the event. This name will appear as a trigger in the Courier + * Automation Trigger node. + * + * @throws CourierInvalidDataException 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 event(): String = event.getRequired("event") + + /** + * A required unique identifier that will be used to de-duplicate requests. If not unique, + * will respond with 409 Conflict status + * + * @throws CourierInvalidDataException 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 messageId(): String = messageId.getRequired("messageId") + + /** + * @throws CourierInvalidDataException 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 properties(): Properties = properties.getRequired("properties") + + /** + * @throws CourierInvalidDataException 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 type(): Type = type.getRequired("type") + + /** + * The user id associatiated with the track + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun userId(): Optional = userId.getOptional("userId") + + /** + * Returns the raw JSON value of [event]. + * + * Unlike [event], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("event") @ExcludeMissing fun _event(): JsonField = event + + /** + * Returns the raw JSON value of [messageId]. + * + * Unlike [messageId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("messageId") @ExcludeMissing fun _messageId(): JsonField = messageId + + /** + * Returns the raw JSON value of [properties]. + * + * Unlike [properties], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("properties") + @ExcludeMissing + fun _properties(): JsonField = properties + + /** + * 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 [userId]. + * + * Unlike [userId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("userId") @ExcludeMissing fun _userId(): JsonField = userId + + @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 + * .event() + * .messageId() + * .properties() + * .type() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var event: JsonField? = null + private var messageId: JsonField? = null + private var properties: JsonField? = null + private var type: JsonField? = null + private var userId: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + event = body.event + messageId = body.messageId + properties = body.properties + type = body.type + userId = body.userId + additionalProperties = body.additionalProperties.toMutableMap() + } + + /** + * A descriptive name of the event. This name will appear as a trigger in the Courier + * Automation Trigger node. + */ + fun event(event: String) = event(JsonField.of(event)) + + /** + * Sets [Builder.event] to an arbitrary JSON value. + * + * You should usually call [Builder.event] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun event(event: JsonField) = apply { this.event = event } + + /** + * A required unique identifier that will be used to de-duplicate requests. If not + * unique, will respond with 409 Conflict status + */ + 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 } + + fun properties(properties: Properties) = properties(JsonField.of(properties)) + + /** + * Sets [Builder.properties] to an arbitrary JSON value. + * + * You should usually call [Builder.properties] with a well-typed [Properties] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun properties(properties: JsonField) = apply { + this.properties = properties + } + + 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 } + + /** The user id associatiated with the track */ + fun userId(userId: String?) = userId(JsonField.ofNullable(userId)) + + /** Alias for calling [Builder.userId] with `userId.orElse(null)`. */ + fun userId(userId: Optional) = userId(userId.getOrNull()) + + /** + * Sets [Builder.userId] to an arbitrary JSON value. + * + * You should usually call [Builder.userId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun userId(userId: JsonField) = apply { this.userId = userId } + + 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 + * .event() + * .messageId() + * .properties() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("event", event), + checkRequired("messageId", messageId), + checkRequired("properties", properties), + checkRequired("type", type), + userId, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + event() + messageId() + properties().validate() + type().validate() + userId() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (event.asKnown().isPresent) 1 else 0) + + (if (messageId.asKnown().isPresent) 1 else 0) + + (properties.asKnown().getOrNull()?.validity() ?: 0) + + (type.asKnown().getOrNull()?.validity() ?: 0) + + (if (userId.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + event == other.event && + messageId == other.messageId && + properties == other.properties && + type == other.type && + userId == other.userId && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(event, messageId, properties, type, userId, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{event=$event, messageId=$messageId, properties=$properties, type=$type, userId=$userId, additionalProperties=$additionalProperties}" + } + + class Properties + @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 [Properties]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Properties]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(properties: Properties) = apply { + additionalProperties = properties.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 [Properties]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Properties = Properties(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): Properties = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Properties && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Properties{additionalProperties=$additionalProperties}" + } + + 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 TRACK = of("track") + + @JvmStatic fun of(value: String) = Type(JsonField.of(value)) + } + + /** An enum containing [Type]'s known values. */ + enum class Known { + TRACK + } + + /** + * 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 { + TRACK, + /** 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) { + TRACK -> Value.TRACK + 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 CourierInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + TRACK -> Known.TRACK + else -> throw CourierInvalidDataException("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 CourierInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { CourierInvalidDataException("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: CourierInvalidDataException) { + 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 InboundTrackEventParams && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = Objects.hash(body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "InboundTrackEventParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/inbound/InboundTrackEventResponse.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/inbound/InboundTrackEventResponse.kt new file mode 100644 index 00000000..0021c852 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/inbound/InboundTrackEventResponse.kt @@ -0,0 +1,177 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.inbound + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkRequired +import com.courier.api.errors.CourierInvalidDataException +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 + +class InboundTrackEventResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val messageId: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("messageId") @ExcludeMissing messageId: JsonField = JsonMissing.of() + ) : this(messageId, mutableMapOf()) + + /** + * A successful call returns a `202` status code along with a `requestId` in the response body. + * + * @throws CourierInvalidDataException 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 messageId(): String = messageId.getRequired("messageId") + + /** + * Returns the raw JSON value of [messageId]. + * + * Unlike [messageId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("messageId") @ExcludeMissing fun _messageId(): JsonField = messageId + + @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 [InboundTrackEventResponse]. + * + * The following fields are required: + * ```java + * .messageId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [InboundTrackEventResponse]. */ + class Builder internal constructor() { + + private var messageId: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(inboundTrackEventResponse: InboundTrackEventResponse) = apply { + messageId = inboundTrackEventResponse.messageId + additionalProperties = inboundTrackEventResponse.additionalProperties.toMutableMap() + } + + /** + * A successful call returns a `202` status code along with a `requestId` in the response + * body. + */ + 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 } + + 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 [InboundTrackEventResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .messageId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): InboundTrackEventResponse = + InboundTrackEventResponse( + checkRequired("messageId", messageId), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): InboundTrackEventResponse = apply { + if (validated) { + return@apply + } + + messageId() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (messageId.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is InboundTrackEventResponse && + messageId == other.messageId && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(messageId, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "InboundTrackEventResponse{messageId=$messageId, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/lists/List.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/lists/List.kt new file mode 100644 index 00000000..b7713493 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/lists/List.kt @@ -0,0 +1,277 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.lists + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkRequired +import com.courier.api.errors.CourierInvalidDataException +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 List +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val id: JsonField, + private val name: JsonField, + private val created: JsonField, + private val updated: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("created") @ExcludeMissing created: JsonField = JsonMissing.of(), + @JsonProperty("updated") @ExcludeMissing updated: JsonField = JsonMissing.of(), + ) : this(id, name, created, updated, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 id(): String = id.getRequired("id") + + /** + * @throws CourierInvalidDataException 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 name(): String = name.getRequired("name") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun created(): Optional = created.getOptional("created") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun updated(): Optional = updated.getOptional("updated") + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + /** + * 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 [created]. + * + * Unlike [created], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created") @ExcludeMissing fun _created(): JsonField = created + + /** + * Returns the raw JSON value of [updated]. + * + * Unlike [updated], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("updated") @ExcludeMissing fun _updated(): JsonField = updated + + @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 [List]. + * + * The following fields are required: + * ```java + * .id() + * .name() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [List]. */ + class Builder internal constructor() { + + private var id: JsonField? = null + private var name: JsonField? = null + private var created: JsonField = JsonMissing.of() + private var updated: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(list: List) = apply { + id = list.id + name = list.name + created = list.created + updated = list.updated + additionalProperties = list.additionalProperties.toMutableMap() + } + + fun id(id: String) = id(JsonField.of(id)) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun id(id: JsonField) = apply { this.id = id } + + 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 } + + fun created(created: String?) = created(JsonField.ofNullable(created)) + + /** Alias for calling [Builder.created] with `created.orElse(null)`. */ + fun created(created: Optional) = created(created.getOrNull()) + + /** + * Sets [Builder.created] to an arbitrary JSON value. + * + * You should usually call [Builder.created] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun created(created: JsonField) = apply { this.created = created } + + fun updated(updated: String?) = updated(JsonField.ofNullable(updated)) + + /** Alias for calling [Builder.updated] with `updated.orElse(null)`. */ + fun updated(updated: Optional) = updated(updated.getOrNull()) + + /** + * Sets [Builder.updated] to an arbitrary JSON value. + * + * You should usually call [Builder.updated] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun updated(updated: JsonField) = apply { this.updated = updated } + + 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 [List]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .name() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): List = + List( + checkRequired("id", id), + checkRequired("name", name), + created, + updated, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): List = apply { + if (validated) { + return@apply + } + + id() + name() + created() + updated() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (id.asKnown().isPresent) 1 else 0) + + (if (name.asKnown().isPresent) 1 else 0) + + (if (created.asKnown().isPresent) 1 else 0) + + (if (updated.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is List && + id == other.id && + name == other.name && + created == other.created && + updated == other.updated && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(id, name, created, updated, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "List{id=$id, name=$name, created=$created, updated=$updated, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/lists/ListDeleteParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/lists/ListDeleteParams.kt new file mode 100644 index 00000000..d528739e --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/lists/ListDeleteParams.kt @@ -0,0 +1,229 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.lists + +import com.courier.api.core.JsonValue +import com.courier.api.core.Params +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import com.courier.api.core.toImmutable +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Delete a list by list ID. */ +class ListDeleteParams +private constructor( + private val listId: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, + private val additionalBodyProperties: Map, +) : Params { + + fun listId(): Optional = Optional.ofNullable(listId) + + /** 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(): ListDeleteParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [ListDeleteParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ListDeleteParams]. */ + class Builder internal constructor() { + + private var listId: 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(listDeleteParams: ListDeleteParams) = apply { + listId = listDeleteParams.listId + additionalHeaders = listDeleteParams.additionalHeaders.toBuilder() + additionalQueryParams = listDeleteParams.additionalQueryParams.toBuilder() + additionalBodyProperties = listDeleteParams.additionalBodyProperties.toMutableMap() + } + + fun listId(listId: String?) = apply { this.listId = listId } + + /** Alias for calling [Builder.listId] with `listId.orElse(null)`. */ + fun listId(listId: Optional) = listId(listId.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 [ListDeleteParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): ListDeleteParams = + ListDeleteParams( + listId, + additionalHeaders.build(), + additionalQueryParams.build(), + additionalBodyProperties.toImmutable(), + ) + } + + fun _body(): Optional> = + Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) + + fun _pathParam(index: Int): String = + when (index) { + 0 -> listId ?: "" + 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 ListDeleteParams && + listId == other.listId && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams && + additionalBodyProperties == other.additionalBodyProperties + } + + override fun hashCode(): Int = + Objects.hash(listId, additionalHeaders, additionalQueryParams, additionalBodyProperties) + + override fun toString() = + "ListDeleteParams{listId=$listId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/lists/ListListParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/lists/ListListParams.kt new file mode 100644 index 00000000..ed5ba28a --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/lists/ListListParams.kt @@ -0,0 +1,220 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.lists + +import com.courier.api.core.Params +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Returns all of the lists, with the ability to filter based on a pattern. */ +class ListListParams +private constructor( + private val cursor: String?, + private val pattern: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** A unique identifier that allows for fetching the next page of lists. */ + fun cursor(): Optional = Optional.ofNullable(cursor) + + /** + * "A pattern used to filter the list items returned. Pattern types supported: exact match on + * `list_id` or a pattern of one or more pattern parts. you may replace a part with either: `*` + * to match all parts in that position, or `**` to signify a wildcard `endsWith` pattern match." + */ + fun pattern(): Optional = Optional.ofNullable(pattern) + + /** 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(): ListListParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [ListListParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ListListParams]. */ + class Builder internal constructor() { + + private var cursor: String? = null + private var pattern: String? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(listListParams: ListListParams) = apply { + cursor = listListParams.cursor + pattern = listListParams.pattern + additionalHeaders = listListParams.additionalHeaders.toBuilder() + additionalQueryParams = listListParams.additionalQueryParams.toBuilder() + } + + /** A unique identifier that allows for fetching the next page of lists. */ + fun cursor(cursor: String?) = apply { this.cursor = cursor } + + /** Alias for calling [Builder.cursor] with `cursor.orElse(null)`. */ + fun cursor(cursor: Optional) = cursor(cursor.getOrNull()) + + /** + * "A pattern used to filter the list items returned. Pattern types supported: exact match + * on `list_id` or a pattern of one or more pattern parts. you may replace a part with + * either: `*` to match all parts in that position, or `**` to signify a wildcard `endsWith` + * pattern match." + */ + fun pattern(pattern: String?) = apply { this.pattern = pattern } + + /** Alias for calling [Builder.pattern] with `pattern.orElse(null)`. */ + fun pattern(pattern: Optional) = pattern(pattern.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 [ListListParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): ListListParams = + ListListParams( + cursor, + pattern, + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + cursor?.let { put("cursor", it) } + pattern?.let { put("pattern", it) } + putAll(additionalQueryParams) + } + .build() + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ListListParams && + cursor == other.cursor && + pattern == other.pattern && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(cursor, pattern, additionalHeaders, additionalQueryParams) + + override fun toString() = + "ListListParams{cursor=$cursor, pattern=$pattern, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/lists/ListListResponse.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/lists/ListListResponse.kt new file mode 100644 index 00000000..f7c1b69f --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/lists/ListListResponse.kt @@ -0,0 +1,222 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.lists + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkKnown +import com.courier.api.core.checkRequired +import com.courier.api.core.toImmutable +import com.courier.api.errors.CourierInvalidDataException +import com.courier.api.models.audiences.Paging +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 kotlin.jvm.optionals.getOrNull + +class ListListResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val items: JsonField>, + private val paging: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("items") @ExcludeMissing items: JsonField> = JsonMissing.of(), + @JsonProperty("paging") @ExcludeMissing paging: JsonField = JsonMissing.of(), + ) : this(items, paging, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 items(): List = items.getRequired("items") + + /** + * @throws CourierInvalidDataException 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 paging(): Paging = paging.getRequired("paging") + + /** + * Returns the raw JSON value of [items]. + * + * Unlike [items], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("items") @ExcludeMissing fun _items(): JsonField> = items + + /** + * Returns the raw JSON value of [paging]. + * + * Unlike [paging], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("paging") @ExcludeMissing fun _paging(): JsonField = paging + + @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 [ListListResponse]. + * + * The following fields are required: + * ```java + * .items() + * .paging() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ListListResponse]. */ + class Builder internal constructor() { + + private var items: JsonField>? = null + private var paging: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(listListResponse: ListListResponse) = apply { + items = listListResponse.items.map { it.toMutableList() } + paging = listListResponse.paging + additionalProperties = listListResponse.additionalProperties.toMutableMap() + } + + fun items(items: List) = items(JsonField.of(items)) + + /** + * Sets [Builder.items] to an arbitrary JSON value. + * + * You should usually call [Builder.items] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun items(items: JsonField>) = apply { + this.items = items.map { it.toMutableList() } + } + + /** + * Adds a single [List] to [items]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addItem(item: List) = apply { + items = + (items ?: JsonField.of(mutableListOf())).also { checkKnown("items", it).add(item) } + } + + fun paging(paging: Paging) = paging(JsonField.of(paging)) + + /** + * Sets [Builder.paging] to an arbitrary JSON value. + * + * You should usually call [Builder.paging] with a well-typed [Paging] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun paging(paging: JsonField) = apply { this.paging = paging } + + 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 [ListListResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .items() + * .paging() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ListListResponse = + ListListResponse( + checkRequired("items", items).map { it.toImmutable() }, + checkRequired("paging", paging), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): ListListResponse = apply { + if (validated) { + return@apply + } + + items().forEach { it.validate() } + paging().validate() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (items.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (paging.asKnown().getOrNull()?.validity() ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ListListResponse && + items == other.items && + paging == other.paging && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(items, paging, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ListListResponse{items=$items, paging=$paging, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/lists/ListRestoreParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/lists/ListRestoreParams.kt new file mode 100644 index 00000000..f2571912 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/lists/ListRestoreParams.kt @@ -0,0 +1,219 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.lists + +import com.courier.api.core.JsonValue +import com.courier.api.core.Params +import com.courier.api.core.checkRequired +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Restore a previously deleted list. */ +class ListRestoreParams +private constructor( + private val listId: String?, + private val body: JsonValue, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun listId(): Optional = Optional.ofNullable(listId) + + fun body(): JsonValue = body + + /** 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 [ListRestoreParams]. + * + * The following fields are required: + * ```java + * .body() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ListRestoreParams]. */ + class Builder internal constructor() { + + private var listId: String? = null + private var body: JsonValue? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(listRestoreParams: ListRestoreParams) = apply { + listId = listRestoreParams.listId + body = listRestoreParams.body + additionalHeaders = listRestoreParams.additionalHeaders.toBuilder() + additionalQueryParams = listRestoreParams.additionalQueryParams.toBuilder() + } + + fun listId(listId: String?) = apply { this.listId = listId } + + /** Alias for calling [Builder.listId] with `listId.orElse(null)`. */ + fun listId(listId: Optional) = listId(listId.getOrNull()) + + fun body(body: JsonValue) = apply { this.body = body } + + 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 [ListRestoreParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .body() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ListRestoreParams = + ListRestoreParams( + listId, + checkRequired("body", body), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): JsonValue = body + + fun _pathParam(index: Int): String = + when (index) { + 0 -> listId ?: "" + 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 ListRestoreParams && + listId == other.listId && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(listId, body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "ListRestoreParams{listId=$listId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/lists/ListRetrieveParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/lists/ListRetrieveParams.kt new file mode 100644 index 00000000..dfafc11c --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/lists/ListRetrieveParams.kt @@ -0,0 +1,189 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.lists + +import com.courier.api.core.Params +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Returns a list based on the list ID provided. */ +class ListRetrieveParams +private constructor( + private val listId: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun listId(): Optional = Optional.ofNullable(listId) + + /** 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(): ListRetrieveParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [ListRetrieveParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ListRetrieveParams]. */ + class Builder internal constructor() { + + private var listId: String? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(listRetrieveParams: ListRetrieveParams) = apply { + listId = listRetrieveParams.listId + additionalHeaders = listRetrieveParams.additionalHeaders.toBuilder() + additionalQueryParams = listRetrieveParams.additionalQueryParams.toBuilder() + } + + fun listId(listId: String?) = apply { this.listId = listId } + + /** Alias for calling [Builder.listId] with `listId.orElse(null)`. */ + fun listId(listId: Optional) = listId(listId.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 [ListRetrieveParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): ListRetrieveParams = + ListRetrieveParams(listId, additionalHeaders.build(), additionalQueryParams.build()) + } + + fun _pathParam(index: Int): String = + when (index) { + 0 -> listId ?: "" + 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 ListRetrieveParams && + listId == other.listId && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = Objects.hash(listId, additionalHeaders, additionalQueryParams) + + override fun toString() = + "ListRetrieveParams{listId=$listId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/lists/ListUpdateParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/lists/ListUpdateParams.kt new file mode 100644 index 00000000..e6d72757 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/lists/ListUpdateParams.kt @@ -0,0 +1,508 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.lists + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.Params +import com.courier.api.core.checkRequired +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import com.courier.api.errors.CourierInvalidDataException +import com.courier.api.models.lists.subscriptions.RecipientPreferences +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 or replace an existing list with the supplied values. */ +class ListUpdateParams +private constructor( + private val listId: String?, + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun listId(): Optional = Optional.ofNullable(listId) + + /** + * @throws CourierInvalidDataException 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 name(): String = body.name() + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun preferences(): Optional = body.preferences() + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _name(): JsonField = body._name() + + /** + * Returns the raw JSON value of [preferences]. + * + * Unlike [preferences], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _preferences(): JsonField = body._preferences() + + 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 [ListUpdateParams]. + * + * The following fields are required: + * ```java + * .name() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ListUpdateParams]. */ + class Builder internal constructor() { + + private var listId: 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(listUpdateParams: ListUpdateParams) = apply { + listId = listUpdateParams.listId + body = listUpdateParams.body.toBuilder() + additionalHeaders = listUpdateParams.additionalHeaders.toBuilder() + additionalQueryParams = listUpdateParams.additionalQueryParams.toBuilder() + } + + fun listId(listId: String?) = apply { this.listId = listId } + + /** Alias for calling [Builder.listId] with `listId.orElse(null)`. */ + fun listId(listId: Optional) = listId(listId.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: + * - [name] + * - [preferences] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + fun name(name: String) = apply { body.name(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 { body.name(name) } + + fun preferences(preferences: RecipientPreferences?) = apply { + body.preferences(preferences) + } + + /** Alias for calling [Builder.preferences] with `preferences.orElse(null)`. */ + fun preferences(preferences: Optional) = + preferences(preferences.getOrNull()) + + /** + * Sets [Builder.preferences] to an arbitrary JSON value. + * + * You should usually call [Builder.preferences] with a well-typed [RecipientPreferences] + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun preferences(preferences: JsonField) = apply { + body.preferences(preferences) + } + + 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 [ListUpdateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .name() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ListUpdateParams = + ListUpdateParams( + listId, + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): Body = body + + fun _pathParam(index: Int): String = + when (index) { + 0 -> listId ?: "" + else -> "" + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + class Body + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val name: JsonField, + private val preferences: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("preferences") + @ExcludeMissing + preferences: JsonField = JsonMissing.of(), + ) : this(name, preferences, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 name(): String = name.getRequired("name") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun preferences(): Optional = preferences.getOptional("preferences") + + /** + * 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 [preferences]. + * + * Unlike [preferences], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("preferences") + @ExcludeMissing + fun _preferences(): JsonField = preferences + + @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 + * .name() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var name: JsonField? = null + private var preferences: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + name = body.name + preferences = body.preferences + additionalProperties = body.additionalProperties.toMutableMap() + } + + 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 } + + fun preferences(preferences: RecipientPreferences?) = + preferences(JsonField.ofNullable(preferences)) + + /** Alias for calling [Builder.preferences] with `preferences.orElse(null)`. */ + fun preferences(preferences: Optional) = + preferences(preferences.getOrNull()) + + /** + * Sets [Builder.preferences] to an arbitrary JSON value. + * + * You should usually call [Builder.preferences] with a well-typed + * [RecipientPreferences] value instead. This method is primarily for setting the field + * to an undocumented or not yet supported value. + */ + fun preferences(preferences: JsonField) = apply { + this.preferences = preferences + } + + 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 + * .name() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body(checkRequired("name", name), preferences, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + name() + preferences().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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) + + (preferences.asKnown().getOrNull()?.validity() ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + name == other.name && + preferences == other.preferences && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(name, preferences, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{name=$name, preferences=$preferences, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ListUpdateParams && + listId == other.listId && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(listId, body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "ListUpdateParams{listId=$listId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/lists/subscriptions/NotificationPreferenceDetails.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/lists/subscriptions/NotificationPreferenceDetails.kt new file mode 100644 index 00000000..1117de10 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/lists/subscriptions/NotificationPreferenceDetails.kt @@ -0,0 +1,292 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.lists.subscriptions + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkKnown +import com.courier.api.core.checkRequired +import com.courier.api.core.toImmutable +import com.courier.api.errors.CourierInvalidDataException +import com.courier.api.models.ChannelPreference +import com.courier.api.models.Rule +import com.courier.api.models.users.preferences.PreferenceStatus +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 NotificationPreferenceDetails +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val status: JsonField, + private val channelPreferences: JsonField>, + private val rules: JsonField>, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("status") + @ExcludeMissing + status: JsonField = JsonMissing.of(), + @JsonProperty("channel_preferences") + @ExcludeMissing + channelPreferences: JsonField> = JsonMissing.of(), + @JsonProperty("rules") @ExcludeMissing rules: JsonField> = JsonMissing.of(), + ) : this(status, channelPreferences, rules, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 status(): PreferenceStatus = status.getRequired("status") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun channelPreferences(): Optional> = + channelPreferences.getOptional("channel_preferences") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun rules(): Optional> = rules.getOptional("rules") + + /** + * 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 [channelPreferences]. + * + * Unlike [channelPreferences], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("channel_preferences") + @ExcludeMissing + fun _channelPreferences(): JsonField> = channelPreferences + + /** + * Returns the raw JSON value of [rules]. + * + * Unlike [rules], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("rules") @ExcludeMissing fun _rules(): JsonField> = rules + + @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 + * [NotificationPreferenceDetails]. + * + * The following fields are required: + * ```java + * .status() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [NotificationPreferenceDetails]. */ + class Builder internal constructor() { + + private var status: JsonField? = null + private var channelPreferences: JsonField>? = null + private var rules: JsonField>? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(notificationPreferenceDetails: NotificationPreferenceDetails) = apply { + status = notificationPreferenceDetails.status + channelPreferences = + notificationPreferenceDetails.channelPreferences.map { it.toMutableList() } + rules = notificationPreferenceDetails.rules.map { it.toMutableList() } + additionalProperties = notificationPreferenceDetails.additionalProperties.toMutableMap() + } + + fun status(status: PreferenceStatus) = status(JsonField.of(status)) + + /** + * Sets [Builder.status] to an arbitrary JSON value. + * + * You should usually call [Builder.status] with a well-typed [PreferenceStatus] 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 channelPreferences(channelPreferences: List?) = + channelPreferences(JsonField.ofNullable(channelPreferences)) + + /** + * Alias for calling [Builder.channelPreferences] with `channelPreferences.orElse(null)`. + */ + fun channelPreferences(channelPreferences: Optional>) = + channelPreferences(channelPreferences.getOrNull()) + + /** + * Sets [Builder.channelPreferences] to an arbitrary JSON value. + * + * You should usually call [Builder.channelPreferences] with a well-typed + * `List` value instead. This method is primarily for setting the field + * to an undocumented or not yet supported value. + */ + fun channelPreferences(channelPreferences: JsonField>) = apply { + this.channelPreferences = channelPreferences.map { it.toMutableList() } + } + + /** + * Adds a single [ChannelPreference] to [channelPreferences]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addChannelPreference(channelPreference: ChannelPreference) = apply { + channelPreferences = + (channelPreferences ?: JsonField.of(mutableListOf())).also { + checkKnown("channelPreferences", it).add(channelPreference) + } + } + + fun rules(rules: List?) = rules(JsonField.ofNullable(rules)) + + /** Alias for calling [Builder.rules] with `rules.orElse(null)`. */ + fun rules(rules: Optional>) = rules(rules.getOrNull()) + + /** + * Sets [Builder.rules] to an arbitrary JSON value. + * + * You should usually call [Builder.rules] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun rules(rules: JsonField>) = apply { + this.rules = rules.map { it.toMutableList() } + } + + /** + * Adds a single [Rule] to [rules]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addRule(rule: Rule) = apply { + rules = + (rules ?: JsonField.of(mutableListOf())).also { checkKnown("rules", it).add(rule) } + } + + 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 [NotificationPreferenceDetails]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .status() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): NotificationPreferenceDetails = + NotificationPreferenceDetails( + checkRequired("status", status), + (channelPreferences ?: JsonMissing.of()).map { it.toImmutable() }, + (rules ?: JsonMissing.of()).map { it.toImmutable() }, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): NotificationPreferenceDetails = apply { + if (validated) { + return@apply + } + + status().validate() + channelPreferences().ifPresent { it.forEach { it.validate() } } + rules().ifPresent { it.forEach { it.validate() } } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (status.asKnown().getOrNull()?.validity() ?: 0) + + (channelPreferences.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (rules.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is NotificationPreferenceDetails && + status == other.status && + channelPreferences == other.channelPreferences && + rules == other.rules && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(status, channelPreferences, rules, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "NotificationPreferenceDetails{status=$status, channelPreferences=$channelPreferences, rules=$rules, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/lists/subscriptions/PutSubscriptionsRecipient.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/lists/subscriptions/PutSubscriptionsRecipient.kt new file mode 100644 index 00000000..6f14ed16 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/lists/subscriptions/PutSubscriptionsRecipient.kt @@ -0,0 +1,222 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.lists.subscriptions + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkRequired +import com.courier.api.errors.CourierInvalidDataException +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 PutSubscriptionsRecipient +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val recipientId: JsonField, + private val preferences: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("recipientId") + @ExcludeMissing + recipientId: JsonField = JsonMissing.of(), + @JsonProperty("preferences") + @ExcludeMissing + preferences: JsonField = JsonMissing.of(), + ) : this(recipientId, preferences, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 recipientId(): String = recipientId.getRequired("recipientId") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun preferences(): Optional = preferences.getOptional("preferences") + + /** + * Returns the raw JSON value of [recipientId]. + * + * Unlike [recipientId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("recipientId") @ExcludeMissing fun _recipientId(): JsonField = recipientId + + /** + * Returns the raw JSON value of [preferences]. + * + * Unlike [preferences], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("preferences") + @ExcludeMissing + fun _preferences(): JsonField = preferences + + @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 [PutSubscriptionsRecipient]. + * + * The following fields are required: + * ```java + * .recipientId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [PutSubscriptionsRecipient]. */ + class Builder internal constructor() { + + private var recipientId: JsonField? = null + private var preferences: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(putSubscriptionsRecipient: PutSubscriptionsRecipient) = apply { + recipientId = putSubscriptionsRecipient.recipientId + preferences = putSubscriptionsRecipient.preferences + additionalProperties = putSubscriptionsRecipient.additionalProperties.toMutableMap() + } + + fun recipientId(recipientId: String) = recipientId(JsonField.of(recipientId)) + + /** + * Sets [Builder.recipientId] to an arbitrary JSON value. + * + * You should usually call [Builder.recipientId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun recipientId(recipientId: JsonField) = apply { this.recipientId = recipientId } + + fun preferences(preferences: RecipientPreferences?) = + preferences(JsonField.ofNullable(preferences)) + + /** Alias for calling [Builder.preferences] with `preferences.orElse(null)`. */ + fun preferences(preferences: Optional) = + preferences(preferences.getOrNull()) + + /** + * Sets [Builder.preferences] to an arbitrary JSON value. + * + * You should usually call [Builder.preferences] with a well-typed [RecipientPreferences] + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun preferences(preferences: JsonField) = apply { + this.preferences = preferences + } + + 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 [PutSubscriptionsRecipient]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .recipientId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): PutSubscriptionsRecipient = + PutSubscriptionsRecipient( + checkRequired("recipientId", recipientId), + preferences, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): PutSubscriptionsRecipient = apply { + if (validated) { + return@apply + } + + recipientId() + preferences().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (recipientId.asKnown().isPresent) 1 else 0) + + (preferences.asKnown().getOrNull()?.validity() ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is PutSubscriptionsRecipient && + recipientId == other.recipientId && + preferences == other.preferences && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(recipientId, preferences, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "PutSubscriptionsRecipient{recipientId=$recipientId, preferences=$preferences, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/lists/subscriptions/RecipientPreferences.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/lists/subscriptions/RecipientPreferences.kt new file mode 100644 index 00000000..227752b7 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/lists/subscriptions/RecipientPreferences.kt @@ -0,0 +1,407 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.lists.subscriptions + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.toImmutable +import com.courier.api.errors.CourierInvalidDataException +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 RecipientPreferences +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val categories: JsonField, + private val notifications: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("categories") + @ExcludeMissing + categories: JsonField = JsonMissing.of(), + @JsonProperty("notifications") + @ExcludeMissing + notifications: JsonField = JsonMissing.of(), + ) : this(categories, notifications, mutableMapOf()) + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun categories(): Optional = categories.getOptional("categories") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun notifications(): Optional = notifications.getOptional("notifications") + + /** + * Returns the raw JSON value of [categories]. + * + * Unlike [categories], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("categories") + @ExcludeMissing + fun _categories(): JsonField = categories + + /** + * Returns the raw JSON value of [notifications]. + * + * Unlike [notifications], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("notifications") + @ExcludeMissing + fun _notifications(): JsonField = notifications + + @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 [RecipientPreferences]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [RecipientPreferences]. */ + class Builder internal constructor() { + + private var categories: JsonField = JsonMissing.of() + private var notifications: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(recipientPreferences: RecipientPreferences) = apply { + categories = recipientPreferences.categories + notifications = recipientPreferences.notifications + additionalProperties = recipientPreferences.additionalProperties.toMutableMap() + } + + fun categories(categories: Categories?) = categories(JsonField.ofNullable(categories)) + + /** Alias for calling [Builder.categories] with `categories.orElse(null)`. */ + fun categories(categories: Optional) = categories(categories.getOrNull()) + + /** + * Sets [Builder.categories] to an arbitrary JSON value. + * + * You should usually call [Builder.categories] with a well-typed [Categories] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun categories(categories: JsonField) = apply { this.categories = categories } + + fun notifications(notifications: Notifications?) = + notifications(JsonField.ofNullable(notifications)) + + /** Alias for calling [Builder.notifications] with `notifications.orElse(null)`. */ + fun notifications(notifications: Optional) = + notifications(notifications.getOrNull()) + + /** + * Sets [Builder.notifications] to an arbitrary JSON value. + * + * You should usually call [Builder.notifications] with a well-typed [Notifications] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun notifications(notifications: JsonField) = apply { + this.notifications = notifications + } + + 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 [RecipientPreferences]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): RecipientPreferences = + RecipientPreferences(categories, notifications, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): RecipientPreferences = apply { + if (validated) { + return@apply + } + + categories().ifPresent { it.validate() } + notifications().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (categories.asKnown().getOrNull()?.validity() ?: 0) + + (notifications.asKnown().getOrNull()?.validity() ?: 0) + + class Categories + @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 [Categories]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Categories]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(categories: Categories) = apply { + additionalProperties = categories.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 [Categories]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Categories = Categories(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): Categories = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Categories && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Categories{additionalProperties=$additionalProperties}" + } + + class Notifications + @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 [Notifications]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Notifications]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(notifications: Notifications) = apply { + additionalProperties = notifications.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 [Notifications]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Notifications = Notifications(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): Notifications = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Notifications && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Notifications{additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is RecipientPreferences && + categories == other.categories && + notifications == other.notifications && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(categories, notifications, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "RecipientPreferences{categories=$categories, notifications=$notifications, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/lists/subscriptions/SubscriptionAddParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/lists/subscriptions/SubscriptionAddParams.kt new file mode 100644 index 00000000..e53154a4 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/lists/subscriptions/SubscriptionAddParams.kt @@ -0,0 +1,473 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.lists.subscriptions + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.Params +import com.courier.api.core.checkKnown +import com.courier.api.core.checkRequired +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import com.courier.api.core.toImmutable +import com.courier.api.errors.CourierInvalidDataException +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 + +/** + * Subscribes additional users to the list, without modifying existing subscriptions. If the list + * does not exist, it will be automatically created. + */ +class SubscriptionAddParams +private constructor( + private val listId: String?, + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun listId(): Optional = Optional.ofNullable(listId) + + /** + * @throws CourierInvalidDataException 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 recipients(): List = body.recipients() + + /** + * Returns the raw JSON value of [recipients]. + * + * Unlike [recipients], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _recipients(): JsonField> = body._recipients() + + 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 [SubscriptionAddParams]. + * + * The following fields are required: + * ```java + * .recipients() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [SubscriptionAddParams]. */ + class Builder internal constructor() { + + private var listId: 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(subscriptionAddParams: SubscriptionAddParams) = apply { + listId = subscriptionAddParams.listId + body = subscriptionAddParams.body.toBuilder() + additionalHeaders = subscriptionAddParams.additionalHeaders.toBuilder() + additionalQueryParams = subscriptionAddParams.additionalQueryParams.toBuilder() + } + + fun listId(listId: String?) = apply { this.listId = listId } + + /** Alias for calling [Builder.listId] with `listId.orElse(null)`. */ + fun listId(listId: Optional) = listId(listId.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: + * - [recipients] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + fun recipients(recipients: List) = apply { + body.recipients(recipients) + } + + /** + * Sets [Builder.recipients] to an arbitrary JSON value. + * + * You should usually call [Builder.recipients] with a well-typed + * `List` value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun recipients(recipients: JsonField>) = apply { + body.recipients(recipients) + } + + /** + * Adds a single [PutSubscriptionsRecipient] to [recipients]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addRecipient(recipient: PutSubscriptionsRecipient) = apply { + body.addRecipient(recipient) + } + + 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 [SubscriptionAddParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .recipients() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): SubscriptionAddParams = + SubscriptionAddParams( + listId, + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): Body = body + + fun _pathParam(index: Int): String = + when (index) { + 0 -> listId ?: "" + else -> "" + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + class Body + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val recipients: JsonField>, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("recipients") + @ExcludeMissing + recipients: JsonField> = JsonMissing.of() + ) : this(recipients, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 recipients(): List = recipients.getRequired("recipients") + + /** + * Returns the raw JSON value of [recipients]. + * + * Unlike [recipients], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("recipients") + @ExcludeMissing + fun _recipients(): JsonField> = recipients + + @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 + * .recipients() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var recipients: JsonField>? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + recipients = body.recipients.map { it.toMutableList() } + additionalProperties = body.additionalProperties.toMutableMap() + } + + fun recipients(recipients: List) = + recipients(JsonField.of(recipients)) + + /** + * Sets [Builder.recipients] to an arbitrary JSON value. + * + * You should usually call [Builder.recipients] with a well-typed + * `List` value instead. This method is primarily for setting + * the field to an undocumented or not yet supported value. + */ + fun recipients(recipients: JsonField>) = apply { + this.recipients = recipients.map { it.toMutableList() } + } + + /** + * Adds a single [PutSubscriptionsRecipient] to [recipients]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addRecipient(recipient: PutSubscriptionsRecipient) = apply { + recipients = + (recipients ?: JsonField.of(mutableListOf())).also { + checkKnown("recipients", it).add(recipient) + } + } + + 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 + * .recipients() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("recipients", recipients).map { it.toImmutable() }, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + recipients().forEach { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (recipients.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + recipients == other.recipients && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(recipients, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{recipients=$recipients, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is SubscriptionAddParams && + listId == other.listId && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(listId, body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "SubscriptionAddParams{listId=$listId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/lists/subscriptions/SubscriptionListParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/lists/subscriptions/SubscriptionListParams.kt new file mode 100644 index 00000000..d0b88e1f --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/lists/subscriptions/SubscriptionListParams.kt @@ -0,0 +1,214 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.lists.subscriptions + +import com.courier.api.core.Params +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Get the list's subscriptions. */ +class SubscriptionListParams +private constructor( + private val listId: String?, + private val cursor: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun listId(): Optional = Optional.ofNullable(listId) + + /** A unique identifier that allows for fetching the next set of list subscriptions */ + fun cursor(): Optional = Optional.ofNullable(cursor) + + /** 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(): SubscriptionListParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [SubscriptionListParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [SubscriptionListParams]. */ + class Builder internal constructor() { + + private var listId: String? = null + private var cursor: String? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(subscriptionListParams: SubscriptionListParams) = apply { + listId = subscriptionListParams.listId + cursor = subscriptionListParams.cursor + additionalHeaders = subscriptionListParams.additionalHeaders.toBuilder() + additionalQueryParams = subscriptionListParams.additionalQueryParams.toBuilder() + } + + fun listId(listId: String?) = apply { this.listId = listId } + + /** Alias for calling [Builder.listId] with `listId.orElse(null)`. */ + fun listId(listId: Optional) = listId(listId.getOrNull()) + + /** A unique identifier that allows for fetching the next set of list subscriptions */ + fun cursor(cursor: String?) = apply { this.cursor = cursor } + + /** Alias for calling [Builder.cursor] with `cursor.orElse(null)`. */ + fun cursor(cursor: Optional) = cursor(cursor.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 [SubscriptionListParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): SubscriptionListParams = + SubscriptionListParams( + listId, + cursor, + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _pathParam(index: Int): String = + when (index) { + 0 -> listId ?: "" + else -> "" + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + cursor?.let { put("cursor", it) } + putAll(additionalQueryParams) + } + .build() + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is SubscriptionListParams && + listId == other.listId && + cursor == other.cursor && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(listId, cursor, additionalHeaders, additionalQueryParams) + + override fun toString() = + "SubscriptionListParams{listId=$listId, cursor=$cursor, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/lists/subscriptions/SubscriptionListResponse.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/lists/subscriptions/SubscriptionListResponse.kt new file mode 100644 index 00000000..3fc3f033 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/lists/subscriptions/SubscriptionListResponse.kt @@ -0,0 +1,467 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.lists.subscriptions + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkKnown +import com.courier.api.core.checkRequired +import com.courier.api.core.toImmutable +import com.courier.api.errors.CourierInvalidDataException +import com.courier.api.models.audiences.Paging +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 SubscriptionListResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val items: JsonField>, + private val paging: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("items") @ExcludeMissing items: JsonField> = JsonMissing.of(), + @JsonProperty("paging") @ExcludeMissing paging: JsonField = JsonMissing.of(), + ) : this(items, paging, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 items(): List = items.getRequired("items") + + /** + * @throws CourierInvalidDataException 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 paging(): Paging = paging.getRequired("paging") + + /** + * Returns the raw JSON value of [items]. + * + * Unlike [items], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("items") @ExcludeMissing fun _items(): JsonField> = items + + /** + * Returns the raw JSON value of [paging]. + * + * Unlike [paging], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("paging") @ExcludeMissing fun _paging(): JsonField = paging + + @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 [SubscriptionListResponse]. + * + * The following fields are required: + * ```java + * .items() + * .paging() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [SubscriptionListResponse]. */ + class Builder internal constructor() { + + private var items: JsonField>? = null + private var paging: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(subscriptionListResponse: SubscriptionListResponse) = apply { + items = subscriptionListResponse.items.map { it.toMutableList() } + paging = subscriptionListResponse.paging + additionalProperties = subscriptionListResponse.additionalProperties.toMutableMap() + } + + fun items(items: List) = items(JsonField.of(items)) + + /** + * Sets [Builder.items] to an arbitrary JSON value. + * + * You should usually call [Builder.items] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun items(items: JsonField>) = apply { + this.items = items.map { it.toMutableList() } + } + + /** + * Adds a single [Item] to [items]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addItem(item: Item) = apply { + items = + (items ?: JsonField.of(mutableListOf())).also { checkKnown("items", it).add(item) } + } + + fun paging(paging: Paging) = paging(JsonField.of(paging)) + + /** + * Sets [Builder.paging] to an arbitrary JSON value. + * + * You should usually call [Builder.paging] with a well-typed [Paging] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun paging(paging: JsonField) = apply { this.paging = paging } + + 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 [SubscriptionListResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .items() + * .paging() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): SubscriptionListResponse = + SubscriptionListResponse( + checkRequired("items", items).map { it.toImmutable() }, + checkRequired("paging", paging), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): SubscriptionListResponse = apply { + if (validated) { + return@apply + } + + items().forEach { it.validate() } + paging().validate() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (items.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (paging.asKnown().getOrNull()?.validity() ?: 0) + + class Item + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val recipientId: JsonField, + private val created: JsonField, + private val preferences: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("recipientId") + @ExcludeMissing + recipientId: JsonField = JsonMissing.of(), + @JsonProperty("created") @ExcludeMissing created: JsonField = JsonMissing.of(), + @JsonProperty("preferences") + @ExcludeMissing + preferences: JsonField = JsonMissing.of(), + ) : this(recipientId, created, preferences, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 recipientId(): String = recipientId.getRequired("recipientId") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun created(): Optional = created.getOptional("created") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun preferences(): Optional = preferences.getOptional("preferences") + + /** + * Returns the raw JSON value of [recipientId]. + * + * Unlike [recipientId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("recipientId") + @ExcludeMissing + fun _recipientId(): JsonField = recipientId + + /** + * Returns the raw JSON value of [created]. + * + * Unlike [created], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created") @ExcludeMissing fun _created(): JsonField = created + + /** + * Returns the raw JSON value of [preferences]. + * + * Unlike [preferences], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("preferences") + @ExcludeMissing + fun _preferences(): JsonField = preferences + + @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 [Item]. + * + * The following fields are required: + * ```java + * .recipientId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Item]. */ + class Builder internal constructor() { + + private var recipientId: JsonField? = null + private var created: JsonField = JsonMissing.of() + private var preferences: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(item: Item) = apply { + recipientId = item.recipientId + created = item.created + preferences = item.preferences + additionalProperties = item.additionalProperties.toMutableMap() + } + + fun recipientId(recipientId: String) = recipientId(JsonField.of(recipientId)) + + /** + * Sets [Builder.recipientId] to an arbitrary JSON value. + * + * You should usually call [Builder.recipientId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun recipientId(recipientId: JsonField) = apply { + this.recipientId = recipientId + } + + fun created(created: String?) = created(JsonField.ofNullable(created)) + + /** Alias for calling [Builder.created] with `created.orElse(null)`. */ + fun created(created: Optional) = created(created.getOrNull()) + + /** + * Sets [Builder.created] to an arbitrary JSON value. + * + * You should usually call [Builder.created] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun created(created: JsonField) = apply { this.created = created } + + fun preferences(preferences: RecipientPreferences?) = + preferences(JsonField.ofNullable(preferences)) + + /** Alias for calling [Builder.preferences] with `preferences.orElse(null)`. */ + fun preferences(preferences: Optional) = + preferences(preferences.getOrNull()) + + /** + * Sets [Builder.preferences] to an arbitrary JSON value. + * + * You should usually call [Builder.preferences] with a well-typed + * [RecipientPreferences] value instead. This method is primarily for setting the field + * to an undocumented or not yet supported value. + */ + fun preferences(preferences: JsonField) = apply { + this.preferences = preferences + } + + 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 [Item]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .recipientId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Item = + Item( + checkRequired("recipientId", recipientId), + created, + preferences, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Item = apply { + if (validated) { + return@apply + } + + recipientId() + created() + preferences().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (recipientId.asKnown().isPresent) 1 else 0) + + (if (created.asKnown().isPresent) 1 else 0) + + (preferences.asKnown().getOrNull()?.validity() ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Item && + recipientId == other.recipientId && + created == other.created && + preferences == other.preferences && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(recipientId, created, preferences, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Item{recipientId=$recipientId, created=$created, preferences=$preferences, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is SubscriptionListResponse && + items == other.items && + paging == other.paging && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(items, paging, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "SubscriptionListResponse{items=$items, paging=$paging, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/lists/subscriptions/SubscriptionSubscribeParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/lists/subscriptions/SubscriptionSubscribeParams.kt new file mode 100644 index 00000000..3e5e4186 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/lists/subscriptions/SubscriptionSubscribeParams.kt @@ -0,0 +1,473 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.lists.subscriptions + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.Params +import com.courier.api.core.checkKnown +import com.courier.api.core.checkRequired +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import com.courier.api.core.toImmutable +import com.courier.api.errors.CourierInvalidDataException +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 + +/** + * Subscribes the users to the list, overwriting existing subscriptions. If the list does not exist, + * it will be automatically created. + */ +class SubscriptionSubscribeParams +private constructor( + private val listId: String?, + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun listId(): Optional = Optional.ofNullable(listId) + + /** + * @throws CourierInvalidDataException 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 recipients(): List = body.recipients() + + /** + * Returns the raw JSON value of [recipients]. + * + * Unlike [recipients], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _recipients(): JsonField> = body._recipients() + + 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 [SubscriptionSubscribeParams]. + * + * The following fields are required: + * ```java + * .recipients() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [SubscriptionSubscribeParams]. */ + class Builder internal constructor() { + + private var listId: 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(subscriptionSubscribeParams: SubscriptionSubscribeParams) = apply { + listId = subscriptionSubscribeParams.listId + body = subscriptionSubscribeParams.body.toBuilder() + additionalHeaders = subscriptionSubscribeParams.additionalHeaders.toBuilder() + additionalQueryParams = subscriptionSubscribeParams.additionalQueryParams.toBuilder() + } + + fun listId(listId: String?) = apply { this.listId = listId } + + /** Alias for calling [Builder.listId] with `listId.orElse(null)`. */ + fun listId(listId: Optional) = listId(listId.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: + * - [recipients] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + fun recipients(recipients: List) = apply { + body.recipients(recipients) + } + + /** + * Sets [Builder.recipients] to an arbitrary JSON value. + * + * You should usually call [Builder.recipients] with a well-typed + * `List` value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun recipients(recipients: JsonField>) = apply { + body.recipients(recipients) + } + + /** + * Adds a single [PutSubscriptionsRecipient] to [recipients]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addRecipient(recipient: PutSubscriptionsRecipient) = apply { + body.addRecipient(recipient) + } + + 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 [SubscriptionSubscribeParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .recipients() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): SubscriptionSubscribeParams = + SubscriptionSubscribeParams( + listId, + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): Body = body + + fun _pathParam(index: Int): String = + when (index) { + 0 -> listId ?: "" + else -> "" + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + class Body + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val recipients: JsonField>, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("recipients") + @ExcludeMissing + recipients: JsonField> = JsonMissing.of() + ) : this(recipients, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 recipients(): List = recipients.getRequired("recipients") + + /** + * Returns the raw JSON value of [recipients]. + * + * Unlike [recipients], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("recipients") + @ExcludeMissing + fun _recipients(): JsonField> = recipients + + @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 + * .recipients() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var recipients: JsonField>? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + recipients = body.recipients.map { it.toMutableList() } + additionalProperties = body.additionalProperties.toMutableMap() + } + + fun recipients(recipients: List) = + recipients(JsonField.of(recipients)) + + /** + * Sets [Builder.recipients] to an arbitrary JSON value. + * + * You should usually call [Builder.recipients] with a well-typed + * `List` value instead. This method is primarily for setting + * the field to an undocumented or not yet supported value. + */ + fun recipients(recipients: JsonField>) = apply { + this.recipients = recipients.map { it.toMutableList() } + } + + /** + * Adds a single [PutSubscriptionsRecipient] to [recipients]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addRecipient(recipient: PutSubscriptionsRecipient) = apply { + recipients = + (recipients ?: JsonField.of(mutableListOf())).also { + checkKnown("recipients", it).add(recipient) + } + } + + 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 + * .recipients() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("recipients", recipients).map { it.toImmutable() }, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + recipients().forEach { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (recipients.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + recipients == other.recipients && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(recipients, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{recipients=$recipients, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is SubscriptionSubscribeParams && + listId == other.listId && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(listId, body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "SubscriptionSubscribeParams{listId=$listId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/lists/subscriptions/SubscriptionSubscribeUserParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/lists/subscriptions/SubscriptionSubscribeUserParams.kt new file mode 100644 index 00000000..c646c26c --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/lists/subscriptions/SubscriptionSubscribeUserParams.kt @@ -0,0 +1,452 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.lists.subscriptions + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.Params +import com.courier.api.core.checkRequired +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import com.courier.api.errors.CourierInvalidDataException +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 + +/** + * Subscribe a user to an existing list (note: if the List does not exist, it will be automatically + * created). + */ +class SubscriptionSubscribeUserParams +private constructor( + private val listId: String, + private val userId: String?, + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun listId(): String = listId + + fun userId(): Optional = Optional.ofNullable(userId) + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun preferences(): Optional = body.preferences() + + /** + * Returns the raw JSON value of [preferences]. + * + * Unlike [preferences], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _preferences(): JsonField = body._preferences() + + 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 + * [SubscriptionSubscribeUserParams]. + * + * The following fields are required: + * ```java + * .listId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [SubscriptionSubscribeUserParams]. */ + class Builder internal constructor() { + + private var listId: String? = null + private var userId: 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(subscriptionSubscribeUserParams: SubscriptionSubscribeUserParams) = + apply { + listId = subscriptionSubscribeUserParams.listId + userId = subscriptionSubscribeUserParams.userId + body = subscriptionSubscribeUserParams.body.toBuilder() + additionalHeaders = subscriptionSubscribeUserParams.additionalHeaders.toBuilder() + additionalQueryParams = + subscriptionSubscribeUserParams.additionalQueryParams.toBuilder() + } + + fun listId(listId: String) = apply { this.listId = listId } + + fun userId(userId: String?) = apply { this.userId = userId } + + /** Alias for calling [Builder.userId] with `userId.orElse(null)`. */ + fun userId(userId: Optional) = userId(userId.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: + * - [preferences] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + fun preferences(preferences: RecipientPreferences?) = apply { + body.preferences(preferences) + } + + /** Alias for calling [Builder.preferences] with `preferences.orElse(null)`. */ + fun preferences(preferences: Optional) = + preferences(preferences.getOrNull()) + + /** + * Sets [Builder.preferences] to an arbitrary JSON value. + * + * You should usually call [Builder.preferences] with a well-typed [RecipientPreferences] + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun preferences(preferences: JsonField) = apply { + body.preferences(preferences) + } + + 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 [SubscriptionSubscribeUserParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .listId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): SubscriptionSubscribeUserParams = + SubscriptionSubscribeUserParams( + checkRequired("listId", listId), + userId, + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): Body = body + + fun _pathParam(index: Int): String = + when (index) { + 0 -> listId + 1 -> userId ?: "" + else -> "" + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + class Body + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val preferences: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("preferences") + @ExcludeMissing + preferences: JsonField = JsonMissing.of() + ) : this(preferences, mutableMapOf()) + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun preferences(): Optional = preferences.getOptional("preferences") + + /** + * Returns the raw JSON value of [preferences]. + * + * Unlike [preferences], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("preferences") + @ExcludeMissing + fun _preferences(): JsonField = preferences + + @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 preferences: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + preferences = body.preferences + additionalProperties = body.additionalProperties.toMutableMap() + } + + fun preferences(preferences: RecipientPreferences?) = + preferences(JsonField.ofNullable(preferences)) + + /** Alias for calling [Builder.preferences] with `preferences.orElse(null)`. */ + fun preferences(preferences: Optional) = + preferences(preferences.getOrNull()) + + /** + * Sets [Builder.preferences] to an arbitrary JSON value. + * + * You should usually call [Builder.preferences] with a well-typed + * [RecipientPreferences] value instead. This method is primarily for setting the field + * to an undocumented or not yet supported value. + */ + fun preferences(preferences: JsonField) = apply { + this.preferences = preferences + } + + 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(preferences, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + preferences().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = (preferences.asKnown().getOrNull()?.validity() ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + preferences == other.preferences && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(preferences, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{preferences=$preferences, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is SubscriptionSubscribeUserParams && + listId == other.listId && + userId == other.userId && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(listId, userId, body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "SubscriptionSubscribeUserParams{listId=$listId, userId=$userId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/lists/subscriptions/SubscriptionUnsubscribeUserParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/lists/subscriptions/SubscriptionUnsubscribeUserParams.kt new file mode 100644 index 00000000..32972d56 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/lists/subscriptions/SubscriptionUnsubscribeUserParams.kt @@ -0,0 +1,262 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.lists.subscriptions + +import com.courier.api.core.JsonValue +import com.courier.api.core.Params +import com.courier.api.core.checkRequired +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import com.courier.api.core.toImmutable +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Delete a subscription to a list by list ID and user ID. */ +class SubscriptionUnsubscribeUserParams +private constructor( + private val listId: String, + private val userId: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, + private val additionalBodyProperties: Map, +) : Params { + + fun listId(): String = listId + + fun userId(): Optional = Optional.ofNullable(userId) + + /** 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 + * [SubscriptionUnsubscribeUserParams]. + * + * The following fields are required: + * ```java + * .listId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [SubscriptionUnsubscribeUserParams]. */ + class Builder internal constructor() { + + private var listId: String? = null + private var userId: 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(subscriptionUnsubscribeUserParams: SubscriptionUnsubscribeUserParams) = + apply { + listId = subscriptionUnsubscribeUserParams.listId + userId = subscriptionUnsubscribeUserParams.userId + additionalHeaders = subscriptionUnsubscribeUserParams.additionalHeaders.toBuilder() + additionalQueryParams = + subscriptionUnsubscribeUserParams.additionalQueryParams.toBuilder() + additionalBodyProperties = + subscriptionUnsubscribeUserParams.additionalBodyProperties.toMutableMap() + } + + fun listId(listId: String) = apply { this.listId = listId } + + fun userId(userId: String?) = apply { this.userId = userId } + + /** Alias for calling [Builder.userId] with `userId.orElse(null)`. */ + fun userId(userId: Optional) = userId(userId.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 [SubscriptionUnsubscribeUserParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .listId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): SubscriptionUnsubscribeUserParams = + SubscriptionUnsubscribeUserParams( + checkRequired("listId", listId), + userId, + additionalHeaders.build(), + additionalQueryParams.build(), + additionalBodyProperties.toImmutable(), + ) + } + + fun _body(): Optional> = + Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) + + fun _pathParam(index: Int): String = + when (index) { + 0 -> listId + 1 -> userId ?: "" + 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 SubscriptionUnsubscribeUserParams && + listId == other.listId && + userId == other.userId && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams && + additionalBodyProperties == other.additionalBodyProperties + } + + override fun hashCode(): Int = + Objects.hash( + listId, + userId, + additionalHeaders, + additionalQueryParams, + additionalBodyProperties, + ) + + override fun toString() = + "SubscriptionUnsubscribeUserParams{listId=$listId, userId=$userId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/messages/MessageCancelParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/messages/MessageCancelParams.kt new file mode 100644 index 00000000..20b8d109 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/messages/MessageCancelParams.kt @@ -0,0 +1,234 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.messages + +import com.courier.api.core.JsonValue +import com.courier.api.core.Params +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import com.courier.api.core.toImmutable +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * Cancel a message that is currently in the process of being delivered. A well-formatted API call + * to the cancel message API will return either `200` status code for a successful cancellation or + * `409` status code for an unsuccessful cancellation. Both cases will include the actual message + * record in the response body (see details below). + */ +class MessageCancelParams +private constructor( + private val messageId: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, + private val additionalBodyProperties: Map, +) : Params { + + fun messageId(): Optional = Optional.ofNullable(messageId) + + /** 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(): MessageCancelParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [MessageCancelParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [MessageCancelParams]. */ + class Builder internal constructor() { + + private var messageId: 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(messageCancelParams: MessageCancelParams) = apply { + messageId = messageCancelParams.messageId + additionalHeaders = messageCancelParams.additionalHeaders.toBuilder() + additionalQueryParams = messageCancelParams.additionalQueryParams.toBuilder() + additionalBodyProperties = messageCancelParams.additionalBodyProperties.toMutableMap() + } + + fun messageId(messageId: String?) = apply { this.messageId = messageId } + + /** Alias for calling [Builder.messageId] with `messageId.orElse(null)`. */ + fun messageId(messageId: Optional) = messageId(messageId.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 [MessageCancelParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): MessageCancelParams = + MessageCancelParams( + messageId, + additionalHeaders.build(), + additionalQueryParams.build(), + additionalBodyProperties.toImmutable(), + ) + } + + fun _body(): Optional> = + Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) + + fun _pathParam(index: Int): String = + when (index) { + 0 -> messageId ?: "" + 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 MessageCancelParams && + messageId == other.messageId && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams && + additionalBodyProperties == other.additionalBodyProperties + } + + override fun hashCode(): Int = + Objects.hash(messageId, additionalHeaders, additionalQueryParams, additionalBodyProperties) + + override fun toString() = + "MessageCancelParams{messageId=$messageId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/messages/MessageContentParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/messages/MessageContentParams.kt new file mode 100644 index 00000000..d05ee1e6 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/messages/MessageContentParams.kt @@ -0,0 +1,193 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.messages + +import com.courier.api.core.Params +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Get message content */ +class MessageContentParams +private constructor( + private val messageId: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun messageId(): Optional = Optional.ofNullable(messageId) + + /** 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(): MessageContentParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [MessageContentParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [MessageContentParams]. */ + class Builder internal constructor() { + + private var messageId: String? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(messageContentParams: MessageContentParams) = apply { + messageId = messageContentParams.messageId + additionalHeaders = messageContentParams.additionalHeaders.toBuilder() + additionalQueryParams = messageContentParams.additionalQueryParams.toBuilder() + } + + fun messageId(messageId: String?) = apply { this.messageId = messageId } + + /** Alias for calling [Builder.messageId] with `messageId.orElse(null)`. */ + fun messageId(messageId: Optional) = messageId(messageId.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 [MessageContentParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): MessageContentParams = + MessageContentParams( + messageId, + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _pathParam(index: Int): String = + when (index) { + 0 -> messageId ?: "" + 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 MessageContentParams && + messageId == other.messageId && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = Objects.hash(messageId, additionalHeaders, additionalQueryParams) + + override fun toString() = + "MessageContentParams{messageId=$messageId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/messages/MessageContentResponse.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/messages/MessageContentResponse.kt new file mode 100644 index 00000000..d27bc382 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/messages/MessageContentResponse.kt @@ -0,0 +1,1015 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.messages + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkKnown +import com.courier.api.core.checkRequired +import com.courier.api.core.toImmutable +import com.courier.api.errors.CourierInvalidDataException +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 kotlin.jvm.optionals.getOrNull + +class MessageContentResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val results: JsonField>, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("results") @ExcludeMissing results: JsonField> = JsonMissing.of() + ) : this(results, mutableMapOf()) + + /** + * An array of render output of a previously sent message. + * + * @throws CourierInvalidDataException 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 results(): List = results.getRequired("results") + + /** + * Returns the raw JSON value of [results]. + * + * Unlike [results], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("results") @ExcludeMissing fun _results(): JsonField> = results + + @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 [MessageContentResponse]. + * + * The following fields are required: + * ```java + * .results() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [MessageContentResponse]. */ + class Builder internal constructor() { + + private var results: JsonField>? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(messageContentResponse: MessageContentResponse) = apply { + results = messageContentResponse.results.map { it.toMutableList() } + additionalProperties = messageContentResponse.additionalProperties.toMutableMap() + } + + /** An array of render output of a previously sent message. */ + fun results(results: List) = results(JsonField.of(results)) + + /** + * Sets [Builder.results] to an arbitrary JSON value. + * + * You should usually call [Builder.results] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun results(results: JsonField>) = apply { + this.results = results.map { it.toMutableList() } + } + + /** + * Adds a single [Result] to [results]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addResult(result: Result) = apply { + results = + (results ?: JsonField.of(mutableListOf())).also { + checkKnown("results", it).add(result) + } + } + + 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 [MessageContentResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .results() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): MessageContentResponse = + MessageContentResponse( + checkRequired("results", results).map { it.toImmutable() }, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): MessageContentResponse = apply { + if (validated) { + return@apply + } + + results().forEach { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (results.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + class Result + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val channel: JsonField, + private val channelId: JsonField, + private val content: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("channel") @ExcludeMissing channel: JsonField = JsonMissing.of(), + @JsonProperty("channel_id") + @ExcludeMissing + channelId: JsonField = JsonMissing.of(), + @JsonProperty("content") @ExcludeMissing content: JsonField = JsonMissing.of(), + ) : this(channel, channelId, content, mutableMapOf()) + + /** + * The channel used for rendering the message. + * + * @throws CourierInvalidDataException 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 channel(): String = channel.getRequired("channel") + + /** + * The ID of channel used for rendering the message. + * + * @throws CourierInvalidDataException 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 channelId(): String = channelId.getRequired("channel_id") + + /** + * Content details of the rendered message. + * + * @throws CourierInvalidDataException 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 content(): Content = content.getRequired("content") + + /** + * Returns the raw JSON value of [channel]. + * + * Unlike [channel], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("channel") @ExcludeMissing fun _channel(): JsonField = channel + + /** + * Returns the raw JSON value of [channelId]. + * + * Unlike [channelId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("channel_id") @ExcludeMissing fun _channelId(): JsonField = channelId + + /** + * Returns the raw JSON value of [content]. + * + * Unlike [content], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("content") @ExcludeMissing fun _content(): JsonField = content + + @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 [Result]. + * + * The following fields are required: + * ```java + * .channel() + * .channelId() + * .content() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Result]. */ + class Builder internal constructor() { + + private var channel: JsonField? = null + private var channelId: JsonField? = null + private var content: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(result: Result) = apply { + channel = result.channel + channelId = result.channelId + content = result.content + additionalProperties = result.additionalProperties.toMutableMap() + } + + /** The channel used for rendering the message. */ + fun channel(channel: String) = channel(JsonField.of(channel)) + + /** + * Sets [Builder.channel] to an arbitrary JSON value. + * + * You should usually call [Builder.channel] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun channel(channel: JsonField) = apply { this.channel = channel } + + /** The ID of channel used for rendering the message. */ + fun channelId(channelId: String) = channelId(JsonField.of(channelId)) + + /** + * Sets [Builder.channelId] to an arbitrary JSON value. + * + * You should usually call [Builder.channelId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun channelId(channelId: JsonField) = apply { this.channelId = channelId } + + /** Content details of the rendered message. */ + fun content(content: Content) = content(JsonField.of(content)) + + /** + * Sets [Builder.content] to an arbitrary JSON value. + * + * You should usually call [Builder.content] with a well-typed [Content] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun content(content: JsonField) = apply { this.content = content } + + 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 [Result]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .channel() + * .channelId() + * .content() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Result = + Result( + checkRequired("channel", channel), + checkRequired("channelId", channelId), + checkRequired("content", content), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Result = apply { + if (validated) { + return@apply + } + + channel() + channelId() + content().validate() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (channel.asKnown().isPresent) 1 else 0) + + (if (channelId.asKnown().isPresent) 1 else 0) + + (content.asKnown().getOrNull()?.validity() ?: 0) + + /** Content details of the rendered message. */ + class Content + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val blocks: JsonField>, + private val body: JsonField, + private val html: JsonField, + private val subject: JsonField, + private val text: JsonField, + private val title: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("blocks") + @ExcludeMissing + blocks: JsonField> = JsonMissing.of(), + @JsonProperty("body") @ExcludeMissing body: JsonField = JsonMissing.of(), + @JsonProperty("html") @ExcludeMissing html: JsonField = JsonMissing.of(), + @JsonProperty("subject") + @ExcludeMissing + subject: JsonField = JsonMissing.of(), + @JsonProperty("text") @ExcludeMissing text: JsonField = JsonMissing.of(), + @JsonProperty("title") @ExcludeMissing title: JsonField = JsonMissing.of(), + ) : this(blocks, body, html, subject, text, title, mutableMapOf()) + + /** + * The blocks of the rendered message. + * + * @throws CourierInvalidDataException 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 blocks(): List = blocks.getRequired("blocks") + + /** + * The body of the rendered message. + * + * @throws CourierInvalidDataException 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 body(): String = body.getRequired("body") + + /** + * The html content of the rendered message. + * + * @throws CourierInvalidDataException 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 html(): String = html.getRequired("html") + + /** + * The subject of the rendered message. + * + * @throws CourierInvalidDataException 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 subject(): String = subject.getRequired("subject") + + /** + * The text of the rendered message. + * + * @throws CourierInvalidDataException 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 text(): String = text.getRequired("text") + + /** + * The title of the rendered message. + * + * @throws CourierInvalidDataException 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 title(): String = title.getRequired("title") + + /** + * Returns the raw JSON value of [blocks]. + * + * Unlike [blocks], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("blocks") @ExcludeMissing fun _blocks(): JsonField> = blocks + + /** + * Returns the raw JSON value of [body]. + * + * Unlike [body], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("body") @ExcludeMissing fun _body(): JsonField = body + + /** + * Returns the raw JSON value of [html]. + * + * Unlike [html], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("html") @ExcludeMissing fun _html(): JsonField = html + + /** + * Returns the raw JSON value of [subject]. + * + * Unlike [subject], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("subject") @ExcludeMissing fun _subject(): JsonField = subject + + /** + * Returns the raw JSON value of [text]. + * + * Unlike [text], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("text") @ExcludeMissing fun _text(): JsonField = text + + /** + * Returns the raw JSON value of [title]. + * + * Unlike [title], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("title") @ExcludeMissing fun _title(): JsonField = title + + @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 [Content]. + * + * The following fields are required: + * ```java + * .blocks() + * .body() + * .html() + * .subject() + * .text() + * .title() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Content]. */ + class Builder internal constructor() { + + private var blocks: JsonField>? = null + private var body: JsonField? = null + private var html: JsonField? = null + private var subject: JsonField? = null + private var text: JsonField? = null + private var title: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(content: Content) = apply { + blocks = content.blocks.map { it.toMutableList() } + body = content.body + html = content.html + subject = content.subject + text = content.text + title = content.title + additionalProperties = content.additionalProperties.toMutableMap() + } + + /** The blocks of the rendered message. */ + fun blocks(blocks: List) = blocks(JsonField.of(blocks)) + + /** + * Sets [Builder.blocks] to an arbitrary JSON value. + * + * You should usually call [Builder.blocks] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun blocks(blocks: JsonField>) = apply { + this.blocks = blocks.map { it.toMutableList() } + } + + /** + * Adds a single [Block] to [blocks]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addBlock(block: Block) = apply { + blocks = + (blocks ?: JsonField.of(mutableListOf())).also { + checkKnown("blocks", it).add(block) + } + } + + /** The body of the rendered message. */ + fun body(body: String) = body(JsonField.of(body)) + + /** + * Sets [Builder.body] to an arbitrary JSON value. + * + * You should usually call [Builder.body] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun body(body: JsonField) = apply { this.body = body } + + /** The html content of the rendered message. */ + fun html(html: String) = html(JsonField.of(html)) + + /** + * Sets [Builder.html] to an arbitrary JSON value. + * + * You should usually call [Builder.html] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun html(html: JsonField) = apply { this.html = html } + + /** The subject of the rendered message. */ + fun subject(subject: String) = subject(JsonField.of(subject)) + + /** + * Sets [Builder.subject] to an arbitrary JSON value. + * + * You should usually call [Builder.subject] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun subject(subject: JsonField) = apply { this.subject = subject } + + /** The text of the rendered message. */ + fun text(text: String) = text(JsonField.of(text)) + + /** + * Sets [Builder.text] to an arbitrary JSON value. + * + * You should usually call [Builder.text] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun text(text: JsonField) = apply { this.text = text } + + /** The title of the rendered message. */ + fun title(title: String) = title(JsonField.of(title)) + + /** + * Sets [Builder.title] to an arbitrary JSON value. + * + * You should usually call [Builder.title] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun title(title: JsonField) = apply { this.title = title } + + 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 [Content]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .blocks() + * .body() + * .html() + * .subject() + * .text() + * .title() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Content = + Content( + checkRequired("blocks", blocks).map { it.toImmutable() }, + checkRequired("body", body), + checkRequired("html", html), + checkRequired("subject", subject), + checkRequired("text", text), + checkRequired("title", title), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Content = apply { + if (validated) { + return@apply + } + + blocks().forEach { it.validate() } + body() + html() + subject() + text() + title() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (blocks.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (body.asKnown().isPresent) 1 else 0) + + (if (html.asKnown().isPresent) 1 else 0) + + (if (subject.asKnown().isPresent) 1 else 0) + + (if (text.asKnown().isPresent) 1 else 0) + + (if (title.asKnown().isPresent) 1 else 0) + + class Block + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val text: JsonField, + private val type: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("text") + @ExcludeMissing + text: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), + ) : this(text, type, mutableMapOf()) + + /** + * The block text of the rendered message block. + * + * @throws CourierInvalidDataException 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 text(): String = text.getRequired("text") + + /** + * The block type of the rendered message block. + * + * @throws CourierInvalidDataException 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 type(): String = type.getRequired("type") + + /** + * Returns the raw JSON value of [text]. + * + * Unlike [text], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("text") @ExcludeMissing fun _text(): JsonField = text + + /** + * 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 + + @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 [Block]. + * + * The following fields are required: + * ```java + * .text() + * .type() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Block]. */ + class Builder internal constructor() { + + private var text: JsonField? = null + private var type: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(block: Block) = apply { + text = block.text + type = block.type + additionalProperties = block.additionalProperties.toMutableMap() + } + + /** The block text of the rendered message block. */ + fun text(text: String) = text(JsonField.of(text)) + + /** + * Sets [Builder.text] to an arbitrary JSON value. + * + * You should usually call [Builder.text] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun text(text: JsonField) = apply { this.text = text } + + /** The block type of the rendered message block. */ + 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 } + + 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 [Block]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .text() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Block = + Block( + checkRequired("text", text), + checkRequired("type", type), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Block = apply { + if (validated) { + return@apply + } + + text() + type() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (text.asKnown().isPresent) 1 else 0) + + (if (type.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Block && + text == other.text && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(text, type, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Block{text=$text, type=$type, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Content && + blocks == other.blocks && + body == other.body && + html == other.html && + subject == other.subject && + text == other.text && + title == other.title && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(blocks, body, html, subject, text, title, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Content{blocks=$blocks, body=$body, html=$html, subject=$subject, text=$text, title=$title, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Result && + channel == other.channel && + channelId == other.channelId && + content == other.content && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(channel, channelId, content, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Result{channel=$channel, channelId=$channelId, content=$content, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is MessageContentResponse && + results == other.results && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(results, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "MessageContentResponse{results=$results, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/messages/MessageDetails.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/messages/MessageDetails.kt new file mode 100644 index 00000000..fcdf2c21 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/messages/MessageDetails.kt @@ -0,0 +1,1009 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.messages + +import com.courier.api.core.Enum +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkRequired +import com.courier.api.errors.CourierInvalidDataException +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 MessageDetails +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val id: JsonField, + private val clicked: JsonField, + private val delivered: JsonField, + private val enqueued: JsonField, + private val event: JsonField, + private val notification: JsonField, + private val opened: JsonField, + private val recipient: JsonField, + private val sent: JsonField, + private val status: JsonField, + private val error: JsonField, + private val reason: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("clicked") @ExcludeMissing clicked: JsonField = JsonMissing.of(), + @JsonProperty("delivered") @ExcludeMissing delivered: JsonField = JsonMissing.of(), + @JsonProperty("enqueued") @ExcludeMissing enqueued: JsonField = JsonMissing.of(), + @JsonProperty("event") @ExcludeMissing event: JsonField = JsonMissing.of(), + @JsonProperty("notification") + @ExcludeMissing + notification: JsonField = JsonMissing.of(), + @JsonProperty("opened") @ExcludeMissing opened: JsonField = JsonMissing.of(), + @JsonProperty("recipient") @ExcludeMissing recipient: JsonField = JsonMissing.of(), + @JsonProperty("sent") @ExcludeMissing sent: JsonField = JsonMissing.of(), + @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(), + @JsonProperty("error") @ExcludeMissing error: JsonField = JsonMissing.of(), + @JsonProperty("reason") @ExcludeMissing reason: JsonField = JsonMissing.of(), + ) : this( + id, + clicked, + delivered, + enqueued, + event, + notification, + opened, + recipient, + sent, + status, + error, + reason, + mutableMapOf(), + ) + + /** + * A unique identifier associated with the message you wish to retrieve (results from a send). + * + * @throws CourierInvalidDataException 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 id(): String = id.getRequired("id") + + /** + * A UTC timestamp at which the recipient clicked on a tracked link for the first time. Stored + * as a millisecond representation of the Unix epoch. + * + * @throws CourierInvalidDataException 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 clicked(): Long = clicked.getRequired("clicked") + + /** + * A UTC timestamp at which the Integration provider delivered the message. Stored as a + * millisecond representation of the Unix epoch. + * + * @throws CourierInvalidDataException 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 delivered(): Long = delivered.getRequired("delivered") + + /** + * A UTC timestamp at which Courier received the message request. Stored as a millisecond + * representation of the Unix epoch. + * + * @throws CourierInvalidDataException 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 enqueued(): Long = enqueued.getRequired("enqueued") + + /** + * A unique identifier associated with the event of the delivered message. + * + * @throws CourierInvalidDataException 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 event(): String = event.getRequired("event") + + /** + * A unique identifier associated with the notification of the delivered message. + * + * @throws CourierInvalidDataException 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 notification(): String = notification.getRequired("notification") + + /** + * A UTC timestamp at which the recipient opened a message for the first time. Stored as a + * millisecond representation of the Unix epoch. + * + * @throws CourierInvalidDataException 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 opened(): Long = opened.getRequired("opened") + + /** + * A unique identifier associated with the recipient of the delivered message. + * + * @throws CourierInvalidDataException 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 recipient(): String = recipient.getRequired("recipient") + + /** + * A UTC timestamp at which Courier passed the message to the Integration provider. Stored as a + * millisecond representation of the Unix epoch. + * + * @throws CourierInvalidDataException 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 sent(): Long = sent.getRequired("sent") + + /** + * The current status of the message. + * + * @throws CourierInvalidDataException 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 status(): Status = status.getRequired("status") + + /** + * A message describing the error that occurred. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun error(): Optional = error.getOptional("error") + + /** + * The reason for the current status of the message. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun reason(): Optional = reason.getOptional("reason") + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + /** + * Returns the raw JSON value of [clicked]. + * + * Unlike [clicked], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("clicked") @ExcludeMissing fun _clicked(): JsonField = clicked + + /** + * Returns the raw JSON value of [delivered]. + * + * Unlike [delivered], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("delivered") @ExcludeMissing fun _delivered(): JsonField = delivered + + /** + * Returns the raw JSON value of [enqueued]. + * + * Unlike [enqueued], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("enqueued") @ExcludeMissing fun _enqueued(): JsonField = enqueued + + /** + * Returns the raw JSON value of [event]. + * + * Unlike [event], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("event") @ExcludeMissing fun _event(): JsonField = event + + /** + * Returns the raw JSON value of [notification]. + * + * Unlike [notification], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("notification") + @ExcludeMissing + fun _notification(): JsonField = notification + + /** + * Returns the raw JSON value of [opened]. + * + * Unlike [opened], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("opened") @ExcludeMissing fun _opened(): JsonField = opened + + /** + * Returns the raw JSON value of [recipient]. + * + * Unlike [recipient], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("recipient") @ExcludeMissing fun _recipient(): JsonField = recipient + + /** + * Returns the raw JSON value of [sent]. + * + * Unlike [sent], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("sent") @ExcludeMissing fun _sent(): JsonField = sent + + /** + * 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 [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 [reason]. + * + * Unlike [reason], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("reason") @ExcludeMissing fun _reason(): JsonField = reason + + @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 [MessageDetails]. + * + * The following fields are required: + * ```java + * .id() + * .clicked() + * .delivered() + * .enqueued() + * .event() + * .notification() + * .opened() + * .recipient() + * .sent() + * .status() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [MessageDetails]. */ + class Builder internal constructor() { + + private var id: JsonField? = null + private var clicked: JsonField? = null + private var delivered: JsonField? = null + private var enqueued: JsonField? = null + private var event: JsonField? = null + private var notification: JsonField? = null + private var opened: JsonField? = null + private var recipient: JsonField? = null + private var sent: JsonField? = null + private var status: JsonField? = null + private var error: JsonField = JsonMissing.of() + private var reason: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(messageDetails: MessageDetails) = apply { + id = messageDetails.id + clicked = messageDetails.clicked + delivered = messageDetails.delivered + enqueued = messageDetails.enqueued + event = messageDetails.event + notification = messageDetails.notification + opened = messageDetails.opened + recipient = messageDetails.recipient + sent = messageDetails.sent + status = messageDetails.status + error = messageDetails.error + reason = messageDetails.reason + additionalProperties = messageDetails.additionalProperties.toMutableMap() + } + + /** + * A unique identifier associated with the message you wish to retrieve (results from a + * send). + */ + fun id(id: String) = id(JsonField.of(id)) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun id(id: JsonField) = apply { this.id = id } + + /** + * A UTC timestamp at which the recipient clicked on a tracked link for the first time. + * Stored as a millisecond representation of the Unix epoch. + */ + fun clicked(clicked: Long) = clicked(JsonField.of(clicked)) + + /** + * Sets [Builder.clicked] to an arbitrary JSON value. + * + * You should usually call [Builder.clicked] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun clicked(clicked: JsonField) = apply { this.clicked = clicked } + + /** + * A UTC timestamp at which the Integration provider delivered the message. Stored as a + * millisecond representation of the Unix epoch. + */ + fun delivered(delivered: Long) = delivered(JsonField.of(delivered)) + + /** + * Sets [Builder.delivered] to an arbitrary JSON value. + * + * You should usually call [Builder.delivered] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun delivered(delivered: JsonField) = apply { this.delivered = delivered } + + /** + * A UTC timestamp at which Courier received the message request. Stored as a millisecond + * representation of the Unix epoch. + */ + fun enqueued(enqueued: Long) = enqueued(JsonField.of(enqueued)) + + /** + * Sets [Builder.enqueued] to an arbitrary JSON value. + * + * You should usually call [Builder.enqueued] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun enqueued(enqueued: JsonField) = apply { this.enqueued = enqueued } + + /** A unique identifier associated with the event of the delivered message. */ + fun event(event: String) = event(JsonField.of(event)) + + /** + * Sets [Builder.event] to an arbitrary JSON value. + * + * You should usually call [Builder.event] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun event(event: JsonField) = apply { this.event = event } + + /** A unique identifier associated with the notification of the delivered message. */ + fun notification(notification: String) = notification(JsonField.of(notification)) + + /** + * Sets [Builder.notification] to an arbitrary JSON value. + * + * You should usually call [Builder.notification] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun notification(notification: JsonField) = apply { + this.notification = notification + } + + /** + * A UTC timestamp at which the recipient opened a message for the first time. Stored as a + * millisecond representation of the Unix epoch. + */ + fun opened(opened: Long) = opened(JsonField.of(opened)) + + /** + * Sets [Builder.opened] to an arbitrary JSON value. + * + * You should usually call [Builder.opened] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun opened(opened: JsonField) = apply { this.opened = opened } + + /** A unique identifier associated with the recipient of the delivered message. */ + fun recipient(recipient: String) = recipient(JsonField.of(recipient)) + + /** + * Sets [Builder.recipient] to an arbitrary JSON value. + * + * You should usually call [Builder.recipient] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun recipient(recipient: JsonField) = apply { this.recipient = recipient } + + /** + * A UTC timestamp at which Courier passed the message to the Integration provider. Stored + * as a millisecond representation of the Unix epoch. + */ + fun sent(sent: Long) = sent(JsonField.of(sent)) + + /** + * Sets [Builder.sent] to an arbitrary JSON value. + * + * You should usually call [Builder.sent] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun sent(sent: JsonField) = apply { this.sent = sent } + + /** The current status of the message. */ + 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 } + + /** A message describing the error that occurred. */ + fun error(error: String?) = error(JsonField.ofNullable(error)) + + /** Alias for calling [Builder.error] with `error.orElse(null)`. */ + fun error(error: Optional) = error(error.getOrNull()) + + /** + * 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 } + + /** The reason for the current status of the message. */ + fun reason(reason: Reason?) = reason(JsonField.ofNullable(reason)) + + /** Alias for calling [Builder.reason] with `reason.orElse(null)`. */ + fun reason(reason: Optional) = reason(reason.getOrNull()) + + /** + * Sets [Builder.reason] to an arbitrary JSON value. + * + * You should usually call [Builder.reason] with a well-typed [Reason] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun reason(reason: JsonField) = apply { this.reason = reason } + + 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 [MessageDetails]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .clicked() + * .delivered() + * .enqueued() + * .event() + * .notification() + * .opened() + * .recipient() + * .sent() + * .status() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): MessageDetails = + MessageDetails( + checkRequired("id", id), + checkRequired("clicked", clicked), + checkRequired("delivered", delivered), + checkRequired("enqueued", enqueued), + checkRequired("event", event), + checkRequired("notification", notification), + checkRequired("opened", opened), + checkRequired("recipient", recipient), + checkRequired("sent", sent), + checkRequired("status", status), + error, + reason, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): MessageDetails = apply { + if (validated) { + return@apply + } + + id() + clicked() + delivered() + enqueued() + event() + notification() + opened() + recipient() + sent() + status().validate() + error() + reason().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (id.asKnown().isPresent) 1 else 0) + + (if (clicked.asKnown().isPresent) 1 else 0) + + (if (delivered.asKnown().isPresent) 1 else 0) + + (if (enqueued.asKnown().isPresent) 1 else 0) + + (if (event.asKnown().isPresent) 1 else 0) + + (if (notification.asKnown().isPresent) 1 else 0) + + (if (opened.asKnown().isPresent) 1 else 0) + + (if (recipient.asKnown().isPresent) 1 else 0) + + (if (sent.asKnown().isPresent) 1 else 0) + + (status.asKnown().getOrNull()?.validity() ?: 0) + + (if (error.asKnown().isPresent) 1 else 0) + + (reason.asKnown().getOrNull()?.validity() ?: 0) + + /** The current status of the message. */ + 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 CANCELED = of("CANCELED") + + @JvmField val CLICKED = of("CLICKED") + + @JvmField val DELAYED = of("DELAYED") + + @JvmField val DELIVERED = of("DELIVERED") + + @JvmField val DIGESTED = of("DIGESTED") + + @JvmField val ENQUEUED = of("ENQUEUED") + + @JvmField val FILTERED = of("FILTERED") + + @JvmField val OPENED = of("OPENED") + + @JvmField val ROUTED = of("ROUTED") + + @JvmField val SENT = of("SENT") + + @JvmField val SIMULATED = of("SIMULATED") + + @JvmField val THROTTLED = of("THROTTLED") + + @JvmField val UNDELIVERABLE = of("UNDELIVERABLE") + + @JvmField val UNMAPPED = of("UNMAPPED") + + @JvmField val UNROUTABLE = of("UNROUTABLE") + + @JvmStatic fun of(value: String) = Status(JsonField.of(value)) + } + + /** An enum containing [Status]'s known values. */ + enum class Known { + CANCELED, + CLICKED, + DELAYED, + DELIVERED, + DIGESTED, + ENQUEUED, + FILTERED, + OPENED, + ROUTED, + SENT, + SIMULATED, + THROTTLED, + UNDELIVERABLE, + UNMAPPED, + UNROUTABLE, + } + + /** + * 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 { + CANCELED, + CLICKED, + DELAYED, + DELIVERED, + DIGESTED, + ENQUEUED, + FILTERED, + OPENED, + ROUTED, + SENT, + SIMULATED, + THROTTLED, + UNDELIVERABLE, + UNMAPPED, + UNROUTABLE, + /** 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) { + CANCELED -> Value.CANCELED + CLICKED -> Value.CLICKED + DELAYED -> Value.DELAYED + DELIVERED -> Value.DELIVERED + DIGESTED -> Value.DIGESTED + ENQUEUED -> Value.ENQUEUED + FILTERED -> Value.FILTERED + OPENED -> Value.OPENED + ROUTED -> Value.ROUTED + SENT -> Value.SENT + SIMULATED -> Value.SIMULATED + THROTTLED -> Value.THROTTLED + UNDELIVERABLE -> Value.UNDELIVERABLE + UNMAPPED -> Value.UNMAPPED + UNROUTABLE -> Value.UNROUTABLE + 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 CourierInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + CANCELED -> Known.CANCELED + CLICKED -> Known.CLICKED + DELAYED -> Known.DELAYED + DELIVERED -> Known.DELIVERED + DIGESTED -> Known.DIGESTED + ENQUEUED -> Known.ENQUEUED + FILTERED -> Known.FILTERED + OPENED -> Known.OPENED + ROUTED -> Known.ROUTED + SENT -> Known.SENT + SIMULATED -> Known.SIMULATED + THROTTLED -> Known.THROTTLED + UNDELIVERABLE -> Known.UNDELIVERABLE + UNMAPPED -> Known.UNMAPPED + UNROUTABLE -> Known.UNROUTABLE + else -> throw CourierInvalidDataException("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 CourierInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { CourierInvalidDataException("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: CourierInvalidDataException) { + 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() + } + + /** The reason for the current status of the message. */ + class Reason @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 BOUNCED = of("BOUNCED") + + @JvmField val FAILED = of("FAILED") + + @JvmField val FILTERED = of("FILTERED") + + @JvmField val NO_CHANNELS = of("NO_CHANNELS") + + @JvmField val NO_PROVIDERS = of("NO_PROVIDERS") + + @JvmField val OPT_IN_REQUIRED = of("OPT_IN_REQUIRED") + + @JvmField val PROVIDER_ERROR = of("PROVIDER_ERROR") + + @JvmField val UNPUBLISHED = of("UNPUBLISHED") + + @JvmField val UNSUBSCRIBED = of("UNSUBSCRIBED") + + @JvmStatic fun of(value: String) = Reason(JsonField.of(value)) + } + + /** An enum containing [Reason]'s known values. */ + enum class Known { + BOUNCED, + FAILED, + FILTERED, + NO_CHANNELS, + NO_PROVIDERS, + OPT_IN_REQUIRED, + PROVIDER_ERROR, + UNPUBLISHED, + UNSUBSCRIBED, + } + + /** + * An enum containing [Reason]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Reason] 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 { + BOUNCED, + FAILED, + FILTERED, + NO_CHANNELS, + NO_PROVIDERS, + OPT_IN_REQUIRED, + PROVIDER_ERROR, + UNPUBLISHED, + UNSUBSCRIBED, + /** An enum member indicating that [Reason] 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) { + BOUNCED -> Value.BOUNCED + FAILED -> Value.FAILED + FILTERED -> Value.FILTERED + NO_CHANNELS -> Value.NO_CHANNELS + NO_PROVIDERS -> Value.NO_PROVIDERS + OPT_IN_REQUIRED -> Value.OPT_IN_REQUIRED + PROVIDER_ERROR -> Value.PROVIDER_ERROR + UNPUBLISHED -> Value.UNPUBLISHED + UNSUBSCRIBED -> Value.UNSUBSCRIBED + 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 CourierInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + BOUNCED -> Known.BOUNCED + FAILED -> Known.FAILED + FILTERED -> Known.FILTERED + NO_CHANNELS -> Known.NO_CHANNELS + NO_PROVIDERS -> Known.NO_PROVIDERS + OPT_IN_REQUIRED -> Known.OPT_IN_REQUIRED + PROVIDER_ERROR -> Known.PROVIDER_ERROR + UNPUBLISHED -> Known.UNPUBLISHED + UNSUBSCRIBED -> Known.UNSUBSCRIBED + else -> throw CourierInvalidDataException("Unknown Reason: $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 CourierInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { CourierInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + fun validate(): Reason = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Reason && 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 MessageDetails && + id == other.id && + clicked == other.clicked && + delivered == other.delivered && + enqueued == other.enqueued && + event == other.event && + notification == other.notification && + opened == other.opened && + recipient == other.recipient && + sent == other.sent && + status == other.status && + error == other.error && + reason == other.reason && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + id, + clicked, + delivered, + enqueued, + event, + notification, + opened, + recipient, + sent, + status, + error, + reason, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "MessageDetails{id=$id, clicked=$clicked, delivered=$delivered, enqueued=$enqueued, event=$event, notification=$notification, opened=$opened, recipient=$recipient, sent=$sent, status=$status, error=$error, reason=$reason, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/messages/MessageHistoryParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/messages/MessageHistoryParams.kt new file mode 100644 index 00000000..eb6a365d --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/messages/MessageHistoryParams.kt @@ -0,0 +1,214 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.messages + +import com.courier.api.core.Params +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Fetch the array of events of a message you've previously sent. */ +class MessageHistoryParams +private constructor( + private val messageId: String?, + private val type: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun messageId(): Optional = Optional.ofNullable(messageId) + + /** A supported Message History type that will filter the events returned. */ + fun type(): Optional = Optional.ofNullable(type) + + /** 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(): MessageHistoryParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [MessageHistoryParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [MessageHistoryParams]. */ + class Builder internal constructor() { + + private var messageId: String? = null + private var type: String? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(messageHistoryParams: MessageHistoryParams) = apply { + messageId = messageHistoryParams.messageId + type = messageHistoryParams.type + additionalHeaders = messageHistoryParams.additionalHeaders.toBuilder() + additionalQueryParams = messageHistoryParams.additionalQueryParams.toBuilder() + } + + fun messageId(messageId: String?) = apply { this.messageId = messageId } + + /** Alias for calling [Builder.messageId] with `messageId.orElse(null)`. */ + fun messageId(messageId: Optional) = messageId(messageId.getOrNull()) + + /** A supported Message History type that will filter the events returned. */ + fun type(type: String?) = apply { this.type = type } + + /** Alias for calling [Builder.type] with `type.orElse(null)`. */ + fun type(type: Optional) = type(type.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 [MessageHistoryParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): MessageHistoryParams = + MessageHistoryParams( + messageId, + type, + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _pathParam(index: Int): String = + when (index) { + 0 -> messageId ?: "" + else -> "" + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + type?.let { put("type", it) } + putAll(additionalQueryParams) + } + .build() + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is MessageHistoryParams && + messageId == other.messageId && + type == other.type && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(messageId, type, additionalHeaders, additionalQueryParams) + + override fun toString() = + "MessageHistoryParams{messageId=$messageId, type=$type, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/messages/MessageHistoryResponse.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/messages/MessageHistoryResponse.kt new file mode 100644 index 00000000..cf2ba77a --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/messages/MessageHistoryResponse.kt @@ -0,0 +1,289 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.messages + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkKnown +import com.courier.api.core.checkRequired +import com.courier.api.core.toImmutable +import com.courier.api.errors.CourierInvalidDataException +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 kotlin.jvm.optionals.getOrNull + +class MessageHistoryResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val results: JsonField>, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("results") @ExcludeMissing results: JsonField> = JsonMissing.of() + ) : this(results, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 results(): List = results.getRequired("results") + + /** + * Returns the raw JSON value of [results]. + * + * Unlike [results], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("results") @ExcludeMissing fun _results(): JsonField> = results + + @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 [MessageHistoryResponse]. + * + * The following fields are required: + * ```java + * .results() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [MessageHistoryResponse]. */ + class Builder internal constructor() { + + private var results: JsonField>? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(messageHistoryResponse: MessageHistoryResponse) = apply { + results = messageHistoryResponse.results.map { it.toMutableList() } + additionalProperties = messageHistoryResponse.additionalProperties.toMutableMap() + } + + fun results(results: List) = results(JsonField.of(results)) + + /** + * Sets [Builder.results] to an arbitrary JSON value. + * + * You should usually call [Builder.results] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun results(results: JsonField>) = apply { + this.results = results.map { it.toMutableList() } + } + + /** + * Adds a single [Result] to [results]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addResult(result: Result) = apply { + results = + (results ?: JsonField.of(mutableListOf())).also { + checkKnown("results", it).add(result) + } + } + + 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 [MessageHistoryResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .results() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): MessageHistoryResponse = + MessageHistoryResponse( + checkRequired("results", results).map { it.toImmutable() }, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): MessageHistoryResponse = apply { + if (validated) { + return@apply + } + + results().forEach { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (results.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + class Result + @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 [Result]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Result]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(result: Result) = apply { + additionalProperties = result.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 [Result]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Result = Result(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): Result = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Result && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Result{additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is MessageHistoryResponse && + results == other.results && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(results, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "MessageHistoryResponse{results=$results, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/messages/MessageListParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/messages/MessageListParams.kt new file mode 100644 index 00000000..92a1fa81 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/messages/MessageListParams.kt @@ -0,0 +1,475 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.messages + +import com.courier.api.core.Params +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import com.courier.api.core.toImmutable +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Fetch the statuses of messages you've previously sent. */ +class MessageListParams +private constructor( + private val archived: Boolean?, + private val cursor: String?, + private val enqueuedAfter: String?, + private val event: String?, + private val list: String?, + private val messageId: String?, + private val notification: String?, + private val provider: List?, + private val recipient: String?, + private val status: List?, + private val tag: List?, + private val tags: String?, + private val tenantId: String?, + private val traceId: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * A boolean value that indicates whether archived messages should be included in the response. + */ + fun archived(): Optional = Optional.ofNullable(archived) + + /** A unique identifier that allows for fetching the next set of messages. */ + fun cursor(): Optional = Optional.ofNullable(cursor) + + /** The enqueued datetime of a message to filter out messages received before. */ + fun enqueuedAfter(): Optional = Optional.ofNullable(enqueuedAfter) + + /** A unique identifier representing the event that was used to send the event. */ + fun event(): Optional = Optional.ofNullable(event) + + /** A unique identifier representing the list the message was sent to. */ + fun list(): Optional = Optional.ofNullable(list) + + /** A unique identifier representing the message_id returned from either /send or /send/list. */ + fun messageId(): Optional = Optional.ofNullable(messageId) + + /** A unique identifier representing the notification that was used to send the event. */ + fun notification(): Optional = Optional.ofNullable(notification) + + /** + * The key assocated to the provider you want to filter on. E.g., sendgrid, inbox, twilio, + * slack, msteams, etc. Allows multiple values to be set in query parameters. + */ + fun provider(): Optional> = Optional.ofNullable(provider) + + /** A unique identifier representing the recipient associated with the requested profile. */ + fun recipient(): Optional = Optional.ofNullable(recipient) + + /** + * An indicator of the current status of the message. Allows multiple values to be set in query + * parameters. + */ + fun status(): Optional> = Optional.ofNullable(status) + + /** + * A tag placed in the metadata.tags during a notification send. Allows multiple values to be + * set in query parameters. + */ + fun tag(): Optional> = Optional.ofNullable(tag) + + /** + * A comma delimited list of 'tags'. Messages will be returned if they match any of the tags + * passed in. + */ + fun tags(): Optional = Optional.ofNullable(tags) + + /** Messages sent with the context of a Tenant */ + fun tenantId(): Optional = Optional.ofNullable(tenantId) + + /** The unique identifier used to trace the requests */ + fun traceId(): Optional = Optional.ofNullable(traceId) + + /** 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(): MessageListParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [MessageListParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [MessageListParams]. */ + class Builder internal constructor() { + + private var archived: Boolean? = null + private var cursor: String? = null + private var enqueuedAfter: String? = null + private var event: String? = null + private var list: String? = null + private var messageId: String? = null + private var notification: String? = null + private var provider: MutableList? = null + private var recipient: String? = null + private var status: MutableList? = null + private var tag: MutableList? = null + private var tags: String? = null + private var tenantId: String? = null + private var traceId: String? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(messageListParams: MessageListParams) = apply { + archived = messageListParams.archived + cursor = messageListParams.cursor + enqueuedAfter = messageListParams.enqueuedAfter + event = messageListParams.event + list = messageListParams.list + messageId = messageListParams.messageId + notification = messageListParams.notification + provider = messageListParams.provider?.toMutableList() + recipient = messageListParams.recipient + status = messageListParams.status?.toMutableList() + tag = messageListParams.tag?.toMutableList() + tags = messageListParams.tags + tenantId = messageListParams.tenantId + traceId = messageListParams.traceId + additionalHeaders = messageListParams.additionalHeaders.toBuilder() + additionalQueryParams = messageListParams.additionalQueryParams.toBuilder() + } + + /** + * A boolean value that indicates whether archived messages should be included in the + * response. + */ + fun archived(archived: Boolean?) = apply { this.archived = archived } + + /** + * Alias for [Builder.archived]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun archived(archived: Boolean) = archived(archived as Boolean?) + + /** Alias for calling [Builder.archived] with `archived.orElse(null)`. */ + fun archived(archived: Optional) = archived(archived.getOrNull()) + + /** A unique identifier that allows for fetching the next set of messages. */ + fun cursor(cursor: String?) = apply { this.cursor = cursor } + + /** Alias for calling [Builder.cursor] with `cursor.orElse(null)`. */ + fun cursor(cursor: Optional) = cursor(cursor.getOrNull()) + + /** The enqueued datetime of a message to filter out messages received before. */ + fun enqueuedAfter(enqueuedAfter: String?) = apply { this.enqueuedAfter = enqueuedAfter } + + /** Alias for calling [Builder.enqueuedAfter] with `enqueuedAfter.orElse(null)`. */ + fun enqueuedAfter(enqueuedAfter: Optional) = + enqueuedAfter(enqueuedAfter.getOrNull()) + + /** A unique identifier representing the event that was used to send the event. */ + fun event(event: String?) = apply { this.event = event } + + /** Alias for calling [Builder.event] with `event.orElse(null)`. */ + fun event(event: Optional) = event(event.getOrNull()) + + /** A unique identifier representing the list the message was sent to. */ + fun list(list: String?) = apply { this.list = list } + + /** Alias for calling [Builder.list] with `list.orElse(null)`. */ + fun list(list: Optional) = list(list.getOrNull()) + + /** + * A unique identifier representing the message_id returned from either /send or /send/list. + */ + fun messageId(messageId: String?) = apply { this.messageId = messageId } + + /** Alias for calling [Builder.messageId] with `messageId.orElse(null)`. */ + fun messageId(messageId: Optional) = messageId(messageId.getOrNull()) + + /** A unique identifier representing the notification that was used to send the event. */ + fun notification(notification: String?) = apply { this.notification = notification } + + /** Alias for calling [Builder.notification] with `notification.orElse(null)`. */ + fun notification(notification: Optional) = notification(notification.getOrNull()) + + /** + * The key assocated to the provider you want to filter on. E.g., sendgrid, inbox, twilio, + * slack, msteams, etc. Allows multiple values to be set in query parameters. + */ + fun provider(provider: List?) = apply { this.provider = provider?.toMutableList() } + + /** Alias for calling [Builder.provider] with `provider.orElse(null)`. */ + fun provider(provider: Optional>) = provider(provider.getOrNull()) + + /** + * Adds a single [String] to [Builder.provider]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addProvider(provider: String) = apply { + this.provider = (this.provider ?: mutableListOf()).apply { add(provider) } + } + + /** A unique identifier representing the recipient associated with the requested profile. */ + fun recipient(recipient: String?) = apply { this.recipient = recipient } + + /** Alias for calling [Builder.recipient] with `recipient.orElse(null)`. */ + fun recipient(recipient: Optional) = recipient(recipient.getOrNull()) + + /** + * An indicator of the current status of the message. Allows multiple values to be set in + * query parameters. + */ + fun status(status: List?) = apply { this.status = status?.toMutableList() } + + /** Alias for calling [Builder.status] with `status.orElse(null)`. */ + fun status(status: Optional>) = status(status.getOrNull()) + + /** + * Adds a single [String] to [Builder.status]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addStatus(status: String) = apply { + this.status = (this.status ?: mutableListOf()).apply { add(status) } + } + + /** + * A tag placed in the metadata.tags during a notification send. Allows multiple values to + * be set in query parameters. + */ + fun tag(tag: List?) = apply { this.tag = tag?.toMutableList() } + + /** Alias for calling [Builder.tag] with `tag.orElse(null)`. */ + fun tag(tag: Optional>) = tag(tag.getOrNull()) + + /** + * Adds a single [String] to [Builder.tag]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addTag(tag: String) = apply { + this.tag = (this.tag ?: mutableListOf()).apply { add(tag) } + } + + /** + * A comma delimited list of 'tags'. Messages will be returned if they match any of the tags + * passed in. + */ + fun tags(tags: String?) = apply { this.tags = tags } + + /** Alias for calling [Builder.tags] with `tags.orElse(null)`. */ + fun tags(tags: Optional) = tags(tags.getOrNull()) + + /** Messages sent with the context of a Tenant */ + fun tenantId(tenantId: String?) = apply { this.tenantId = tenantId } + + /** Alias for calling [Builder.tenantId] with `tenantId.orElse(null)`. */ + fun tenantId(tenantId: Optional) = tenantId(tenantId.getOrNull()) + + /** The unique identifier used to trace the requests */ + fun traceId(traceId: String?) = apply { this.traceId = traceId } + + /** Alias for calling [Builder.traceId] with `traceId.orElse(null)`. */ + fun traceId(traceId: Optional) = traceId(traceId.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 [MessageListParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): MessageListParams = + MessageListParams( + archived, + cursor, + enqueuedAfter, + event, + list, + messageId, + notification, + provider?.toImmutable(), + recipient, + status?.toImmutable(), + tag?.toImmutable(), + tags, + tenantId, + traceId, + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + archived?.let { put("archived", it.toString()) } + cursor?.let { put("cursor", it) } + enqueuedAfter?.let { put("enqueued_after", it) } + event?.let { put("event", it) } + list?.let { put("list", it) } + messageId?.let { put("messageId", it) } + notification?.let { put("notification", it) } + provider?.let { put("provider", it.joinToString(",")) } + recipient?.let { put("recipient", it) } + status?.let { put("status", it.joinToString(",")) } + tag?.let { put("tag", it.joinToString(",")) } + tags?.let { put("tags", it) } + tenantId?.let { put("tenant_id", it) } + traceId?.let { put("traceId", it) } + putAll(additionalQueryParams) + } + .build() + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is MessageListParams && + archived == other.archived && + cursor == other.cursor && + enqueuedAfter == other.enqueuedAfter && + event == other.event && + list == other.list && + messageId == other.messageId && + notification == other.notification && + provider == other.provider && + recipient == other.recipient && + status == other.status && + tag == other.tag && + tags == other.tags && + tenantId == other.tenantId && + traceId == other.traceId && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash( + archived, + cursor, + enqueuedAfter, + event, + list, + messageId, + notification, + provider, + recipient, + status, + tag, + tags, + tenantId, + traceId, + additionalHeaders, + additionalQueryParams, + ) + + override fun toString() = + "MessageListParams{archived=$archived, cursor=$cursor, enqueuedAfter=$enqueuedAfter, event=$event, list=$list, messageId=$messageId, notification=$notification, provider=$provider, recipient=$recipient, status=$status, tag=$tag, tags=$tags, tenantId=$tenantId, traceId=$traceId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/messages/MessageListResponse.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/messages/MessageListResponse.kt new file mode 100644 index 00000000..4cb37861 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/messages/MessageListResponse.kt @@ -0,0 +1,234 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.messages + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkKnown +import com.courier.api.core.checkRequired +import com.courier.api.core.toImmutable +import com.courier.api.errors.CourierInvalidDataException +import com.courier.api.models.audiences.Paging +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 kotlin.jvm.optionals.getOrNull + +class MessageListResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val paging: JsonField, + private val results: JsonField>, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("paging") @ExcludeMissing paging: JsonField = JsonMissing.of(), + @JsonProperty("results") + @ExcludeMissing + results: JsonField> = JsonMissing.of(), + ) : this(paging, results, mutableMapOf()) + + /** + * Paging information for the result set. + * + * @throws CourierInvalidDataException 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 paging(): Paging = paging.getRequired("paging") + + /** + * An array of messages with their details. + * + * @throws CourierInvalidDataException 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 results(): List = results.getRequired("results") + + /** + * Returns the raw JSON value of [paging]. + * + * Unlike [paging], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("paging") @ExcludeMissing fun _paging(): JsonField = paging + + /** + * Returns the raw JSON value of [results]. + * + * Unlike [results], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("results") + @ExcludeMissing + fun _results(): JsonField> = results + + @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 [MessageListResponse]. + * + * The following fields are required: + * ```java + * .paging() + * .results() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [MessageListResponse]. */ + class Builder internal constructor() { + + private var paging: JsonField? = null + private var results: JsonField>? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(messageListResponse: MessageListResponse) = apply { + paging = messageListResponse.paging + results = messageListResponse.results.map { it.toMutableList() } + additionalProperties = messageListResponse.additionalProperties.toMutableMap() + } + + /** Paging information for the result set. */ + fun paging(paging: Paging) = paging(JsonField.of(paging)) + + /** + * Sets [Builder.paging] to an arbitrary JSON value. + * + * You should usually call [Builder.paging] with a well-typed [Paging] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun paging(paging: JsonField) = apply { this.paging = paging } + + /** An array of messages with their details. */ + fun results(results: List) = results(JsonField.of(results)) + + /** + * Sets [Builder.results] to an arbitrary JSON value. + * + * You should usually call [Builder.results] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun results(results: JsonField>) = apply { + this.results = results.map { it.toMutableList() } + } + + /** + * Adds a single [MessageDetails] to [results]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addResult(result: MessageDetails) = apply { + results = + (results ?: JsonField.of(mutableListOf())).also { + checkKnown("results", it).add(result) + } + } + + 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 [MessageListResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .paging() + * .results() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): MessageListResponse = + MessageListResponse( + checkRequired("paging", paging), + checkRequired("results", results).map { it.toImmutable() }, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): MessageListResponse = apply { + if (validated) { + return@apply + } + + paging().validate() + results().forEach { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (paging.asKnown().getOrNull()?.validity() ?: 0) + + (results.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is MessageListResponse && + paging == other.paging && + results == other.results && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(paging, results, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "MessageListResponse{paging=$paging, results=$results, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/messages/MessageRetrieveParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/messages/MessageRetrieveParams.kt new file mode 100644 index 00000000..de135e40 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/messages/MessageRetrieveParams.kt @@ -0,0 +1,193 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.messages + +import com.courier.api.core.Params +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Fetch the status of a message you've previously sent. */ +class MessageRetrieveParams +private constructor( + private val messageId: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun messageId(): Optional = Optional.ofNullable(messageId) + + /** 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(): MessageRetrieveParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [MessageRetrieveParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [MessageRetrieveParams]. */ + class Builder internal constructor() { + + private var messageId: String? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(messageRetrieveParams: MessageRetrieveParams) = apply { + messageId = messageRetrieveParams.messageId + additionalHeaders = messageRetrieveParams.additionalHeaders.toBuilder() + additionalQueryParams = messageRetrieveParams.additionalQueryParams.toBuilder() + } + + fun messageId(messageId: String?) = apply { this.messageId = messageId } + + /** Alias for calling [Builder.messageId] with `messageId.orElse(null)`. */ + fun messageId(messageId: Optional) = messageId(messageId.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 [MessageRetrieveParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): MessageRetrieveParams = + MessageRetrieveParams( + messageId, + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _pathParam(index: Int): String = + when (index) { + 0 -> messageId ?: "" + 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 MessageRetrieveParams && + messageId == other.messageId && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = Objects.hash(messageId, additionalHeaders, additionalQueryParams) + + override fun toString() = + "MessageRetrieveParams{messageId=$messageId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/messages/MessageRetrieveResponse.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/messages/MessageRetrieveResponse.kt new file mode 100644 index 00000000..ef93ce21 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/messages/MessageRetrieveResponse.kt @@ -0,0 +1,814 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.messages + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkKnown +import com.courier.api.core.checkRequired +import com.courier.api.core.toImmutable +import com.courier.api.errors.CourierInvalidDataException +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 MessageRetrieveResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val id: JsonField, + private val clicked: JsonField, + private val delivered: JsonField, + private val enqueued: JsonField, + private val event: JsonField, + private val notification: JsonField, + private val opened: JsonField, + private val recipient: JsonField, + private val sent: JsonField, + private val status: JsonField, + private val error: JsonField, + private val reason: JsonField, + private val providers: JsonField>, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("clicked") @ExcludeMissing clicked: JsonField = JsonMissing.of(), + @JsonProperty("delivered") @ExcludeMissing delivered: JsonField = JsonMissing.of(), + @JsonProperty("enqueued") @ExcludeMissing enqueued: JsonField = JsonMissing.of(), + @JsonProperty("event") @ExcludeMissing event: JsonField = JsonMissing.of(), + @JsonProperty("notification") + @ExcludeMissing + notification: JsonField = JsonMissing.of(), + @JsonProperty("opened") @ExcludeMissing opened: JsonField = JsonMissing.of(), + @JsonProperty("recipient") @ExcludeMissing recipient: JsonField = JsonMissing.of(), + @JsonProperty("sent") @ExcludeMissing sent: JsonField = JsonMissing.of(), + @JsonProperty("status") + @ExcludeMissing + status: JsonField = JsonMissing.of(), + @JsonProperty("error") @ExcludeMissing error: JsonField = JsonMissing.of(), + @JsonProperty("reason") + @ExcludeMissing + reason: JsonField = JsonMissing.of(), + @JsonProperty("providers") + @ExcludeMissing + providers: JsonField> = JsonMissing.of(), + ) : this( + id, + clicked, + delivered, + enqueued, + event, + notification, + opened, + recipient, + sent, + status, + error, + reason, + providers, + mutableMapOf(), + ) + + fun toMessageDetails(): MessageDetails = + MessageDetails.builder() + .id(id) + .clicked(clicked) + .delivered(delivered) + .enqueued(enqueued) + .event(event) + .notification(notification) + .opened(opened) + .recipient(recipient) + .sent(sent) + .status(status) + .error(error) + .reason(reason) + .build() + + /** + * A unique identifier associated with the message you wish to retrieve (results from a send). + * + * @throws CourierInvalidDataException 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 id(): String = id.getRequired("id") + + /** + * A UTC timestamp at which the recipient clicked on a tracked link for the first time. Stored + * as a millisecond representation of the Unix epoch. + * + * @throws CourierInvalidDataException 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 clicked(): Long = clicked.getRequired("clicked") + + /** + * A UTC timestamp at which the Integration provider delivered the message. Stored as a + * millisecond representation of the Unix epoch. + * + * @throws CourierInvalidDataException 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 delivered(): Long = delivered.getRequired("delivered") + + /** + * A UTC timestamp at which Courier received the message request. Stored as a millisecond + * representation of the Unix epoch. + * + * @throws CourierInvalidDataException 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 enqueued(): Long = enqueued.getRequired("enqueued") + + /** + * A unique identifier associated with the event of the delivered message. + * + * @throws CourierInvalidDataException 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 event(): String = event.getRequired("event") + + /** + * A unique identifier associated with the notification of the delivered message. + * + * @throws CourierInvalidDataException 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 notification(): String = notification.getRequired("notification") + + /** + * A UTC timestamp at which the recipient opened a message for the first time. Stored as a + * millisecond representation of the Unix epoch. + * + * @throws CourierInvalidDataException 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 opened(): Long = opened.getRequired("opened") + + /** + * A unique identifier associated with the recipient of the delivered message. + * + * @throws CourierInvalidDataException 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 recipient(): String = recipient.getRequired("recipient") + + /** + * A UTC timestamp at which Courier passed the message to the Integration provider. Stored as a + * millisecond representation of the Unix epoch. + * + * @throws CourierInvalidDataException 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 sent(): Long = sent.getRequired("sent") + + /** + * The current status of the message. + * + * @throws CourierInvalidDataException 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 status(): MessageDetails.Status = status.getRequired("status") + + /** + * A message describing the error that occurred. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun error(): Optional = error.getOptional("error") + + /** + * The reason for the current status of the message. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun reason(): Optional = reason.getOptional("reason") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun providers(): Optional> = providers.getOptional("providers") + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + /** + * Returns the raw JSON value of [clicked]. + * + * Unlike [clicked], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("clicked") @ExcludeMissing fun _clicked(): JsonField = clicked + + /** + * Returns the raw JSON value of [delivered]. + * + * Unlike [delivered], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("delivered") @ExcludeMissing fun _delivered(): JsonField = delivered + + /** + * Returns the raw JSON value of [enqueued]. + * + * Unlike [enqueued], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("enqueued") @ExcludeMissing fun _enqueued(): JsonField = enqueued + + /** + * Returns the raw JSON value of [event]. + * + * Unlike [event], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("event") @ExcludeMissing fun _event(): JsonField = event + + /** + * Returns the raw JSON value of [notification]. + * + * Unlike [notification], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("notification") + @ExcludeMissing + fun _notification(): JsonField = notification + + /** + * Returns the raw JSON value of [opened]. + * + * Unlike [opened], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("opened") @ExcludeMissing fun _opened(): JsonField = opened + + /** + * Returns the raw JSON value of [recipient]. + * + * Unlike [recipient], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("recipient") @ExcludeMissing fun _recipient(): JsonField = recipient + + /** + * Returns the raw JSON value of [sent]. + * + * Unlike [sent], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("sent") @ExcludeMissing fun _sent(): JsonField = sent + + /** + * 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 [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 [reason]. + * + * Unlike [reason], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("reason") @ExcludeMissing fun _reason(): JsonField = reason + + /** + * Returns the raw JSON value of [providers]. + * + * Unlike [providers], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("providers") + @ExcludeMissing + fun _providers(): JsonField> = providers + + @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 [MessageRetrieveResponse]. + * + * The following fields are required: + * ```java + * .id() + * .clicked() + * .delivered() + * .enqueued() + * .event() + * .notification() + * .opened() + * .recipient() + * .sent() + * .status() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [MessageRetrieveResponse]. */ + class Builder internal constructor() { + + private var id: JsonField? = null + private var clicked: JsonField? = null + private var delivered: JsonField? = null + private var enqueued: JsonField? = null + private var event: JsonField? = null + private var notification: JsonField? = null + private var opened: JsonField? = null + private var recipient: JsonField? = null + private var sent: JsonField? = null + private var status: JsonField? = null + private var error: JsonField = JsonMissing.of() + private var reason: JsonField = JsonMissing.of() + private var providers: JsonField>? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(messageRetrieveResponse: MessageRetrieveResponse) = apply { + id = messageRetrieveResponse.id + clicked = messageRetrieveResponse.clicked + delivered = messageRetrieveResponse.delivered + enqueued = messageRetrieveResponse.enqueued + event = messageRetrieveResponse.event + notification = messageRetrieveResponse.notification + opened = messageRetrieveResponse.opened + recipient = messageRetrieveResponse.recipient + sent = messageRetrieveResponse.sent + status = messageRetrieveResponse.status + error = messageRetrieveResponse.error + reason = messageRetrieveResponse.reason + providers = messageRetrieveResponse.providers.map { it.toMutableList() } + additionalProperties = messageRetrieveResponse.additionalProperties.toMutableMap() + } + + /** + * A unique identifier associated with the message you wish to retrieve (results from a + * send). + */ + fun id(id: String) = id(JsonField.of(id)) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun id(id: JsonField) = apply { this.id = id } + + /** + * A UTC timestamp at which the recipient clicked on a tracked link for the first time. + * Stored as a millisecond representation of the Unix epoch. + */ + fun clicked(clicked: Long) = clicked(JsonField.of(clicked)) + + /** + * Sets [Builder.clicked] to an arbitrary JSON value. + * + * You should usually call [Builder.clicked] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun clicked(clicked: JsonField) = apply { this.clicked = clicked } + + /** + * A UTC timestamp at which the Integration provider delivered the message. Stored as a + * millisecond representation of the Unix epoch. + */ + fun delivered(delivered: Long) = delivered(JsonField.of(delivered)) + + /** + * Sets [Builder.delivered] to an arbitrary JSON value. + * + * You should usually call [Builder.delivered] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun delivered(delivered: JsonField) = apply { this.delivered = delivered } + + /** + * A UTC timestamp at which Courier received the message request. Stored as a millisecond + * representation of the Unix epoch. + */ + fun enqueued(enqueued: Long) = enqueued(JsonField.of(enqueued)) + + /** + * Sets [Builder.enqueued] to an arbitrary JSON value. + * + * You should usually call [Builder.enqueued] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun enqueued(enqueued: JsonField) = apply { this.enqueued = enqueued } + + /** A unique identifier associated with the event of the delivered message. */ + fun event(event: String) = event(JsonField.of(event)) + + /** + * Sets [Builder.event] to an arbitrary JSON value. + * + * You should usually call [Builder.event] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun event(event: JsonField) = apply { this.event = event } + + /** A unique identifier associated with the notification of the delivered message. */ + fun notification(notification: String) = notification(JsonField.of(notification)) + + /** + * Sets [Builder.notification] to an arbitrary JSON value. + * + * You should usually call [Builder.notification] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun notification(notification: JsonField) = apply { + this.notification = notification + } + + /** + * A UTC timestamp at which the recipient opened a message for the first time. Stored as a + * millisecond representation of the Unix epoch. + */ + fun opened(opened: Long) = opened(JsonField.of(opened)) + + /** + * Sets [Builder.opened] to an arbitrary JSON value. + * + * You should usually call [Builder.opened] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun opened(opened: JsonField) = apply { this.opened = opened } + + /** A unique identifier associated with the recipient of the delivered message. */ + fun recipient(recipient: String) = recipient(JsonField.of(recipient)) + + /** + * Sets [Builder.recipient] to an arbitrary JSON value. + * + * You should usually call [Builder.recipient] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun recipient(recipient: JsonField) = apply { this.recipient = recipient } + + /** + * A UTC timestamp at which Courier passed the message to the Integration provider. Stored + * as a millisecond representation of the Unix epoch. + */ + fun sent(sent: Long) = sent(JsonField.of(sent)) + + /** + * Sets [Builder.sent] to an arbitrary JSON value. + * + * You should usually call [Builder.sent] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun sent(sent: JsonField) = apply { this.sent = sent } + + /** The current status of the message. */ + fun status(status: MessageDetails.Status) = status(JsonField.of(status)) + + /** + * Sets [Builder.status] to an arbitrary JSON value. + * + * You should usually call [Builder.status] with a well-typed [MessageDetails.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 } + + /** A message describing the error that occurred. */ + fun error(error: String?) = error(JsonField.ofNullable(error)) + + /** Alias for calling [Builder.error] with `error.orElse(null)`. */ + fun error(error: Optional) = error(error.getOrNull()) + + /** + * 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 } + + /** The reason for the current status of the message. */ + fun reason(reason: MessageDetails.Reason?) = reason(JsonField.ofNullable(reason)) + + /** Alias for calling [Builder.reason] with `reason.orElse(null)`. */ + fun reason(reason: Optional) = reason(reason.getOrNull()) + + /** + * Sets [Builder.reason] to an arbitrary JSON value. + * + * You should usually call [Builder.reason] with a well-typed [MessageDetails.Reason] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun reason(reason: JsonField) = apply { this.reason = reason } + + fun providers(providers: List?) = providers(JsonField.ofNullable(providers)) + + /** Alias for calling [Builder.providers] with `providers.orElse(null)`. */ + fun providers(providers: Optional>) = providers(providers.getOrNull()) + + /** + * Sets [Builder.providers] to an arbitrary JSON value. + * + * You should usually call [Builder.providers] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun providers(providers: JsonField>) = apply { + this.providers = providers.map { it.toMutableList() } + } + + /** + * Adds a single [Provider] to [providers]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addProvider(provider: Provider) = apply { + providers = + (providers ?: JsonField.of(mutableListOf())).also { + checkKnown("providers", it).add(provider) + } + } + + 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 [MessageRetrieveResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .clicked() + * .delivered() + * .enqueued() + * .event() + * .notification() + * .opened() + * .recipient() + * .sent() + * .status() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): MessageRetrieveResponse = + MessageRetrieveResponse( + checkRequired("id", id), + checkRequired("clicked", clicked), + checkRequired("delivered", delivered), + checkRequired("enqueued", enqueued), + checkRequired("event", event), + checkRequired("notification", notification), + checkRequired("opened", opened), + checkRequired("recipient", recipient), + checkRequired("sent", sent), + checkRequired("status", status), + error, + reason, + (providers ?: JsonMissing.of()).map { it.toImmutable() }, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): MessageRetrieveResponse = apply { + if (validated) { + return@apply + } + + id() + clicked() + delivered() + enqueued() + event() + notification() + opened() + recipient() + sent() + status().validate() + error() + reason().ifPresent { it.validate() } + providers().ifPresent { it.forEach { it.validate() } } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (id.asKnown().isPresent) 1 else 0) + + (if (clicked.asKnown().isPresent) 1 else 0) + + (if (delivered.asKnown().isPresent) 1 else 0) + + (if (enqueued.asKnown().isPresent) 1 else 0) + + (if (event.asKnown().isPresent) 1 else 0) + + (if (notification.asKnown().isPresent) 1 else 0) + + (if (opened.asKnown().isPresent) 1 else 0) + + (if (recipient.asKnown().isPresent) 1 else 0) + + (if (sent.asKnown().isPresent) 1 else 0) + + (status.asKnown().getOrNull()?.validity() ?: 0) + + (if (error.asKnown().isPresent) 1 else 0) + + (reason.asKnown().getOrNull()?.validity() ?: 0) + + (providers.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + class Provider + @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 [Provider]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Provider]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(provider: Provider) = apply { + additionalProperties = provider.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 [Provider]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Provider = Provider(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): Provider = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Provider && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Provider{additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is MessageRetrieveResponse && + id == other.id && + clicked == other.clicked && + delivered == other.delivered && + enqueued == other.enqueued && + event == other.event && + notification == other.notification && + opened == other.opened && + recipient == other.recipient && + sent == other.sent && + status == other.status && + error == other.error && + reason == other.reason && + providers == other.providers && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + id, + clicked, + delivered, + enqueued, + event, + notification, + opened, + recipient, + sent, + status, + error, + reason, + providers, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "MessageRetrieveResponse{id=$id, clicked=$clicked, delivered=$delivered, enqueued=$enqueued, event=$event, notification=$notification, opened=$opened, recipient=$recipient, sent=$sent, status=$status, error=$error, reason=$reason, providers=$providers, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/notifications/NotificationContent.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/notifications/NotificationContent.kt new file mode 100644 index 00000000..c09eef97 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/notifications/NotificationContent.kt @@ -0,0 +1,1906 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.notifications + +import com.courier.api.core.BaseDeserializer +import com.courier.api.core.BaseSerializer +import com.courier.api.core.Enum +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.allMaxBy +import com.courier.api.core.checkKnown +import com.courier.api.core.checkRequired +import com.courier.api.core.getOrThrow +import com.courier.api.core.toImmutable +import com.courier.api.errors.CourierInvalidDataException +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 com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.ObjectCodec +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.module.kotlin.jacksonTypeRef +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +class NotificationContent +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val blocks: JsonField>, + private val channels: JsonField>, + private val checksum: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("blocks") @ExcludeMissing blocks: JsonField> = JsonMissing.of(), + @JsonProperty("channels") + @ExcludeMissing + channels: JsonField> = JsonMissing.of(), + @JsonProperty("checksum") @ExcludeMissing checksum: JsonField = JsonMissing.of(), + ) : this(blocks, channels, checksum, mutableMapOf()) + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun blocks(): Optional> = blocks.getOptional("blocks") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun channels(): Optional> = channels.getOptional("channels") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun checksum(): Optional = checksum.getOptional("checksum") + + /** + * Returns the raw JSON value of [blocks]. + * + * Unlike [blocks], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("blocks") @ExcludeMissing fun _blocks(): JsonField> = blocks + + /** + * Returns the raw JSON value of [channels]. + * + * Unlike [channels], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("channels") @ExcludeMissing fun _channels(): JsonField> = channels + + /** + * Returns the raw JSON value of [checksum]. + * + * Unlike [checksum], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("checksum") @ExcludeMissing fun _checksum(): JsonField = checksum + + @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 [NotificationContent]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [NotificationContent]. */ + class Builder internal constructor() { + + private var blocks: JsonField>? = null + private var channels: JsonField>? = null + private var checksum: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(notificationContent: NotificationContent) = apply { + blocks = notificationContent.blocks.map { it.toMutableList() } + channels = notificationContent.channels.map { it.toMutableList() } + checksum = notificationContent.checksum + additionalProperties = notificationContent.additionalProperties.toMutableMap() + } + + fun blocks(blocks: List?) = blocks(JsonField.ofNullable(blocks)) + + /** Alias for calling [Builder.blocks] with `blocks.orElse(null)`. */ + fun blocks(blocks: Optional>) = blocks(blocks.getOrNull()) + + /** + * Sets [Builder.blocks] to an arbitrary JSON value. + * + * You should usually call [Builder.blocks] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun blocks(blocks: JsonField>) = apply { + this.blocks = blocks.map { it.toMutableList() } + } + + /** + * Adds a single [Block] to [blocks]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addBlock(block: Block) = apply { + blocks = + (blocks ?: JsonField.of(mutableListOf())).also { + checkKnown("blocks", it).add(block) + } + } + + fun channels(channels: List?) = channels(JsonField.ofNullable(channels)) + + /** Alias for calling [Builder.channels] with `channels.orElse(null)`. */ + fun channels(channels: Optional>) = channels(channels.getOrNull()) + + /** + * Sets [Builder.channels] to an arbitrary JSON value. + * + * You should usually call [Builder.channels] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun channels(channels: JsonField>) = apply { + this.channels = channels.map { it.toMutableList() } + } + + /** + * Adds a single [Channel] to [channels]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addChannel(channel: Channel) = apply { + channels = + (channels ?: JsonField.of(mutableListOf())).also { + checkKnown("channels", it).add(channel) + } + } + + fun checksum(checksum: String?) = checksum(JsonField.ofNullable(checksum)) + + /** Alias for calling [Builder.checksum] with `checksum.orElse(null)`. */ + fun checksum(checksum: Optional) = checksum(checksum.getOrNull()) + + /** + * Sets [Builder.checksum] to an arbitrary JSON value. + * + * You should usually call [Builder.checksum] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun checksum(checksum: JsonField) = apply { this.checksum = checksum } + + 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 [NotificationContent]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): NotificationContent = + NotificationContent( + (blocks ?: JsonMissing.of()).map { it.toImmutable() }, + (channels ?: JsonMissing.of()).map { it.toImmutable() }, + checksum, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): NotificationContent = apply { + if (validated) { + return@apply + } + + blocks().ifPresent { it.forEach { it.validate() } } + channels().ifPresent { it.forEach { it.validate() } } + checksum() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (blocks.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (channels.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (checksum.asKnown().isPresent) 1 else 0) + + class Block + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val id: JsonField, + private val type: JsonField, + private val alias: JsonField, + private val checksum: JsonField, + private val content: JsonField, + private val context: JsonField, + private val locales: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), + @JsonProperty("alias") @ExcludeMissing alias: JsonField = JsonMissing.of(), + @JsonProperty("checksum") + @ExcludeMissing + checksum: JsonField = JsonMissing.of(), + @JsonProperty("content") @ExcludeMissing content: JsonField = JsonMissing.of(), + @JsonProperty("context") @ExcludeMissing context: JsonField = JsonMissing.of(), + @JsonProperty("locales") @ExcludeMissing locales: JsonField = JsonMissing.of(), + ) : this(id, type, alias, checksum, content, context, locales, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 id(): String = id.getRequired("id") + + /** + * @throws CourierInvalidDataException 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 type(): Type = type.getRequired("type") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun alias(): Optional = alias.getOptional("alias") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun checksum(): Optional = checksum.getOptional("checksum") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun content(): Optional = content.getOptional("content") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun context(): Optional = context.getOptional("context") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun locales(): Optional = locales.getOptional("locales") + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + /** + * 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 [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 [checksum]. + * + * Unlike [checksum], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("checksum") @ExcludeMissing fun _checksum(): JsonField = checksum + + /** + * Returns the raw JSON value of [content]. + * + * Unlike [content], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("content") @ExcludeMissing fun _content(): JsonField = content + + /** + * Returns the raw JSON value of [context]. + * + * Unlike [context], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("context") @ExcludeMissing fun _context(): JsonField = context + + /** + * Returns the raw JSON value of [locales]. + * + * Unlike [locales], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("locales") @ExcludeMissing fun _locales(): JsonField = locales + + @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 [Block]. + * + * The following fields are required: + * ```java + * .id() + * .type() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Block]. */ + class Builder internal constructor() { + + private var id: JsonField? = null + private var type: JsonField? = null + private var alias: JsonField = JsonMissing.of() + private var checksum: JsonField = JsonMissing.of() + private var content: JsonField = JsonMissing.of() + private var context: JsonField = JsonMissing.of() + private var locales: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(block: Block) = apply { + id = block.id + type = block.type + alias = block.alias + checksum = block.checksum + content = block.content + context = block.context + locales = block.locales + additionalProperties = block.additionalProperties.toMutableMap() + } + + fun id(id: String) = id(JsonField.of(id)) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun id(id: JsonField) = apply { this.id = id } + + 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 } + + fun alias(alias: String?) = alias(JsonField.ofNullable(alias)) + + /** Alias for calling [Builder.alias] with `alias.orElse(null)`. */ + fun alias(alias: Optional) = alias(alias.getOrNull()) + + /** + * 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 } + + fun checksum(checksum: String?) = checksum(JsonField.ofNullable(checksum)) + + /** Alias for calling [Builder.checksum] with `checksum.orElse(null)`. */ + fun checksum(checksum: Optional) = checksum(checksum.getOrNull()) + + /** + * Sets [Builder.checksum] to an arbitrary JSON value. + * + * You should usually call [Builder.checksum] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun checksum(checksum: JsonField) = apply { this.checksum = checksum } + + fun content(content: Content?) = content(JsonField.ofNullable(content)) + + /** Alias for calling [Builder.content] with `content.orElse(null)`. */ + fun content(content: Optional) = content(content.getOrNull()) + + /** + * Sets [Builder.content] to an arbitrary JSON value. + * + * You should usually call [Builder.content] with a well-typed [Content] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun content(content: JsonField) = apply { this.content = content } + + /** Alias for calling [content] with `Content.ofString(string)`. */ + fun content(string: String) = content(Content.ofString(string)) + + /** + * Alias for calling [content] with + * `Content.ofNotificationContentHierarchy(notificationContentHierarchy)`. + */ + fun content(notificationContentHierarchy: Content.NotificationContentHierarchy) = + content(Content.ofNotificationContentHierarchy(notificationContentHierarchy)) + + fun context(context: String?) = context(JsonField.ofNullable(context)) + + /** Alias for calling [Builder.context] with `context.orElse(null)`. */ + fun context(context: Optional) = context(context.getOrNull()) + + /** + * Sets [Builder.context] to an arbitrary JSON value. + * + * You should usually call [Builder.context] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun context(context: JsonField) = apply { this.context = context } + + fun locales(locales: Locales?) = locales(JsonField.ofNullable(locales)) + + /** Alias for calling [Builder.locales] with `locales.orElse(null)`. */ + fun locales(locales: Optional) = locales(locales.getOrNull()) + + /** + * Sets [Builder.locales] to an arbitrary JSON value. + * + * You should usually call [Builder.locales] with a well-typed [Locales] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun locales(locales: JsonField) = apply { this.locales = locales } + + 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 [Block]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Block = + Block( + checkRequired("id", id), + checkRequired("type", type), + alias, + checksum, + content, + context, + locales, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Block = apply { + if (validated) { + return@apply + } + + id() + type().validate() + alias() + checksum() + content().ifPresent { it.validate() } + context() + locales().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (id.asKnown().isPresent) 1 else 0) + + (type.asKnown().getOrNull()?.validity() ?: 0) + + (if (alias.asKnown().isPresent) 1 else 0) + + (if (checksum.asKnown().isPresent) 1 else 0) + + (content.asKnown().getOrNull()?.validity() ?: 0) + + (if (context.asKnown().isPresent) 1 else 0) + + (locales.asKnown().getOrNull()?.validity() ?: 0) + + 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 ACTION = of("action") + + @JvmField val DIVIDER = of("divider") + + @JvmField val IMAGE = of("image") + + @JvmField val JSONNET = of("jsonnet") + + @JvmField val LIST = of("list") + + @JvmField val MARKDOWN = of("markdown") + + @JvmField val QUOTE = of("quote") + + @JvmField val TEMPLATE = of("template") + + @JvmField val TEXT = of("text") + + @JvmStatic fun of(value: String) = Type(JsonField.of(value)) + } + + /** An enum containing [Type]'s known values. */ + enum class Known { + ACTION, + DIVIDER, + IMAGE, + JSONNET, + LIST, + MARKDOWN, + QUOTE, + TEMPLATE, + TEXT, + } + + /** + * 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 { + ACTION, + DIVIDER, + IMAGE, + JSONNET, + LIST, + MARKDOWN, + QUOTE, + TEMPLATE, + TEXT, + /** 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) { + ACTION -> Value.ACTION + DIVIDER -> Value.DIVIDER + IMAGE -> Value.IMAGE + JSONNET -> Value.JSONNET + LIST -> Value.LIST + MARKDOWN -> Value.MARKDOWN + QUOTE -> Value.QUOTE + TEMPLATE -> Value.TEMPLATE + TEXT -> Value.TEXT + 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 CourierInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + ACTION -> Known.ACTION + DIVIDER -> Known.DIVIDER + IMAGE -> Known.IMAGE + JSONNET -> Known.JSONNET + LIST -> Known.LIST + MARKDOWN -> Known.MARKDOWN + QUOTE -> Known.QUOTE + TEMPLATE -> Known.TEMPLATE + TEXT -> Known.TEXT + else -> throw CourierInvalidDataException("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 CourierInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CourierInvalidDataException("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: CourierInvalidDataException) { + 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() + } + + @JsonDeserialize(using = Content.Deserializer::class) + @JsonSerialize(using = Content.Serializer::class) + class Content + private constructor( + private val string: String? = null, + private val notificationContentHierarchy: NotificationContentHierarchy? = null, + private val _json: JsonValue? = null, + ) { + + fun string(): Optional = Optional.ofNullable(string) + + fun notificationContentHierarchy(): Optional = + Optional.ofNullable(notificationContentHierarchy) + + fun isString(): Boolean = string != null + + fun isNotificationContentHierarchy(): Boolean = notificationContentHierarchy != null + + fun asString(): String = string.getOrThrow("string") + + fun asNotificationContentHierarchy(): NotificationContentHierarchy = + notificationContentHierarchy.getOrThrow("notificationContentHierarchy") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T = + when { + string != null -> visitor.visitString(string) + notificationContentHierarchy != null -> + visitor.visitNotificationContentHierarchy(notificationContentHierarchy) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + fun validate(): Content = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitString(string: String) {} + + override fun visitNotificationContentHierarchy( + notificationContentHierarchy: NotificationContentHierarchy + ) { + notificationContentHierarchy.validate() + } + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + accept( + object : Visitor { + override fun visitString(string: String) = 1 + + override fun visitNotificationContentHierarchy( + notificationContentHierarchy: NotificationContentHierarchy + ) = notificationContentHierarchy.validity() + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Content && + string == other.string && + notificationContentHierarchy == other.notificationContentHierarchy + } + + override fun hashCode(): Int = Objects.hash(string, notificationContentHierarchy) + + override fun toString(): String = + when { + string != null -> "Content{string=$string}" + notificationContentHierarchy != null -> + "Content{notificationContentHierarchy=$notificationContentHierarchy}" + _json != null -> "Content{_unknown=$_json}" + else -> throw IllegalStateException("Invalid Content") + } + + companion object { + + @JvmStatic fun ofString(string: String) = Content(string = string) + + @JvmStatic + fun ofNotificationContentHierarchy( + notificationContentHierarchy: NotificationContentHierarchy + ) = Content(notificationContentHierarchy = notificationContentHierarchy) + } + + /** + * An interface that defines how to map each variant of [Content] to a value of type + * [T]. + */ + interface Visitor { + + fun visitString(string: String): T + + fun visitNotificationContentHierarchy( + notificationContentHierarchy: NotificationContentHierarchy + ): T + + /** + * Maps an unknown variant of [Content] to a value of type [T]. + * + * An instance of [Content] can contain an unknown variant if it was deserialized + * from data that doesn't match any known variant. For example, if the SDK is on an + * older version than the API, then the API may respond with new variants that the + * SDK is unaware of. + * + * @throws CourierInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw CourierInvalidDataException("Unknown Content: $json") + } + } + + internal class Deserializer : BaseDeserializer(Content::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): Content { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef()) + ?.let { + Content(notificationContentHierarchy = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + Content(string = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible + // with all the possible variants (e.g. deserializing from array). + 0 -> Content(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the + // first completely valid match, or simply the first match if none are + // completely valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : BaseSerializer(Content::class) { + + override fun serialize( + value: Content, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.string != null -> generator.writeObject(value.string) + value.notificationContentHierarchy != null -> + generator.writeObject(value.notificationContentHierarchy) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid Content") + } + } + } + + class NotificationContentHierarchy + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val children: JsonField, + private val parent: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("children") + @ExcludeMissing + children: JsonField = JsonMissing.of(), + @JsonProperty("parent") + @ExcludeMissing + parent: JsonField = JsonMissing.of(), + ) : this(children, parent, mutableMapOf()) + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun children(): Optional = children.getOptional("children") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun parent(): Optional = parent.getOptional("parent") + + /** + * Returns the raw JSON value of [children]. + * + * Unlike [children], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("children") + @ExcludeMissing + fun _children(): JsonField = children + + /** + * Returns the raw JSON value of [parent]. + * + * Unlike [parent], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("parent") @ExcludeMissing fun _parent(): JsonField = parent + + @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 + * [NotificationContentHierarchy]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [NotificationContentHierarchy]. */ + class Builder internal constructor() { + + private var children: JsonField = JsonMissing.of() + private var parent: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(notificationContentHierarchy: NotificationContentHierarchy) = + apply { + children = notificationContentHierarchy.children + parent = notificationContentHierarchy.parent + additionalProperties = + notificationContentHierarchy.additionalProperties.toMutableMap() + } + + fun children(children: String?) = children(JsonField.ofNullable(children)) + + /** Alias for calling [Builder.children] with `children.orElse(null)`. */ + fun children(children: Optional) = children(children.getOrNull()) + + /** + * Sets [Builder.children] to an arbitrary JSON value. + * + * You should usually call [Builder.children] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun children(children: JsonField) = apply { this.children = children } + + fun parent(parent: String?) = parent(JsonField.ofNullable(parent)) + + /** Alias for calling [Builder.parent] with `parent.orElse(null)`. */ + fun parent(parent: Optional) = parent(parent.getOrNull()) + + /** + * Sets [Builder.parent] to an arbitrary JSON value. + * + * You should usually call [Builder.parent] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun parent(parent: JsonField) = apply { this.parent = parent } + + 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 [NotificationContentHierarchy]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): NotificationContentHierarchy = + NotificationContentHierarchy( + children, + parent, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): NotificationContentHierarchy = apply { + if (validated) { + return@apply + } + + children() + parent() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (children.asKnown().isPresent) 1 else 0) + + (if (parent.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is NotificationContentHierarchy && + children == other.children && + parent == other.parent && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(children, parent, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "NotificationContentHierarchy{children=$children, parent=$parent, additionalProperties=$additionalProperties}" + } + } + + class Locales + @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 [Locales]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Locales]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(locales: Locales) = apply { + additionalProperties = locales.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 [Locales]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Locales = Locales(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): Locales = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Locales && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Locales{additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Block && + id == other.id && + type == other.type && + alias == other.alias && + checksum == other.checksum && + content == other.content && + context == other.context && + locales == other.locales && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(id, type, alias, checksum, content, context, locales, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Block{id=$id, type=$type, alias=$alias, checksum=$checksum, content=$content, context=$context, locales=$locales, additionalProperties=$additionalProperties}" + } + + class Channel + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val id: JsonField, + private val checksum: JsonField, + private val content: JsonField, + private val locales: JsonField, + private val type: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("checksum") + @ExcludeMissing + checksum: JsonField = JsonMissing.of(), + @JsonProperty("content") @ExcludeMissing content: JsonField = JsonMissing.of(), + @JsonProperty("locales") @ExcludeMissing locales: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), + ) : this(id, checksum, content, locales, type, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 id(): String = id.getRequired("id") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun checksum(): Optional = checksum.getOptional("checksum") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun content(): Optional = content.getOptional("content") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun locales(): Optional = locales.getOptional("locales") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun type(): Optional = type.getOptional("type") + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + /** + * Returns the raw JSON value of [checksum]. + * + * Unlike [checksum], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("checksum") @ExcludeMissing fun _checksum(): JsonField = checksum + + /** + * Returns the raw JSON value of [content]. + * + * Unlike [content], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("content") @ExcludeMissing fun _content(): JsonField = content + + /** + * Returns the raw JSON value of [locales]. + * + * Unlike [locales], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("locales") @ExcludeMissing fun _locales(): JsonField = locales + + /** + * 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 + + @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 [Channel]. + * + * The following fields are required: + * ```java + * .id() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Channel]. */ + class Builder internal constructor() { + + private var id: JsonField? = null + private var checksum: JsonField = JsonMissing.of() + private var content: JsonField = JsonMissing.of() + private var locales: JsonField = JsonMissing.of() + private var type: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(channel: Channel) = apply { + id = channel.id + checksum = channel.checksum + content = channel.content + locales = channel.locales + type = channel.type + additionalProperties = channel.additionalProperties.toMutableMap() + } + + fun id(id: String) = id(JsonField.of(id)) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun id(id: JsonField) = apply { this.id = id } + + fun checksum(checksum: String?) = checksum(JsonField.ofNullable(checksum)) + + /** Alias for calling [Builder.checksum] with `checksum.orElse(null)`. */ + fun checksum(checksum: Optional) = checksum(checksum.getOrNull()) + + /** + * Sets [Builder.checksum] to an arbitrary JSON value. + * + * You should usually call [Builder.checksum] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun checksum(checksum: JsonField) = apply { this.checksum = checksum } + + fun content(content: Content?) = content(JsonField.ofNullable(content)) + + /** Alias for calling [Builder.content] with `content.orElse(null)`. */ + fun content(content: Optional) = content(content.getOrNull()) + + /** + * Sets [Builder.content] to an arbitrary JSON value. + * + * You should usually call [Builder.content] with a well-typed [Content] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun content(content: JsonField) = apply { this.content = content } + + fun locales(locales: Locales?) = locales(JsonField.ofNullable(locales)) + + /** Alias for calling [Builder.locales] with `locales.orElse(null)`. */ + fun locales(locales: Optional) = locales(locales.getOrNull()) + + /** + * Sets [Builder.locales] to an arbitrary JSON value. + * + * You should usually call [Builder.locales] with a well-typed [Locales] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun locales(locales: JsonField) = apply { this.locales = locales } + + fun type(type: String?) = type(JsonField.ofNullable(type)) + + /** Alias for calling [Builder.type] with `type.orElse(null)`. */ + fun type(type: Optional) = type(type.getOrNull()) + + /** + * 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 } + + 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 [Channel]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Channel = + Channel( + checkRequired("id", id), + checksum, + content, + locales, + type, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Channel = apply { + if (validated) { + return@apply + } + + id() + checksum() + content().ifPresent { it.validate() } + locales().ifPresent { it.validate() } + type() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (id.asKnown().isPresent) 1 else 0) + + (if (checksum.asKnown().isPresent) 1 else 0) + + (content.asKnown().getOrNull()?.validity() ?: 0) + + (locales.asKnown().getOrNull()?.validity() ?: 0) + + (if (type.asKnown().isPresent) 1 else 0) + + class Content + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val subject: JsonField, + private val title: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("subject") + @ExcludeMissing + subject: JsonField = JsonMissing.of(), + @JsonProperty("title") @ExcludeMissing title: JsonField = JsonMissing.of(), + ) : this(subject, title, mutableMapOf()) + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun subject(): Optional = subject.getOptional("subject") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun title(): Optional = title.getOptional("title") + + /** + * Returns the raw JSON value of [subject]. + * + * Unlike [subject], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("subject") @ExcludeMissing fun _subject(): JsonField = subject + + /** + * Returns the raw JSON value of [title]. + * + * Unlike [title], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("title") @ExcludeMissing fun _title(): JsonField = title + + @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 [Content]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Content]. */ + class Builder internal constructor() { + + private var subject: JsonField = JsonMissing.of() + private var title: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(content: Content) = apply { + subject = content.subject + title = content.title + additionalProperties = content.additionalProperties.toMutableMap() + } + + fun subject(subject: String?) = subject(JsonField.ofNullable(subject)) + + /** Alias for calling [Builder.subject] with `subject.orElse(null)`. */ + fun subject(subject: Optional) = subject(subject.getOrNull()) + + /** + * Sets [Builder.subject] to an arbitrary JSON value. + * + * You should usually call [Builder.subject] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun subject(subject: JsonField) = apply { this.subject = subject } + + fun title(title: String?) = title(JsonField.ofNullable(title)) + + /** Alias for calling [Builder.title] with `title.orElse(null)`. */ + fun title(title: Optional) = title(title.getOrNull()) + + /** + * Sets [Builder.title] to an arbitrary JSON value. + * + * You should usually call [Builder.title] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun title(title: JsonField) = apply { this.title = title } + + 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 [Content]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Content = Content(subject, title, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Content = apply { + if (validated) { + return@apply + } + + subject() + title() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (subject.asKnown().isPresent) 1 else 0) + + (if (title.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Content && + subject == other.subject && + title == other.title && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(subject, title, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Content{subject=$subject, title=$title, additionalProperties=$additionalProperties}" + } + + class Locales + @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 [Locales]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Locales]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(locales: Locales) = apply { + additionalProperties = locales.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 [Locales]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Locales = Locales(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): Locales = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Locales && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Locales{additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Channel && + id == other.id && + checksum == other.checksum && + content == other.content && + locales == other.locales && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(id, checksum, content, locales, type, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Channel{id=$id, checksum=$checksum, content=$content, locales=$locales, type=$type, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is NotificationContent && + blocks == other.blocks && + channels == other.channels && + checksum == other.checksum && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(blocks, channels, checksum, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "NotificationContent{blocks=$blocks, channels=$channels, checksum=$checksum, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/notifications/NotificationListParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/notifications/NotificationListParams.kt new file mode 100644 index 00000000..16af7e50 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/notifications/NotificationListParams.kt @@ -0,0 +1,215 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.notifications + +import com.courier.api.core.Params +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +class NotificationListParams +private constructor( + private val cursor: String?, + private val notes: Boolean?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun cursor(): Optional = Optional.ofNullable(cursor) + + /** Retrieve the notes from the Notification template settings. */ + fun notes(): Optional = Optional.ofNullable(notes) + + /** 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(): NotificationListParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [NotificationListParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [NotificationListParams]. */ + class Builder internal constructor() { + + private var cursor: String? = null + private var notes: Boolean? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(notificationListParams: NotificationListParams) = apply { + cursor = notificationListParams.cursor + notes = notificationListParams.notes + additionalHeaders = notificationListParams.additionalHeaders.toBuilder() + additionalQueryParams = notificationListParams.additionalQueryParams.toBuilder() + } + + fun cursor(cursor: String?) = apply { this.cursor = cursor } + + /** Alias for calling [Builder.cursor] with `cursor.orElse(null)`. */ + fun cursor(cursor: Optional) = cursor(cursor.getOrNull()) + + /** Retrieve the notes from the Notification template settings. */ + fun notes(notes: Boolean?) = apply { this.notes = notes } + + /** + * Alias for [Builder.notes]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun notes(notes: Boolean) = notes(notes as Boolean?) + + /** Alias for calling [Builder.notes] with `notes.orElse(null)`. */ + fun notes(notes: Optional) = notes(notes.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 [NotificationListParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): NotificationListParams = + NotificationListParams( + cursor, + notes, + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + cursor?.let { put("cursor", it) } + notes?.let { put("notes", it.toString()) } + putAll(additionalQueryParams) + } + .build() + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is NotificationListParams && + cursor == other.cursor && + notes == other.notes && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(cursor, notes, additionalHeaders, additionalQueryParams) + + override fun toString() = + "NotificationListParams{cursor=$cursor, notes=$notes, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/notifications/NotificationListResponse.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/notifications/NotificationListResponse.kt new file mode 100644 index 00000000..3cd46340 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/notifications/NotificationListResponse.kt @@ -0,0 +1,1015 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.notifications + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkKnown +import com.courier.api.core.checkRequired +import com.courier.api.core.toImmutable +import com.courier.api.errors.CourierInvalidDataException +import com.courier.api.models.audiences.Paging +import com.courier.api.models.send.MessageRouting +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 NotificationListResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val paging: JsonField, + private val results: JsonField>, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("paging") @ExcludeMissing paging: JsonField = JsonMissing.of(), + @JsonProperty("results") @ExcludeMissing results: JsonField> = JsonMissing.of(), + ) : this(paging, results, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 paging(): Paging = paging.getRequired("paging") + + /** + * @throws CourierInvalidDataException 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 results(): List = results.getRequired("results") + + /** + * Returns the raw JSON value of [paging]. + * + * Unlike [paging], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("paging") @ExcludeMissing fun _paging(): JsonField = paging + + /** + * Returns the raw JSON value of [results]. + * + * Unlike [results], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("results") @ExcludeMissing fun _results(): JsonField> = results + + @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 [NotificationListResponse]. + * + * The following fields are required: + * ```java + * .paging() + * .results() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [NotificationListResponse]. */ + class Builder internal constructor() { + + private var paging: JsonField? = null + private var results: JsonField>? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(notificationListResponse: NotificationListResponse) = apply { + paging = notificationListResponse.paging + results = notificationListResponse.results.map { it.toMutableList() } + additionalProperties = notificationListResponse.additionalProperties.toMutableMap() + } + + fun paging(paging: Paging) = paging(JsonField.of(paging)) + + /** + * Sets [Builder.paging] to an arbitrary JSON value. + * + * You should usually call [Builder.paging] with a well-typed [Paging] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun paging(paging: JsonField) = apply { this.paging = paging } + + fun results(results: List) = results(JsonField.of(results)) + + /** + * Sets [Builder.results] to an arbitrary JSON value. + * + * You should usually call [Builder.results] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun results(results: JsonField>) = apply { + this.results = results.map { it.toMutableList() } + } + + /** + * Adds a single [Result] to [results]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addResult(result: Result) = apply { + results = + (results ?: JsonField.of(mutableListOf())).also { + checkKnown("results", it).add(result) + } + } + + 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 [NotificationListResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .paging() + * .results() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): NotificationListResponse = + NotificationListResponse( + checkRequired("paging", paging), + checkRequired("results", results).map { it.toImmutable() }, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): NotificationListResponse = apply { + if (validated) { + return@apply + } + + paging().validate() + results().forEach { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (paging.asKnown().getOrNull()?.validity() ?: 0) + + (results.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + class Result + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val id: JsonField, + private val createdAt: JsonField, + private val note: JsonField, + private val routing: JsonField, + private val topicId: JsonField, + private val updatedAt: JsonField, + private val tags: JsonField, + private val title: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("created_at") + @ExcludeMissing + createdAt: JsonField = JsonMissing.of(), + @JsonProperty("note") @ExcludeMissing note: JsonField = JsonMissing.of(), + @JsonProperty("routing") + @ExcludeMissing + routing: JsonField = JsonMissing.of(), + @JsonProperty("topic_id") @ExcludeMissing topicId: JsonField = JsonMissing.of(), + @JsonProperty("updated_at") + @ExcludeMissing + updatedAt: JsonField = JsonMissing.of(), + @JsonProperty("tags") @ExcludeMissing tags: JsonField = JsonMissing.of(), + @JsonProperty("title") @ExcludeMissing title: JsonField = JsonMissing.of(), + ) : this(id, createdAt, note, routing, topicId, updatedAt, tags, title, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 id(): String = id.getRequired("id") + + /** + * @throws CourierInvalidDataException 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 createdAt(): Long = createdAt.getRequired("created_at") + + /** + * @throws CourierInvalidDataException 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 note(): String = note.getRequired("note") + + /** + * @throws CourierInvalidDataException 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 routing(): MessageRouting = routing.getRequired("routing") + + /** + * @throws CourierInvalidDataException 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 topicId(): String = topicId.getRequired("topic_id") + + /** + * @throws CourierInvalidDataException 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 updatedAt(): Long = updatedAt.getRequired("updated_at") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun tags(): Optional = tags.getOptional("tags") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun title(): Optional = title.getOptional("title") + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + /** + * 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 [note]. + * + * Unlike [note], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("note") @ExcludeMissing fun _note(): JsonField = note + + /** + * Returns the raw JSON value of [routing]. + * + * Unlike [routing], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("routing") @ExcludeMissing fun _routing(): JsonField = routing + + /** + * Returns the raw JSON value of [topicId]. + * + * Unlike [topicId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("topic_id") @ExcludeMissing fun _topicId(): JsonField = topicId + + /** + * 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 + + /** + * Returns the raw JSON value of [tags]. + * + * Unlike [tags], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("tags") @ExcludeMissing fun _tags(): JsonField = tags + + /** + * Returns the raw JSON value of [title]. + * + * Unlike [title], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("title") @ExcludeMissing fun _title(): JsonField = title + + @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 [Result]. + * + * The following fields are required: + * ```java + * .id() + * .createdAt() + * .note() + * .routing() + * .topicId() + * .updatedAt() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Result]. */ + class Builder internal constructor() { + + private var id: JsonField? = null + private var createdAt: JsonField? = null + private var note: JsonField? = null + private var routing: JsonField? = null + private var topicId: JsonField? = null + private var updatedAt: JsonField? = null + private var tags: JsonField = JsonMissing.of() + private var title: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(result: Result) = apply { + id = result.id + createdAt = result.createdAt + note = result.note + routing = result.routing + topicId = result.topicId + updatedAt = result.updatedAt + tags = result.tags + title = result.title + additionalProperties = result.additionalProperties.toMutableMap() + } + + fun id(id: String) = id(JsonField.of(id)) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun id(id: JsonField) = apply { this.id = id } + + fun createdAt(createdAt: Long) = createdAt(JsonField.of(createdAt)) + + /** + * Sets [Builder.createdAt] to an arbitrary JSON value. + * + * You should usually call [Builder.createdAt] with a well-typed [Long] 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 } + + fun note(note: String) = note(JsonField.of(note)) + + /** + * Sets [Builder.note] to an arbitrary JSON value. + * + * You should usually call [Builder.note] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun note(note: JsonField) = apply { this.note = note } + + fun routing(routing: MessageRouting) = routing(JsonField.of(routing)) + + /** + * Sets [Builder.routing] to an arbitrary JSON value. + * + * You should usually call [Builder.routing] with a well-typed [MessageRouting] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun routing(routing: JsonField) = apply { this.routing = routing } + + fun topicId(topicId: String) = topicId(JsonField.of(topicId)) + + /** + * Sets [Builder.topicId] to an arbitrary JSON value. + * + * You should usually call [Builder.topicId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun topicId(topicId: JsonField) = apply { this.topicId = topicId } + + fun updatedAt(updatedAt: Long) = updatedAt(JsonField.of(updatedAt)) + + /** + * Sets [Builder.updatedAt] to an arbitrary JSON value. + * + * You should usually call [Builder.updatedAt] with a well-typed [Long] 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 tags(tags: Tags?) = tags(JsonField.ofNullable(tags)) + + /** Alias for calling [Builder.tags] with `tags.orElse(null)`. */ + fun tags(tags: Optional) = tags(tags.getOrNull()) + + /** + * Sets [Builder.tags] to an arbitrary JSON value. + * + * You should usually call [Builder.tags] with a well-typed [Tags] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun tags(tags: JsonField) = apply { this.tags = tags } + + fun title(title: String?) = title(JsonField.ofNullable(title)) + + /** Alias for calling [Builder.title] with `title.orElse(null)`. */ + fun title(title: Optional) = title(title.getOrNull()) + + /** + * Sets [Builder.title] to an arbitrary JSON value. + * + * You should usually call [Builder.title] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun title(title: JsonField) = apply { this.title = title } + + 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 [Result]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .createdAt() + * .note() + * .routing() + * .topicId() + * .updatedAt() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Result = + Result( + checkRequired("id", id), + checkRequired("createdAt", createdAt), + checkRequired("note", note), + checkRequired("routing", routing), + checkRequired("topicId", topicId), + checkRequired("updatedAt", updatedAt), + tags, + title, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Result = apply { + if (validated) { + return@apply + } + + id() + createdAt() + note() + routing().validate() + topicId() + updatedAt() + tags().ifPresent { it.validate() } + title() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (id.asKnown().isPresent) 1 else 0) + + (if (createdAt.asKnown().isPresent) 1 else 0) + + (if (note.asKnown().isPresent) 1 else 0) + + (routing.asKnown().getOrNull()?.validity() ?: 0) + + (if (topicId.asKnown().isPresent) 1 else 0) + + (if (updatedAt.asKnown().isPresent) 1 else 0) + + (tags.asKnown().getOrNull()?.validity() ?: 0) + + (if (title.asKnown().isPresent) 1 else 0) + + class Tags + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val data: JsonField>, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("data") @ExcludeMissing data: JsonField> = JsonMissing.of() + ) : this(data, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 data(): List = data.getRequired("data") + + /** + * 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 + + @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 [Tags]. + * + * The following fields are required: + * ```java + * .data() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Tags]. */ + class Builder internal constructor() { + + private var data: JsonField>? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(tags: Tags) = apply { + data = tags.data.map { it.toMutableList() } + additionalProperties = tags.additionalProperties.toMutableMap() + } + + fun data(data: List) = data(JsonField.of(data)) + + /** + * Sets [Builder.data] to an arbitrary JSON value. + * + * You should usually call [Builder.data] with a well-typed `List` 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.map { it.toMutableList() } + } + + /** + * Adds a single [Data] to [Builder.data]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addData(data: Data) = apply { + this.data = + (this.data ?: JsonField.of(mutableListOf())).also { + checkKnown("data", it).add(data) + } + } + + 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 [Tags]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .data() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Tags = + Tags( + checkRequired("data", data).map { it.toImmutable() }, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Tags = apply { + if (validated) { + return@apply + } + + data().forEach { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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()?.sumOf { it.validity().toInt() } ?: 0) + + class Data + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val id: JsonField, + private val name: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + ) : this(id, name, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 id(): String = id.getRequired("id") + + /** + * @throws CourierInvalidDataException 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 name(): String = name.getRequired("name") + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + /** + * 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 + + @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]. + * + * The following fields are required: + * ```java + * .id() + * .name() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Data]. */ + class Builder internal constructor() { + + private var id: JsonField? = null + private var name: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(data: Data) = apply { + id = data.id + name = data.name + additionalProperties = data.additionalProperties.toMutableMap() + } + + fun id(id: String) = id(JsonField.of(id)) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun id(id: JsonField) = apply { this.id = id } + + 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 } + + 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. + * + * The following fields are required: + * ```java + * .id() + * .name() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Data = + Data( + checkRequired("id", id), + checkRequired("name", name), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Data = apply { + if (validated) { + return@apply + } + + id() + name() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (id.asKnown().isPresent) 1 else 0) + + (if (name.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Data && + id == other.id && + name == other.name && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(id, name, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Data{id=$id, name=$name, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Tags && + data == other.data && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(data, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Tags{data=$data, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Result && + id == other.id && + createdAt == other.createdAt && + note == other.note && + routing == other.routing && + topicId == other.topicId && + updatedAt == other.updatedAt && + tags == other.tags && + title == other.title && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + id, + createdAt, + note, + routing, + topicId, + updatedAt, + tags, + title, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Result{id=$id, createdAt=$createdAt, note=$note, routing=$routing, topicId=$topicId, updatedAt=$updatedAt, tags=$tags, title=$title, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is NotificationListResponse && + paging == other.paging && + results == other.results && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(paging, results, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "NotificationListResponse{paging=$paging, results=$results, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/notifications/NotificationRetrieveContentParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/notifications/NotificationRetrieveContentParams.kt new file mode 100644 index 00000000..218897c6 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/notifications/NotificationRetrieveContentParams.kt @@ -0,0 +1,197 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.notifications + +import com.courier.api.core.Params +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +class NotificationRetrieveContentParams +private constructor( + private val id: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun id(): Optional = Optional.ofNullable(id) + + /** 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(): NotificationRetrieveContentParams = builder().build() + + /** + * Returns a mutable builder for constructing an instance of + * [NotificationRetrieveContentParams]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [NotificationRetrieveContentParams]. */ + class Builder internal constructor() { + + private var id: String? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(notificationRetrieveContentParams: NotificationRetrieveContentParams) = + apply { + id = notificationRetrieveContentParams.id + additionalHeaders = notificationRetrieveContentParams.additionalHeaders.toBuilder() + additionalQueryParams = + notificationRetrieveContentParams.additionalQueryParams.toBuilder() + } + + fun id(id: String?) = apply { this.id = id } + + /** Alias for calling [Builder.id] with `id.orElse(null)`. */ + fun id(id: Optional) = id(id.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 [NotificationRetrieveContentParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): NotificationRetrieveContentParams = + NotificationRetrieveContentParams( + id, + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _pathParam(index: Int): String = + when (index) { + 0 -> id ?: "" + 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 NotificationRetrieveContentParams && + id == other.id && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = Objects.hash(id, additionalHeaders, additionalQueryParams) + + override fun toString() = + "NotificationRetrieveContentParams{id=$id, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/notifications/checks/BaseCheck.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/notifications/checks/BaseCheck.kt new file mode 100644 index 00000000..171e9dff --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/notifications/checks/BaseCheck.kt @@ -0,0 +1,490 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.notifications.checks + +import com.courier.api.core.Enum +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkRequired +import com.courier.api.errors.CourierInvalidDataException +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 kotlin.jvm.optionals.getOrNull + +class BaseCheck +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val id: JsonField, + private val status: JsonField, + private val type: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), + ) : this(id, status, type, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 id(): String = id.getRequired("id") + + /** + * @throws CourierInvalidDataException 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 status(): Status = status.getRequired("status") + + /** + * @throws CourierInvalidDataException 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 type(): Type = type.getRequired("type") + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + /** + * 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 [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + + @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 [BaseCheck]. + * + * The following fields are required: + * ```java + * .id() + * .status() + * .type() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [BaseCheck]. */ + class Builder internal constructor() { + + private var id: JsonField? = null + private var status: JsonField? = null + private var type: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(baseCheck: BaseCheck) = apply { + id = baseCheck.id + status = baseCheck.status + type = baseCheck.type + additionalProperties = baseCheck.additionalProperties.toMutableMap() + } + + fun id(id: String) = id(JsonField.of(id)) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun id(id: JsonField) = apply { this.id = id } + + 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 } + + 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 } + + 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 [BaseCheck]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .status() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): BaseCheck = + BaseCheck( + checkRequired("id", id), + checkRequired("status", status), + checkRequired("type", type), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): BaseCheck = apply { + if (validated) { + return@apply + } + + id() + status().validate() + type().validate() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (id.asKnown().isPresent) 1 else 0) + + (status.asKnown().getOrNull()?.validity() ?: 0) + + (type.asKnown().getOrNull()?.validity() ?: 0) + + 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 RESOLVED = of("RESOLVED") + + @JvmField val FAILED = of("FAILED") + + @JvmField val PENDING = of("PENDING") + + @JvmStatic fun of(value: String) = Status(JsonField.of(value)) + } + + /** An enum containing [Status]'s known values. */ + enum class Known { + RESOLVED, + FAILED, + PENDING, + } + + /** + * 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 { + RESOLVED, + FAILED, + PENDING, + /** 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) { + RESOLVED -> Value.RESOLVED + FAILED -> Value.FAILED + PENDING -> Value.PENDING + 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 CourierInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + RESOLVED -> Known.RESOLVED + FAILED -> Known.FAILED + PENDING -> Known.PENDING + else -> throw CourierInvalidDataException("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 CourierInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { CourierInvalidDataException("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: CourierInvalidDataException) { + 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() + } + + 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 CUSTOM = of("custom") + + @JvmStatic fun of(value: String) = Type(JsonField.of(value)) + } + + /** An enum containing [Type]'s known values. */ + enum class Known { + CUSTOM + } + + /** + * 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 { + CUSTOM, + /** 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) { + CUSTOM -> Value.CUSTOM + 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 CourierInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + CUSTOM -> Known.CUSTOM + else -> throw CourierInvalidDataException("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 CourierInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { CourierInvalidDataException("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: CourierInvalidDataException) { + 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 BaseCheck && + id == other.id && + status == other.status && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(id, status, type, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "BaseCheck{id=$id, status=$status, type=$type, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/notifications/checks/Check.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/notifications/checks/Check.kt new file mode 100644 index 00000000..e2c20679 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/notifications/checks/Check.kt @@ -0,0 +1,280 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.notifications.checks + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkRequired +import com.courier.api.errors.CourierInvalidDataException +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 kotlin.jvm.optionals.getOrNull + +class Check +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val id: JsonField, + private val status: JsonField, + private val type: JsonField, + private val updated: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("status") + @ExcludeMissing + status: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), + @JsonProperty("updated") @ExcludeMissing updated: JsonField = JsonMissing.of(), + ) : this(id, status, type, updated, mutableMapOf()) + + fun toBaseCheck(): BaseCheck = BaseCheck.builder().id(id).status(status).type(type).build() + + /** + * @throws CourierInvalidDataException 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 id(): String = id.getRequired("id") + + /** + * @throws CourierInvalidDataException 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 status(): BaseCheck.Status = status.getRequired("status") + + /** + * @throws CourierInvalidDataException 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 type(): BaseCheck.Type = type.getRequired("type") + + /** + * @throws CourierInvalidDataException 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 updated(): Long = updated.getRequired("updated") + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + /** + * 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 [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 [updated]. + * + * Unlike [updated], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("updated") @ExcludeMissing fun _updated(): JsonField = updated + + @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 [Check]. + * + * The following fields are required: + * ```java + * .id() + * .status() + * .type() + * .updated() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Check]. */ + class Builder internal constructor() { + + private var id: JsonField? = null + private var status: JsonField? = null + private var type: JsonField? = null + private var updated: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(check: Check) = apply { + id = check.id + status = check.status + type = check.type + updated = check.updated + additionalProperties = check.additionalProperties.toMutableMap() + } + + fun id(id: String) = id(JsonField.of(id)) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun id(id: JsonField) = apply { this.id = id } + + fun status(status: BaseCheck.Status) = status(JsonField.of(status)) + + /** + * Sets [Builder.status] to an arbitrary JSON value. + * + * You should usually call [Builder.status] with a well-typed [BaseCheck.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 } + + fun type(type: BaseCheck.Type) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [BaseCheck.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 updated(updated: Long) = updated(JsonField.of(updated)) + + /** + * Sets [Builder.updated] to an arbitrary JSON value. + * + * You should usually call [Builder.updated] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun updated(updated: JsonField) = apply { this.updated = updated } + + 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 [Check]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .status() + * .type() + * .updated() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Check = + Check( + checkRequired("id", id), + checkRequired("status", status), + checkRequired("type", type), + checkRequired("updated", updated), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Check = apply { + if (validated) { + return@apply + } + + id() + status().validate() + type().validate() + updated() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (id.asKnown().isPresent) 1 else 0) + + (status.asKnown().getOrNull()?.validity() ?: 0) + + (type.asKnown().getOrNull()?.validity() ?: 0) + + (if (updated.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Check && + id == other.id && + status == other.status && + type == other.type && + updated == other.updated && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(id, status, type, updated, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Check{id=$id, status=$status, type=$type, updated=$updated, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/notifications/checks/CheckDeleteParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/notifications/checks/CheckDeleteParams.kt new file mode 100644 index 00000000..e4f88658 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/notifications/checks/CheckDeleteParams.kt @@ -0,0 +1,257 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.notifications.checks + +import com.courier.api.core.JsonValue +import com.courier.api.core.Params +import com.courier.api.core.checkRequired +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import com.courier.api.core.toImmutable +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +class CheckDeleteParams +private constructor( + private val id: String, + private val submissionId: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, + private val additionalBodyProperties: Map, +) : Params { + + fun id(): String = id + + fun submissionId(): Optional = Optional.ofNullable(submissionId) + + /** 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 [CheckDeleteParams]. + * + * The following fields are required: + * ```java + * .id() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [CheckDeleteParams]. */ + class Builder internal constructor() { + + private var id: String? = null + private var submissionId: 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(checkDeleteParams: CheckDeleteParams) = apply { + id = checkDeleteParams.id + submissionId = checkDeleteParams.submissionId + additionalHeaders = checkDeleteParams.additionalHeaders.toBuilder() + additionalQueryParams = checkDeleteParams.additionalQueryParams.toBuilder() + additionalBodyProperties = checkDeleteParams.additionalBodyProperties.toMutableMap() + } + + fun id(id: String) = apply { this.id = id } + + fun submissionId(submissionId: String?) = apply { this.submissionId = submissionId } + + /** Alias for calling [Builder.submissionId] with `submissionId.orElse(null)`. */ + fun submissionId(submissionId: Optional) = submissionId(submissionId.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 [CheckDeleteParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): CheckDeleteParams = + CheckDeleteParams( + checkRequired("id", id), + submissionId, + additionalHeaders.build(), + additionalQueryParams.build(), + additionalBodyProperties.toImmutable(), + ) + } + + fun _body(): Optional> = + Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) + + fun _pathParam(index: Int): String = + when (index) { + 0 -> id + 1 -> submissionId ?: "" + 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 CheckDeleteParams && + id == other.id && + submissionId == other.submissionId && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams && + additionalBodyProperties == other.additionalBodyProperties + } + + override fun hashCode(): Int = + Objects.hash( + id, + submissionId, + additionalHeaders, + additionalQueryParams, + additionalBodyProperties, + ) + + override fun toString() = + "CheckDeleteParams{id=$id, submissionId=$submissionId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/notifications/checks/CheckListParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/notifications/checks/CheckListParams.kt new file mode 100644 index 00000000..cec93f6b --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/notifications/checks/CheckListParams.kt @@ -0,0 +1,216 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.notifications.checks + +import com.courier.api.core.Params +import com.courier.api.core.checkRequired +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +class CheckListParams +private constructor( + private val id: String, + private val submissionId: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun id(): String = id + + fun submissionId(): Optional = Optional.ofNullable(submissionId) + + /** 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 [CheckListParams]. + * + * The following fields are required: + * ```java + * .id() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [CheckListParams]. */ + class Builder internal constructor() { + + private var id: String? = null + private var submissionId: String? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(checkListParams: CheckListParams) = apply { + id = checkListParams.id + submissionId = checkListParams.submissionId + additionalHeaders = checkListParams.additionalHeaders.toBuilder() + additionalQueryParams = checkListParams.additionalQueryParams.toBuilder() + } + + fun id(id: String) = apply { this.id = id } + + fun submissionId(submissionId: String?) = apply { this.submissionId = submissionId } + + /** Alias for calling [Builder.submissionId] with `submissionId.orElse(null)`. */ + fun submissionId(submissionId: Optional) = submissionId(submissionId.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 [CheckListParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): CheckListParams = + CheckListParams( + checkRequired("id", id), + submissionId, + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _pathParam(index: Int): String = + when (index) { + 0 -> id + 1 -> submissionId ?: "" + 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 CheckListParams && + id == other.id && + submissionId == other.submissionId && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(id, submissionId, additionalHeaders, additionalQueryParams) + + override fun toString() = + "CheckListParams{id=$id, submissionId=$submissionId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/notifications/checks/CheckListResponse.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/notifications/checks/CheckListResponse.kt new file mode 100644 index 00000000..b9032b32 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/notifications/checks/CheckListResponse.kt @@ -0,0 +1,190 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.notifications.checks + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkKnown +import com.courier.api.core.checkRequired +import com.courier.api.core.toImmutable +import com.courier.api.errors.CourierInvalidDataException +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 kotlin.jvm.optionals.getOrNull + +class CheckListResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val checks: JsonField>, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("checks") @ExcludeMissing checks: JsonField> = JsonMissing.of() + ) : this(checks, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 checks(): List = checks.getRequired("checks") + + /** + * Returns the raw JSON value of [checks]. + * + * Unlike [checks], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("checks") @ExcludeMissing fun _checks(): JsonField> = checks + + @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 [CheckListResponse]. + * + * The following fields are required: + * ```java + * .checks() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [CheckListResponse]. */ + class Builder internal constructor() { + + private var checks: JsonField>? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(checkListResponse: CheckListResponse) = apply { + checks = checkListResponse.checks.map { it.toMutableList() } + additionalProperties = checkListResponse.additionalProperties.toMutableMap() + } + + fun checks(checks: List) = checks(JsonField.of(checks)) + + /** + * Sets [Builder.checks] to an arbitrary JSON value. + * + * You should usually call [Builder.checks] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun checks(checks: JsonField>) = apply { + this.checks = checks.map { it.toMutableList() } + } + + /** + * Adds a single [Check] to [checks]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addCheck(check: Check) = apply { + checks = + (checks ?: JsonField.of(mutableListOf())).also { + checkKnown("checks", it).add(check) + } + } + + 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 [CheckListResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .checks() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): CheckListResponse = + CheckListResponse( + checkRequired("checks", checks).map { it.toImmutable() }, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): CheckListResponse = apply { + if (validated) { + return@apply + } + + checks().forEach { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (checks.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is CheckListResponse && + checks == other.checks && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(checks, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "CheckListResponse{checks=$checks, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/notifications/checks/CheckUpdateParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/notifications/checks/CheckUpdateParams.kt new file mode 100644 index 00000000..da33d0cf --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/notifications/checks/CheckUpdateParams.kt @@ -0,0 +1,471 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.notifications.checks + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.Params +import com.courier.api.core.checkKnown +import com.courier.api.core.checkRequired +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import com.courier.api.core.toImmutable +import com.courier.api.errors.CourierInvalidDataException +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 CheckUpdateParams +private constructor( + private val id: String, + private val submissionId: String?, + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun id(): String = id + + fun submissionId(): Optional = Optional.ofNullable(submissionId) + + /** + * @throws CourierInvalidDataException 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 checks(): List = body.checks() + + /** + * Returns the raw JSON value of [checks]. + * + * Unlike [checks], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _checks(): JsonField> = body._checks() + + 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 [CheckUpdateParams]. + * + * The following fields are required: + * ```java + * .id() + * .checks() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [CheckUpdateParams]. */ + class Builder internal constructor() { + + private var id: String? = null + private var submissionId: 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(checkUpdateParams: CheckUpdateParams) = apply { + id = checkUpdateParams.id + submissionId = checkUpdateParams.submissionId + body = checkUpdateParams.body.toBuilder() + additionalHeaders = checkUpdateParams.additionalHeaders.toBuilder() + additionalQueryParams = checkUpdateParams.additionalQueryParams.toBuilder() + } + + fun id(id: String) = apply { this.id = id } + + fun submissionId(submissionId: String?) = apply { this.submissionId = submissionId } + + /** Alias for calling [Builder.submissionId] with `submissionId.orElse(null)`. */ + fun submissionId(submissionId: Optional) = submissionId(submissionId.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: + * - [checks] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + fun checks(checks: List) = apply { body.checks(checks) } + + /** + * Sets [Builder.checks] to an arbitrary JSON value. + * + * You should usually call [Builder.checks] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun checks(checks: JsonField>) = apply { body.checks(checks) } + + /** + * Adds a single [BaseCheck] to [checks]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addCheck(check: BaseCheck) = apply { body.addCheck(check) } + + 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 [CheckUpdateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .checks() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): CheckUpdateParams = + CheckUpdateParams( + checkRequired("id", id), + submissionId, + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): Body = body + + fun _pathParam(index: Int): String = + when (index) { + 0 -> id + 1 -> submissionId ?: "" + else -> "" + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + class Body + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val checks: JsonField>, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("checks") + @ExcludeMissing + checks: JsonField> = JsonMissing.of() + ) : this(checks, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 checks(): List = checks.getRequired("checks") + + /** + * Returns the raw JSON value of [checks]. + * + * Unlike [checks], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("checks") @ExcludeMissing fun _checks(): JsonField> = checks + + @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 + * .checks() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var checks: JsonField>? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + checks = body.checks.map { it.toMutableList() } + additionalProperties = body.additionalProperties.toMutableMap() + } + + fun checks(checks: List) = checks(JsonField.of(checks)) + + /** + * Sets [Builder.checks] to an arbitrary JSON value. + * + * You should usually call [Builder.checks] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun checks(checks: JsonField>) = apply { + this.checks = checks.map { it.toMutableList() } + } + + /** + * Adds a single [BaseCheck] to [checks]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addCheck(check: BaseCheck) = apply { + checks = + (checks ?: JsonField.of(mutableListOf())).also { + checkKnown("checks", it).add(check) + } + } + + 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 + * .checks() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("checks", checks).map { it.toImmutable() }, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + checks().forEach { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (checks.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + checks == other.checks && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(checks, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Body{checks=$checks, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is CheckUpdateParams && + id == other.id && + submissionId == other.submissionId && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(id, submissionId, body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "CheckUpdateParams{id=$id, submissionId=$submissionId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/notifications/checks/CheckUpdateResponse.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/notifications/checks/CheckUpdateResponse.kt new file mode 100644 index 00000000..247b068e --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/notifications/checks/CheckUpdateResponse.kt @@ -0,0 +1,190 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.notifications.checks + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkKnown +import com.courier.api.core.checkRequired +import com.courier.api.core.toImmutable +import com.courier.api.errors.CourierInvalidDataException +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 kotlin.jvm.optionals.getOrNull + +class CheckUpdateResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val checks: JsonField>, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("checks") @ExcludeMissing checks: JsonField> = JsonMissing.of() + ) : this(checks, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 checks(): List = checks.getRequired("checks") + + /** + * Returns the raw JSON value of [checks]. + * + * Unlike [checks], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("checks") @ExcludeMissing fun _checks(): JsonField> = checks + + @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 [CheckUpdateResponse]. + * + * The following fields are required: + * ```java + * .checks() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [CheckUpdateResponse]. */ + class Builder internal constructor() { + + private var checks: JsonField>? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(checkUpdateResponse: CheckUpdateResponse) = apply { + checks = checkUpdateResponse.checks.map { it.toMutableList() } + additionalProperties = checkUpdateResponse.additionalProperties.toMutableMap() + } + + fun checks(checks: List) = checks(JsonField.of(checks)) + + /** + * Sets [Builder.checks] to an arbitrary JSON value. + * + * You should usually call [Builder.checks] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun checks(checks: JsonField>) = apply { + this.checks = checks.map { it.toMutableList() } + } + + /** + * Adds a single [Check] to [checks]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addCheck(check: Check) = apply { + checks = + (checks ?: JsonField.of(mutableListOf())).also { + checkKnown("checks", it).add(check) + } + } + + 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 [CheckUpdateResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .checks() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): CheckUpdateResponse = + CheckUpdateResponse( + checkRequired("checks", checks).map { it.toImmutable() }, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): CheckUpdateResponse = apply { + if (validated) { + return@apply + } + + checks().forEach { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (checks.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is CheckUpdateResponse && + checks == other.checks && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(checks, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "CheckUpdateResponse{checks=$checks, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/notifications/draft/DraftRetrieveContentParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/notifications/draft/DraftRetrieveContentParams.kt new file mode 100644 index 00000000..5c43c165 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/notifications/draft/DraftRetrieveContentParams.kt @@ -0,0 +1,190 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.notifications.draft + +import com.courier.api.core.Params +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +class DraftRetrieveContentParams +private constructor( + private val id: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun id(): Optional = Optional.ofNullable(id) + + /** 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(): DraftRetrieveContentParams = builder().build() + + /** + * Returns a mutable builder for constructing an instance of [DraftRetrieveContentParams]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [DraftRetrieveContentParams]. */ + class Builder internal constructor() { + + private var id: String? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(draftRetrieveContentParams: DraftRetrieveContentParams) = apply { + id = draftRetrieveContentParams.id + additionalHeaders = draftRetrieveContentParams.additionalHeaders.toBuilder() + additionalQueryParams = draftRetrieveContentParams.additionalQueryParams.toBuilder() + } + + fun id(id: String?) = apply { this.id = id } + + /** Alias for calling [Builder.id] with `id.orElse(null)`. */ + fun id(id: Optional) = id(id.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 [DraftRetrieveContentParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): DraftRetrieveContentParams = + DraftRetrieveContentParams(id, additionalHeaders.build(), additionalQueryParams.build()) + } + + fun _pathParam(index: Int): String = + when (index) { + 0 -> id ?: "" + 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 DraftRetrieveContentParams && + id == other.id && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = Objects.hash(id, additionalHeaders, additionalQueryParams) + + override fun toString() = + "DraftRetrieveContentParams{id=$id, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/ProfileCreateParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/ProfileCreateParams.kt new file mode 100644 index 00000000..3152fbfa --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/ProfileCreateParams.kt @@ -0,0 +1,534 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.profiles + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.Params +import com.courier.api.core.checkRequired +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import com.courier.api.core.toImmutable +import com.courier.api.errors.CourierInvalidDataException +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 + +/** + * Merge the supplied values with an existing profile or create a new profile if one doesn't already + * exist. + */ +class ProfileCreateParams +private constructor( + private val userId: String?, + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun userId(): Optional = Optional.ofNullable(userId) + + /** + * @throws CourierInvalidDataException 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 profile(): Profile = body.profile() + + /** + * Returns the raw JSON value of [profile]. + * + * Unlike [profile], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _profile(): JsonField = body._profile() + + 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 [ProfileCreateParams]. + * + * The following fields are required: + * ```java + * .profile() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ProfileCreateParams]. */ + class Builder internal constructor() { + + private var userId: 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(profileCreateParams: ProfileCreateParams) = apply { + userId = profileCreateParams.userId + body = profileCreateParams.body.toBuilder() + additionalHeaders = profileCreateParams.additionalHeaders.toBuilder() + additionalQueryParams = profileCreateParams.additionalQueryParams.toBuilder() + } + + fun userId(userId: String?) = apply { this.userId = userId } + + /** Alias for calling [Builder.userId] with `userId.orElse(null)`. */ + fun userId(userId: Optional) = userId(userId.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: + * - [profile] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + fun profile(profile: Profile) = apply { body.profile(profile) } + + /** + * Sets [Builder.profile] to an arbitrary JSON value. + * + * You should usually call [Builder.profile] with a well-typed [Profile] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun profile(profile: JsonField) = apply { body.profile(profile) } + + 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 [ProfileCreateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .profile() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ProfileCreateParams = + ProfileCreateParams( + userId, + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): Body = body + + fun _pathParam(index: Int): String = + when (index) { + 0 -> userId ?: "" + else -> "" + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + class Body + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val profile: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("profile") @ExcludeMissing profile: JsonField = JsonMissing.of() + ) : this(profile, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 profile(): Profile = profile.getRequired("profile") + + /** + * Returns the raw JSON value of [profile]. + * + * Unlike [profile], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("profile") @ExcludeMissing fun _profile(): JsonField = profile + + @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 + * .profile() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var profile: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + profile = body.profile + additionalProperties = body.additionalProperties.toMutableMap() + } + + fun profile(profile: Profile) = profile(JsonField.of(profile)) + + /** + * Sets [Builder.profile] to an arbitrary JSON value. + * + * You should usually call [Builder.profile] with a well-typed [Profile] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun profile(profile: JsonField) = apply { this.profile = profile } + + 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 + * .profile() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body(checkRequired("profile", profile), additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + profile().validate() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = (profile.asKnown().getOrNull()?.validity() ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + profile == other.profile && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(profile, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{profile=$profile, additionalProperties=$additionalProperties}" + } + + class Profile + @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 [Profile]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Profile]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(profile: Profile) = apply { + additionalProperties = profile.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 [Profile]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Profile = Profile(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): Profile = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Profile && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Profile{additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ProfileCreateParams && + userId == other.userId && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(userId, body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "ProfileCreateParams{userId=$userId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/ProfileCreateResponse.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/ProfileCreateResponse.kt new file mode 100644 index 00000000..3fbea25f --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/ProfileCreateResponse.kt @@ -0,0 +1,291 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.profiles + +import com.courier.api.core.Enum +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkRequired +import com.courier.api.errors.CourierInvalidDataException +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 kotlin.jvm.optionals.getOrNull + +class ProfileCreateResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val status: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of() + ) : this(status, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 status(): Status = status.getRequired("status") + + /** + * 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 [ProfileCreateResponse]. + * + * The following fields are required: + * ```java + * .status() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ProfileCreateResponse]. */ + class Builder internal constructor() { + + private var status: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(profileCreateResponse: ProfileCreateResponse) = apply { + status = profileCreateResponse.status + additionalProperties = profileCreateResponse.additionalProperties.toMutableMap() + } + + 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 } + + 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 [ProfileCreateResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .status() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ProfileCreateResponse = + ProfileCreateResponse( + checkRequired("status", status), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): ProfileCreateResponse = apply { + if (validated) { + return@apply + } + + status().validate() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = (status.asKnown().getOrNull()?.validity() ?: 0) + + 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 SUCCESS = of("SUCCESS") + + @JvmStatic fun of(value: String) = Status(JsonField.of(value)) + } + + /** An enum containing [Status]'s known values. */ + enum class Known { + SUCCESS + } + + /** + * 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 { + SUCCESS, + /** 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) { + SUCCESS -> Value.SUCCESS + 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 CourierInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + SUCCESS -> Known.SUCCESS + else -> throw CourierInvalidDataException("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 CourierInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { CourierInvalidDataException("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: CourierInvalidDataException) { + 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 ProfileCreateResponse && + status == other.status && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(status, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ProfileCreateResponse{status=$status, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/ProfileDeleteParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/ProfileDeleteParams.kt new file mode 100644 index 00000000..00f0c4ec --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/ProfileDeleteParams.kt @@ -0,0 +1,229 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.profiles + +import com.courier.api.core.JsonValue +import com.courier.api.core.Params +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import com.courier.api.core.toImmutable +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Deletes the specified user profile. */ +class ProfileDeleteParams +private constructor( + private val userId: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, + private val additionalBodyProperties: Map, +) : Params { + + fun userId(): Optional = Optional.ofNullable(userId) + + /** 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(): ProfileDeleteParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [ProfileDeleteParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ProfileDeleteParams]. */ + class Builder internal constructor() { + + private var userId: 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(profileDeleteParams: ProfileDeleteParams) = apply { + userId = profileDeleteParams.userId + additionalHeaders = profileDeleteParams.additionalHeaders.toBuilder() + additionalQueryParams = profileDeleteParams.additionalQueryParams.toBuilder() + additionalBodyProperties = profileDeleteParams.additionalBodyProperties.toMutableMap() + } + + fun userId(userId: String?) = apply { this.userId = userId } + + /** Alias for calling [Builder.userId] with `userId.orElse(null)`. */ + fun userId(userId: Optional) = userId(userId.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 [ProfileDeleteParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): ProfileDeleteParams = + ProfileDeleteParams( + userId, + additionalHeaders.build(), + additionalQueryParams.build(), + additionalBodyProperties.toImmutable(), + ) + } + + fun _body(): Optional> = + Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) + + fun _pathParam(index: Int): String = + when (index) { + 0 -> userId ?: "" + 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 ProfileDeleteParams && + userId == other.userId && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams && + additionalBodyProperties == other.additionalBodyProperties + } + + override fun hashCode(): Int = + Objects.hash(userId, additionalHeaders, additionalQueryParams, additionalBodyProperties) + + override fun toString() = + "ProfileDeleteParams{userId=$userId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/ProfileReplaceParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/ProfileReplaceParams.kt new file mode 100644 index 00000000..b098e69f --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/ProfileReplaceParams.kt @@ -0,0 +1,536 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.profiles + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.Params +import com.courier.api.core.checkRequired +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import com.courier.api.core.toImmutable +import com.courier.api.errors.CourierInvalidDataException +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 + +/** + * When using `PUT`, be sure to include all the key-value pairs required by the recipient's profile. + * Any key-value pairs that exist in the profile but fail to be included in the `PUT` request will + * be removed from the profile. Remember, a `PUT` update is a full replacement of the data. For + * partial updates, use the [Patch](https://www.courier.com/docs/reference/profiles/patch/) request. + */ +class ProfileReplaceParams +private constructor( + private val userId: String?, + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun userId(): Optional = Optional.ofNullable(userId) + + /** + * @throws CourierInvalidDataException 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 profile(): Profile = body.profile() + + /** + * Returns the raw JSON value of [profile]. + * + * Unlike [profile], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _profile(): JsonField = body._profile() + + 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 [ProfileReplaceParams]. + * + * The following fields are required: + * ```java + * .profile() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ProfileReplaceParams]. */ + class Builder internal constructor() { + + private var userId: 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(profileReplaceParams: ProfileReplaceParams) = apply { + userId = profileReplaceParams.userId + body = profileReplaceParams.body.toBuilder() + additionalHeaders = profileReplaceParams.additionalHeaders.toBuilder() + additionalQueryParams = profileReplaceParams.additionalQueryParams.toBuilder() + } + + fun userId(userId: String?) = apply { this.userId = userId } + + /** Alias for calling [Builder.userId] with `userId.orElse(null)`. */ + fun userId(userId: Optional) = userId(userId.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: + * - [profile] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + fun profile(profile: Profile) = apply { body.profile(profile) } + + /** + * Sets [Builder.profile] to an arbitrary JSON value. + * + * You should usually call [Builder.profile] with a well-typed [Profile] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun profile(profile: JsonField) = apply { body.profile(profile) } + + 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 [ProfileReplaceParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .profile() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ProfileReplaceParams = + ProfileReplaceParams( + userId, + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): Body = body + + fun _pathParam(index: Int): String = + when (index) { + 0 -> userId ?: "" + else -> "" + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + class Body + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val profile: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("profile") @ExcludeMissing profile: JsonField = JsonMissing.of() + ) : this(profile, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 profile(): Profile = profile.getRequired("profile") + + /** + * Returns the raw JSON value of [profile]. + * + * Unlike [profile], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("profile") @ExcludeMissing fun _profile(): JsonField = profile + + @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 + * .profile() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var profile: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + profile = body.profile + additionalProperties = body.additionalProperties.toMutableMap() + } + + fun profile(profile: Profile) = profile(JsonField.of(profile)) + + /** + * Sets [Builder.profile] to an arbitrary JSON value. + * + * You should usually call [Builder.profile] with a well-typed [Profile] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun profile(profile: JsonField) = apply { this.profile = profile } + + 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 + * .profile() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body(checkRequired("profile", profile), additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + profile().validate() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = (profile.asKnown().getOrNull()?.validity() ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + profile == other.profile && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(profile, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{profile=$profile, additionalProperties=$additionalProperties}" + } + + class Profile + @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 [Profile]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Profile]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(profile: Profile) = apply { + additionalProperties = profile.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 [Profile]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Profile = Profile(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): Profile = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Profile && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Profile{additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ProfileReplaceParams && + userId == other.userId && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(userId, body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "ProfileReplaceParams{userId=$userId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/ProfileReplaceResponse.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/ProfileReplaceResponse.kt new file mode 100644 index 00000000..aece92bb --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/ProfileReplaceResponse.kt @@ -0,0 +1,291 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.profiles + +import com.courier.api.core.Enum +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkRequired +import com.courier.api.errors.CourierInvalidDataException +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 kotlin.jvm.optionals.getOrNull + +class ProfileReplaceResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val status: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of() + ) : this(status, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 status(): Status = status.getRequired("status") + + /** + * 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 [ProfileReplaceResponse]. + * + * The following fields are required: + * ```java + * .status() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ProfileReplaceResponse]. */ + class Builder internal constructor() { + + private var status: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(profileReplaceResponse: ProfileReplaceResponse) = apply { + status = profileReplaceResponse.status + additionalProperties = profileReplaceResponse.additionalProperties.toMutableMap() + } + + 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 } + + 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 [ProfileReplaceResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .status() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ProfileReplaceResponse = + ProfileReplaceResponse( + checkRequired("status", status), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): ProfileReplaceResponse = apply { + if (validated) { + return@apply + } + + status().validate() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = (status.asKnown().getOrNull()?.validity() ?: 0) + + 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 SUCCESS = of("SUCCESS") + + @JvmStatic fun of(value: String) = Status(JsonField.of(value)) + } + + /** An enum containing [Status]'s known values. */ + enum class Known { + SUCCESS + } + + /** + * 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 { + SUCCESS, + /** 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) { + SUCCESS -> Value.SUCCESS + 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 CourierInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + SUCCESS -> Known.SUCCESS + else -> throw CourierInvalidDataException("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 CourierInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { CourierInvalidDataException("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: CourierInvalidDataException) { + 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 ProfileReplaceResponse && + status == other.status && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(status, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ProfileReplaceResponse{status=$status, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/ProfileRetrieveParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/ProfileRetrieveParams.kt new file mode 100644 index 00000000..f1473061 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/ProfileRetrieveParams.kt @@ -0,0 +1,189 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.profiles + +import com.courier.api.core.Params +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Returns the specified user profile. */ +class ProfileRetrieveParams +private constructor( + private val userId: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun userId(): Optional = Optional.ofNullable(userId) + + /** 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(): ProfileRetrieveParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [ProfileRetrieveParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ProfileRetrieveParams]. */ + class Builder internal constructor() { + + private var userId: String? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(profileRetrieveParams: ProfileRetrieveParams) = apply { + userId = profileRetrieveParams.userId + additionalHeaders = profileRetrieveParams.additionalHeaders.toBuilder() + additionalQueryParams = profileRetrieveParams.additionalQueryParams.toBuilder() + } + + fun userId(userId: String?) = apply { this.userId = userId } + + /** Alias for calling [Builder.userId] with `userId.orElse(null)`. */ + fun userId(userId: Optional) = userId(userId.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 [ProfileRetrieveParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): ProfileRetrieveParams = + ProfileRetrieveParams(userId, additionalHeaders.build(), additionalQueryParams.build()) + } + + fun _pathParam(index: Int): String = + when (index) { + 0 -> userId ?: "" + 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 ProfileRetrieveParams && + userId == other.userId && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = Objects.hash(userId, additionalHeaders, additionalQueryParams) + + override fun toString() = + "ProfileRetrieveParams{userId=$userId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/ProfileRetrieveResponse.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/ProfileRetrieveResponse.kt new file mode 100644 index 00000000..3cad1eaf --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/ProfileRetrieveResponse.kt @@ -0,0 +1,318 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.profiles + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkRequired +import com.courier.api.core.toImmutable +import com.courier.api.errors.CourierInvalidDataException +import com.courier.api.models.lists.subscriptions.RecipientPreferences +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 ProfileRetrieveResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val profile: JsonField, + private val preferences: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("profile") @ExcludeMissing profile: JsonField = JsonMissing.of(), + @JsonProperty("preferences") + @ExcludeMissing + preferences: JsonField = JsonMissing.of(), + ) : this(profile, preferences, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 profile(): Profile = profile.getRequired("profile") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun preferences(): Optional = preferences.getOptional("preferences") + + /** + * Returns the raw JSON value of [profile]. + * + * Unlike [profile], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("profile") @ExcludeMissing fun _profile(): JsonField = profile + + /** + * Returns the raw JSON value of [preferences]. + * + * Unlike [preferences], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("preferences") + @ExcludeMissing + fun _preferences(): JsonField = preferences + + @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 [ProfileRetrieveResponse]. + * + * The following fields are required: + * ```java + * .profile() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ProfileRetrieveResponse]. */ + class Builder internal constructor() { + + private var profile: JsonField? = null + private var preferences: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(profileRetrieveResponse: ProfileRetrieveResponse) = apply { + profile = profileRetrieveResponse.profile + preferences = profileRetrieveResponse.preferences + additionalProperties = profileRetrieveResponse.additionalProperties.toMutableMap() + } + + fun profile(profile: Profile) = profile(JsonField.of(profile)) + + /** + * Sets [Builder.profile] to an arbitrary JSON value. + * + * You should usually call [Builder.profile] with a well-typed [Profile] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun profile(profile: JsonField) = apply { this.profile = profile } + + fun preferences(preferences: RecipientPreferences?) = + preferences(JsonField.ofNullable(preferences)) + + /** Alias for calling [Builder.preferences] with `preferences.orElse(null)`. */ + fun preferences(preferences: Optional) = + preferences(preferences.getOrNull()) + + /** + * Sets [Builder.preferences] to an arbitrary JSON value. + * + * You should usually call [Builder.preferences] with a well-typed [RecipientPreferences] + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun preferences(preferences: JsonField) = apply { + this.preferences = preferences + } + + 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 [ProfileRetrieveResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .profile() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ProfileRetrieveResponse = + ProfileRetrieveResponse( + checkRequired("profile", profile), + preferences, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): ProfileRetrieveResponse = apply { + if (validated) { + return@apply + } + + profile().validate() + preferences().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (profile.asKnown().getOrNull()?.validity() ?: 0) + + (preferences.asKnown().getOrNull()?.validity() ?: 0) + + class Profile + @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 [Profile]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Profile]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(profile: Profile) = apply { + additionalProperties = profile.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 [Profile]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Profile = Profile(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): Profile = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Profile && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Profile{additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ProfileRetrieveResponse && + profile == other.profile && + preferences == other.preferences && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(profile, preferences, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ProfileRetrieveResponse{profile=$profile, preferences=$preferences, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/ProfileUpdateParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/ProfileUpdateParams.kt new file mode 100644 index 00000000..bba60512 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/ProfileUpdateParams.kt @@ -0,0 +1,699 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.profiles + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.Params +import com.courier.api.core.checkKnown +import com.courier.api.core.checkRequired +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import com.courier.api.core.toImmutable +import com.courier.api.errors.CourierInvalidDataException +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 + +/** Update a profile */ +class ProfileUpdateParams +private constructor( + private val userId: String?, + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun userId(): Optional = Optional.ofNullable(userId) + + /** + * List of patch operations to apply to the profile. + * + * @throws CourierInvalidDataException 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 patch(): List = body.patch() + + /** + * Returns the raw JSON value of [patch]. + * + * Unlike [patch], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _patch(): JsonField> = body._patch() + + 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 [ProfileUpdateParams]. + * + * The following fields are required: + * ```java + * .patch() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ProfileUpdateParams]. */ + class Builder internal constructor() { + + private var userId: 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(profileUpdateParams: ProfileUpdateParams) = apply { + userId = profileUpdateParams.userId + body = profileUpdateParams.body.toBuilder() + additionalHeaders = profileUpdateParams.additionalHeaders.toBuilder() + additionalQueryParams = profileUpdateParams.additionalQueryParams.toBuilder() + } + + fun userId(userId: String?) = apply { this.userId = userId } + + /** Alias for calling [Builder.userId] with `userId.orElse(null)`. */ + fun userId(userId: Optional) = userId(userId.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: + * - [patch] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + /** List of patch operations to apply to the profile. */ + fun patch(patch: List) = apply { body.patch(patch) } + + /** + * Sets [Builder.patch] to an arbitrary JSON value. + * + * You should usually call [Builder.patch] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun patch(patch: JsonField>) = apply { body.patch(patch) } + + /** + * Adds a single [Patch] to [Builder.patch]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addPatch(patch: Patch) = apply { body.addPatch(patch) } + + 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 [ProfileUpdateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .patch() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ProfileUpdateParams = + ProfileUpdateParams( + userId, + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): Body = body + + fun _pathParam(index: Int): String = + when (index) { + 0 -> userId ?: "" + else -> "" + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + class Body + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val patch: JsonField>, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("patch") @ExcludeMissing patch: JsonField> = JsonMissing.of() + ) : this(patch, mutableMapOf()) + + /** + * List of patch operations to apply to the profile. + * + * @throws CourierInvalidDataException 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 patch(): List = patch.getRequired("patch") + + /** + * Returns the raw JSON value of [patch]. + * + * Unlike [patch], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("patch") @ExcludeMissing fun _patch(): JsonField> = patch + + @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 + * .patch() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var patch: JsonField>? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + patch = body.patch.map { it.toMutableList() } + additionalProperties = body.additionalProperties.toMutableMap() + } + + /** List of patch operations to apply to the profile. */ + fun patch(patch: List) = patch(JsonField.of(patch)) + + /** + * Sets [Builder.patch] to an arbitrary JSON value. + * + * You should usually call [Builder.patch] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun patch(patch: JsonField>) = apply { + this.patch = patch.map { it.toMutableList() } + } + + /** + * Adds a single [Patch] to [Builder.patch]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addPatch(patch: Patch) = apply { + this.patch = + (this.patch ?: JsonField.of(mutableListOf())).also { + checkKnown("patch", it).add(patch) + } + } + + 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 + * .patch() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("patch", patch).map { it.toImmutable() }, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + patch().forEach { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (patch.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + patch == other.patch && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(patch, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Body{patch=$patch, additionalProperties=$additionalProperties}" + } + + class Patch + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val op: JsonField, + private val path: JsonField, + private val value: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("op") @ExcludeMissing op: JsonField = JsonMissing.of(), + @JsonProperty("path") @ExcludeMissing path: JsonField = JsonMissing.of(), + @JsonProperty("value") @ExcludeMissing value: JsonField = JsonMissing.of(), + ) : this(op, path, value, mutableMapOf()) + + /** + * The operation to perform. + * + * @throws CourierInvalidDataException 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 op(): String = op.getRequired("op") + + /** + * The JSON path specifying the part of the profile to operate on. + * + * @throws CourierInvalidDataException 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 path(): String = path.getRequired("path") + + /** + * The value for the operation. + * + * @throws CourierInvalidDataException 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 value(): String = value.getRequired("value") + + /** + * Returns the raw JSON value of [op]. + * + * Unlike [op], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("op") @ExcludeMissing fun _op(): JsonField = op + + /** + * 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 [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 [Patch]. + * + * The following fields are required: + * ```java + * .op() + * .path() + * .value() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Patch]. */ + class Builder internal constructor() { + + private var op: JsonField? = null + private var path: JsonField? = null + private var value: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(patch: Patch) = apply { + op = patch.op + path = patch.path + value = patch.value + additionalProperties = patch.additionalProperties.toMutableMap() + } + + /** The operation to perform. */ + fun op(op: String) = op(JsonField.of(op)) + + /** + * Sets [Builder.op] to an arbitrary JSON value. + * + * You should usually call [Builder.op] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun op(op: JsonField) = apply { this.op = op } + + /** The JSON path specifying the part of the profile to operate on. */ + 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 } + + /** The value for the operation. */ + fun value(value: String) = value(JsonField.of(value)) + + /** + * Sets [Builder.value] to an arbitrary JSON value. + * + * You should usually call [Builder.value] 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 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 [Patch]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .op() + * .path() + * .value() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Patch = + Patch( + checkRequired("op", op), + checkRequired("path", path), + checkRequired("value", value), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Patch = apply { + if (validated) { + return@apply + } + + op() + path() + value() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (op.asKnown().isPresent) 1 else 0) + + (if (path.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 Patch && + op == other.op && + path == other.path && + value == other.value && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(op, path, value, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Patch{op=$op, path=$path, value=$value, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ProfileUpdateParams && + userId == other.userId && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(userId, body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "ProfileUpdateParams{userId=$userId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/lists/ListDeleteParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/lists/ListDeleteParams.kt new file mode 100644 index 00000000..2ec008a1 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/lists/ListDeleteParams.kt @@ -0,0 +1,229 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.profiles.lists + +import com.courier.api.core.JsonValue +import com.courier.api.core.Params +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import com.courier.api.core.toImmutable +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Removes all list subscriptions for given user. */ +class ListDeleteParams +private constructor( + private val userId: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, + private val additionalBodyProperties: Map, +) : Params { + + fun userId(): Optional = Optional.ofNullable(userId) + + /** 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(): ListDeleteParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [ListDeleteParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ListDeleteParams]. */ + class Builder internal constructor() { + + private var userId: 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(listDeleteParams: ListDeleteParams) = apply { + userId = listDeleteParams.userId + additionalHeaders = listDeleteParams.additionalHeaders.toBuilder() + additionalQueryParams = listDeleteParams.additionalQueryParams.toBuilder() + additionalBodyProperties = listDeleteParams.additionalBodyProperties.toMutableMap() + } + + fun userId(userId: String?) = apply { this.userId = userId } + + /** Alias for calling [Builder.userId] with `userId.orElse(null)`. */ + fun userId(userId: Optional) = userId(userId.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 [ListDeleteParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): ListDeleteParams = + ListDeleteParams( + userId, + additionalHeaders.build(), + additionalQueryParams.build(), + additionalBodyProperties.toImmutable(), + ) + } + + fun _body(): Optional> = + Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) + + fun _pathParam(index: Int): String = + when (index) { + 0 -> userId ?: "" + 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 ListDeleteParams && + userId == other.userId && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams && + additionalBodyProperties == other.additionalBodyProperties + } + + override fun hashCode(): Int = + Objects.hash(userId, additionalHeaders, additionalQueryParams, additionalBodyProperties) + + override fun toString() = + "ListDeleteParams{userId=$userId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/lists/ListDeleteResponse.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/lists/ListDeleteResponse.kt new file mode 100644 index 00000000..87e9f656 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/lists/ListDeleteResponse.kt @@ -0,0 +1,288 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.profiles.lists + +import com.courier.api.core.Enum +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkRequired +import com.courier.api.errors.CourierInvalidDataException +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 kotlin.jvm.optionals.getOrNull + +class ListDeleteResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val status: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of() + ) : this(status, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 status(): Status = status.getRequired("status") + + /** + * 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 [ListDeleteResponse]. + * + * The following fields are required: + * ```java + * .status() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ListDeleteResponse]. */ + class Builder internal constructor() { + + private var status: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(listDeleteResponse: ListDeleteResponse) = apply { + status = listDeleteResponse.status + additionalProperties = listDeleteResponse.additionalProperties.toMutableMap() + } + + 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 } + + 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 [ListDeleteResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .status() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ListDeleteResponse = + ListDeleteResponse(checkRequired("status", status), additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): ListDeleteResponse = apply { + if (validated) { + return@apply + } + + status().validate() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = (status.asKnown().getOrNull()?.validity() ?: 0) + + 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 SUCCESS = of("SUCCESS") + + @JvmStatic fun of(value: String) = Status(JsonField.of(value)) + } + + /** An enum containing [Status]'s known values. */ + enum class Known { + SUCCESS + } + + /** + * 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 { + SUCCESS, + /** 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) { + SUCCESS -> Value.SUCCESS + 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 CourierInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + SUCCESS -> Known.SUCCESS + else -> throw CourierInvalidDataException("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 CourierInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { CourierInvalidDataException("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: CourierInvalidDataException) { + 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 ListDeleteResponse && + status == other.status && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(status, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ListDeleteResponse{status=$status, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/lists/ListRetrieveParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/lists/ListRetrieveParams.kt new file mode 100644 index 00000000..58865be6 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/lists/ListRetrieveParams.kt @@ -0,0 +1,214 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.profiles.lists + +import com.courier.api.core.Params +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Returns the subscribed lists for a specified user. */ +class ListRetrieveParams +private constructor( + private val userId: String?, + private val cursor: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun userId(): Optional = Optional.ofNullable(userId) + + /** A unique identifier that allows for fetching the next set of message statuses. */ + fun cursor(): Optional = Optional.ofNullable(cursor) + + /** 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(): ListRetrieveParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [ListRetrieveParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ListRetrieveParams]. */ + class Builder internal constructor() { + + private var userId: String? = null + private var cursor: String? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(listRetrieveParams: ListRetrieveParams) = apply { + userId = listRetrieveParams.userId + cursor = listRetrieveParams.cursor + additionalHeaders = listRetrieveParams.additionalHeaders.toBuilder() + additionalQueryParams = listRetrieveParams.additionalQueryParams.toBuilder() + } + + fun userId(userId: String?) = apply { this.userId = userId } + + /** Alias for calling [Builder.userId] with `userId.orElse(null)`. */ + fun userId(userId: Optional) = userId(userId.getOrNull()) + + /** A unique identifier that allows for fetching the next set of message statuses. */ + fun cursor(cursor: String?) = apply { this.cursor = cursor } + + /** Alias for calling [Builder.cursor] with `cursor.orElse(null)`. */ + fun cursor(cursor: Optional) = cursor(cursor.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 [ListRetrieveParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): ListRetrieveParams = + ListRetrieveParams( + userId, + cursor, + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _pathParam(index: Int): String = + when (index) { + 0 -> userId ?: "" + else -> "" + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + cursor?.let { put("cursor", it) } + putAll(additionalQueryParams) + } + .build() + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ListRetrieveParams && + userId == other.userId && + cursor == other.cursor && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(userId, cursor, additionalHeaders, additionalQueryParams) + + override fun toString() = + "ListRetrieveParams{userId=$userId, cursor=$cursor, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/lists/ListRetrieveResponse.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/lists/ListRetrieveResponse.kt new file mode 100644 index 00000000..c9315e95 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/lists/ListRetrieveResponse.kt @@ -0,0 +1,547 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.profiles.lists + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkKnown +import com.courier.api.core.checkRequired +import com.courier.api.core.toImmutable +import com.courier.api.errors.CourierInvalidDataException +import com.courier.api.models.audiences.Paging +import com.courier.api.models.lists.subscriptions.RecipientPreferences +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 ListRetrieveResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val paging: JsonField, + private val results: JsonField>, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("paging") @ExcludeMissing paging: JsonField = JsonMissing.of(), + @JsonProperty("results") @ExcludeMissing results: JsonField> = JsonMissing.of(), + ) : this(paging, results, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 paging(): Paging = paging.getRequired("paging") + + /** + * An array of lists + * + * @throws CourierInvalidDataException 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 results(): List = results.getRequired("results") + + /** + * Returns the raw JSON value of [paging]. + * + * Unlike [paging], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("paging") @ExcludeMissing fun _paging(): JsonField = paging + + /** + * Returns the raw JSON value of [results]. + * + * Unlike [results], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("results") @ExcludeMissing fun _results(): JsonField> = results + + @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 [ListRetrieveResponse]. + * + * The following fields are required: + * ```java + * .paging() + * .results() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ListRetrieveResponse]. */ + class Builder internal constructor() { + + private var paging: JsonField? = null + private var results: JsonField>? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(listRetrieveResponse: ListRetrieveResponse) = apply { + paging = listRetrieveResponse.paging + results = listRetrieveResponse.results.map { it.toMutableList() } + additionalProperties = listRetrieveResponse.additionalProperties.toMutableMap() + } + + fun paging(paging: Paging) = paging(JsonField.of(paging)) + + /** + * Sets [Builder.paging] to an arbitrary JSON value. + * + * You should usually call [Builder.paging] with a well-typed [Paging] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun paging(paging: JsonField) = apply { this.paging = paging } + + /** An array of lists */ + fun results(results: List) = results(JsonField.of(results)) + + /** + * Sets [Builder.results] to an arbitrary JSON value. + * + * You should usually call [Builder.results] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun results(results: JsonField>) = apply { + this.results = results.map { it.toMutableList() } + } + + /** + * Adds a single [Result] to [results]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addResult(result: Result) = apply { + results = + (results ?: JsonField.of(mutableListOf())).also { + checkKnown("results", it).add(result) + } + } + + 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 [ListRetrieveResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .paging() + * .results() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ListRetrieveResponse = + ListRetrieveResponse( + checkRequired("paging", paging), + checkRequired("results", results).map { it.toImmutable() }, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): ListRetrieveResponse = apply { + if (validated) { + return@apply + } + + paging().validate() + results().forEach { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (paging.asKnown().getOrNull()?.validity() ?: 0) + + (results.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + class Result + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val id: JsonField, + private val created: JsonField, + private val name: JsonField, + private val updated: JsonField, + private val preferences: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("created") @ExcludeMissing created: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("updated") @ExcludeMissing updated: JsonField = JsonMissing.of(), + @JsonProperty("preferences") + @ExcludeMissing + preferences: JsonField = JsonMissing.of(), + ) : this(id, created, name, updated, preferences, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 id(): String = id.getRequired("id") + + /** + * The date/time of when the list was created. Represented as a string in ISO format. + * + * @throws CourierInvalidDataException 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 created(): String = created.getRequired("created") + + /** + * List name + * + * @throws CourierInvalidDataException 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 name(): String = name.getRequired("name") + + /** + * The date/time of when the list was updated. Represented as a string in ISO format. + * + * @throws CourierInvalidDataException 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 updated(): String = updated.getRequired("updated") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun preferences(): Optional = preferences.getOptional("preferences") + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + /** + * Returns the raw JSON value of [created]. + * + * Unlike [created], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created") @ExcludeMissing fun _created(): JsonField = created + + /** + * 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 [updated]. + * + * Unlike [updated], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("updated") @ExcludeMissing fun _updated(): JsonField = updated + + /** + * Returns the raw JSON value of [preferences]. + * + * Unlike [preferences], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("preferences") + @ExcludeMissing + fun _preferences(): JsonField = preferences + + @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 [Result]. + * + * The following fields are required: + * ```java + * .id() + * .created() + * .name() + * .updated() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Result]. */ + class Builder internal constructor() { + + private var id: JsonField? = null + private var created: JsonField? = null + private var name: JsonField? = null + private var updated: JsonField? = null + private var preferences: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(result: Result) = apply { + id = result.id + created = result.created + name = result.name + updated = result.updated + preferences = result.preferences + additionalProperties = result.additionalProperties.toMutableMap() + } + + fun id(id: String) = id(JsonField.of(id)) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun id(id: JsonField) = apply { this.id = id } + + /** + * The date/time of when the list was created. Represented as a string in ISO format. + */ + fun created(created: String) = created(JsonField.of(created)) + + /** + * Sets [Builder.created] to an arbitrary JSON value. + * + * You should usually call [Builder.created] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun created(created: JsonField) = apply { this.created = created } + + /** List 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 } + + /** + * The date/time of when the list was updated. Represented as a string in ISO format. + */ + fun updated(updated: String) = updated(JsonField.of(updated)) + + /** + * Sets [Builder.updated] to an arbitrary JSON value. + * + * You should usually call [Builder.updated] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun updated(updated: JsonField) = apply { this.updated = updated } + + fun preferences(preferences: RecipientPreferences?) = + preferences(JsonField.ofNullable(preferences)) + + /** Alias for calling [Builder.preferences] with `preferences.orElse(null)`. */ + fun preferences(preferences: Optional) = + preferences(preferences.getOrNull()) + + /** + * Sets [Builder.preferences] to an arbitrary JSON value. + * + * You should usually call [Builder.preferences] with a well-typed + * [RecipientPreferences] value instead. This method is primarily for setting the field + * to an undocumented or not yet supported value. + */ + fun preferences(preferences: JsonField) = apply { + this.preferences = preferences + } + + 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 [Result]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .created() + * .name() + * .updated() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Result = + Result( + checkRequired("id", id), + checkRequired("created", created), + checkRequired("name", name), + checkRequired("updated", updated), + preferences, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Result = apply { + if (validated) { + return@apply + } + + id() + created() + name() + updated() + preferences().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (id.asKnown().isPresent) 1 else 0) + + (if (created.asKnown().isPresent) 1 else 0) + + (if (name.asKnown().isPresent) 1 else 0) + + (if (updated.asKnown().isPresent) 1 else 0) + + (preferences.asKnown().getOrNull()?.validity() ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Result && + id == other.id && + created == other.created && + name == other.name && + updated == other.updated && + preferences == other.preferences && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(id, created, name, updated, preferences, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Result{id=$id, created=$created, name=$name, updated=$updated, preferences=$preferences, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ListRetrieveResponse && + paging == other.paging && + results == other.results && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(paging, results, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ListRetrieveResponse{paging=$paging, results=$results, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/lists/ListSubscribeParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/lists/ListSubscribeParams.kt new file mode 100644 index 00000000..b8ae717f --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/lists/ListSubscribeParams.kt @@ -0,0 +1,664 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.profiles.lists + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.Params +import com.courier.api.core.checkKnown +import com.courier.api.core.checkRequired +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import com.courier.api.core.toImmutable +import com.courier.api.errors.CourierInvalidDataException +import com.courier.api.models.lists.subscriptions.RecipientPreferences +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 + +/** + * Subscribes the given user to one or more lists. If the list does not exist, it will be created. + */ +class ListSubscribeParams +private constructor( + private val userId: String?, + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun userId(): Optional = Optional.ofNullable(userId) + + /** + * @throws CourierInvalidDataException 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 lists(): List = body.lists() + + /** + * Returns the raw JSON value of [lists]. + * + * Unlike [lists], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _lists(): JsonField> = body._lists() + + 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 [ListSubscribeParams]. + * + * The following fields are required: + * ```java + * .lists() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ListSubscribeParams]. */ + class Builder internal constructor() { + + private var userId: 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(listSubscribeParams: ListSubscribeParams) = apply { + userId = listSubscribeParams.userId + body = listSubscribeParams.body.toBuilder() + additionalHeaders = listSubscribeParams.additionalHeaders.toBuilder() + additionalQueryParams = listSubscribeParams.additionalQueryParams.toBuilder() + } + + fun userId(userId: String?) = apply { this.userId = userId } + + /** Alias for calling [Builder.userId] with `userId.orElse(null)`. */ + fun userId(userId: Optional) = userId(userId.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: + * - [lists] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + fun lists(lists: List) = apply { body.lists(lists) } + + /** + * Sets [Builder.lists] to an arbitrary JSON value. + * + * You should usually call [Builder.lists] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun lists(lists: JsonField>) = apply { body.lists(lists) } + + /** + * Adds a single [List] to [lists]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addList(list: List) = apply { body.addList(list) } + + 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 [ListSubscribeParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .lists() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ListSubscribeParams = + ListSubscribeParams( + userId, + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): Body = body + + fun _pathParam(index: Int): String = + when (index) { + 0 -> userId ?: "" + else -> "" + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + class Body + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val lists: JsonField>, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("lists") @ExcludeMissing lists: JsonField> = JsonMissing.of() + ) : this(lists, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 lists(): List = lists.getRequired("lists") + + /** + * Returns the raw JSON value of [lists]. + * + * Unlike [lists], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("lists") @ExcludeMissing fun _lists(): JsonField> = lists + + @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 + * .lists() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var lists: JsonField>? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + lists = body.lists.map { it.toMutableList() } + additionalProperties = body.additionalProperties.toMutableMap() + } + + fun lists(lists: List) = lists(JsonField.of(lists)) + + /** + * Sets [Builder.lists] to an arbitrary JSON value. + * + * You should usually call [Builder.lists] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun lists(lists: JsonField>) = apply { + this.lists = lists.map { it.toMutableList() } + } + + /** + * Adds a single [List] to [lists]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addList(list: List) = apply { + lists = + (lists ?: JsonField.of(mutableListOf())).also { + checkKnown("lists", it).add(list) + } + } + + 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 + * .lists() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("lists", lists).map { it.toImmutable() }, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + lists().forEach { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (lists.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + lists == other.lists && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(lists, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Body{lists=$lists, additionalProperties=$additionalProperties}" + } + + class List + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val listId: JsonField, + private val preferences: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("listId") @ExcludeMissing listId: JsonField = JsonMissing.of(), + @JsonProperty("preferences") + @ExcludeMissing + preferences: JsonField = JsonMissing.of(), + ) : this(listId, preferences, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 listId(): String = listId.getRequired("listId") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun preferences(): Optional = preferences.getOptional("preferences") + + /** + * Returns the raw JSON value of [listId]. + * + * Unlike [listId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("listId") @ExcludeMissing fun _listId(): JsonField = listId + + /** + * Returns the raw JSON value of [preferences]. + * + * Unlike [preferences], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("preferences") + @ExcludeMissing + fun _preferences(): JsonField = preferences + + @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 [List]. + * + * The following fields are required: + * ```java + * .listId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [List]. */ + class Builder internal constructor() { + + private var listId: JsonField? = null + private var preferences: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(list: List) = apply { + listId = list.listId + preferences = list.preferences + additionalProperties = list.additionalProperties.toMutableMap() + } + + fun listId(listId: String) = listId(JsonField.of(listId)) + + /** + * Sets [Builder.listId] to an arbitrary JSON value. + * + * You should usually call [Builder.listId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun listId(listId: JsonField) = apply { this.listId = listId } + + fun preferences(preferences: RecipientPreferences?) = + preferences(JsonField.ofNullable(preferences)) + + /** Alias for calling [Builder.preferences] with `preferences.orElse(null)`. */ + fun preferences(preferences: Optional) = + preferences(preferences.getOrNull()) + + /** + * Sets [Builder.preferences] to an arbitrary JSON value. + * + * You should usually call [Builder.preferences] with a well-typed + * [RecipientPreferences] value instead. This method is primarily for setting the field + * to an undocumented or not yet supported value. + */ + fun preferences(preferences: JsonField) = apply { + this.preferences = preferences + } + + 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 [List]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .listId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): List = + List( + checkRequired("listId", listId), + preferences, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): List = apply { + if (validated) { + return@apply + } + + listId() + preferences().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (listId.asKnown().isPresent) 1 else 0) + + (preferences.asKnown().getOrNull()?.validity() ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is List && + listId == other.listId && + preferences == other.preferences && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(listId, preferences, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "List{listId=$listId, preferences=$preferences, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ListSubscribeParams && + userId == other.userId && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(userId, body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "ListSubscribeParams{userId=$userId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/lists/ListSubscribeResponse.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/lists/ListSubscribeResponse.kt new file mode 100644 index 00000000..63337ea9 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/profiles/lists/ListSubscribeResponse.kt @@ -0,0 +1,291 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.profiles.lists + +import com.courier.api.core.Enum +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkRequired +import com.courier.api.errors.CourierInvalidDataException +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 kotlin.jvm.optionals.getOrNull + +class ListSubscribeResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val status: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of() + ) : this(status, mutableMapOf()) + + /** + * @throws CourierInvalidDataException 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 status(): Status = status.getRequired("status") + + /** + * 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 [ListSubscribeResponse]. + * + * The following fields are required: + * ```java + * .status() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ListSubscribeResponse]. */ + class Builder internal constructor() { + + private var status: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(listSubscribeResponse: ListSubscribeResponse) = apply { + status = listSubscribeResponse.status + additionalProperties = listSubscribeResponse.additionalProperties.toMutableMap() + } + + 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 } + + 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 [ListSubscribeResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .status() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ListSubscribeResponse = + ListSubscribeResponse( + checkRequired("status", status), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): ListSubscribeResponse = apply { + if (validated) { + return@apply + } + + status().validate() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = (status.asKnown().getOrNull()?.validity() ?: 0) + + 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 SUCCESS = of("SUCCESS") + + @JvmStatic fun of(value: String) = Status(JsonField.of(value)) + } + + /** An enum containing [Status]'s known values. */ + enum class Known { + SUCCESS + } + + /** + * 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 { + SUCCESS, + /** 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) { + SUCCESS -> Value.SUCCESS + 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 CourierInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + SUCCESS -> Known.SUCCESS + else -> throw CourierInvalidDataException("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 CourierInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { CourierInvalidDataException("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: CourierInvalidDataException) { + 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 ListSubscribeResponse && + status == other.status && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(status, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ListSubscribeResponse{status=$status, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/requests/RequestArchiveParams.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/requests/RequestArchiveParams.kt new file mode 100644 index 00000000..7a8d7632 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/requests/RequestArchiveParams.kt @@ -0,0 +1,229 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.requests + +import com.courier.api.core.JsonValue +import com.courier.api.core.Params +import com.courier.api.core.http.Headers +import com.courier.api.core.http.QueryParams +import com.courier.api.core.toImmutable +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Archive message */ +class RequestArchiveParams +private constructor( + private val requestId: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, + private val additionalBodyProperties: Map, +) : Params { + + fun requestId(): Optional = Optional.ofNullable(requestId) + + /** 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(): RequestArchiveParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [RequestArchiveParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [RequestArchiveParams]. */ + class Builder internal constructor() { + + private var requestId: 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(requestArchiveParams: RequestArchiveParams) = apply { + requestId = requestArchiveParams.requestId + additionalHeaders = requestArchiveParams.additionalHeaders.toBuilder() + additionalQueryParams = requestArchiveParams.additionalQueryParams.toBuilder() + additionalBodyProperties = requestArchiveParams.additionalBodyProperties.toMutableMap() + } + + fun requestId(requestId: String?) = apply { this.requestId = requestId } + + /** Alias for calling [Builder.requestId] with `requestId.orElse(null)`. */ + fun requestId(requestId: Optional) = requestId(requestId.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 [RequestArchiveParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): RequestArchiveParams = + RequestArchiveParams( + requestId, + additionalHeaders.build(), + additionalQueryParams.build(), + additionalBodyProperties.toImmutable(), + ) + } + + fun _body(): Optional> = + Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) + + fun _pathParam(index: Int): String = + when (index) { + 0 -> requestId ?: "" + 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 RequestArchiveParams && + requestId == other.requestId && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams && + additionalBodyProperties == other.additionalBodyProperties + } + + override fun hashCode(): Int = + Objects.hash(requestId, additionalHeaders, additionalQueryParams, additionalBodyProperties) + + override fun toString() = + "RequestArchiveParams{requestId=$requestId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/send/Alignment.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/send/Alignment.kt new file mode 100644 index 00000000..c1dfd2ba --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/send/Alignment.kt @@ -0,0 +1,142 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.send + +import com.courier.api.core.Enum +import com.courier.api.core.JsonField +import com.courier.api.errors.CourierInvalidDataException +import com.fasterxml.jackson.annotation.JsonCreator + +class Alignment @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 CENTER = of("center") + + @JvmField val LEFT = of("left") + + @JvmField val RIGHT = of("right") + + @JvmField val FULL = of("full") + + @JvmStatic fun of(value: String) = Alignment(JsonField.of(value)) + } + + /** An enum containing [Alignment]'s known values. */ + enum class Known { + CENTER, + LEFT, + RIGHT, + FULL, + } + + /** + * An enum containing [Alignment]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Alignment] 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 { + CENTER, + LEFT, + RIGHT, + FULL, + /** An enum member indicating that [Alignment] 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) { + CENTER -> Value.CENTER + LEFT -> Value.LEFT + RIGHT -> Value.RIGHT + FULL -> Value.FULL + 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 CourierInvalidDataException if this class instance's value is a not a known member. + */ + fun known(): Known = + when (this) { + CENTER -> Known.CENTER + LEFT -> Known.LEFT + RIGHT -> Known.RIGHT + FULL -> Known.FULL + else -> throw CourierInvalidDataException("Unknown Alignment: $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 CourierInvalidDataException if this class instance's value does not have the expected + * primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { CourierInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + fun validate(): Alignment = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Alignment && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/send/Content.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/send/Content.kt new file mode 100644 index 00000000..935207df --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/send/Content.kt @@ -0,0 +1,412 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.send + +import com.courier.api.core.BaseDeserializer +import com.courier.api.core.BaseSerializer +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.allMaxBy +import com.courier.api.core.checkRequired +import com.courier.api.core.getOrThrow +import com.courier.api.errors.CourierInvalidDataException +import com.courier.api.models.tenants.templates.ElementalContent +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 com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.ObjectCodec +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.module.kotlin.jacksonTypeRef +import java.util.Collections +import java.util.Objects +import java.util.Optional + +/** Syntactic sugar to provide a fast shorthand for Courier Elemental Blocks. */ +@JsonDeserialize(using = Content.Deserializer::class) +@JsonSerialize(using = Content.Serializer::class) +class Content +private constructor( + private val elementalContentSugar: ElementalContentSugar? = null, + private val elemental: ElementalContent? = null, + private val _json: JsonValue? = null, +) { + + /** Syntactic sugar to provide a fast shorthand for Courier Elemental Blocks. */ + fun elementalContentSugar(): Optional = + Optional.ofNullable(elementalContentSugar) + + fun elemental(): Optional = Optional.ofNullable(elemental) + + fun isElementalContentSugar(): Boolean = elementalContentSugar != null + + fun isElemental(): Boolean = elemental != null + + /** Syntactic sugar to provide a fast shorthand for Courier Elemental Blocks. */ + fun asElementalContentSugar(): ElementalContentSugar = + elementalContentSugar.getOrThrow("elementalContentSugar") + + fun asElemental(): ElementalContent = elemental.getOrThrow("elemental") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T = + when { + elementalContentSugar != null -> + visitor.visitElementalContentSugar(elementalContentSugar) + elemental != null -> visitor.visitElemental(elemental) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + fun validate(): Content = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitElementalContentSugar( + elementalContentSugar: ElementalContentSugar + ) { + elementalContentSugar.validate() + } + + override fun visitElemental(elemental: ElementalContent) { + elemental.validate() + } + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + accept( + object : Visitor { + override fun visitElementalContentSugar( + elementalContentSugar: ElementalContentSugar + ) = elementalContentSugar.validity() + + override fun visitElemental(elemental: ElementalContent) = elemental.validity() + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Content && + elementalContentSugar == other.elementalContentSugar && + elemental == other.elemental + } + + override fun hashCode(): Int = Objects.hash(elementalContentSugar, elemental) + + override fun toString(): String = + when { + elementalContentSugar != null -> "Content{elementalContentSugar=$elementalContentSugar}" + elemental != null -> "Content{elemental=$elemental}" + _json != null -> "Content{_unknown=$_json}" + else -> throw IllegalStateException("Invalid Content") + } + + companion object { + + /** Syntactic sugar to provide a fast shorthand for Courier Elemental Blocks. */ + @JvmStatic + fun ofElementalContentSugar(elementalContentSugar: ElementalContentSugar) = + Content(elementalContentSugar = elementalContentSugar) + + @JvmStatic fun ofElemental(elemental: ElementalContent) = Content(elemental = elemental) + } + + /** An interface that defines how to map each variant of [Content] to a value of type [T]. */ + interface Visitor { + + /** Syntactic sugar to provide a fast shorthand for Courier Elemental Blocks. */ + fun visitElementalContentSugar(elementalContentSugar: ElementalContentSugar): T + + fun visitElemental(elemental: ElementalContent): T + + /** + * Maps an unknown variant of [Content] to a value of type [T]. + * + * An instance of [Content] can contain an unknown variant if it was deserialized from data + * that doesn't match any known variant. For example, if the SDK is on an older version than + * the API, then the API may respond with new variants that the SDK is unaware of. + * + * @throws CourierInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw CourierInvalidDataException("Unknown Content: $json") + } + } + + internal class Deserializer : BaseDeserializer(Content::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): Content { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef())?.let { + Content(elementalContentSugar = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + Content(elemental = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible with all + // the possible variants (e.g. deserializing from boolean). + 0 -> Content(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the first + // completely valid match, or simply the first match if none are completely valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : BaseSerializer(Content::class) { + + override fun serialize( + value: Content, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.elementalContentSugar != null -> + generator.writeObject(value.elementalContentSugar) + value.elemental != null -> generator.writeObject(value.elemental) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid Content") + } + } + } + + /** Syntactic sugar to provide a fast shorthand for Courier Elemental Blocks. */ + class ElementalContentSugar + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val body: JsonField, + private val title: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("body") @ExcludeMissing body: JsonField = JsonMissing.of(), + @JsonProperty("title") @ExcludeMissing title: JsonField = JsonMissing.of(), + ) : this(body, title, mutableMapOf()) + + /** + * The text content displayed in the notification. + * + * @throws CourierInvalidDataException 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 body(): String = body.getRequired("body") + + /** + * Title/subject displayed by supported channels. + * + * @throws CourierInvalidDataException 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 title(): String = title.getRequired("title") + + /** + * Returns the raw JSON value of [body]. + * + * Unlike [body], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("body") @ExcludeMissing fun _body(): JsonField = body + + /** + * Returns the raw JSON value of [title]. + * + * Unlike [title], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("title") @ExcludeMissing fun _title(): JsonField = title + + @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 [ElementalContentSugar]. + * + * The following fields are required: + * ```java + * .body() + * .title() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ElementalContentSugar]. */ + class Builder internal constructor() { + + private var body: JsonField? = null + private var title: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(elementalContentSugar: ElementalContentSugar) = apply { + body = elementalContentSugar.body + title = elementalContentSugar.title + additionalProperties = elementalContentSugar.additionalProperties.toMutableMap() + } + + /** The text content displayed in the notification. */ + fun body(body: String) = body(JsonField.of(body)) + + /** + * Sets [Builder.body] to an arbitrary JSON value. + * + * You should usually call [Builder.body] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun body(body: JsonField) = apply { this.body = body } + + /** Title/subject displayed by supported channels. */ + fun title(title: String) = title(JsonField.of(title)) + + /** + * Sets [Builder.title] to an arbitrary JSON value. + * + * You should usually call [Builder.title] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun title(title: JsonField) = apply { this.title = title } + + 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 [ElementalContentSugar]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .body() + * .title() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ElementalContentSugar = + ElementalContentSugar( + checkRequired("body", body), + checkRequired("title", title), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): ElementalContentSugar = apply { + if (validated) { + return@apply + } + + body() + title() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 (body.asKnown().isPresent) 1 else 0) + (if (title.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ElementalContentSugar && + body == other.body && + title == other.title && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(body, title, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ElementalContentSugar{body=$body, title=$title, additionalProperties=$additionalProperties}" + } +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/send/ElementalBaseNode.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/send/ElementalBaseNode.kt new file mode 100644 index 00000000..6770bb1b --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/send/ElementalBaseNode.kt @@ -0,0 +1,285 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.send + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkKnown +import com.courier.api.core.toImmutable +import com.courier.api.errors.CourierInvalidDataException +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 ElementalBaseNode +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val channels: JsonField>, + private val if_: JsonField, + private val loop: JsonField, + private val ref: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("channels") + @ExcludeMissing + channels: JsonField> = JsonMissing.of(), + @JsonProperty("if") @ExcludeMissing if_: JsonField = JsonMissing.of(), + @JsonProperty("loop") @ExcludeMissing loop: JsonField = JsonMissing.of(), + @JsonProperty("ref") @ExcludeMissing ref: JsonField = JsonMissing.of(), + ) : this(channels, if_, loop, ref, mutableMapOf()) + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun channels(): Optional> = channels.getOptional("channels") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun if_(): Optional = if_.getOptional("if") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun loop(): Optional = loop.getOptional("loop") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun ref(): Optional = ref.getOptional("ref") + + /** + * Returns the raw JSON value of [channels]. + * + * Unlike [channels], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("channels") @ExcludeMissing fun _channels(): JsonField> = channels + + /** + * Returns the raw JSON value of [if_]. + * + * Unlike [if_], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("if") @ExcludeMissing fun _if_(): JsonField = if_ + + /** + * Returns the raw JSON value of [loop]. + * + * Unlike [loop], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("loop") @ExcludeMissing fun _loop(): JsonField = loop + + /** + * Returns the raw JSON value of [ref]. + * + * Unlike [ref], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("ref") @ExcludeMissing fun _ref(): JsonField = ref + + @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 [ElementalBaseNode]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ElementalBaseNode]. */ + class Builder internal constructor() { + + private var channels: JsonField>? = null + private var if_: JsonField = JsonMissing.of() + private var loop: JsonField = JsonMissing.of() + private var ref: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(elementalBaseNode: ElementalBaseNode) = apply { + channels = elementalBaseNode.channels.map { it.toMutableList() } + if_ = elementalBaseNode.if_ + loop = elementalBaseNode.loop + ref = elementalBaseNode.ref + additionalProperties = elementalBaseNode.additionalProperties.toMutableMap() + } + + fun channels(channels: List?) = channels(JsonField.ofNullable(channels)) + + /** Alias for calling [Builder.channels] with `channels.orElse(null)`. */ + fun channels(channels: Optional>) = channels(channels.getOrNull()) + + /** + * Sets [Builder.channels] to an arbitrary JSON value. + * + * You should usually call [Builder.channels] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun channels(channels: JsonField>) = apply { + this.channels = channels.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [channels]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addChannel(channel: String) = apply { + channels = + (channels ?: JsonField.of(mutableListOf())).also { + checkKnown("channels", it).add(channel) + } + } + + fun if_(if_: String?) = if_(JsonField.ofNullable(if_)) + + /** Alias for calling [Builder.if_] with `if_.orElse(null)`. */ + fun if_(if_: Optional) = if_(if_.getOrNull()) + + /** + * Sets [Builder.if_] to an arbitrary JSON value. + * + * You should usually call [Builder.if_] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun if_(if_: JsonField) = apply { this.if_ = if_ } + + fun loop(loop: String?) = loop(JsonField.ofNullable(loop)) + + /** Alias for calling [Builder.loop] with `loop.orElse(null)`. */ + fun loop(loop: Optional) = loop(loop.getOrNull()) + + /** + * Sets [Builder.loop] to an arbitrary JSON value. + * + * You should usually call [Builder.loop] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun loop(loop: JsonField) = apply { this.loop = loop } + + fun ref(ref: String?) = ref(JsonField.ofNullable(ref)) + + /** Alias for calling [Builder.ref] with `ref.orElse(null)`. */ + fun ref(ref: Optional) = ref(ref.getOrNull()) + + /** + * Sets [Builder.ref] to an arbitrary JSON value. + * + * You should usually call [Builder.ref] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun ref(ref: JsonField) = apply { this.ref = ref } + + 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 [ElementalBaseNode]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): ElementalBaseNode = + ElementalBaseNode( + (channels ?: JsonMissing.of()).map { it.toImmutable() }, + if_, + loop, + ref, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): ElementalBaseNode = apply { + if (validated) { + return@apply + } + + channels() + if_() + loop() + ref() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (channels.asKnown().getOrNull()?.size ?: 0) + + (if (if_.asKnown().isPresent) 1 else 0) + + (if (loop.asKnown().isPresent) 1 else 0) + + (if (ref.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ElementalBaseNode && + channels == other.channels && + if_ == other.if_ && + loop == other.loop && + ref == other.ref && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(channels, if_, loop, ref, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ElementalBaseNode{channels=$channels, if_=$if_, loop=$loop, ref=$ref, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/send/ElementalChannelNode.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/send/ElementalChannelNode.kt new file mode 100644 index 00000000..bb38b567 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/send/ElementalChannelNode.kt @@ -0,0 +1,494 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.send + +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.checkKnown +import com.courier.api.core.checkRequired +import com.courier.api.core.toImmutable +import com.courier.api.errors.CourierInvalidDataException +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 + +/** + * The channel element allows a notification to be customized based on which channel it is sent + * through. For example, you may want to display a detailed message when the notification is sent + * through email, and a more concise message in a push notification. Channel elements are only valid + * as top-level elements; you cannot nest channel elements. If there is a channel element specified + * at the top-level of the document, all sibling elements must be channel elements. Note: As an + * alternative, most elements support a `channel` property. Which allows you to selectively display + * an individual element on a per channel basis. See the + * [control flow docs](https://www.courier.com/docs/platform/content/elemental/control-flow/) for + * more details. + */ +class ElementalChannelNode +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val channels: JsonField>, + private val if_: JsonField, + private val loop: JsonField, + private val ref: JsonField, + private val channel: JsonField, + private val raw: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("channels") + @ExcludeMissing + channels: JsonField> = JsonMissing.of(), + @JsonProperty("if") @ExcludeMissing if_: JsonField = JsonMissing.of(), + @JsonProperty("loop") @ExcludeMissing loop: JsonField = JsonMissing.of(), + @JsonProperty("ref") @ExcludeMissing ref: JsonField = JsonMissing.of(), + @JsonProperty("channel") @ExcludeMissing channel: JsonField = JsonMissing.of(), + @JsonProperty("raw") @ExcludeMissing raw: JsonField = JsonMissing.of(), + ) : this(channels, if_, loop, ref, channel, raw, mutableMapOf()) + + fun toElementalBaseNode(): ElementalBaseNode = + ElementalBaseNode.builder().channels(channels).if_(if_).loop(loop).ref(ref).build() + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun channels(): Optional> = channels.getOptional("channels") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun if_(): Optional = if_.getOptional("if") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun loop(): Optional = loop.getOptional("loop") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun ref(): Optional = ref.getOptional("ref") + + /** + * The channel the contents of this element should be applied to. Can be `email`, `push`, + * `direct_message`, `sms` or a provider such as slack + * + * @throws CourierInvalidDataException 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 channel(): String = channel.getRequired("channel") + + /** + * Raw data to apply to the channel. If `elements` has not been specified, `raw` is `required`. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun raw(): Optional = raw.getOptional("raw") + + /** + * Returns the raw JSON value of [channels]. + * + * Unlike [channels], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("channels") @ExcludeMissing fun _channels(): JsonField> = channels + + /** + * Returns the raw JSON value of [if_]. + * + * Unlike [if_], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("if") @ExcludeMissing fun _if_(): JsonField = if_ + + /** + * Returns the raw JSON value of [loop]. + * + * Unlike [loop], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("loop") @ExcludeMissing fun _loop(): JsonField = loop + + /** + * Returns the raw JSON value of [ref]. + * + * Unlike [ref], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("ref") @ExcludeMissing fun _ref(): JsonField = ref + + /** + * Returns the raw JSON value of [channel]. + * + * Unlike [channel], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("channel") @ExcludeMissing fun _channel(): JsonField = channel + + /** + * Returns the raw JSON value of [raw]. + * + * Unlike [raw], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("raw") @ExcludeMissing fun _raw(): JsonField = raw + + @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 [ElementalChannelNode]. + * + * The following fields are required: + * ```java + * .channel() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ElementalChannelNode]. */ + class Builder internal constructor() { + + private var channels: JsonField>? = null + private var if_: JsonField = JsonMissing.of() + private var loop: JsonField = JsonMissing.of() + private var ref: JsonField = JsonMissing.of() + private var channel: JsonField? = null + private var raw: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(elementalChannelNode: ElementalChannelNode) = apply { + channels = elementalChannelNode.channels.map { it.toMutableList() } + if_ = elementalChannelNode.if_ + loop = elementalChannelNode.loop + ref = elementalChannelNode.ref + channel = elementalChannelNode.channel + raw = elementalChannelNode.raw + additionalProperties = elementalChannelNode.additionalProperties.toMutableMap() + } + + fun channels(channels: List?) = channels(JsonField.ofNullable(channels)) + + /** Alias for calling [Builder.channels] with `channels.orElse(null)`. */ + fun channels(channels: Optional>) = channels(channels.getOrNull()) + + /** + * Sets [Builder.channels] to an arbitrary JSON value. + * + * You should usually call [Builder.channels] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun channels(channels: JsonField>) = apply { + this.channels = channels.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [channels]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addChannel(channel: String) = apply { + channels = + (channels ?: JsonField.of(mutableListOf())).also { + checkKnown("channels", it).add(channel) + } + } + + fun if_(if_: String?) = if_(JsonField.ofNullable(if_)) + + /** Alias for calling [Builder.if_] with `if_.orElse(null)`. */ + fun if_(if_: Optional) = if_(if_.getOrNull()) + + /** + * Sets [Builder.if_] to an arbitrary JSON value. + * + * You should usually call [Builder.if_] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun if_(if_: JsonField) = apply { this.if_ = if_ } + + fun loop(loop: String?) = loop(JsonField.ofNullable(loop)) + + /** Alias for calling [Builder.loop] with `loop.orElse(null)`. */ + fun loop(loop: Optional) = loop(loop.getOrNull()) + + /** + * Sets [Builder.loop] to an arbitrary JSON value. + * + * You should usually call [Builder.loop] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun loop(loop: JsonField) = apply { this.loop = loop } + + fun ref(ref: String?) = ref(JsonField.ofNullable(ref)) + + /** Alias for calling [Builder.ref] with `ref.orElse(null)`. */ + fun ref(ref: Optional) = ref(ref.getOrNull()) + + /** + * Sets [Builder.ref] to an arbitrary JSON value. + * + * You should usually call [Builder.ref] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun ref(ref: JsonField) = apply { this.ref = ref } + + /** + * The channel the contents of this element should be applied to. Can be `email`, `push`, + * `direct_message`, `sms` or a provider such as slack + */ + fun channel(channel: String) = channel(JsonField.of(channel)) + + /** + * Sets [Builder.channel] to an arbitrary JSON value. + * + * You should usually call [Builder.channel] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun channel(channel: JsonField) = apply { this.channel = channel } + + /** + * Raw data to apply to the channel. If `elements` has not been specified, `raw` is + * `required`. + */ + fun raw(raw: Raw?) = raw(JsonField.ofNullable(raw)) + + /** Alias for calling [Builder.raw] with `raw.orElse(null)`. */ + fun raw(raw: Optional) = raw(raw.getOrNull()) + + /** + * Sets [Builder.raw] to an arbitrary JSON value. + * + * You should usually call [Builder.raw] with a well-typed [Raw] value instead. This method + * is primarily for setting the field to an undocumented or not yet supported value. + */ + fun raw(raw: JsonField) = apply { this.raw = raw } + + 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 [ElementalChannelNode]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .channel() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ElementalChannelNode = + ElementalChannelNode( + (channels ?: JsonMissing.of()).map { it.toImmutable() }, + if_, + loop, + ref, + checkRequired("channel", channel), + raw, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): ElementalChannelNode = apply { + if (validated) { + return@apply + } + + channels() + if_() + loop() + ref() + channel() + raw().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (channels.asKnown().getOrNull()?.size ?: 0) + + (if (if_.asKnown().isPresent) 1 else 0) + + (if (loop.asKnown().isPresent) 1 else 0) + + (if (ref.asKnown().isPresent) 1 else 0) + + (if (channel.asKnown().isPresent) 1 else 0) + + (raw.asKnown().getOrNull()?.validity() ?: 0) + + /** + * Raw data to apply to the channel. If `elements` has not been specified, `raw` is `required`. + */ + class Raw + @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 [Raw]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Raw]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(raw: Raw) = apply { + additionalProperties = raw.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 [Raw]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Raw = Raw(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): Raw = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 Raw && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Raw{additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ElementalChannelNode && + channels == other.channels && + if_ == other.if_ && + loop == other.loop && + ref == other.ref && + channel == other.channel && + raw == other.raw && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(channels, if_, loop, ref, channel, raw, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ElementalChannelNode{channels=$channels, if_=$if_, loop=$loop, ref=$ref, channel=$channel, raw=$raw, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/api/models/send/ElementalNode.kt b/courier-java-core/src/main/kotlin/com/courier/api/models/send/ElementalNode.kt new file mode 100644 index 00000000..69912245 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/api/models/send/ElementalNode.kt @@ -0,0 +1,3881 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.api.models.send + +import com.courier.api.core.BaseDeserializer +import com.courier.api.core.BaseSerializer +import com.courier.api.core.Enum +import com.courier.api.core.ExcludeMissing +import com.courier.api.core.JsonField +import com.courier.api.core.JsonMissing +import com.courier.api.core.JsonValue +import com.courier.api.core.allMaxBy +import com.courier.api.core.checkKnown +import com.courier.api.core.checkRequired +import com.courier.api.core.getOrThrow +import com.courier.api.core.toImmutable +import com.courier.api.errors.CourierInvalidDataException +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 com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.ObjectCodec +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.module.kotlin.jacksonTypeRef +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * The channel element allows a notification to be customized based on which channel it is sent + * through. For example, you may want to display a detailed message when the notification is sent + * through email, and a more concise message in a push notification. Channel elements are only valid + * as top-level elements; you cannot nest channel elements. If there is a channel element specified + * at the top-level of the document, all sibling elements must be channel elements. Note: As an + * alternative, most elements support a `channel` property. Which allows you to selectively display + * an individual element on a per channel basis. See the + * [control flow docs](https://www.courier.com/docs/platform/content/elemental/control-flow/) for + * more details. + */ +@JsonDeserialize(using = ElementalNode.Deserializer::class) +@JsonSerialize(using = ElementalNode.Serializer::class) +class ElementalNode +private constructor( + private val unionMember0: UnionMember0? = null, + private val unionMember1: UnionMember1? = null, + private val unionMember2: UnionMember2? = null, + private val unionMember3: UnionMember3? = null, + private val unionMember4: UnionMember4? = null, + private val unionMember5: UnionMember5? = null, + private val unionMember6: UnionMember6? = null, + private val _json: JsonValue? = null, +) { + + fun unionMember0(): Optional = Optional.ofNullable(unionMember0) + + fun unionMember1(): Optional = Optional.ofNullable(unionMember1) + + /** + * The channel element allows a notification to be customized based on which channel it is sent + * through. For example, you may want to display a detailed message when the notification is + * sent through email, and a more concise message in a push notification. Channel elements are + * only valid as top-level elements; you cannot nest channel elements. If there is a channel + * element specified at the top-level of the document, all sibling elements must be channel + * elements. Note: As an alternative, most elements support a `channel` property. Which allows + * you to selectively display an individual element on a per channel basis. See the + * [control flow docs](https://www.courier.com/docs/platform/content/elemental/control-flow/) + * for more details. + */ + fun unionMember2(): Optional = Optional.ofNullable(unionMember2) + + fun unionMember3(): Optional = Optional.ofNullable(unionMember3) + + fun unionMember4(): Optional = Optional.ofNullable(unionMember4) + + fun unionMember5(): Optional = Optional.ofNullable(unionMember5) + + fun unionMember6(): Optional = Optional.ofNullable(unionMember6) + + fun isUnionMember0(): Boolean = unionMember0 != null + + fun isUnionMember1(): Boolean = unionMember1 != null + + fun isUnionMember2(): Boolean = unionMember2 != null + + fun isUnionMember3(): Boolean = unionMember3 != null + + fun isUnionMember4(): Boolean = unionMember4 != null + + fun isUnionMember5(): Boolean = unionMember5 != null + + fun isUnionMember6(): Boolean = unionMember6 != null + + fun asUnionMember0(): UnionMember0 = unionMember0.getOrThrow("unionMember0") + + fun asUnionMember1(): UnionMember1 = unionMember1.getOrThrow("unionMember1") + + /** + * The channel element allows a notification to be customized based on which channel it is sent + * through. For example, you may want to display a detailed message when the notification is + * sent through email, and a more concise message in a push notification. Channel elements are + * only valid as top-level elements; you cannot nest channel elements. If there is a channel + * element specified at the top-level of the document, all sibling elements must be channel + * elements. Note: As an alternative, most elements support a `channel` property. Which allows + * you to selectively display an individual element on a per channel basis. See the + * [control flow docs](https://www.courier.com/docs/platform/content/elemental/control-flow/) + * for more details. + */ + fun asUnionMember2(): UnionMember2 = unionMember2.getOrThrow("unionMember2") + + fun asUnionMember3(): UnionMember3 = unionMember3.getOrThrow("unionMember3") + + fun asUnionMember4(): UnionMember4 = unionMember4.getOrThrow("unionMember4") + + fun asUnionMember5(): UnionMember5 = unionMember5.getOrThrow("unionMember5") + + fun asUnionMember6(): UnionMember6 = unionMember6.getOrThrow("unionMember6") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T = + when { + unionMember0 != null -> visitor.visitUnionMember0(unionMember0) + unionMember1 != null -> visitor.visitUnionMember1(unionMember1) + unionMember2 != null -> visitor.visitUnionMember2(unionMember2) + unionMember3 != null -> visitor.visitUnionMember3(unionMember3) + unionMember4 != null -> visitor.visitUnionMember4(unionMember4) + unionMember5 != null -> visitor.visitUnionMember5(unionMember5) + unionMember6 != null -> visitor.visitUnionMember6(unionMember6) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + fun validate(): ElementalNode = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitUnionMember0(unionMember0: UnionMember0) { + unionMember0.validate() + } + + override fun visitUnionMember1(unionMember1: UnionMember1) { + unionMember1.validate() + } + + override fun visitUnionMember2(unionMember2: UnionMember2) { + unionMember2.validate() + } + + override fun visitUnionMember3(unionMember3: UnionMember3) { + unionMember3.validate() + } + + override fun visitUnionMember4(unionMember4: UnionMember4) { + unionMember4.validate() + } + + override fun visitUnionMember5(unionMember5: UnionMember5) { + unionMember5.validate() + } + + override fun visitUnionMember6(unionMember6: UnionMember6) { + unionMember6.validate() + } + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + accept( + object : Visitor { + override fun visitUnionMember0(unionMember0: UnionMember0) = unionMember0.validity() + + override fun visitUnionMember1(unionMember1: UnionMember1) = unionMember1.validity() + + override fun visitUnionMember2(unionMember2: UnionMember2) = unionMember2.validity() + + override fun visitUnionMember3(unionMember3: UnionMember3) = unionMember3.validity() + + override fun visitUnionMember4(unionMember4: UnionMember4) = unionMember4.validity() + + override fun visitUnionMember5(unionMember5: UnionMember5) = unionMember5.validity() + + override fun visitUnionMember6(unionMember6: UnionMember6) = unionMember6.validity() + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ElementalNode && + unionMember0 == other.unionMember0 && + unionMember1 == other.unionMember1 && + unionMember2 == other.unionMember2 && + unionMember3 == other.unionMember3 && + unionMember4 == other.unionMember4 && + unionMember5 == other.unionMember5 && + unionMember6 == other.unionMember6 + } + + override fun hashCode(): Int = + Objects.hash( + unionMember0, + unionMember1, + unionMember2, + unionMember3, + unionMember4, + unionMember5, + unionMember6, + ) + + override fun toString(): String = + when { + unionMember0 != null -> "ElementalNode{unionMember0=$unionMember0}" + unionMember1 != null -> "ElementalNode{unionMember1=$unionMember1}" + unionMember2 != null -> "ElementalNode{unionMember2=$unionMember2}" + unionMember3 != null -> "ElementalNode{unionMember3=$unionMember3}" + unionMember4 != null -> "ElementalNode{unionMember4=$unionMember4}" + unionMember5 != null -> "ElementalNode{unionMember5=$unionMember5}" + unionMember6 != null -> "ElementalNode{unionMember6=$unionMember6}" + _json != null -> "ElementalNode{_unknown=$_json}" + else -> throw IllegalStateException("Invalid ElementalNode") + } + + companion object { + + @JvmStatic + fun ofUnionMember0(unionMember0: UnionMember0) = ElementalNode(unionMember0 = unionMember0) + + @JvmStatic + fun ofUnionMember1(unionMember1: UnionMember1) = ElementalNode(unionMember1 = unionMember1) + + /** + * The channel element allows a notification to be customized based on which channel it is + * sent through. For example, you may want to display a detailed message when the + * notification is sent through email, and a more concise message in a push notification. + * Channel elements are only valid as top-level elements; you cannot nest channel elements. + * If there is a channel element specified at the top-level of the document, all sibling + * elements must be channel elements. Note: As an alternative, most elements support a + * `channel` property. Which allows you to selectively display an individual element on a + * per channel basis. See the + * [control flow docs](https://www.courier.com/docs/platform/content/elemental/control-flow/) + * for more details. + */ + @JvmStatic + fun ofUnionMember2(unionMember2: UnionMember2) = ElementalNode(unionMember2 = unionMember2) + + @JvmStatic + fun ofUnionMember3(unionMember3: UnionMember3) = ElementalNode(unionMember3 = unionMember3) + + @JvmStatic + fun ofUnionMember4(unionMember4: UnionMember4) = ElementalNode(unionMember4 = unionMember4) + + @JvmStatic + fun ofUnionMember5(unionMember5: UnionMember5) = ElementalNode(unionMember5 = unionMember5) + + @JvmStatic + fun ofUnionMember6(unionMember6: UnionMember6) = ElementalNode(unionMember6 = unionMember6) + } + + /** + * An interface that defines how to map each variant of [ElementalNode] to a value of type [T]. + */ + interface Visitor { + + fun visitUnionMember0(unionMember0: UnionMember0): T + + fun visitUnionMember1(unionMember1: UnionMember1): T + + /** + * The channel element allows a notification to be customized based on which channel it is + * sent through. For example, you may want to display a detailed message when the + * notification is sent through email, and a more concise message in a push notification. + * Channel elements are only valid as top-level elements; you cannot nest channel elements. + * If there is a channel element specified at the top-level of the document, all sibling + * elements must be channel elements. Note: As an alternative, most elements support a + * `channel` property. Which allows you to selectively display an individual element on a + * per channel basis. See the + * [control flow docs](https://www.courier.com/docs/platform/content/elemental/control-flow/) + * for more details. + */ + fun visitUnionMember2(unionMember2: UnionMember2): T + + fun visitUnionMember3(unionMember3: UnionMember3): T + + fun visitUnionMember4(unionMember4: UnionMember4): T + + fun visitUnionMember5(unionMember5: UnionMember5): T + + fun visitUnionMember6(unionMember6: UnionMember6): T + + /** + * Maps an unknown variant of [ElementalNode] to a value of type [T]. + * + * An instance of [ElementalNode] can contain an unknown variant if it was deserialized from + * data that doesn't match any known variant. For example, if the SDK is on an older version + * than the API, then the API may respond with new variants that the SDK is unaware of. + * + * @throws CourierInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw CourierInvalidDataException("Unknown ElementalNode: $json") + } + } + + internal class Deserializer : BaseDeserializer(ElementalNode::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): ElementalNode { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef())?.let { + ElementalNode(unionMember0 = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + ElementalNode(unionMember1 = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + ElementalNode(unionMember2 = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + ElementalNode(unionMember3 = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + ElementalNode(unionMember4 = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + ElementalNode(unionMember5 = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + ElementalNode(unionMember6 = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible with all + // the possible variants (e.g. deserializing from boolean). + 0 -> ElementalNode(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the first + // completely valid match, or simply the first match if none are completely valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : BaseSerializer(ElementalNode::class) { + + override fun serialize( + value: ElementalNode, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.unionMember0 != null -> generator.writeObject(value.unionMember0) + value.unionMember1 != null -> generator.writeObject(value.unionMember1) + value.unionMember2 != null -> generator.writeObject(value.unionMember2) + value.unionMember3 != null -> generator.writeObject(value.unionMember3) + value.unionMember4 != null -> generator.writeObject(value.unionMember4) + value.unionMember5 != null -> generator.writeObject(value.unionMember5) + value.unionMember6 != null -> generator.writeObject(value.unionMember6) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid ElementalNode") + } + } + } + + class UnionMember0 + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val channels: JsonField>, + private val if_: JsonField, + private val loop: JsonField, + private val ref: JsonField, + private val type: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("channels") + @ExcludeMissing + channels: JsonField> = JsonMissing.of(), + @JsonProperty("if") @ExcludeMissing if_: JsonField = JsonMissing.of(), + @JsonProperty("loop") @ExcludeMissing loop: JsonField = JsonMissing.of(), + @JsonProperty("ref") @ExcludeMissing ref: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), + ) : this(channels, if_, loop, ref, type, mutableMapOf()) + + fun toElementalBaseNode(): ElementalBaseNode = + ElementalBaseNode.builder().channels(channels).if_(if_).loop(loop).ref(ref).build() + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun channels(): Optional> = channels.getOptional("channels") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun if_(): Optional = if_.getOptional("if") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun loop(): Optional = loop.getOptional("loop") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun ref(): Optional = ref.getOptional("ref") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun type(): Optional = type.getOptional("type") + + /** + * Returns the raw JSON value of [channels]. + * + * Unlike [channels], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("channels") + @ExcludeMissing + fun _channels(): JsonField> = channels + + /** + * Returns the raw JSON value of [if_]. + * + * Unlike [if_], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("if") @ExcludeMissing fun _if_(): JsonField = if_ + + /** + * Returns the raw JSON value of [loop]. + * + * Unlike [loop], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("loop") @ExcludeMissing fun _loop(): JsonField = loop + + /** + * Returns the raw JSON value of [ref]. + * + * Unlike [ref], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("ref") @ExcludeMissing fun _ref(): JsonField = ref + + /** + * 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 + + @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 [UnionMember0]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [UnionMember0]. */ + class Builder internal constructor() { + + private var channels: JsonField>? = null + private var if_: JsonField = JsonMissing.of() + private var loop: JsonField = JsonMissing.of() + private var ref: JsonField = JsonMissing.of() + private var type: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(unionMember0: UnionMember0) = apply { + channels = unionMember0.channels.map { it.toMutableList() } + if_ = unionMember0.if_ + loop = unionMember0.loop + ref = unionMember0.ref + type = unionMember0.type + additionalProperties = unionMember0.additionalProperties.toMutableMap() + } + + fun channels(channels: List?) = channels(JsonField.ofNullable(channels)) + + /** Alias for calling [Builder.channels] with `channels.orElse(null)`. */ + fun channels(channels: Optional>) = channels(channels.getOrNull()) + + /** + * Sets [Builder.channels] to an arbitrary JSON value. + * + * You should usually call [Builder.channels] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun channels(channels: JsonField>) = apply { + this.channels = channels.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [channels]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addChannel(channel: String) = apply { + channels = + (channels ?: JsonField.of(mutableListOf())).also { + checkKnown("channels", it).add(channel) + } + } + + fun if_(if_: String?) = if_(JsonField.ofNullable(if_)) + + /** Alias for calling [Builder.if_] with `if_.orElse(null)`. */ + fun if_(if_: Optional) = if_(if_.getOrNull()) + + /** + * Sets [Builder.if_] to an arbitrary JSON value. + * + * You should usually call [Builder.if_] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun if_(if_: JsonField) = apply { this.if_ = if_ } + + fun loop(loop: String?) = loop(JsonField.ofNullable(loop)) + + /** Alias for calling [Builder.loop] with `loop.orElse(null)`. */ + fun loop(loop: Optional) = loop(loop.getOrNull()) + + /** + * Sets [Builder.loop] to an arbitrary JSON value. + * + * You should usually call [Builder.loop] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun loop(loop: JsonField) = apply { this.loop = loop } + + fun ref(ref: String?) = ref(JsonField.ofNullable(ref)) + + /** Alias for calling [Builder.ref] with `ref.orElse(null)`. */ + fun ref(ref: Optional) = ref(ref.getOrNull()) + + /** + * Sets [Builder.ref] to an arbitrary JSON value. + * + * You should usually call [Builder.ref] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun ref(ref: JsonField) = apply { this.ref = ref } + + 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 } + + 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 [UnionMember0]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): UnionMember0 = + UnionMember0( + (channels ?: JsonMissing.of()).map { it.toImmutable() }, + if_, + loop, + ref, + type, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): UnionMember0 = apply { + if (validated) { + return@apply + } + + channels() + if_() + loop() + ref() + type().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (channels.asKnown().getOrNull()?.size ?: 0) + + (if (if_.asKnown().isPresent) 1 else 0) + + (if (loop.asKnown().isPresent) 1 else 0) + + (if (ref.asKnown().isPresent) 1 else 0) + + (type.asKnown().getOrNull()?.validity() ?: 0) + + 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 TEXT = of("text") + + @JvmStatic fun of(value: String) = Type(JsonField.of(value)) + } + + /** An enum containing [Type]'s known values. */ + enum class Known { + TEXT + } + + /** + * 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 { + TEXT, + /** 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) { + TEXT -> Value.TEXT + 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 CourierInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + TEXT -> Known.TEXT + else -> throw CourierInvalidDataException("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 CourierInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CourierInvalidDataException("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: CourierInvalidDataException) { + 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 UnionMember0 && + channels == other.channels && + if_ == other.if_ && + loop == other.loop && + ref == other.ref && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(channels, if_, loop, ref, type, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "UnionMember0{channels=$channels, if_=$if_, loop=$loop, ref=$ref, type=$type, additionalProperties=$additionalProperties}" + } + + class UnionMember1 + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val channels: JsonField>, + private val if_: JsonField, + private val loop: JsonField, + private val ref: JsonField, + private val type: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("channels") + @ExcludeMissing + channels: JsonField> = JsonMissing.of(), + @JsonProperty("if") @ExcludeMissing if_: JsonField = JsonMissing.of(), + @JsonProperty("loop") @ExcludeMissing loop: JsonField = JsonMissing.of(), + @JsonProperty("ref") @ExcludeMissing ref: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), + ) : this(channels, if_, loop, ref, type, mutableMapOf()) + + fun toElementalBaseNode(): ElementalBaseNode = + ElementalBaseNode.builder().channels(channels).if_(if_).loop(loop).ref(ref).build() + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun channels(): Optional> = channels.getOptional("channels") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun if_(): Optional = if_.getOptional("if") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun loop(): Optional = loop.getOptional("loop") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun ref(): Optional = ref.getOptional("ref") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun type(): Optional = type.getOptional("type") + + /** + * Returns the raw JSON value of [channels]. + * + * Unlike [channels], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("channels") + @ExcludeMissing + fun _channels(): JsonField> = channels + + /** + * Returns the raw JSON value of [if_]. + * + * Unlike [if_], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("if") @ExcludeMissing fun _if_(): JsonField = if_ + + /** + * Returns the raw JSON value of [loop]. + * + * Unlike [loop], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("loop") @ExcludeMissing fun _loop(): JsonField = loop + + /** + * Returns the raw JSON value of [ref]. + * + * Unlike [ref], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("ref") @ExcludeMissing fun _ref(): JsonField = ref + + /** + * 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 + + @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 [UnionMember1]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [UnionMember1]. */ + class Builder internal constructor() { + + private var channels: JsonField>? = null + private var if_: JsonField = JsonMissing.of() + private var loop: JsonField = JsonMissing.of() + private var ref: JsonField = JsonMissing.of() + private var type: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(unionMember1: UnionMember1) = apply { + channels = unionMember1.channels.map { it.toMutableList() } + if_ = unionMember1.if_ + loop = unionMember1.loop + ref = unionMember1.ref + type = unionMember1.type + additionalProperties = unionMember1.additionalProperties.toMutableMap() + } + + fun channels(channels: List?) = channels(JsonField.ofNullable(channels)) + + /** Alias for calling [Builder.channels] with `channels.orElse(null)`. */ + fun channels(channels: Optional>) = channels(channels.getOrNull()) + + /** + * Sets [Builder.channels] to an arbitrary JSON value. + * + * You should usually call [Builder.channels] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun channels(channels: JsonField>) = apply { + this.channels = channels.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [channels]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addChannel(channel: String) = apply { + channels = + (channels ?: JsonField.of(mutableListOf())).also { + checkKnown("channels", it).add(channel) + } + } + + fun if_(if_: String?) = if_(JsonField.ofNullable(if_)) + + /** Alias for calling [Builder.if_] with `if_.orElse(null)`. */ + fun if_(if_: Optional) = if_(if_.getOrNull()) + + /** + * Sets [Builder.if_] to an arbitrary JSON value. + * + * You should usually call [Builder.if_] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun if_(if_: JsonField) = apply { this.if_ = if_ } + + fun loop(loop: String?) = loop(JsonField.ofNullable(loop)) + + /** Alias for calling [Builder.loop] with `loop.orElse(null)`. */ + fun loop(loop: Optional) = loop(loop.getOrNull()) + + /** + * Sets [Builder.loop] to an arbitrary JSON value. + * + * You should usually call [Builder.loop] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun loop(loop: JsonField) = apply { this.loop = loop } + + fun ref(ref: String?) = ref(JsonField.ofNullable(ref)) + + /** Alias for calling [Builder.ref] with `ref.orElse(null)`. */ + fun ref(ref: Optional) = ref(ref.getOrNull()) + + /** + * Sets [Builder.ref] to an arbitrary JSON value. + * + * You should usually call [Builder.ref] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun ref(ref: JsonField) = apply { this.ref = ref } + + 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 } + + 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 [UnionMember1]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): UnionMember1 = + UnionMember1( + (channels ?: JsonMissing.of()).map { it.toImmutable() }, + if_, + loop, + ref, + type, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): UnionMember1 = apply { + if (validated) { + return@apply + } + + channels() + if_() + loop() + ref() + type().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (channels.asKnown().getOrNull()?.size ?: 0) + + (if (if_.asKnown().isPresent) 1 else 0) + + (if (loop.asKnown().isPresent) 1 else 0) + + (if (ref.asKnown().isPresent) 1 else 0) + + (type.asKnown().getOrNull()?.validity() ?: 0) + + 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 META = of("meta") + + @JvmStatic fun of(value: String) = Type(JsonField.of(value)) + } + + /** An enum containing [Type]'s known values. */ + enum class Known { + META + } + + /** + * 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 { + META, + /** 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) { + META -> Value.META + 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 CourierInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + META -> Known.META + else -> throw CourierInvalidDataException("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 CourierInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CourierInvalidDataException("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: CourierInvalidDataException) { + 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 UnionMember1 && + channels == other.channels && + if_ == other.if_ && + loop == other.loop && + ref == other.ref && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(channels, if_, loop, ref, type, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "UnionMember1{channels=$channels, if_=$if_, loop=$loop, ref=$ref, type=$type, additionalProperties=$additionalProperties}" + } + + /** + * The channel element allows a notification to be customized based on which channel it is sent + * through. For example, you may want to display a detailed message when the notification is + * sent through email, and a more concise message in a push notification. Channel elements are + * only valid as top-level elements; you cannot nest channel elements. If there is a channel + * element specified at the top-level of the document, all sibling elements must be channel + * elements. Note: As an alternative, most elements support a `channel` property. Which allows + * you to selectively display an individual element on a per channel basis. See the + * [control flow docs](https://www.courier.com/docs/platform/content/elemental/control-flow/) + * for more details. + */ + class UnionMember2 + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val channels: JsonField>, + private val if_: JsonField, + private val loop: JsonField, + private val ref: JsonField, + private val channel: JsonField, + private val raw: JsonField, + private val type: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("channels") + @ExcludeMissing + channels: JsonField> = JsonMissing.of(), + @JsonProperty("if") @ExcludeMissing if_: JsonField = JsonMissing.of(), + @JsonProperty("loop") @ExcludeMissing loop: JsonField = JsonMissing.of(), + @JsonProperty("ref") @ExcludeMissing ref: JsonField = JsonMissing.of(), + @JsonProperty("channel") @ExcludeMissing channel: JsonField = JsonMissing.of(), + @JsonProperty("raw") + @ExcludeMissing + raw: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), + ) : this(channels, if_, loop, ref, channel, raw, type, mutableMapOf()) + + fun toElementalChannelNode(): ElementalChannelNode = + ElementalChannelNode.builder() + .channels(channels) + .if_(if_) + .loop(loop) + .ref(ref) + .channel(channel) + .raw(raw) + .build() + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun channels(): Optional> = channels.getOptional("channels") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun if_(): Optional = if_.getOptional("if") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun loop(): Optional = loop.getOptional("loop") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun ref(): Optional = ref.getOptional("ref") + + /** + * The channel the contents of this element should be applied to. Can be `email`, `push`, + * `direct_message`, `sms` or a provider such as slack + * + * @throws CourierInvalidDataException 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 channel(): String = channel.getRequired("channel") + + /** + * Raw data to apply to the channel. If `elements` has not been specified, `raw` is + * `required`. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun raw(): Optional = raw.getOptional("raw") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun type(): Optional = type.getOptional("type") + + /** + * Returns the raw JSON value of [channels]. + * + * Unlike [channels], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("channels") + @ExcludeMissing + fun _channels(): JsonField> = channels + + /** + * Returns the raw JSON value of [if_]. + * + * Unlike [if_], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("if") @ExcludeMissing fun _if_(): JsonField = if_ + + /** + * Returns the raw JSON value of [loop]. + * + * Unlike [loop], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("loop") @ExcludeMissing fun _loop(): JsonField = loop + + /** + * Returns the raw JSON value of [ref]. + * + * Unlike [ref], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("ref") @ExcludeMissing fun _ref(): JsonField = ref + + /** + * Returns the raw JSON value of [channel]. + * + * Unlike [channel], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("channel") @ExcludeMissing fun _channel(): JsonField = channel + + /** + * Returns the raw JSON value of [raw]. + * + * Unlike [raw], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("raw") @ExcludeMissing fun _raw(): JsonField = raw + + /** + * 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 + + @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 [UnionMember2]. + * + * The following fields are required: + * ```java + * .channel() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [UnionMember2]. */ + class Builder internal constructor() { + + private var channels: JsonField>? = null + private var if_: JsonField = JsonMissing.of() + private var loop: JsonField = JsonMissing.of() + private var ref: JsonField = JsonMissing.of() + private var channel: JsonField? = null + private var raw: JsonField = JsonMissing.of() + private var type: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(unionMember2: UnionMember2) = apply { + channels = unionMember2.channels.map { it.toMutableList() } + if_ = unionMember2.if_ + loop = unionMember2.loop + ref = unionMember2.ref + channel = unionMember2.channel + raw = unionMember2.raw + type = unionMember2.type + additionalProperties = unionMember2.additionalProperties.toMutableMap() + } + + fun channels(channels: List?) = channels(JsonField.ofNullable(channels)) + + /** Alias for calling [Builder.channels] with `channels.orElse(null)`. */ + fun channels(channels: Optional>) = channels(channels.getOrNull()) + + /** + * Sets [Builder.channels] to an arbitrary JSON value. + * + * You should usually call [Builder.channels] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun channels(channels: JsonField>) = apply { + this.channels = channels.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [channels]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addChannel(channel: String) = apply { + channels = + (channels ?: JsonField.of(mutableListOf())).also { + checkKnown("channels", it).add(channel) + } + } + + fun if_(if_: String?) = if_(JsonField.ofNullable(if_)) + + /** Alias for calling [Builder.if_] with `if_.orElse(null)`. */ + fun if_(if_: Optional) = if_(if_.getOrNull()) + + /** + * Sets [Builder.if_] to an arbitrary JSON value. + * + * You should usually call [Builder.if_] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun if_(if_: JsonField) = apply { this.if_ = if_ } + + fun loop(loop: String?) = loop(JsonField.ofNullable(loop)) + + /** Alias for calling [Builder.loop] with `loop.orElse(null)`. */ + fun loop(loop: Optional) = loop(loop.getOrNull()) + + /** + * Sets [Builder.loop] to an arbitrary JSON value. + * + * You should usually call [Builder.loop] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun loop(loop: JsonField) = apply { this.loop = loop } + + fun ref(ref: String?) = ref(JsonField.ofNullable(ref)) + + /** Alias for calling [Builder.ref] with `ref.orElse(null)`. */ + fun ref(ref: Optional) = ref(ref.getOrNull()) + + /** + * Sets [Builder.ref] to an arbitrary JSON value. + * + * You should usually call [Builder.ref] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun ref(ref: JsonField) = apply { this.ref = ref } + + /** + * The channel the contents of this element should be applied to. Can be `email`, + * `push`, `direct_message`, `sms` or a provider such as slack + */ + fun channel(channel: String) = channel(JsonField.of(channel)) + + /** + * Sets [Builder.channel] to an arbitrary JSON value. + * + * You should usually call [Builder.channel] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun channel(channel: JsonField) = apply { this.channel = channel } + + /** + * Raw data to apply to the channel. If `elements` has not been specified, `raw` is + * `required`. + */ + fun raw(raw: ElementalChannelNode.Raw?) = raw(JsonField.ofNullable(raw)) + + /** Alias for calling [Builder.raw] with `raw.orElse(null)`. */ + fun raw(raw: Optional) = raw(raw.getOrNull()) + + /** + * Sets [Builder.raw] to an arbitrary JSON value. + * + * You should usually call [Builder.raw] with a well-typed [ElementalChannelNode.Raw] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun raw(raw: JsonField) = apply { this.raw = raw } + + 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 } + + 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 [UnionMember2]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .channel() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): UnionMember2 = + UnionMember2( + (channels ?: JsonMissing.of()).map { it.toImmutable() }, + if_, + loop, + ref, + checkRequired("channel", channel), + raw, + type, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): UnionMember2 = apply { + if (validated) { + return@apply + } + + channels() + if_() + loop() + ref() + channel() + raw().ifPresent { it.validate() } + type().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (channels.asKnown().getOrNull()?.size ?: 0) + + (if (if_.asKnown().isPresent) 1 else 0) + + (if (loop.asKnown().isPresent) 1 else 0) + + (if (ref.asKnown().isPresent) 1 else 0) + + (if (channel.asKnown().isPresent) 1 else 0) + + (raw.asKnown().getOrNull()?.validity() ?: 0) + + (type.asKnown().getOrNull()?.validity() ?: 0) + + 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 CHANNEL = of("channel") + + @JvmStatic fun of(value: String) = Type(JsonField.of(value)) + } + + /** An enum containing [Type]'s known values. */ + enum class Known { + CHANNEL + } + + /** + * 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 { + CHANNEL, + /** 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) { + CHANNEL -> Value.CHANNEL + 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 CourierInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + CHANNEL -> Known.CHANNEL + else -> throw CourierInvalidDataException("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 CourierInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CourierInvalidDataException("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: CourierInvalidDataException) { + 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 UnionMember2 && + channels == other.channels && + if_ == other.if_ && + loop == other.loop && + ref == other.ref && + channel == other.channel && + raw == other.raw && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(channels, if_, loop, ref, channel, raw, type, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "UnionMember2{channels=$channels, if_=$if_, loop=$loop, ref=$ref, channel=$channel, raw=$raw, type=$type, additionalProperties=$additionalProperties}" + } + + class UnionMember3 + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val channels: JsonField>, + private val if_: JsonField, + private val loop: JsonField, + private val ref: JsonField, + private val type: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("channels") + @ExcludeMissing + channels: JsonField> = JsonMissing.of(), + @JsonProperty("if") @ExcludeMissing if_: JsonField = JsonMissing.of(), + @JsonProperty("loop") @ExcludeMissing loop: JsonField = JsonMissing.of(), + @JsonProperty("ref") @ExcludeMissing ref: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), + ) : this(channels, if_, loop, ref, type, mutableMapOf()) + + fun toElementalBaseNode(): ElementalBaseNode = + ElementalBaseNode.builder().channels(channels).if_(if_).loop(loop).ref(ref).build() + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun channels(): Optional> = channels.getOptional("channels") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun if_(): Optional = if_.getOptional("if") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun loop(): Optional = loop.getOptional("loop") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun ref(): Optional = ref.getOptional("ref") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun type(): Optional = type.getOptional("type") + + /** + * Returns the raw JSON value of [channels]. + * + * Unlike [channels], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("channels") + @ExcludeMissing + fun _channels(): JsonField> = channels + + /** + * Returns the raw JSON value of [if_]. + * + * Unlike [if_], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("if") @ExcludeMissing fun _if_(): JsonField = if_ + + /** + * Returns the raw JSON value of [loop]. + * + * Unlike [loop], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("loop") @ExcludeMissing fun _loop(): JsonField = loop + + /** + * Returns the raw JSON value of [ref]. + * + * Unlike [ref], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("ref") @ExcludeMissing fun _ref(): JsonField = ref + + /** + * 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 + + @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 [UnionMember3]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [UnionMember3]. */ + class Builder internal constructor() { + + private var channels: JsonField>? = null + private var if_: JsonField = JsonMissing.of() + private var loop: JsonField = JsonMissing.of() + private var ref: JsonField = JsonMissing.of() + private var type: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(unionMember3: UnionMember3) = apply { + channels = unionMember3.channels.map { it.toMutableList() } + if_ = unionMember3.if_ + loop = unionMember3.loop + ref = unionMember3.ref + type = unionMember3.type + additionalProperties = unionMember3.additionalProperties.toMutableMap() + } + + fun channels(channels: List?) = channels(JsonField.ofNullable(channels)) + + /** Alias for calling [Builder.channels] with `channels.orElse(null)`. */ + fun channels(channels: Optional>) = channels(channels.getOrNull()) + + /** + * Sets [Builder.channels] to an arbitrary JSON value. + * + * You should usually call [Builder.channels] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun channels(channels: JsonField>) = apply { + this.channels = channels.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [channels]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addChannel(channel: String) = apply { + channels = + (channels ?: JsonField.of(mutableListOf())).also { + checkKnown("channels", it).add(channel) + } + } + + fun if_(if_: String?) = if_(JsonField.ofNullable(if_)) + + /** Alias for calling [Builder.if_] with `if_.orElse(null)`. */ + fun if_(if_: Optional) = if_(if_.getOrNull()) + + /** + * Sets [Builder.if_] to an arbitrary JSON value. + * + * You should usually call [Builder.if_] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun if_(if_: JsonField) = apply { this.if_ = if_ } + + fun loop(loop: String?) = loop(JsonField.ofNullable(loop)) + + /** Alias for calling [Builder.loop] with `loop.orElse(null)`. */ + fun loop(loop: Optional) = loop(loop.getOrNull()) + + /** + * Sets [Builder.loop] to an arbitrary JSON value. + * + * You should usually call [Builder.loop] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun loop(loop: JsonField) = apply { this.loop = loop } + + fun ref(ref: String?) = ref(JsonField.ofNullable(ref)) + + /** Alias for calling [Builder.ref] with `ref.orElse(null)`. */ + fun ref(ref: Optional) = ref(ref.getOrNull()) + + /** + * Sets [Builder.ref] to an arbitrary JSON value. + * + * You should usually call [Builder.ref] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun ref(ref: JsonField) = apply { this.ref = ref } + + 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 } + + 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 [UnionMember3]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): UnionMember3 = + UnionMember3( + (channels ?: JsonMissing.of()).map { it.toImmutable() }, + if_, + loop, + ref, + type, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): UnionMember3 = apply { + if (validated) { + return@apply + } + + channels() + if_() + loop() + ref() + type().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + 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 = + (channels.asKnown().getOrNull()?.size ?: 0) + + (if (if_.asKnown().isPresent) 1 else 0) + + (if (loop.asKnown().isPresent) 1 else 0) + + (if (ref.asKnown().isPresent) 1 else 0) + + (type.asKnown().getOrNull()?.validity() ?: 0) + + 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 IMAGE = of("image") + + @JvmStatic fun of(value: String) = Type(JsonField.of(value)) + } + + /** An enum containing [Type]'s known values. */ + enum class Known { + IMAGE + } + + /** + * 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 { + IMAGE, + /** 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) { + IMAGE -> Value.IMAGE + 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 CourierInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + IMAGE -> Known.IMAGE + else -> throw CourierInvalidDataException("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 CourierInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CourierInvalidDataException("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: CourierInvalidDataException) { + 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 UnionMember3 && + channels == other.channels && + if_ == other.if_ && + loop == other.loop && + ref == other.ref && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(channels, if_, loop, ref, type, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "UnionMember3{channels=$channels, if_=$if_, loop=$loop, ref=$ref, type=$type, additionalProperties=$additionalProperties}" + } + + class UnionMember4 + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val actionId: JsonField, + private val align: JsonField, + private val backgroundColor: JsonField, + private val content: JsonField, + private val href: JsonField, + private val locales: JsonField, + private val style: JsonField