schema
  @link(url: "https://specs.apollo.dev/link/v1.0")
  @link(url: "https://specs.apollo.dev/join/v0.3", for: EXECUTION) {
  query: Query
  mutation: Mutation
}

directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE

directive @join__field(
  graph: join__Graph
  requires: join__FieldSet
  provides: join__FieldSet
  type: String
  external: Boolean
  override: String
  usedOverridden: Boolean
) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION

directive @join__graph(name: String!, url: String!) on ENUM_VALUE

directive @join__implements(
  graph: join__Graph!
  interface: String!
) repeatable on OBJECT | INTERFACE

directive @join__type(
  graph: join__Graph!
  key: join__FieldSet
  extension: Boolean! = false
  resolvable: Boolean! = true
  isInterfaceObject: Boolean! = false
) repeatable on OBJECT | INTERFACE | UNION | ENUM | INPUT_OBJECT | SCALAR

directive @join__unionMember(
  graph: join__Graph!
  member: String!
) repeatable on UNION

directive @link(
  url: String
  as: String
  for: link__Purpose
  import: [link__Import]
) repeatable on SCHEMA

scalar join__FieldSet

enum join__Graph {
  ACCOUNTS @join__graph(name: "accounts", url: "http://accounts")
  BOOKS @join__graph(name: "books", url: "http://books")
  DOCUMENTS @join__graph(name: "documents", url: "http://documents")
  INVENTORY @join__graph(name: "inventory", url: "http://inventory")
  PRODUCT @join__graph(name: "product", url: "http://products")
  REVIEWS @join__graph(name: "reviews", url: "http://reviews")
}

scalar link__Import

enum link__Purpose {
  SECURITY
  EXECUTION
}
directive @stream on FIELD

directive @transform(from: String!) on FIELD

union AccountType @join__type(graph: ACCOUNTS) = PasswordAccount | SMSAccount

type Amazon @join__type(graph: PRODUCT, key: "referrer") {
  referrer: String
}

union Body @join__type(graph: DOCUMENTS) = Image | Text

type Book implements Product
  @join__type(graph: BOOKS, key: "isbn")
  @join__type(graph: INVENTORY, key: "isbn")
  @join__type(graph: PRODUCT, key: "isbn")
  @join__type(graph: REVIEWS, key: "isbn") {
  isbn: String!
    @join__field(graph: BOOKS)
    @join__field(graph: REVIEWS, external: true)
    @join__field(graph: INVENTORY, external: true)
    @join__field(graph: PRODUCT, external: true)
  title: String
    @join__field(graph: BOOKS)
    @join__field(graph: PRODUCT, external: true)
  year: Int
    @join__field(graph: BOOKS)
    @join__field(graph: PRODUCT, external: true)
  similarBooks: [Book]!
    @join__field(graph: BOOKS)
    @join__field(graph: REVIEWS, external: true)
  metadata: [MetadataOrError] @join__field(graph: BOOKS)
  inStock: Boolean @join__field(graph: INVENTORY)
  isCheckedOut: Boolean @join__field(graph: INVENTORY)
  upc: String! @join__field(graph: PRODUCT)
  sku: String! @join__field(graph: PRODUCT)
  name(delimeter: String = " "): String
    @join__field(graph: PRODUCT, requires: "title year")
  price: String @join__field(graph: PRODUCT)
  details: ProductDetailsBook @join__field(graph: PRODUCT)
  reviews: [Review] @join__field(graph: REVIEWS)
  relatedReviews: [Review!]!
    @join__field(graph: REVIEWS, requires: "similarBooks{isbn}")
}

union Brand @join__type(graph: PRODUCT) = Ikea | Amazon

type Car implements Vehicle
  @join__type(graph: PRODUCT, key: "id")
  @join__type(graph: REVIEWS, key: "id") {
  id: String! @join__field(graph: PRODUCT) @join__field(graph: REVIEWS)
  description: String @join__field(graph: PRODUCT)
  price: String
    @join__field(graph: PRODUCT)
    @join__field(graph: REVIEWS, external: true)
  retailPrice: String @join__field(graph: REVIEWS, requires: "price")
}

type Error
  @join__type(graph: REVIEWS, key: "code")
  @join__type(graph: PRODUCT, key: "code")
  @join__type(graph: BOOKS, key: "code") {
  code: Int
  message: String
}

type Furniture implements Product
  @join__type(graph: PRODUCT, key: "upc")
  @join__type(graph: PRODUCT, key: "sku")
  @join__type(graph: INVENTORY, key: "sku")
  @join__type(graph: REVIEWS, key: "upc") {
  upc: String!
    @join__field(graph: PRODUCT)
    @join__field(graph: REVIEWS, external: true)
  sku: String!
    @join__field(graph: PRODUCT)
    @join__field(graph: INVENTORY, external: true)
  name: String @join__field(graph: PRODUCT)
  price: String @join__field(graph: PRODUCT)
  brand: Brand @join__field(graph: PRODUCT)
  metadata: [MetadataOrError] @join__field(graph: PRODUCT)
  details: ProductDetailsFurniture @join__field(graph: PRODUCT)
  inStock: Boolean @join__field(graph: INVENTORY)
  isHeavy: Boolean @join__field(graph: INVENTORY)
  reviews: [Review] @join__field(graph: REVIEWS)
}

type Ikea @join__type(graph: PRODUCT, key: "asile") {
  asile: Int
}

type Image implements NamedObject @join__type(graph: DOCUMENTS, key: "name") {
  name: String!
  attributes: ImageAttributes!
}

type ImageAttributes @join__type(graph: DOCUMENTS, key: "url") {
  url: String!
}

type KeyValue
  @join__type(graph: REVIEWS, key: "key")
  @join__type(graph: PRODUCT, key: "key")
  @join__type(graph: BOOKS, key: "key") {
  key: String!
  value: String!
}

type Library
  @join__type(graph: BOOKS, key: "id")
  @join__type(graph: ACCOUNTS, key: "id") {
  id: ID!
  name: String
    @join__field(graph: BOOKS)
    @join__field(graph: ACCOUNTS, external: true)
  userAccount(id: ID! = 1): User @join__field(graph: ACCOUNTS, requires: "name")
}

union MetadataOrError
  @join__type(graph: REVIEWS)
  @join__type(graph: PRODUCT)
  @join__type(graph: BOOKS)
  @join__type(graph: REVIEWS)
  @join__type(graph: PRODUCT)
  @join__type(graph: BOOKS) =
    KeyValue
  | Error

type Mutation @join__type(graph: ACCOUNTS) @join__type(graph: REVIEWS) {
  login(username: String!, password: String!): User
    @join__field(graph: ACCOUNTS)
  reviewProduct(upc: String!, body: String!): Product
    @join__field(graph: REVIEWS)
  updateReview(review: UpdateReviewInput!): Review @join__field(graph: REVIEWS)
  deleteReview(id: ID!): Boolean @join__field(graph: REVIEWS)
}

type Name @join__type(graph: ACCOUNTS) {
  first: String
  last: String
}

interface NamedObject @join__type(graph: DOCUMENTS) {
  name: String!
}

type PasswordAccount @join__type(graph: ACCOUNTS, key: "email") {
  email: String! @join__field(graph: ACCOUNTS)
}

interface Product @join__type(graph: PRODUCT) @join__type(graph: REVIEWS) {
  upc: String!
  sku: String!
  name: String
  price: String
  details: ProductDetails
  inStock: Boolean
  reviews: [Review]
}

interface ProductDetails
  @join__type(graph: PRODUCT)
  @join__type(graph: REVIEWS) {
  country: String
}

type ProductDetailsBook implements ProductDetails @join__type(graph: PRODUCT) {
  country: String
  pages: Int
}

type ProductDetailsFurniture implements ProductDetails
  @join__type(graph: PRODUCT) {
  country: String
  color: String
}

type Query
  @join__type(graph: ACCOUNTS)
  @join__type(graph: DOCUMENTS)
  @join__type(graph: BOOKS)
  @join__type(graph: PRODUCT)
  @join__type(graph: REVIEWS) {
  user(id: ID!): User @join__field(graph: ACCOUNTS)
  me: User @join__field(graph: ACCOUNTS)
  book(isbn: String!): Book @join__field(graph: BOOKS)
  books: [Book] @join__field(graph: BOOKS)
  library(id: ID!): Library @join__field(graph: BOOKS)
  body: Body! @join__field(graph: DOCUMENTS)
  product(upc: String!): Product @join__field(graph: PRODUCT)
  vehicle(id: String!): Vehicle @join__field(graph: PRODUCT)
  topProducts(first: Int = 5): [Product] @join__field(graph: PRODUCT)
  topCars(first: Int = 5): [Car] @join__field(graph: PRODUCT)
  topReviews(first: Int = 5): [Review] @join__field(graph: REVIEWS)
}

type Review
  @join__type(graph: REVIEWS, key: "id")
  @join__type(graph: PRODUCT, key: "id") {
  id: ID! @join__field(graph: REVIEWS)
  body(format: Boolean = false): String @join__field(graph: REVIEWS)
  author: User @join__field(graph: REVIEWS, provides: "username")
  product: Product @join__field(graph: REVIEWS)
  metadata: [MetadataOrError] @join__field(graph: REVIEWS)
}

type SMSAccount @join__type(graph: ACCOUNTS, key: "number") {
  number: String @join__field(graph: ACCOUNTS)
}

type Text implements NamedObject @join__type(graph: DOCUMENTS, key: "name") {
  name: String!
  attributes: TextAttributes!
}

type TextAttributes @join__type(graph: DOCUMENTS) {
  bold: Boolean
  text: String
}

union Thing @join__type(graph: PRODUCT) = Car | Ikea

input UpdateReviewInput @join__type(graph: REVIEWS) {
  id: ID!
  body: String
}

type User
  @join__type(graph: ACCOUNTS, key: "id")
  @join__type(graph: ACCOUNTS, key: "username name{first last}")
  @join__type(graph: INVENTORY, key: "id")
  @join__type(graph: PRODUCT, key: "id")
  @join__type(graph: REVIEWS, key: "id") {
  id: ID!
  name: Name @join__field(graph: ACCOUNTS)
  username: String @join__field(graph: ACCOUNTS) @join__field(graph: REVIEWS)
  birthDate(locale: String): String @join__field(graph: ACCOUNTS)
  account: AccountType @join__field(graph: ACCOUNTS)
  metadata: [UserMetadata]
    @join__field(graph: ACCOUNTS)
    @join__field(graph: INVENTORY, external: true)
    @join__field(graph: REVIEWS, external: true)
  goodDescription: Boolean
    @join__field(graph: INVENTORY, requires: "metadata{description}")
  vehicle: Vehicle @join__field(graph: PRODUCT)
  thing: Thing @join__field(graph: PRODUCT)
  reviews: [Review] @join__field(graph: REVIEWS)
  numberOfReviews: Int! @join__field(graph: REVIEWS)
  goodAddress: Boolean
    @join__field(graph: REVIEWS, requires: "metadata{address}")
}

type UserMetadata
  @join__type(graph: ACCOUNTS)
  @join__type(graph: INVENTORY)
  @join__type(graph: REVIEWS) {
  name: String
  address: String
  description: String
}

type Van implements Vehicle
  @join__type(graph: PRODUCT, key: "id")
  @join__type(graph: REVIEWS, key: "id") {
  id: String!
  description: String @join__field(graph: PRODUCT)
  price: String
    @join__field(graph: PRODUCT)
    @join__field(graph: REVIEWS, external: true)
  retailPrice: String @join__field(graph: REVIEWS, requires: "price")
}

interface Vehicle @join__type(graph: PRODUCT) {
  id: String!
  description: String
  price: String
  retailPrice: String
}
