"Base address properties"
interface Address {
  "City"
  city: String

  "Company"
  company: String

  "Country"
  country: Country!

  "Fax"
  fax: String

  "First Name"
  firstname: String

  "Last Name"
  lastname: String

  "Middle Name/Initial"
  middlename: String

  "Zip/Postal Code"
  postcode: String

  "Prefix"
  prefix: String

  "Region"
  region: AddressRegion

  "Street"
  street: [String!]!

  "Suffix"
  suffix: String

  "Telephone"
  telephone: String

  "VAT number"
  vatId: String
}

"An address region"
type AddressRegion {
  "Region code, ISO 3166-2"
  code: String!

  "Region name"
  name: String!
}

"Enum representing possible validation errors for an address"
enum AddressValidationError {
  "Telephone is invalid"
  errorInvalidTelephone

  "City is missing a value"
  errorMissingCity

  "Country is missing a value"
  errorMissingCountry

  "Firstname is missing a value"
  errorMissingFirstname

  "Lastname is missing a value"
  errorMissingLastname

  "Postcode is missing a value"
  errorMissingPostcode

  "Region is missing a value"
  errorMissingRegion

  "Street is missing a value"
  errorMissingStreet

  "Telephone is missing a value"
  errorMissingTelephone
}

"A country in an address"
type Country {
  "Country code, ISO 3166-2"
  code: ID!

  "Country name for the current locale"
  name: String!
}

"Type containing the result of createCustomerAddress"
type CreateCustomerAddressResult {
  "The set address customer address, if no error occurred or if address failed to validate"
  address: CustomerAddress

  "The customer result, if no error occurred"
  customer: Customer

  "The type of result"
  result: CreateCustomerAddressResultType!

  "List of validation errors if the address failed to validate"
  validationErrors: [AddressValidationError!]!
}

"Type of result from removeCustomerAddress mutation"
enum CreateCustomerAddressResultType {
  "The supplied address id is invalid."
  errorInvalidAddress

  "Customer is not logged in."
  errorNotLoggedIn

  "Address"
  success
}

"Type containing customer information"
type Customer {
  "List of addresses for the customer."
  addresses: [CustomerAddress!]!

  "Customer created date"
  createdAt: String!

  "Date Of Birth"
  dob: String

  "Customer email"
  email: String!

  "First Name"
  firstname: String!

  "Gender"
  gender: String

  "Last Name"
  lastname: String!

  "Middle Name/Initial"
  middlename: String

  "Prefix"
  prefix: String

  "Suffix"
  suffix: String
}

"A customer address"
type CustomerAddress implements Address {
  "City"
  city: String

  "Company"
  company: String

  "Country"
  country: Country!

  "Fax"
  fax: String

  "First Name"
  firstname: String

  "Address id, used to update/delete"
  id: ID!

  "If the address is the default billing address"
  isDefaultBilling: Boolean!

  "If the address is the default shipping address"
  isDefaultShipping: Boolean!

  "Last Name"
  lastname: String

  "Middle Name/Initial"
  middlename: String

  "Zip/Postal Code"
  postcode: String

  "Prefix"
  prefix: String

  "Region"
  region: AddressRegion

  "Street"
  street: [String!]!

  "Suffix"
  suffix: String

  "Telephone"
  telephone: String

  "VAT number"
  vatId: String
}

"Object containing a partially or fully populated address"
input CustomerAddressInput {
  "City"
  city: String

  "Company"
  company: String

  "Country code"
  countryCode: ID

  "Fax"
  fax: String

  "First Name"
  firstname: String

  "Last Name"
  lastname: String

  "Middle Name/Initial"
  middlename: String

  "Zip/Postal Code"
  postcode: String

  "Prefix"
  prefix: String

  "Region code"
  regionCode: ID

  "Street, one line per array item"
  street: [String!]

  "Suffix"
  suffix: String

  "Telephone"
  telephone: String

  "VAT number"
  vatId: String
}

"Setting for customer input field"
enum CustomerInputFieldSettingType {
  "Field is hidden (not saved)"
  hidden

  "Field is visible and can be updated (saved)"
  normal

  "Field is visible and read only (not saved)"
  readonly
}

"Type containing the result of a login operation"
type LoginCustomerResult {
  "Present if it is a success"
  customer: Customer

  "The result type"
  result: LoginCustomerResultType!
}

"Type indicating the result of a login operation"
enum LoginCustomerResultType {
  "Invalid email or password."
  errorInvalidEmailOrPassword

  "Login mutation is not enabled"
  errorLoginNotEnabled

  "The account is not yet confirmed by email."
  errorUserNotConfirmed

  "A successful login"
  success
}

"Root mutation type."
type Mutation {
  "Creates a customer address"
  createCustomerAddress(
    "The new address data"
    address: CustomerAddressInput!

    "If the newly created address should be set as the default billing address"
    setDefaultBilling: Boolean = false

    "If the newly created address should be set as the default shipping address"
    setDefaultShipping: Boolean = false
  ): CreateCustomerAddressResult!

  "Attempts to log in a customer"
  loginCustomer(
    "The email of the customer account"
    email: String!

    "The password"
    password: String!
  ): LoginCustomerResult!

  "Attempts to log out a customer"
  logoutCustomer: Boolean!

  "Attempts to delete a customer address"
  removeCustomerAddress(
    "The id of the customer address"
    id: ID!
  ): RemoveCustomerAddressResult!

  "Attempts to set the given address id as the default billing address for the currently logged in customer"
  setCustomerDefaultBillingAddress(
    "The id of the customer address to use as default billing address"
    id: ID!
  ): SetCustomerDefaultAddressResult!

  "Attempts to set the given address id as the default shipping address for the currently logged in customer"
  setCustomerDefaultShippingAddress(
    "The id of the customer address to use as default shipping address"
    id: ID!
  ): SetCustomerDefaultAddressResult!

  "Attempts to subscribe to newsletter"
  subscribeToNewsletter(
    "The subscriber email"
    email: String

    "The subscriber firstname"
    firstname: String

    "The subscriber lastname"
    lastname: String
  ): SubscribeToNewsletterResult!

  "Updates the customer information for the currently logged in customer"
  updateCustomer(
    "The new customer information"
    customer: UpdateCustomerInput!
  ): UpdateCustomerResult!

  "Updates a customer address with new data"
  updateCustomerAddress(
    "Address data to update"
    address: CustomerAddressInput!

    "The id of the customer address to update"
    id: ID!
  ): UpdateCustomerAddressResult!

  "Updates the email for the currently logged in customer, this will also propagate to any quote."
  updateCustomerEmail(
    "The new email for the account"
    email: String!
  ): UpdateCustomerEmailResult!
}

"Price information which carries tax information"
interface Price {
  "Price excluding VAT"
  exVat: Float!

  "Price including VAT"
  incVat: Float!

  "VAT amount"
  vat: Float!
}

"Root query type."
type Query {
  "Customer information if a customer is logged in"
  customer: Customer

  "Information about the current store"
  info: StoreInfo!

  "Attempt to fetch a resource by its route"
  route(
    "Path to resource"
    path: String!
  ): Route
}

"Type containing the result of a customer address removal."
type RemoveCustomerAddressResult {
  "The type of result from removeCustomerAddress"
  result: RemoveCustomerAddressResultType!
}

"Type of result from removeCustomerAddress mutation"
enum RemoveCustomerAddressResultType {
  "The supplied address id is invalid."
  errorInvalidAddressId

  "Customer is not logged in."
  errorNotLoggedIn

  "Address was successfully removed."
  success
}

"Response from a route"
interface Route {
  "Type of route resource"
  type: RouteType!
}

"A response containing a category"
type RouteRedirect implements Route {
  "If the redirect is a permanent redirect"
  isPermanent: Boolean!

  "Type of route"
  type: RouteType!

  "Redirect to"
  url: String!
}

"Type indicating variant of route resource"
enum RouteType {
  "A category"
  category

  "A CMS page"
  cms_page

  "A product"
  product

  "A redirect to another path"
  redirect
}

"Result of setCustomerDefaultShippingAddress or setCustomerDefaultBillingAddress."
type SetCustomerDefaultAddressResult {
  "The set address customer address, if no error occurred"
  address: Address

  "The customer result, if no error occurred"
  customer: Customer

  "The type of result"
  result: SetCustomerDefaultAddressResultType!
}

"Type of result from updateCustomerEmail mutation"
enum SetCustomerDefaultAddressResultType {
  "The supplied address id is invalid."
  errorInvalidAddressId

  "Customer is not logged in."
  errorNotLoggedIn

  "Default address was not modified."
  notModified

  "Default address was successfully updated."
  success
}

"Basic store information"
type StoreInfo {
  "Base currency code"
  baseCurrencyCode: String!

  "Base URL"
  baseUrl: String!

  "Store code"
  code: String!

  "List of available countries for the store"
  countries: [Country!]!

  "Currency codes"
  currencyCodes: [String!]!

  "Settings for customer input fields"
  customerInputFieldsSettings: [customerInputFieldsSetting!]

  "Default country for the store"
  defaultCountry: Country!

  "Default page description"
  defaultDescription: String

  "Default page title"
  defaultTitle: String

  "Locale code for the store"
  locale: String!

  "Name"
  name: String!

  "Price lock"
  pricelock: Boolean

  "Store time"
  time: String!

  "Page title prefix"
  titlePrefix: String

  "Page title suffix"
  titleSuffix: String
}

"Type containing the result of subscribing to newsletters"
type SubscribeToNewsletterResult {
  "The type of result"
  result: SubscribeToNewslettersResultType!
}

"Type of result from subscribeToNewsletter mutation"
enum SubscribeToNewslettersResultType {
  "Invalid email."
  invalidEmail

  "Customer not logged in."
  notLoggedIn

  "Subscription not modified."
  notModified

  "Email was successfully subcribed."
  success
}

"Result of updateCustomerAddress mutation"
type UpdateCustomerAddressResult {
  "The updated customer address, if no error occurred"
  address: CustomerAddress

  "The customer result, if no error occurred"
  customer: Customer

  "The type of result"
  result: UpdateCustomerAddressResultType!

  "List of validation errors if the address failed to validate"
  validationErrors: [AddressValidationError!]!
}

"Type of result from updateCustomerAddress mutation"
enum UpdateCustomerAddressResultType {
  "The supplied address id is invalid."
  errorInvalidAddress

  "The supplied address id is invalid."
  errorInvalidAddressId

  "Customer is not logged in."
  errorNotLoggedIn

  "Address was not modified"
  notModified

  "Address was successfully updated"
  success
}

"Result of updateCustomerEmail mutation"
type UpdateCustomerEmailResult {
  "The customer result, if no error occurred"
  customer: Customer

  "The type of result"
  result: UpdateCustomerEmailResultType!
}

"Type of result from updateCustomerEmail mutation"
enum UpdateCustomerEmailResultType {
  "The updateCustomerEmail mutation is disabled"
  errorDisabled

  "The supplied email is used by another customer"
  errorEmailExists

  "The supplied email address is invalid."
  errorInvalidEmail

  "Customer is not logged in."
  errorNotLoggedIn

  "Email was not modified."
  notModified

  "Email was successfully updated."
  success
}

"New data for customer"
input UpdateCustomerInput {
  "Date Of Birth"
  dob: String

  "First Name"
  firstname: String

  "Gender"
  gender: String

  "Last Name"
  lastname: String

  "Middle Name/Initial"
  middlename: String

  "Prefix"
  prefix: String

  "Suffix"
  suffix: String

  "Tax/VAT Number"
  taxvat: String
}

"Result of updateCustomer mutation"
type UpdateCustomerResult {
  "Present if it is a success"
  customer: Customer

  "The result type"
  result: UpdateCustomerResultType!
}

"Type of result from updateCustomer mutation"
enum UpdateCustomerResultType {
  "Customer is not logged in."
  errorNotLoggedIn

  "Address was not modified"
  notModified

  "Address was successfully updated"
  success
}

"Setting for specified customer input field"
type customerInputFieldsSetting {
  "Customer input field name"
  field: String!

  "Customer input field setting"
  setting: CustomerInputFieldSettingType!
}
