From 393159f9bc12a5bb89dd42305ab6601f781a2c29 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 17 Jun 2025 07:23:29 +0000 Subject: [PATCH 1/4] chore(ci): enable for pull requests --- .github/workflows/ci.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dc563e0..3aac699 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,6 +7,10 @@ on: - 'integrated/**' - 'stl-preview-head/**' - 'stl-preview-base/**' + pull_request: + branches-ignore: + - 'stl-preview-head/**' + - 'stl-preview-base/**' jobs: lint: From 8b819ae77d457e0d8cd987f3e83c8070e25e2c13 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 19 Jun 2025 19:44:58 +0000 Subject: [PATCH 2/4] feat(api): manual updates --- .stats.yml | 8 +- .../api/models/brand/BrandScreenshotParams.kt | 374 ++ .../models/brand/BrandScreenshotResponse.kt | 437 ++ .../api/models/brand/BrandStyleguideParams.kt | 239 + .../models/brand/BrandStyleguideResponse.kt | 5829 +++++++++++++++++ .../api/services/async/BrandServiceAsync.kt | 62 + .../services/async/BrandServiceAsyncImpl.kt | 80 + .../api/services/blocking/BrandService.kt | 62 + .../api/services/blocking/BrandServiceImpl.kt | 74 + .../models/brand/BrandScreenshotParamsTest.kt | 47 + .../brand/BrandScreenshotResponseTest.kt | 54 + .../models/brand/BrandStyleguideParamsTest.kt | 38 + .../brand/BrandStyleguideResponseTest.kt | 525 ++ .../services/async/BrandServiceAsyncTest.kt | 43 + .../api/services/blocking/BrandServiceTest.kt | 41 + 15 files changed, 7909 insertions(+), 4 deletions(-) create mode 100644 brand-dev-java-core/src/main/kotlin/com/branddev/api/models/brand/BrandScreenshotParams.kt create mode 100644 brand-dev-java-core/src/main/kotlin/com/branddev/api/models/brand/BrandScreenshotResponse.kt create mode 100644 brand-dev-java-core/src/main/kotlin/com/branddev/api/models/brand/BrandStyleguideParams.kt create mode 100644 brand-dev-java-core/src/main/kotlin/com/branddev/api/models/brand/BrandStyleguideResponse.kt create mode 100644 brand-dev-java-core/src/test/kotlin/com/branddev/api/models/brand/BrandScreenshotParamsTest.kt create mode 100644 brand-dev-java-core/src/test/kotlin/com/branddev/api/models/brand/BrandScreenshotResponseTest.kt create mode 100644 brand-dev-java-core/src/test/kotlin/com/branddev/api/models/brand/BrandStyleguideParamsTest.kt create mode 100644 brand-dev-java-core/src/test/kotlin/com/branddev/api/models/brand/BrandStyleguideResponseTest.kt diff --git a/.stats.yml b/.stats.yml index e5a78c5..137e5c9 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 7 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/brand-dev%2Fbrand.dev-103a28182099d9866bc8c40db00f3356fe5be36302874e7ee84ee4fd2f593859.yml -openapi_spec_hash: 30241efa79f9aab6e430c29383d9a2cf -config_hash: 4ab8d35881cc0191126ff443317e03ba +configured_endpoints: 9 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/brand-dev%2Fbrand.dev-3f6d4c0f819a0d3128951d315ad216df22050fbc47c5f601d261d56f8b1d80a5.yml +openapi_spec_hash: 8e7953259a1b6bd7440a780eccad1742 +config_hash: 6ce904be333b502d5fd8b746088aad6d diff --git a/brand-dev-java-core/src/main/kotlin/com/branddev/api/models/brand/BrandScreenshotParams.kt b/brand-dev-java-core/src/main/kotlin/com/branddev/api/models/brand/BrandScreenshotParams.kt new file mode 100644 index 0000000..0fa8913 --- /dev/null +++ b/brand-dev-java-core/src/main/kotlin/com/branddev/api/models/brand/BrandScreenshotParams.kt @@ -0,0 +1,374 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.branddev.api.models.brand + +import com.branddev.api.core.Enum +import com.branddev.api.core.JsonField +import com.branddev.api.core.Params +import com.branddev.api.core.checkRequired +import com.branddev.api.core.http.Headers +import com.branddev.api.core.http.QueryParams +import com.branddev.api.errors.BrandDevInvalidDataException +import com.fasterxml.jackson.annotation.JsonCreator +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * Beta feature: Capture a screenshot of a website. Supports both viewport (standard browser view) + * and full-page screenshots. Returns a URL to the uploaded screenshot image hosted on our CDN. + */ +class BrandScreenshotParams +private constructor( + private val domain: String, + private val fullScreenshot: FullScreenshot?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Domain name to take screenshot of (e.g., 'example.com', 'google.com'). The domain will be + * automatically normalized and validated. + */ + fun domain(): String = domain + + /** + * Optional parameter to determine screenshot type. If 'true', takes a full page screenshot + * capturing all content. If 'false' or not provided, takes a viewport screenshot (standard + * browser view). + */ + fun fullScreenshot(): Optional = Optional.ofNullable(fullScreenshot) + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [BrandScreenshotParams]. + * + * The following fields are required: + * ```java + * .domain() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [BrandScreenshotParams]. */ + class Builder internal constructor() { + + private var domain: String? = null + private var fullScreenshot: FullScreenshot? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(brandScreenshotParams: BrandScreenshotParams) = apply { + domain = brandScreenshotParams.domain + fullScreenshot = brandScreenshotParams.fullScreenshot + additionalHeaders = brandScreenshotParams.additionalHeaders.toBuilder() + additionalQueryParams = brandScreenshotParams.additionalQueryParams.toBuilder() + } + + /** + * Domain name to take screenshot of (e.g., 'example.com', 'google.com'). The domain will be + * automatically normalized and validated. + */ + fun domain(domain: String) = apply { this.domain = domain } + + /** + * Optional parameter to determine screenshot type. If 'true', takes a full page screenshot + * capturing all content. If 'false' or not provided, takes a viewport screenshot (standard + * browser view). + */ + fun fullScreenshot(fullScreenshot: FullScreenshot?) = apply { + this.fullScreenshot = fullScreenshot + } + + /** Alias for calling [Builder.fullScreenshot] with `fullScreenshot.orElse(null)`. */ + fun fullScreenshot(fullScreenshot: Optional) = + fullScreenshot(fullScreenshot.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 [BrandScreenshotParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .domain() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): BrandScreenshotParams = + BrandScreenshotParams( + checkRequired("domain", domain), + fullScreenshot, + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + put("domain", domain) + fullScreenshot?.let { put("fullScreenshot", it.toString()) } + putAll(additionalQueryParams) + } + .build() + + /** + * Optional parameter to determine screenshot type. If 'true', takes a full page screenshot + * capturing all content. If 'false' or not provided, takes a viewport screenshot (standard + * browser view). + */ + class FullScreenshot @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 TRUE = of("true") + + @JvmField val FALSE = of("false") + + @JvmStatic fun of(value: String) = FullScreenshot(JsonField.of(value)) + } + + /** An enum containing [FullScreenshot]'s known values. */ + enum class Known { + TRUE, + FALSE, + } + + /** + * An enum containing [FullScreenshot]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [FullScreenshot] 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 { + TRUE, + FALSE, + /** + * An enum member indicating that [FullScreenshot] 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) { + TRUE -> Value.TRUE + FALSE -> Value.FALSE + 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 BrandDevInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + TRUE -> Known.TRUE + FALSE -> Known.FALSE + else -> throw BrandDevInvalidDataException("Unknown FullScreenshot: $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 BrandDevInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BrandDevInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): FullScreenshot = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: BrandDevInvalidDataException) { + false + } + + /** + * Returns 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 /* spotless:off */ other is FullScreenshot && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is BrandScreenshotParams && domain == other.domain && fullScreenshot == other.fullScreenshot && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(domain, fullScreenshot, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "BrandScreenshotParams{domain=$domain, fullScreenshot=$fullScreenshot, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/brand-dev-java-core/src/main/kotlin/com/branddev/api/models/brand/BrandScreenshotResponse.kt b/brand-dev-java-core/src/main/kotlin/com/branddev/api/models/brand/BrandScreenshotResponse.kt new file mode 100644 index 0000000..b4fdbcd --- /dev/null +++ b/brand-dev-java-core/src/main/kotlin/com/branddev/api/models/brand/BrandScreenshotResponse.kt @@ -0,0 +1,437 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.branddev.api.models.brand + +import com.branddev.api.core.Enum +import com.branddev.api.core.ExcludeMissing +import com.branddev.api.core.JsonField +import com.branddev.api.core.JsonMissing +import com.branddev.api.core.JsonValue +import com.branddev.api.errors.BrandDevInvalidDataException +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 BrandScreenshotResponse +private constructor( + private val code: JsonField, + private val domain: JsonField, + private val screenshot: JsonField, + private val screenshotType: JsonField, + private val status: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("code") @ExcludeMissing code: JsonField = JsonMissing.of(), + @JsonProperty("domain") @ExcludeMissing domain: JsonField = JsonMissing.of(), + @JsonProperty("screenshot") + @ExcludeMissing + screenshot: JsonField = JsonMissing.of(), + @JsonProperty("screenshotType") + @ExcludeMissing + screenshotType: JsonField = JsonMissing.of(), + @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(), + ) : this(code, domain, screenshot, screenshotType, status, mutableMapOf()) + + /** + * HTTP status code + * + * @throws BrandDevInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun code(): Optional = code.getOptional("code") + + /** + * The normalized domain that was processed + * + * @throws BrandDevInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun domain(): Optional = domain.getOptional("domain") + + /** + * Public URL of the uploaded screenshot image + * + * @throws BrandDevInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun screenshot(): Optional = screenshot.getOptional("screenshot") + + /** + * Type of screenshot that was captured + * + * @throws BrandDevInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun screenshotType(): Optional = screenshotType.getOptional("screenshotType") + + /** + * Status of the response, e.g., 'ok' + * + * @throws BrandDevInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun status(): Optional = status.getOptional("status") + + /** + * Returns the raw JSON value of [code]. + * + * Unlike [code], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("code") @ExcludeMissing fun _code(): JsonField = code + + /** + * Returns the raw JSON value of [domain]. + * + * Unlike [domain], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("domain") @ExcludeMissing fun _domain(): JsonField = domain + + /** + * Returns the raw JSON value of [screenshot]. + * + * Unlike [screenshot], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("screenshot") @ExcludeMissing fun _screenshot(): JsonField = screenshot + + /** + * Returns the raw JSON value of [screenshotType]. + * + * Unlike [screenshotType], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("screenshotType") + @ExcludeMissing + fun _screenshotType(): JsonField = screenshotType + + /** + * 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 [BrandScreenshotResponse]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [BrandScreenshotResponse]. */ + class Builder internal constructor() { + + private var code: JsonField = JsonMissing.of() + private var domain: JsonField = JsonMissing.of() + private var screenshot: JsonField = JsonMissing.of() + private var screenshotType: JsonField = JsonMissing.of() + private var status: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(brandScreenshotResponse: BrandScreenshotResponse) = apply { + code = brandScreenshotResponse.code + domain = brandScreenshotResponse.domain + screenshot = brandScreenshotResponse.screenshot + screenshotType = brandScreenshotResponse.screenshotType + status = brandScreenshotResponse.status + additionalProperties = brandScreenshotResponse.additionalProperties.toMutableMap() + } + + /** HTTP status code */ + fun code(code: Long) = code(JsonField.of(code)) + + /** + * Sets [Builder.code] to an arbitrary JSON value. + * + * You should usually call [Builder.code] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun code(code: JsonField) = apply { this.code = code } + + /** The normalized domain that was processed */ + fun domain(domain: String) = domain(JsonField.of(domain)) + + /** + * Sets [Builder.domain] to an arbitrary JSON value. + * + * You should usually call [Builder.domain] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun domain(domain: JsonField) = apply { this.domain = domain } + + /** Public URL of the uploaded screenshot image */ + fun screenshot(screenshot: String) = screenshot(JsonField.of(screenshot)) + + /** + * Sets [Builder.screenshot] to an arbitrary JSON value. + * + * You should usually call [Builder.screenshot] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun screenshot(screenshot: JsonField) = apply { this.screenshot = screenshot } + + /** Type of screenshot that was captured */ + fun screenshotType(screenshotType: ScreenshotType) = + screenshotType(JsonField.of(screenshotType)) + + /** + * Sets [Builder.screenshotType] to an arbitrary JSON value. + * + * You should usually call [Builder.screenshotType] with a well-typed [ScreenshotType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun screenshotType(screenshotType: JsonField) = apply { + this.screenshotType = screenshotType + } + + /** Status of the response, e.g., 'ok' */ + fun status(status: String) = status(JsonField.of(status)) + + /** + * Sets [Builder.status] to an arbitrary JSON value. + * + * You should usually call [Builder.status] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun status(status: JsonField) = apply { this.status = status } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [BrandScreenshotResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): BrandScreenshotResponse = + BrandScreenshotResponse( + code, + domain, + screenshot, + screenshotType, + status, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): BrandScreenshotResponse = apply { + if (validated) { + return@apply + } + + code() + domain() + screenshot() + screenshotType().ifPresent { it.validate() } + status() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: BrandDevInvalidDataException) { + false + } + + /** + * Returns 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 (code.asKnown().isPresent) 1 else 0) + + (if (domain.asKnown().isPresent) 1 else 0) + + (if (screenshot.asKnown().isPresent) 1 else 0) + + (screenshotType.asKnown().getOrNull()?.validity() ?: 0) + + (if (status.asKnown().isPresent) 1 else 0) + + /** Type of screenshot that was captured */ + class ScreenshotType @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 VIEWPORT = of("viewport") + + @JvmField val FULL_PAGE = of("fullPage") + + @JvmStatic fun of(value: String) = ScreenshotType(JsonField.of(value)) + } + + /** An enum containing [ScreenshotType]'s known values. */ + enum class Known { + VIEWPORT, + FULL_PAGE, + } + + /** + * An enum containing [ScreenshotType]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [ScreenshotType] 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 { + VIEWPORT, + FULL_PAGE, + /** + * An enum member indicating that [ScreenshotType] 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) { + VIEWPORT -> Value.VIEWPORT + FULL_PAGE -> Value.FULL_PAGE + 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 BrandDevInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + VIEWPORT -> Known.VIEWPORT + FULL_PAGE -> Known.FULL_PAGE + else -> throw BrandDevInvalidDataException("Unknown ScreenshotType: $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 BrandDevInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BrandDevInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): ScreenshotType = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: BrandDevInvalidDataException) { + false + } + + /** + * Returns 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 /* spotless:off */ other is ScreenshotType && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is BrandScreenshotResponse && code == other.code && domain == other.domain && screenshot == other.screenshot && screenshotType == other.screenshotType && status == other.status && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(code, domain, screenshot, screenshotType, status, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "BrandScreenshotResponse{code=$code, domain=$domain, screenshot=$screenshot, screenshotType=$screenshotType, status=$status, additionalProperties=$additionalProperties}" +} diff --git a/brand-dev-java-core/src/main/kotlin/com/branddev/api/models/brand/BrandStyleguideParams.kt b/brand-dev-java-core/src/main/kotlin/com/branddev/api/models/brand/BrandStyleguideParams.kt new file mode 100644 index 0000000..ef36b0b --- /dev/null +++ b/brand-dev-java-core/src/main/kotlin/com/branddev/api/models/brand/BrandStyleguideParams.kt @@ -0,0 +1,239 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.branddev.api.models.brand + +import com.branddev.api.core.Params +import com.branddev.api.core.checkRequired +import com.branddev.api.core.http.Headers +import com.branddev.api.core.http.QueryParams +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * Beta feature: Automatically extract comprehensive design system information from a brand's + * website including colors, typography, spacing, shadows, and UI components. Uses AI-powered + * analysis of website screenshots to identify design patterns and create a reusable styleguide. + */ +class BrandStyleguideParams +private constructor( + private val domain: String, + private val timeoutMs: Long?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Domain name to extract styleguide from (e.g., 'example.com', 'google.com'). The domain will + * be automatically normalized and validated. + */ + fun domain(): String = domain + + /** + * Optional timeout in milliseconds for the request. If the request takes longer than this + * value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 + * minutes). + */ + fun timeoutMs(): Optional = Optional.ofNullable(timeoutMs) + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [BrandStyleguideParams]. + * + * The following fields are required: + * ```java + * .domain() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [BrandStyleguideParams]. */ + class Builder internal constructor() { + + private var domain: String? = null + private var timeoutMs: Long? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(brandStyleguideParams: BrandStyleguideParams) = apply { + domain = brandStyleguideParams.domain + timeoutMs = brandStyleguideParams.timeoutMs + additionalHeaders = brandStyleguideParams.additionalHeaders.toBuilder() + additionalQueryParams = brandStyleguideParams.additionalQueryParams.toBuilder() + } + + /** + * Domain name to extract styleguide from (e.g., 'example.com', 'google.com'). The domain + * will be automatically normalized and validated. + */ + fun domain(domain: String) = apply { this.domain = domain } + + /** + * Optional timeout in milliseconds for the request. If the request takes longer than this + * value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 + * minutes). + */ + fun timeoutMs(timeoutMs: Long?) = apply { this.timeoutMs = timeoutMs } + + /** + * Alias for [Builder.timeoutMs]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun timeoutMs(timeoutMs: Long) = timeoutMs(timeoutMs as Long?) + + /** Alias for calling [Builder.timeoutMs] with `timeoutMs.orElse(null)`. */ + fun timeoutMs(timeoutMs: Optional) = timeoutMs(timeoutMs.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 [BrandStyleguideParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .domain() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): BrandStyleguideParams = + BrandStyleguideParams( + checkRequired("domain", domain), + timeoutMs, + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + put("domain", domain) + timeoutMs?.let { put("timeoutMS", it.toString()) } + putAll(additionalQueryParams) + } + .build() + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is BrandStyleguideParams && domain == other.domain && timeoutMs == other.timeoutMs && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(domain, timeoutMs, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "BrandStyleguideParams{domain=$domain, timeoutMs=$timeoutMs, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/brand-dev-java-core/src/main/kotlin/com/branddev/api/models/brand/BrandStyleguideResponse.kt b/brand-dev-java-core/src/main/kotlin/com/branddev/api/models/brand/BrandStyleguideResponse.kt new file mode 100644 index 0000000..a2cdecd --- /dev/null +++ b/brand-dev-java-core/src/main/kotlin/com/branddev/api/models/brand/BrandStyleguideResponse.kt @@ -0,0 +1,5829 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.branddev.api.models.brand + +import com.branddev.api.core.ExcludeMissing +import com.branddev.api.core.JsonField +import com.branddev.api.core.JsonMissing +import com.branddev.api.core.JsonValue +import com.branddev.api.errors.BrandDevInvalidDataException +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 BrandStyleguideResponse +private constructor( + private val code: JsonField, + private val domain: JsonField, + private val status: JsonField, + private val styleguide: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("code") @ExcludeMissing code: JsonField = JsonMissing.of(), + @JsonProperty("domain") @ExcludeMissing domain: JsonField = JsonMissing.of(), + @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(), + @JsonProperty("styleguide") + @ExcludeMissing + styleguide: JsonField = JsonMissing.of(), + ) : this(code, domain, status, styleguide, mutableMapOf()) + + /** + * HTTP status code + * + * @throws BrandDevInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun code(): Optional = code.getOptional("code") + + /** + * The normalized domain that was processed + * + * @throws BrandDevInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun domain(): Optional = domain.getOptional("domain") + + /** + * Status of the response, e.g., 'ok' + * + * @throws BrandDevInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun status(): Optional = status.getOptional("status") + + /** + * Comprehensive styleguide data extracted from the website + * + * @throws BrandDevInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun styleguide(): Optional = styleguide.getOptional("styleguide") + + /** + * Returns the raw JSON value of [code]. + * + * Unlike [code], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("code") @ExcludeMissing fun _code(): JsonField = code + + /** + * Returns the raw JSON value of [domain]. + * + * Unlike [domain], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("domain") @ExcludeMissing fun _domain(): JsonField = domain + + /** + * 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 [styleguide]. + * + * Unlike [styleguide], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("styleguide") + @ExcludeMissing + fun _styleguide(): JsonField = styleguide + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [BrandStyleguideResponse]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [BrandStyleguideResponse]. */ + class Builder internal constructor() { + + private var code: JsonField = JsonMissing.of() + private var domain: JsonField = JsonMissing.of() + private var status: JsonField = JsonMissing.of() + private var styleguide: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(brandStyleguideResponse: BrandStyleguideResponse) = apply { + code = brandStyleguideResponse.code + domain = brandStyleguideResponse.domain + status = brandStyleguideResponse.status + styleguide = brandStyleguideResponse.styleguide + additionalProperties = brandStyleguideResponse.additionalProperties.toMutableMap() + } + + /** HTTP status code */ + fun code(code: Long) = code(JsonField.of(code)) + + /** + * Sets [Builder.code] to an arbitrary JSON value. + * + * You should usually call [Builder.code] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun code(code: JsonField) = apply { this.code = code } + + /** The normalized domain that was processed */ + fun domain(domain: String) = domain(JsonField.of(domain)) + + /** + * Sets [Builder.domain] to an arbitrary JSON value. + * + * You should usually call [Builder.domain] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun domain(domain: JsonField) = apply { this.domain = domain } + + /** Status of the response, e.g., 'ok' */ + fun status(status: String) = status(JsonField.of(status)) + + /** + * Sets [Builder.status] to an arbitrary JSON value. + * + * You should usually call [Builder.status] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun status(status: JsonField) = apply { this.status = status } + + /** Comprehensive styleguide data extracted from the website */ + fun styleguide(styleguide: Styleguide) = styleguide(JsonField.of(styleguide)) + + /** + * Sets [Builder.styleguide] to an arbitrary JSON value. + * + * You should usually call [Builder.styleguide] with a well-typed [Styleguide] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun styleguide(styleguide: JsonField) = apply { this.styleguide = styleguide } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [BrandStyleguideResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): BrandStyleguideResponse = + BrandStyleguideResponse( + code, + domain, + status, + styleguide, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): BrandStyleguideResponse = apply { + if (validated) { + return@apply + } + + code() + domain() + status() + styleguide().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: BrandDevInvalidDataException) { + false + } + + /** + * Returns 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 (code.asKnown().isPresent) 1 else 0) + + (if (domain.asKnown().isPresent) 1 else 0) + + (if (status.asKnown().isPresent) 1 else 0) + + (styleguide.asKnown().getOrNull()?.validity() ?: 0) + + /** Comprehensive styleguide data extracted from the website */ + class Styleguide + private constructor( + private val colors: JsonField, + private val components: JsonField, + private val elementSpacing: JsonField, + private val shadows: JsonField, + private val typography: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("colors") @ExcludeMissing colors: JsonField = JsonMissing.of(), + @JsonProperty("components") + @ExcludeMissing + components: JsonField = JsonMissing.of(), + @JsonProperty("elementSpacing") + @ExcludeMissing + elementSpacing: JsonField = JsonMissing.of(), + @JsonProperty("shadows") @ExcludeMissing shadows: JsonField = JsonMissing.of(), + @JsonProperty("typography") + @ExcludeMissing + typography: JsonField = JsonMissing.of(), + ) : this(colors, components, elementSpacing, shadows, typography, mutableMapOf()) + + /** + * Primary colors used on the website + * + * @throws BrandDevInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun colors(): Optional = colors.getOptional("colors") + + /** + * UI component styles + * + * @throws BrandDevInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun components(): Optional = components.getOptional("components") + + /** + * Spacing system used on the website + * + * @throws BrandDevInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun elementSpacing(): Optional = + elementSpacing.getOptional("elementSpacing") + + /** + * Shadow styles used on the website + * + * @throws BrandDevInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun shadows(): Optional = shadows.getOptional("shadows") + + /** + * Typography styles used on the website + * + * @throws BrandDevInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun typography(): Optional = typography.getOptional("typography") + + /** + * 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 [components]. + * + * Unlike [components], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("components") + @ExcludeMissing + fun _components(): JsonField = components + + /** + * Returns the raw JSON value of [elementSpacing]. + * + * Unlike [elementSpacing], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("elementSpacing") + @ExcludeMissing + fun _elementSpacing(): JsonField = elementSpacing + + /** + * Returns the raw JSON value of [shadows]. + * + * Unlike [shadows], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("shadows") @ExcludeMissing fun _shadows(): JsonField = shadows + + /** + * Returns the raw JSON value of [typography]. + * + * Unlike [typography], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("typography") + @ExcludeMissing + fun _typography(): JsonField = typography + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Styleguide]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Styleguide]. */ + class Builder internal constructor() { + + private var colors: JsonField = JsonMissing.of() + private var components: JsonField = JsonMissing.of() + private var elementSpacing: JsonField = JsonMissing.of() + private var shadows: JsonField = JsonMissing.of() + private var typography: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(styleguide: Styleguide) = apply { + colors = styleguide.colors + components = styleguide.components + elementSpacing = styleguide.elementSpacing + shadows = styleguide.shadows + typography = styleguide.typography + additionalProperties = styleguide.additionalProperties.toMutableMap() + } + + /** Primary colors used on the website */ + fun colors(colors: Colors) = colors(JsonField.of(colors)) + + /** + * Sets [Builder.colors] to an arbitrary JSON value. + * + * You should usually call [Builder.colors] with a well-typed [Colors] 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 } + + /** UI component styles */ + fun components(components: Components) = components(JsonField.of(components)) + + /** + * Sets [Builder.components] to an arbitrary JSON value. + * + * You should usually call [Builder.components] with a well-typed [Components] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun components(components: JsonField) = apply { + this.components = components + } + + /** Spacing system used on the website */ + fun elementSpacing(elementSpacing: ElementSpacing) = + elementSpacing(JsonField.of(elementSpacing)) + + /** + * Sets [Builder.elementSpacing] to an arbitrary JSON value. + * + * You should usually call [Builder.elementSpacing] with a well-typed [ElementSpacing] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun elementSpacing(elementSpacing: JsonField) = apply { + this.elementSpacing = elementSpacing + } + + /** Shadow styles used on the website */ + fun shadows(shadows: Shadows) = shadows(JsonField.of(shadows)) + + /** + * Sets [Builder.shadows] to an arbitrary JSON value. + * + * You should usually call [Builder.shadows] with a well-typed [Shadows] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun shadows(shadows: JsonField) = apply { this.shadows = shadows } + + /** Typography styles used on the website */ + fun typography(typography: Typography) = typography(JsonField.of(typography)) + + /** + * Sets [Builder.typography] to an arbitrary JSON value. + * + * You should usually call [Builder.typography] with a well-typed [Typography] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun typography(typography: JsonField) = apply { + this.typography = typography + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Styleguide]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Styleguide = + Styleguide( + colors, + components, + elementSpacing, + shadows, + typography, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Styleguide = apply { + if (validated) { + return@apply + } + + colors().ifPresent { it.validate() } + components().ifPresent { it.validate() } + elementSpacing().ifPresent { it.validate() } + shadows().ifPresent { it.validate() } + typography().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: BrandDevInvalidDataException) { + false + } + + /** + * Returns 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) + + (components.asKnown().getOrNull()?.validity() ?: 0) + + (elementSpacing.asKnown().getOrNull()?.validity() ?: 0) + + (shadows.asKnown().getOrNull()?.validity() ?: 0) + + (typography.asKnown().getOrNull()?.validity() ?: 0) + + /** Primary colors used on the website */ + class Colors + private constructor( + private val accent: JsonField, + private val background: JsonField, + private val text: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("accent") + @ExcludeMissing + accent: JsonField = JsonMissing.of(), + @JsonProperty("background") + @ExcludeMissing + background: JsonField = JsonMissing.of(), + @JsonProperty("text") @ExcludeMissing text: JsonField = JsonMissing.of(), + ) : this(accent, background, text, mutableMapOf()) + + /** + * Accent color of the website (hex format) + * + * @throws BrandDevInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun accent(): Optional = accent.getOptional("accent") + + /** + * Background color of the website (hex format) + * + * @throws BrandDevInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun background(): Optional = background.getOptional("background") + + /** + * Text color of the website (hex format) + * + * @throws BrandDevInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun text(): Optional = text.getOptional("text") + + /** + * Returns the raw JSON value of [accent]. + * + * Unlike [accent], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("accent") @ExcludeMissing fun _accent(): JsonField = accent + + /** + * Returns the raw JSON value of [background]. + * + * Unlike [background], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("background") + @ExcludeMissing + fun _background(): JsonField = background + + /** + * 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 + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Colors]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Colors]. */ + class Builder internal constructor() { + + private var accent: JsonField = JsonMissing.of() + private var background: JsonField = JsonMissing.of() + private var text: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(colors: Colors) = apply { + accent = colors.accent + background = colors.background + text = colors.text + additionalProperties = colors.additionalProperties.toMutableMap() + } + + /** Accent color of the website (hex format) */ + fun accent(accent: String) = accent(JsonField.of(accent)) + + /** + * Sets [Builder.accent] to an arbitrary JSON value. + * + * You should usually call [Builder.accent] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun accent(accent: JsonField) = apply { this.accent = accent } + + /** Background color of the website (hex format) */ + fun background(background: String) = background(JsonField.of(background)) + + /** + * Sets [Builder.background] to an arbitrary JSON value. + * + * You should usually call [Builder.background] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun background(background: JsonField) = apply { + this.background = background + } + + /** Text color of the website (hex format) */ + 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 } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Colors]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Colors = + Colors(accent, background, text, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Colors = apply { + if (validated) { + return@apply + } + + accent() + background() + text() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: BrandDevInvalidDataException) { + false + } + + /** + * Returns 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 (accent.asKnown().isPresent) 1 else 0) + + (if (background.asKnown().isPresent) 1 else 0) + + (if (text.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Colors && accent == other.accent && background == other.background && text == other.text && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(accent, background, text, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Colors{accent=$accent, background=$background, text=$text, additionalProperties=$additionalProperties}" + } + + /** UI component styles */ + class Components + private constructor( + private val button: JsonField