"A date"
scalar Date

"A date and time"
scalar DateTime

"An object with any fields"
scalar JSONObject

"Distance units"
enum DistanceUnit {
  "Centimeter"
  cm

  "Foot"
  ft

  "Inch"
  in
}

"Mass units"
enum MassUnit {
  "Gram"
  g

  "Kilogram"
  kg

  "Pound"
  lb

  "Ounce"
  oz
}

"Relational Operator Types used in filtering inside a single condition"
enum RelationalOperatorTypes{
  "Begins With used with String types to filter based on the beginning of the string"
  beginsWith

  "Ends With used with String types to filter based on the end of the string"
  endsWith

  "Equal to"
  eq

  "Greater Than"
  gt

  "Greater Than or Equal"
  gte

  "In used with Array types to filter based on the array containing the value"
  in

  "Less Than"
  lt

  "Less Than or Equal"
  lte

  "Not Equal to"
  ne

  "Not In used with Array types to filter based on the array not containing the value"
  nin

  "Regex used with String types to filter based on the regex pattern"
  regex
}

"Single Condition for filter, use exactly one of the optional input value type"
input SingleConditionInput {
  "Value to filter if it is Boolean input"
  booleanValue: Boolean

  "Flag to set if the regex is case insensitive"
  caseSensitive: Boolean

  "Value to filter if it is Date input"
  dateValue: DateTime

  "Value to filter if it is Float Array input" 
  floatArrayValue: [Float]

  "Value to filter if it is Float input"
  floatValue: Float

  "Value to filter if it is Integer Array input" 
  integerArrayValue: [Int]

  "Value to filter if it is Integer input"
  integerValue: Int

  "Field name"
  key: String!

  "Logical NOT operator to negate the condition"
  logicalNot: Boolean

  "Relational Operator to join the key and value"
  relationalOperator: RelationalOperatorTypes!

  "Value to filter if it is String Array input"
  stringArrayValue: [String]

  "Value to filter if it is String input"
  stringValue: String
}

"Filter with One level of conditions (use either 'any' or 'all' not both)"
input ConditionsArray {
  "Array of single-conditions"
  all: [SingleConditionInput]

  "Array of single-conditions"
  any: [SingleConditionInput]
}

"Filter with nested conditions of input (use either 'any' or 'all' not both)"
input FilterConditionsInput {
  "Array holding Nested conditions (use either 'any' or 'all' not both)"
  all: [ConditionsArray]

  "Array holding Nested conditions (use either 'any' or 'all' not both)"
  any: [ConditionsArray]
}


"A list of URLs for various sizes of an image"
type ImageSizes {
  "Use this URL to get a large resolution file for this image"
  large: String

  "Use this URL to get a medium resolution file for this image"
  medium: String

  """
  Use this URL to get this image with its original resolution as uploaded. This may not be
  the true original size if there is a hard cap on how big image files can be.
  """
  original: String

  "Use this URL to get a small resolution file for this image"
  small: String

  "Use this URL to get a thumbnail resolution file for this image"
  thumbnail: String
}

"Information about an image"
type ImageInfo {
  "A list of URLs for various size files of this image"
  URLs: ImageSizes

  "ID"
  _id: ID

  """
  Sort by priority ascending when displaying more than one image for a product in a user interface.
  This is an integer with 1 being the first / highest priority image.
  """
  priority: Int

  "The related product ID"
  productId: ID

  "The related variant ID, if linked with a particular variant"
  variantId: ID
}

"Represents some amount of a single currency"
type Money {
  "The numeric amount"
  amount: Float!

  "The currency, for interpreting the `amount`"
  currency: Currency!

  "The display amount, with any currency symbols and decimal places already added"
  displayAmount: String!
}

"Represents input for some amount of a single currency"
input MoneyInput {
  "The numeric amount"
  amount: Float!

  "The currency code, for interpreting the `amount`"
  currencyCode: String!
}

"A numeric rate, with its corresponding percent values"
type Rate {
  "The rate"
  amount: Float!

  "The percent as a preformatted string with percent symbol included"
  displayPercent: String!

  "The percent (rate x 100)"
  percent: Float!
}

"Mutations have side effects, such as mutating data or triggering a task"
type Mutation {
  "A test mutation that returns whatever string you send it"
  echo("Any string" str: String): String
}

"Queries return all requested data, without any side effects"
type Query {
  "A test query"
  ping: String!
}

# Although the spec allows and Apollo supports defining an empty union
# that is extended later in other files, the graphql-schema-linter
# package currently has a problem with this, so we must assign FakeData
# to the unions to work around this issue.
#
# Do not use this type, and remove it after this bug is fixed.
#
# Usage:
#   union PaymentData = FakeData
#
# https://github.com/cjoudrey/graphql-schema-linter/issues/151
"Do not use this"
type FakeData {
  "Do not use this"
  doNotUse: String
}

"Represents one type of currency"
type Currency implements Node {
  "ID"
  _id: ID!

  "Currency code"
  code: String!

  "Decimal symbol"
  decimal: String

  "Format string"
  format: String!

  "Exchange rate from shop default currency, if known"
  rate: Float

  "The decimal scale used by this currency"
  scale: Int

  "Currency symbol"
  symbol: String!

  "Thousands separator symbol"
  thousand: String
}

"A string used as a connection cursor"
scalar ConnectionCursor

"An integer which will be auto-adjusted to be greater than 0 and less than 50 if necessary"
scalar ConnectionLimitInt

"The order in which the connection results should be sorted, based on the sortBy field."
enum SortOrder {
  "ascending"
  asc

  "descending"
  desc
}

"Objects implementing the Node interface will always have an _id field that is globally unique."
interface Node {
  "The ID of the object"
  _id: ID!
}

"Objects implementing the Deletable support soft deletion"
interface Deletable {
  """
  If true, this object should be considered deleted. Soft deleted objects are not
  returned in query results unless you explicitly ask for them.
  """
  isDeleted: Boolean!
}

"""
Objects implementing the NodeEdge interface will always have a node and a cursor
that represents that node for purposes of requesting paginated results.
"""
interface NodeEdge {
  "The cursor that represents this node in the paginated results"
  cursor: ConnectionCursor!

  "The node itself"
  node: Node
}

"""
Pagination information. When requesting pages of results, you can use endCursor or startCursor
as your before or after parameters for the query you are paging.
"""
type PageInfo {
  "When paginating forwards, the cursor to continue."
  endCursor: ConnectionCursor

  "When paginating forwards, are there more items?"
  hasNextPage: Boolean!

  "When paginating backwards, are there more items?"
  hasPreviousPage: Boolean!

  "When paginating backwards, the cursor to continue."
  startCursor: ConnectionCursor
}

"A string email address"
scalar Email

"A confirmable email record"
type EmailRecord {
  "The actual email address"
  address: String

  "The services provided by this address"
  provides: String

  "Has this address been verified?"
  verified: Boolean
}

"A confirmable email record"
input EmailRecordInput {
  "The actual email address"
  address: String

  "The services provided by this address"
  provides: String

  "Has this address been verified?"
  verified: Boolean
}

"User defined attributes. You can include only `key` and use these like tags, or also include a `value`."
input MetafieldInput {
  "Field description"
  description: String

  "Field key"
  key: String!

  "Field namespace"
  namespace: String

  "Field scope"
  scope: String

  "Field value"
  value: String

  "Field value type"
  valueType: String
}

"User defined attributes"
type Metafield {
  "Field description"
  description: String

  "Field key"
  key: String

  "Field namespace"
  namespace: String

  "Field scope"
  scope: String

  "Field value"
  value: String

  "Field value type"
  valueType: String
}

"The details of an `Address` to be created or updated"
input AddressInput {
  "The street address / first line"
  address1: String!

  "Optional second line"
  address2: String

  """
  Optionally, a name for this address (e.g. 'Home') to easily identify it in the future
  """
  addressName: String

  "City"
  city: String!

  "Optional company name, if it's a business address"
  company: String

  "Country"
  country: String!

  """
  The first name of a person at this address
  This is an optional field to support legacy and third party platforms
  We use fullName internally, and use first and last name fields to combine into a full name if needed
  """
  firstName: String

  "The full name of a person at this address"
  fullName: String!

  "Is this the default address for billing purposes?"
  isBillingDefault: Boolean

  "Is this a commercial address?"
  isCommercial: Boolean

  "Is this the default address to use when selecting a shipping address at checkout?"
  isShippingDefault: Boolean

  """
  The last name of a person at this address
  This is an optional field to support legacy and third party platforms
  We use fullName internally, and use first and last name fields to combine into a full name if needed
  """
  lastName: String

  "Arbitrary additional metadata about this address"
  metafields: [MetafieldInput]

  "A phone number for someone at this address"
  phone: String!

  "Postal code"
  postal: String!

  "Region. For example, a U.S. state"
  region: String!
}

"Represents a physical or mailing address somewhere on Earth"
type Address {
  "The address ID"
  _id: ID

  "The street address / first line"
  address1: String!

  "Optional second line"
  address2: String

  "City"
  city: String!

  "Optional company name, if it's a business address"
  company: String

  "Country"
  country: String!

  """
  The first name of a person at this address
  This is an optional field to support legacy and third party platforms
  We use fullName internally, and use first and last name fields to combine into a full name if needed
  """
  firstName: String

  "The full name of a person at this address"
  fullName: String!

  "Is this the default address for billing purposes?"
  isBillingDefault: Boolean

  "Is this a commercial address?"
  isCommercial: Boolean!

  "Is this the default address to use when selecting a shipping address at checkout?"
  isShippingDefault: Boolean

  """
  The last name of a person at this address
  This is an optional field to support legacy and third party platforms
  We use fullName internally, and use first and last name fields to combine into a full name if needed
  """
  lastName: String

  "Arbitrary additional metadata about this address"
  metafields: [Metafield]

  "A phone number for someone at this address"
  phone: String!

  "Postal code"
  postal: String!

  "Region. For example, a U.S. state"
  region: String!
}

"""
Wraps a list of `Addresses`, providing pagination cursors and information.

For information about what Relay-compatible connections are and how to use them, see the following articles:
- [Relay Connection Documentation](https://facebook.github.io/relay/docs/en/graphql-server-specification.html#connections)
- [Relay Connection Specification](https://facebook.github.io/relay/graphql/connections.htm)
- [Using Relay-style Connections With Apollo Client](https://www.apollographql.com/docs/react/recipes/pagination.html)
"""
type AddressConnection {
  "The list of nodes that match the query, wrapped in an edge to provide a cursor string for each"
  edges: [AddressEdge]

  """
  You can request the `nodes` directly to avoid the extra wrapping that `NodeEdge` has,
  if you know you will not need to paginate the results.
  """
  nodes: [Address]
  "Information to help a client request the next or previous page"
  pageInfo: PageInfo!
  "The total number of nodes that match your query"
  totalCount: Int!
}

"A connection edge in which each node is an `Address` object"
type AddressEdge {
  "The cursor that represents this node in the paginated results"
  cursor: ConnectionCursor!
  "The address"
  node: Address
}
