/** * Generated by API Builder - https://www.apibuilder.io * Service version: 0.16.53 * User agent: apibuilder app.apibuilder.io/apicollective/apibuilder-spec/0.16.53/http4s_0_22 */ package io.apibuilder.spec.v0.models { sealed trait ResponseCode extends _root_.scala.Product with _root_.scala.Serializable /** * Used to indicate an API concern for a field that is specific to the field's * usage but not necessarily its data type. For example, you might use annotations * to mark that certain fields contain PII or PCI data and thus should not be * stored once processing is complete. Annotations communicate meaning to consumers * of an API and may also be used within an implementation or tooling; for example, * using static analysis tools to detect logging of sensitive data. */ final case class Annotation( name: String, description: _root_.scala.Option[String] = None, deprecation: _root_.scala.Option[io.apibuilder.spec.v0.models.Deprecation] = None ) final case class Apidoc( version: String ) /** * @param key Unique key identifying this application */ final case class Application( key: String ) /** * Represents an additional attribute that is attached to one of the objects in * apibuilder. The main use case is to capture additional metadata that doesn't * necessarily define the API but aids in code generation. Examples would be hints * for certain code generators about classes to extend, interfaces to implement, * annotations to add, names to assign to certain methods, etc. The specific * attributes will be applicable only in the context of the specific code * generators usings them. */ final case class Attribute( name: String, value: Map[String, _root_.io.circe.Json], description: _root_.scala.Option[String] = None, deprecation: _root_.scala.Option[io.apibuilder.spec.v0.models.Deprecation] = None ) final case class Body( `type`: String, description: _root_.scala.Option[String] = None, deprecation: _root_.scala.Option[io.apibuilder.spec.v0.models.Deprecation] = None, attributes: Seq[io.apibuilder.spec.v0.models.Attribute] = Nil ) /** * Describes the primary contact for this service */ final case class Contact( name: _root_.scala.Option[String] = None, url: _root_.scala.Option[String] = None, email: _root_.scala.Option[String] = None ) /** * Indicates that this particular element is considered deprecated in the API. See * the description for details */ final case class Deprecation( description: _root_.scala.Option[String] = None ) final case class Enum( name: String, plural: String, description: _root_.scala.Option[String] = None, deprecation: _root_.scala.Option[io.apibuilder.spec.v0.models.Deprecation] = None, values: Seq[io.apibuilder.spec.v0.models.EnumValue], attributes: Seq[io.apibuilder.spec.v0.models.Attribute] = Nil ) /** * @param value The actual string representation of this value. If not specified, defaults to * 'name' */ final case class EnumValue( name: String, description: _root_.scala.Option[String] = None, deprecation: _root_.scala.Option[io.apibuilder.spec.v0.models.Deprecation] = None, attributes: Seq[io.apibuilder.spec.v0.models.Attribute] = Nil, value: _root_.scala.Option[String] = None ) final case class Field( name: String, `type`: String, description: _root_.scala.Option[String] = None, deprecation: _root_.scala.Option[io.apibuilder.spec.v0.models.Deprecation] = None, default: _root_.scala.Option[String] = None, required: Boolean, minimum: _root_.scala.Option[Long] = None, maximum: _root_.scala.Option[Long] = None, example: _root_.scala.Option[String] = None, attributes: Seq[io.apibuilder.spec.v0.models.Attribute] = Nil, annotations: Seq[String] = Nil ) final case class Header( name: String, `type`: String, description: _root_.scala.Option[String] = None, deprecation: _root_.scala.Option[io.apibuilder.spec.v0.models.Deprecation] = None, required: Boolean, default: _root_.scala.Option[String] = None, attributes: Seq[io.apibuilder.spec.v0.models.Attribute] = Nil ) /** * An import is used to declare a dependency on another application. This allows * you to reference the models and or enums from that application in your own app. * * @param uri Full URI to the service.json file of the service we are importing * @param namespace the fully qualified namespace that we have imported * @param version The version of the service that we are importing * @param enums Enums made available by this import * @param interfaces Interfaces made available by this import * @param unions Unions made available by this import * @param models Models made available by this import * @param annotations Annotations made available by this import */ final case class Import( uri: String, namespace: String, organization: io.apibuilder.spec.v0.models.Organization, application: io.apibuilder.spec.v0.models.Application, version: String, enums: Seq[String] = Nil, interfaces: Seq[String] = Nil, unions: Seq[String] = Nil, models: Seq[String] = Nil, annotations: Seq[io.apibuilder.spec.v0.models.Annotation] = Nil ) /** * General metadata about this service */ final case class Info( license: _root_.scala.Option[io.apibuilder.spec.v0.models.License] = None, contact: _root_.scala.Option[io.apibuilder.spec.v0.models.Contact] = None ) final case class Interface( name: String, plural: String, description: _root_.scala.Option[String] = None, deprecation: _root_.scala.Option[io.apibuilder.spec.v0.models.Deprecation] = None, fields: Seq[io.apibuilder.spec.v0.models.Field], attributes: Seq[io.apibuilder.spec.v0.models.Attribute] = Nil ) /** * Describes the software license contact for this service */ final case class License( name: String, url: _root_.scala.Option[String] = None ) final case class Model( name: String, plural: String, description: _root_.scala.Option[String] = None, deprecation: _root_.scala.Option[io.apibuilder.spec.v0.models.Deprecation] = None, fields: Seq[io.apibuilder.spec.v0.models.Field], attributes: Seq[io.apibuilder.spec.v0.models.Attribute] = Nil, interfaces: Seq[String] = Nil ) /** * @param path The full path to this operation, relative to the service's base url. */ final case class Operation( method: io.apibuilder.spec.v0.models.Method, path: String, description: _root_.scala.Option[String] = None, deprecation: _root_.scala.Option[io.apibuilder.spec.v0.models.Deprecation] = None, body: _root_.scala.Option[io.apibuilder.spec.v0.models.Body] = None, parameters: Seq[io.apibuilder.spec.v0.models.Parameter] = Nil, responses: Seq[io.apibuilder.spec.v0.models.Response] = Nil, attributes: Seq[io.apibuilder.spec.v0.models.Attribute] = Nil ) /** * @param key Unique key identifying the organization that owns this service */ final case class Organization( key: String ) final case class Parameter( name: String, `type`: String, location: io.apibuilder.spec.v0.models.ParameterLocation, description: _root_.scala.Option[String] = None, deprecation: _root_.scala.Option[io.apibuilder.spec.v0.models.Deprecation] = None, required: Boolean, default: _root_.scala.Option[String] = None, minimum: _root_.scala.Option[Long] = None, maximum: _root_.scala.Option[Long] = None, example: _root_.scala.Option[String] = None, attributes: _root_.scala.Option[Seq[io.apibuilder.spec.v0.models.Attribute]] = None ) /** * @param `type` The type of this resource will map to a defined model, enum, or union type * @param path The path to this specific resource. This was added in 2016 to help us * differentiate between the resource path and the operation path which can be * helpful when, for example, generating method names for operations. This field is * optional as some of our input formats (e.g. swagger) do not explicitly * differentiate resoure paths. */ final case class Resource( `type`: String, plural: String, path: _root_.scala.Option[String] = None, description: _root_.scala.Option[String] = None, deprecation: _root_.scala.Option[io.apibuilder.spec.v0.models.Deprecation] = None, operations: Seq[io.apibuilder.spec.v0.models.Operation], attributes: Seq[io.apibuilder.spec.v0.models.Attribute] = Nil ) final case class Response( code: io.apibuilder.spec.v0.models.ResponseCode, `type`: String, headers: _root_.scala.Option[Seq[io.apibuilder.spec.v0.models.Header]] = None, description: _root_.scala.Option[String] = None, deprecation: _root_.scala.Option[io.apibuilder.spec.v0.models.Deprecation] = None, attributes: _root_.scala.Option[Seq[io.apibuilder.spec.v0.models.Attribute]] = None ) /** * @param apidoc Documents that this is an apibuilder document, noting the specific version used. * Internally the version is then used for backwards compatibility when applicable * as new features are added to apibuilder. Note naming refers to the original name * of this project, 'apidoc', and is left here to avoid a breaking change for * preexisting services. * @param namespace Fully qualified namespace for this service */ final case class Service( @deprecated("This field is no longer used in API Builder and may be removed in the future.") apidoc: _root_.scala.Option[io.apibuilder.spec.v0.models.Apidoc] = None, name: String, organization: io.apibuilder.spec.v0.models.Organization, application: io.apibuilder.spec.v0.models.Application, namespace: String, version: String, baseUrl: _root_.scala.Option[String] = None, description: _root_.scala.Option[String] = None, info: io.apibuilder.spec.v0.models.Info, headers: Seq[io.apibuilder.spec.v0.models.Header] = Nil, imports: Seq[io.apibuilder.spec.v0.models.Import] = Nil, enums: Seq[io.apibuilder.spec.v0.models.Enum] = Nil, interfaces: Seq[io.apibuilder.spec.v0.models.Interface] = Nil, unions: Seq[io.apibuilder.spec.v0.models.Union] = Nil, models: Seq[io.apibuilder.spec.v0.models.Model] = Nil, resources: Seq[io.apibuilder.spec.v0.models.Resource] = Nil, attributes: Seq[io.apibuilder.spec.v0.models.Attribute] = Nil, annotations: Seq[io.apibuilder.spec.v0.models.Annotation] = Nil ) /** * @param discriminator If a type discriminator is provided, serialization of these union types will * always contain a field named with the value of the discriminator that will * contain the name of the type. This provides a simpler (for many use cases) JSON * serialization/deserialization mechanism. When specified, apibuilder itself will * verify that none of the types in the union type itself contain a field with the * same name as the discriminator * @param types The names of the types that make up this union type */ final case class Union( name: String, plural: String, discriminator: _root_.scala.Option[String] = None, description: _root_.scala.Option[String] = None, deprecation: _root_.scala.Option[io.apibuilder.spec.v0.models.Deprecation] = None, types: Seq[io.apibuilder.spec.v0.models.UnionType], attributes: Seq[io.apibuilder.spec.v0.models.Attribute] = Nil, interfaces: Seq[String] = Nil ) /** * Metadata about one of the types that is part of a union type * * @param `type` The name of a type (a primitive, model name, or enum name) that makes up this * union type * @param default If true, indicates that this type should be used as the default when * deserializing union types. This field is only used by union types that require a * discriminator and sets the default value for that discriminator during * deserialization. * @param discriminatorValue The discriminator value defines the string to use in the discriminator field to * identify this type. If not specified, the discriminator value will default to * the name of the type itself. */ final case class UnionType( `type`: String, description: _root_.scala.Option[String] = None, deprecation: _root_.scala.Option[io.apibuilder.spec.v0.models.Deprecation] = None, attributes: Seq[io.apibuilder.spec.v0.models.Attribute] = Nil, default: _root_.scala.Option[Boolean] = None, discriminatorValue: _root_.scala.Option[String] = None ) /** * Provides future compatibility in clients - in the future, when a type is added * to the union ResponseCode, it will need to be handled in the client code. This * implementation will deserialize these future types as an instance of this class. * * @param description Information about the type that we received that is undefined in this version of * the client. */ final case class ResponseCodeUndefinedType( description: String ) extends ResponseCode /** * Wrapper class to support the union types containing the datatype[integer] */ final case class ResponseCodeInt( value: Int ) extends ResponseCode sealed trait Method extends _root_.scala.Product with _root_.scala.Serializable object Method { case object Get extends Method { override def toString = "GET" } case object Post extends Method { override def toString = "POST" } case object Put extends Method { override def toString = "PUT" } case object Patch extends Method { override def toString = "PATCH" } case object Delete extends Method { override def toString = "DELETE" } case object Head extends Method { override def toString = "HEAD" } case object Connect extends Method { override def toString = "CONNECT" } case object Options extends Method { override def toString = "OPTIONS" } case object Trace extends Method { override def toString = "TRACE" } /** * UNDEFINED captures values that are sent either in error or * that were added by the server after this library was * generated. We want to make it easy and obvious for users of * this library to handle this case gracefully. * * We use all CAPS for the variable name to avoid collisions * with the camel cased values above. */ final case class UNDEFINED(override val toString: String) extends Method /** * all returns a list of all the valid, known values. We use * lower case to avoid collisions with the camel cased values * above. */ val all: scala.List[Method] = scala.List(Get, Post, Put, Patch, Delete, Head, Connect, Options, Trace) private val byName: Map[String, Method] = all.map(x => x.toString.toLowerCase -> x).toMap def apply(value: String): Method = fromString(value).getOrElse(UNDEFINED(value)) def fromString(value: String): _root_.scala.Option[Method] = byName.get(value.toLowerCase) } sealed trait ParameterLocation extends _root_.scala.Product with _root_.scala.Serializable object ParameterLocation { case object Path extends ParameterLocation { override def toString = "Path" } case object Query extends ParameterLocation { override def toString = "Query" } case object Form extends ParameterLocation { override def toString = "Form" } case object Header extends ParameterLocation { override def toString = "Header" } /** * UNDEFINED captures values that are sent either in error or * that were added by the server after this library was * generated. We want to make it easy and obvious for users of * this library to handle this case gracefully. * * We use all CAPS for the variable name to avoid collisions * with the camel cased values above. */ final case class UNDEFINED(override val toString: String) extends ParameterLocation /** * all returns a list of all the valid, known values. We use * lower case to avoid collisions with the camel cased values * above. */ val all: scala.List[ParameterLocation] = scala.List(Path, Query, Form, Header) private val byName: Map[String, ParameterLocation] = all.map(x => x.toString.toLowerCase -> x).toMap def apply(value: String): ParameterLocation = fromString(value).getOrElse(UNDEFINED(value)) def fromString(value: String): _root_.scala.Option[ParameterLocation] = byName.get(value.toLowerCase) } sealed trait ResponseCodeOption extends ResponseCode object ResponseCodeOption { case object Default extends ResponseCodeOption { override def toString = "Default" } /** * UNDEFINED captures values that are sent either in error or * that were added by the server after this library was * generated. We want to make it easy and obvious for users of * this library to handle this case gracefully. * * We use all CAPS for the variable name to avoid collisions * with the camel cased values above. */ final case class UNDEFINED(override val toString: String) extends ResponseCodeOption /** * all returns a list of all the valid, known values. We use * lower case to avoid collisions with the camel cased values * above. */ val all: scala.List[ResponseCodeOption] = scala.List(Default) private val byName: Map[String, ResponseCodeOption] = all.map(x => x.toString.toLowerCase -> x).toMap def apply(value: String): ResponseCodeOption = fromString(value).getOrElse(UNDEFINED(value)) def fromString(value: String): _root_.scala.Option[ResponseCodeOption] = byName.get(value.toLowerCase) } } package io.apibuilder.spec.v0.models { package object json { import io.circe.Decoder._ import io.circe.Encoder._ import scala.language.implicitConversions // See below - Make Scala 2.11 Either monadic import scala.util.Try import io.circe.{Json, JsonObject, Encoder, Decoder, DecodingFailure} import io.circe.syntax._ import io.apibuilder.spec.v0.models.json._ // Make Scala 2.11 Either monadic private[v0] implicit def eitherOps[A,B](e: Either[A,B]) = cats.implicits.catsSyntaxEither(e) private[v0] implicit val decodeUUID: Decoder[_root_.java.util.UUID] = Decoder.decodeString.emapTry(str => Try(_root_.java.util.UUID.fromString(str))) private[v0] implicit val encodeUUID: Encoder[_root_.java.util.UUID] = Encoder.encodeString.contramap[_root_.java.util.UUID](uuid => uuid.toString) private[v0] implicit val decodeInstant: Decoder[_root_.java.time.Instant] = Decoder.decodeString.emapTry(str => Try(_root_.java.time.OffsetDateTime.parse(str).toInstant)) private[v0] implicit val encodeInstant: Encoder[_root_.java.time.Instant] = Encoder.encodeString.contramap[_root_.java.time.Instant](_.toString) private[v0] implicit val decodeLocalDate: Decoder[_root_.java.time.LocalDate] = Decoder.decodeString.emapTry(str => Try(_root_.java.time.LocalDate.parse(str))) private[v0] implicit val encodeLocalDate: Encoder[_root_.java.time.LocalDate] = Encoder.encodeString.contramap[_root_.java.time.LocalDate](_.toString) implicit val jsonDecoderApibuilderSpecMethod: Decoder[io.apibuilder.spec.v0.models.Method] = Decoder.decodeString.map(io.apibuilder.spec.v0.models.Method(_)) implicit val jsonEncoderApibuilderSpecMethod: Encoder[io.apibuilder.spec.v0.models.Method] = Encoder.encodeString.contramap[io.apibuilder.spec.v0.models.Method](_.toString) implicit val jsonDecoderApibuilderSpecParameterLocation: Decoder[io.apibuilder.spec.v0.models.ParameterLocation] = Decoder.decodeString.map(io.apibuilder.spec.v0.models.ParameterLocation(_)) implicit val jsonEncoderApibuilderSpecParameterLocation: Encoder[io.apibuilder.spec.v0.models.ParameterLocation] = Encoder.encodeString.contramap[io.apibuilder.spec.v0.models.ParameterLocation](_.toString) implicit val jsonDecoderApibuilderSpecResponseCodeOption: Decoder[io.apibuilder.spec.v0.models.ResponseCodeOption] = Decoder.decodeString.map(io.apibuilder.spec.v0.models.ResponseCodeOption(_)) implicit val jsonEncoderApibuilderSpecResponseCodeOption: Encoder[io.apibuilder.spec.v0.models.ResponseCodeOption] = Encoder.encodeString.contramap[io.apibuilder.spec.v0.models.ResponseCodeOption](_.toString) implicit def decodeApibuilderSpecAnnotation: Decoder[Annotation] = Decoder.instance { c => for { name <- c.downField("name").as[String] description <- c.downField("description").as[Option[String]] deprecation <- c.downField("deprecation").as[Option[io.apibuilder.spec.v0.models.Deprecation]] } yield { Annotation( name = name, description = description, deprecation = deprecation ) } } implicit def encodeApibuilderSpecAnnotation: Encoder[Annotation] = Encoder.instance { t => Json.fromFields(Seq( Some("name" -> t.name.asJson), t.description.map(t => "description" -> t.asJson), t.deprecation.map(t => "deprecation" -> t.asJson) ).flatten) } implicit def decodeApibuilderSpecApidoc: Decoder[Apidoc] = Decoder.instance { c => for { version <- c.downField("version").as[String] } yield { Apidoc( version = version ) } } implicit def encodeApibuilderSpecApidoc: Encoder[Apidoc] = Encoder.instance { t => Json.fromFields(Seq( Some("version" -> t.version.asJson) ).flatten) } implicit def decodeApibuilderSpecApplication: Decoder[Application] = Decoder.instance { c => for { key <- c.downField("key").as[String] } yield { Application( key = key ) } } implicit def encodeApibuilderSpecApplication: Encoder[Application] = Encoder.instance { t => Json.fromFields(Seq( Some("key" -> t.key.asJson) ).flatten) } implicit def decodeApibuilderSpecAttribute: Decoder[Attribute] = Decoder.instance { c => for { name <- c.downField("name").as[String] value <- c.downField("value").as[Map[String, _root_.io.circe.Json]] description <- c.downField("description").as[Option[String]] deprecation <- c.downField("deprecation").as[Option[io.apibuilder.spec.v0.models.Deprecation]] } yield { Attribute( name = name, value = value, description = description, deprecation = deprecation ) } } implicit def encodeApibuilderSpecAttribute: Encoder[Attribute] = Encoder.instance { t => Json.fromFields(Seq( Some("name" -> t.name.asJson), Some("value" -> t.value.asJson), t.description.map(t => "description" -> t.asJson), t.deprecation.map(t => "deprecation" -> t.asJson) ).flatten) } implicit def decodeApibuilderSpecBody: Decoder[Body] = Decoder.instance { c => for { __type__ <- c.downField("type").as[String] description <- c.downField("description").as[Option[String]] deprecation <- c.downField("deprecation").as[Option[io.apibuilder.spec.v0.models.Deprecation]] attributes <- c.downField("attributes").as[Seq[io.apibuilder.spec.v0.models.Attribute]] } yield { Body( `type` = __type__, description = description, deprecation = deprecation, attributes = attributes ) } } implicit def encodeApibuilderSpecBody: Encoder[Body] = Encoder.instance { t => Json.fromFields(Seq( Some("type" -> t.`type`.asJson), t.description.map(t => "description" -> t.asJson), t.deprecation.map(t => "deprecation" -> t.asJson), Some("attributes" -> t.attributes.asJson) ).flatten) } implicit def decodeApibuilderSpecContact: Decoder[Contact] = Decoder.instance { c => for { name <- c.downField("name").as[Option[String]] url <- c.downField("url").as[Option[String]] email <- c.downField("email").as[Option[String]] } yield { Contact( name = name, url = url, email = email ) } } implicit def encodeApibuilderSpecContact: Encoder[Contact] = Encoder.instance { t => Json.fromFields(Seq( t.name.map(t => "name" -> t.asJson), t.url.map(t => "url" -> t.asJson), t.email.map(t => "email" -> t.asJson) ).flatten) } implicit def decodeApibuilderSpecDeprecation: Decoder[Deprecation] = Decoder.instance { c => for { description <- c.downField("description").as[Option[String]] } yield { Deprecation( description = description ) } } implicit def encodeApibuilderSpecDeprecation: Encoder[Deprecation] = Encoder.instance { t => Json.fromFields(Seq( t.description.map(t => "description" -> t.asJson) ).flatten) } implicit def decodeApibuilderSpecEnum: Decoder[Enum] = Decoder.instance { c => for { name <- c.downField("name").as[String] plural <- c.downField("plural").as[String] description <- c.downField("description").as[Option[String]] deprecation <- c.downField("deprecation").as[Option[io.apibuilder.spec.v0.models.Deprecation]] values <- c.downField("values").as[Seq[io.apibuilder.spec.v0.models.EnumValue]] attributes <- c.downField("attributes").as[Seq[io.apibuilder.spec.v0.models.Attribute]] } yield { Enum( name = name, plural = plural, description = description, deprecation = deprecation, values = values, attributes = attributes ) } } implicit def encodeApibuilderSpecEnum: Encoder[Enum] = Encoder.instance { t => Json.fromFields(Seq( Some("name" -> t.name.asJson), Some("plural" -> t.plural.asJson), t.description.map(t => "description" -> t.asJson), t.deprecation.map(t => "deprecation" -> t.asJson), Some("values" -> t.values.asJson), Some("attributes" -> t.attributes.asJson) ).flatten) } implicit def decodeApibuilderSpecEnumValue: Decoder[EnumValue] = Decoder.instance { c => for { name <- c.downField("name").as[String] description <- c.downField("description").as[Option[String]] deprecation <- c.downField("deprecation").as[Option[io.apibuilder.spec.v0.models.Deprecation]] attributes <- c.downField("attributes").as[Seq[io.apibuilder.spec.v0.models.Attribute]] value <- c.downField("value").as[Option[String]] } yield { EnumValue( name = name, description = description, deprecation = deprecation, attributes = attributes, value = value ) } } implicit def encodeApibuilderSpecEnumValue: Encoder[EnumValue] = Encoder.instance { t => Json.fromFields(Seq( Some("name" -> t.name.asJson), t.description.map(t => "description" -> t.asJson), t.deprecation.map(t => "deprecation" -> t.asJson), Some("attributes" -> t.attributes.asJson), t.value.map(t => "value" -> t.asJson) ).flatten) } implicit def decodeApibuilderSpecField: Decoder[Field] = Decoder.instance { c => for { name <- c.downField("name").as[String] __type__ <- c.downField("type").as[String] description <- c.downField("description").as[Option[String]] deprecation <- c.downField("deprecation").as[Option[io.apibuilder.spec.v0.models.Deprecation]] default <- c.downField("default").as[Option[String]] required <- c.downField("required").as[Boolean] minimum <- c.downField("minimum").as[Option[Long]] maximum <- c.downField("maximum").as[Option[Long]] example <- c.downField("example").as[Option[String]] attributes <- c.downField("attributes").as[Seq[io.apibuilder.spec.v0.models.Attribute]] annotations <- c.downField("annotations").as[Option[Seq[String]]] } yield { Field( name = name, `type` = __type__, description = description, deprecation = deprecation, default = default, required = required, minimum = minimum, maximum = maximum, example = example, attributes = attributes, annotations = annotations.getOrElse(Nil) ) } } implicit def encodeApibuilderSpecField: Encoder[Field] = Encoder.instance { t => Json.fromFields(Seq( Some("name" -> t.name.asJson), Some("type" -> t.`type`.asJson), t.description.map(t => "description" -> t.asJson), t.deprecation.map(t => "deprecation" -> t.asJson), t.default.map(t => "default" -> t.asJson), Some("required" -> t.required.asJson), t.minimum.map(t => "minimum" -> t.asJson), t.maximum.map(t => "maximum" -> t.asJson), t.example.map(t => "example" -> t.asJson), Some("attributes" -> t.attributes.asJson), Some("annotations" -> t.annotations.asJson) ).flatten) } implicit def decodeApibuilderSpecHeader: Decoder[Header] = Decoder.instance { c => for { name <- c.downField("name").as[String] __type__ <- c.downField("type").as[String] description <- c.downField("description").as[Option[String]] deprecation <- c.downField("deprecation").as[Option[io.apibuilder.spec.v0.models.Deprecation]] required <- c.downField("required").as[Boolean] default <- c.downField("default").as[Option[String]] attributes <- c.downField("attributes").as[Seq[io.apibuilder.spec.v0.models.Attribute]] } yield { Header( name = name, `type` = __type__, description = description, deprecation = deprecation, required = required, default = default, attributes = attributes ) } } implicit def encodeApibuilderSpecHeader: Encoder[Header] = Encoder.instance { t => Json.fromFields(Seq( Some("name" -> t.name.asJson), Some("type" -> t.`type`.asJson), t.description.map(t => "description" -> t.asJson), t.deprecation.map(t => "deprecation" -> t.asJson), Some("required" -> t.required.asJson), t.default.map(t => "default" -> t.asJson), Some("attributes" -> t.attributes.asJson) ).flatten) } implicit def decodeApibuilderSpecImport: Decoder[Import] = Decoder.instance { c => for { uri <- c.downField("uri").as[String] namespace <- c.downField("namespace").as[String] organization <- c.downField("organization").as[io.apibuilder.spec.v0.models.Organization] application <- c.downField("application").as[io.apibuilder.spec.v0.models.Application] version <- c.downField("version").as[String] enums <- c.downField("enums").as[Seq[String]] interfaces <- c.downField("interfaces").as[Option[Seq[String]]] unions <- c.downField("unions").as[Seq[String]] models <- c.downField("models").as[Seq[String]] annotations <- c.downField("annotations").as[Option[Seq[io.apibuilder.spec.v0.models.Annotation]]] } yield { Import( uri = uri, namespace = namespace, organization = organization, application = application, version = version, enums = enums, interfaces = interfaces.getOrElse(Nil), unions = unions, models = models, annotations = annotations.getOrElse(Nil) ) } } implicit def encodeApibuilderSpecImport: Encoder[Import] = Encoder.instance { t => Json.fromFields(Seq( Some("uri" -> t.uri.asJson), Some("namespace" -> t.namespace.asJson), Some("organization" -> t.organization.asJson), Some("application" -> t.application.asJson), Some("version" -> t.version.asJson), Some("enums" -> t.enums.asJson), Some("interfaces" -> t.interfaces.asJson), Some("unions" -> t.unions.asJson), Some("models" -> t.models.asJson), Some("annotations" -> t.annotations.asJson) ).flatten) } implicit def decodeApibuilderSpecInfo: Decoder[Info] = Decoder.instance { c => for { license <- c.downField("license").as[Option[io.apibuilder.spec.v0.models.License]] contact <- c.downField("contact").as[Option[io.apibuilder.spec.v0.models.Contact]] } yield { Info( license = license, contact = contact ) } } implicit def encodeApibuilderSpecInfo: Encoder[Info] = Encoder.instance { t => Json.fromFields(Seq( t.license.map(t => "license" -> t.asJson), t.contact.map(t => "contact" -> t.asJson) ).flatten) } implicit def decodeApibuilderSpecInterface: Decoder[Interface] = Decoder.instance { c => for { name <- c.downField("name").as[String] plural <- c.downField("plural").as[String] description <- c.downField("description").as[Option[String]] deprecation <- c.downField("deprecation").as[Option[io.apibuilder.spec.v0.models.Deprecation]] fields <- c.downField("fields").as[Seq[io.apibuilder.spec.v0.models.Field]] attributes <- c.downField("attributes").as[Seq[io.apibuilder.spec.v0.models.Attribute]] } yield { Interface( name = name, plural = plural, description = description, deprecation = deprecation, fields = fields, attributes = attributes ) } } implicit def encodeApibuilderSpecInterface: Encoder[Interface] = Encoder.instance { t => Json.fromFields(Seq( Some("name" -> t.name.asJson), Some("plural" -> t.plural.asJson), t.description.map(t => "description" -> t.asJson), t.deprecation.map(t => "deprecation" -> t.asJson), Some("fields" -> t.fields.asJson), Some("attributes" -> t.attributes.asJson) ).flatten) } implicit def decodeApibuilderSpecLicense: Decoder[License] = Decoder.instance { c => for { name <- c.downField("name").as[String] url <- c.downField("url").as[Option[String]] } yield { License( name = name, url = url ) } } implicit def encodeApibuilderSpecLicense: Encoder[License] = Encoder.instance { t => Json.fromFields(Seq( Some("name" -> t.name.asJson), t.url.map(t => "url" -> t.asJson) ).flatten) } implicit def decodeApibuilderSpecModel: Decoder[Model] = Decoder.instance { c => for { name <- c.downField("name").as[String] plural <- c.downField("plural").as[String] description <- c.downField("description").as[Option[String]] deprecation <- c.downField("deprecation").as[Option[io.apibuilder.spec.v0.models.Deprecation]] fields <- c.downField("fields").as[Seq[io.apibuilder.spec.v0.models.Field]] attributes <- c.downField("attributes").as[Seq[io.apibuilder.spec.v0.models.Attribute]] interfaces <- c.downField("interfaces").as[Option[Seq[String]]] } yield { Model( name = name, plural = plural, description = description, deprecation = deprecation, fields = fields, attributes = attributes, interfaces = interfaces.getOrElse(Nil) ) } } implicit def encodeApibuilderSpecModel: Encoder[Model] = Encoder.instance { t => Json.fromFields(Seq( Some("name" -> t.name.asJson), Some("plural" -> t.plural.asJson), t.description.map(t => "description" -> t.asJson), t.deprecation.map(t => "deprecation" -> t.asJson), Some("fields" -> t.fields.asJson), Some("attributes" -> t.attributes.asJson), Some("interfaces" -> t.interfaces.asJson) ).flatten) } implicit def decodeApibuilderSpecOperation: Decoder[Operation] = Decoder.instance { c => for { method <- c.downField("method").as[io.apibuilder.spec.v0.models.Method] path <- c.downField("path").as[String] description <- c.downField("description").as[Option[String]] deprecation <- c.downField("deprecation").as[Option[io.apibuilder.spec.v0.models.Deprecation]] body <- c.downField("body").as[Option[io.apibuilder.spec.v0.models.Body]] parameters <- c.downField("parameters").as[Seq[io.apibuilder.spec.v0.models.Parameter]] responses <- c.downField("responses").as[Seq[io.apibuilder.spec.v0.models.Response]] attributes <- c.downField("attributes").as[Seq[io.apibuilder.spec.v0.models.Attribute]] } yield { Operation( method = method, path = path, description = description, deprecation = deprecation, body = body, parameters = parameters, responses = responses, attributes = attributes ) } } implicit def encodeApibuilderSpecOperation: Encoder[Operation] = Encoder.instance { t => Json.fromFields(Seq( Some("method" -> t.method.asJson), Some("path" -> t.path.asJson), t.description.map(t => "description" -> t.asJson), t.deprecation.map(t => "deprecation" -> t.asJson), t.body.map(t => "body" -> t.asJson), Some("parameters" -> t.parameters.asJson), Some("responses" -> t.responses.asJson), Some("attributes" -> t.attributes.asJson) ).flatten) } implicit def decodeApibuilderSpecOrganization: Decoder[Organization] = Decoder.instance { c => for { key <- c.downField("key").as[String] } yield { Organization( key = key ) } } implicit def encodeApibuilderSpecOrganization: Encoder[Organization] = Encoder.instance { t => Json.fromFields(Seq( Some("key" -> t.key.asJson) ).flatten) } implicit def decodeApibuilderSpecParameter: Decoder[Parameter] = Decoder.instance { c => for { name <- c.downField("name").as[String] __type__ <- c.downField("type").as[String] location <- c.downField("location").as[io.apibuilder.spec.v0.models.ParameterLocation] description <- c.downField("description").as[Option[String]] deprecation <- c.downField("deprecation").as[Option[io.apibuilder.spec.v0.models.Deprecation]] required <- c.downField("required").as[Boolean] default <- c.downField("default").as[Option[String]] minimum <- c.downField("minimum").as[Option[Long]] maximum <- c.downField("maximum").as[Option[Long]] example <- c.downField("example").as[Option[String]] attributes <- c.downField("attributes").as[Option[Seq[io.apibuilder.spec.v0.models.Attribute]]] } yield { Parameter( name = name, `type` = __type__, location = location, description = description, deprecation = deprecation, required = required, default = default, minimum = minimum, maximum = maximum, example = example, attributes = attributes ) } } implicit def encodeApibuilderSpecParameter: Encoder[Parameter] = Encoder.instance { t => Json.fromFields(Seq( Some("name" -> t.name.asJson), Some("type" -> t.`type`.asJson), Some("location" -> t.location.asJson), t.description.map(t => "description" -> t.asJson), t.deprecation.map(t => "deprecation" -> t.asJson), Some("required" -> t.required.asJson), t.default.map(t => "default" -> t.asJson), t.minimum.map(t => "minimum" -> t.asJson), t.maximum.map(t => "maximum" -> t.asJson), t.example.map(t => "example" -> t.asJson), t.attributes.map(t => "attributes" -> t.asJson) ).flatten) } implicit def decodeApibuilderSpecResource: Decoder[Resource] = Decoder.instance { c => for { __type__ <- c.downField("type").as[String] plural <- c.downField("plural").as[String] path <- c.downField("path").as[Option[String]] description <- c.downField("description").as[Option[String]] deprecation <- c.downField("deprecation").as[Option[io.apibuilder.spec.v0.models.Deprecation]] operations <- c.downField("operations").as[Seq[io.apibuilder.spec.v0.models.Operation]] attributes <- c.downField("attributes").as[Seq[io.apibuilder.spec.v0.models.Attribute]] } yield { Resource( `type` = __type__, plural = plural, path = path, description = description, deprecation = deprecation, operations = operations, attributes = attributes ) } } implicit def encodeApibuilderSpecResource: Encoder[Resource] = Encoder.instance { t => Json.fromFields(Seq( Some("type" -> t.`type`.asJson), Some("plural" -> t.plural.asJson), t.path.map(t => "path" -> t.asJson), t.description.map(t => "description" -> t.asJson), t.deprecation.map(t => "deprecation" -> t.asJson), Some("operations" -> t.operations.asJson), Some("attributes" -> t.attributes.asJson) ).flatten) } implicit def decodeApibuilderSpecResponse: Decoder[Response] = Decoder.instance { c => for { code <- c.downField("code").as[io.apibuilder.spec.v0.models.ResponseCode] __type__ <- c.downField("type").as[String] headers <- c.downField("headers").as[Option[Seq[io.apibuilder.spec.v0.models.Header]]] description <- c.downField("description").as[Option[String]] deprecation <- c.downField("deprecation").as[Option[io.apibuilder.spec.v0.models.Deprecation]] attributes <- c.downField("attributes").as[Option[Seq[io.apibuilder.spec.v0.models.Attribute]]] } yield { Response( code = code, `type` = __type__, headers = headers, description = description, deprecation = deprecation, attributes = attributes ) } } implicit def encodeApibuilderSpecResponse: Encoder[Response] = Encoder.instance { t => Json.fromFields(Seq( Some("code" -> t.code.asJson), Some("type" -> t.`type`.asJson), t.headers.map(t => "headers" -> t.asJson), t.description.map(t => "description" -> t.asJson), t.deprecation.map(t => "deprecation" -> t.asJson), t.attributes.map(t => "attributes" -> t.asJson) ).flatten) } implicit def decodeApibuilderSpecService: Decoder[Service] = Decoder.instance { c => for { apidoc <- c.downField("apidoc").as[Option[io.apibuilder.spec.v0.models.Apidoc]] name <- c.downField("name").as[String] organization <- c.downField("organization").as[io.apibuilder.spec.v0.models.Organization] application <- c.downField("application").as[io.apibuilder.spec.v0.models.Application] namespace <- c.downField("namespace").as[String] version <- c.downField("version").as[String] baseUrl <- c.downField("base_url").as[Option[String]] description <- c.downField("description").as[Option[String]] info <- c.downField("info").as[io.apibuilder.spec.v0.models.Info] headers <- c.downField("headers").as[Seq[io.apibuilder.spec.v0.models.Header]] imports <- c.downField("imports").as[Seq[io.apibuilder.spec.v0.models.Import]] enums <- c.downField("enums").as[Seq[io.apibuilder.spec.v0.models.Enum]] interfaces <- c.downField("interfaces").as[Option[Seq[io.apibuilder.spec.v0.models.Interface]]] unions <- c.downField("unions").as[Seq[io.apibuilder.spec.v0.models.Union]] models <- c.downField("models").as[Seq[io.apibuilder.spec.v0.models.Model]] resources <- c.downField("resources").as[Seq[io.apibuilder.spec.v0.models.Resource]] attributes <- c.downField("attributes").as[Seq[io.apibuilder.spec.v0.models.Attribute]] annotations <- c.downField("annotations").as[Option[Seq[io.apibuilder.spec.v0.models.Annotation]]] } yield { Service( apidoc = apidoc, name = name, organization = organization, application = application, namespace = namespace, version = version, baseUrl = baseUrl, description = description, info = info, headers = headers, imports = imports, enums = enums, interfaces = interfaces.getOrElse(Nil), unions = unions, models = models, resources = resources, attributes = attributes, annotations = annotations.getOrElse(Nil) ) } } implicit def encodeApibuilderSpecService: Encoder[Service] = Encoder.instance { t => Json.fromFields(Seq( t.apidoc.map(t => "apidoc" -> t.asJson), Some("name" -> t.name.asJson), Some("organization" -> t.organization.asJson), Some("application" -> t.application.asJson), Some("namespace" -> t.namespace.asJson), Some("version" -> t.version.asJson), t.baseUrl.map(t => "base_url" -> t.asJson), t.description.map(t => "description" -> t.asJson), Some("info" -> t.info.asJson), Some("headers" -> t.headers.asJson), Some("imports" -> t.imports.asJson), Some("enums" -> t.enums.asJson), Some("interfaces" -> t.interfaces.asJson), Some("unions" -> t.unions.asJson), Some("models" -> t.models.asJson), Some("resources" -> t.resources.asJson), Some("attributes" -> t.attributes.asJson), Some("annotations" -> t.annotations.asJson) ).flatten) } implicit def decodeApibuilderSpecUnion: Decoder[Union] = Decoder.instance { c => for { name <- c.downField("name").as[String] plural <- c.downField("plural").as[String] discriminator <- c.downField("discriminator").as[Option[String]] description <- c.downField("description").as[Option[String]] deprecation <- c.downField("deprecation").as[Option[io.apibuilder.spec.v0.models.Deprecation]] types <- c.downField("types").as[Seq[io.apibuilder.spec.v0.models.UnionType]] attributes <- c.downField("attributes").as[Seq[io.apibuilder.spec.v0.models.Attribute]] interfaces <- c.downField("interfaces").as[Option[Seq[String]]] } yield { Union( name = name, plural = plural, discriminator = discriminator, description = description, deprecation = deprecation, types = types, attributes = attributes, interfaces = interfaces.getOrElse(Nil) ) } } implicit def encodeApibuilderSpecUnion: Encoder[Union] = Encoder.instance { t => Json.fromFields(Seq( Some("name" -> t.name.asJson), Some("plural" -> t.plural.asJson), t.discriminator.map(t => "discriminator" -> t.asJson), t.description.map(t => "description" -> t.asJson), t.deprecation.map(t => "deprecation" -> t.asJson), Some("types" -> t.types.asJson), Some("attributes" -> t.attributes.asJson), Some("interfaces" -> t.interfaces.asJson) ).flatten) } implicit def decodeApibuilderSpecUnionType: Decoder[UnionType] = Decoder.instance { c => for { __type__ <- c.downField("type").as[String] description <- c.downField("description").as[Option[String]] deprecation <- c.downField("deprecation").as[Option[io.apibuilder.spec.v0.models.Deprecation]] attributes <- c.downField("attributes").as[Seq[io.apibuilder.spec.v0.models.Attribute]] default <- c.downField("default").as[Option[Boolean]] discriminatorValue <- c.downField("discriminator_value").as[Option[String]] } yield { UnionType( `type` = __type__, description = description, deprecation = deprecation, attributes = attributes, default = default, discriminatorValue = discriminatorValue ) } } implicit def encodeApibuilderSpecUnionType: Encoder[UnionType] = Encoder.instance { t => Json.fromFields(Seq( Some("type" -> t.`type`.asJson), t.description.map(t => "description" -> t.asJson), t.deprecation.map(t => "deprecation" -> t.asJson), Some("attributes" -> t.attributes.asJson), t.default.map(t => "default" -> t.asJson), t.discriminatorValue.map(t => "discriminator_value" -> t.asJson) ).flatten) } implicit def decodeApibuilderSpecResponseCodeInt: Decoder[ResponseCodeInt] = Decoder.instance { c => for { value <- c.downField("value").as[Int] } yield { ResponseCodeInt( value = value ) } } implicit def encodeApibuilderSpecResponseCodeInt: Encoder[ResponseCodeInt] = Encoder.instance { t => Json.fromFields(Seq( Some("value" -> t.value.asJson) ).flatten) } implicit def decodeApibuilderSpecResponseCode: Decoder[ResponseCode] = Decoder.instance { c => c.get[io.apibuilder.spec.v0.models.ResponseCodeInt]("integer") orElse c.get[io.apibuilder.spec.v0.models.ResponseCodeOption]("response_code_option") orElse Right(io.apibuilder.spec.v0.models.ResponseCodeUndefinedType(c.value.toString)) } implicit def encodeApibuilderSpecResponseCode: Encoder[ResponseCode] = Encoder.instance { case t: io.apibuilder.spec.v0.models.ResponseCodeInt => Json.fromJsonObject(JsonObject.singleton("integer", t.asJson)) case t: io.apibuilder.spec.v0.models.ResponseCodeOption => Json.fromJsonObject(JsonObject.singleton("response_code_option", t.asJson)) case other => sys.error(s"The type[${other.getClass.getName}] has no JSON encoder") } } } package io.apibuilder.spec.v0 { import cats.effect._ import cats.implicits._ import io.circe.syntax._ object Constants { val Namespace = "io.apibuilder.spec.v0" val UserAgent = "apibuilder app.apibuilder.io/apicollective/apibuilder-spec/0.16.53/http4s_0_22" val Version = "0.16.53" val VersionMajor = 0 } class Client[F[_]: Sync]( val baseUrl: org.http4s.Uri, auth: scala.Option[io.apibuilder.spec.v0.Authorization] = None, defaultHeaders: Seq[(String, String)] = Nil, httpClient: org.http4s.client.Client[F] ) extends interfaces.Client[F] { import org.http4s.Response import io.apibuilder.spec.v0.models.json._ private lazy val defaultApiHeaders = Seq( ("User-Agent", Constants.UserAgent), ("X-Apidoc-Version", Constants.Version), ("X-Apidoc-Version-Major", Constants.VersionMajor.toString) ) def apiHeaders: Seq[(String, String)] = defaultApiHeaders def modifyRequest(request: org.http4s.Request[F]): org.http4s.Request[F] = request implicit def circeJsonEncoder[F[_]: Sync, A](implicit encoder: io.circe.Encoder[A]) = org.http4s.circe.jsonEncoderOf[F, A] def _executeRequest[T, U]( method: String, path: Seq[String], queryParameters: Seq[(String, String)] = Nil, requestHeaders: Seq[(String, String)] = Nil, body: Option[T] = None, formBody : Option[org.http4s.UrlForm] = None )(handler: org.http4s.Response[F] => F[U] )(implicit encoder: io.circe.Encoder[T]): F[U] = { import org.http4s.QueryParamEncoder._ val m = org.http4s.Method.fromString(method) match { case Right(m) => m case Left(e) => sys.error(e.toString) } val headers = org.http4s.Headers(( apiHeaders ++ defaultHeaders ++ requestHeaders ).groupBy(_._1).map { case (k, l) => org.http4s.Header.Raw(org.typelevel.ci.CIString(k), l.last._2) }.toList) val queryMap = queryParameters.groupBy(_._1).map { case (k, v) => k -> v.map(_._2) } val uri = path.foldLeft(baseUrl){ case (uri, segment) => uri / segment }.setQueryParams(queryMap) val request = org.http4s.Request[F](method = m, uri = uri, headers = headers) val reqAndMaybeAuth = auth.fold(request) { case Authorization.Basic(username, passwordOpt) => { val userpass = s"$username:${passwordOpt.getOrElse("")}" val token = java.util.Base64.getEncoder.encodeToString(userpass.getBytes(java.nio.charset.StandardCharsets.ISO_8859_1)) request.putHeaders(org.http4s.Header.Raw(org.typelevel.ci.CIString("Authorization"), s"Basic $token")) } case a => sys.error("Invalid authorization scheme[" + a.getClass + "]") } val reqAndMaybeAuthAndBody = if (formBody.nonEmpty) formBody.fold(reqAndMaybeAuth)(reqAndMaybeAuth.withEntity) else body.fold(reqAndMaybeAuth)(reqAndMaybeAuth.withEntity) httpClient.fetch(modifyRequest(reqAndMaybeAuthAndBody))(handler) } } object Client { import cats.effect._ implicit def circeJsonDecoder[F[_]: Sync, A](implicit decoder: io.circe.Decoder[A]) = org.http4s.circe.jsonOf[F, A] def parseJson[F[_]: Sync, T]( className: String, r: org.http4s.Response[F] )(implicit decoder: io.circe.Decoder[T]): F[T] = r.attemptAs[T].value.flatMap { case Right(value) => Sync[F].pure(value) case Left(error) => Sync[F].raiseError(new io.apibuilder.spec.v0.errors.FailedRequest(r.status.code, s"Invalid json for class[" + className + "]", None, error)) } } sealed trait Authorization extends _root_.scala.Product with _root_.scala.Serializable object Authorization { final case class Basic(username: String, password: Option[String] = None) extends Authorization } package interfaces { trait Client[F[_]] { def baseUrl: org.http4s.Uri } } package errors { final case class FailedRequest(responseCode: Int, message: String, requestUri: Option[_root_.java.net.URI] = None, parent: Exception = null) extends _root_.java.lang.Exception(s"HTTP $responseCode: $message", parent) } }