diff --git a/functions-fulfillment-option-generators-js/.gitignore b/functions-fulfillment-option-generators-js/.gitignore new file mode 100644 index 00000000..562ebe05 --- /dev/null +++ b/functions-fulfillment-option-generators-js/.gitignore @@ -0,0 +1,2 @@ +dist +generated diff --git a/functions-fulfillment-option-generators-js/README.md b/functions-fulfillment-option-generators-js/README.md new file mode 100644 index 00000000..be438d4c --- /dev/null +++ b/functions-fulfillment-option-generators-js/README.md @@ -0,0 +1,220 @@ +# Fulfillment option generators demo + +This repository contains a function that demonstrates how to generate fulfillment options for the fulfillments in a +cart, based on an external API accessible via an HTTP request. To simulate an external API, we have hosted a +[JSON file](https://cdn.shopify.com/s/files/1/0628/3830/9033/files/pickup-points-external-api-v2.json?v=1714588690), +which contains delivery point information in the following format: + +```json +{ + "deliveryPoints": [ + { + "pointId": "001", + "pointName": "Toronto Store", + "location": { + "addressComponents": { + "streetNumber": "620", + "route": "King St W", + "locality": "Toronto", + "administrativeArea": { + "name": "Ontario", + "code": "ON" + }, + "postalCode": "M5V 1M6", + "country": "Canada", + "countryCode": "CA" + }, + "geometry": { + "location": { + "lat": 43.644664618786685, + "lng": -79.40066267417106 + } + } + }, + "openingHours": { + "weekdayText": [ + "Monday: 9:00 AM – 9:00 PM", + "Tuesday: 9:00 AM – 9:00 PM", + "Wednesday: 9:00 AM – 9:00 PM", + "Thursday: 9:00 AM – 9:00 PM", + "Friday: 9:00 AM – 9:00 PM", + "Saturday: 10:00 AM – 6:00 PM", + "Sunday: Closed" + ] + } + } + ] +} +``` + +## Implementation details + +A function can have one or more targets, each characterized by a specific input/output API. The Fulfillment Option +Generators have two targets: an optional **fetch** target and a **run** target. The input/output APIs are +represented as a GraphQL API within the attached [schema](./schema.graphql). + +### Fetch target + +The **fetch** target is responsible for generating an HTTP request to call the external API. Its input API is defined +by the `Input` type in the [schema](./schema.graphql). In our demo, we are only interested in the buyer's localization +country, which we specify within the [**fetch** target input query](./src/fetch.graphql). + +The [**fetch** target](./src/fetch.js) reads the input and generates an output representing an HTTP request to the +external API if the buyer's country is Canada. The output API is defined by the `FunctionFetchResult` type in +the [schema](./schema.graphql). + +#### Fetch target input/output example + +##### Input + +```json +{ + "localization": { + "country": { + "isoCode": "CA" + } + } +} +``` + +##### Output + +```json +{ + "request": { + "method": "GET", + "url": "https://cdn.shopify.com/s/files/1/0628/3830/9033/files/pickup-points-external-api-v2.json?v=1714588690", + "headers": [ + { + "name": "Accept", + "value": "application/json; charset=utf-8" + } + ], + "body": null, + "policy": { + "readTimeoutMs": 500 + } + } +} +``` + +### Run target + +The **run** target is responsible for generating the fulfillment options. Its input API is defined by the `Input` type +in the [schema](./schema.graphql). In our demo, we are interested in the cart's fulfillments along with the external +API HTTP response status and body, which we specify within the [**run** target input query](./src/run.graphql). + +The [**run** target](./src/run.js) parses the response body and produces fulfillment options in the format specified +by the `FunctionRunResult` type in the [schema](./schema.graphql). Providers and service points are deduplicated into +the `references` block and referenced from `fulfillmentOptionsAdd` operations by their handle, to keep the payload +small. One fulfillment option is generated per service point, for every input fulfillment. + +#### Run target input/output example + +##### Input + +```json +{ + "fulfillments": [ + { "handle": "fulfillment-1" } + ], + "fetchResult": { + "status": 200, + "body": "{\"deliveryPoints\":[{\"pointId\":\"001\",\"pointName\":\"Toronto Store\",\"location\":{\"addressComponents\":{\"streetNumber\":\"620\",\"route\":\"King St W\",\"locality\":\"Toronto\",\"administrativeArea\":{\"name\":\"Ontario\",\"code\":\"ON\"},\"postalCode\":\"M5V 1M6\",\"country\":\"Canada\",\"countryCode\":\"CA\"},\"geometry\":{\"location\":{\"lat\":43.644664618786685,\"lng\":-79.40066267417106}}},\"openingHours\":{\"weekdayText\":[\"Monday: 9:00 AM – 9:00 PM\",\"Sunday: Closed\"]}}]}" + } +} +``` + +##### Output + +```json +{ + "references": { + "providers": [ + { + "handle": "shopify-demo-provider", + "externalId": "shopify-demo", + "name": "Shopify Functions Demo", + "logoUrl": "https://cdn.shopify.com/s/files/1/0628/3830/9033/files/shopify_icon_146101.png?v=1706120545" + } + ], + "servicePoints": [ + { + "handle": "service-point-001", + "externalId": "001", + "name": "Toronto Store", + "address1": "620 King St W", + "address2": null, + "city": "Toronto", + "countryCode": "CA", + "provinceCode": "ON", + "zip": "M5V 1M6", + "phone": null, + "latitude": 43.644664618786685, + "longitude": -79.40066267417106, + "businessHours": [ + { + "day": "MONDAY", + "periods": [ + { + "openingTime": "09:00:00", + "closingTime": "21:00:00" + } + ] + }, + { + "day": "SUNDAY", + "periods": [] + } + ] + } + ] + }, + "operations": [ + { + "fulfillmentOptionsAdd": { + "fulfillmentHandle": "fulfillment-1", + "title": "Toronto Store", + "providerHandle": "shopify-demo-provider", + "destinationServicePointHandle": "service-point-001", + "cost": null, + "metafields": [] + } + } + ] +} +``` + +## Usage + +### Installing dependencies + +1. Install the necessary dependencies by running the following command in your terminal: + +```bash +yarn install +``` + +### Running tests + +1. Execute the tests by running the following command in your terminal: + +```bash +yarn test +``` + +### Deploying the function to the app + +1. Navigate to the root directory of your app. Deploy the function by running the following command +in your terminal: + +```bash +yarn deploy +``` + +### Using the function in a store + +1. Activate the function by selecting it in the relevant fulfillment settings of the store admin, then save. + +2. To use the function, initiate a checkout process with a product available from the configured location. Enter an +address in Canada — a list of fulfillment options generated using this function should now be visible. diff --git a/functions-fulfillment-option-generators-js/locales/en.default.json.liquid b/functions-fulfillment-option-generators-js/locales/en.default.json.liquid new file mode 100644 index 00000000..333045ae --- /dev/null +++ b/functions-fulfillment-option-generators-js/locales/en.default.json.liquid @@ -0,0 +1,4 @@ +{ + "name": "{{name}}", + "description": "{{name}}" +} diff --git a/functions-fulfillment-option-generators-js/package.json.liquid b/functions-fulfillment-option-generators-js/package.json.liquid new file mode 100644 index 00000000..d519b00a --- /dev/null +++ b/functions-fulfillment-option-generators-js/package.json.liquid @@ -0,0 +1,35 @@ +{ + "name": "{{handle}}", + "version": "0.0.1", + "license": "UNLICENSED", + "type": "module", + "scripts": { + "shopify": "npm exec -- shopify", + "typegen": "npm exec -- shopify app function typegen", + "build": "npm exec -- shopify app function build", + "preview": "npm exec -- shopify app function run", + "test": "vitest" + }, + "codegen": { + "schema": "schema.graphql", + "documents": "src/*.graphql", + "generates": { + "./generated/api.ts": { + "plugins": [ + "typescript", + "typescript-operations" + ] + } + }, + "config": { + "omitOperationSuffix": true + } + }, + "dependencies": { + "@shopify/shopify_function": "^2.0.1" + }, + "devDependencies": { + "@shopify/shopify-function-test-helpers": "^1.0.0", + "vitest": "^3.2.4" + } +} diff --git a/functions-fulfillment-option-generators-js/schema.graphql b/functions-fulfillment-option-generators-js/schema.graphql new file mode 100644 index 00000000..2b5d55cd --- /dev/null +++ b/functions-fulfillment-option-generators-js/schema.graphql @@ -0,0 +1,5800 @@ +# This file is auto-generated from the current state of the GraphQL API. Instead of editing this file, +# please edit the ruby definition files and run `bin/rails graphql:schema:dump` to regenerate the schema. +# +# If you're just looking to browse, you may find it friendlier to use the graphiql browser which is +# available in services-internal at https://app.shopify.com/services/internal/shops/14168/graphql. +# Check out the "Docs" tab in the top right. + +schema { + query: Input + mutation: MutationRoot +} + +""" +Only allow the field to be queried when targeting one of the specified targets. +""" +directive @restrictTarget(only: [String!]!) on FIELD_DEFINITION + +""" +Scale the Functions resource limits based on the field's length. +""" +directive @scaleLimits(rate: Float!) on FIELD_DEFINITION + +""" +Requires that exactly one field must be supplied and that field must not be `null`. +""" +directive @oneOf on INPUT_OBJECT + +""" +Represents an app. +""" +type App { + """ + The ID of the app. + """ + id: ID! +} + +""" +A custom property. Attributes are used to store additional information about a Shopify resource, such as +products, customers, or orders. Attributes are stored as key-value pairs. + +For example, a list of attributes might include whether a customer is a first-time buyer (`"customer_first_order": "true"`), +whether an order is gift-wrapped (`"gift_wrapped": "true"`), a preferred delivery date +(`"preferred_delivery_date": "2025-10-01"`), the discount applied (`"loyalty_discount_applied": "10%"`), and any +notes provided by the customer (`"customer_notes": "Please leave at the front door"`). +""" +type Attribute { + """ + The key or name of the attribute. For example, `"customer_first_order"`. + """ + key: String! + + """ + The value of the attribute. For example, `"true"`. + """ + value: String +} + +""" +Operating hours of a service point for a specific day of the week. A day +with no entry is considered closed. Use multiple periods to express +split schedules (e.g. lunch closures). +""" +input BusinessHours { + """ + The day of the week. + """ + day: Weekday! + + """ + Operating periods for the day. + """ + periods: [BusinessHoursPeriod!]! +} + +""" +An operating-time period within a single day at a service point. +""" +input BusinessHoursPeriod { + """ + The time the service point closes. + """ + closingTime: TimeWithoutTimezone! + + """ + The time the service point opens. + """ + openingTime: TimeWithoutTimezone! +} + +""" +Information about the customer that's interacting with the cart. It includes details such as the +customer's email and phone number, and the total amount of money the customer has spent in the store. +This information helps personalize the checkout experience and ensures that accurate pricing and delivery options +are displayed to customers. +""" +type BuyerIdentity { + """ + The [customer](https://help.shopify.com/manual/customers/manage-customers) that's interacting with the cart. + """ + customer: Customer + + """ + The email address of the customer that's interacting with the cart. + """ + email: String + + """ + Whether the customer is authenticated through their + [customer account](https://help.shopify.com/manual/customers/customer-accounts). + """ + isAuthenticated: Boolean! + + """ + The phone number of the customer that's interacting with the cart. + """ + phone: String + + """ + The company of a B2B customer that's interacting with the cart. + Used to manage and track purchases made by businesses rather than individual customers. + """ + purchasingCompany: PurchasingCompany + + """ + Represents the [Shop User](https://help.shopify.com/en/manual/online-sales-channels/shop/sign-in-features) + corresponding to the customer within the shop, if the buyer is a Shop User. Can be used to request [Shop User + metafields](https://shopify.dev/docs/api/shop-user-custom-data). + """ + shopUser: ShopUser +} + +""" +The cart where the Function is running. A cart contains the merchandise that a customer intends to purchase +and information about the customer, such as the customer's email address and phone number. +""" +type Cart implements HasMetafields { + """ + The custom attributes associated with a cart to store additional information. Cart attributes + allow you to collect specific information from customers on the **Cart** page, such as order notes, + gift wrapping requests, or custom product details. Attributes are stored as key-value pairs. + """ + attribute( + """ + The key of the cart attribute to retrieve. For example, `"gift_wrapping"`. + """ + key: String + ): Attribute + + """ + The billing address associated with the cart. + """ + billingAddress: MailingAddress + + """ + Information about the customer that's interacting with the cart. It includes details such as the + customer's email and phone number, and the total amount of money the customer has spent in the store. + This information helps personalize the checkout experience and ensures that accurate pricing and delivery options + are displayed to customers. + """ + buyerIdentity: BuyerIdentity + + """ + A breakdown of the costs that the customer will pay at checkout. It includes the total amount, + the subtotal before taxes and duties, the tax amount, and duty charges. + """ + cost: CartCost! + + """ + The items in a cart that are eligible for fulfillment and can be delivered to the customer. + """ + deliverableLines: [DeliverableCartLine!]! + + """ + A collection of items that are grouped by shared delivery characteristics. Delivery groups streamline + fulfillment by organizing items that can be shipped together, based on the customer's + shipping address. For example, if a customer orders a t-shirt and a pair of shoes that can be shipped + together, then the items are included in the same delivery group. + + In the [Order Discount](https://shopify.dev/docs/api/functions/reference/order-discounts) and + [Product Discount](https://shopify.dev/docs/api/functions/reference/product-discounts) legacy APIs, + the `cart.deliveryGroups` input is always an empty array. This means you can't access delivery groups when + creating Order Discount or Product Discount Functions. If you need to apply discounts to shipping costs, + then use the [Discount Function API](https://shopify.dev/docs/api/functions/reference/discount) + instead. + """ + deliveryGroups: [CartDeliveryGroup!]! + + """ + The discounts that have been applied to the cart. + """ + discountApplications: [DiscountApplication!]! + + """ + The items in a cart that the customer intends to purchase. A cart line is an entry in the + customer's cart that represents a single unit of a product variant. For example, if a customer adds two + different sizes of the same t-shirt to their cart, then each size is represented as a separate cart line. + """ + lines: [CartLine!]! @scaleLimits(rate: 0.005) + + """ + The additional fields on the **Cart** page that are required for international orders in specific countries, + such as customs information or tax identification numbers. + """ + localizedFields( + """ + The keys of the localized fields to retrieve. + """ + keys: [LocalizedFieldKey!]! = [] + ): [LocalizedField!]! + + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield + + """ + A purchase order number associated with the cart, often used for B2B transactions + to reference the buyer's internal purchase order. + """ + poNumber: String + + """ + The physical location where a retail order is created or completed. + """ + retailLocation: Location +} + +""" +A breakdown of the costs that the customer will pay at checkout. It includes the total amount, +the subtotal before taxes and duties, the tax amount, and duty charges. +""" +type CartCost { + """ + The amount, before taxes and cart-level discounts, for the customer to pay. + """ + subtotalAmount: MoneyV2! + + """ + The total amount for the customer to pay at checkout. + """ + totalAmount: MoneyV2! + + """ + The duty charges for a customer to pay at checkout. + """ + totalDutyAmount: MoneyV2 + + """ + The total tax amount for the customer to pay at checkout. + """ + totalTaxAmount: MoneyV2 +} + +""" +Information about items in a cart that are grouped by shared delivery characteristics. +Delivery groups streamline fulfillment by organizing items that can be shipped together, based on the customer's +shipping address. For example, if a customer orders a t-shirt and a pair of shoes that can be shipped +together, then the items are included in the same delivery group. +""" +type CartDeliveryGroup { + """ + Information about items in a cart that a customer intends to purchase. A cart line is an entry in the + customer's cart that represents a single unit of a product variant. For example, if a customer adds two + different sizes of the same t-shirt to their cart, then each size is represented as a separate cart line. + """ + cartLines: [CartLine!]! @scaleLimits(rate: 0.005) + + """ + The shipping or destination address associated with the delivery group. + """ + deliveryAddress: MailingAddress + + """ + The delivery options available for the delivery group. Delivery options are the different ways that customers + can choose to have their orders shipped. Examples include express shipping or standard shipping. + """ + deliveryOptions: [CartDeliveryOption!]! + + """ + The discounts that have been applied to the delivery group. + """ + discountAllocations: [DiscountAllocation!]! + + """ + The type of merchandise in the delivery group. + """ + groupType: CartDeliveryGroupType! + + """ + A [globally-unique ID](https://shopify.dev/docs/api/usage/gids) + for the delivery group. + """ + id: ID! + + """ + Information about the delivery option that the customer has selected. + """ + selectedDeliveryOption: CartDeliveryOption +} + +""" +Defines what type of merchandise is in the delivery group. +""" +enum CartDeliveryGroupType { + """ + The delivery group only contains merchandise that is either a one time purchase or a first delivery of + subscription merchandise. + """ + ONE_TIME_PURCHASE + + """ + The delivery group only contains subscription merchandise. + """ + SUBSCRIPTION +} + +""" +Information about a delivery option that's available for an item in a cart. Delivery options are the different +ways that customers can choose to have their orders shipped. Examples include express shipping or standard +shipping. +""" +type CartDeliveryOption { + """ + A unique identifier that represents the delivery option offered to customers. + For example, `Canada Post Expedited`. + """ + code: String + + """ + The amount that the customer pays if they select the delivery option. + """ + cost: MoneyV2! + + """ + The delivery method associated with the delivery option. A delivery method is a way that merchants can + fulfill orders from their online stores. Delivery methods include shipping to an address, + [local pickup](https://help.shopify.com/manual/fulfillment/setup/delivery-methods/pickup-in-store), + and shipping to a [pickup point](https://help.shopify.com/manual/fulfillment/shopify-shipping/pickup-points), + all of which are natively supported by Shopify checkout. + """ + deliveryMethodType: DeliveryMethod! + + """ + A single-line description of the delivery option, with HTML tags removed. + """ + description: String + + """ + A unique, human-readable identifier of the delivery option's title. + A handle can contain letters, hyphens (`-`), and numbers, but not spaces. + For example, `standard-shipping`. + """ + handle: Handle! + + """ + The name of the delivery option that displays to customers. The title is used to construct the delivery + option's handle. For example, if a delivery option is titled "Standard Shipping", then the handle is + `standard-shipping`. + """ + title: String +} + +""" +The fetch target result. Refer to network access for Shopify Functions. +""" +input FunctionFetchResult { + """ + HTTP request to dispatch on behalf of the function. + """ + request: HttpRequest +} + +""" +The output of the Function `run` target. Contains the operations to +apply, plus a `References` block with deduplicated lookup tables for +providers and service points. +""" +input FunctionRunResult { + """ + The ordered list of operations to apply. + """ + operations: [Operation!]! + + """ + Deduplicated lookup tables for providers and service points. + """ + references: References +} + +""" +Information about an item in a cart that a customer intends to purchase. A cart line is an entry in the +customer's cart that represents a single unit of a product variant. For example, if a customer adds two +different sizes of the same t-shirt to their cart, then each size is represented as a separate cart line. +""" +type CartLine { + """ + The custom attributes associated with a cart to store additional information. Cart attributes + allow you to collect specific information from customers on the **Cart** page, such as order notes, + gift wrapping requests, or custom product details. Attributes are stored as key-value pairs. + + Cart line attributes are equivalent to the + [`line_item`](https://shopify.dev/docs/api/liquid/objects/line_item) + object in Liquid. + """ + attribute( + """ + The key of the cart attribute to retrieve. For example, `"gift_wrapping"`. + """ + key: String + ): Attribute + + """ + The cost of an item in a cart that the customer intends to purchase. Cart lines are entries in the customer's + cart that represent a single unit of a product variant. For example, if a customer adds two different sizes of + the same t-shirt to their cart, then each size is represented as a separate cart line. + """ + cost: CartLineCost! + + """ + The discounts that have been applied to the cart line. + """ + discountAllocations: [DiscountAllocation!]! + + """ + The ID of the cart line. + """ + id: ID! + + """ + The item that the customer intends to purchase. + """ + merchandise: Merchandise! + + """ + The [nested relationship](https://shopify.dev/docs/apps/build/product-merchandising/nested-cart-lines) + between this line and its parent line, if any. + """ + parentRelationship: CartLineParentRelationship + + """ + The quantity of the item that the customer intends to purchase. + """ + quantity: Int! + + """ + The [selling plan](https://shopify.dev/docs/apps/build/purchase-options/subscriptions/selling-plans) + associated with the cart line, including information about how a product variant can be sold and purchased. + """ + sellingPlanAllocation: SellingPlanAllocation +} + +""" +The cost of an item in a cart that the customer intends to purchase. Cart lines are entries in the customer's +cart that represent a single unit of a product variant. For example, if a customer adds two different sizes of +the same t-shirt to their cart, then each size is represented as a separate cart line. +""" +type CartLineCost { + """ + The cost of a single unit. For example, if a customer purchases three units of a product + that are priced at $10 each, then the `amountPerQuantity` is $10. + """ + amountPerQuantity: MoneyV2! + + """ + The `compareAt` price of a single unit before any discounts are applied. This field is used to calculate and display + savings for customers. For example, if a product's `compareAtAmountPerQuantity` is $25 and its current price + is $20, then the customer sees a $5 discount. This value can change based on the buyer's identity and is + `null` when the value is hidden from buyers. + """ + compareAtAmountPerQuantity: MoneyV2 + + """ + The cost of items in the cart before applying any discounts to certain items. + This amount serves as the starting point for calculating any potential savings customers + might receive through promotions or discounts. + """ + subtotalAmount: MoneyV2! + + """ + The total cost of items in a cart. + """ + totalAmount: MoneyV2! +} + +""" +Represents the relationship between a cart line and its parent line. +""" +type CartLineParentRelationship { + """ + The parent line in the relationship. + """ + parent: CartLine! +} + +""" +Whether the product is in the specified collection. + +A collection is a group of products that can be displayed in online stores and other sales channels in +categories, which makes it easy for customers to find them. For example, an athletics store might create +different collections for running attire and accessories. +""" +type CollectionMembership { + """ + A [globally-unique ID](https://shopify.dev/docs/api/usage/gids) + for the collection. + """ + collectionId: ID! + + """ + Whether the product is in the specified collection. + """ + isMember: Boolean! +} + +""" +Represents information about a company which is also a customer of the shop. +""" +type Company implements HasMetafields { + """ + The date and time ([ISO 8601 format](http://en.wikipedia.org/wiki/ISO_8601)) at which the company was created in Shopify. + """ + createdAt: DateTime! + + """ + A unique externally-supplied ID for the company. + """ + externalId: String + + """ + The ID of the company. + """ + id: ID! + + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield + + """ + The name of the company. + """ + name: String! + + """ + The date and time ([ISO 8601 format](http://en.wikipedia.org/wiki/ISO_8601)) at which the company was last modified. + """ + updatedAt: DateTime! +} + +""" +A company's main point of contact. +""" +type CompanyContact { + """ + The date and time ([ISO 8601 format](http://en.wikipedia.org/wiki/ISO_8601)) + at which the company contact was created in Shopify. + """ + createdAt: DateTime! + + """ + The ID of the company. + """ + id: ID! + + """ + The company contact's locale (language). + """ + locale: String + + """ + The company contact's job title. + """ + title: String + + """ + The date and time ([ISO 8601 format](http://en.wikipedia.org/wiki/ISO_8601)) + at which the company contact was last modified. + """ + updatedAt: DateTime! +} + +""" +A company's location. +""" +type CompanyLocation implements HasMetafields { + """ + The date and time ([ISO 8601 format](http://en.wikipedia.org/wiki/ISO_8601)) + at which the company location was created in Shopify. + """ + createdAt: DateTime! + + """ + A unique externally-supplied ID for the company. + """ + externalId: String + + """ + The ID of the company. + """ + id: ID! + + """ + The preferred locale of the company location. + """ + locale: String + + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield + + """ + The name of the company location. + """ + name: String! + + """ + The number of orders placed at this company location. + """ + ordersCount: Int! + + """ + The total amount spent at this company location. + """ + totalSpent: MoneyV2! + + """ + The date and time ([ISO 8601 format](http://en.wikipedia.org/wiki/ISO_8601)) + at which the company location was last modified. + """ + updatedAt: DateTime! +} + +""" +The country for which the store is customized, reflecting local preferences and regulations. +Localization might influence the language, currency, and product offerings available in a store to enhance +the shopping experience for customers in that region. +""" +type Country { + """ + The ISO code of the country. + """ + isoCode: CountryCode! +} + +""" +The code designating a country/region, which generally follows ISO 3166-1 alpha-2 guidelines. +If a territory doesn't have a country code value in the `CountryCode` enum, then it might be considered a subdivision +of another country. For example, the territories associated with Spain are represented by the country code `ES`, +and the territories associated with the United States of America are represented by the country code `US`. +""" +enum CountryCode { + """ + Ascension Island. + """ + AC + + """ + Andorra. + """ + AD + + """ + United Arab Emirates. + """ + AE + + """ + Afghanistan. + """ + AF + + """ + Antigua & Barbuda. + """ + AG + + """ + Anguilla. + """ + AI + + """ + Albania. + """ + AL + + """ + Armenia. + """ + AM + + """ + Netherlands Antilles. + """ + AN + + """ + Angola. + """ + AO + + """ + Argentina. + """ + AR + + """ + Austria. + """ + AT + + """ + Australia. + """ + AU + + """ + Aruba. + """ + AW + + """ + Åland Islands. + """ + AX + + """ + Azerbaijan. + """ + AZ + + """ + Bosnia & Herzegovina. + """ + BA + + """ + Barbados. + """ + BB + + """ + Bangladesh. + """ + BD + + """ + Belgium. + """ + BE + + """ + Burkina Faso. + """ + BF + + """ + Bulgaria. + """ + BG + + """ + Bahrain. + """ + BH + + """ + Burundi. + """ + BI + + """ + Benin. + """ + BJ + + """ + St. Barthélemy. + """ + BL + + """ + Bermuda. + """ + BM + + """ + Brunei. + """ + BN + + """ + Bolivia. + """ + BO + + """ + Caribbean Netherlands. + """ + BQ + + """ + Brazil. + """ + BR + + """ + Bahamas. + """ + BS + + """ + Bhutan. + """ + BT + + """ + Bouvet Island. + """ + BV + + """ + Botswana. + """ + BW + + """ + Belarus. + """ + BY + + """ + Belize. + """ + BZ + + """ + Canada. + """ + CA + + """ + Cocos (Keeling) Islands. + """ + CC + + """ + Congo - Kinshasa. + """ + CD + + """ + Central African Republic. + """ + CF + + """ + Congo - Brazzaville. + """ + CG + + """ + Switzerland. + """ + CH + + """ + Côte d’Ivoire. + """ + CI + + """ + Cook Islands. + """ + CK + + """ + Chile. + """ + CL + + """ + Cameroon. + """ + CM + + """ + China. + """ + CN + + """ + Colombia. + """ + CO + + """ + Costa Rica. + """ + CR + + """ + Cuba. + """ + CU + + """ + Cape Verde. + """ + CV + + """ + Curaçao. + """ + CW + + """ + Christmas Island. + """ + CX + + """ + Cyprus. + """ + CY + + """ + Czechia. + """ + CZ + + """ + Germany. + """ + DE + + """ + Djibouti. + """ + DJ + + """ + Denmark. + """ + DK + + """ + Dominica. + """ + DM + + """ + Dominican Republic. + """ + DO + + """ + Algeria. + """ + DZ + + """ + Ecuador. + """ + EC + + """ + Estonia. + """ + EE + + """ + Egypt. + """ + EG + + """ + Western Sahara. + """ + EH + + """ + Eritrea. + """ + ER + + """ + Spain. + """ + ES + + """ + Ethiopia. + """ + ET + + """ + Finland. + """ + FI + + """ + Fiji. + """ + FJ + + """ + Falkland Islands. + """ + FK + + """ + Faroe Islands. + """ + FO + + """ + France. + """ + FR + + """ + Gabon. + """ + GA + + """ + United Kingdom. + """ + GB + + """ + Grenada. + """ + GD + + """ + Georgia. + """ + GE + + """ + French Guiana. + """ + GF + + """ + Guernsey. + """ + GG + + """ + Ghana. + """ + GH + + """ + Gibraltar. + """ + GI + + """ + Greenland. + """ + GL + + """ + Gambia. + """ + GM + + """ + Guinea. + """ + GN + + """ + Guadeloupe. + """ + GP + + """ + Equatorial Guinea. + """ + GQ + + """ + Greece. + """ + GR + + """ + South Georgia & South Sandwich Islands. + """ + GS + + """ + Guatemala. + """ + GT + + """ + Guinea-Bissau. + """ + GW + + """ + Guyana. + """ + GY + + """ + Hong Kong SAR. + """ + HK + + """ + Heard & McDonald Islands. + """ + HM + + """ + Honduras. + """ + HN + + """ + Croatia. + """ + HR + + """ + Haiti. + """ + HT + + """ + Hungary. + """ + HU + + """ + Indonesia. + """ + ID + + """ + Ireland. + """ + IE + + """ + Israel. + """ + IL + + """ + Isle of Man. + """ + IM + + """ + India. + """ + IN + + """ + British Indian Ocean Territory. + """ + IO + + """ + Iraq. + """ + IQ + + """ + Iran. + """ + IR + + """ + Iceland. + """ + IS + + """ + Italy. + """ + IT + + """ + Jersey. + """ + JE + + """ + Jamaica. + """ + JM + + """ + Jordan. + """ + JO + + """ + Japan. + """ + JP + + """ + Kenya. + """ + KE + + """ + Kyrgyzstan. + """ + KG + + """ + Cambodia. + """ + KH + + """ + Kiribati. + """ + KI + + """ + Comoros. + """ + KM + + """ + St. Kitts & Nevis. + """ + KN + + """ + North Korea. + """ + KP + + """ + South Korea. + """ + KR + + """ + Kuwait. + """ + KW + + """ + Cayman Islands. + """ + KY + + """ + Kazakhstan. + """ + KZ + + """ + Laos. + """ + LA + + """ + Lebanon. + """ + LB + + """ + St. Lucia. + """ + LC + + """ + Liechtenstein. + """ + LI + + """ + Sri Lanka. + """ + LK + + """ + Liberia. + """ + LR + + """ + Lesotho. + """ + LS + + """ + Lithuania. + """ + LT + + """ + Luxembourg. + """ + LU + + """ + Latvia. + """ + LV + + """ + Libya. + """ + LY + + """ + Morocco. + """ + MA + + """ + Monaco. + """ + MC + + """ + Moldova. + """ + MD + + """ + Montenegro. + """ + ME + + """ + St. Martin. + """ + MF + + """ + Madagascar. + """ + MG + + """ + North Macedonia. + """ + MK + + """ + Mali. + """ + ML + + """ + Myanmar (Burma). + """ + MM + + """ + Mongolia. + """ + MN + + """ + Macao SAR. + """ + MO + + """ + Martinique. + """ + MQ + + """ + Mauritania. + """ + MR + + """ + Montserrat. + """ + MS + + """ + Malta. + """ + MT + + """ + Mauritius. + """ + MU + + """ + Maldives. + """ + MV + + """ + Malawi. + """ + MW + + """ + Mexico. + """ + MX + + """ + Malaysia. + """ + MY + + """ + Mozambique. + """ + MZ + + """ + Namibia. + """ + NA + + """ + New Caledonia. + """ + NC + + """ + Niger. + """ + NE + + """ + Norfolk Island. + """ + NF + + """ + Nigeria. + """ + NG + + """ + Nicaragua. + """ + NI + + """ + Netherlands. + """ + NL + + """ + Norway. + """ + NO + + """ + Nepal. + """ + NP + + """ + Nauru. + """ + NR + + """ + Niue. + """ + NU + + """ + New Zealand. + """ + NZ + + """ + Oman. + """ + OM + + """ + Panama. + """ + PA + + """ + Peru. + """ + PE + + """ + French Polynesia. + """ + PF + + """ + Papua New Guinea. + """ + PG + + """ + Philippines. + """ + PH + + """ + Pakistan. + """ + PK + + """ + Poland. + """ + PL + + """ + St. Pierre & Miquelon. + """ + PM + + """ + Pitcairn Islands. + """ + PN + + """ + Palestinian Territories. + """ + PS + + """ + Portugal. + """ + PT + + """ + Paraguay. + """ + PY + + """ + Qatar. + """ + QA + + """ + Réunion. + """ + RE + + """ + Romania. + """ + RO + + """ + Serbia. + """ + RS + + """ + Russia. + """ + RU + + """ + Rwanda. + """ + RW + + """ + Saudi Arabia. + """ + SA + + """ + Solomon Islands. + """ + SB + + """ + Seychelles. + """ + SC + + """ + Sudan. + """ + SD + + """ + Sweden. + """ + SE + + """ + Singapore. + """ + SG + + """ + St. Helena. + """ + SH + + """ + Slovenia. + """ + SI + + """ + Svalbard & Jan Mayen. + """ + SJ + + """ + Slovakia. + """ + SK + + """ + Sierra Leone. + """ + SL + + """ + San Marino. + """ + SM + + """ + Senegal. + """ + SN + + """ + Somalia. + """ + SO + + """ + Suriname. + """ + SR + + """ + South Sudan. + """ + SS + + """ + São Tomé & Príncipe. + """ + ST + + """ + El Salvador. + """ + SV + + """ + Sint Maarten. + """ + SX + + """ + Syria. + """ + SY + + """ + Eswatini. + """ + SZ + + """ + Tristan da Cunha. + """ + TA + + """ + Turks & Caicos Islands. + """ + TC + + """ + Chad. + """ + TD + + """ + French Southern Territories. + """ + TF + + """ + Togo. + """ + TG + + """ + Thailand. + """ + TH + + """ + Tajikistan. + """ + TJ + + """ + Tokelau. + """ + TK + + """ + Timor-Leste. + """ + TL + + """ + Turkmenistan. + """ + TM + + """ + Tunisia. + """ + TN + + """ + Tonga. + """ + TO + + """ + Türkiye. + """ + TR + + """ + Trinidad & Tobago. + """ + TT + + """ + Tuvalu. + """ + TV + + """ + Taiwan. + """ + TW + + """ + Tanzania. + """ + TZ + + """ + Ukraine. + """ + UA + + """ + Uganda. + """ + UG + + """ + U.S. Outlying Islands. + """ + UM + + """ + Unknown country code. + """ + UNKNOWN__ + + """ + United States. + """ + US + + """ + Uruguay. + """ + UY + + """ + Uzbekistan. + """ + UZ + + """ + Vatican City. + """ + VA + + """ + St. Vincent & Grenadines. + """ + VC + + """ + Venezuela. + """ + VE + + """ + British Virgin Islands. + """ + VG + + """ + Vietnam. + """ + VN + + """ + Vanuatu. + """ + VU + + """ + Wallis & Futuna. + """ + WF + + """ + Samoa. + """ + WS + + """ + Kosovo. + """ + XK + + """ + Yemen. + """ + YE + + """ + Mayotte. + """ + YT + + """ + South Africa. + """ + ZA + + """ + Zambia. + """ + ZM + + """ + Zimbabwe. + """ + ZW + + """ + Unknown Region. + """ + ZZ +} + +""" +The currency codes that represent the world currencies throughout the Admin API. Currency codes include +[standard ISO 4217 codes](https://en.wikipedia.org/wiki/ISO_4217), legacy codes, non-standard codes, +digital currency codes. +""" +enum CurrencyCode { + """ + United Arab Emirates Dirham (AED). + """ + AED + + """ + Afghan Afghani (AFN). + """ + AFN + + """ + Albanian Lek (ALL). + """ + ALL + + """ + Armenian Dram (AMD). + """ + AMD + + """ + Netherlands Antillean Guilder. + """ + ANG + + """ + Angolan Kwanza (AOA). + """ + AOA + + """ + Argentine Pesos (ARS). + """ + ARS + + """ + Australian Dollars (AUD). + """ + AUD + + """ + Aruban Florin (AWG). + """ + AWG + + """ + Azerbaijani Manat (AZN). + """ + AZN + + """ + Bosnia and Herzegovina Convertible Mark (BAM). + """ + BAM + + """ + Barbadian Dollar (BBD). + """ + BBD + + """ + Bangladesh Taka (BDT). + """ + BDT + + """ + Bulgarian Lev (BGN). + """ + BGN + + """ + Bahraini Dinar (BHD). + """ + BHD + + """ + Burundian Franc (BIF). + """ + BIF + + """ + Bermudian Dollar (BMD). + """ + BMD + + """ + Brunei Dollar (BND). + """ + BND + + """ + Bolivian Boliviano (BOB). + """ + BOB + + """ + Brazilian Real (BRL). + """ + BRL + + """ + Bahamian Dollar (BSD). + """ + BSD + + """ + Bhutanese Ngultrum (BTN). + """ + BTN + + """ + Botswana Pula (BWP). + """ + BWP + + """ + Belarusian Ruble (BYN). + """ + BYN + + """ + Belarusian Ruble (BYR). + """ + BYR @deprecated(reason: "Use `BYN` instead.") + + """ + Belize Dollar (BZD). + """ + BZD + + """ + Canadian Dollars (CAD). + """ + CAD + + """ + Congolese franc (CDF). + """ + CDF + + """ + Swiss Francs (CHF). + """ + CHF + + """ + Chilean Peso (CLP). + """ + CLP + + """ + Chinese Yuan Renminbi (CNY). + """ + CNY + + """ + Colombian Peso (COP). + """ + COP + + """ + Costa Rican Colones (CRC). + """ + CRC + + """ + Cape Verdean escudo (CVE). + """ + CVE + + """ + Czech Koruny (CZK). + """ + CZK + + """ + Djiboutian Franc (DJF). + """ + DJF + + """ + Danish Kroner (DKK). + """ + DKK + + """ + Dominican Peso (DOP). + """ + DOP + + """ + Algerian Dinar (DZD). + """ + DZD + + """ + Egyptian Pound (EGP). + """ + EGP + + """ + Eritrean Nakfa (ERN). + """ + ERN + + """ + Ethiopian Birr (ETB). + """ + ETB + + """ + Euro (EUR). + """ + EUR + + """ + Fijian Dollars (FJD). + """ + FJD + + """ + Falkland Islands Pounds (FKP). + """ + FKP + + """ + United Kingdom Pounds (GBP). + """ + GBP + + """ + Georgian Lari (GEL). + """ + GEL + + """ + Ghanaian Cedi (GHS). + """ + GHS + + """ + Gibraltar Pounds (GIP). + """ + GIP + + """ + Gambian Dalasi (GMD). + """ + GMD + + """ + Guinean Franc (GNF). + """ + GNF + + """ + Guatemalan Quetzal (GTQ). + """ + GTQ + + """ + Guyanese Dollar (GYD). + """ + GYD + + """ + Hong Kong Dollars (HKD). + """ + HKD + + """ + Honduran Lempira (HNL). + """ + HNL + + """ + Croatian Kuna (HRK). + """ + HRK + + """ + Haitian Gourde (HTG). + """ + HTG + + """ + Hungarian Forint (HUF). + """ + HUF + + """ + Indonesian Rupiah (IDR). + """ + IDR + + """ + Israeli New Shekel (NIS). + """ + ILS + + """ + Indian Rupees (INR). + """ + INR + + """ + Iraqi Dinar (IQD). + """ + IQD + + """ + Iranian Rial (IRR). + """ + IRR + + """ + Icelandic Kronur (ISK). + """ + ISK + + """ + Jersey Pound. + """ + JEP + + """ + Jamaican Dollars (JMD). + """ + JMD + + """ + Jordanian Dinar (JOD). + """ + JOD + + """ + Japanese Yen (JPY). + """ + JPY + + """ + Kenyan Shilling (KES). + """ + KES + + """ + Kyrgyzstani Som (KGS). + """ + KGS + + """ + Cambodian Riel. + """ + KHR + + """ + Kiribati Dollar (KID). + """ + KID + + """ + Comorian Franc (KMF). + """ + KMF + + """ + South Korean Won (KRW). + """ + KRW + + """ + Kuwaiti Dinar (KWD). + """ + KWD + + """ + Cayman Dollars (KYD). + """ + KYD + + """ + Kazakhstani Tenge (KZT). + """ + KZT + + """ + Laotian Kip (LAK). + """ + LAK + + """ + Lebanese Pounds (LBP). + """ + LBP + + """ + Sri Lankan Rupees (LKR). + """ + LKR + + """ + Liberian Dollar (LRD). + """ + LRD + + """ + Lesotho Loti (LSL). + """ + LSL + + """ + Lithuanian Litai (LTL). + """ + LTL + + """ + Latvian Lati (LVL). + """ + LVL + + """ + Libyan Dinar (LYD). + """ + LYD + + """ + Moroccan Dirham. + """ + MAD + + """ + Moldovan Leu (MDL). + """ + MDL + + """ + Malagasy Ariary (MGA). + """ + MGA + + """ + Macedonia Denar (MKD). + """ + MKD + + """ + Burmese Kyat (MMK). + """ + MMK + + """ + Mongolian Tugrik. + """ + MNT + + """ + Macanese Pataca (MOP). + """ + MOP + + """ + Mauritanian Ouguiya (MRU). + """ + MRU + + """ + Mauritian Rupee (MUR). + """ + MUR + + """ + Maldivian Rufiyaa (MVR). + """ + MVR + + """ + Malawian Kwacha (MWK). + """ + MWK + + """ + Mexican Pesos (MXN). + """ + MXN + + """ + Malaysian Ringgits (MYR). + """ + MYR + + """ + Mozambican Metical. + """ + MZN + + """ + Namibian Dollar. + """ + NAD + + """ + Nigerian Naira (NGN). + """ + NGN + + """ + Nicaraguan Córdoba (NIO). + """ + NIO + + """ + Norwegian Kroner (NOK). + """ + NOK + + """ + Nepalese Rupee (NPR). + """ + NPR + + """ + New Zealand Dollars (NZD). + """ + NZD + + """ + Omani Rial (OMR). + """ + OMR + + """ + Panamian Balboa (PAB). + """ + PAB + + """ + Peruvian Nuevo Sol (PEN). + """ + PEN + + """ + Papua New Guinean Kina (PGK). + """ + PGK + + """ + Philippine Peso (PHP). + """ + PHP + + """ + Pakistani Rupee (PKR). + """ + PKR + + """ + Polish Zlotych (PLN). + """ + PLN + + """ + Paraguayan Guarani (PYG). + """ + PYG + + """ + Qatari Rial (QAR). + """ + QAR + + """ + Romanian Lei (RON). + """ + RON + + """ + Serbian dinar (RSD). + """ + RSD + + """ + Russian Rubles (RUB). + """ + RUB + + """ + Rwandan Franc (RWF). + """ + RWF + + """ + Saudi Riyal (SAR). + """ + SAR + + """ + Solomon Islands Dollar (SBD). + """ + SBD + + """ + Seychellois Rupee (SCR). + """ + SCR + + """ + Sudanese Pound (SDG). + """ + SDG + + """ + Swedish Kronor (SEK). + """ + SEK + + """ + Singapore Dollars (SGD). + """ + SGD + + """ + Saint Helena Pounds (SHP). + """ + SHP + + """ + Sierra Leonean Leone (SLL). + """ + SLL + + """ + Somali Shilling (SOS). + """ + SOS + + """ + Surinamese Dollar (SRD). + """ + SRD + + """ + South Sudanese Pound (SSP). + """ + SSP + + """ + Sao Tome And Principe Dobra (STD). + """ + STD @deprecated(reason: "Use `STN` instead.") + + """ + Sao Tome And Principe Dobra (STN). + """ + STN + + """ + Syrian Pound (SYP). + """ + SYP + + """ + Swazi Lilangeni (SZL). + """ + SZL + + """ + Thai baht (THB). + """ + THB + + """ + Tajikistani Somoni (TJS). + """ + TJS + + """ + Turkmenistani Manat (TMT). + """ + TMT + + """ + Tunisian Dinar (TND). + """ + TND + + """ + Tongan Pa'anga (TOP). + """ + TOP + + """ + Turkish Lira (TRY). + """ + TRY + + """ + Trinidad and Tobago Dollars (TTD). + """ + TTD + + """ + Taiwan Dollars (TWD). + """ + TWD + + """ + Tanzanian Shilling (TZS). + """ + TZS + + """ + Ukrainian Hryvnia (UAH). + """ + UAH + + """ + Ugandan Shilling (UGX). + """ + UGX + + """ + United States Dollars (USD). + """ + USD + + """ + United States Dollars Coin (USDC). + """ + USDC + + """ + Uruguayan Pesos (UYU). + """ + UYU + + """ + Uzbekistan som (UZS). + """ + UZS + + """ + Venezuelan Bolivares (VED). + """ + VED + + """ + Venezuelan Bolivares (VEF). + """ + VEF @deprecated(reason: "Use `VES` instead.") + + """ + Venezuelan Bolivares Soberanos (VES). + """ + VES + + """ + Vietnamese đồng (VND). + """ + VND + + """ + Vanuatu Vatu (VUV). + """ + VUV + + """ + Samoan Tala (WST). + """ + WST + + """ + Central African CFA Franc (XAF). + """ + XAF + + """ + East Caribbean Dollar (XCD). + """ + XCD + + """ + West African CFA franc (XOF). + """ + XOF + + """ + CFP Franc (XPF). + """ + XPF + + """ + Unrecognized currency. + """ + XXX + + """ + Yemeni Rial (YER). + """ + YER + + """ + South African Rand (ZAR). + """ + ZAR + + """ + Zambian Kwacha (ZMW). + """ + ZMW +} + +""" +A custom product represents a product that doesn't map to Shopify's +[standard product categories](https://help.shopify.com/manual/products/details/product-type). +For example, you can use a custom product to manage gift cards, shipping requirements, localized product +information, or weight measurements and conversions. +""" +type CustomProduct { + """ + Whether the merchandise is a gift card. + """ + isGiftCard: Boolean! + + """ + Whether the item needs to be shipped to the customer. For example, a + digital gift card doesn't need to be shipped, but a t-shirt does + need to be shipped. + """ + requiresShipping: Boolean! + + """ + The localized name for the product that displays to customers. The title is used to construct the product's + handle, which is a unique, human-readable string of the product's title. For example, if a product is titled + "Black Sunglasses", then the handle is `black-sunglasses`. + """ + title: String! + + """ + The product variant's weight, in the system of measurement set in the `weightUnit` field. + """ + weight: Float + + """ + The unit of measurement for weight. + """ + weightUnit: WeightUnit! +} + +""" +Represents a [customer](https://help.shopify.com/manual/customers/manage-customers). +`Customer` returns data including the customer's contact information and order history. +""" +type Customer implements HasMetafields { + """ + The total amount that the customer has spent on orders. + The amount is converted from the shop's currency to the currency of the cart using a market rate. + """ + amountSpent: MoneyV2! + + """ + The full name of the customer, based on the values for `firstName` and `lastName`. + If `firstName` and `lastName` aren't specified, then the value is the customer's email address. + If the email address isn't specified, then the value is the customer's phone number. + """ + displayName: String! + + """ + The customer's email address. + """ + email: String + + """ + The customer's first name. + """ + firstName: String + + """ + Whether the customer is associated with any of the specified tags. The customer must have at least one tag + from the list to return `true`. + """ + hasAnyTag( + """ + A comma-separated list of searchable keywords that are associated with the customer. For example, + `"VIP, Gold"` returns customers with either the `VIP` or `Gold` tag. + """ + tags: [String!]! = [] + ): Boolean! + + """ + Whether the customer is associated with the specified tags. + """ + hasTags( + """ + A comma-separated list of searchable keywords that are associated with the customer. For example, + `"VIP, Gold"` returns customers with both the `VIP` and `Gold` tags. + """ + tags: [String!]! = [] + ): [HasTagResponse!]! + + """ + A [globally-unique ID](https://shopify.dev/docs/api/usage/gids) + for the customer. + """ + id: ID! + + """ + The customer's last name. + """ + lastName: String + + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield + + """ + The total number of orders that the customer has made at the store. + """ + numberOfOrders: Int! +} + +""" +Represents an [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601)-encoded date string. +For example, September 7, 2019 is represented as `"2019-07-16"`. +""" +scalar Date + +""" +Represents an [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601)-encoded date and time string. +For example, 3:50 pm on September 7, 2019 in the time zone of UTC (Coordinated Universal Time) is +represented as `"2019-09-07T15:50:00Z`". +""" +scalar DateTime + +""" +A subset of the [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format that +includes the date and time but not the timezone which is determined from context. + +For example, "2018-01-01T00:00:00". +""" +scalar DateTimeWithoutTimezone + +""" +A signed decimal number, which supports arbitrary precision and is serialized as a string. + +Example values: `"29.99"`, `"29.999"`. +""" +scalar Decimal + +""" +Represents information about the merchandise in the cart. +""" +type DeliverableCartLine { + """ + The custom attributes associated with a cart to store additional information. Cart attributes + allow you to collect specific information from customers on the **Cart** page, such as order notes, + gift wrapping requests, or custom product details. Attributes are stored as key-value pairs. + + Cart line attributes are equivalent to the + [`line_item`](https://shopify.dev/docs/api/liquid/objects/line_item) + object in Liquid. + """ + attribute( + """ + The key of the cart attribute to retrieve. For example, `"gift_wrapping"`. + """ + key: String + ): Attribute + + """ + The ID of the cart line. + """ + id: ID! + + """ + The item that the customer intends to purchase. + """ + merchandise: Merchandise! + + """ + The quantity of the item that the customer intends to purchase. + """ + quantity: Int! +} + +""" +List of different delivery method types. +""" +enum DeliveryMethod { + """ + Local Delivery. + """ + LOCAL + + """ + None. + """ + NONE + + """ + Shipping to a Pickup Point. + """ + PICKUP_POINT + + """ + Local Pickup. + """ + PICK_UP + + """ + Retail. + """ + RETAIL + + """ + Shipping. + """ + SHIPPING +} + +""" +The discount application and the amount applied. +""" +type DiscountAllocation { + """ + The discount that was applied. + """ + discountApplication: DiscountApplication! + + """ + The amount that was discounted. + """ + discountedAmount: MoneyV2! +} + +""" +Discount that has been applied to the cart. +""" +type DiscountApplication implements HasMetafields { + """ + The method by which the discount's value is allocated to its entitled items. + """ + allocationMethod: DiscountApplicationAllocationMethod! + + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield + + """ + The lines on the cart targeted by the discount. + """ + targetSelection: DiscountApplicationTargetSelection! + + """ + The type of line (i.e. line item or shipping line) on a cart that the discount is applicable towards. + """ + targetType: DiscountApplicationTarget! + + """ + The total allocated amount of the discount across all items. + """ + totalAllocatedAmount: MoneyV2! + + """ + The value of the discount. + """ + value: PricingValue! +} + +""" +The method by which the discount's value is allocated onto its entitled lines. +""" +enum DiscountApplicationAllocationMethod { + """ + The value is spread across all entitled lines. + """ + ACROSS + + """ + The value is applied onto every entitled line. + """ + EACH +} + +""" +The type of line on an order that the discount is applicable towards. +""" +enum DiscountApplicationTarget { + """ + The discount applies onto line items. + """ + LINE_ITEM + + """ + The discount applies onto shipping lines. + """ + SHIPPING_LINE +} + +""" +The lines on the order to which the discount is applied, of the type defined by +the discount application's `targetType`. For example, the value `ENTITLED`, combined with a `targetType` of +`LINE_ITEM`, applies the discount on all line items that are entitled to the discount. +The value `ALL`, combined with a `targetType` of `SHIPPING_LINE`, applies the discount on all shipping lines. +""" +enum DiscountApplicationTargetSelection { + """ + The discount is allocated onto all the lines. + """ + ALL + + """ + The discount is allocated onto only the lines that it's entitled for. + """ + ENTITLED + + """ + The discount is allocated onto explicitly chosen lines. + """ + EXPLICIT +} + +""" +An ISO 8601 duration string. For example: "P2D", "PT8H", "PT0S". +""" +scalar Duration + +""" +A set of one or more packages traveling together from a single origin +address to a single destination address. The function generates one or +more `FulfillmentOption`s per fulfillment. +""" +type Fulfillment { + """ + Handle of the fulfillment's destination address reference in `address_references`. + """ + destinationAddressHandle: Handle! + + """ + Stable handle identifying the fulfillment within the function input. + """ + handle: Handle! + + """ + Handle of the fulfillment's origin address reference in `address_references`. + """ + originAddressHandle: Handle! + + """ + The packages that make up the fulfillment. + """ + packages: [Package!]! +} + +""" +A polymorphic address used as the origin or destination of a fulfillment. + +- `MailingAddress`: a specific buyer-facing mailing address. +- `Location`: a merchant location, such as a retail store or warehouse. +- `ServiceArea`: a region (e.g. a pickup-point service area). +""" +union FulfillmentAddress = Location | MailingAddress | ServiceArea + +""" +A deduplicated fulfillment address referenced by a `Handle`. Fulfillments +reference addresses through their handle so the same address never has to +be serialized into the function input twice. +""" +type FulfillmentAddressReference { + """ + The polymorphic fulfillment address. + """ + address: FulfillmentAddress! + + """ + Stable handle identifying this fulfillment address reference within the function input. + """ + handle: Handle! +} + +""" +The fulfillment option generator the function instance is bound to. +""" +type FulfillmentOptionGenerator implements HasMetafields { + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield +} + +""" +Add a single fulfillment option for a specific fulfillment. +""" +input FulfillmentOptionsAddOperation { + """ + The specific carrier service level or service point to uniquely identify each fulfillment option in the context + of a single input fulfillment. + """ + code: String + + """ + Cost of the fulfillment option. Null defaults to 0 or a configured fallback. + """ + cost: MoneyV2Output + + """ + Override the destination address by referencing a service point in + `References.service_points` by handle. Required when the fulfillment's destination + address is a service area. + """ + destinationServicePointHandle: Handle + + """ + Handle of the input fulfillment this fulfillment option applies to. + """ + fulfillmentHandle: Handle! + + """ + Instructions shown to the buyer about how to receive the fulfillment, localized. + """ + instructions: String + + """ + Metafields associated with the fulfillment option. + """ + metafields: [MetafieldOutput!] = [] + + """ + Reference to a provider in `References.providers` by handle. + """ + providerHandle: Handle + + """ + Estimated fulfillment time period. Null means a `start` and `end` of + `after` P0D (zero duration). + """ + timePeriod: TimePeriod + + """ + Human-facing display name, localized. Can be a carrier service level or service point name. + """ + title: String +} + +""" +Represents a fulfillment service that prepares and ships orders on behalf of the store owner. +""" +type FulfillmentService { + """ + The app associated with this fulfillment service. + """ + app: App +} + +""" +A function-scoped handle to a refer a resource. +The Handle type appears in a JSON response as a String, but it is not intended to be human-readable. +Example value: `"10079785100"` +""" +scalar Handle + +""" +Represents information about the metafields associated to the specified resource. +""" +interface HasMetafields { + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield +} + +""" +Whether a Shopify resource, such as a product or customer, has a specified tag. +""" +type HasTagResponse { + """ + Whether the Shopify resource has the tag. + """ + hasTag: Boolean! + + """ + A searchable keyword that's associated with a Shopify resource, such as a product or customer. For example, + a merchant might apply the `sports` and `summer` tags to products that are associated with sportswear for + summer. + """ + tag: String! +} + +""" +The attributes associated with an HTTP request. +""" +input HttpRequest { + """ + The HTTP request body as a plain string. + Use this field when the body isn't in JSON format. + """ + body: String + + """ + The HTTP headers. + """ + headers: [HttpRequestHeader!]! + + """ + The HTTP request body as a JSON object. + Use this field when the body's in JSON format, to reduce function instruction consumption + and to ensure the body's formatted in logs. + Don't use this field together with the `body` field. If both are provided, then the `body` field + will take precedence. + If this field is specified and no `Content-Type` header is included, then the header will + automatically be set to `application/json`. + """ + jsonBody: JSON + + """ + The HTTP method. + """ + method: HttpRequestMethod! + + """ + Policy attached to the HTTP request. + """ + policy: HttpRequestPolicy! + + """ + The HTTP url (eg.: https://example.com). The scheme needs to be HTTPS. + """ + url: URL! +} + +""" +The attributes associated with an HTTP request header. +""" +input HttpRequestHeader { + """ + Header name. + """ + name: String! + + """ + Header value. + """ + value: String! +} + +""" +The HTTP request available methods. +""" +enum HttpRequestMethod { + """ + Http GET. + """ + GET + + """ + Http POST. + """ + POST +} + +""" +The attributes associated with an HTTP request policy. +""" +input HttpRequestPolicy { + """ + Read timeout in milliseconds. + """ + readTimeoutMs: Int! +} + +""" +The attributes associated with an HTTP response. +""" +type HttpResponse { + """ + The HTTP response body as a plain string. + Use this field when the body is not in JSON format. + """ + body: String + + """ + An HTTP header. + """ + header( + """ + A case-insensitive header name. + """ + name: String! + ): HttpResponseHeader + + """ + The HTTP headers. + """ + headers: [HttpResponseHeader!]! @deprecated(reason: "Use `header` instead.") + + """ + The HTTP response body parsed as JSON. + If the body is valid JSON, it will be parsed and returned as a JSON object. + If parsing fails, then raw body is returned as a string. + Use this field when you expect the response to be JSON, or when you're dealing + with mixed response types, meaning both JSON and non-JSON. + Using this field reduces function instruction consumption and ensures that the data is formatted in logs. + To prevent increasing the function target input size unnecessarily, avoid querying + both `body` and `jsonBody` simultaneously. + """ + jsonBody: JSON + + """ + The HTTP status code. + """ + status: Int! +} + +""" +The attributes associated with an HTTP response header. +""" +type HttpResponseHeader { + """ + Header name. + """ + name: String! + + """ + Header value. + """ + value: String! +} + +""" +Represents a unique identifier, often used to refetch an object. +The ID type appears in a JSON response as a String, but it is not intended to be human-readable. + +Example value: `"gid://shopify/Product/10079785100"` +""" +scalar ID + +type Input { + """ + Deduplicated list of fulfillment addresses referenced by fulfillments via + `Fulfillment.origin_address_handle` and + `Fulfillment.destination_address_handle`. Each reference's address can be + any variant of `FulfillmentAddress`. + """ + addressReferences: [FulfillmentAddressReference!]! + + """ + The cart where the Function is running. A cart contains the merchandise that a customer intends to purchase + and information about the customer, such as the customer's email address and phone number. + """ + cart: Cart! + + """ + The HTTP response produced by the function's `fetch` target. Available only on `run`. + """ + fetchResult: HttpResponse @restrictTarget(only: ["cart.fulfillment-options.generate.run"]) + + """ + The backend `DeliveryOptionGenerator` record this function instance is + bound to. Includes the metafields associated with the generator. + """ + fulfillmentOptionGenerator: FulfillmentOptionGenerator! + + """ + The fulfillments the function should produce fulfillment options for. Each + fulfillment has an origin, a destination, and a set of packages. + """ + fulfillments: [Fulfillment!]! @scaleLimits(rate: 0.05) + + """ + The regional and language settings that determine how the Function + handles currency, numbers, dates, and other locale-specific values + during discount calculations. These settings are based on the store's configured + [localization practices](https://shopify.dev/docs/apps/build/functions/localization-practices-shopify-functions). + """ + localization: Localization! + + """ + The exchange rate used to convert discounts between the shop's default + currency and the currency that displays to the customer during checkout. + For example, if a store operates in USD but a customer is viewing discounts in EUR, + then the presentment currency rate handles this conversion for accurate pricing. + """ + presentmentCurrencyRate: Decimal! + + """ + Information about the shop where the Function is running, including the shop's timezone + setting and associated [metafields](https://shopify.dev/docs/apps/build/custom-data). + """ + shop: Shop! +} + +""" +A [JSON](https://www.json.org/json-en.html) object. + +Example value: +`{ + "product": { + "id": "gid://shopify/Product/1346443542550", + "title": "White T-shirt", + "options": [{ + "name": "Size", + "values": ["M", "L"] + }] + } +}` +""" +scalar JSON + +""" +The language for which the store is customized, ensuring content is tailored to local customers. +This includes product descriptions and customer communications that resonate with the target audience. +""" +type Language { + """ + The ISO code. + """ + isoCode: LanguageCode! +} + +""" +Language codes supported by Shopify. +""" +enum LanguageCode { + """ + Afrikaans. + """ + AF + + """ + Akan. + """ + AK + + """ + Amharic. + """ + AM + + """ + Arabic. + """ + AR + + """ + Assamese. + """ + AS + + """ + Azerbaijani. + """ + AZ + + """ + Belarusian. + """ + BE + + """ + Bulgarian. + """ + BG + + """ + Bambara. + """ + BM + + """ + Bangla. + """ + BN + + """ + Tibetan. + """ + BO + + """ + Breton. + """ + BR + + """ + Bosnian. + """ + BS + + """ + Catalan. + """ + CA + + """ + Chechen. + """ + CE + + """ + Central Kurdish. + """ + CKB + + """ + Czech. + """ + CS + + """ + Church Slavic. + """ + CU + + """ + Welsh. + """ + CY + + """ + Danish. + """ + DA + + """ + German. + """ + DE + + """ + Dzongkha. + """ + DZ + + """ + Ewe. + """ + EE + + """ + Greek. + """ + EL + + """ + English. + """ + EN + + """ + Esperanto. + """ + EO + + """ + Spanish. + """ + ES + + """ + Estonian. + """ + ET + + """ + Basque. + """ + EU + + """ + Persian. + """ + FA + + """ + Fulah. + """ + FF + + """ + Finnish. + """ + FI + + """ + Filipino. + """ + FIL + + """ + Faroese. + """ + FO + + """ + French. + """ + FR + + """ + Western Frisian. + """ + FY + + """ + Irish. + """ + GA + + """ + Scottish Gaelic. + """ + GD + + """ + Galician. + """ + GL + + """ + Gujarati. + """ + GU + + """ + Manx. + """ + GV + + """ + Hausa. + """ + HA + + """ + Hebrew. + """ + HE + + """ + Hindi. + """ + HI + + """ + Croatian. + """ + HR + + """ + Hungarian. + """ + HU + + """ + Armenian. + """ + HY + + """ + Interlingua. + """ + IA + + """ + Indonesian. + """ + ID + + """ + Igbo. + """ + IG + + """ + Sichuan Yi. + """ + II + + """ + Icelandic. + """ + IS + + """ + Italian. + """ + IT + + """ + Japanese. + """ + JA + + """ + Javanese. + """ + JV + + """ + Georgian. + """ + KA + + """ + Kikuyu. + """ + KI + + """ + Kazakh. + """ + KK + + """ + Kalaallisut. + """ + KL + + """ + Khmer. + """ + KM + + """ + Kannada. + """ + KN + + """ + Korean. + """ + KO + + """ + Kashmiri. + """ + KS + + """ + Kurdish. + """ + KU + + """ + Cornish. + """ + KW + + """ + Kyrgyz. + """ + KY + + """ + Luxembourgish. + """ + LB + + """ + Ganda. + """ + LG + + """ + Lingala. + """ + LN + + """ + Lao. + """ + LO + + """ + Lithuanian. + """ + LT + + """ + Luba-Katanga. + """ + LU + + """ + Latvian. + """ + LV + + """ + Malagasy. + """ + MG + + """ + Māori. + """ + MI + + """ + Macedonian. + """ + MK + + """ + Malayalam. + """ + ML + + """ + Mongolian. + """ + MN + + """ + Marathi. + """ + MR + + """ + Malay. + """ + MS + + """ + Maltese. + """ + MT + + """ + Burmese. + """ + MY + + """ + Norwegian (Bokmål). + """ + NB + + """ + North Ndebele. + """ + ND + + """ + Nepali. + """ + NE + + """ + Dutch. + """ + NL + + """ + Norwegian Nynorsk. + """ + NN + + """ + Norwegian. + """ + NO + + """ + Oromo. + """ + OM + + """ + Odia. + """ + OR + + """ + Ossetic. + """ + OS + + """ + Punjabi. + """ + PA + + """ + Polish. + """ + PL + + """ + Pashto. + """ + PS + + """ + Portuguese. + """ + PT + + """ + Portuguese (Brazil). + """ + PT_BR + + """ + Portuguese (Portugal). + """ + PT_PT + + """ + Quechua. + """ + QU + + """ + Romansh. + """ + RM + + """ + Rundi. + """ + RN + + """ + Romanian. + """ + RO + + """ + Russian. + """ + RU + + """ + Kinyarwanda. + """ + RW + + """ + Sanskrit. + """ + SA + + """ + Sardinian. + """ + SC + + """ + Sindhi. + """ + SD + + """ + Northern Sami. + """ + SE + + """ + Sango. + """ + SG + + """ + Sinhala. + """ + SI + + """ + Slovak. + """ + SK + + """ + Slovenian. + """ + SL + + """ + Shona. + """ + SN + + """ + Somali. + """ + SO + + """ + Albanian. + """ + SQ + + """ + Serbian. + """ + SR + + """ + Sundanese. + """ + SU + + """ + Swedish. + """ + SV + + """ + Swahili. + """ + SW + + """ + Tamil. + """ + TA + + """ + Telugu. + """ + TE + + """ + Tajik. + """ + TG + + """ + Thai. + """ + TH + + """ + Tigrinya. + """ + TI + + """ + Turkmen. + """ + TK + + """ + Tongan. + """ + TO + + """ + Turkish. + """ + TR + + """ + Tatar. + """ + TT + + """ + Uyghur. + """ + UG + + """ + Ukrainian. + """ + UK + + """ + Urdu. + """ + UR + + """ + Uzbek. + """ + UZ + + """ + Vietnamese. + """ + VI + + """ + Volapük. + """ + VO + + """ + Wolof. + """ + WO + + """ + Xhosa. + """ + XH + + """ + Yiddish. + """ + YI + + """ + Yoruba. + """ + YO + + """ + Chinese. + """ + ZH + + """ + Chinese (Simplified). + """ + ZH_CN + + """ + Chinese (Traditional). + """ + ZH_TW + + """ + Zulu. + """ + ZU +} + +""" +A quantity of a single cart line included in a package. +""" +type LineQuantity { + """ + The cart line ID. + """ + lineId: ID! + + """ + The number of units of the line included in the package. Will be a positive number. + """ + quantity: Int! +} + +""" +Local pickup settings associated with a location. +""" +type LocalPickup { + """ + Whether local pickup is enabled for the location. + """ + enabled: Boolean! +} + +""" +The current time based on the +[store's timezone setting](https://help.shopify.com/manual/intro-to-shopify/initial-setup/setup-business-settings). +""" +type LocalTime { + """ + The current date relative to the parent object. + """ + date: Date! + + """ + Returns true if the current date and time is at or past the given date and time, and false otherwise. + """ + dateTimeAfter( + """ + The date and time to compare against, assumed to be in the timezone of the parent object. + """ + dateTime: DateTimeWithoutTimezone! + ): Boolean! + + """ + Returns true if the current date and time is before the given date and time, and false otherwise. + """ + dateTimeBefore( + """ + The date and time to compare against, assumed to be in the timezone of the parent timezone. + """ + dateTime: DateTimeWithoutTimezone! + ): Boolean! + + """ + Returns true if the current date and time is between the two given date and times, and false otherwise. + """ + dateTimeBetween( + """ + The upper bound time to compare against, assumed to be in the timezone of the parent timezone. + """ + endDateTime: DateTimeWithoutTimezone! + + """ + The lower bound time to compare against, assumed to be in the timezone of the parent timezone. + """ + startDateTime: DateTimeWithoutTimezone! + ): Boolean! + + """ + Returns true if the current time is at or past the given time, and false otherwise. + """ + timeAfter( + """ + The time to compare against, assumed to be in the timezone of the parent timezone. + """ + time: TimeWithoutTimezone! + ): Boolean! + + """ + Returns true if the current time is at or past the given time, and false otherwise. + """ + timeBefore( + """ + The time to compare against, assumed to be in the timezone of the parent timezone. + """ + time: TimeWithoutTimezone! + ): Boolean! + + """ + Returns true if the current time is between the two given times, and false otherwise. + """ + timeBetween( + """ + The upper bound time to compare against, assumed to be in the timezone of the parent timezone. + """ + endTime: TimeWithoutTimezone! + + """ + The lower bound time to compare against, assumed to be in the timezone of the parent timezone. + """ + startTime: TimeWithoutTimezone! + ): Boolean! +} + +""" +Details about the localized experience for the store in a specific region, including country and language +settings. The localized experience is determined by the store's settings and the customer's location. +Localization ensures that customers can access relevant content and options while browsing or purchasing +products in a store. +""" +type Localization { + """ + The country for which the store is customized, reflecting local preferences and regulations. + Localization might influence the language, currency, and product offerings available in a store to enhance + the shopping experience for customers in that region. + """ + country: Country! + + """ + The language for which the store is customized, ensuring content is tailored to local customers. + This includes product descriptions and customer communications that resonate with the target audience. + """ + language: Language! + + """ + The market of the active localized experience. + """ + market: Market! @deprecated(reason: "This `market` field will be removed in a future version of the API.") +} + +""" +Represents the value captured by a localized field. Localized fields are +additional fields required by certain countries on international orders. For +example, some countries require additional fields for customs information or tax +identification numbers. +""" +type LocalizedField { + """ + The key of the localized field. + """ + key: LocalizedFieldKey! + + """ + The title of the localized field. + """ + title: String! + + """ + The value of the localized field. + """ + value: String +} + +""" +Unique key identifying localized fields. +""" +enum LocalizedFieldKey { + """ + Localized field key 'shipping_credential_br' for country Brazil. + """ + SHIPPING_CREDENTIAL_BR + + """ + Localized field key 'shipping_credential_cl' for country Chile. + """ + SHIPPING_CREDENTIAL_CL + + """ + Localized field key 'shipping_credential_cn' for country China. + """ + SHIPPING_CREDENTIAL_CN + + """ + Localized field key 'shipping_credential_co' for country Colombia. + """ + SHIPPING_CREDENTIAL_CO + + """ + Localized field key 'shipping_credential_cr' for country Costa Rica. + """ + SHIPPING_CREDENTIAL_CR + + """ + Localized field key 'shipping_credential_ec' for country Ecuador. + """ + SHIPPING_CREDENTIAL_EC + + """ + Localized field key 'shipping_credential_es' for country Spain. + """ + SHIPPING_CREDENTIAL_ES + + """ + Localized field key 'shipping_credential_gt' for country Guatemala. + """ + SHIPPING_CREDENTIAL_GT + + """ + Localized field key 'shipping_credential_id' for country Indonesia. + """ + SHIPPING_CREDENTIAL_ID + + """ + Localized field key 'shipping_credential_kr' for country South Korea. + """ + SHIPPING_CREDENTIAL_KR + + """ + Localized field key 'shipping_credential_mx' for country Mexico. + """ + SHIPPING_CREDENTIAL_MX + + """ + Localized field key 'shipping_credential_my' for country Malaysia. + """ + SHIPPING_CREDENTIAL_MY + + """ + Localized field key 'shipping_credential_pe' for country Peru. + """ + SHIPPING_CREDENTIAL_PE + + """ + Localized field key 'shipping_credential_pt' for country Portugal. + """ + SHIPPING_CREDENTIAL_PT + + """ + Localized field key 'shipping_credential_py' for country Paraguay. + """ + SHIPPING_CREDENTIAL_PY + + """ + Localized field key 'shipping_credential_tr' for country Turkey. + """ + SHIPPING_CREDENTIAL_TR + + """ + Localized field key 'shipping_credential_tw' for country Taiwan. + """ + SHIPPING_CREDENTIAL_TW + + """ + Localized field key 'shipping_credential_type_co' for country Colombia. + """ + SHIPPING_CREDENTIAL_TYPE_CO + + """ + Localized field key 'tax_credential_br' for country Brazil. + """ + TAX_CREDENTIAL_BR + + """ + Localized field key 'tax_credential_cl' for country Chile. + """ + TAX_CREDENTIAL_CL + + """ + Localized field key 'tax_credential_co' for country Colombia. + """ + TAX_CREDENTIAL_CO + + """ + Localized field key 'tax_credential_cr' for country Costa Rica. + """ + TAX_CREDENTIAL_CR + + """ + Localized field key 'tax_credential_ec' for country Ecuador. + """ + TAX_CREDENTIAL_EC + + """ + Localized field key 'tax_credential_es' for country Spain. + """ + TAX_CREDENTIAL_ES + + """ + Localized field key 'tax_credential_gt' for country Guatemala. + """ + TAX_CREDENTIAL_GT + + """ + Localized field key 'tax_credential_id' for country Indonesia. + """ + TAX_CREDENTIAL_ID + + """ + Localized field key 'tax_credential_it' for country Italy. + """ + TAX_CREDENTIAL_IT + + """ + Localized field key 'tax_credential_mx' for country Mexico. + """ + TAX_CREDENTIAL_MX + + """ + Localized field key 'tax_credential_my' for country Malaysia. + """ + TAX_CREDENTIAL_MY + + """ + Localized field key 'tax_credential_pe' for country Peru. + """ + TAX_CREDENTIAL_PE + + """ + Localized field key 'tax_credential_pt' for country Portugal. + """ + TAX_CREDENTIAL_PT + + """ + Localized field key 'tax_credential_py' for country Paraguay. + """ + TAX_CREDENTIAL_PY + + """ + Localized field key 'tax_credential_tr' for country Turkey. + """ + TAX_CREDENTIAL_TR + + """ + Localized field key 'tax_credential_type_co' for country Colombia. + """ + TAX_CREDENTIAL_TYPE_CO + + """ + Localized field key 'tax_credential_type_mx' for country Mexico. + """ + TAX_CREDENTIAL_TYPE_MX + + """ + Localized field key 'tax_credential_use_mx' for country Mexico. + """ + TAX_CREDENTIAL_USE_MX + + """ + Localized field key 'tax_email_it' for country Italy. + """ + TAX_EMAIL_IT +} + +""" +Represents the location where the inventory resides. +""" +type Location implements HasMetafields { + """ + The address of this location. + """ + address: LocationAddress! + + """ + The fulfillment service, if any, that's associated with the location. + """ + fulfillmentService: FulfillmentService + + """ + The location handle. + """ + handle: Handle! + + """ + The location id. + """ + id: ID! + + """ + Local pickup settings associated with a location. + """ + localPickup: LocalPickup! + + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield + + """ + The name of the location. + """ + name: String! +} + +""" +Represents the address of a location. +""" +type LocationAddress { + """ + The first line of the address for the location. + """ + address1: String + + """ + The second line of the address for the location. + """ + address2: String + + """ + The city of the location. + """ + city: String + + """ + The country of the location. + """ + country: String + + """ + The country code of the location. + """ + countryCode: String + + """ + A formatted version of the address for the location. + """ + formatted: [String!]! + + """ + The approximate latitude coordinates of the location. + """ + latitude: Float + + """ + The approximate longitude coordinates of the location. + """ + longitude: Float + + """ + The phone number of the location. + """ + phone: String + + """ + The province of the location. + """ + province: String + + """ + The code for the province, state, or district of the address of the location. + """ + provinceCode: String + + """ + The ZIP code of the location. + """ + zip: String +} + +""" +Represents a mailing address. +""" +type MailingAddress { + """ + The first line of the address. Typically the street address or PO Box number. + """ + address1: String + + """ + The second line of the address. Typically the number of the apartment, suite, or unit. + """ + address2: String + + """ + The name of the city, district, village, or town. + """ + city: String + + """ + The name of the customer's company or organization. + """ + company: String + + """ + The two-letter code for the country of the address. For example, US. + """ + countryCode: CountryCode + + """ + The first name of the customer. + """ + firstName: String + + """ + The last name of the customer. + """ + lastName: String + + """ + The approximate latitude of the address. + """ + latitude: Float + + """ + The approximate longitude of the address. + """ + longitude: Float + + """ + The market of the address. + """ + market: Market @deprecated(reason: "This `market` field will be removed in a future version of the API.") + + """ + The full name of the customer, based on firstName and lastName. + """ + name: String + + """ + A unique phone number for the customer. Formatted using E.164 standard. For example, +16135551111. + """ + phone: String + + """ + The alphanumeric code for the region. For example, ON. + """ + provinceCode: String + + """ + The zip or postal code of the address. + """ + zip: String +} + +""" +A market is a group of one or more regions that you want to target for international sales. +By creating a market, you can configure a distinct, localized shopping experience for +customers from a specific area of the world. For example, you can +[change currency](https://shopify.dev/api/admin-graphql/current/mutations/marketCurrencySettingsUpdate), +[configure international pricing](https://shopify.dev/api/examples/product-price-lists), +or [add market-specific domains or subfolders](https://shopify.dev/api/admin-graphql/current/objects/MarketWebPresence). +""" +type Market implements HasMetafields { + """ + A human-readable unique string for the market automatically generated from its title. + """ + handle: Handle! + + """ + A globally-unique identifier. + """ + id: ID! + + """ + The manager of the market, if the accessing app is the market’s manager. Otherwise, this will be null. + """ + manager: MarketManager + + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield + + """ + A geographic region which comprises a market. + """ + regions: [MarketRegion!]! +} + +""" +The entity that manages a particular market. +""" +type MarketManager { + """ + The identity of the manager. This can either be `merchant` if the market is + manually managed by the merchant or an ID of the app responsible for managing the market. + """ + identifier: String! +} + +""" +Represents a region. +""" +interface MarketRegion { + """ + The name of the region in the language of the current localization. + """ + name: String +} + +""" +A country which comprises a market. +""" +type MarketRegionCountry implements MarketRegion { + """ + The two-letter code for the country. + """ + code: CountryCode! + + """ + The country name in the language of the current localization. + """ + name: String! +} + +""" +The item that a customer intends to purchase. Merchandise can be a product variant or a custom +product. + +A product variant is a specific version of a product that comes in more than one option, such as size or color. +For example, if a merchant sells t-shirts with options for size and color, then a small, blue t-shirt would be +one product variant and a large, blue t-shirt would be another. + +A custom product represents a product that doesn't map to Shopify's +[standard product categories](https://help.shopify.com/manual/products/details/product-type). +For example, you can use a custom product to manage gift cards, shipping requirements, localized product +information, or weight measurements and conversions. +""" +union Merchandise = CustomProduct | ProductVariant + +""" +[Custom fields](https://shopify.dev/docs/apps/build/custom-data) that store additional information +about a Shopify resource, such as products, orders, and +[many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). +Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) +enables you to customize the checkout experience. +""" +type Metafield { + """ + The data that's stored in the metafield, using JSON format. + """ + jsonValue: JSON! + + """ + The [type of data](https://shopify.dev/apps/metafields/types) that the metafield stores in + the `value` field. + """ + type: String! + + """ + The data that's stored in the metafield. The data is always stored as a string, + regardless of the [metafield's type](https://shopify.dev/apps/metafields/types). + """ + value: String! +} + +""" +[Custom fields](https://shopify.dev/docs/apps/build/custom-data) that store additional information +about a Shopify resource, such as products, orders, and +[many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). +Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) +enables you to customize the checkout experience. +""" +input MetafieldOutput { + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + + """ + The [type of data](https://shopify.dev/docs/apps/build/custom-data/metafields/list-of-data-types) + that's stored in the metafield. + """ + type: String! + + """ + The data to store in the metafield. + """ + value: String! +} + +""" +An instance of custom structured data defined by a MetaobjectDefinition. +""" +type Metaobject { + """ + The field for an object key, or null if the key has no field definition. + """ + field( + """ + The metaobject key to access. + """ + key: String! + ): MetaobjectField + + """ + The unique handle of the metaobject, useful as a custom ID. + """ + handle: String! + + """ + The type of the metaobject. + """ + type: String! +} + +""" +Provides a field definition and the data value assigned to it. +""" +type MetaobjectField { + """ + The assigned field value in JSON format. + """ + jsonValue: JSON + + """ + The object key of this field. + """ + key: String! + + """ + The type of the field. + """ + type: String! + + """ + The assigned field value, always stored as a string regardless of the field type. + """ + value: String +} + +""" +The input fields for retrieving a metaobject by handle. +""" +input MetaobjectHandleInput { + """ + The handle of the metaobject to retrieve. + """ + handle: String! + + """ + The type of the metaobject. Must match an existing metaobject definition type. + """ + type: String! +} + +""" +A precise monetary value and its associated currency. Combines a decimal amount +with a three-letter currency code to express prices, costs, and other financial +values throughout the API. For example, 12.99 USD. +""" +type MoneyV2 { + """ + A monetary value in decimal format, allowing for precise representation of cents or fractional + currency. For example, 12.99. + """ + amount: Decimal! + + """ + The three-letter currency code that represents a world currency used in a store. Currency codes + include standard [standard ISO 4217 codes](https://en.wikipedia.org/wiki/ISO_4217), legacy codes, + and non-standard codes. For example, USD. + """ + currencyCode: CurrencyCode! +} + +""" +A precise monetary value and its associated currency. Combines a decimal amount +with a three-letter currency code to express prices, costs, and other financial +values throughout the API. For example, 12.99 USD. +""" +input MoneyV2Output { + """ + A monetary value in decimal format, allowing for precise representation of cents or fractional + currency. For example, 12.99. + """ + amount: Decimal! + + """ + The three-letter currency code that represents a world currency used in a store. Currency codes + include standard [standard ISO 4217 codes](https://en.wikipedia.org/wiki/ISO_4217), legacy codes, + and non-standard codes. For example, USD. + """ + currencyCode: CurrencyCode! +} + +""" +The root mutation for the API. +""" +type MutationRoot { + """ + Handles the Function result for the cart.fulfillment-options.generate.fetch target. + """ + fetch( + """ + The result of the Function. + """ + result: FunctionFetchResult! + ): Void! + + """ + Handles the Function result for the cart.fulfillment-options.generate.run target. + """ + run( + """ + The result of the Function. + """ + result: FunctionRunResult! + ): Void! +} + +""" +An operation to apply when generating fulfillment options. +""" +input Operation { + """ + Add a fulfillment option. + """ + fulfillmentOptionsAdd: FulfillmentOptionsAddOperation! +} + +""" +A package within a fulfillment. Carries one or more cart-line quantities +and, when available, the package's physical attributes. +""" +type Package { + """ + The cart-line quantities included in the package. + """ + lineQuantities: [LineQuantity!]! +} + +""" +The percentage value of a discount. +""" +type PricingPercentageValue { + """ + The percentage value of the discount. + """ + value: Decimal! +} + +""" +The price value for a discount application. +""" +union PricingValue = MoneyV2 | PricingPercentageValue + +""" +The goods and services that merchants offer to customers. Products can include details such as +title, vendor, and custom data stored in [metafields](https://shopify.dev/docs/apps/build/custom-data). +Products can be organized by grouping them into a collection. + +Learn more about [managing products in a merchant's store](https://help.shopify.com/manual/products). +""" +type Product implements HasMetafields { + """ + A unique, human-readable string of the product's title. A handle can contain letters, hyphens (`-`), and + numbers, but not spaces. The handle is used in the online store URL for the product. For example, if a product + is titled "Black Sunglasses", then the handle is `black-sunglasses`. + """ + handle: Handle! + + """ + Whether the product is associated with any of the specified tags. The product must have at least one tag + from the list to return `true`. + """ + hasAnyTag( + """ + A comma-separated list of searchable keywords that are associated with the product. For example, + `"sports, summer"` returns products with either the `sports` or `summer` tag. + """ + tags: [String!]! = [] + ): Boolean! + + """ + Whether the product is associated with the specified tags. + """ + hasTags( + """ + A comma-separated list of searchable keywords that are associated with the product. For example, + `"sports, summer"` returns products with both the `sports` and `summer` tags. + """ + tags: [String!]! = [] + ): [HasTagResponse!]! + + """ + A [globally-unique ID](https://shopify.dev/docs/api/usage/gids) + for the product. + """ + id: ID! + + """ + Whether the product is in any of the specified collections. The product must be in at least one collection + from the list to return `true`. + + A collection is a group of products that can be displayed in online stores and other sales channels in + categories, which makes it easy for customers to find them. For example, an athletics store might create + different collections for running attire and accessories. + """ + inAnyCollection( + """ + A comma-separated list of [globally-unique collection IDs](https://shopify.dev/docs/api/usage/gids) + that are associated with the product. For example, `gid://shopify/Collection/123`, `gid://shopify/Collection/456`. + """ + ids: [ID!]! = [] + ): Boolean! + + """ + Whether the product is in the specified collections. The product must be in all of the collections in the + list to return `true`. + + A collection is a group of products that can be displayed in online stores and other sales channels in + categories, which makes it easy for customers to find them. For example, an athletics store might create + different collections for running attire and accessories. + """ + inCollections( + """ + A comma-separated list of [globally-unique collection IDs](https://shopify.dev/docs/api/usage/gids) + that are associated with the product. For example, `gid://shopify/Collection/123`, `gid://shopify/Collection/456`. + """ + ids: [ID!]! = [] + ): [CollectionMembership!]! + + """ + Whether the product is a gift card. + """ + isGiftCard: Boolean! + + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield + + """ + A custom category for a product. Product types allow merchants to define categories other than the + ones available in Shopify's + [standard product categories](https://help.shopify.com/manual/products/details/product-type). + """ + productType: String + + """ + The localized name for the product that displays to customers. The title is used to construct the product's + handle, which is a unique, human-readable string of the product's title. For example, if a product is titled + "Black Sunglasses", then the handle is `black-sunglasses`. + """ + title: String! + + """ + The name of the product's vendor. + """ + vendor: String +} + +""" +A specific version of a product that comes in more than one option, such as size or color. For example, +if a merchant sells t-shirts with options for size and color, then a small, blue t-shirt would be one +product variant and a large, blue t-shirt would be another. +""" +type ProductVariant implements HasMetafields { + """ + A [globally-unique ID](https://shopify.dev/docs/api/usage/gids) + for the product variant. + """ + id: ID! + + """ + Whether the product variant is in any of the specified collections. The variant must be in at least one + collection from the list to return `true`. A variant is considered to be in a collection when the variant + itself is a member of the collection, or when its product is a member of the collection. + + A collection is a group of products that can be displayed in online stores and other sales channels in + categories, which makes it easy for customers to find them. For example, an athletics store might create + different collections for running attire and accessories. + """ + inAnyCollection( + """ + A list of [globally-unique collection IDs](https://shopify.dev/docs/api/usage/gids) + to check membership against. For example, `gid://shopify/Collection/123`, `gid://shopify/Collection/456`. + """ + ids: [ID!]! = [] + ): Boolean! + + """ + Whether the product variant is in each of the specified collections. A variant is considered to be in a + collection when the variant itself is a member of the collection, or when its product is a member of the + collection. + + A collection is a group of products that can be displayed in online stores and other sales channels in + categories, which makes it easy for customers to find them. For example, an athletics store might create + different collections for running attire and accessories. + """ + inCollections( + """ + A list of [globally-unique collection IDs](https://shopify.dev/docs/api/usage/gids) + to check membership against. For example, `gid://shopify/Collection/123`, `gid://shopify/Collection/456`. + """ + ids: [ID!]! = [] + ): [CollectionMembership!]! + + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield + + """ + The product associated with the product variant. For example, if a + merchant sells t-shirts with options for size and color, then a small, + blue t-shirt would be one product variant and a large, blue t-shirt would be another. + The product associated with the product variant would be the t-shirt itself. + """ + product: Product! + + """ + Whether the item needs to be shipped to the customer. For example, a + digital gift card doesn't need to be shipped, but a t-shirt does + need to be shipped. + """ + requiresShipping: Boolean! + + """ + A case-sensitive identifier for the product variant in the merchant's store. For example, `"BBC-1"`. + A product variant must have a SKU to be connected to a + [fulfillment service](https://shopify.dev/docs/apps/build/orders-fulfillment/fulfillment-service-apps/build-for-fulfillment-services). + """ + sku: String + + """ + The localized name for the product variant that displays to customers. + """ + title: String + + """ + The product variant's weight, in the system of measurement set in the `weightUnit` field. + """ + weight: Float + + """ + The unit of measurement for weight. + """ + weightUnit: WeightUnit! +} + +""" +A fulfillment option provider. Providers are +declared once in `References.providers` and referenced from individual +fulfillment options by their handle, to keep the payload small. +""" +input Provider { + """ + The provider's external id from the third-party service. + """ + externalId: String! + + """ + Stable handle identifying the provider within this run result. + """ + handle: Handle! + + """ + URL to the provider's logo. Must use the `https` scheme, be served + from the Shopify CDN host, and be RFC 3986 compliant. + """ + logoUrl: URL! + + """ + The provider's display name. + """ + name: String! +} + +""" +The company of a B2B customer that's interacting with the cart. +Used to manage and track purchases made by businesses rather than individual customers. +""" +type PurchasingCompany { + """ + The company associated to the order or draft order. + """ + company: Company! + + """ + The company contact associated to the order or draft order. + """ + contact: CompanyContact + + """ + The company location associated to the order or draft order. + """ + location: CompanyLocation! +} + +""" +Deduplicated lookup tables for values that operations reference by +handle. Grouping references together keeps the payload compact when a +small number of providers or service points is shared across many +operations. +""" +input References { + """ + Deduplicated list of providers referenced by `fulfillment_options_add.provider_handle`. + """ + providers: [Provider!] = [] + + """ + Deduplicated list of service points referenced by `fulfillment_options_add.destination_service_point_handle`. + """ + servicePoints: [ServicePoint!] = [] +} + +""" +Represents how products and variants can be sold and purchased. +""" +type SellingPlan implements HasMetafields { + """ + The description of the selling plan. + """ + description: String + + """ + A globally-unique identifier. + """ + id: ID! + + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield + + """ + The name of the selling plan. For example, '6 weeks of prepaid granola, delivered weekly'. + """ + name: String! + + """ + Whether purchasing the selling plan will result in multiple deliveries. + """ + recurringDeliveries: Boolean! +} + +""" +Represents an association between a variant and a selling plan. Selling plan +allocations describe the options offered for each variant, and the price of the +variant when purchased with a selling plan. +""" +type SellingPlanAllocation { + """ + A list of price adjustments, with a maximum of two. When there are two, the + first price adjustment goes into effect at the time of purchase, while the + second one starts after a certain number of orders. A price adjustment + represents how a selling plan affects pricing when a variant is purchased with + a selling plan. Prices display in the customer's currency if the shop is + configured for it. + """ + priceAdjustments: [SellingPlanAllocationPriceAdjustment!]! + + """ + A representation of how products and variants can be sold and purchased. For + example, an individual selling plan could be '6 weeks of prepaid granola, + delivered weekly'. + """ + sellingPlan: SellingPlan! +} + +""" +The resulting prices for variants when they're purchased with a specific selling plan. +""" +type SellingPlanAllocationPriceAdjustment { + """ + The effective price for a single delivery. For example, for a prepaid + subscription plan that includes 6 deliveries at the price of $48.00, the per + delivery price is $8.00. + """ + perDeliveryPrice: MoneyV2! + + """ + The price of the variant when it's purchased with a selling plan For example, + for a prepaid subscription plan that includes 6 deliveries of $10.00 granola, + where the customer gets 20% off, the price is 6 x $10.00 x 0.80 = $48.00. + """ + price: MoneyV2! +} + +""" +A geographical region a fulfillment can be sent to (e.g. a pickup-point +service area) where the precise address may not be known up front. Expressed +as a radius around a center address. +""" +type ServiceArea { + """ + The center address of the service area, when known. + """ + address: MailingAddress + + """ + Radius around the center address, in meters. + """ + radius: Int +} + +""" +A third-party service point (such as a pickup-point locker or partner +location) returned by the function as a fulfillment address. Combines a +physical address with operational metadata. +""" +input ServicePoint { + """ + Address line 1. + """ + address1: String! + + """ + Address line 2. + """ + address2: String + + """ + Operating hours. A day with no entry is considered closed. + """ + businessHours: [BusinessHours!] + + """ + City. + """ + city: String! + + """ + Country code. + """ + countryCode: CountryCode! + + """ + The provider's external id for this service point. Required + and non-blank. + """ + externalId: String! + + """ + Stable handle identifying this service point within the run result. Referenced + by `FulfillmentOptionsAddOperation.destination_service_point_handle`. + """ + handle: Handle! + + """ + Latitude. + """ + latitude: Float! + + """ + Longitude. + """ + longitude: Float! + + """ + The name the third-party service has assigned to this service point. + Identifies the physical location itself. + """ + name: String! + + """ + Contact phone number for the service point. + """ + phone: String + + """ + Province or state code. + """ + provinceCode: String + + """ + Postal or ZIP code. + """ + zip: String +} + +""" +Information about the store, including the store's timezone setting +and custom data stored in [metafields](https://shopify.dev/docs/apps/build/custom-data). +""" +type Shop implements HasMetafields { + """ + The current time based on the + [store's timezone setting](https://help.shopify.com/manual/intro-to-shopify/initial-setup/setup-business-settings). + """ + localTime: LocalTime! + + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield + + """ + Fetch a specific Metaobject by one of its unique identifiers. Only app-owned + metaobjects with the $app reserved prefix are accessible to functions. + """ + metaobject( + """ + The handle and type of the metaobject. + """ + handle: MetaobjectHandleInput + + """ + The ID of the metaobject. + """ + id: ID + ): Metaobject +} + +""" +Represents information about the buyer that is interacting with the cart. +""" +type ShopUser implements HasMetafields { + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield +} + +""" +A period of time bounded by two `TimePoint`s. `end` must be greater than +or equal to `start`. Reads as, e.g., +`{ "start": { "at": "2026-06-09T12:10:23Z" }, "end": { "after": "P2D" } }`. +""" +input TimePeriod { + """ + Upper bound of the period. Must be >= `start`. + """ + end: TimePoint! + + """ + Lower bound of the period. + """ + start: TimePoint! +} + +""" +A single point in time, expressed as exactly one of: + +- `at`: an absolute `DateTime` (e.g. "2026-06-09T12:10:23Z"). +- `after`: a relative ISO 8601 `Duration` measured from the + fulfillment's ready time (e.g. "P2D"). +""" +input TimePoint @oneOf { + """ + A point in time relative to the fulfillment's ready time, as an ISO 8601 duration. + """ + after: Duration + + """ + An absolute point in time. + """ + at: DateTime +} + +""" +A subset of the [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format that +includes the time but not the date or timezone which is determined from context. +For example, "05:43:21". +""" +scalar TimeWithoutTimezone + +""" +Represents an [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986) and +[RFC 3987](https://datatracker.ietf.org/doc/html/rfc3987)-compliant URI string. + +For example, `"https://example.myshopify.com"` is a valid URL. It includes a scheme (`https`) and a host +(`example.myshopify.com`). +""" +scalar URL + +""" +A void type that can be used to return a null value from a mutation. +""" +scalar Void + +""" +A day of the week. +""" +enum Weekday { + """ + Friday. + """ + FRIDAY + + """ + Monday. + """ + MONDAY + + """ + Saturday. + """ + SATURDAY + + """ + Sunday. + """ + SUNDAY + + """ + Thursday. + """ + THURSDAY + + """ + Tuesday. + """ + TUESDAY + + """ + Wednesday. + """ + WEDNESDAY +} + +""" +Units of measurement for weight. +""" +enum WeightUnit { + """ + Metric system unit of mass. + """ + GRAMS + + """ + 1 kilogram equals 1000 grams. + """ + KILOGRAMS + + """ + Imperial system unit of mass. + """ + OUNCES + + """ + 1 pound equals 16 ounces. + """ + POUNDS +} diff --git a/functions-fulfillment-option-generators-js/shopify.extension.toml.liquid b/functions-fulfillment-option-generators-js/shopify.extension.toml.liquid new file mode 100644 index 00000000..8450672c --- /dev/null +++ b/functions-fulfillment-option-generators-js/shopify.extension.toml.liquid @@ -0,0 +1,25 @@ +api_version = "unstable" + +[[extensions]] +name = "t:name" +handle = "{{handle}}" +type = "function" +{% if uid %}uid = "{{ uid }}"{% endif %} + + [[extensions.targeting]] + target = "cart.fulfillment-options.generate.fetch" + input_query = "src/fetch.graphql" + export = "fetch" + + [[extensions.targeting]] + target = "cart.fulfillment-options.generate.run" + input_query = "src/run.graphql" + export = "run" + + [extensions.build] + command = "" + path = "dist/function.wasm" + + [extensions.ui.paths] + create = "/" + details = "/" diff --git a/functions-fulfillment-option-generators-js/src/fetch.graphql.liquid b/functions-fulfillment-option-generators-js/src/fetch.graphql.liquid new file mode 100644 index 00000000..4491cea1 --- /dev/null +++ b/functions-fulfillment-option-generators-js/src/fetch.graphql.liquid @@ -0,0 +1,7 @@ +query FetchInput { + localization { + country { + isoCode + } + } +} diff --git a/functions-fulfillment-option-generators-js/src/fetch.liquid b/functions-fulfillment-option-generators-js/src/fetch.liquid new file mode 100644 index 00000000..8f7a9397 --- /dev/null +++ b/functions-fulfillment-option-generators-js/src/fetch.liquid @@ -0,0 +1,71 @@ +{%- if flavor contains "vanilla-js" -%} +export function fetch(input) { + const countryCode = input?.localization?.country?.isoCode; + + // Only reach out to the external service when it can return relevant + // fulfillment options. Returning `null` skips the network call entirely. + if (countryCode === 'CA') { + return { + request: buildExternalApiRequest(), + }; + } + + return { request: null }; +} + +function buildExternalApiRequest() { + const url = "https://cdn.shopify.com/s/files/1/0628/3830/9033/files/pickup-points-external-api-v2.json?v=1714588690"; + + return { + method: 'GET', + url, + headers: [{ + name: "Accept", + value: "application/json; charset=utf-8" + }], + body: null, + policy: { + readTimeoutMs: 500, + }, + }; +} +{%- elsif flavor contains "typescript" -%} +import { + CountryCode, + HttpRequest, + HttpRequestMethod, + FunctionFetchResult, + FetchInput +} from '../generated/api'; + +export function fetch(input: FetchInput): FunctionFetchResult { + const countryCode = input?.localization?.country?.isoCode; + + // Only reach out to the external service when it can return relevant + // fulfillment options. Returning `null` skips the network call entirely. + if (countryCode === CountryCode.Ca) { + return { + request: buildExternalApiRequest(), + }; + } + + return { request: null }; +} + +function buildExternalApiRequest(): HttpRequest { + const url = "https://cdn.shopify.com/s/files/1/0628/3830/9033/files/pickup-points-external-api-v2.json?v=1714588690"; + + return { + method: HttpRequestMethod.Get, + url, + headers: [{ + name: "Accept", + value: "application/json; charset=utf-8" + }], + body: null, + policy: { + readTimeoutMs: 500, + }, + }; +} +{%- endif -%} diff --git a/functions-fulfillment-option-generators-js/src/index.liquid b/functions-fulfillment-option-generators-js/src/index.liquid new file mode 100644 index 00000000..345f82d2 --- /dev/null +++ b/functions-fulfillment-option-generators-js/src/index.liquid @@ -0,0 +1,2 @@ +export * from './run'; +export * from './fetch'; diff --git a/functions-fulfillment-option-generators-js/src/run.graphql.liquid b/functions-fulfillment-option-generators-js/src/run.graphql.liquid new file mode 100644 index 00000000..e1f146d5 --- /dev/null +++ b/functions-fulfillment-option-generators-js/src/run.graphql.liquid @@ -0,0 +1,9 @@ +query RunInput { + fulfillments { + handle + } + fetchResult { + status + body + } +} diff --git a/functions-fulfillment-option-generators-js/src/run.liquid b/functions-fulfillment-option-generators-js/src/run.liquid new file mode 100644 index 00000000..788542e5 --- /dev/null +++ b/functions-fulfillment-option-generators-js/src/run.liquid @@ -0,0 +1,232 @@ +{%- if flavor contains "vanilla-js" -%} +export function run(input) { + const { fulfillments, fetchResult } = input; + const status = fetchResult?.status; + const body = fetchResult?.body; + + if (status !== 200 || !body) { + return { operations: [] }; + } + + const { deliveryPoints } = JSON.parse(body); + + // Providers and service points are deduplicated into the `references` block + // and referenced from operations by their handle, to keep the payload small. + const provider = buildProvider(); + const servicePoints = deliveryPoints.map(buildServicePoint); + + // Generate one fulfillment option per service point, for every input fulfillment. + const operations = fulfillments.flatMap((fulfillment) => + servicePoints.map((servicePoint) => ({ + fulfillmentOptionsAdd: { + fulfillmentHandle: fulfillment.handle, + title: servicePoint.name, + providerHandle: provider.handle, + destinationServicePointHandle: servicePoint.handle, + cost: null, + metafields: [], + }, + })) + ); + + return { + references: { + providers: [provider], + servicePoints, + }, + operations, + }; +} + +function buildProvider() { + return { + handle: "shopify-demo-provider", + externalId: "shopify-demo", + name: "Shopify Functions Demo", + logoUrl: "https://cdn.shopify.com/s/files/1/0628/3830/9033/files/shopify_icon_146101.png?v=1706120545", + }; +} + +function buildServicePoint(externalApiDeliveryPoint) { + const { addressComponents } = externalApiDeliveryPoint.location; + const geometry = externalApiDeliveryPoint.location.geometry.location; + + return { + handle: `service-point-${externalApiDeliveryPoint.pointId}`, + externalId: externalApiDeliveryPoint.pointId, + name: externalApiDeliveryPoint.pointName, + address1: `${addressComponents.streetNumber} ${addressComponents.route}`, + address2: null, + city: addressComponents.locality, + countryCode: addressComponents.countryCode, + provinceCode: addressComponents.administrativeArea.code, + zip: addressComponents.postalCode, + phone: null, + latitude: geometry.lat, + longitude: geometry.lng, + businessHours: buildBusinessHours(externalApiDeliveryPoint), + }; +} + +// Transforms the opening hours of a delivery point into a list of `BusinessHours` objects. +// Each day's opening hours are represented using a `BusinessHours` object as follows: +// "Monday: 9:00 AM – 5:00 PM" is transformed to {day: "MONDAY", periods: [{openingTime: "09:00:00", closingTime: "17:00:00"}]} +// "Tuesday: Closed" is transformed to {day: "TUESDAY", periods: []} +function buildBusinessHours(externalApiDeliveryPoint) { + if (!externalApiDeliveryPoint.openingHours) { + return null; + } + + return externalApiDeliveryPoint.openingHours.weekdayText + .map(day => { + let dayParts = day.split(": "); + let dayName = dayParts[0].toUpperCase(); + if (dayParts[1] === "Closed") { + return { day: dayName, periods: [] }; + } else { + let openingClosingTimes = dayParts[1].split(" – "); + return { + day: dayName, + periods: [{ + openingTime: formatTime(openingClosingTimes[0]), + closingTime: formatTime(openingClosingTimes[1]), + }], + }; + } + }); +} + +// Converts a time string from 12-hour to 24-hour format. +// Example: "9:00 AM" => "09:00:00", "5:00 PM" => "17:00:00" +function formatTime(time) { + let timeParts = time.split(' '); + let hourMin = timeParts[0].split(':'); + let hour = parseInt(hourMin[0]); + let min = hourMin[1]; + let period = timeParts[1]; + + let hourIn24Format = period === 'AM' ? (hour === 12 ? 0 : hour) : (hour === 12 ? hour : hour + 12); + + return `${hourIn24Format.toString().padStart(2, '0')}:${min}:00`; +} +{%- elsif flavor contains "typescript" -%} +import { + BusinessHours, + FunctionRunResult, + Operation, + Provider, + ServicePoint, + RunInput +} from "../generated/api"; + +export function run(input: RunInput): FunctionRunResult { + const { fulfillments, fetchResult } = input; + const status = fetchResult?.status; + const body = fetchResult?.body; + + if (status !== 200 || !body) { + return { operations: [] }; + } + + const { deliveryPoints: externalApiDeliveryPoints } = JSON.parse(body); + + // Providers and service points are deduplicated into the `references` block + // and referenced from operations by their handle, to keep the payload small. + const provider = buildProvider(); + const servicePoints = externalApiDeliveryPoints.map(buildServicePoint); + + // Generate one fulfillment option per service point, for every input fulfillment. + const operations: Operation[] = fulfillments.flatMap((fulfillment) => + servicePoints.map((servicePoint: ServicePoint) => ({ + fulfillmentOptionsAdd: { + fulfillmentHandle: fulfillment.handle, + title: servicePoint.name, + providerHandle: provider.handle, + destinationServicePointHandle: servicePoint.handle, + cost: null, + metafields: [], + }, + })) + ); + + return { + references: { + providers: [provider], + servicePoints, + }, + operations, + }; +} + +function buildProvider(): Provider { + return { + handle: "shopify-demo-provider", + externalId: "shopify-demo", + name: "Shopify Functions Demo", + logoUrl: "https://cdn.shopify.com/s/files/1/0628/3830/9033/files/shopify_icon_146101.png?v=1706120545", + }; +} + +function buildServicePoint(externalApiDeliveryPoint: any): ServicePoint { + const { addressComponents } = externalApiDeliveryPoint.location; + const geometry = externalApiDeliveryPoint.location.geometry.location; + + return { + handle: `service-point-${externalApiDeliveryPoint.pointId}`, + externalId: externalApiDeliveryPoint.pointId, + name: externalApiDeliveryPoint.pointName, + address1: `${addressComponents.streetNumber} ${addressComponents.route}`, + address2: null, + city: addressComponents.locality, + countryCode: addressComponents.countryCode, + provinceCode: addressComponents.administrativeArea.code, + zip: addressComponents.postalCode, + phone: null, + latitude: geometry.lat, + longitude: geometry.lng, + businessHours: buildBusinessHours(externalApiDeliveryPoint), + }; +} + +// Transforms the opening hours of a delivery point into a list of `BusinessHours` objects. +// Each day's opening hours are represented using a `BusinessHours` object as follows: +// "Monday: 9:00 AM – 5:00 PM" is transformed to {day: "MONDAY", periods: [{openingTime: "09:00:00", closingTime: "17:00:00"}]} +// "Tuesday: Closed" is transformed to {day: "TUESDAY", periods: []} +function buildBusinessHours(externalApiDeliveryPoint: any): BusinessHours[] | null { + if (!externalApiDeliveryPoint.openingHours) { + return null; + } + + return externalApiDeliveryPoint.openingHours.weekdayText + .map((dayOpeningHours: string) => { + let dayParts = dayOpeningHours.split(": "); + let dayName = dayParts[0].toUpperCase(); + if (dayParts[1] === "Closed") { + return { day: dayName, periods: [] }; + } else { + let openingClosingTimes = dayParts[1].split(" – "); + return { + day: dayName, + periods: [{ + openingTime: formatTime(openingClosingTimes[0]), + closingTime: formatTime(openingClosingTimes[1]), + }], + }; + } + }); +} + +// Converts a time string from 12-hour to 24-hour format. +// Example: "9:00 AM" => "09:00:00", "5:00 PM" => "17:00:00" +function formatTime(time: string): string { + let timeParts = time.split(' '); + let hourMin = timeParts[0].split(':'); + let hour = parseInt(hourMin[0]); + let min = hourMin[1]; + let period = timeParts[1]; + + let hourIn24Format = period === 'AM' ? (hour === 12 ? 0 : hour) : (hour === 12 ? hour : hour + 12); + + return `${hourIn24Format.toString().padStart(2, '0')}:${min}:00`; +} +{%- endif -%} diff --git a/functions-fulfillment-option-generators-js/tests/default.test.js b/functions-fulfillment-option-generators-js/tests/default.test.js new file mode 100644 index 00000000..0d5ad405 --- /dev/null +++ b/functions-fulfillment-option-generators-js/tests/default.test.js @@ -0,0 +1,44 @@ +import path from "path"; +import fs from "fs"; +import { describe, beforeAll, test, expect } from "vitest"; +import { buildFunction, getFunctionInfo, loadSchema, loadInputQuery, loadFixture, validateTestAssets, runFunction } from "@shopify/shopify-function-test-helpers"; + +describe("Default Integration Test", () => { + let schema; + let functionDir; + let functionInfo; + let schemaPath; + let targeting; + let functionRunnerPath; + let wasmPath; + + beforeAll(async () => { + functionDir = path.dirname(__dirname); + await buildFunction(functionDir); + functionInfo = await getFunctionInfo(functionDir); + ({ schemaPath, functionRunnerPath, wasmPath, targeting } = functionInfo); + schema = await loadSchema(schemaPath); + }, 45000); + + const fixturesDir = path.join(__dirname, "fixtures"); + const fixtureFiles = fs.readdirSync(fixturesDir) + .filter((file) => file.endsWith(".json")) + .map((file) => path.join(fixturesDir, file)); + + fixtureFiles.forEach((fixtureFile) => { + test(`runs ${path.relative(fixturesDir, fixtureFile)}`, async () => { + const fixture = await loadFixture(fixtureFile); + const targetInputQueryPath = targeting[fixture.target].inputQueryPath; + const inputQueryAST = await loadInputQuery(targetInputQueryPath); + + const validationResult = await validateTestAssets({ schema, fixture, inputQueryAST }); + expect(validationResult.inputQuery.errors).toEqual([]); + expect(validationResult.inputFixture.errors).toEqual([]); + expect(validationResult.outputFixture.errors).toEqual([]); + + const runResult = await runFunction(fixture, functionRunnerPath, wasmPath, targetInputQueryPath, schemaPath); + expect(runResult.error).toBeNull(); + expect(runResult.result.output).toEqual(fixture.expectedOutput); + }, 10000); + }); +}); diff --git a/functions-fulfillment-option-generators-js/tests/fixtures/fetch-canada-request.json b/functions-fulfillment-option-generators-js/tests/fixtures/fetch-canada-request.json new file mode 100644 index 00000000..ff5991e6 --- /dev/null +++ b/functions-fulfillment-option-generators-js/tests/fixtures/fetch-canada-request.json @@ -0,0 +1,26 @@ +{ + "payload": { + "export": "fetch", + "target": "cart.fulfillment-options.generate.fetch", + "input": { + "localization": { + "country": { + "isoCode": "CA" + } + } + }, + "output": { + "request": { + "body": null, + "headers": [ + { "name": "Accept", "value": "application/json; charset=utf-8" } + ], + "method": "GET", + "policy": { + "readTimeoutMs": 500 + }, + "url": "https://cdn.shopify.com/s/files/1/0628/3830/9033/files/pickup-points-external-api-v2.json?v=1714588690" + } + } + } +} diff --git a/functions-fulfillment-option-generators-js/tests/fixtures/fetch-non-canada-no-request.json b/functions-fulfillment-option-generators-js/tests/fixtures/fetch-non-canada-no-request.json new file mode 100644 index 00000000..037487f4 --- /dev/null +++ b/functions-fulfillment-option-generators-js/tests/fixtures/fetch-non-canada-no-request.json @@ -0,0 +1,16 @@ +{ + "payload": { + "export": "fetch", + "target": "cart.fulfillment-options.generate.fetch", + "input": { + "localization": { + "country": { + "isoCode": "US" + } + } + }, + "output": { + "request": null + } + } +} diff --git a/functions-fulfillment-option-generators-js/tests/fixtures/run-null-opening-hours.json b/functions-fulfillment-option-generators-js/tests/fixtures/run-null-opening-hours.json new file mode 100644 index 00000000..6c6eae51 --- /dev/null +++ b/functions-fulfillment-option-generators-js/tests/fixtures/run-null-opening-hours.json @@ -0,0 +1,56 @@ +{ + "payload": { + "export": "run", + "target": "cart.fulfillment-options.generate.run", + "input": { + "fulfillments": [ + { "handle": "fulfillment-1" } + ], + "fetchResult": { + "status": 200, + "body": "{\"deliveryPoints\":[{\"pointId\":\"001\",\"pointName\":\"Toronto Store\",\"location\":{\"addressComponents\":{\"streetNumber\":\"620\",\"route\":\"King St W\",\"locality\":\"Toronto\",\"administrativeArea\":{\"name\":\"Ontario\",\"code\":\"ON\"},\"postalCode\":\"M5V 1M6\",\"country\":\"Canada\",\"countryCode\":\"CA\"},\"geometry\":{\"location\":{\"lat\":43.644664618786685,\"lng\":-79.40066267417106}}},\"openingHours\":null}]}" + } + }, + "output": { + "references": { + "providers": [ + { + "handle": "shopify-demo-provider", + "externalId": "shopify-demo", + "name": "Shopify Functions Demo", + "logoUrl": "https://cdn.shopify.com/s/files/1/0628/3830/9033/files/shopify_icon_146101.png?v=1706120545" + } + ], + "servicePoints": [ + { + "handle": "service-point-001", + "externalId": "001", + "name": "Toronto Store", + "address1": "620 King St W", + "address2": null, + "city": "Toronto", + "countryCode": "CA", + "provinceCode": "ON", + "zip": "M5V 1M6", + "phone": null, + "latitude": 43.644664618786685, + "longitude": -79.40066267417106, + "businessHours": null + } + ] + }, + "operations": [ + { + "fulfillmentOptionsAdd": { + "fulfillmentHandle": "fulfillment-1", + "title": "Toronto Store", + "providerHandle": "shopify-demo-provider", + "destinationServicePointHandle": "service-point-001", + "cost": null, + "metafields": [] + } + } + ] + } + } +} diff --git a/functions-fulfillment-option-generators-js/tests/fixtures/run-successful-fetch.json b/functions-fulfillment-option-generators-js/tests/fixtures/run-successful-fetch.json new file mode 100644 index 00000000..32cdb895 --- /dev/null +++ b/functions-fulfillment-option-generators-js/tests/fixtures/run-successful-fetch.json @@ -0,0 +1,59 @@ +{ + "payload": { + "export": "run", + "target": "cart.fulfillment-options.generate.run", + "input": { + "fulfillments": [ + { "handle": "fulfillment-1" } + ], + "fetchResult": { + "status": 200, + "body": "{\"deliveryPoints\":[{\"pointId\":\"001\",\"pointName\":\"Toronto Store\",\"location\":{\"addressComponents\":{\"streetNumber\":\"620\",\"route\":\"King St W\",\"locality\":\"Toronto\",\"administrativeArea\":{\"name\":\"Ontario\",\"code\":\"ON\"},\"postalCode\":\"M5V 1M6\",\"country\":\"Canada\",\"countryCode\":\"CA\"},\"geometry\":{\"location\":{\"lat\":43.644664618786685,\"lng\":-79.40066267417106}}},\"openingHours\":{\"weekdayText\":[\"Monday: 9:00 AM – 9:00 PM\",\"Sunday: Closed\"]}}]}" + } + }, + "output": { + "references": { + "providers": [ + { + "handle": "shopify-demo-provider", + "externalId": "shopify-demo", + "name": "Shopify Functions Demo", + "logoUrl": "https://cdn.shopify.com/s/files/1/0628/3830/9033/files/shopify_icon_146101.png?v=1706120545" + } + ], + "servicePoints": [ + { + "handle": "service-point-001", + "externalId": "001", + "name": "Toronto Store", + "address1": "620 King St W", + "address2": null, + "city": "Toronto", + "countryCode": "CA", + "provinceCode": "ON", + "zip": "M5V 1M6", + "phone": null, + "latitude": 43.644664618786685, + "longitude": -79.40066267417106, + "businessHours": [ + { "day": "MONDAY", "periods": [{ "openingTime": "09:00:00", "closingTime": "21:00:00" }] }, + { "day": "SUNDAY", "periods": [] } + ] + } + ] + }, + "operations": [ + { + "fulfillmentOptionsAdd": { + "fulfillmentHandle": "fulfillment-1", + "title": "Toronto Store", + "providerHandle": "shopify-demo-provider", + "destinationServicePointHandle": "service-point-001", + "cost": null, + "metafields": [] + } + } + ] + } + } +} diff --git a/functions-fulfillment-option-generators-js/tests/fixtures/run-unsuccessful-fetch.json b/functions-fulfillment-option-generators-js/tests/fixtures/run-unsuccessful-fetch.json new file mode 100644 index 00000000..4a2adfde --- /dev/null +++ b/functions-fulfillment-option-generators-js/tests/fixtures/run-unsuccessful-fetch.json @@ -0,0 +1,18 @@ +{ + "payload": { + "export": "run", + "target": "cart.fulfillment-options.generate.run", + "input": { + "fulfillments": [ + { "handle": "fulfillment-1" } + ], + "fetchResult": { + "status": 404, + "body": null + } + }, + "output": { + "operations": [] + } + } +} diff --git a/functions-fulfillment-option-generators-js/vite.config.js b/functions-fulfillment-option-generators-js/vite.config.js new file mode 100644 index 00000000..210c90d4 --- /dev/null +++ b/functions-fulfillment-option-generators-js/vite.config.js @@ -0,0 +1 @@ +// Prevents inheritance from parent Remix project diff --git a/functions-fulfillment-option-generators-js/vitest.config.js b/functions-fulfillment-option-generators-js/vitest.config.js new file mode 100644 index 00000000..b1d0db3a --- /dev/null +++ b/functions-fulfillment-option-generators-js/vitest.config.js @@ -0,0 +1,8 @@ +export default { + test: { + forceRerunTriggers: [ + '**/tests/fixtures/**', + '**/src/**', + ], + }, +}; diff --git a/functions-fulfillment-option-generators-rs/.gitignore b/functions-fulfillment-option-generators-rs/.gitignore new file mode 100644 index 00000000..96ef6c0b --- /dev/null +++ b/functions-fulfillment-option-generators-rs/.gitignore @@ -0,0 +1,2 @@ +/target +Cargo.lock diff --git a/functions-fulfillment-option-generators-rs/Cargo.toml.liquid b/functions-fulfillment-option-generators-rs/Cargo.toml.liquid new file mode 100644 index 00000000..c34a7e31 --- /dev/null +++ b/functions-fulfillment-option-generators-rs/Cargo.toml.liquid @@ -0,0 +1,14 @@ +[package] +name = "{{handle | replace: " ", "-" | downcase}}" +version = "1.0.0" +edition = "2021" + +[dependencies] +serde = { version = "1.0.13", features = ["derive"] } +serde_json = "1.0" +shopify_function = "2.1.0" + +[profile.release] +lto = true +opt-level = 'z' +strip = true diff --git a/functions-fulfillment-option-generators-rs/README.md b/functions-fulfillment-option-generators-rs/README.md new file mode 100644 index 00000000..213136cd --- /dev/null +++ b/functions-fulfillment-option-generators-rs/README.md @@ -0,0 +1,216 @@ +# Fulfillment option generators demo + +This repository contains a function that demonstrates how to generate fulfillment options for the fulfillments in a +cart, based on an external API accessible via an HTTP request. To simulate an external API, we have hosted a +[JSON file](https://cdn.shopify.com/s/files/1/0628/3830/9033/files/pickup-points-external-api-v2.json?v=1714588690), +which contains delivery point information in the following format: + +```json +{ + "deliveryPoints": [ + { + "pointId": "001", + "pointName": "Toronto Store", + "location": { + "addressComponents": { + "streetNumber": "620", + "route": "King St W", + "locality": "Toronto", + "administrativeArea": { + "name": "Ontario", + "code": "ON" + }, + "postalCode": "M5V 1M6", + "country": "Canada", + "countryCode": "CA" + }, + "geometry": { + "location": { + "lat": 43.644664618786685, + "lng": -79.40066267417106 + } + } + }, + "openingHours": { + "weekdayText": [ + "Monday: 9:00 AM – 9:00 PM", + "Tuesday: 9:00 AM – 9:00 PM", + "Wednesday: 9:00 AM – 9:00 PM", + "Thursday: 9:00 AM – 9:00 PM", + "Friday: 9:00 AM – 9:00 PM", + "Saturday: 10:00 AM – 6:00 PM", + "Sunday: Closed" + ] + } + } + ] +} +``` + +## Implementation details + +A function can have one or more targets, each characterized by a specific input/output API. The Fulfillment Option +Generators have two targets: an optional **fetch** target and a **run** target. The input/output APIs are +represented as a GraphQL API within the attached [schema](./schema.graphql). + +### Fetch target + +The **fetch** target is responsible for generating an HTTP request to call the external API. Its input API is defined +by the `Input` type in the [schema](./schema.graphql). In our demo, we are only interested in the buyer's localization +country, which we specify within the [**fetch** target input query](./src/fetch.graphql). + +The [**fetch** target](./src/fetch.rs) reads the input and generates an output representing an HTTP request to the +external API if the buyer's country is Canada. The output API is defined by the `FunctionFetchResult` type in +the [schema](./schema.graphql). + +#### Fetch target input/output example + +##### Input + +```json +{ + "localization": { + "country": { + "isoCode": "CA" + } + } +} +``` + +##### Output + +```json +{ + "request": { + "method": "GET", + "url": "https://cdn.shopify.com/s/files/1/0628/3830/9033/files/pickup-points-external-api-v2.json?v=1714588690", + "headers": [ + { + "name": "Accept", + "value": "application/json; charset=utf-8" + } + ], + "body": null, + "jsonBody": null, + "policy": { + "readTimeoutMs": 500 + } + } +} +``` + +### Run target + +The **run** target is responsible for generating the fulfillment options. Its input API is defined by the `Input` type +in the [schema](./schema.graphql). In our demo, we are interested in the cart's fulfillments along with the external +API HTTP response status and body, which we specify within the [**run** target input query](./src/run.graphql). + +The [**run** target](./src/run.rs) parses the response body and produces fulfillment options in the format specified +by the `FunctionRunResult` type in the [schema](./schema.graphql). Providers and service points are deduplicated into +the `references` block and referenced from `fulfillmentOptionsAdd` operations by their handle, to keep the payload +small. One fulfillment option is generated per service point, for every input fulfillment. + +#### Run target input/output example + +##### Input + +```json +{ + "fulfillments": [ + { "handle": "fulfillment-1" } + ], + "fetchResult": { + "status": 200, + "body": "{\"deliveryPoints\":[{\"pointId\":\"001\",\"pointName\":\"Toronto Store\",\"location\":{\"addressComponents\":{\"streetNumber\":\"620\",\"route\":\"King St W\",\"locality\":\"Toronto\",\"administrativeArea\":{\"name\":\"Ontario\",\"code\":\"ON\"},\"postalCode\":\"M5V 1M6\",\"country\":\"Canada\",\"countryCode\":\"CA\"},\"geometry\":{\"location\":{\"lat\":43.644664618786685,\"lng\":-79.40066267417106}}},\"openingHours\":{\"weekdayText\":[\"Monday: 9:00 AM – 9:00 PM\",\"Sunday: Closed\"]}}]}" + } +} +``` + +##### Output + +```json +{ + "references": { + "providers": [ + { + "handle": "shopify-demo-provider", + "externalId": "shopify-demo", + "name": "Shopify Functions Demo", + "logoUrl": "https://cdn.shopify.com/s/files/1/0628/3830/9033/files/shopify_icon_146101.png?v=1706120545" + } + ], + "servicePoints": [ + { + "handle": "service-point-001", + "externalId": "001", + "name": "Toronto Store", + "address1": "620 King St W", + "address2": null, + "city": "Toronto", + "countryCode": "CA", + "provinceCode": "ON", + "zip": "M5V 1M6", + "phone": null, + "latitude": 43.644664618786685, + "longitude": -79.40066267417106, + "businessHours": [ + { + "day": "MONDAY", + "periods": [ + { + "openingTime": "09:00:00", + "closingTime": "21:00:00" + } + ] + }, + { + "day": "SUNDAY", + "periods": [] + } + ] + } + ] + }, + "operations": [ + { + "fulfillmentOptionsAdd": { + "fulfillmentHandle": "fulfillment-1", + "code": null, + "title": "Toronto Store", + "instructions": null, + "providerHandle": "shopify-demo-provider", + "destinationServicePointHandle": "service-point-001", + "cost": null, + "timePeriod": null, + "metafields": [] + } + } + ] +} +``` + +## Usage + +### Running tests + +1. Execute the tests by running the following command in your terminal: + +```bash +cargo test +``` + +### Deploying the function to the app + +1. Navigate to the root directory of your app. Deploy the function by running the following command +in your terminal: + +```bash +yarn deploy +``` + +### Using the function in a store + +1. Activate the function by selecting it in the relevant fulfillment settings of the store admin, then save. + +2. To use the function, initiate a checkout process with a product available from the configured location. Enter an +address in Canada — a list of fulfillment options generated using this function should now be visible. diff --git a/functions-fulfillment-option-generators-rs/locales/en.default.json.liquid b/functions-fulfillment-option-generators-rs/locales/en.default.json.liquid new file mode 100644 index 00000000..333045ae --- /dev/null +++ b/functions-fulfillment-option-generators-rs/locales/en.default.json.liquid @@ -0,0 +1,4 @@ +{ + "name": "{{name}}", + "description": "{{name}}" +} diff --git a/functions-fulfillment-option-generators-rs/package.json.liquid b/functions-fulfillment-option-generators-rs/package.json.liquid new file mode 100644 index 00000000..58d4ac93 --- /dev/null +++ b/functions-fulfillment-option-generators-rs/package.json.liquid @@ -0,0 +1,13 @@ +{ + "name": "{{handle}}", + "version": "0.0.1", + "private": true, + "type": "module", + "scripts": { + "test": "vitest" + }, + "devDependencies": { + "@shopify/shopify-function-test-helpers": "^1.0.0", + "vitest": "^3.2.4" + } +} diff --git a/functions-fulfillment-option-generators-rs/schema.graphql b/functions-fulfillment-option-generators-rs/schema.graphql new file mode 100644 index 00000000..2b5d55cd --- /dev/null +++ b/functions-fulfillment-option-generators-rs/schema.graphql @@ -0,0 +1,5800 @@ +# This file is auto-generated from the current state of the GraphQL API. Instead of editing this file, +# please edit the ruby definition files and run `bin/rails graphql:schema:dump` to regenerate the schema. +# +# If you're just looking to browse, you may find it friendlier to use the graphiql browser which is +# available in services-internal at https://app.shopify.com/services/internal/shops/14168/graphql. +# Check out the "Docs" tab in the top right. + +schema { + query: Input + mutation: MutationRoot +} + +""" +Only allow the field to be queried when targeting one of the specified targets. +""" +directive @restrictTarget(only: [String!]!) on FIELD_DEFINITION + +""" +Scale the Functions resource limits based on the field's length. +""" +directive @scaleLimits(rate: Float!) on FIELD_DEFINITION + +""" +Requires that exactly one field must be supplied and that field must not be `null`. +""" +directive @oneOf on INPUT_OBJECT + +""" +Represents an app. +""" +type App { + """ + The ID of the app. + """ + id: ID! +} + +""" +A custom property. Attributes are used to store additional information about a Shopify resource, such as +products, customers, or orders. Attributes are stored as key-value pairs. + +For example, a list of attributes might include whether a customer is a first-time buyer (`"customer_first_order": "true"`), +whether an order is gift-wrapped (`"gift_wrapped": "true"`), a preferred delivery date +(`"preferred_delivery_date": "2025-10-01"`), the discount applied (`"loyalty_discount_applied": "10%"`), and any +notes provided by the customer (`"customer_notes": "Please leave at the front door"`). +""" +type Attribute { + """ + The key or name of the attribute. For example, `"customer_first_order"`. + """ + key: String! + + """ + The value of the attribute. For example, `"true"`. + """ + value: String +} + +""" +Operating hours of a service point for a specific day of the week. A day +with no entry is considered closed. Use multiple periods to express +split schedules (e.g. lunch closures). +""" +input BusinessHours { + """ + The day of the week. + """ + day: Weekday! + + """ + Operating periods for the day. + """ + periods: [BusinessHoursPeriod!]! +} + +""" +An operating-time period within a single day at a service point. +""" +input BusinessHoursPeriod { + """ + The time the service point closes. + """ + closingTime: TimeWithoutTimezone! + + """ + The time the service point opens. + """ + openingTime: TimeWithoutTimezone! +} + +""" +Information about the customer that's interacting with the cart. It includes details such as the +customer's email and phone number, and the total amount of money the customer has spent in the store. +This information helps personalize the checkout experience and ensures that accurate pricing and delivery options +are displayed to customers. +""" +type BuyerIdentity { + """ + The [customer](https://help.shopify.com/manual/customers/manage-customers) that's interacting with the cart. + """ + customer: Customer + + """ + The email address of the customer that's interacting with the cart. + """ + email: String + + """ + Whether the customer is authenticated through their + [customer account](https://help.shopify.com/manual/customers/customer-accounts). + """ + isAuthenticated: Boolean! + + """ + The phone number of the customer that's interacting with the cart. + """ + phone: String + + """ + The company of a B2B customer that's interacting with the cart. + Used to manage and track purchases made by businesses rather than individual customers. + """ + purchasingCompany: PurchasingCompany + + """ + Represents the [Shop User](https://help.shopify.com/en/manual/online-sales-channels/shop/sign-in-features) + corresponding to the customer within the shop, if the buyer is a Shop User. Can be used to request [Shop User + metafields](https://shopify.dev/docs/api/shop-user-custom-data). + """ + shopUser: ShopUser +} + +""" +The cart where the Function is running. A cart contains the merchandise that a customer intends to purchase +and information about the customer, such as the customer's email address and phone number. +""" +type Cart implements HasMetafields { + """ + The custom attributes associated with a cart to store additional information. Cart attributes + allow you to collect specific information from customers on the **Cart** page, such as order notes, + gift wrapping requests, or custom product details. Attributes are stored as key-value pairs. + """ + attribute( + """ + The key of the cart attribute to retrieve. For example, `"gift_wrapping"`. + """ + key: String + ): Attribute + + """ + The billing address associated with the cart. + """ + billingAddress: MailingAddress + + """ + Information about the customer that's interacting with the cart. It includes details such as the + customer's email and phone number, and the total amount of money the customer has spent in the store. + This information helps personalize the checkout experience and ensures that accurate pricing and delivery options + are displayed to customers. + """ + buyerIdentity: BuyerIdentity + + """ + A breakdown of the costs that the customer will pay at checkout. It includes the total amount, + the subtotal before taxes and duties, the tax amount, and duty charges. + """ + cost: CartCost! + + """ + The items in a cart that are eligible for fulfillment and can be delivered to the customer. + """ + deliverableLines: [DeliverableCartLine!]! + + """ + A collection of items that are grouped by shared delivery characteristics. Delivery groups streamline + fulfillment by organizing items that can be shipped together, based on the customer's + shipping address. For example, if a customer orders a t-shirt and a pair of shoes that can be shipped + together, then the items are included in the same delivery group. + + In the [Order Discount](https://shopify.dev/docs/api/functions/reference/order-discounts) and + [Product Discount](https://shopify.dev/docs/api/functions/reference/product-discounts) legacy APIs, + the `cart.deliveryGroups` input is always an empty array. This means you can't access delivery groups when + creating Order Discount or Product Discount Functions. If you need to apply discounts to shipping costs, + then use the [Discount Function API](https://shopify.dev/docs/api/functions/reference/discount) + instead. + """ + deliveryGroups: [CartDeliveryGroup!]! + + """ + The discounts that have been applied to the cart. + """ + discountApplications: [DiscountApplication!]! + + """ + The items in a cart that the customer intends to purchase. A cart line is an entry in the + customer's cart that represents a single unit of a product variant. For example, if a customer adds two + different sizes of the same t-shirt to their cart, then each size is represented as a separate cart line. + """ + lines: [CartLine!]! @scaleLimits(rate: 0.005) + + """ + The additional fields on the **Cart** page that are required for international orders in specific countries, + such as customs information or tax identification numbers. + """ + localizedFields( + """ + The keys of the localized fields to retrieve. + """ + keys: [LocalizedFieldKey!]! = [] + ): [LocalizedField!]! + + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield + + """ + A purchase order number associated with the cart, often used for B2B transactions + to reference the buyer's internal purchase order. + """ + poNumber: String + + """ + The physical location where a retail order is created or completed. + """ + retailLocation: Location +} + +""" +A breakdown of the costs that the customer will pay at checkout. It includes the total amount, +the subtotal before taxes and duties, the tax amount, and duty charges. +""" +type CartCost { + """ + The amount, before taxes and cart-level discounts, for the customer to pay. + """ + subtotalAmount: MoneyV2! + + """ + The total amount for the customer to pay at checkout. + """ + totalAmount: MoneyV2! + + """ + The duty charges for a customer to pay at checkout. + """ + totalDutyAmount: MoneyV2 + + """ + The total tax amount for the customer to pay at checkout. + """ + totalTaxAmount: MoneyV2 +} + +""" +Information about items in a cart that are grouped by shared delivery characteristics. +Delivery groups streamline fulfillment by organizing items that can be shipped together, based on the customer's +shipping address. For example, if a customer orders a t-shirt and a pair of shoes that can be shipped +together, then the items are included in the same delivery group. +""" +type CartDeliveryGroup { + """ + Information about items in a cart that a customer intends to purchase. A cart line is an entry in the + customer's cart that represents a single unit of a product variant. For example, if a customer adds two + different sizes of the same t-shirt to their cart, then each size is represented as a separate cart line. + """ + cartLines: [CartLine!]! @scaleLimits(rate: 0.005) + + """ + The shipping or destination address associated with the delivery group. + """ + deliveryAddress: MailingAddress + + """ + The delivery options available for the delivery group. Delivery options are the different ways that customers + can choose to have their orders shipped. Examples include express shipping or standard shipping. + """ + deliveryOptions: [CartDeliveryOption!]! + + """ + The discounts that have been applied to the delivery group. + """ + discountAllocations: [DiscountAllocation!]! + + """ + The type of merchandise in the delivery group. + """ + groupType: CartDeliveryGroupType! + + """ + A [globally-unique ID](https://shopify.dev/docs/api/usage/gids) + for the delivery group. + """ + id: ID! + + """ + Information about the delivery option that the customer has selected. + """ + selectedDeliveryOption: CartDeliveryOption +} + +""" +Defines what type of merchandise is in the delivery group. +""" +enum CartDeliveryGroupType { + """ + The delivery group only contains merchandise that is either a one time purchase or a first delivery of + subscription merchandise. + """ + ONE_TIME_PURCHASE + + """ + The delivery group only contains subscription merchandise. + """ + SUBSCRIPTION +} + +""" +Information about a delivery option that's available for an item in a cart. Delivery options are the different +ways that customers can choose to have their orders shipped. Examples include express shipping or standard +shipping. +""" +type CartDeliveryOption { + """ + A unique identifier that represents the delivery option offered to customers. + For example, `Canada Post Expedited`. + """ + code: String + + """ + The amount that the customer pays if they select the delivery option. + """ + cost: MoneyV2! + + """ + The delivery method associated with the delivery option. A delivery method is a way that merchants can + fulfill orders from their online stores. Delivery methods include shipping to an address, + [local pickup](https://help.shopify.com/manual/fulfillment/setup/delivery-methods/pickup-in-store), + and shipping to a [pickup point](https://help.shopify.com/manual/fulfillment/shopify-shipping/pickup-points), + all of which are natively supported by Shopify checkout. + """ + deliveryMethodType: DeliveryMethod! + + """ + A single-line description of the delivery option, with HTML tags removed. + """ + description: String + + """ + A unique, human-readable identifier of the delivery option's title. + A handle can contain letters, hyphens (`-`), and numbers, but not spaces. + For example, `standard-shipping`. + """ + handle: Handle! + + """ + The name of the delivery option that displays to customers. The title is used to construct the delivery + option's handle. For example, if a delivery option is titled "Standard Shipping", then the handle is + `standard-shipping`. + """ + title: String +} + +""" +The fetch target result. Refer to network access for Shopify Functions. +""" +input FunctionFetchResult { + """ + HTTP request to dispatch on behalf of the function. + """ + request: HttpRequest +} + +""" +The output of the Function `run` target. Contains the operations to +apply, plus a `References` block with deduplicated lookup tables for +providers and service points. +""" +input FunctionRunResult { + """ + The ordered list of operations to apply. + """ + operations: [Operation!]! + + """ + Deduplicated lookup tables for providers and service points. + """ + references: References +} + +""" +Information about an item in a cart that a customer intends to purchase. A cart line is an entry in the +customer's cart that represents a single unit of a product variant. For example, if a customer adds two +different sizes of the same t-shirt to their cart, then each size is represented as a separate cart line. +""" +type CartLine { + """ + The custom attributes associated with a cart to store additional information. Cart attributes + allow you to collect specific information from customers on the **Cart** page, such as order notes, + gift wrapping requests, or custom product details. Attributes are stored as key-value pairs. + + Cart line attributes are equivalent to the + [`line_item`](https://shopify.dev/docs/api/liquid/objects/line_item) + object in Liquid. + """ + attribute( + """ + The key of the cart attribute to retrieve. For example, `"gift_wrapping"`. + """ + key: String + ): Attribute + + """ + The cost of an item in a cart that the customer intends to purchase. Cart lines are entries in the customer's + cart that represent a single unit of a product variant. For example, if a customer adds two different sizes of + the same t-shirt to their cart, then each size is represented as a separate cart line. + """ + cost: CartLineCost! + + """ + The discounts that have been applied to the cart line. + """ + discountAllocations: [DiscountAllocation!]! + + """ + The ID of the cart line. + """ + id: ID! + + """ + The item that the customer intends to purchase. + """ + merchandise: Merchandise! + + """ + The [nested relationship](https://shopify.dev/docs/apps/build/product-merchandising/nested-cart-lines) + between this line and its parent line, if any. + """ + parentRelationship: CartLineParentRelationship + + """ + The quantity of the item that the customer intends to purchase. + """ + quantity: Int! + + """ + The [selling plan](https://shopify.dev/docs/apps/build/purchase-options/subscriptions/selling-plans) + associated with the cart line, including information about how a product variant can be sold and purchased. + """ + sellingPlanAllocation: SellingPlanAllocation +} + +""" +The cost of an item in a cart that the customer intends to purchase. Cart lines are entries in the customer's +cart that represent a single unit of a product variant. For example, if a customer adds two different sizes of +the same t-shirt to their cart, then each size is represented as a separate cart line. +""" +type CartLineCost { + """ + The cost of a single unit. For example, if a customer purchases three units of a product + that are priced at $10 each, then the `amountPerQuantity` is $10. + """ + amountPerQuantity: MoneyV2! + + """ + The `compareAt` price of a single unit before any discounts are applied. This field is used to calculate and display + savings for customers. For example, if a product's `compareAtAmountPerQuantity` is $25 and its current price + is $20, then the customer sees a $5 discount. This value can change based on the buyer's identity and is + `null` when the value is hidden from buyers. + """ + compareAtAmountPerQuantity: MoneyV2 + + """ + The cost of items in the cart before applying any discounts to certain items. + This amount serves as the starting point for calculating any potential savings customers + might receive through promotions or discounts. + """ + subtotalAmount: MoneyV2! + + """ + The total cost of items in a cart. + """ + totalAmount: MoneyV2! +} + +""" +Represents the relationship between a cart line and its parent line. +""" +type CartLineParentRelationship { + """ + The parent line in the relationship. + """ + parent: CartLine! +} + +""" +Whether the product is in the specified collection. + +A collection is a group of products that can be displayed in online stores and other sales channels in +categories, which makes it easy for customers to find them. For example, an athletics store might create +different collections for running attire and accessories. +""" +type CollectionMembership { + """ + A [globally-unique ID](https://shopify.dev/docs/api/usage/gids) + for the collection. + """ + collectionId: ID! + + """ + Whether the product is in the specified collection. + """ + isMember: Boolean! +} + +""" +Represents information about a company which is also a customer of the shop. +""" +type Company implements HasMetafields { + """ + The date and time ([ISO 8601 format](http://en.wikipedia.org/wiki/ISO_8601)) at which the company was created in Shopify. + """ + createdAt: DateTime! + + """ + A unique externally-supplied ID for the company. + """ + externalId: String + + """ + The ID of the company. + """ + id: ID! + + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield + + """ + The name of the company. + """ + name: String! + + """ + The date and time ([ISO 8601 format](http://en.wikipedia.org/wiki/ISO_8601)) at which the company was last modified. + """ + updatedAt: DateTime! +} + +""" +A company's main point of contact. +""" +type CompanyContact { + """ + The date and time ([ISO 8601 format](http://en.wikipedia.org/wiki/ISO_8601)) + at which the company contact was created in Shopify. + """ + createdAt: DateTime! + + """ + The ID of the company. + """ + id: ID! + + """ + The company contact's locale (language). + """ + locale: String + + """ + The company contact's job title. + """ + title: String + + """ + The date and time ([ISO 8601 format](http://en.wikipedia.org/wiki/ISO_8601)) + at which the company contact was last modified. + """ + updatedAt: DateTime! +} + +""" +A company's location. +""" +type CompanyLocation implements HasMetafields { + """ + The date and time ([ISO 8601 format](http://en.wikipedia.org/wiki/ISO_8601)) + at which the company location was created in Shopify. + """ + createdAt: DateTime! + + """ + A unique externally-supplied ID for the company. + """ + externalId: String + + """ + The ID of the company. + """ + id: ID! + + """ + The preferred locale of the company location. + """ + locale: String + + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield + + """ + The name of the company location. + """ + name: String! + + """ + The number of orders placed at this company location. + """ + ordersCount: Int! + + """ + The total amount spent at this company location. + """ + totalSpent: MoneyV2! + + """ + The date and time ([ISO 8601 format](http://en.wikipedia.org/wiki/ISO_8601)) + at which the company location was last modified. + """ + updatedAt: DateTime! +} + +""" +The country for which the store is customized, reflecting local preferences and regulations. +Localization might influence the language, currency, and product offerings available in a store to enhance +the shopping experience for customers in that region. +""" +type Country { + """ + The ISO code of the country. + """ + isoCode: CountryCode! +} + +""" +The code designating a country/region, which generally follows ISO 3166-1 alpha-2 guidelines. +If a territory doesn't have a country code value in the `CountryCode` enum, then it might be considered a subdivision +of another country. For example, the territories associated with Spain are represented by the country code `ES`, +and the territories associated with the United States of America are represented by the country code `US`. +""" +enum CountryCode { + """ + Ascension Island. + """ + AC + + """ + Andorra. + """ + AD + + """ + United Arab Emirates. + """ + AE + + """ + Afghanistan. + """ + AF + + """ + Antigua & Barbuda. + """ + AG + + """ + Anguilla. + """ + AI + + """ + Albania. + """ + AL + + """ + Armenia. + """ + AM + + """ + Netherlands Antilles. + """ + AN + + """ + Angola. + """ + AO + + """ + Argentina. + """ + AR + + """ + Austria. + """ + AT + + """ + Australia. + """ + AU + + """ + Aruba. + """ + AW + + """ + Åland Islands. + """ + AX + + """ + Azerbaijan. + """ + AZ + + """ + Bosnia & Herzegovina. + """ + BA + + """ + Barbados. + """ + BB + + """ + Bangladesh. + """ + BD + + """ + Belgium. + """ + BE + + """ + Burkina Faso. + """ + BF + + """ + Bulgaria. + """ + BG + + """ + Bahrain. + """ + BH + + """ + Burundi. + """ + BI + + """ + Benin. + """ + BJ + + """ + St. Barthélemy. + """ + BL + + """ + Bermuda. + """ + BM + + """ + Brunei. + """ + BN + + """ + Bolivia. + """ + BO + + """ + Caribbean Netherlands. + """ + BQ + + """ + Brazil. + """ + BR + + """ + Bahamas. + """ + BS + + """ + Bhutan. + """ + BT + + """ + Bouvet Island. + """ + BV + + """ + Botswana. + """ + BW + + """ + Belarus. + """ + BY + + """ + Belize. + """ + BZ + + """ + Canada. + """ + CA + + """ + Cocos (Keeling) Islands. + """ + CC + + """ + Congo - Kinshasa. + """ + CD + + """ + Central African Republic. + """ + CF + + """ + Congo - Brazzaville. + """ + CG + + """ + Switzerland. + """ + CH + + """ + Côte d’Ivoire. + """ + CI + + """ + Cook Islands. + """ + CK + + """ + Chile. + """ + CL + + """ + Cameroon. + """ + CM + + """ + China. + """ + CN + + """ + Colombia. + """ + CO + + """ + Costa Rica. + """ + CR + + """ + Cuba. + """ + CU + + """ + Cape Verde. + """ + CV + + """ + Curaçao. + """ + CW + + """ + Christmas Island. + """ + CX + + """ + Cyprus. + """ + CY + + """ + Czechia. + """ + CZ + + """ + Germany. + """ + DE + + """ + Djibouti. + """ + DJ + + """ + Denmark. + """ + DK + + """ + Dominica. + """ + DM + + """ + Dominican Republic. + """ + DO + + """ + Algeria. + """ + DZ + + """ + Ecuador. + """ + EC + + """ + Estonia. + """ + EE + + """ + Egypt. + """ + EG + + """ + Western Sahara. + """ + EH + + """ + Eritrea. + """ + ER + + """ + Spain. + """ + ES + + """ + Ethiopia. + """ + ET + + """ + Finland. + """ + FI + + """ + Fiji. + """ + FJ + + """ + Falkland Islands. + """ + FK + + """ + Faroe Islands. + """ + FO + + """ + France. + """ + FR + + """ + Gabon. + """ + GA + + """ + United Kingdom. + """ + GB + + """ + Grenada. + """ + GD + + """ + Georgia. + """ + GE + + """ + French Guiana. + """ + GF + + """ + Guernsey. + """ + GG + + """ + Ghana. + """ + GH + + """ + Gibraltar. + """ + GI + + """ + Greenland. + """ + GL + + """ + Gambia. + """ + GM + + """ + Guinea. + """ + GN + + """ + Guadeloupe. + """ + GP + + """ + Equatorial Guinea. + """ + GQ + + """ + Greece. + """ + GR + + """ + South Georgia & South Sandwich Islands. + """ + GS + + """ + Guatemala. + """ + GT + + """ + Guinea-Bissau. + """ + GW + + """ + Guyana. + """ + GY + + """ + Hong Kong SAR. + """ + HK + + """ + Heard & McDonald Islands. + """ + HM + + """ + Honduras. + """ + HN + + """ + Croatia. + """ + HR + + """ + Haiti. + """ + HT + + """ + Hungary. + """ + HU + + """ + Indonesia. + """ + ID + + """ + Ireland. + """ + IE + + """ + Israel. + """ + IL + + """ + Isle of Man. + """ + IM + + """ + India. + """ + IN + + """ + British Indian Ocean Territory. + """ + IO + + """ + Iraq. + """ + IQ + + """ + Iran. + """ + IR + + """ + Iceland. + """ + IS + + """ + Italy. + """ + IT + + """ + Jersey. + """ + JE + + """ + Jamaica. + """ + JM + + """ + Jordan. + """ + JO + + """ + Japan. + """ + JP + + """ + Kenya. + """ + KE + + """ + Kyrgyzstan. + """ + KG + + """ + Cambodia. + """ + KH + + """ + Kiribati. + """ + KI + + """ + Comoros. + """ + KM + + """ + St. Kitts & Nevis. + """ + KN + + """ + North Korea. + """ + KP + + """ + South Korea. + """ + KR + + """ + Kuwait. + """ + KW + + """ + Cayman Islands. + """ + KY + + """ + Kazakhstan. + """ + KZ + + """ + Laos. + """ + LA + + """ + Lebanon. + """ + LB + + """ + St. Lucia. + """ + LC + + """ + Liechtenstein. + """ + LI + + """ + Sri Lanka. + """ + LK + + """ + Liberia. + """ + LR + + """ + Lesotho. + """ + LS + + """ + Lithuania. + """ + LT + + """ + Luxembourg. + """ + LU + + """ + Latvia. + """ + LV + + """ + Libya. + """ + LY + + """ + Morocco. + """ + MA + + """ + Monaco. + """ + MC + + """ + Moldova. + """ + MD + + """ + Montenegro. + """ + ME + + """ + St. Martin. + """ + MF + + """ + Madagascar. + """ + MG + + """ + North Macedonia. + """ + MK + + """ + Mali. + """ + ML + + """ + Myanmar (Burma). + """ + MM + + """ + Mongolia. + """ + MN + + """ + Macao SAR. + """ + MO + + """ + Martinique. + """ + MQ + + """ + Mauritania. + """ + MR + + """ + Montserrat. + """ + MS + + """ + Malta. + """ + MT + + """ + Mauritius. + """ + MU + + """ + Maldives. + """ + MV + + """ + Malawi. + """ + MW + + """ + Mexico. + """ + MX + + """ + Malaysia. + """ + MY + + """ + Mozambique. + """ + MZ + + """ + Namibia. + """ + NA + + """ + New Caledonia. + """ + NC + + """ + Niger. + """ + NE + + """ + Norfolk Island. + """ + NF + + """ + Nigeria. + """ + NG + + """ + Nicaragua. + """ + NI + + """ + Netherlands. + """ + NL + + """ + Norway. + """ + NO + + """ + Nepal. + """ + NP + + """ + Nauru. + """ + NR + + """ + Niue. + """ + NU + + """ + New Zealand. + """ + NZ + + """ + Oman. + """ + OM + + """ + Panama. + """ + PA + + """ + Peru. + """ + PE + + """ + French Polynesia. + """ + PF + + """ + Papua New Guinea. + """ + PG + + """ + Philippines. + """ + PH + + """ + Pakistan. + """ + PK + + """ + Poland. + """ + PL + + """ + St. Pierre & Miquelon. + """ + PM + + """ + Pitcairn Islands. + """ + PN + + """ + Palestinian Territories. + """ + PS + + """ + Portugal. + """ + PT + + """ + Paraguay. + """ + PY + + """ + Qatar. + """ + QA + + """ + Réunion. + """ + RE + + """ + Romania. + """ + RO + + """ + Serbia. + """ + RS + + """ + Russia. + """ + RU + + """ + Rwanda. + """ + RW + + """ + Saudi Arabia. + """ + SA + + """ + Solomon Islands. + """ + SB + + """ + Seychelles. + """ + SC + + """ + Sudan. + """ + SD + + """ + Sweden. + """ + SE + + """ + Singapore. + """ + SG + + """ + St. Helena. + """ + SH + + """ + Slovenia. + """ + SI + + """ + Svalbard & Jan Mayen. + """ + SJ + + """ + Slovakia. + """ + SK + + """ + Sierra Leone. + """ + SL + + """ + San Marino. + """ + SM + + """ + Senegal. + """ + SN + + """ + Somalia. + """ + SO + + """ + Suriname. + """ + SR + + """ + South Sudan. + """ + SS + + """ + São Tomé & Príncipe. + """ + ST + + """ + El Salvador. + """ + SV + + """ + Sint Maarten. + """ + SX + + """ + Syria. + """ + SY + + """ + Eswatini. + """ + SZ + + """ + Tristan da Cunha. + """ + TA + + """ + Turks & Caicos Islands. + """ + TC + + """ + Chad. + """ + TD + + """ + French Southern Territories. + """ + TF + + """ + Togo. + """ + TG + + """ + Thailand. + """ + TH + + """ + Tajikistan. + """ + TJ + + """ + Tokelau. + """ + TK + + """ + Timor-Leste. + """ + TL + + """ + Turkmenistan. + """ + TM + + """ + Tunisia. + """ + TN + + """ + Tonga. + """ + TO + + """ + Türkiye. + """ + TR + + """ + Trinidad & Tobago. + """ + TT + + """ + Tuvalu. + """ + TV + + """ + Taiwan. + """ + TW + + """ + Tanzania. + """ + TZ + + """ + Ukraine. + """ + UA + + """ + Uganda. + """ + UG + + """ + U.S. Outlying Islands. + """ + UM + + """ + Unknown country code. + """ + UNKNOWN__ + + """ + United States. + """ + US + + """ + Uruguay. + """ + UY + + """ + Uzbekistan. + """ + UZ + + """ + Vatican City. + """ + VA + + """ + St. Vincent & Grenadines. + """ + VC + + """ + Venezuela. + """ + VE + + """ + British Virgin Islands. + """ + VG + + """ + Vietnam. + """ + VN + + """ + Vanuatu. + """ + VU + + """ + Wallis & Futuna. + """ + WF + + """ + Samoa. + """ + WS + + """ + Kosovo. + """ + XK + + """ + Yemen. + """ + YE + + """ + Mayotte. + """ + YT + + """ + South Africa. + """ + ZA + + """ + Zambia. + """ + ZM + + """ + Zimbabwe. + """ + ZW + + """ + Unknown Region. + """ + ZZ +} + +""" +The currency codes that represent the world currencies throughout the Admin API. Currency codes include +[standard ISO 4217 codes](https://en.wikipedia.org/wiki/ISO_4217), legacy codes, non-standard codes, +digital currency codes. +""" +enum CurrencyCode { + """ + United Arab Emirates Dirham (AED). + """ + AED + + """ + Afghan Afghani (AFN). + """ + AFN + + """ + Albanian Lek (ALL). + """ + ALL + + """ + Armenian Dram (AMD). + """ + AMD + + """ + Netherlands Antillean Guilder. + """ + ANG + + """ + Angolan Kwanza (AOA). + """ + AOA + + """ + Argentine Pesos (ARS). + """ + ARS + + """ + Australian Dollars (AUD). + """ + AUD + + """ + Aruban Florin (AWG). + """ + AWG + + """ + Azerbaijani Manat (AZN). + """ + AZN + + """ + Bosnia and Herzegovina Convertible Mark (BAM). + """ + BAM + + """ + Barbadian Dollar (BBD). + """ + BBD + + """ + Bangladesh Taka (BDT). + """ + BDT + + """ + Bulgarian Lev (BGN). + """ + BGN + + """ + Bahraini Dinar (BHD). + """ + BHD + + """ + Burundian Franc (BIF). + """ + BIF + + """ + Bermudian Dollar (BMD). + """ + BMD + + """ + Brunei Dollar (BND). + """ + BND + + """ + Bolivian Boliviano (BOB). + """ + BOB + + """ + Brazilian Real (BRL). + """ + BRL + + """ + Bahamian Dollar (BSD). + """ + BSD + + """ + Bhutanese Ngultrum (BTN). + """ + BTN + + """ + Botswana Pula (BWP). + """ + BWP + + """ + Belarusian Ruble (BYN). + """ + BYN + + """ + Belarusian Ruble (BYR). + """ + BYR @deprecated(reason: "Use `BYN` instead.") + + """ + Belize Dollar (BZD). + """ + BZD + + """ + Canadian Dollars (CAD). + """ + CAD + + """ + Congolese franc (CDF). + """ + CDF + + """ + Swiss Francs (CHF). + """ + CHF + + """ + Chilean Peso (CLP). + """ + CLP + + """ + Chinese Yuan Renminbi (CNY). + """ + CNY + + """ + Colombian Peso (COP). + """ + COP + + """ + Costa Rican Colones (CRC). + """ + CRC + + """ + Cape Verdean escudo (CVE). + """ + CVE + + """ + Czech Koruny (CZK). + """ + CZK + + """ + Djiboutian Franc (DJF). + """ + DJF + + """ + Danish Kroner (DKK). + """ + DKK + + """ + Dominican Peso (DOP). + """ + DOP + + """ + Algerian Dinar (DZD). + """ + DZD + + """ + Egyptian Pound (EGP). + """ + EGP + + """ + Eritrean Nakfa (ERN). + """ + ERN + + """ + Ethiopian Birr (ETB). + """ + ETB + + """ + Euro (EUR). + """ + EUR + + """ + Fijian Dollars (FJD). + """ + FJD + + """ + Falkland Islands Pounds (FKP). + """ + FKP + + """ + United Kingdom Pounds (GBP). + """ + GBP + + """ + Georgian Lari (GEL). + """ + GEL + + """ + Ghanaian Cedi (GHS). + """ + GHS + + """ + Gibraltar Pounds (GIP). + """ + GIP + + """ + Gambian Dalasi (GMD). + """ + GMD + + """ + Guinean Franc (GNF). + """ + GNF + + """ + Guatemalan Quetzal (GTQ). + """ + GTQ + + """ + Guyanese Dollar (GYD). + """ + GYD + + """ + Hong Kong Dollars (HKD). + """ + HKD + + """ + Honduran Lempira (HNL). + """ + HNL + + """ + Croatian Kuna (HRK). + """ + HRK + + """ + Haitian Gourde (HTG). + """ + HTG + + """ + Hungarian Forint (HUF). + """ + HUF + + """ + Indonesian Rupiah (IDR). + """ + IDR + + """ + Israeli New Shekel (NIS). + """ + ILS + + """ + Indian Rupees (INR). + """ + INR + + """ + Iraqi Dinar (IQD). + """ + IQD + + """ + Iranian Rial (IRR). + """ + IRR + + """ + Icelandic Kronur (ISK). + """ + ISK + + """ + Jersey Pound. + """ + JEP + + """ + Jamaican Dollars (JMD). + """ + JMD + + """ + Jordanian Dinar (JOD). + """ + JOD + + """ + Japanese Yen (JPY). + """ + JPY + + """ + Kenyan Shilling (KES). + """ + KES + + """ + Kyrgyzstani Som (KGS). + """ + KGS + + """ + Cambodian Riel. + """ + KHR + + """ + Kiribati Dollar (KID). + """ + KID + + """ + Comorian Franc (KMF). + """ + KMF + + """ + South Korean Won (KRW). + """ + KRW + + """ + Kuwaiti Dinar (KWD). + """ + KWD + + """ + Cayman Dollars (KYD). + """ + KYD + + """ + Kazakhstani Tenge (KZT). + """ + KZT + + """ + Laotian Kip (LAK). + """ + LAK + + """ + Lebanese Pounds (LBP). + """ + LBP + + """ + Sri Lankan Rupees (LKR). + """ + LKR + + """ + Liberian Dollar (LRD). + """ + LRD + + """ + Lesotho Loti (LSL). + """ + LSL + + """ + Lithuanian Litai (LTL). + """ + LTL + + """ + Latvian Lati (LVL). + """ + LVL + + """ + Libyan Dinar (LYD). + """ + LYD + + """ + Moroccan Dirham. + """ + MAD + + """ + Moldovan Leu (MDL). + """ + MDL + + """ + Malagasy Ariary (MGA). + """ + MGA + + """ + Macedonia Denar (MKD). + """ + MKD + + """ + Burmese Kyat (MMK). + """ + MMK + + """ + Mongolian Tugrik. + """ + MNT + + """ + Macanese Pataca (MOP). + """ + MOP + + """ + Mauritanian Ouguiya (MRU). + """ + MRU + + """ + Mauritian Rupee (MUR). + """ + MUR + + """ + Maldivian Rufiyaa (MVR). + """ + MVR + + """ + Malawian Kwacha (MWK). + """ + MWK + + """ + Mexican Pesos (MXN). + """ + MXN + + """ + Malaysian Ringgits (MYR). + """ + MYR + + """ + Mozambican Metical. + """ + MZN + + """ + Namibian Dollar. + """ + NAD + + """ + Nigerian Naira (NGN). + """ + NGN + + """ + Nicaraguan Córdoba (NIO). + """ + NIO + + """ + Norwegian Kroner (NOK). + """ + NOK + + """ + Nepalese Rupee (NPR). + """ + NPR + + """ + New Zealand Dollars (NZD). + """ + NZD + + """ + Omani Rial (OMR). + """ + OMR + + """ + Panamian Balboa (PAB). + """ + PAB + + """ + Peruvian Nuevo Sol (PEN). + """ + PEN + + """ + Papua New Guinean Kina (PGK). + """ + PGK + + """ + Philippine Peso (PHP). + """ + PHP + + """ + Pakistani Rupee (PKR). + """ + PKR + + """ + Polish Zlotych (PLN). + """ + PLN + + """ + Paraguayan Guarani (PYG). + """ + PYG + + """ + Qatari Rial (QAR). + """ + QAR + + """ + Romanian Lei (RON). + """ + RON + + """ + Serbian dinar (RSD). + """ + RSD + + """ + Russian Rubles (RUB). + """ + RUB + + """ + Rwandan Franc (RWF). + """ + RWF + + """ + Saudi Riyal (SAR). + """ + SAR + + """ + Solomon Islands Dollar (SBD). + """ + SBD + + """ + Seychellois Rupee (SCR). + """ + SCR + + """ + Sudanese Pound (SDG). + """ + SDG + + """ + Swedish Kronor (SEK). + """ + SEK + + """ + Singapore Dollars (SGD). + """ + SGD + + """ + Saint Helena Pounds (SHP). + """ + SHP + + """ + Sierra Leonean Leone (SLL). + """ + SLL + + """ + Somali Shilling (SOS). + """ + SOS + + """ + Surinamese Dollar (SRD). + """ + SRD + + """ + South Sudanese Pound (SSP). + """ + SSP + + """ + Sao Tome And Principe Dobra (STD). + """ + STD @deprecated(reason: "Use `STN` instead.") + + """ + Sao Tome And Principe Dobra (STN). + """ + STN + + """ + Syrian Pound (SYP). + """ + SYP + + """ + Swazi Lilangeni (SZL). + """ + SZL + + """ + Thai baht (THB). + """ + THB + + """ + Tajikistani Somoni (TJS). + """ + TJS + + """ + Turkmenistani Manat (TMT). + """ + TMT + + """ + Tunisian Dinar (TND). + """ + TND + + """ + Tongan Pa'anga (TOP). + """ + TOP + + """ + Turkish Lira (TRY). + """ + TRY + + """ + Trinidad and Tobago Dollars (TTD). + """ + TTD + + """ + Taiwan Dollars (TWD). + """ + TWD + + """ + Tanzanian Shilling (TZS). + """ + TZS + + """ + Ukrainian Hryvnia (UAH). + """ + UAH + + """ + Ugandan Shilling (UGX). + """ + UGX + + """ + United States Dollars (USD). + """ + USD + + """ + United States Dollars Coin (USDC). + """ + USDC + + """ + Uruguayan Pesos (UYU). + """ + UYU + + """ + Uzbekistan som (UZS). + """ + UZS + + """ + Venezuelan Bolivares (VED). + """ + VED + + """ + Venezuelan Bolivares (VEF). + """ + VEF @deprecated(reason: "Use `VES` instead.") + + """ + Venezuelan Bolivares Soberanos (VES). + """ + VES + + """ + Vietnamese đồng (VND). + """ + VND + + """ + Vanuatu Vatu (VUV). + """ + VUV + + """ + Samoan Tala (WST). + """ + WST + + """ + Central African CFA Franc (XAF). + """ + XAF + + """ + East Caribbean Dollar (XCD). + """ + XCD + + """ + West African CFA franc (XOF). + """ + XOF + + """ + CFP Franc (XPF). + """ + XPF + + """ + Unrecognized currency. + """ + XXX + + """ + Yemeni Rial (YER). + """ + YER + + """ + South African Rand (ZAR). + """ + ZAR + + """ + Zambian Kwacha (ZMW). + """ + ZMW +} + +""" +A custom product represents a product that doesn't map to Shopify's +[standard product categories](https://help.shopify.com/manual/products/details/product-type). +For example, you can use a custom product to manage gift cards, shipping requirements, localized product +information, or weight measurements and conversions. +""" +type CustomProduct { + """ + Whether the merchandise is a gift card. + """ + isGiftCard: Boolean! + + """ + Whether the item needs to be shipped to the customer. For example, a + digital gift card doesn't need to be shipped, but a t-shirt does + need to be shipped. + """ + requiresShipping: Boolean! + + """ + The localized name for the product that displays to customers. The title is used to construct the product's + handle, which is a unique, human-readable string of the product's title. For example, if a product is titled + "Black Sunglasses", then the handle is `black-sunglasses`. + """ + title: String! + + """ + The product variant's weight, in the system of measurement set in the `weightUnit` field. + """ + weight: Float + + """ + The unit of measurement for weight. + """ + weightUnit: WeightUnit! +} + +""" +Represents a [customer](https://help.shopify.com/manual/customers/manage-customers). +`Customer` returns data including the customer's contact information and order history. +""" +type Customer implements HasMetafields { + """ + The total amount that the customer has spent on orders. + The amount is converted from the shop's currency to the currency of the cart using a market rate. + """ + amountSpent: MoneyV2! + + """ + The full name of the customer, based on the values for `firstName` and `lastName`. + If `firstName` and `lastName` aren't specified, then the value is the customer's email address. + If the email address isn't specified, then the value is the customer's phone number. + """ + displayName: String! + + """ + The customer's email address. + """ + email: String + + """ + The customer's first name. + """ + firstName: String + + """ + Whether the customer is associated with any of the specified tags. The customer must have at least one tag + from the list to return `true`. + """ + hasAnyTag( + """ + A comma-separated list of searchable keywords that are associated with the customer. For example, + `"VIP, Gold"` returns customers with either the `VIP` or `Gold` tag. + """ + tags: [String!]! = [] + ): Boolean! + + """ + Whether the customer is associated with the specified tags. + """ + hasTags( + """ + A comma-separated list of searchable keywords that are associated with the customer. For example, + `"VIP, Gold"` returns customers with both the `VIP` and `Gold` tags. + """ + tags: [String!]! = [] + ): [HasTagResponse!]! + + """ + A [globally-unique ID](https://shopify.dev/docs/api/usage/gids) + for the customer. + """ + id: ID! + + """ + The customer's last name. + """ + lastName: String + + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield + + """ + The total number of orders that the customer has made at the store. + """ + numberOfOrders: Int! +} + +""" +Represents an [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601)-encoded date string. +For example, September 7, 2019 is represented as `"2019-07-16"`. +""" +scalar Date + +""" +Represents an [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601)-encoded date and time string. +For example, 3:50 pm on September 7, 2019 in the time zone of UTC (Coordinated Universal Time) is +represented as `"2019-09-07T15:50:00Z`". +""" +scalar DateTime + +""" +A subset of the [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format that +includes the date and time but not the timezone which is determined from context. + +For example, "2018-01-01T00:00:00". +""" +scalar DateTimeWithoutTimezone + +""" +A signed decimal number, which supports arbitrary precision and is serialized as a string. + +Example values: `"29.99"`, `"29.999"`. +""" +scalar Decimal + +""" +Represents information about the merchandise in the cart. +""" +type DeliverableCartLine { + """ + The custom attributes associated with a cart to store additional information. Cart attributes + allow you to collect specific information from customers on the **Cart** page, such as order notes, + gift wrapping requests, or custom product details. Attributes are stored as key-value pairs. + + Cart line attributes are equivalent to the + [`line_item`](https://shopify.dev/docs/api/liquid/objects/line_item) + object in Liquid. + """ + attribute( + """ + The key of the cart attribute to retrieve. For example, `"gift_wrapping"`. + """ + key: String + ): Attribute + + """ + The ID of the cart line. + """ + id: ID! + + """ + The item that the customer intends to purchase. + """ + merchandise: Merchandise! + + """ + The quantity of the item that the customer intends to purchase. + """ + quantity: Int! +} + +""" +List of different delivery method types. +""" +enum DeliveryMethod { + """ + Local Delivery. + """ + LOCAL + + """ + None. + """ + NONE + + """ + Shipping to a Pickup Point. + """ + PICKUP_POINT + + """ + Local Pickup. + """ + PICK_UP + + """ + Retail. + """ + RETAIL + + """ + Shipping. + """ + SHIPPING +} + +""" +The discount application and the amount applied. +""" +type DiscountAllocation { + """ + The discount that was applied. + """ + discountApplication: DiscountApplication! + + """ + The amount that was discounted. + """ + discountedAmount: MoneyV2! +} + +""" +Discount that has been applied to the cart. +""" +type DiscountApplication implements HasMetafields { + """ + The method by which the discount's value is allocated to its entitled items. + """ + allocationMethod: DiscountApplicationAllocationMethod! + + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield + + """ + The lines on the cart targeted by the discount. + """ + targetSelection: DiscountApplicationTargetSelection! + + """ + The type of line (i.e. line item or shipping line) on a cart that the discount is applicable towards. + """ + targetType: DiscountApplicationTarget! + + """ + The total allocated amount of the discount across all items. + """ + totalAllocatedAmount: MoneyV2! + + """ + The value of the discount. + """ + value: PricingValue! +} + +""" +The method by which the discount's value is allocated onto its entitled lines. +""" +enum DiscountApplicationAllocationMethod { + """ + The value is spread across all entitled lines. + """ + ACROSS + + """ + The value is applied onto every entitled line. + """ + EACH +} + +""" +The type of line on an order that the discount is applicable towards. +""" +enum DiscountApplicationTarget { + """ + The discount applies onto line items. + """ + LINE_ITEM + + """ + The discount applies onto shipping lines. + """ + SHIPPING_LINE +} + +""" +The lines on the order to which the discount is applied, of the type defined by +the discount application's `targetType`. For example, the value `ENTITLED`, combined with a `targetType` of +`LINE_ITEM`, applies the discount on all line items that are entitled to the discount. +The value `ALL`, combined with a `targetType` of `SHIPPING_LINE`, applies the discount on all shipping lines. +""" +enum DiscountApplicationTargetSelection { + """ + The discount is allocated onto all the lines. + """ + ALL + + """ + The discount is allocated onto only the lines that it's entitled for. + """ + ENTITLED + + """ + The discount is allocated onto explicitly chosen lines. + """ + EXPLICIT +} + +""" +An ISO 8601 duration string. For example: "P2D", "PT8H", "PT0S". +""" +scalar Duration + +""" +A set of one or more packages traveling together from a single origin +address to a single destination address. The function generates one or +more `FulfillmentOption`s per fulfillment. +""" +type Fulfillment { + """ + Handle of the fulfillment's destination address reference in `address_references`. + """ + destinationAddressHandle: Handle! + + """ + Stable handle identifying the fulfillment within the function input. + """ + handle: Handle! + + """ + Handle of the fulfillment's origin address reference in `address_references`. + """ + originAddressHandle: Handle! + + """ + The packages that make up the fulfillment. + """ + packages: [Package!]! +} + +""" +A polymorphic address used as the origin or destination of a fulfillment. + +- `MailingAddress`: a specific buyer-facing mailing address. +- `Location`: a merchant location, such as a retail store or warehouse. +- `ServiceArea`: a region (e.g. a pickup-point service area). +""" +union FulfillmentAddress = Location | MailingAddress | ServiceArea + +""" +A deduplicated fulfillment address referenced by a `Handle`. Fulfillments +reference addresses through their handle so the same address never has to +be serialized into the function input twice. +""" +type FulfillmentAddressReference { + """ + The polymorphic fulfillment address. + """ + address: FulfillmentAddress! + + """ + Stable handle identifying this fulfillment address reference within the function input. + """ + handle: Handle! +} + +""" +The fulfillment option generator the function instance is bound to. +""" +type FulfillmentOptionGenerator implements HasMetafields { + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield +} + +""" +Add a single fulfillment option for a specific fulfillment. +""" +input FulfillmentOptionsAddOperation { + """ + The specific carrier service level or service point to uniquely identify each fulfillment option in the context + of a single input fulfillment. + """ + code: String + + """ + Cost of the fulfillment option. Null defaults to 0 or a configured fallback. + """ + cost: MoneyV2Output + + """ + Override the destination address by referencing a service point in + `References.service_points` by handle. Required when the fulfillment's destination + address is a service area. + """ + destinationServicePointHandle: Handle + + """ + Handle of the input fulfillment this fulfillment option applies to. + """ + fulfillmentHandle: Handle! + + """ + Instructions shown to the buyer about how to receive the fulfillment, localized. + """ + instructions: String + + """ + Metafields associated with the fulfillment option. + """ + metafields: [MetafieldOutput!] = [] + + """ + Reference to a provider in `References.providers` by handle. + """ + providerHandle: Handle + + """ + Estimated fulfillment time period. Null means a `start` and `end` of + `after` P0D (zero duration). + """ + timePeriod: TimePeriod + + """ + Human-facing display name, localized. Can be a carrier service level or service point name. + """ + title: String +} + +""" +Represents a fulfillment service that prepares and ships orders on behalf of the store owner. +""" +type FulfillmentService { + """ + The app associated with this fulfillment service. + """ + app: App +} + +""" +A function-scoped handle to a refer a resource. +The Handle type appears in a JSON response as a String, but it is not intended to be human-readable. +Example value: `"10079785100"` +""" +scalar Handle + +""" +Represents information about the metafields associated to the specified resource. +""" +interface HasMetafields { + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield +} + +""" +Whether a Shopify resource, such as a product or customer, has a specified tag. +""" +type HasTagResponse { + """ + Whether the Shopify resource has the tag. + """ + hasTag: Boolean! + + """ + A searchable keyword that's associated with a Shopify resource, such as a product or customer. For example, + a merchant might apply the `sports` and `summer` tags to products that are associated with sportswear for + summer. + """ + tag: String! +} + +""" +The attributes associated with an HTTP request. +""" +input HttpRequest { + """ + The HTTP request body as a plain string. + Use this field when the body isn't in JSON format. + """ + body: String + + """ + The HTTP headers. + """ + headers: [HttpRequestHeader!]! + + """ + The HTTP request body as a JSON object. + Use this field when the body's in JSON format, to reduce function instruction consumption + and to ensure the body's formatted in logs. + Don't use this field together with the `body` field. If both are provided, then the `body` field + will take precedence. + If this field is specified and no `Content-Type` header is included, then the header will + automatically be set to `application/json`. + """ + jsonBody: JSON + + """ + The HTTP method. + """ + method: HttpRequestMethod! + + """ + Policy attached to the HTTP request. + """ + policy: HttpRequestPolicy! + + """ + The HTTP url (eg.: https://example.com). The scheme needs to be HTTPS. + """ + url: URL! +} + +""" +The attributes associated with an HTTP request header. +""" +input HttpRequestHeader { + """ + Header name. + """ + name: String! + + """ + Header value. + """ + value: String! +} + +""" +The HTTP request available methods. +""" +enum HttpRequestMethod { + """ + Http GET. + """ + GET + + """ + Http POST. + """ + POST +} + +""" +The attributes associated with an HTTP request policy. +""" +input HttpRequestPolicy { + """ + Read timeout in milliseconds. + """ + readTimeoutMs: Int! +} + +""" +The attributes associated with an HTTP response. +""" +type HttpResponse { + """ + The HTTP response body as a plain string. + Use this field when the body is not in JSON format. + """ + body: String + + """ + An HTTP header. + """ + header( + """ + A case-insensitive header name. + """ + name: String! + ): HttpResponseHeader + + """ + The HTTP headers. + """ + headers: [HttpResponseHeader!]! @deprecated(reason: "Use `header` instead.") + + """ + The HTTP response body parsed as JSON. + If the body is valid JSON, it will be parsed and returned as a JSON object. + If parsing fails, then raw body is returned as a string. + Use this field when you expect the response to be JSON, or when you're dealing + with mixed response types, meaning both JSON and non-JSON. + Using this field reduces function instruction consumption and ensures that the data is formatted in logs. + To prevent increasing the function target input size unnecessarily, avoid querying + both `body` and `jsonBody` simultaneously. + """ + jsonBody: JSON + + """ + The HTTP status code. + """ + status: Int! +} + +""" +The attributes associated with an HTTP response header. +""" +type HttpResponseHeader { + """ + Header name. + """ + name: String! + + """ + Header value. + """ + value: String! +} + +""" +Represents a unique identifier, often used to refetch an object. +The ID type appears in a JSON response as a String, but it is not intended to be human-readable. + +Example value: `"gid://shopify/Product/10079785100"` +""" +scalar ID + +type Input { + """ + Deduplicated list of fulfillment addresses referenced by fulfillments via + `Fulfillment.origin_address_handle` and + `Fulfillment.destination_address_handle`. Each reference's address can be + any variant of `FulfillmentAddress`. + """ + addressReferences: [FulfillmentAddressReference!]! + + """ + The cart where the Function is running. A cart contains the merchandise that a customer intends to purchase + and information about the customer, such as the customer's email address and phone number. + """ + cart: Cart! + + """ + The HTTP response produced by the function's `fetch` target. Available only on `run`. + """ + fetchResult: HttpResponse @restrictTarget(only: ["cart.fulfillment-options.generate.run"]) + + """ + The backend `DeliveryOptionGenerator` record this function instance is + bound to. Includes the metafields associated with the generator. + """ + fulfillmentOptionGenerator: FulfillmentOptionGenerator! + + """ + The fulfillments the function should produce fulfillment options for. Each + fulfillment has an origin, a destination, and a set of packages. + """ + fulfillments: [Fulfillment!]! @scaleLimits(rate: 0.05) + + """ + The regional and language settings that determine how the Function + handles currency, numbers, dates, and other locale-specific values + during discount calculations. These settings are based on the store's configured + [localization practices](https://shopify.dev/docs/apps/build/functions/localization-practices-shopify-functions). + """ + localization: Localization! + + """ + The exchange rate used to convert discounts between the shop's default + currency and the currency that displays to the customer during checkout. + For example, if a store operates in USD but a customer is viewing discounts in EUR, + then the presentment currency rate handles this conversion for accurate pricing. + """ + presentmentCurrencyRate: Decimal! + + """ + Information about the shop where the Function is running, including the shop's timezone + setting and associated [metafields](https://shopify.dev/docs/apps/build/custom-data). + """ + shop: Shop! +} + +""" +A [JSON](https://www.json.org/json-en.html) object. + +Example value: +`{ + "product": { + "id": "gid://shopify/Product/1346443542550", + "title": "White T-shirt", + "options": [{ + "name": "Size", + "values": ["M", "L"] + }] + } +}` +""" +scalar JSON + +""" +The language for which the store is customized, ensuring content is tailored to local customers. +This includes product descriptions and customer communications that resonate with the target audience. +""" +type Language { + """ + The ISO code. + """ + isoCode: LanguageCode! +} + +""" +Language codes supported by Shopify. +""" +enum LanguageCode { + """ + Afrikaans. + """ + AF + + """ + Akan. + """ + AK + + """ + Amharic. + """ + AM + + """ + Arabic. + """ + AR + + """ + Assamese. + """ + AS + + """ + Azerbaijani. + """ + AZ + + """ + Belarusian. + """ + BE + + """ + Bulgarian. + """ + BG + + """ + Bambara. + """ + BM + + """ + Bangla. + """ + BN + + """ + Tibetan. + """ + BO + + """ + Breton. + """ + BR + + """ + Bosnian. + """ + BS + + """ + Catalan. + """ + CA + + """ + Chechen. + """ + CE + + """ + Central Kurdish. + """ + CKB + + """ + Czech. + """ + CS + + """ + Church Slavic. + """ + CU + + """ + Welsh. + """ + CY + + """ + Danish. + """ + DA + + """ + German. + """ + DE + + """ + Dzongkha. + """ + DZ + + """ + Ewe. + """ + EE + + """ + Greek. + """ + EL + + """ + English. + """ + EN + + """ + Esperanto. + """ + EO + + """ + Spanish. + """ + ES + + """ + Estonian. + """ + ET + + """ + Basque. + """ + EU + + """ + Persian. + """ + FA + + """ + Fulah. + """ + FF + + """ + Finnish. + """ + FI + + """ + Filipino. + """ + FIL + + """ + Faroese. + """ + FO + + """ + French. + """ + FR + + """ + Western Frisian. + """ + FY + + """ + Irish. + """ + GA + + """ + Scottish Gaelic. + """ + GD + + """ + Galician. + """ + GL + + """ + Gujarati. + """ + GU + + """ + Manx. + """ + GV + + """ + Hausa. + """ + HA + + """ + Hebrew. + """ + HE + + """ + Hindi. + """ + HI + + """ + Croatian. + """ + HR + + """ + Hungarian. + """ + HU + + """ + Armenian. + """ + HY + + """ + Interlingua. + """ + IA + + """ + Indonesian. + """ + ID + + """ + Igbo. + """ + IG + + """ + Sichuan Yi. + """ + II + + """ + Icelandic. + """ + IS + + """ + Italian. + """ + IT + + """ + Japanese. + """ + JA + + """ + Javanese. + """ + JV + + """ + Georgian. + """ + KA + + """ + Kikuyu. + """ + KI + + """ + Kazakh. + """ + KK + + """ + Kalaallisut. + """ + KL + + """ + Khmer. + """ + KM + + """ + Kannada. + """ + KN + + """ + Korean. + """ + KO + + """ + Kashmiri. + """ + KS + + """ + Kurdish. + """ + KU + + """ + Cornish. + """ + KW + + """ + Kyrgyz. + """ + KY + + """ + Luxembourgish. + """ + LB + + """ + Ganda. + """ + LG + + """ + Lingala. + """ + LN + + """ + Lao. + """ + LO + + """ + Lithuanian. + """ + LT + + """ + Luba-Katanga. + """ + LU + + """ + Latvian. + """ + LV + + """ + Malagasy. + """ + MG + + """ + Māori. + """ + MI + + """ + Macedonian. + """ + MK + + """ + Malayalam. + """ + ML + + """ + Mongolian. + """ + MN + + """ + Marathi. + """ + MR + + """ + Malay. + """ + MS + + """ + Maltese. + """ + MT + + """ + Burmese. + """ + MY + + """ + Norwegian (Bokmål). + """ + NB + + """ + North Ndebele. + """ + ND + + """ + Nepali. + """ + NE + + """ + Dutch. + """ + NL + + """ + Norwegian Nynorsk. + """ + NN + + """ + Norwegian. + """ + NO + + """ + Oromo. + """ + OM + + """ + Odia. + """ + OR + + """ + Ossetic. + """ + OS + + """ + Punjabi. + """ + PA + + """ + Polish. + """ + PL + + """ + Pashto. + """ + PS + + """ + Portuguese. + """ + PT + + """ + Portuguese (Brazil). + """ + PT_BR + + """ + Portuguese (Portugal). + """ + PT_PT + + """ + Quechua. + """ + QU + + """ + Romansh. + """ + RM + + """ + Rundi. + """ + RN + + """ + Romanian. + """ + RO + + """ + Russian. + """ + RU + + """ + Kinyarwanda. + """ + RW + + """ + Sanskrit. + """ + SA + + """ + Sardinian. + """ + SC + + """ + Sindhi. + """ + SD + + """ + Northern Sami. + """ + SE + + """ + Sango. + """ + SG + + """ + Sinhala. + """ + SI + + """ + Slovak. + """ + SK + + """ + Slovenian. + """ + SL + + """ + Shona. + """ + SN + + """ + Somali. + """ + SO + + """ + Albanian. + """ + SQ + + """ + Serbian. + """ + SR + + """ + Sundanese. + """ + SU + + """ + Swedish. + """ + SV + + """ + Swahili. + """ + SW + + """ + Tamil. + """ + TA + + """ + Telugu. + """ + TE + + """ + Tajik. + """ + TG + + """ + Thai. + """ + TH + + """ + Tigrinya. + """ + TI + + """ + Turkmen. + """ + TK + + """ + Tongan. + """ + TO + + """ + Turkish. + """ + TR + + """ + Tatar. + """ + TT + + """ + Uyghur. + """ + UG + + """ + Ukrainian. + """ + UK + + """ + Urdu. + """ + UR + + """ + Uzbek. + """ + UZ + + """ + Vietnamese. + """ + VI + + """ + Volapük. + """ + VO + + """ + Wolof. + """ + WO + + """ + Xhosa. + """ + XH + + """ + Yiddish. + """ + YI + + """ + Yoruba. + """ + YO + + """ + Chinese. + """ + ZH + + """ + Chinese (Simplified). + """ + ZH_CN + + """ + Chinese (Traditional). + """ + ZH_TW + + """ + Zulu. + """ + ZU +} + +""" +A quantity of a single cart line included in a package. +""" +type LineQuantity { + """ + The cart line ID. + """ + lineId: ID! + + """ + The number of units of the line included in the package. Will be a positive number. + """ + quantity: Int! +} + +""" +Local pickup settings associated with a location. +""" +type LocalPickup { + """ + Whether local pickup is enabled for the location. + """ + enabled: Boolean! +} + +""" +The current time based on the +[store's timezone setting](https://help.shopify.com/manual/intro-to-shopify/initial-setup/setup-business-settings). +""" +type LocalTime { + """ + The current date relative to the parent object. + """ + date: Date! + + """ + Returns true if the current date and time is at or past the given date and time, and false otherwise. + """ + dateTimeAfter( + """ + The date and time to compare against, assumed to be in the timezone of the parent object. + """ + dateTime: DateTimeWithoutTimezone! + ): Boolean! + + """ + Returns true if the current date and time is before the given date and time, and false otherwise. + """ + dateTimeBefore( + """ + The date and time to compare against, assumed to be in the timezone of the parent timezone. + """ + dateTime: DateTimeWithoutTimezone! + ): Boolean! + + """ + Returns true if the current date and time is between the two given date and times, and false otherwise. + """ + dateTimeBetween( + """ + The upper bound time to compare against, assumed to be in the timezone of the parent timezone. + """ + endDateTime: DateTimeWithoutTimezone! + + """ + The lower bound time to compare against, assumed to be in the timezone of the parent timezone. + """ + startDateTime: DateTimeWithoutTimezone! + ): Boolean! + + """ + Returns true if the current time is at or past the given time, and false otherwise. + """ + timeAfter( + """ + The time to compare against, assumed to be in the timezone of the parent timezone. + """ + time: TimeWithoutTimezone! + ): Boolean! + + """ + Returns true if the current time is at or past the given time, and false otherwise. + """ + timeBefore( + """ + The time to compare against, assumed to be in the timezone of the parent timezone. + """ + time: TimeWithoutTimezone! + ): Boolean! + + """ + Returns true if the current time is between the two given times, and false otherwise. + """ + timeBetween( + """ + The upper bound time to compare against, assumed to be in the timezone of the parent timezone. + """ + endTime: TimeWithoutTimezone! + + """ + The lower bound time to compare against, assumed to be in the timezone of the parent timezone. + """ + startTime: TimeWithoutTimezone! + ): Boolean! +} + +""" +Details about the localized experience for the store in a specific region, including country and language +settings. The localized experience is determined by the store's settings and the customer's location. +Localization ensures that customers can access relevant content and options while browsing or purchasing +products in a store. +""" +type Localization { + """ + The country for which the store is customized, reflecting local preferences and regulations. + Localization might influence the language, currency, and product offerings available in a store to enhance + the shopping experience for customers in that region. + """ + country: Country! + + """ + The language for which the store is customized, ensuring content is tailored to local customers. + This includes product descriptions and customer communications that resonate with the target audience. + """ + language: Language! + + """ + The market of the active localized experience. + """ + market: Market! @deprecated(reason: "This `market` field will be removed in a future version of the API.") +} + +""" +Represents the value captured by a localized field. Localized fields are +additional fields required by certain countries on international orders. For +example, some countries require additional fields for customs information or tax +identification numbers. +""" +type LocalizedField { + """ + The key of the localized field. + """ + key: LocalizedFieldKey! + + """ + The title of the localized field. + """ + title: String! + + """ + The value of the localized field. + """ + value: String +} + +""" +Unique key identifying localized fields. +""" +enum LocalizedFieldKey { + """ + Localized field key 'shipping_credential_br' for country Brazil. + """ + SHIPPING_CREDENTIAL_BR + + """ + Localized field key 'shipping_credential_cl' for country Chile. + """ + SHIPPING_CREDENTIAL_CL + + """ + Localized field key 'shipping_credential_cn' for country China. + """ + SHIPPING_CREDENTIAL_CN + + """ + Localized field key 'shipping_credential_co' for country Colombia. + """ + SHIPPING_CREDENTIAL_CO + + """ + Localized field key 'shipping_credential_cr' for country Costa Rica. + """ + SHIPPING_CREDENTIAL_CR + + """ + Localized field key 'shipping_credential_ec' for country Ecuador. + """ + SHIPPING_CREDENTIAL_EC + + """ + Localized field key 'shipping_credential_es' for country Spain. + """ + SHIPPING_CREDENTIAL_ES + + """ + Localized field key 'shipping_credential_gt' for country Guatemala. + """ + SHIPPING_CREDENTIAL_GT + + """ + Localized field key 'shipping_credential_id' for country Indonesia. + """ + SHIPPING_CREDENTIAL_ID + + """ + Localized field key 'shipping_credential_kr' for country South Korea. + """ + SHIPPING_CREDENTIAL_KR + + """ + Localized field key 'shipping_credential_mx' for country Mexico. + """ + SHIPPING_CREDENTIAL_MX + + """ + Localized field key 'shipping_credential_my' for country Malaysia. + """ + SHIPPING_CREDENTIAL_MY + + """ + Localized field key 'shipping_credential_pe' for country Peru. + """ + SHIPPING_CREDENTIAL_PE + + """ + Localized field key 'shipping_credential_pt' for country Portugal. + """ + SHIPPING_CREDENTIAL_PT + + """ + Localized field key 'shipping_credential_py' for country Paraguay. + """ + SHIPPING_CREDENTIAL_PY + + """ + Localized field key 'shipping_credential_tr' for country Turkey. + """ + SHIPPING_CREDENTIAL_TR + + """ + Localized field key 'shipping_credential_tw' for country Taiwan. + """ + SHIPPING_CREDENTIAL_TW + + """ + Localized field key 'shipping_credential_type_co' for country Colombia. + """ + SHIPPING_CREDENTIAL_TYPE_CO + + """ + Localized field key 'tax_credential_br' for country Brazil. + """ + TAX_CREDENTIAL_BR + + """ + Localized field key 'tax_credential_cl' for country Chile. + """ + TAX_CREDENTIAL_CL + + """ + Localized field key 'tax_credential_co' for country Colombia. + """ + TAX_CREDENTIAL_CO + + """ + Localized field key 'tax_credential_cr' for country Costa Rica. + """ + TAX_CREDENTIAL_CR + + """ + Localized field key 'tax_credential_ec' for country Ecuador. + """ + TAX_CREDENTIAL_EC + + """ + Localized field key 'tax_credential_es' for country Spain. + """ + TAX_CREDENTIAL_ES + + """ + Localized field key 'tax_credential_gt' for country Guatemala. + """ + TAX_CREDENTIAL_GT + + """ + Localized field key 'tax_credential_id' for country Indonesia. + """ + TAX_CREDENTIAL_ID + + """ + Localized field key 'tax_credential_it' for country Italy. + """ + TAX_CREDENTIAL_IT + + """ + Localized field key 'tax_credential_mx' for country Mexico. + """ + TAX_CREDENTIAL_MX + + """ + Localized field key 'tax_credential_my' for country Malaysia. + """ + TAX_CREDENTIAL_MY + + """ + Localized field key 'tax_credential_pe' for country Peru. + """ + TAX_CREDENTIAL_PE + + """ + Localized field key 'tax_credential_pt' for country Portugal. + """ + TAX_CREDENTIAL_PT + + """ + Localized field key 'tax_credential_py' for country Paraguay. + """ + TAX_CREDENTIAL_PY + + """ + Localized field key 'tax_credential_tr' for country Turkey. + """ + TAX_CREDENTIAL_TR + + """ + Localized field key 'tax_credential_type_co' for country Colombia. + """ + TAX_CREDENTIAL_TYPE_CO + + """ + Localized field key 'tax_credential_type_mx' for country Mexico. + """ + TAX_CREDENTIAL_TYPE_MX + + """ + Localized field key 'tax_credential_use_mx' for country Mexico. + """ + TAX_CREDENTIAL_USE_MX + + """ + Localized field key 'tax_email_it' for country Italy. + """ + TAX_EMAIL_IT +} + +""" +Represents the location where the inventory resides. +""" +type Location implements HasMetafields { + """ + The address of this location. + """ + address: LocationAddress! + + """ + The fulfillment service, if any, that's associated with the location. + """ + fulfillmentService: FulfillmentService + + """ + The location handle. + """ + handle: Handle! + + """ + The location id. + """ + id: ID! + + """ + Local pickup settings associated with a location. + """ + localPickup: LocalPickup! + + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield + + """ + The name of the location. + """ + name: String! +} + +""" +Represents the address of a location. +""" +type LocationAddress { + """ + The first line of the address for the location. + """ + address1: String + + """ + The second line of the address for the location. + """ + address2: String + + """ + The city of the location. + """ + city: String + + """ + The country of the location. + """ + country: String + + """ + The country code of the location. + """ + countryCode: String + + """ + A formatted version of the address for the location. + """ + formatted: [String!]! + + """ + The approximate latitude coordinates of the location. + """ + latitude: Float + + """ + The approximate longitude coordinates of the location. + """ + longitude: Float + + """ + The phone number of the location. + """ + phone: String + + """ + The province of the location. + """ + province: String + + """ + The code for the province, state, or district of the address of the location. + """ + provinceCode: String + + """ + The ZIP code of the location. + """ + zip: String +} + +""" +Represents a mailing address. +""" +type MailingAddress { + """ + The first line of the address. Typically the street address or PO Box number. + """ + address1: String + + """ + The second line of the address. Typically the number of the apartment, suite, or unit. + """ + address2: String + + """ + The name of the city, district, village, or town. + """ + city: String + + """ + The name of the customer's company or organization. + """ + company: String + + """ + The two-letter code for the country of the address. For example, US. + """ + countryCode: CountryCode + + """ + The first name of the customer. + """ + firstName: String + + """ + The last name of the customer. + """ + lastName: String + + """ + The approximate latitude of the address. + """ + latitude: Float + + """ + The approximate longitude of the address. + """ + longitude: Float + + """ + The market of the address. + """ + market: Market @deprecated(reason: "This `market` field will be removed in a future version of the API.") + + """ + The full name of the customer, based on firstName and lastName. + """ + name: String + + """ + A unique phone number for the customer. Formatted using E.164 standard. For example, +16135551111. + """ + phone: String + + """ + The alphanumeric code for the region. For example, ON. + """ + provinceCode: String + + """ + The zip or postal code of the address. + """ + zip: String +} + +""" +A market is a group of one or more regions that you want to target for international sales. +By creating a market, you can configure a distinct, localized shopping experience for +customers from a specific area of the world. For example, you can +[change currency](https://shopify.dev/api/admin-graphql/current/mutations/marketCurrencySettingsUpdate), +[configure international pricing](https://shopify.dev/api/examples/product-price-lists), +or [add market-specific domains or subfolders](https://shopify.dev/api/admin-graphql/current/objects/MarketWebPresence). +""" +type Market implements HasMetafields { + """ + A human-readable unique string for the market automatically generated from its title. + """ + handle: Handle! + + """ + A globally-unique identifier. + """ + id: ID! + + """ + The manager of the market, if the accessing app is the market’s manager. Otherwise, this will be null. + """ + manager: MarketManager + + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield + + """ + A geographic region which comprises a market. + """ + regions: [MarketRegion!]! +} + +""" +The entity that manages a particular market. +""" +type MarketManager { + """ + The identity of the manager. This can either be `merchant` if the market is + manually managed by the merchant or an ID of the app responsible for managing the market. + """ + identifier: String! +} + +""" +Represents a region. +""" +interface MarketRegion { + """ + The name of the region in the language of the current localization. + """ + name: String +} + +""" +A country which comprises a market. +""" +type MarketRegionCountry implements MarketRegion { + """ + The two-letter code for the country. + """ + code: CountryCode! + + """ + The country name in the language of the current localization. + """ + name: String! +} + +""" +The item that a customer intends to purchase. Merchandise can be a product variant or a custom +product. + +A product variant is a specific version of a product that comes in more than one option, such as size or color. +For example, if a merchant sells t-shirts with options for size and color, then a small, blue t-shirt would be +one product variant and a large, blue t-shirt would be another. + +A custom product represents a product that doesn't map to Shopify's +[standard product categories](https://help.shopify.com/manual/products/details/product-type). +For example, you can use a custom product to manage gift cards, shipping requirements, localized product +information, or weight measurements and conversions. +""" +union Merchandise = CustomProduct | ProductVariant + +""" +[Custom fields](https://shopify.dev/docs/apps/build/custom-data) that store additional information +about a Shopify resource, such as products, orders, and +[many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). +Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) +enables you to customize the checkout experience. +""" +type Metafield { + """ + The data that's stored in the metafield, using JSON format. + """ + jsonValue: JSON! + + """ + The [type of data](https://shopify.dev/apps/metafields/types) that the metafield stores in + the `value` field. + """ + type: String! + + """ + The data that's stored in the metafield. The data is always stored as a string, + regardless of the [metafield's type](https://shopify.dev/apps/metafields/types). + """ + value: String! +} + +""" +[Custom fields](https://shopify.dev/docs/apps/build/custom-data) that store additional information +about a Shopify resource, such as products, orders, and +[many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). +Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) +enables you to customize the checkout experience. +""" +input MetafieldOutput { + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + + """ + The [type of data](https://shopify.dev/docs/apps/build/custom-data/metafields/list-of-data-types) + that's stored in the metafield. + """ + type: String! + + """ + The data to store in the metafield. + """ + value: String! +} + +""" +An instance of custom structured data defined by a MetaobjectDefinition. +""" +type Metaobject { + """ + The field for an object key, or null if the key has no field definition. + """ + field( + """ + The metaobject key to access. + """ + key: String! + ): MetaobjectField + + """ + The unique handle of the metaobject, useful as a custom ID. + """ + handle: String! + + """ + The type of the metaobject. + """ + type: String! +} + +""" +Provides a field definition and the data value assigned to it. +""" +type MetaobjectField { + """ + The assigned field value in JSON format. + """ + jsonValue: JSON + + """ + The object key of this field. + """ + key: String! + + """ + The type of the field. + """ + type: String! + + """ + The assigned field value, always stored as a string regardless of the field type. + """ + value: String +} + +""" +The input fields for retrieving a metaobject by handle. +""" +input MetaobjectHandleInput { + """ + The handle of the metaobject to retrieve. + """ + handle: String! + + """ + The type of the metaobject. Must match an existing metaobject definition type. + """ + type: String! +} + +""" +A precise monetary value and its associated currency. Combines a decimal amount +with a three-letter currency code to express prices, costs, and other financial +values throughout the API. For example, 12.99 USD. +""" +type MoneyV2 { + """ + A monetary value in decimal format, allowing for precise representation of cents or fractional + currency. For example, 12.99. + """ + amount: Decimal! + + """ + The three-letter currency code that represents a world currency used in a store. Currency codes + include standard [standard ISO 4217 codes](https://en.wikipedia.org/wiki/ISO_4217), legacy codes, + and non-standard codes. For example, USD. + """ + currencyCode: CurrencyCode! +} + +""" +A precise monetary value and its associated currency. Combines a decimal amount +with a three-letter currency code to express prices, costs, and other financial +values throughout the API. For example, 12.99 USD. +""" +input MoneyV2Output { + """ + A monetary value in decimal format, allowing for precise representation of cents or fractional + currency. For example, 12.99. + """ + amount: Decimal! + + """ + The three-letter currency code that represents a world currency used in a store. Currency codes + include standard [standard ISO 4217 codes](https://en.wikipedia.org/wiki/ISO_4217), legacy codes, + and non-standard codes. For example, USD. + """ + currencyCode: CurrencyCode! +} + +""" +The root mutation for the API. +""" +type MutationRoot { + """ + Handles the Function result for the cart.fulfillment-options.generate.fetch target. + """ + fetch( + """ + The result of the Function. + """ + result: FunctionFetchResult! + ): Void! + + """ + Handles the Function result for the cart.fulfillment-options.generate.run target. + """ + run( + """ + The result of the Function. + """ + result: FunctionRunResult! + ): Void! +} + +""" +An operation to apply when generating fulfillment options. +""" +input Operation { + """ + Add a fulfillment option. + """ + fulfillmentOptionsAdd: FulfillmentOptionsAddOperation! +} + +""" +A package within a fulfillment. Carries one or more cart-line quantities +and, when available, the package's physical attributes. +""" +type Package { + """ + The cart-line quantities included in the package. + """ + lineQuantities: [LineQuantity!]! +} + +""" +The percentage value of a discount. +""" +type PricingPercentageValue { + """ + The percentage value of the discount. + """ + value: Decimal! +} + +""" +The price value for a discount application. +""" +union PricingValue = MoneyV2 | PricingPercentageValue + +""" +The goods and services that merchants offer to customers. Products can include details such as +title, vendor, and custom data stored in [metafields](https://shopify.dev/docs/apps/build/custom-data). +Products can be organized by grouping them into a collection. + +Learn more about [managing products in a merchant's store](https://help.shopify.com/manual/products). +""" +type Product implements HasMetafields { + """ + A unique, human-readable string of the product's title. A handle can contain letters, hyphens (`-`), and + numbers, but not spaces. The handle is used in the online store URL for the product. For example, if a product + is titled "Black Sunglasses", then the handle is `black-sunglasses`. + """ + handle: Handle! + + """ + Whether the product is associated with any of the specified tags. The product must have at least one tag + from the list to return `true`. + """ + hasAnyTag( + """ + A comma-separated list of searchable keywords that are associated with the product. For example, + `"sports, summer"` returns products with either the `sports` or `summer` tag. + """ + tags: [String!]! = [] + ): Boolean! + + """ + Whether the product is associated with the specified tags. + """ + hasTags( + """ + A comma-separated list of searchable keywords that are associated with the product. For example, + `"sports, summer"` returns products with both the `sports` and `summer` tags. + """ + tags: [String!]! = [] + ): [HasTagResponse!]! + + """ + A [globally-unique ID](https://shopify.dev/docs/api/usage/gids) + for the product. + """ + id: ID! + + """ + Whether the product is in any of the specified collections. The product must be in at least one collection + from the list to return `true`. + + A collection is a group of products that can be displayed in online stores and other sales channels in + categories, which makes it easy for customers to find them. For example, an athletics store might create + different collections for running attire and accessories. + """ + inAnyCollection( + """ + A comma-separated list of [globally-unique collection IDs](https://shopify.dev/docs/api/usage/gids) + that are associated with the product. For example, `gid://shopify/Collection/123`, `gid://shopify/Collection/456`. + """ + ids: [ID!]! = [] + ): Boolean! + + """ + Whether the product is in the specified collections. The product must be in all of the collections in the + list to return `true`. + + A collection is a group of products that can be displayed in online stores and other sales channels in + categories, which makes it easy for customers to find them. For example, an athletics store might create + different collections for running attire and accessories. + """ + inCollections( + """ + A comma-separated list of [globally-unique collection IDs](https://shopify.dev/docs/api/usage/gids) + that are associated with the product. For example, `gid://shopify/Collection/123`, `gid://shopify/Collection/456`. + """ + ids: [ID!]! = [] + ): [CollectionMembership!]! + + """ + Whether the product is a gift card. + """ + isGiftCard: Boolean! + + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield + + """ + A custom category for a product. Product types allow merchants to define categories other than the + ones available in Shopify's + [standard product categories](https://help.shopify.com/manual/products/details/product-type). + """ + productType: String + + """ + The localized name for the product that displays to customers. The title is used to construct the product's + handle, which is a unique, human-readable string of the product's title. For example, if a product is titled + "Black Sunglasses", then the handle is `black-sunglasses`. + """ + title: String! + + """ + The name of the product's vendor. + """ + vendor: String +} + +""" +A specific version of a product that comes in more than one option, such as size or color. For example, +if a merchant sells t-shirts with options for size and color, then a small, blue t-shirt would be one +product variant and a large, blue t-shirt would be another. +""" +type ProductVariant implements HasMetafields { + """ + A [globally-unique ID](https://shopify.dev/docs/api/usage/gids) + for the product variant. + """ + id: ID! + + """ + Whether the product variant is in any of the specified collections. The variant must be in at least one + collection from the list to return `true`. A variant is considered to be in a collection when the variant + itself is a member of the collection, or when its product is a member of the collection. + + A collection is a group of products that can be displayed in online stores and other sales channels in + categories, which makes it easy for customers to find them. For example, an athletics store might create + different collections for running attire and accessories. + """ + inAnyCollection( + """ + A list of [globally-unique collection IDs](https://shopify.dev/docs/api/usage/gids) + to check membership against. For example, `gid://shopify/Collection/123`, `gid://shopify/Collection/456`. + """ + ids: [ID!]! = [] + ): Boolean! + + """ + Whether the product variant is in each of the specified collections. A variant is considered to be in a + collection when the variant itself is a member of the collection, or when its product is a member of the + collection. + + A collection is a group of products that can be displayed in online stores and other sales channels in + categories, which makes it easy for customers to find them. For example, an athletics store might create + different collections for running attire and accessories. + """ + inCollections( + """ + A list of [globally-unique collection IDs](https://shopify.dev/docs/api/usage/gids) + to check membership against. For example, `gid://shopify/Collection/123`, `gid://shopify/Collection/456`. + """ + ids: [ID!]! = [] + ): [CollectionMembership!]! + + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield + + """ + The product associated with the product variant. For example, if a + merchant sells t-shirts with options for size and color, then a small, + blue t-shirt would be one product variant and a large, blue t-shirt would be another. + The product associated with the product variant would be the t-shirt itself. + """ + product: Product! + + """ + Whether the item needs to be shipped to the customer. For example, a + digital gift card doesn't need to be shipped, but a t-shirt does + need to be shipped. + """ + requiresShipping: Boolean! + + """ + A case-sensitive identifier for the product variant in the merchant's store. For example, `"BBC-1"`. + A product variant must have a SKU to be connected to a + [fulfillment service](https://shopify.dev/docs/apps/build/orders-fulfillment/fulfillment-service-apps/build-for-fulfillment-services). + """ + sku: String + + """ + The localized name for the product variant that displays to customers. + """ + title: String + + """ + The product variant's weight, in the system of measurement set in the `weightUnit` field. + """ + weight: Float + + """ + The unit of measurement for weight. + """ + weightUnit: WeightUnit! +} + +""" +A fulfillment option provider. Providers are +declared once in `References.providers` and referenced from individual +fulfillment options by their handle, to keep the payload small. +""" +input Provider { + """ + The provider's external id from the third-party service. + """ + externalId: String! + + """ + Stable handle identifying the provider within this run result. + """ + handle: Handle! + + """ + URL to the provider's logo. Must use the `https` scheme, be served + from the Shopify CDN host, and be RFC 3986 compliant. + """ + logoUrl: URL! + + """ + The provider's display name. + """ + name: String! +} + +""" +The company of a B2B customer that's interacting with the cart. +Used to manage and track purchases made by businesses rather than individual customers. +""" +type PurchasingCompany { + """ + The company associated to the order or draft order. + """ + company: Company! + + """ + The company contact associated to the order or draft order. + """ + contact: CompanyContact + + """ + The company location associated to the order or draft order. + """ + location: CompanyLocation! +} + +""" +Deduplicated lookup tables for values that operations reference by +handle. Grouping references together keeps the payload compact when a +small number of providers or service points is shared across many +operations. +""" +input References { + """ + Deduplicated list of providers referenced by `fulfillment_options_add.provider_handle`. + """ + providers: [Provider!] = [] + + """ + Deduplicated list of service points referenced by `fulfillment_options_add.destination_service_point_handle`. + """ + servicePoints: [ServicePoint!] = [] +} + +""" +Represents how products and variants can be sold and purchased. +""" +type SellingPlan implements HasMetafields { + """ + The description of the selling plan. + """ + description: String + + """ + A globally-unique identifier. + """ + id: ID! + + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield + + """ + The name of the selling plan. For example, '6 weeks of prepaid granola, delivered weekly'. + """ + name: String! + + """ + Whether purchasing the selling plan will result in multiple deliveries. + """ + recurringDeliveries: Boolean! +} + +""" +Represents an association between a variant and a selling plan. Selling plan +allocations describe the options offered for each variant, and the price of the +variant when purchased with a selling plan. +""" +type SellingPlanAllocation { + """ + A list of price adjustments, with a maximum of two. When there are two, the + first price adjustment goes into effect at the time of purchase, while the + second one starts after a certain number of orders. A price adjustment + represents how a selling plan affects pricing when a variant is purchased with + a selling plan. Prices display in the customer's currency if the shop is + configured for it. + """ + priceAdjustments: [SellingPlanAllocationPriceAdjustment!]! + + """ + A representation of how products and variants can be sold and purchased. For + example, an individual selling plan could be '6 weeks of prepaid granola, + delivered weekly'. + """ + sellingPlan: SellingPlan! +} + +""" +The resulting prices for variants when they're purchased with a specific selling plan. +""" +type SellingPlanAllocationPriceAdjustment { + """ + The effective price for a single delivery. For example, for a prepaid + subscription plan that includes 6 deliveries at the price of $48.00, the per + delivery price is $8.00. + """ + perDeliveryPrice: MoneyV2! + + """ + The price of the variant when it's purchased with a selling plan For example, + for a prepaid subscription plan that includes 6 deliveries of $10.00 granola, + where the customer gets 20% off, the price is 6 x $10.00 x 0.80 = $48.00. + """ + price: MoneyV2! +} + +""" +A geographical region a fulfillment can be sent to (e.g. a pickup-point +service area) where the precise address may not be known up front. Expressed +as a radius around a center address. +""" +type ServiceArea { + """ + The center address of the service area, when known. + """ + address: MailingAddress + + """ + Radius around the center address, in meters. + """ + radius: Int +} + +""" +A third-party service point (such as a pickup-point locker or partner +location) returned by the function as a fulfillment address. Combines a +physical address with operational metadata. +""" +input ServicePoint { + """ + Address line 1. + """ + address1: String! + + """ + Address line 2. + """ + address2: String + + """ + Operating hours. A day with no entry is considered closed. + """ + businessHours: [BusinessHours!] + + """ + City. + """ + city: String! + + """ + Country code. + """ + countryCode: CountryCode! + + """ + The provider's external id for this service point. Required + and non-blank. + """ + externalId: String! + + """ + Stable handle identifying this service point within the run result. Referenced + by `FulfillmentOptionsAddOperation.destination_service_point_handle`. + """ + handle: Handle! + + """ + Latitude. + """ + latitude: Float! + + """ + Longitude. + """ + longitude: Float! + + """ + The name the third-party service has assigned to this service point. + Identifies the physical location itself. + """ + name: String! + + """ + Contact phone number for the service point. + """ + phone: String + + """ + Province or state code. + """ + provinceCode: String + + """ + Postal or ZIP code. + """ + zip: String +} + +""" +Information about the store, including the store's timezone setting +and custom data stored in [metafields](https://shopify.dev/docs/apps/build/custom-data). +""" +type Shop implements HasMetafields { + """ + The current time based on the + [store's timezone setting](https://help.shopify.com/manual/intro-to-shopify/initial-setup/setup-business-settings). + """ + localTime: LocalTime! + + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield + + """ + Fetch a specific Metaobject by one of its unique identifiers. Only app-owned + metaobjects with the $app reserved prefix are accessible to functions. + """ + metaobject( + """ + The handle and type of the metaobject. + """ + handle: MetaobjectHandleInput + + """ + The ID of the metaobject. + """ + id: ID + ): Metaobject +} + +""" +Represents information about the buyer that is interacting with the cart. +""" +type ShopUser implements HasMetafields { + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield +} + +""" +A period of time bounded by two `TimePoint`s. `end` must be greater than +or equal to `start`. Reads as, e.g., +`{ "start": { "at": "2026-06-09T12:10:23Z" }, "end": { "after": "P2D" } }`. +""" +input TimePeriod { + """ + Upper bound of the period. Must be >= `start`. + """ + end: TimePoint! + + """ + Lower bound of the period. + """ + start: TimePoint! +} + +""" +A single point in time, expressed as exactly one of: + +- `at`: an absolute `DateTime` (e.g. "2026-06-09T12:10:23Z"). +- `after`: a relative ISO 8601 `Duration` measured from the + fulfillment's ready time (e.g. "P2D"). +""" +input TimePoint @oneOf { + """ + A point in time relative to the fulfillment's ready time, as an ISO 8601 duration. + """ + after: Duration + + """ + An absolute point in time. + """ + at: DateTime +} + +""" +A subset of the [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format that +includes the time but not the date or timezone which is determined from context. +For example, "05:43:21". +""" +scalar TimeWithoutTimezone + +""" +Represents an [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986) and +[RFC 3987](https://datatracker.ietf.org/doc/html/rfc3987)-compliant URI string. + +For example, `"https://example.myshopify.com"` is a valid URL. It includes a scheme (`https`) and a host +(`example.myshopify.com`). +""" +scalar URL + +""" +A void type that can be used to return a null value from a mutation. +""" +scalar Void + +""" +A day of the week. +""" +enum Weekday { + """ + Friday. + """ + FRIDAY + + """ + Monday. + """ + MONDAY + + """ + Saturday. + """ + SATURDAY + + """ + Sunday. + """ + SUNDAY + + """ + Thursday. + """ + THURSDAY + + """ + Tuesday. + """ + TUESDAY + + """ + Wednesday. + """ + WEDNESDAY +} + +""" +Units of measurement for weight. +""" +enum WeightUnit { + """ + Metric system unit of mass. + """ + GRAMS + + """ + 1 kilogram equals 1000 grams. + """ + KILOGRAMS + + """ + Imperial system unit of mass. + """ + OUNCES + + """ + 1 pound equals 16 ounces. + """ + POUNDS +} diff --git a/functions-fulfillment-option-generators-rs/shopify.extension.toml.liquid b/functions-fulfillment-option-generators-rs/shopify.extension.toml.liquid new file mode 100644 index 00000000..261d5474 --- /dev/null +++ b/functions-fulfillment-option-generators-rs/shopify.extension.toml.liquid @@ -0,0 +1,26 @@ +api_version = "unstable" + +[[extensions]] +name = "t:name" +handle = "{{handle}}" +type = "function" +{% if uid %}uid = "{{ uid }}"{% endif %} + +[[extensions.targeting]] +target = "cart.fulfillment-options.generate.fetch" +input_query = "src/fetch.graphql" +export = "fetch" + +[[extensions.targeting]] +target = "cart.fulfillment-options.generate.run" +input_query = "src/run.graphql" +export = "run" + +[extensions.build] +command = "cargo build --target=wasm32-unknown-unknown --release" +path = "target/wasm32-unknown-unknown/release/{{handle | replace: " ", "_" | downcase}}.wasm" +watch = ["src/**/*.rs"] + +[extensions.ui.paths] +create = "/" +details = "/" diff --git a/functions-fulfillment-option-generators-rs/src/fetch.graphql.liquid b/functions-fulfillment-option-generators-rs/src/fetch.graphql.liquid new file mode 100644 index 00000000..6f103990 --- /dev/null +++ b/functions-fulfillment-option-generators-rs/src/fetch.graphql.liquid @@ -0,0 +1,7 @@ +query Input { + localization { + country { + isoCode + } + } +} diff --git a/functions-fulfillment-option-generators-rs/src/fetch.rs b/functions-fulfillment-option-generators-rs/src/fetch.rs new file mode 100644 index 00000000..0c182f1e --- /dev/null +++ b/functions-fulfillment-option-generators-rs/src/fetch.rs @@ -0,0 +1,32 @@ +use super::schema; +use shopify_function::prelude::*; +use shopify_function::Result; + +#[shopify_function] +fn fetch(input: schema::fetch::Input) -> Result { + // Only reach out to the external service when it can return relevant + // fulfillment options. Returning no request skips the network call entirely. + if input.localization().country().iso_code().as_str() == "CA" { + return Ok(schema::FunctionFetchResult { + request: Some(build_external_api_request()), + }); + } + + Ok(schema::FunctionFetchResult { request: None }) +} + +fn build_external_api_request() -> schema::HttpRequest { + schema::HttpRequest { + method: schema::HttpRequestMethod::Get, + url: "https://cdn.shopify.com/s/files/1/0628/3830/9033/files/pickup-points-external-api-v2.json?v=1714588690".to_string(), + headers: vec![schema::HttpRequestHeader { + name: "Accept".to_string(), + value: "application/json; charset=utf-8".to_string(), + }], + body: None, + json_body: None, + policy: schema::HttpRequestPolicy { + read_timeout_ms: 500, + }, + } +} diff --git a/functions-fulfillment-option-generators-rs/src/main.rs b/functions-fulfillment-option-generators-rs/src/main.rs new file mode 100644 index 00000000..ed1b4368 --- /dev/null +++ b/functions-fulfillment-option-generators-rs/src/main.rs @@ -0,0 +1,24 @@ +use shopify_function::prelude::*; +use std::process; + +pub mod fetch; +pub mod run; + +#[typegen("schema.graphql")] +pub mod schema { + // Type aliases must be defined for any custom scalars in the schema that the + // typegen macro doesn't already know about. `Duration` is an ISO 8601 duration + // string (e.g. "P2D"). + type Duration = String; + + #[query("src/run.graphql")] + pub mod run {} + + #[query("src/fetch.graphql")] + pub mod fetch {} +} + +fn main() { + log!("Please invoke a named export."); + process::abort(); +} diff --git a/functions-fulfillment-option-generators-rs/src/run.graphql.liquid b/functions-fulfillment-option-generators-rs/src/run.graphql.liquid new file mode 100644 index 00000000..be5ba1b9 --- /dev/null +++ b/functions-fulfillment-option-generators-rs/src/run.graphql.liquid @@ -0,0 +1,9 @@ +query Input { + fulfillments { + handle + } + fetchResult { + status + body + } +} diff --git a/functions-fulfillment-option-generators-rs/src/run.rs b/functions-fulfillment-option-generators-rs/src/run.rs new file mode 100644 index 00000000..b5183e69 --- /dev/null +++ b/functions-fulfillment-option-generators-rs/src/run.rs @@ -0,0 +1,183 @@ +use super::schema; +use shopify_function::prelude::*; +use shopify_function::Result; + +use serde_json::Value; + +type TimeWithoutTimezone = String; + +#[shopify_function] +fn run(input: schema::run::Input) -> Result { + // The HTTP response from the `fetch` target is available here in `fetch_result`. + let Some(fetch_result) = input.fetch_result() else { + return Ok(empty_result()); + }; + + if *fetch_result.status() != 200 { + return Ok(empty_result()); + } + + let Some(body) = fetch_result.body() else { + return Ok(empty_result()); + }; + + let Ok(external_api_data) = serde_json::from_str::(body) else { + return Ok(empty_result()); + }; + + let Some(external_api_delivery_points) = external_api_data["deliveryPoints"].as_array() else { + return Ok(empty_result()); + }; + + // Providers and service points are deduplicated into the `references` block + // and referenced from operations by their handle, to keep the payload small. + let provider = build_provider(); + let service_points: Vec = external_api_delivery_points + .iter() + .filter_map(build_service_point) + .collect(); + + // Generate one fulfillment option per service point, for every input fulfillment. + let mut operations = Vec::new(); + for fulfillment in input.fulfillments().iter() { + for service_point in service_points.iter() { + operations.push(schema::Operation { + fulfillment_options_add: schema::FulfillmentOptionsAddOperation { + fulfillment_handle: fulfillment.handle().to_string(), + code: None, + title: Some(service_point.name.clone()), + instructions: None, + provider_handle: Some(provider.handle.clone()), + destination_service_point_handle: Some(service_point.handle.clone()), + cost: None, + time_period: None, + metafields: Some(vec![]), + }, + }); + } + } + + Ok(schema::FunctionRunResult { + references: Some(schema::References { + providers: Some(vec![provider]), + service_points: Some(service_points), + }), + operations, + }) +} + +fn empty_result() -> schema::FunctionRunResult { + schema::FunctionRunResult { + operations: vec![], + references: None, + } +} + +fn build_provider() -> schema::Provider { + schema::Provider { + handle: "shopify-demo-provider".to_string(), + external_id: "shopify-demo".to_string(), + name: "Shopify Functions Demo".to_string(), + logo_url: "https://cdn.shopify.com/s/files/1/0628/3830/9033/files/shopify_icon_146101.png?v=1706120545".to_string(), + } +} + +fn build_service_point(external_api_delivery_point: &Value) -> Option { + let location = &external_api_delivery_point["location"]; + let address_components = &location["addressComponents"]; + let geometry = &location["geometry"]["location"]; + let point_id = external_api_delivery_point["pointId"].as_str()?; + + Some(schema::ServicePoint { + handle: format!("service-point-{point_id}"), + external_id: point_id.to_string(), + name: external_api_delivery_point["pointName"] + .as_str()? + .to_string(), + address_1: format!( + "{} {}", + address_components["streetNumber"].as_str()?, + address_components["route"].as_str()? + ), + address_2: None, + city: address_components["locality"].as_str()?.to_string(), + country_code: address_components["countryCode"].as_str()?.to_string(), + province_code: address_components["administrativeArea"]["code"] + .as_str() + .map(|code| code.to_string()), + zip: address_components["postalCode"] + .as_str() + .map(|zip| zip.to_string()), + phone: None, + latitude: geometry["lat"].as_f64().unwrap_or_default(), + longitude: geometry["lng"].as_f64().unwrap_or_default(), + business_hours: build_business_hours(external_api_delivery_point), + }) +} + +/// Transforms the opening hours of a delivery point into a vector of `BusinessHours` objects. +/// Each day's opening hours are represented using a `BusinessHours` object as follows: +/// "Monday: 9:00 AM – 5:00 PM" is transformed to {day: Monday, periods: [{opening_time: "09:00:00", closing_time: "17:00:00"}]} +/// "Tuesday: Closed" is transformed to {day: Tuesday, periods: []} +fn build_business_hours(external_api_delivery_point: &Value) -> Option> { + if external_api_delivery_point["openingHours"].is_null() { + return None; + } + + let business_hours = external_api_delivery_point["openingHours"]["weekdayText"] + .as_array() + .unwrap() + .iter() + .map(|day| { + let day_parts: Vec<&str> = day.as_str().unwrap().split(": ").collect(); + let day_name = schema::Weekday::from_str(&day_parts[0].to_uppercase()); + if day_parts[1] == "Closed" { + schema::BusinessHours { + day: day_name, + periods: vec![], + } + } else { + let opening_closing_times: Vec<&str> = day_parts[1].split(" – ").collect(); + schema::BusinessHours { + day: day_name, + periods: vec![schema::BusinessHoursPeriod { + opening_time: format_time(opening_closing_times[0]), + closing_time: format_time(opening_closing_times[1]), + }], + } + } + }) + .collect(); + + Some(business_hours) +} + +/// Converts a time string from 12-hour to 24-hour format. +/// Example: "9:00 AM" => "09:00:00", "5:00 PM" => "17:00:00" +fn format_time(time: &str) -> TimeWithoutTimezone { + let time_parts: Vec<&str> = time.split_whitespace().collect(); + let hour_min: Vec<&str> = time_parts[0].split(':').collect(); + let hour: u32 = hour_min[0].parse().unwrap(); + let min: &str = hour_min[1]; + let period: &str = time_parts[1]; + + let hour_in_24_format = match period { + "AM" => { + if hour == 12 { + 0 + } else { + hour + } + } + "PM" => { + if hour == 12 { + hour + } else { + hour + 12 + } + } + _ => hour, + }; + + format!("{hour_in_24_format:02}:{min:02}:00") +} diff --git a/functions-fulfillment-option-generators-rs/tests/default.test.js b/functions-fulfillment-option-generators-rs/tests/default.test.js new file mode 100644 index 00000000..0d5ad405 --- /dev/null +++ b/functions-fulfillment-option-generators-rs/tests/default.test.js @@ -0,0 +1,44 @@ +import path from "path"; +import fs from "fs"; +import { describe, beforeAll, test, expect } from "vitest"; +import { buildFunction, getFunctionInfo, loadSchema, loadInputQuery, loadFixture, validateTestAssets, runFunction } from "@shopify/shopify-function-test-helpers"; + +describe("Default Integration Test", () => { + let schema; + let functionDir; + let functionInfo; + let schemaPath; + let targeting; + let functionRunnerPath; + let wasmPath; + + beforeAll(async () => { + functionDir = path.dirname(__dirname); + await buildFunction(functionDir); + functionInfo = await getFunctionInfo(functionDir); + ({ schemaPath, functionRunnerPath, wasmPath, targeting } = functionInfo); + schema = await loadSchema(schemaPath); + }, 45000); + + const fixturesDir = path.join(__dirname, "fixtures"); + const fixtureFiles = fs.readdirSync(fixturesDir) + .filter((file) => file.endsWith(".json")) + .map((file) => path.join(fixturesDir, file)); + + fixtureFiles.forEach((fixtureFile) => { + test(`runs ${path.relative(fixturesDir, fixtureFile)}`, async () => { + const fixture = await loadFixture(fixtureFile); + const targetInputQueryPath = targeting[fixture.target].inputQueryPath; + const inputQueryAST = await loadInputQuery(targetInputQueryPath); + + const validationResult = await validateTestAssets({ schema, fixture, inputQueryAST }); + expect(validationResult.inputQuery.errors).toEqual([]); + expect(validationResult.inputFixture.errors).toEqual([]); + expect(validationResult.outputFixture.errors).toEqual([]); + + const runResult = await runFunction(fixture, functionRunnerPath, wasmPath, targetInputQueryPath, schemaPath); + expect(runResult.error).toBeNull(); + expect(runResult.result.output).toEqual(fixture.expectedOutput); + }, 10000); + }); +}); diff --git a/functions-fulfillment-option-generators-rs/tests/fixtures/fetch-canada-request.json b/functions-fulfillment-option-generators-rs/tests/fixtures/fetch-canada-request.json new file mode 100644 index 00000000..c6d6d0ed --- /dev/null +++ b/functions-fulfillment-option-generators-rs/tests/fixtures/fetch-canada-request.json @@ -0,0 +1,27 @@ +{ + "payload": { + "export": "fetch", + "target": "cart.fulfillment-options.generate.fetch", + "input": { + "localization": { + "country": { + "isoCode": "CA" + } + } + }, + "output": { + "request": { + "method": "GET", + "url": "https://cdn.shopify.com/s/files/1/0628/3830/9033/files/pickup-points-external-api-v2.json?v=1714588690", + "headers": [ + { "name": "Accept", "value": "application/json; charset=utf-8" } + ], + "body": null, + "jsonBody": null, + "policy": { + "readTimeoutMs": 500 + } + } + } + } +} diff --git a/functions-fulfillment-option-generators-rs/tests/fixtures/fetch-non-canada-no-request.json b/functions-fulfillment-option-generators-rs/tests/fixtures/fetch-non-canada-no-request.json new file mode 100644 index 00000000..037487f4 --- /dev/null +++ b/functions-fulfillment-option-generators-rs/tests/fixtures/fetch-non-canada-no-request.json @@ -0,0 +1,16 @@ +{ + "payload": { + "export": "fetch", + "target": "cart.fulfillment-options.generate.fetch", + "input": { + "localization": { + "country": { + "isoCode": "US" + } + } + }, + "output": { + "request": null + } + } +} diff --git a/functions-fulfillment-option-generators-rs/tests/fixtures/run-failed-response.json b/functions-fulfillment-option-generators-rs/tests/fixtures/run-failed-response.json new file mode 100644 index 00000000..ea3e1423 --- /dev/null +++ b/functions-fulfillment-option-generators-rs/tests/fixtures/run-failed-response.json @@ -0,0 +1,19 @@ +{ + "payload": { + "export": "run", + "target": "cart.fulfillment-options.generate.run", + "input": { + "fulfillments": [ + { "handle": "fulfillment-1" } + ], + "fetchResult": { + "status": 500, + "body": "Server Error" + } + }, + "output": { + "references": null, + "operations": [] + } + } +} diff --git a/functions-fulfillment-option-generators-rs/tests/fixtures/run-null-opening-hours.json b/functions-fulfillment-option-generators-rs/tests/fixtures/run-null-opening-hours.json new file mode 100644 index 00000000..587a38d7 --- /dev/null +++ b/functions-fulfillment-option-generators-rs/tests/fixtures/run-null-opening-hours.json @@ -0,0 +1,59 @@ +{ + "payload": { + "export": "run", + "target": "cart.fulfillment-options.generate.run", + "input": { + "fulfillments": [ + { "handle": "fulfillment-1" } + ], + "fetchResult": { + "status": 200, + "body": "{\"deliveryPoints\":[{\"pointId\":\"001\",\"pointName\":\"Toronto Store\",\"location\":{\"addressComponents\":{\"streetNumber\":\"620\",\"route\":\"King St W\",\"locality\":\"Toronto\",\"administrativeArea\":{\"name\":\"Ontario\",\"code\":\"ON\"},\"postalCode\":\"M5V 1M6\",\"country\":\"Canada\",\"countryCode\":\"CA\"},\"geometry\":{\"location\":{\"lat\":43.644664618786685,\"lng\":-79.40066267417106}}},\"openingHours\":null}]}" + } + }, + "output": { + "references": { + "providers": [ + { + "handle": "shopify-demo-provider", + "externalId": "shopify-demo", + "name": "Shopify Functions Demo", + "logoUrl": "https://cdn.shopify.com/s/files/1/0628/3830/9033/files/shopify_icon_146101.png?v=1706120545" + } + ], + "servicePoints": [ + { + "handle": "service-point-001", + "externalId": "001", + "name": "Toronto Store", + "address1": "620 King St W", + "address2": null, + "city": "Toronto", + "countryCode": "CA", + "provinceCode": "ON", + "zip": "M5V 1M6", + "phone": null, + "latitude": 43.644664618786685, + "longitude": -79.40066267417106, + "businessHours": null + } + ] + }, + "operations": [ + { + "fulfillmentOptionsAdd": { + "fulfillmentHandle": "fulfillment-1", + "code": null, + "title": "Toronto Store", + "instructions": null, + "providerHandle": "shopify-demo-provider", + "destinationServicePointHandle": "service-point-001", + "cost": null, + "timePeriod": null, + "metafields": [] + } + } + ] + } + } +} diff --git a/functions-fulfillment-option-generators-rs/tests/fixtures/run-successful-fetch.json b/functions-fulfillment-option-generators-rs/tests/fixtures/run-successful-fetch.json new file mode 100644 index 00000000..d319da8a --- /dev/null +++ b/functions-fulfillment-option-generators-rs/tests/fixtures/run-successful-fetch.json @@ -0,0 +1,62 @@ +{ + "payload": { + "export": "run", + "target": "cart.fulfillment-options.generate.run", + "input": { + "fulfillments": [ + { "handle": "fulfillment-1" } + ], + "fetchResult": { + "status": 200, + "body": "{\"deliveryPoints\":[{\"pointId\":\"001\",\"pointName\":\"Toronto Store\",\"location\":{\"addressComponents\":{\"streetNumber\":\"620\",\"route\":\"King St W\",\"locality\":\"Toronto\",\"administrativeArea\":{\"name\":\"Ontario\",\"code\":\"ON\"},\"postalCode\":\"M5V 1M6\",\"country\":\"Canada\",\"countryCode\":\"CA\"},\"geometry\":{\"location\":{\"lat\":43.644664618786685,\"lng\":-79.40066267417106}}},\"openingHours\":{\"weekdayText\":[\"Monday: 9:00 AM – 9:00 PM\",\"Sunday: Closed\"]}}]}" + } + }, + "output": { + "references": { + "providers": [ + { + "handle": "shopify-demo-provider", + "externalId": "shopify-demo", + "name": "Shopify Functions Demo", + "logoUrl": "https://cdn.shopify.com/s/files/1/0628/3830/9033/files/shopify_icon_146101.png?v=1706120545" + } + ], + "servicePoints": [ + { + "handle": "service-point-001", + "externalId": "001", + "name": "Toronto Store", + "address1": "620 King St W", + "address2": null, + "city": "Toronto", + "countryCode": "CA", + "provinceCode": "ON", + "zip": "M5V 1M6", + "phone": null, + "latitude": 43.644664618786685, + "longitude": -79.40066267417106, + "businessHours": [ + { "day": "MONDAY", "periods": [{ "openingTime": "09:00:00", "closingTime": "21:00:00" }] }, + { "day": "SUNDAY", "periods": [] } + ] + } + ] + }, + "operations": [ + { + "fulfillmentOptionsAdd": { + "fulfillmentHandle": "fulfillment-1", + "code": null, + "title": "Toronto Store", + "instructions": null, + "providerHandle": "shopify-demo-provider", + "destinationServicePointHandle": "service-point-001", + "cost": null, + "timePeriod": null, + "metafields": [] + } + } + ] + } + } +} diff --git a/functions-fulfillment-option-generators-rs/vitest.config.js b/functions-fulfillment-option-generators-rs/vitest.config.js new file mode 100644 index 00000000..b1d0db3a --- /dev/null +++ b/functions-fulfillment-option-generators-rs/vitest.config.js @@ -0,0 +1,8 @@ +export default { + test: { + forceRerunTriggers: [ + '**/tests/fixtures/**', + '**/src/**', + ], + }, +}; diff --git a/functions-fulfillment-option-generators-wasm/fetch.graphql.liquid b/functions-fulfillment-option-generators-wasm/fetch.graphql.liquid new file mode 100644 index 00000000..6f103990 --- /dev/null +++ b/functions-fulfillment-option-generators-wasm/fetch.graphql.liquid @@ -0,0 +1,7 @@ +query Input { + localization { + country { + isoCode + } + } +} diff --git a/functions-fulfillment-option-generators-wasm/locales/en.default.json.liquid b/functions-fulfillment-option-generators-wasm/locales/en.default.json.liquid new file mode 100644 index 00000000..333045ae --- /dev/null +++ b/functions-fulfillment-option-generators-wasm/locales/en.default.json.liquid @@ -0,0 +1,4 @@ +{ + "name": "{{name}}", + "description": "{{name}}" +} diff --git a/functions-fulfillment-option-generators-wasm/run.graphql.liquid b/functions-fulfillment-option-generators-wasm/run.graphql.liquid new file mode 100644 index 00000000..be5ba1b9 --- /dev/null +++ b/functions-fulfillment-option-generators-wasm/run.graphql.liquid @@ -0,0 +1,9 @@ +query Input { + fulfillments { + handle + } + fetchResult { + status + body + } +} diff --git a/functions-fulfillment-option-generators-wasm/schema.graphql b/functions-fulfillment-option-generators-wasm/schema.graphql new file mode 100644 index 00000000..2b5d55cd --- /dev/null +++ b/functions-fulfillment-option-generators-wasm/schema.graphql @@ -0,0 +1,5800 @@ +# This file is auto-generated from the current state of the GraphQL API. Instead of editing this file, +# please edit the ruby definition files and run `bin/rails graphql:schema:dump` to regenerate the schema. +# +# If you're just looking to browse, you may find it friendlier to use the graphiql browser which is +# available in services-internal at https://app.shopify.com/services/internal/shops/14168/graphql. +# Check out the "Docs" tab in the top right. + +schema { + query: Input + mutation: MutationRoot +} + +""" +Only allow the field to be queried when targeting one of the specified targets. +""" +directive @restrictTarget(only: [String!]!) on FIELD_DEFINITION + +""" +Scale the Functions resource limits based on the field's length. +""" +directive @scaleLimits(rate: Float!) on FIELD_DEFINITION + +""" +Requires that exactly one field must be supplied and that field must not be `null`. +""" +directive @oneOf on INPUT_OBJECT + +""" +Represents an app. +""" +type App { + """ + The ID of the app. + """ + id: ID! +} + +""" +A custom property. Attributes are used to store additional information about a Shopify resource, such as +products, customers, or orders. Attributes are stored as key-value pairs. + +For example, a list of attributes might include whether a customer is a first-time buyer (`"customer_first_order": "true"`), +whether an order is gift-wrapped (`"gift_wrapped": "true"`), a preferred delivery date +(`"preferred_delivery_date": "2025-10-01"`), the discount applied (`"loyalty_discount_applied": "10%"`), and any +notes provided by the customer (`"customer_notes": "Please leave at the front door"`). +""" +type Attribute { + """ + The key or name of the attribute. For example, `"customer_first_order"`. + """ + key: String! + + """ + The value of the attribute. For example, `"true"`. + """ + value: String +} + +""" +Operating hours of a service point for a specific day of the week. A day +with no entry is considered closed. Use multiple periods to express +split schedules (e.g. lunch closures). +""" +input BusinessHours { + """ + The day of the week. + """ + day: Weekday! + + """ + Operating periods for the day. + """ + periods: [BusinessHoursPeriod!]! +} + +""" +An operating-time period within a single day at a service point. +""" +input BusinessHoursPeriod { + """ + The time the service point closes. + """ + closingTime: TimeWithoutTimezone! + + """ + The time the service point opens. + """ + openingTime: TimeWithoutTimezone! +} + +""" +Information about the customer that's interacting with the cart. It includes details such as the +customer's email and phone number, and the total amount of money the customer has spent in the store. +This information helps personalize the checkout experience and ensures that accurate pricing and delivery options +are displayed to customers. +""" +type BuyerIdentity { + """ + The [customer](https://help.shopify.com/manual/customers/manage-customers) that's interacting with the cart. + """ + customer: Customer + + """ + The email address of the customer that's interacting with the cart. + """ + email: String + + """ + Whether the customer is authenticated through their + [customer account](https://help.shopify.com/manual/customers/customer-accounts). + """ + isAuthenticated: Boolean! + + """ + The phone number of the customer that's interacting with the cart. + """ + phone: String + + """ + The company of a B2B customer that's interacting with the cart. + Used to manage and track purchases made by businesses rather than individual customers. + """ + purchasingCompany: PurchasingCompany + + """ + Represents the [Shop User](https://help.shopify.com/en/manual/online-sales-channels/shop/sign-in-features) + corresponding to the customer within the shop, if the buyer is a Shop User. Can be used to request [Shop User + metafields](https://shopify.dev/docs/api/shop-user-custom-data). + """ + shopUser: ShopUser +} + +""" +The cart where the Function is running. A cart contains the merchandise that a customer intends to purchase +and information about the customer, such as the customer's email address and phone number. +""" +type Cart implements HasMetafields { + """ + The custom attributes associated with a cart to store additional information. Cart attributes + allow you to collect specific information from customers on the **Cart** page, such as order notes, + gift wrapping requests, or custom product details. Attributes are stored as key-value pairs. + """ + attribute( + """ + The key of the cart attribute to retrieve. For example, `"gift_wrapping"`. + """ + key: String + ): Attribute + + """ + The billing address associated with the cart. + """ + billingAddress: MailingAddress + + """ + Information about the customer that's interacting with the cart. It includes details such as the + customer's email and phone number, and the total amount of money the customer has spent in the store. + This information helps personalize the checkout experience and ensures that accurate pricing and delivery options + are displayed to customers. + """ + buyerIdentity: BuyerIdentity + + """ + A breakdown of the costs that the customer will pay at checkout. It includes the total amount, + the subtotal before taxes and duties, the tax amount, and duty charges. + """ + cost: CartCost! + + """ + The items in a cart that are eligible for fulfillment and can be delivered to the customer. + """ + deliverableLines: [DeliverableCartLine!]! + + """ + A collection of items that are grouped by shared delivery characteristics. Delivery groups streamline + fulfillment by organizing items that can be shipped together, based on the customer's + shipping address. For example, if a customer orders a t-shirt and a pair of shoes that can be shipped + together, then the items are included in the same delivery group. + + In the [Order Discount](https://shopify.dev/docs/api/functions/reference/order-discounts) and + [Product Discount](https://shopify.dev/docs/api/functions/reference/product-discounts) legacy APIs, + the `cart.deliveryGroups` input is always an empty array. This means you can't access delivery groups when + creating Order Discount or Product Discount Functions. If you need to apply discounts to shipping costs, + then use the [Discount Function API](https://shopify.dev/docs/api/functions/reference/discount) + instead. + """ + deliveryGroups: [CartDeliveryGroup!]! + + """ + The discounts that have been applied to the cart. + """ + discountApplications: [DiscountApplication!]! + + """ + The items in a cart that the customer intends to purchase. A cart line is an entry in the + customer's cart that represents a single unit of a product variant. For example, if a customer adds two + different sizes of the same t-shirt to their cart, then each size is represented as a separate cart line. + """ + lines: [CartLine!]! @scaleLimits(rate: 0.005) + + """ + The additional fields on the **Cart** page that are required for international orders in specific countries, + such as customs information or tax identification numbers. + """ + localizedFields( + """ + The keys of the localized fields to retrieve. + """ + keys: [LocalizedFieldKey!]! = [] + ): [LocalizedField!]! + + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield + + """ + A purchase order number associated with the cart, often used for B2B transactions + to reference the buyer's internal purchase order. + """ + poNumber: String + + """ + The physical location where a retail order is created or completed. + """ + retailLocation: Location +} + +""" +A breakdown of the costs that the customer will pay at checkout. It includes the total amount, +the subtotal before taxes and duties, the tax amount, and duty charges. +""" +type CartCost { + """ + The amount, before taxes and cart-level discounts, for the customer to pay. + """ + subtotalAmount: MoneyV2! + + """ + The total amount for the customer to pay at checkout. + """ + totalAmount: MoneyV2! + + """ + The duty charges for a customer to pay at checkout. + """ + totalDutyAmount: MoneyV2 + + """ + The total tax amount for the customer to pay at checkout. + """ + totalTaxAmount: MoneyV2 +} + +""" +Information about items in a cart that are grouped by shared delivery characteristics. +Delivery groups streamline fulfillment by organizing items that can be shipped together, based on the customer's +shipping address. For example, if a customer orders a t-shirt and a pair of shoes that can be shipped +together, then the items are included in the same delivery group. +""" +type CartDeliveryGroup { + """ + Information about items in a cart that a customer intends to purchase. A cart line is an entry in the + customer's cart that represents a single unit of a product variant. For example, if a customer adds two + different sizes of the same t-shirt to their cart, then each size is represented as a separate cart line. + """ + cartLines: [CartLine!]! @scaleLimits(rate: 0.005) + + """ + The shipping or destination address associated with the delivery group. + """ + deliveryAddress: MailingAddress + + """ + The delivery options available for the delivery group. Delivery options are the different ways that customers + can choose to have their orders shipped. Examples include express shipping or standard shipping. + """ + deliveryOptions: [CartDeliveryOption!]! + + """ + The discounts that have been applied to the delivery group. + """ + discountAllocations: [DiscountAllocation!]! + + """ + The type of merchandise in the delivery group. + """ + groupType: CartDeliveryGroupType! + + """ + A [globally-unique ID](https://shopify.dev/docs/api/usage/gids) + for the delivery group. + """ + id: ID! + + """ + Information about the delivery option that the customer has selected. + """ + selectedDeliveryOption: CartDeliveryOption +} + +""" +Defines what type of merchandise is in the delivery group. +""" +enum CartDeliveryGroupType { + """ + The delivery group only contains merchandise that is either a one time purchase or a first delivery of + subscription merchandise. + """ + ONE_TIME_PURCHASE + + """ + The delivery group only contains subscription merchandise. + """ + SUBSCRIPTION +} + +""" +Information about a delivery option that's available for an item in a cart. Delivery options are the different +ways that customers can choose to have their orders shipped. Examples include express shipping or standard +shipping. +""" +type CartDeliveryOption { + """ + A unique identifier that represents the delivery option offered to customers. + For example, `Canada Post Expedited`. + """ + code: String + + """ + The amount that the customer pays if they select the delivery option. + """ + cost: MoneyV2! + + """ + The delivery method associated with the delivery option. A delivery method is a way that merchants can + fulfill orders from their online stores. Delivery methods include shipping to an address, + [local pickup](https://help.shopify.com/manual/fulfillment/setup/delivery-methods/pickup-in-store), + and shipping to a [pickup point](https://help.shopify.com/manual/fulfillment/shopify-shipping/pickup-points), + all of which are natively supported by Shopify checkout. + """ + deliveryMethodType: DeliveryMethod! + + """ + A single-line description of the delivery option, with HTML tags removed. + """ + description: String + + """ + A unique, human-readable identifier of the delivery option's title. + A handle can contain letters, hyphens (`-`), and numbers, but not spaces. + For example, `standard-shipping`. + """ + handle: Handle! + + """ + The name of the delivery option that displays to customers. The title is used to construct the delivery + option's handle. For example, if a delivery option is titled "Standard Shipping", then the handle is + `standard-shipping`. + """ + title: String +} + +""" +The fetch target result. Refer to network access for Shopify Functions. +""" +input FunctionFetchResult { + """ + HTTP request to dispatch on behalf of the function. + """ + request: HttpRequest +} + +""" +The output of the Function `run` target. Contains the operations to +apply, plus a `References` block with deduplicated lookup tables for +providers and service points. +""" +input FunctionRunResult { + """ + The ordered list of operations to apply. + """ + operations: [Operation!]! + + """ + Deduplicated lookup tables for providers and service points. + """ + references: References +} + +""" +Information about an item in a cart that a customer intends to purchase. A cart line is an entry in the +customer's cart that represents a single unit of a product variant. For example, if a customer adds two +different sizes of the same t-shirt to their cart, then each size is represented as a separate cart line. +""" +type CartLine { + """ + The custom attributes associated with a cart to store additional information. Cart attributes + allow you to collect specific information from customers on the **Cart** page, such as order notes, + gift wrapping requests, or custom product details. Attributes are stored as key-value pairs. + + Cart line attributes are equivalent to the + [`line_item`](https://shopify.dev/docs/api/liquid/objects/line_item) + object in Liquid. + """ + attribute( + """ + The key of the cart attribute to retrieve. For example, `"gift_wrapping"`. + """ + key: String + ): Attribute + + """ + The cost of an item in a cart that the customer intends to purchase. Cart lines are entries in the customer's + cart that represent a single unit of a product variant. For example, if a customer adds two different sizes of + the same t-shirt to their cart, then each size is represented as a separate cart line. + """ + cost: CartLineCost! + + """ + The discounts that have been applied to the cart line. + """ + discountAllocations: [DiscountAllocation!]! + + """ + The ID of the cart line. + """ + id: ID! + + """ + The item that the customer intends to purchase. + """ + merchandise: Merchandise! + + """ + The [nested relationship](https://shopify.dev/docs/apps/build/product-merchandising/nested-cart-lines) + between this line and its parent line, if any. + """ + parentRelationship: CartLineParentRelationship + + """ + The quantity of the item that the customer intends to purchase. + """ + quantity: Int! + + """ + The [selling plan](https://shopify.dev/docs/apps/build/purchase-options/subscriptions/selling-plans) + associated with the cart line, including information about how a product variant can be sold and purchased. + """ + sellingPlanAllocation: SellingPlanAllocation +} + +""" +The cost of an item in a cart that the customer intends to purchase. Cart lines are entries in the customer's +cart that represent a single unit of a product variant. For example, if a customer adds two different sizes of +the same t-shirt to their cart, then each size is represented as a separate cart line. +""" +type CartLineCost { + """ + The cost of a single unit. For example, if a customer purchases three units of a product + that are priced at $10 each, then the `amountPerQuantity` is $10. + """ + amountPerQuantity: MoneyV2! + + """ + The `compareAt` price of a single unit before any discounts are applied. This field is used to calculate and display + savings for customers. For example, if a product's `compareAtAmountPerQuantity` is $25 and its current price + is $20, then the customer sees a $5 discount. This value can change based on the buyer's identity and is + `null` when the value is hidden from buyers. + """ + compareAtAmountPerQuantity: MoneyV2 + + """ + The cost of items in the cart before applying any discounts to certain items. + This amount serves as the starting point for calculating any potential savings customers + might receive through promotions or discounts. + """ + subtotalAmount: MoneyV2! + + """ + The total cost of items in a cart. + """ + totalAmount: MoneyV2! +} + +""" +Represents the relationship between a cart line and its parent line. +""" +type CartLineParentRelationship { + """ + The parent line in the relationship. + """ + parent: CartLine! +} + +""" +Whether the product is in the specified collection. + +A collection is a group of products that can be displayed in online stores and other sales channels in +categories, which makes it easy for customers to find them. For example, an athletics store might create +different collections for running attire and accessories. +""" +type CollectionMembership { + """ + A [globally-unique ID](https://shopify.dev/docs/api/usage/gids) + for the collection. + """ + collectionId: ID! + + """ + Whether the product is in the specified collection. + """ + isMember: Boolean! +} + +""" +Represents information about a company which is also a customer of the shop. +""" +type Company implements HasMetafields { + """ + The date and time ([ISO 8601 format](http://en.wikipedia.org/wiki/ISO_8601)) at which the company was created in Shopify. + """ + createdAt: DateTime! + + """ + A unique externally-supplied ID for the company. + """ + externalId: String + + """ + The ID of the company. + """ + id: ID! + + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield + + """ + The name of the company. + """ + name: String! + + """ + The date and time ([ISO 8601 format](http://en.wikipedia.org/wiki/ISO_8601)) at which the company was last modified. + """ + updatedAt: DateTime! +} + +""" +A company's main point of contact. +""" +type CompanyContact { + """ + The date and time ([ISO 8601 format](http://en.wikipedia.org/wiki/ISO_8601)) + at which the company contact was created in Shopify. + """ + createdAt: DateTime! + + """ + The ID of the company. + """ + id: ID! + + """ + The company contact's locale (language). + """ + locale: String + + """ + The company contact's job title. + """ + title: String + + """ + The date and time ([ISO 8601 format](http://en.wikipedia.org/wiki/ISO_8601)) + at which the company contact was last modified. + """ + updatedAt: DateTime! +} + +""" +A company's location. +""" +type CompanyLocation implements HasMetafields { + """ + The date and time ([ISO 8601 format](http://en.wikipedia.org/wiki/ISO_8601)) + at which the company location was created in Shopify. + """ + createdAt: DateTime! + + """ + A unique externally-supplied ID for the company. + """ + externalId: String + + """ + The ID of the company. + """ + id: ID! + + """ + The preferred locale of the company location. + """ + locale: String + + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield + + """ + The name of the company location. + """ + name: String! + + """ + The number of orders placed at this company location. + """ + ordersCount: Int! + + """ + The total amount spent at this company location. + """ + totalSpent: MoneyV2! + + """ + The date and time ([ISO 8601 format](http://en.wikipedia.org/wiki/ISO_8601)) + at which the company location was last modified. + """ + updatedAt: DateTime! +} + +""" +The country for which the store is customized, reflecting local preferences and regulations. +Localization might influence the language, currency, and product offerings available in a store to enhance +the shopping experience for customers in that region. +""" +type Country { + """ + The ISO code of the country. + """ + isoCode: CountryCode! +} + +""" +The code designating a country/region, which generally follows ISO 3166-1 alpha-2 guidelines. +If a territory doesn't have a country code value in the `CountryCode` enum, then it might be considered a subdivision +of another country. For example, the territories associated with Spain are represented by the country code `ES`, +and the territories associated with the United States of America are represented by the country code `US`. +""" +enum CountryCode { + """ + Ascension Island. + """ + AC + + """ + Andorra. + """ + AD + + """ + United Arab Emirates. + """ + AE + + """ + Afghanistan. + """ + AF + + """ + Antigua & Barbuda. + """ + AG + + """ + Anguilla. + """ + AI + + """ + Albania. + """ + AL + + """ + Armenia. + """ + AM + + """ + Netherlands Antilles. + """ + AN + + """ + Angola. + """ + AO + + """ + Argentina. + """ + AR + + """ + Austria. + """ + AT + + """ + Australia. + """ + AU + + """ + Aruba. + """ + AW + + """ + Åland Islands. + """ + AX + + """ + Azerbaijan. + """ + AZ + + """ + Bosnia & Herzegovina. + """ + BA + + """ + Barbados. + """ + BB + + """ + Bangladesh. + """ + BD + + """ + Belgium. + """ + BE + + """ + Burkina Faso. + """ + BF + + """ + Bulgaria. + """ + BG + + """ + Bahrain. + """ + BH + + """ + Burundi. + """ + BI + + """ + Benin. + """ + BJ + + """ + St. Barthélemy. + """ + BL + + """ + Bermuda. + """ + BM + + """ + Brunei. + """ + BN + + """ + Bolivia. + """ + BO + + """ + Caribbean Netherlands. + """ + BQ + + """ + Brazil. + """ + BR + + """ + Bahamas. + """ + BS + + """ + Bhutan. + """ + BT + + """ + Bouvet Island. + """ + BV + + """ + Botswana. + """ + BW + + """ + Belarus. + """ + BY + + """ + Belize. + """ + BZ + + """ + Canada. + """ + CA + + """ + Cocos (Keeling) Islands. + """ + CC + + """ + Congo - Kinshasa. + """ + CD + + """ + Central African Republic. + """ + CF + + """ + Congo - Brazzaville. + """ + CG + + """ + Switzerland. + """ + CH + + """ + Côte d’Ivoire. + """ + CI + + """ + Cook Islands. + """ + CK + + """ + Chile. + """ + CL + + """ + Cameroon. + """ + CM + + """ + China. + """ + CN + + """ + Colombia. + """ + CO + + """ + Costa Rica. + """ + CR + + """ + Cuba. + """ + CU + + """ + Cape Verde. + """ + CV + + """ + Curaçao. + """ + CW + + """ + Christmas Island. + """ + CX + + """ + Cyprus. + """ + CY + + """ + Czechia. + """ + CZ + + """ + Germany. + """ + DE + + """ + Djibouti. + """ + DJ + + """ + Denmark. + """ + DK + + """ + Dominica. + """ + DM + + """ + Dominican Republic. + """ + DO + + """ + Algeria. + """ + DZ + + """ + Ecuador. + """ + EC + + """ + Estonia. + """ + EE + + """ + Egypt. + """ + EG + + """ + Western Sahara. + """ + EH + + """ + Eritrea. + """ + ER + + """ + Spain. + """ + ES + + """ + Ethiopia. + """ + ET + + """ + Finland. + """ + FI + + """ + Fiji. + """ + FJ + + """ + Falkland Islands. + """ + FK + + """ + Faroe Islands. + """ + FO + + """ + France. + """ + FR + + """ + Gabon. + """ + GA + + """ + United Kingdom. + """ + GB + + """ + Grenada. + """ + GD + + """ + Georgia. + """ + GE + + """ + French Guiana. + """ + GF + + """ + Guernsey. + """ + GG + + """ + Ghana. + """ + GH + + """ + Gibraltar. + """ + GI + + """ + Greenland. + """ + GL + + """ + Gambia. + """ + GM + + """ + Guinea. + """ + GN + + """ + Guadeloupe. + """ + GP + + """ + Equatorial Guinea. + """ + GQ + + """ + Greece. + """ + GR + + """ + South Georgia & South Sandwich Islands. + """ + GS + + """ + Guatemala. + """ + GT + + """ + Guinea-Bissau. + """ + GW + + """ + Guyana. + """ + GY + + """ + Hong Kong SAR. + """ + HK + + """ + Heard & McDonald Islands. + """ + HM + + """ + Honduras. + """ + HN + + """ + Croatia. + """ + HR + + """ + Haiti. + """ + HT + + """ + Hungary. + """ + HU + + """ + Indonesia. + """ + ID + + """ + Ireland. + """ + IE + + """ + Israel. + """ + IL + + """ + Isle of Man. + """ + IM + + """ + India. + """ + IN + + """ + British Indian Ocean Territory. + """ + IO + + """ + Iraq. + """ + IQ + + """ + Iran. + """ + IR + + """ + Iceland. + """ + IS + + """ + Italy. + """ + IT + + """ + Jersey. + """ + JE + + """ + Jamaica. + """ + JM + + """ + Jordan. + """ + JO + + """ + Japan. + """ + JP + + """ + Kenya. + """ + KE + + """ + Kyrgyzstan. + """ + KG + + """ + Cambodia. + """ + KH + + """ + Kiribati. + """ + KI + + """ + Comoros. + """ + KM + + """ + St. Kitts & Nevis. + """ + KN + + """ + North Korea. + """ + KP + + """ + South Korea. + """ + KR + + """ + Kuwait. + """ + KW + + """ + Cayman Islands. + """ + KY + + """ + Kazakhstan. + """ + KZ + + """ + Laos. + """ + LA + + """ + Lebanon. + """ + LB + + """ + St. Lucia. + """ + LC + + """ + Liechtenstein. + """ + LI + + """ + Sri Lanka. + """ + LK + + """ + Liberia. + """ + LR + + """ + Lesotho. + """ + LS + + """ + Lithuania. + """ + LT + + """ + Luxembourg. + """ + LU + + """ + Latvia. + """ + LV + + """ + Libya. + """ + LY + + """ + Morocco. + """ + MA + + """ + Monaco. + """ + MC + + """ + Moldova. + """ + MD + + """ + Montenegro. + """ + ME + + """ + St. Martin. + """ + MF + + """ + Madagascar. + """ + MG + + """ + North Macedonia. + """ + MK + + """ + Mali. + """ + ML + + """ + Myanmar (Burma). + """ + MM + + """ + Mongolia. + """ + MN + + """ + Macao SAR. + """ + MO + + """ + Martinique. + """ + MQ + + """ + Mauritania. + """ + MR + + """ + Montserrat. + """ + MS + + """ + Malta. + """ + MT + + """ + Mauritius. + """ + MU + + """ + Maldives. + """ + MV + + """ + Malawi. + """ + MW + + """ + Mexico. + """ + MX + + """ + Malaysia. + """ + MY + + """ + Mozambique. + """ + MZ + + """ + Namibia. + """ + NA + + """ + New Caledonia. + """ + NC + + """ + Niger. + """ + NE + + """ + Norfolk Island. + """ + NF + + """ + Nigeria. + """ + NG + + """ + Nicaragua. + """ + NI + + """ + Netherlands. + """ + NL + + """ + Norway. + """ + NO + + """ + Nepal. + """ + NP + + """ + Nauru. + """ + NR + + """ + Niue. + """ + NU + + """ + New Zealand. + """ + NZ + + """ + Oman. + """ + OM + + """ + Panama. + """ + PA + + """ + Peru. + """ + PE + + """ + French Polynesia. + """ + PF + + """ + Papua New Guinea. + """ + PG + + """ + Philippines. + """ + PH + + """ + Pakistan. + """ + PK + + """ + Poland. + """ + PL + + """ + St. Pierre & Miquelon. + """ + PM + + """ + Pitcairn Islands. + """ + PN + + """ + Palestinian Territories. + """ + PS + + """ + Portugal. + """ + PT + + """ + Paraguay. + """ + PY + + """ + Qatar. + """ + QA + + """ + Réunion. + """ + RE + + """ + Romania. + """ + RO + + """ + Serbia. + """ + RS + + """ + Russia. + """ + RU + + """ + Rwanda. + """ + RW + + """ + Saudi Arabia. + """ + SA + + """ + Solomon Islands. + """ + SB + + """ + Seychelles. + """ + SC + + """ + Sudan. + """ + SD + + """ + Sweden. + """ + SE + + """ + Singapore. + """ + SG + + """ + St. Helena. + """ + SH + + """ + Slovenia. + """ + SI + + """ + Svalbard & Jan Mayen. + """ + SJ + + """ + Slovakia. + """ + SK + + """ + Sierra Leone. + """ + SL + + """ + San Marino. + """ + SM + + """ + Senegal. + """ + SN + + """ + Somalia. + """ + SO + + """ + Suriname. + """ + SR + + """ + South Sudan. + """ + SS + + """ + São Tomé & Príncipe. + """ + ST + + """ + El Salvador. + """ + SV + + """ + Sint Maarten. + """ + SX + + """ + Syria. + """ + SY + + """ + Eswatini. + """ + SZ + + """ + Tristan da Cunha. + """ + TA + + """ + Turks & Caicos Islands. + """ + TC + + """ + Chad. + """ + TD + + """ + French Southern Territories. + """ + TF + + """ + Togo. + """ + TG + + """ + Thailand. + """ + TH + + """ + Tajikistan. + """ + TJ + + """ + Tokelau. + """ + TK + + """ + Timor-Leste. + """ + TL + + """ + Turkmenistan. + """ + TM + + """ + Tunisia. + """ + TN + + """ + Tonga. + """ + TO + + """ + Türkiye. + """ + TR + + """ + Trinidad & Tobago. + """ + TT + + """ + Tuvalu. + """ + TV + + """ + Taiwan. + """ + TW + + """ + Tanzania. + """ + TZ + + """ + Ukraine. + """ + UA + + """ + Uganda. + """ + UG + + """ + U.S. Outlying Islands. + """ + UM + + """ + Unknown country code. + """ + UNKNOWN__ + + """ + United States. + """ + US + + """ + Uruguay. + """ + UY + + """ + Uzbekistan. + """ + UZ + + """ + Vatican City. + """ + VA + + """ + St. Vincent & Grenadines. + """ + VC + + """ + Venezuela. + """ + VE + + """ + British Virgin Islands. + """ + VG + + """ + Vietnam. + """ + VN + + """ + Vanuatu. + """ + VU + + """ + Wallis & Futuna. + """ + WF + + """ + Samoa. + """ + WS + + """ + Kosovo. + """ + XK + + """ + Yemen. + """ + YE + + """ + Mayotte. + """ + YT + + """ + South Africa. + """ + ZA + + """ + Zambia. + """ + ZM + + """ + Zimbabwe. + """ + ZW + + """ + Unknown Region. + """ + ZZ +} + +""" +The currency codes that represent the world currencies throughout the Admin API. Currency codes include +[standard ISO 4217 codes](https://en.wikipedia.org/wiki/ISO_4217), legacy codes, non-standard codes, +digital currency codes. +""" +enum CurrencyCode { + """ + United Arab Emirates Dirham (AED). + """ + AED + + """ + Afghan Afghani (AFN). + """ + AFN + + """ + Albanian Lek (ALL). + """ + ALL + + """ + Armenian Dram (AMD). + """ + AMD + + """ + Netherlands Antillean Guilder. + """ + ANG + + """ + Angolan Kwanza (AOA). + """ + AOA + + """ + Argentine Pesos (ARS). + """ + ARS + + """ + Australian Dollars (AUD). + """ + AUD + + """ + Aruban Florin (AWG). + """ + AWG + + """ + Azerbaijani Manat (AZN). + """ + AZN + + """ + Bosnia and Herzegovina Convertible Mark (BAM). + """ + BAM + + """ + Barbadian Dollar (BBD). + """ + BBD + + """ + Bangladesh Taka (BDT). + """ + BDT + + """ + Bulgarian Lev (BGN). + """ + BGN + + """ + Bahraini Dinar (BHD). + """ + BHD + + """ + Burundian Franc (BIF). + """ + BIF + + """ + Bermudian Dollar (BMD). + """ + BMD + + """ + Brunei Dollar (BND). + """ + BND + + """ + Bolivian Boliviano (BOB). + """ + BOB + + """ + Brazilian Real (BRL). + """ + BRL + + """ + Bahamian Dollar (BSD). + """ + BSD + + """ + Bhutanese Ngultrum (BTN). + """ + BTN + + """ + Botswana Pula (BWP). + """ + BWP + + """ + Belarusian Ruble (BYN). + """ + BYN + + """ + Belarusian Ruble (BYR). + """ + BYR @deprecated(reason: "Use `BYN` instead.") + + """ + Belize Dollar (BZD). + """ + BZD + + """ + Canadian Dollars (CAD). + """ + CAD + + """ + Congolese franc (CDF). + """ + CDF + + """ + Swiss Francs (CHF). + """ + CHF + + """ + Chilean Peso (CLP). + """ + CLP + + """ + Chinese Yuan Renminbi (CNY). + """ + CNY + + """ + Colombian Peso (COP). + """ + COP + + """ + Costa Rican Colones (CRC). + """ + CRC + + """ + Cape Verdean escudo (CVE). + """ + CVE + + """ + Czech Koruny (CZK). + """ + CZK + + """ + Djiboutian Franc (DJF). + """ + DJF + + """ + Danish Kroner (DKK). + """ + DKK + + """ + Dominican Peso (DOP). + """ + DOP + + """ + Algerian Dinar (DZD). + """ + DZD + + """ + Egyptian Pound (EGP). + """ + EGP + + """ + Eritrean Nakfa (ERN). + """ + ERN + + """ + Ethiopian Birr (ETB). + """ + ETB + + """ + Euro (EUR). + """ + EUR + + """ + Fijian Dollars (FJD). + """ + FJD + + """ + Falkland Islands Pounds (FKP). + """ + FKP + + """ + United Kingdom Pounds (GBP). + """ + GBP + + """ + Georgian Lari (GEL). + """ + GEL + + """ + Ghanaian Cedi (GHS). + """ + GHS + + """ + Gibraltar Pounds (GIP). + """ + GIP + + """ + Gambian Dalasi (GMD). + """ + GMD + + """ + Guinean Franc (GNF). + """ + GNF + + """ + Guatemalan Quetzal (GTQ). + """ + GTQ + + """ + Guyanese Dollar (GYD). + """ + GYD + + """ + Hong Kong Dollars (HKD). + """ + HKD + + """ + Honduran Lempira (HNL). + """ + HNL + + """ + Croatian Kuna (HRK). + """ + HRK + + """ + Haitian Gourde (HTG). + """ + HTG + + """ + Hungarian Forint (HUF). + """ + HUF + + """ + Indonesian Rupiah (IDR). + """ + IDR + + """ + Israeli New Shekel (NIS). + """ + ILS + + """ + Indian Rupees (INR). + """ + INR + + """ + Iraqi Dinar (IQD). + """ + IQD + + """ + Iranian Rial (IRR). + """ + IRR + + """ + Icelandic Kronur (ISK). + """ + ISK + + """ + Jersey Pound. + """ + JEP + + """ + Jamaican Dollars (JMD). + """ + JMD + + """ + Jordanian Dinar (JOD). + """ + JOD + + """ + Japanese Yen (JPY). + """ + JPY + + """ + Kenyan Shilling (KES). + """ + KES + + """ + Kyrgyzstani Som (KGS). + """ + KGS + + """ + Cambodian Riel. + """ + KHR + + """ + Kiribati Dollar (KID). + """ + KID + + """ + Comorian Franc (KMF). + """ + KMF + + """ + South Korean Won (KRW). + """ + KRW + + """ + Kuwaiti Dinar (KWD). + """ + KWD + + """ + Cayman Dollars (KYD). + """ + KYD + + """ + Kazakhstani Tenge (KZT). + """ + KZT + + """ + Laotian Kip (LAK). + """ + LAK + + """ + Lebanese Pounds (LBP). + """ + LBP + + """ + Sri Lankan Rupees (LKR). + """ + LKR + + """ + Liberian Dollar (LRD). + """ + LRD + + """ + Lesotho Loti (LSL). + """ + LSL + + """ + Lithuanian Litai (LTL). + """ + LTL + + """ + Latvian Lati (LVL). + """ + LVL + + """ + Libyan Dinar (LYD). + """ + LYD + + """ + Moroccan Dirham. + """ + MAD + + """ + Moldovan Leu (MDL). + """ + MDL + + """ + Malagasy Ariary (MGA). + """ + MGA + + """ + Macedonia Denar (MKD). + """ + MKD + + """ + Burmese Kyat (MMK). + """ + MMK + + """ + Mongolian Tugrik. + """ + MNT + + """ + Macanese Pataca (MOP). + """ + MOP + + """ + Mauritanian Ouguiya (MRU). + """ + MRU + + """ + Mauritian Rupee (MUR). + """ + MUR + + """ + Maldivian Rufiyaa (MVR). + """ + MVR + + """ + Malawian Kwacha (MWK). + """ + MWK + + """ + Mexican Pesos (MXN). + """ + MXN + + """ + Malaysian Ringgits (MYR). + """ + MYR + + """ + Mozambican Metical. + """ + MZN + + """ + Namibian Dollar. + """ + NAD + + """ + Nigerian Naira (NGN). + """ + NGN + + """ + Nicaraguan Córdoba (NIO). + """ + NIO + + """ + Norwegian Kroner (NOK). + """ + NOK + + """ + Nepalese Rupee (NPR). + """ + NPR + + """ + New Zealand Dollars (NZD). + """ + NZD + + """ + Omani Rial (OMR). + """ + OMR + + """ + Panamian Balboa (PAB). + """ + PAB + + """ + Peruvian Nuevo Sol (PEN). + """ + PEN + + """ + Papua New Guinean Kina (PGK). + """ + PGK + + """ + Philippine Peso (PHP). + """ + PHP + + """ + Pakistani Rupee (PKR). + """ + PKR + + """ + Polish Zlotych (PLN). + """ + PLN + + """ + Paraguayan Guarani (PYG). + """ + PYG + + """ + Qatari Rial (QAR). + """ + QAR + + """ + Romanian Lei (RON). + """ + RON + + """ + Serbian dinar (RSD). + """ + RSD + + """ + Russian Rubles (RUB). + """ + RUB + + """ + Rwandan Franc (RWF). + """ + RWF + + """ + Saudi Riyal (SAR). + """ + SAR + + """ + Solomon Islands Dollar (SBD). + """ + SBD + + """ + Seychellois Rupee (SCR). + """ + SCR + + """ + Sudanese Pound (SDG). + """ + SDG + + """ + Swedish Kronor (SEK). + """ + SEK + + """ + Singapore Dollars (SGD). + """ + SGD + + """ + Saint Helena Pounds (SHP). + """ + SHP + + """ + Sierra Leonean Leone (SLL). + """ + SLL + + """ + Somali Shilling (SOS). + """ + SOS + + """ + Surinamese Dollar (SRD). + """ + SRD + + """ + South Sudanese Pound (SSP). + """ + SSP + + """ + Sao Tome And Principe Dobra (STD). + """ + STD @deprecated(reason: "Use `STN` instead.") + + """ + Sao Tome And Principe Dobra (STN). + """ + STN + + """ + Syrian Pound (SYP). + """ + SYP + + """ + Swazi Lilangeni (SZL). + """ + SZL + + """ + Thai baht (THB). + """ + THB + + """ + Tajikistani Somoni (TJS). + """ + TJS + + """ + Turkmenistani Manat (TMT). + """ + TMT + + """ + Tunisian Dinar (TND). + """ + TND + + """ + Tongan Pa'anga (TOP). + """ + TOP + + """ + Turkish Lira (TRY). + """ + TRY + + """ + Trinidad and Tobago Dollars (TTD). + """ + TTD + + """ + Taiwan Dollars (TWD). + """ + TWD + + """ + Tanzanian Shilling (TZS). + """ + TZS + + """ + Ukrainian Hryvnia (UAH). + """ + UAH + + """ + Ugandan Shilling (UGX). + """ + UGX + + """ + United States Dollars (USD). + """ + USD + + """ + United States Dollars Coin (USDC). + """ + USDC + + """ + Uruguayan Pesos (UYU). + """ + UYU + + """ + Uzbekistan som (UZS). + """ + UZS + + """ + Venezuelan Bolivares (VED). + """ + VED + + """ + Venezuelan Bolivares (VEF). + """ + VEF @deprecated(reason: "Use `VES` instead.") + + """ + Venezuelan Bolivares Soberanos (VES). + """ + VES + + """ + Vietnamese đồng (VND). + """ + VND + + """ + Vanuatu Vatu (VUV). + """ + VUV + + """ + Samoan Tala (WST). + """ + WST + + """ + Central African CFA Franc (XAF). + """ + XAF + + """ + East Caribbean Dollar (XCD). + """ + XCD + + """ + West African CFA franc (XOF). + """ + XOF + + """ + CFP Franc (XPF). + """ + XPF + + """ + Unrecognized currency. + """ + XXX + + """ + Yemeni Rial (YER). + """ + YER + + """ + South African Rand (ZAR). + """ + ZAR + + """ + Zambian Kwacha (ZMW). + """ + ZMW +} + +""" +A custom product represents a product that doesn't map to Shopify's +[standard product categories](https://help.shopify.com/manual/products/details/product-type). +For example, you can use a custom product to manage gift cards, shipping requirements, localized product +information, or weight measurements and conversions. +""" +type CustomProduct { + """ + Whether the merchandise is a gift card. + """ + isGiftCard: Boolean! + + """ + Whether the item needs to be shipped to the customer. For example, a + digital gift card doesn't need to be shipped, but a t-shirt does + need to be shipped. + """ + requiresShipping: Boolean! + + """ + The localized name for the product that displays to customers. The title is used to construct the product's + handle, which is a unique, human-readable string of the product's title. For example, if a product is titled + "Black Sunglasses", then the handle is `black-sunglasses`. + """ + title: String! + + """ + The product variant's weight, in the system of measurement set in the `weightUnit` field. + """ + weight: Float + + """ + The unit of measurement for weight. + """ + weightUnit: WeightUnit! +} + +""" +Represents a [customer](https://help.shopify.com/manual/customers/manage-customers). +`Customer` returns data including the customer's contact information and order history. +""" +type Customer implements HasMetafields { + """ + The total amount that the customer has spent on orders. + The amount is converted from the shop's currency to the currency of the cart using a market rate. + """ + amountSpent: MoneyV2! + + """ + The full name of the customer, based on the values for `firstName` and `lastName`. + If `firstName` and `lastName` aren't specified, then the value is the customer's email address. + If the email address isn't specified, then the value is the customer's phone number. + """ + displayName: String! + + """ + The customer's email address. + """ + email: String + + """ + The customer's first name. + """ + firstName: String + + """ + Whether the customer is associated with any of the specified tags. The customer must have at least one tag + from the list to return `true`. + """ + hasAnyTag( + """ + A comma-separated list of searchable keywords that are associated with the customer. For example, + `"VIP, Gold"` returns customers with either the `VIP` or `Gold` tag. + """ + tags: [String!]! = [] + ): Boolean! + + """ + Whether the customer is associated with the specified tags. + """ + hasTags( + """ + A comma-separated list of searchable keywords that are associated with the customer. For example, + `"VIP, Gold"` returns customers with both the `VIP` and `Gold` tags. + """ + tags: [String!]! = [] + ): [HasTagResponse!]! + + """ + A [globally-unique ID](https://shopify.dev/docs/api/usage/gids) + for the customer. + """ + id: ID! + + """ + The customer's last name. + """ + lastName: String + + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield + + """ + The total number of orders that the customer has made at the store. + """ + numberOfOrders: Int! +} + +""" +Represents an [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601)-encoded date string. +For example, September 7, 2019 is represented as `"2019-07-16"`. +""" +scalar Date + +""" +Represents an [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601)-encoded date and time string. +For example, 3:50 pm on September 7, 2019 in the time zone of UTC (Coordinated Universal Time) is +represented as `"2019-09-07T15:50:00Z`". +""" +scalar DateTime + +""" +A subset of the [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format that +includes the date and time but not the timezone which is determined from context. + +For example, "2018-01-01T00:00:00". +""" +scalar DateTimeWithoutTimezone + +""" +A signed decimal number, which supports arbitrary precision and is serialized as a string. + +Example values: `"29.99"`, `"29.999"`. +""" +scalar Decimal + +""" +Represents information about the merchandise in the cart. +""" +type DeliverableCartLine { + """ + The custom attributes associated with a cart to store additional information. Cart attributes + allow you to collect specific information from customers on the **Cart** page, such as order notes, + gift wrapping requests, or custom product details. Attributes are stored as key-value pairs. + + Cart line attributes are equivalent to the + [`line_item`](https://shopify.dev/docs/api/liquid/objects/line_item) + object in Liquid. + """ + attribute( + """ + The key of the cart attribute to retrieve. For example, `"gift_wrapping"`. + """ + key: String + ): Attribute + + """ + The ID of the cart line. + """ + id: ID! + + """ + The item that the customer intends to purchase. + """ + merchandise: Merchandise! + + """ + The quantity of the item that the customer intends to purchase. + """ + quantity: Int! +} + +""" +List of different delivery method types. +""" +enum DeliveryMethod { + """ + Local Delivery. + """ + LOCAL + + """ + None. + """ + NONE + + """ + Shipping to a Pickup Point. + """ + PICKUP_POINT + + """ + Local Pickup. + """ + PICK_UP + + """ + Retail. + """ + RETAIL + + """ + Shipping. + """ + SHIPPING +} + +""" +The discount application and the amount applied. +""" +type DiscountAllocation { + """ + The discount that was applied. + """ + discountApplication: DiscountApplication! + + """ + The amount that was discounted. + """ + discountedAmount: MoneyV2! +} + +""" +Discount that has been applied to the cart. +""" +type DiscountApplication implements HasMetafields { + """ + The method by which the discount's value is allocated to its entitled items. + """ + allocationMethod: DiscountApplicationAllocationMethod! + + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield + + """ + The lines on the cart targeted by the discount. + """ + targetSelection: DiscountApplicationTargetSelection! + + """ + The type of line (i.e. line item or shipping line) on a cart that the discount is applicable towards. + """ + targetType: DiscountApplicationTarget! + + """ + The total allocated amount of the discount across all items. + """ + totalAllocatedAmount: MoneyV2! + + """ + The value of the discount. + """ + value: PricingValue! +} + +""" +The method by which the discount's value is allocated onto its entitled lines. +""" +enum DiscountApplicationAllocationMethod { + """ + The value is spread across all entitled lines. + """ + ACROSS + + """ + The value is applied onto every entitled line. + """ + EACH +} + +""" +The type of line on an order that the discount is applicable towards. +""" +enum DiscountApplicationTarget { + """ + The discount applies onto line items. + """ + LINE_ITEM + + """ + The discount applies onto shipping lines. + """ + SHIPPING_LINE +} + +""" +The lines on the order to which the discount is applied, of the type defined by +the discount application's `targetType`. For example, the value `ENTITLED`, combined with a `targetType` of +`LINE_ITEM`, applies the discount on all line items that are entitled to the discount. +The value `ALL`, combined with a `targetType` of `SHIPPING_LINE`, applies the discount on all shipping lines. +""" +enum DiscountApplicationTargetSelection { + """ + The discount is allocated onto all the lines. + """ + ALL + + """ + The discount is allocated onto only the lines that it's entitled for. + """ + ENTITLED + + """ + The discount is allocated onto explicitly chosen lines. + """ + EXPLICIT +} + +""" +An ISO 8601 duration string. For example: "P2D", "PT8H", "PT0S". +""" +scalar Duration + +""" +A set of one or more packages traveling together from a single origin +address to a single destination address. The function generates one or +more `FulfillmentOption`s per fulfillment. +""" +type Fulfillment { + """ + Handle of the fulfillment's destination address reference in `address_references`. + """ + destinationAddressHandle: Handle! + + """ + Stable handle identifying the fulfillment within the function input. + """ + handle: Handle! + + """ + Handle of the fulfillment's origin address reference in `address_references`. + """ + originAddressHandle: Handle! + + """ + The packages that make up the fulfillment. + """ + packages: [Package!]! +} + +""" +A polymorphic address used as the origin or destination of a fulfillment. + +- `MailingAddress`: a specific buyer-facing mailing address. +- `Location`: a merchant location, such as a retail store or warehouse. +- `ServiceArea`: a region (e.g. a pickup-point service area). +""" +union FulfillmentAddress = Location | MailingAddress | ServiceArea + +""" +A deduplicated fulfillment address referenced by a `Handle`. Fulfillments +reference addresses through their handle so the same address never has to +be serialized into the function input twice. +""" +type FulfillmentAddressReference { + """ + The polymorphic fulfillment address. + """ + address: FulfillmentAddress! + + """ + Stable handle identifying this fulfillment address reference within the function input. + """ + handle: Handle! +} + +""" +The fulfillment option generator the function instance is bound to. +""" +type FulfillmentOptionGenerator implements HasMetafields { + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield +} + +""" +Add a single fulfillment option for a specific fulfillment. +""" +input FulfillmentOptionsAddOperation { + """ + The specific carrier service level or service point to uniquely identify each fulfillment option in the context + of a single input fulfillment. + """ + code: String + + """ + Cost of the fulfillment option. Null defaults to 0 or a configured fallback. + """ + cost: MoneyV2Output + + """ + Override the destination address by referencing a service point in + `References.service_points` by handle. Required when the fulfillment's destination + address is a service area. + """ + destinationServicePointHandle: Handle + + """ + Handle of the input fulfillment this fulfillment option applies to. + """ + fulfillmentHandle: Handle! + + """ + Instructions shown to the buyer about how to receive the fulfillment, localized. + """ + instructions: String + + """ + Metafields associated with the fulfillment option. + """ + metafields: [MetafieldOutput!] = [] + + """ + Reference to a provider in `References.providers` by handle. + """ + providerHandle: Handle + + """ + Estimated fulfillment time period. Null means a `start` and `end` of + `after` P0D (zero duration). + """ + timePeriod: TimePeriod + + """ + Human-facing display name, localized. Can be a carrier service level or service point name. + """ + title: String +} + +""" +Represents a fulfillment service that prepares and ships orders on behalf of the store owner. +""" +type FulfillmentService { + """ + The app associated with this fulfillment service. + """ + app: App +} + +""" +A function-scoped handle to a refer a resource. +The Handle type appears in a JSON response as a String, but it is not intended to be human-readable. +Example value: `"10079785100"` +""" +scalar Handle + +""" +Represents information about the metafields associated to the specified resource. +""" +interface HasMetafields { + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield +} + +""" +Whether a Shopify resource, such as a product or customer, has a specified tag. +""" +type HasTagResponse { + """ + Whether the Shopify resource has the tag. + """ + hasTag: Boolean! + + """ + A searchable keyword that's associated with a Shopify resource, such as a product or customer. For example, + a merchant might apply the `sports` and `summer` tags to products that are associated with sportswear for + summer. + """ + tag: String! +} + +""" +The attributes associated with an HTTP request. +""" +input HttpRequest { + """ + The HTTP request body as a plain string. + Use this field when the body isn't in JSON format. + """ + body: String + + """ + The HTTP headers. + """ + headers: [HttpRequestHeader!]! + + """ + The HTTP request body as a JSON object. + Use this field when the body's in JSON format, to reduce function instruction consumption + and to ensure the body's formatted in logs. + Don't use this field together with the `body` field. If both are provided, then the `body` field + will take precedence. + If this field is specified and no `Content-Type` header is included, then the header will + automatically be set to `application/json`. + """ + jsonBody: JSON + + """ + The HTTP method. + """ + method: HttpRequestMethod! + + """ + Policy attached to the HTTP request. + """ + policy: HttpRequestPolicy! + + """ + The HTTP url (eg.: https://example.com). The scheme needs to be HTTPS. + """ + url: URL! +} + +""" +The attributes associated with an HTTP request header. +""" +input HttpRequestHeader { + """ + Header name. + """ + name: String! + + """ + Header value. + """ + value: String! +} + +""" +The HTTP request available methods. +""" +enum HttpRequestMethod { + """ + Http GET. + """ + GET + + """ + Http POST. + """ + POST +} + +""" +The attributes associated with an HTTP request policy. +""" +input HttpRequestPolicy { + """ + Read timeout in milliseconds. + """ + readTimeoutMs: Int! +} + +""" +The attributes associated with an HTTP response. +""" +type HttpResponse { + """ + The HTTP response body as a plain string. + Use this field when the body is not in JSON format. + """ + body: String + + """ + An HTTP header. + """ + header( + """ + A case-insensitive header name. + """ + name: String! + ): HttpResponseHeader + + """ + The HTTP headers. + """ + headers: [HttpResponseHeader!]! @deprecated(reason: "Use `header` instead.") + + """ + The HTTP response body parsed as JSON. + If the body is valid JSON, it will be parsed and returned as a JSON object. + If parsing fails, then raw body is returned as a string. + Use this field when you expect the response to be JSON, or when you're dealing + with mixed response types, meaning both JSON and non-JSON. + Using this field reduces function instruction consumption and ensures that the data is formatted in logs. + To prevent increasing the function target input size unnecessarily, avoid querying + both `body` and `jsonBody` simultaneously. + """ + jsonBody: JSON + + """ + The HTTP status code. + """ + status: Int! +} + +""" +The attributes associated with an HTTP response header. +""" +type HttpResponseHeader { + """ + Header name. + """ + name: String! + + """ + Header value. + """ + value: String! +} + +""" +Represents a unique identifier, often used to refetch an object. +The ID type appears in a JSON response as a String, but it is not intended to be human-readable. + +Example value: `"gid://shopify/Product/10079785100"` +""" +scalar ID + +type Input { + """ + Deduplicated list of fulfillment addresses referenced by fulfillments via + `Fulfillment.origin_address_handle` and + `Fulfillment.destination_address_handle`. Each reference's address can be + any variant of `FulfillmentAddress`. + """ + addressReferences: [FulfillmentAddressReference!]! + + """ + The cart where the Function is running. A cart contains the merchandise that a customer intends to purchase + and information about the customer, such as the customer's email address and phone number. + """ + cart: Cart! + + """ + The HTTP response produced by the function's `fetch` target. Available only on `run`. + """ + fetchResult: HttpResponse @restrictTarget(only: ["cart.fulfillment-options.generate.run"]) + + """ + The backend `DeliveryOptionGenerator` record this function instance is + bound to. Includes the metafields associated with the generator. + """ + fulfillmentOptionGenerator: FulfillmentOptionGenerator! + + """ + The fulfillments the function should produce fulfillment options for. Each + fulfillment has an origin, a destination, and a set of packages. + """ + fulfillments: [Fulfillment!]! @scaleLimits(rate: 0.05) + + """ + The regional and language settings that determine how the Function + handles currency, numbers, dates, and other locale-specific values + during discount calculations. These settings are based on the store's configured + [localization practices](https://shopify.dev/docs/apps/build/functions/localization-practices-shopify-functions). + """ + localization: Localization! + + """ + The exchange rate used to convert discounts between the shop's default + currency and the currency that displays to the customer during checkout. + For example, if a store operates in USD but a customer is viewing discounts in EUR, + then the presentment currency rate handles this conversion for accurate pricing. + """ + presentmentCurrencyRate: Decimal! + + """ + Information about the shop where the Function is running, including the shop's timezone + setting and associated [metafields](https://shopify.dev/docs/apps/build/custom-data). + """ + shop: Shop! +} + +""" +A [JSON](https://www.json.org/json-en.html) object. + +Example value: +`{ + "product": { + "id": "gid://shopify/Product/1346443542550", + "title": "White T-shirt", + "options": [{ + "name": "Size", + "values": ["M", "L"] + }] + } +}` +""" +scalar JSON + +""" +The language for which the store is customized, ensuring content is tailored to local customers. +This includes product descriptions and customer communications that resonate with the target audience. +""" +type Language { + """ + The ISO code. + """ + isoCode: LanguageCode! +} + +""" +Language codes supported by Shopify. +""" +enum LanguageCode { + """ + Afrikaans. + """ + AF + + """ + Akan. + """ + AK + + """ + Amharic. + """ + AM + + """ + Arabic. + """ + AR + + """ + Assamese. + """ + AS + + """ + Azerbaijani. + """ + AZ + + """ + Belarusian. + """ + BE + + """ + Bulgarian. + """ + BG + + """ + Bambara. + """ + BM + + """ + Bangla. + """ + BN + + """ + Tibetan. + """ + BO + + """ + Breton. + """ + BR + + """ + Bosnian. + """ + BS + + """ + Catalan. + """ + CA + + """ + Chechen. + """ + CE + + """ + Central Kurdish. + """ + CKB + + """ + Czech. + """ + CS + + """ + Church Slavic. + """ + CU + + """ + Welsh. + """ + CY + + """ + Danish. + """ + DA + + """ + German. + """ + DE + + """ + Dzongkha. + """ + DZ + + """ + Ewe. + """ + EE + + """ + Greek. + """ + EL + + """ + English. + """ + EN + + """ + Esperanto. + """ + EO + + """ + Spanish. + """ + ES + + """ + Estonian. + """ + ET + + """ + Basque. + """ + EU + + """ + Persian. + """ + FA + + """ + Fulah. + """ + FF + + """ + Finnish. + """ + FI + + """ + Filipino. + """ + FIL + + """ + Faroese. + """ + FO + + """ + French. + """ + FR + + """ + Western Frisian. + """ + FY + + """ + Irish. + """ + GA + + """ + Scottish Gaelic. + """ + GD + + """ + Galician. + """ + GL + + """ + Gujarati. + """ + GU + + """ + Manx. + """ + GV + + """ + Hausa. + """ + HA + + """ + Hebrew. + """ + HE + + """ + Hindi. + """ + HI + + """ + Croatian. + """ + HR + + """ + Hungarian. + """ + HU + + """ + Armenian. + """ + HY + + """ + Interlingua. + """ + IA + + """ + Indonesian. + """ + ID + + """ + Igbo. + """ + IG + + """ + Sichuan Yi. + """ + II + + """ + Icelandic. + """ + IS + + """ + Italian. + """ + IT + + """ + Japanese. + """ + JA + + """ + Javanese. + """ + JV + + """ + Georgian. + """ + KA + + """ + Kikuyu. + """ + KI + + """ + Kazakh. + """ + KK + + """ + Kalaallisut. + """ + KL + + """ + Khmer. + """ + KM + + """ + Kannada. + """ + KN + + """ + Korean. + """ + KO + + """ + Kashmiri. + """ + KS + + """ + Kurdish. + """ + KU + + """ + Cornish. + """ + KW + + """ + Kyrgyz. + """ + KY + + """ + Luxembourgish. + """ + LB + + """ + Ganda. + """ + LG + + """ + Lingala. + """ + LN + + """ + Lao. + """ + LO + + """ + Lithuanian. + """ + LT + + """ + Luba-Katanga. + """ + LU + + """ + Latvian. + """ + LV + + """ + Malagasy. + """ + MG + + """ + Māori. + """ + MI + + """ + Macedonian. + """ + MK + + """ + Malayalam. + """ + ML + + """ + Mongolian. + """ + MN + + """ + Marathi. + """ + MR + + """ + Malay. + """ + MS + + """ + Maltese. + """ + MT + + """ + Burmese. + """ + MY + + """ + Norwegian (Bokmål). + """ + NB + + """ + North Ndebele. + """ + ND + + """ + Nepali. + """ + NE + + """ + Dutch. + """ + NL + + """ + Norwegian Nynorsk. + """ + NN + + """ + Norwegian. + """ + NO + + """ + Oromo. + """ + OM + + """ + Odia. + """ + OR + + """ + Ossetic. + """ + OS + + """ + Punjabi. + """ + PA + + """ + Polish. + """ + PL + + """ + Pashto. + """ + PS + + """ + Portuguese. + """ + PT + + """ + Portuguese (Brazil). + """ + PT_BR + + """ + Portuguese (Portugal). + """ + PT_PT + + """ + Quechua. + """ + QU + + """ + Romansh. + """ + RM + + """ + Rundi. + """ + RN + + """ + Romanian. + """ + RO + + """ + Russian. + """ + RU + + """ + Kinyarwanda. + """ + RW + + """ + Sanskrit. + """ + SA + + """ + Sardinian. + """ + SC + + """ + Sindhi. + """ + SD + + """ + Northern Sami. + """ + SE + + """ + Sango. + """ + SG + + """ + Sinhala. + """ + SI + + """ + Slovak. + """ + SK + + """ + Slovenian. + """ + SL + + """ + Shona. + """ + SN + + """ + Somali. + """ + SO + + """ + Albanian. + """ + SQ + + """ + Serbian. + """ + SR + + """ + Sundanese. + """ + SU + + """ + Swedish. + """ + SV + + """ + Swahili. + """ + SW + + """ + Tamil. + """ + TA + + """ + Telugu. + """ + TE + + """ + Tajik. + """ + TG + + """ + Thai. + """ + TH + + """ + Tigrinya. + """ + TI + + """ + Turkmen. + """ + TK + + """ + Tongan. + """ + TO + + """ + Turkish. + """ + TR + + """ + Tatar. + """ + TT + + """ + Uyghur. + """ + UG + + """ + Ukrainian. + """ + UK + + """ + Urdu. + """ + UR + + """ + Uzbek. + """ + UZ + + """ + Vietnamese. + """ + VI + + """ + Volapük. + """ + VO + + """ + Wolof. + """ + WO + + """ + Xhosa. + """ + XH + + """ + Yiddish. + """ + YI + + """ + Yoruba. + """ + YO + + """ + Chinese. + """ + ZH + + """ + Chinese (Simplified). + """ + ZH_CN + + """ + Chinese (Traditional). + """ + ZH_TW + + """ + Zulu. + """ + ZU +} + +""" +A quantity of a single cart line included in a package. +""" +type LineQuantity { + """ + The cart line ID. + """ + lineId: ID! + + """ + The number of units of the line included in the package. Will be a positive number. + """ + quantity: Int! +} + +""" +Local pickup settings associated with a location. +""" +type LocalPickup { + """ + Whether local pickup is enabled for the location. + """ + enabled: Boolean! +} + +""" +The current time based on the +[store's timezone setting](https://help.shopify.com/manual/intro-to-shopify/initial-setup/setup-business-settings). +""" +type LocalTime { + """ + The current date relative to the parent object. + """ + date: Date! + + """ + Returns true if the current date and time is at or past the given date and time, and false otherwise. + """ + dateTimeAfter( + """ + The date and time to compare against, assumed to be in the timezone of the parent object. + """ + dateTime: DateTimeWithoutTimezone! + ): Boolean! + + """ + Returns true if the current date and time is before the given date and time, and false otherwise. + """ + dateTimeBefore( + """ + The date and time to compare against, assumed to be in the timezone of the parent timezone. + """ + dateTime: DateTimeWithoutTimezone! + ): Boolean! + + """ + Returns true if the current date and time is between the two given date and times, and false otherwise. + """ + dateTimeBetween( + """ + The upper bound time to compare against, assumed to be in the timezone of the parent timezone. + """ + endDateTime: DateTimeWithoutTimezone! + + """ + The lower bound time to compare against, assumed to be in the timezone of the parent timezone. + """ + startDateTime: DateTimeWithoutTimezone! + ): Boolean! + + """ + Returns true if the current time is at or past the given time, and false otherwise. + """ + timeAfter( + """ + The time to compare against, assumed to be in the timezone of the parent timezone. + """ + time: TimeWithoutTimezone! + ): Boolean! + + """ + Returns true if the current time is at or past the given time, and false otherwise. + """ + timeBefore( + """ + The time to compare against, assumed to be in the timezone of the parent timezone. + """ + time: TimeWithoutTimezone! + ): Boolean! + + """ + Returns true if the current time is between the two given times, and false otherwise. + """ + timeBetween( + """ + The upper bound time to compare against, assumed to be in the timezone of the parent timezone. + """ + endTime: TimeWithoutTimezone! + + """ + The lower bound time to compare against, assumed to be in the timezone of the parent timezone. + """ + startTime: TimeWithoutTimezone! + ): Boolean! +} + +""" +Details about the localized experience for the store in a specific region, including country and language +settings. The localized experience is determined by the store's settings and the customer's location. +Localization ensures that customers can access relevant content and options while browsing or purchasing +products in a store. +""" +type Localization { + """ + The country for which the store is customized, reflecting local preferences and regulations. + Localization might influence the language, currency, and product offerings available in a store to enhance + the shopping experience for customers in that region. + """ + country: Country! + + """ + The language for which the store is customized, ensuring content is tailored to local customers. + This includes product descriptions and customer communications that resonate with the target audience. + """ + language: Language! + + """ + The market of the active localized experience. + """ + market: Market! @deprecated(reason: "This `market` field will be removed in a future version of the API.") +} + +""" +Represents the value captured by a localized field. Localized fields are +additional fields required by certain countries on international orders. For +example, some countries require additional fields for customs information or tax +identification numbers. +""" +type LocalizedField { + """ + The key of the localized field. + """ + key: LocalizedFieldKey! + + """ + The title of the localized field. + """ + title: String! + + """ + The value of the localized field. + """ + value: String +} + +""" +Unique key identifying localized fields. +""" +enum LocalizedFieldKey { + """ + Localized field key 'shipping_credential_br' for country Brazil. + """ + SHIPPING_CREDENTIAL_BR + + """ + Localized field key 'shipping_credential_cl' for country Chile. + """ + SHIPPING_CREDENTIAL_CL + + """ + Localized field key 'shipping_credential_cn' for country China. + """ + SHIPPING_CREDENTIAL_CN + + """ + Localized field key 'shipping_credential_co' for country Colombia. + """ + SHIPPING_CREDENTIAL_CO + + """ + Localized field key 'shipping_credential_cr' for country Costa Rica. + """ + SHIPPING_CREDENTIAL_CR + + """ + Localized field key 'shipping_credential_ec' for country Ecuador. + """ + SHIPPING_CREDENTIAL_EC + + """ + Localized field key 'shipping_credential_es' for country Spain. + """ + SHIPPING_CREDENTIAL_ES + + """ + Localized field key 'shipping_credential_gt' for country Guatemala. + """ + SHIPPING_CREDENTIAL_GT + + """ + Localized field key 'shipping_credential_id' for country Indonesia. + """ + SHIPPING_CREDENTIAL_ID + + """ + Localized field key 'shipping_credential_kr' for country South Korea. + """ + SHIPPING_CREDENTIAL_KR + + """ + Localized field key 'shipping_credential_mx' for country Mexico. + """ + SHIPPING_CREDENTIAL_MX + + """ + Localized field key 'shipping_credential_my' for country Malaysia. + """ + SHIPPING_CREDENTIAL_MY + + """ + Localized field key 'shipping_credential_pe' for country Peru. + """ + SHIPPING_CREDENTIAL_PE + + """ + Localized field key 'shipping_credential_pt' for country Portugal. + """ + SHIPPING_CREDENTIAL_PT + + """ + Localized field key 'shipping_credential_py' for country Paraguay. + """ + SHIPPING_CREDENTIAL_PY + + """ + Localized field key 'shipping_credential_tr' for country Turkey. + """ + SHIPPING_CREDENTIAL_TR + + """ + Localized field key 'shipping_credential_tw' for country Taiwan. + """ + SHIPPING_CREDENTIAL_TW + + """ + Localized field key 'shipping_credential_type_co' for country Colombia. + """ + SHIPPING_CREDENTIAL_TYPE_CO + + """ + Localized field key 'tax_credential_br' for country Brazil. + """ + TAX_CREDENTIAL_BR + + """ + Localized field key 'tax_credential_cl' for country Chile. + """ + TAX_CREDENTIAL_CL + + """ + Localized field key 'tax_credential_co' for country Colombia. + """ + TAX_CREDENTIAL_CO + + """ + Localized field key 'tax_credential_cr' for country Costa Rica. + """ + TAX_CREDENTIAL_CR + + """ + Localized field key 'tax_credential_ec' for country Ecuador. + """ + TAX_CREDENTIAL_EC + + """ + Localized field key 'tax_credential_es' for country Spain. + """ + TAX_CREDENTIAL_ES + + """ + Localized field key 'tax_credential_gt' for country Guatemala. + """ + TAX_CREDENTIAL_GT + + """ + Localized field key 'tax_credential_id' for country Indonesia. + """ + TAX_CREDENTIAL_ID + + """ + Localized field key 'tax_credential_it' for country Italy. + """ + TAX_CREDENTIAL_IT + + """ + Localized field key 'tax_credential_mx' for country Mexico. + """ + TAX_CREDENTIAL_MX + + """ + Localized field key 'tax_credential_my' for country Malaysia. + """ + TAX_CREDENTIAL_MY + + """ + Localized field key 'tax_credential_pe' for country Peru. + """ + TAX_CREDENTIAL_PE + + """ + Localized field key 'tax_credential_pt' for country Portugal. + """ + TAX_CREDENTIAL_PT + + """ + Localized field key 'tax_credential_py' for country Paraguay. + """ + TAX_CREDENTIAL_PY + + """ + Localized field key 'tax_credential_tr' for country Turkey. + """ + TAX_CREDENTIAL_TR + + """ + Localized field key 'tax_credential_type_co' for country Colombia. + """ + TAX_CREDENTIAL_TYPE_CO + + """ + Localized field key 'tax_credential_type_mx' for country Mexico. + """ + TAX_CREDENTIAL_TYPE_MX + + """ + Localized field key 'tax_credential_use_mx' for country Mexico. + """ + TAX_CREDENTIAL_USE_MX + + """ + Localized field key 'tax_email_it' for country Italy. + """ + TAX_EMAIL_IT +} + +""" +Represents the location where the inventory resides. +""" +type Location implements HasMetafields { + """ + The address of this location. + """ + address: LocationAddress! + + """ + The fulfillment service, if any, that's associated with the location. + """ + fulfillmentService: FulfillmentService + + """ + The location handle. + """ + handle: Handle! + + """ + The location id. + """ + id: ID! + + """ + Local pickup settings associated with a location. + """ + localPickup: LocalPickup! + + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield + + """ + The name of the location. + """ + name: String! +} + +""" +Represents the address of a location. +""" +type LocationAddress { + """ + The first line of the address for the location. + """ + address1: String + + """ + The second line of the address for the location. + """ + address2: String + + """ + The city of the location. + """ + city: String + + """ + The country of the location. + """ + country: String + + """ + The country code of the location. + """ + countryCode: String + + """ + A formatted version of the address for the location. + """ + formatted: [String!]! + + """ + The approximate latitude coordinates of the location. + """ + latitude: Float + + """ + The approximate longitude coordinates of the location. + """ + longitude: Float + + """ + The phone number of the location. + """ + phone: String + + """ + The province of the location. + """ + province: String + + """ + The code for the province, state, or district of the address of the location. + """ + provinceCode: String + + """ + The ZIP code of the location. + """ + zip: String +} + +""" +Represents a mailing address. +""" +type MailingAddress { + """ + The first line of the address. Typically the street address or PO Box number. + """ + address1: String + + """ + The second line of the address. Typically the number of the apartment, suite, or unit. + """ + address2: String + + """ + The name of the city, district, village, or town. + """ + city: String + + """ + The name of the customer's company or organization. + """ + company: String + + """ + The two-letter code for the country of the address. For example, US. + """ + countryCode: CountryCode + + """ + The first name of the customer. + """ + firstName: String + + """ + The last name of the customer. + """ + lastName: String + + """ + The approximate latitude of the address. + """ + latitude: Float + + """ + The approximate longitude of the address. + """ + longitude: Float + + """ + The market of the address. + """ + market: Market @deprecated(reason: "This `market` field will be removed in a future version of the API.") + + """ + The full name of the customer, based on firstName and lastName. + """ + name: String + + """ + A unique phone number for the customer. Formatted using E.164 standard. For example, +16135551111. + """ + phone: String + + """ + The alphanumeric code for the region. For example, ON. + """ + provinceCode: String + + """ + The zip or postal code of the address. + """ + zip: String +} + +""" +A market is a group of one or more regions that you want to target for international sales. +By creating a market, you can configure a distinct, localized shopping experience for +customers from a specific area of the world. For example, you can +[change currency](https://shopify.dev/api/admin-graphql/current/mutations/marketCurrencySettingsUpdate), +[configure international pricing](https://shopify.dev/api/examples/product-price-lists), +or [add market-specific domains or subfolders](https://shopify.dev/api/admin-graphql/current/objects/MarketWebPresence). +""" +type Market implements HasMetafields { + """ + A human-readable unique string for the market automatically generated from its title. + """ + handle: Handle! + + """ + A globally-unique identifier. + """ + id: ID! + + """ + The manager of the market, if the accessing app is the market’s manager. Otherwise, this will be null. + """ + manager: MarketManager + + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield + + """ + A geographic region which comprises a market. + """ + regions: [MarketRegion!]! +} + +""" +The entity that manages a particular market. +""" +type MarketManager { + """ + The identity of the manager. This can either be `merchant` if the market is + manually managed by the merchant or an ID of the app responsible for managing the market. + """ + identifier: String! +} + +""" +Represents a region. +""" +interface MarketRegion { + """ + The name of the region in the language of the current localization. + """ + name: String +} + +""" +A country which comprises a market. +""" +type MarketRegionCountry implements MarketRegion { + """ + The two-letter code for the country. + """ + code: CountryCode! + + """ + The country name in the language of the current localization. + """ + name: String! +} + +""" +The item that a customer intends to purchase. Merchandise can be a product variant or a custom +product. + +A product variant is a specific version of a product that comes in more than one option, such as size or color. +For example, if a merchant sells t-shirts with options for size and color, then a small, blue t-shirt would be +one product variant and a large, blue t-shirt would be another. + +A custom product represents a product that doesn't map to Shopify's +[standard product categories](https://help.shopify.com/manual/products/details/product-type). +For example, you can use a custom product to manage gift cards, shipping requirements, localized product +information, or weight measurements and conversions. +""" +union Merchandise = CustomProduct | ProductVariant + +""" +[Custom fields](https://shopify.dev/docs/apps/build/custom-data) that store additional information +about a Shopify resource, such as products, orders, and +[many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). +Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) +enables you to customize the checkout experience. +""" +type Metafield { + """ + The data that's stored in the metafield, using JSON format. + """ + jsonValue: JSON! + + """ + The [type of data](https://shopify.dev/apps/metafields/types) that the metafield stores in + the `value` field. + """ + type: String! + + """ + The data that's stored in the metafield. The data is always stored as a string, + regardless of the [metafield's type](https://shopify.dev/apps/metafields/types). + """ + value: String! +} + +""" +[Custom fields](https://shopify.dev/docs/apps/build/custom-data) that store additional information +about a Shopify resource, such as products, orders, and +[many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). +Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) +enables you to customize the checkout experience. +""" +input MetafieldOutput { + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + + """ + The [type of data](https://shopify.dev/docs/apps/build/custom-data/metafields/list-of-data-types) + that's stored in the metafield. + """ + type: String! + + """ + The data to store in the metafield. + """ + value: String! +} + +""" +An instance of custom structured data defined by a MetaobjectDefinition. +""" +type Metaobject { + """ + The field for an object key, or null if the key has no field definition. + """ + field( + """ + The metaobject key to access. + """ + key: String! + ): MetaobjectField + + """ + The unique handle of the metaobject, useful as a custom ID. + """ + handle: String! + + """ + The type of the metaobject. + """ + type: String! +} + +""" +Provides a field definition and the data value assigned to it. +""" +type MetaobjectField { + """ + The assigned field value in JSON format. + """ + jsonValue: JSON + + """ + The object key of this field. + """ + key: String! + + """ + The type of the field. + """ + type: String! + + """ + The assigned field value, always stored as a string regardless of the field type. + """ + value: String +} + +""" +The input fields for retrieving a metaobject by handle. +""" +input MetaobjectHandleInput { + """ + The handle of the metaobject to retrieve. + """ + handle: String! + + """ + The type of the metaobject. Must match an existing metaobject definition type. + """ + type: String! +} + +""" +A precise monetary value and its associated currency. Combines a decimal amount +with a three-letter currency code to express prices, costs, and other financial +values throughout the API. For example, 12.99 USD. +""" +type MoneyV2 { + """ + A monetary value in decimal format, allowing for precise representation of cents or fractional + currency. For example, 12.99. + """ + amount: Decimal! + + """ + The three-letter currency code that represents a world currency used in a store. Currency codes + include standard [standard ISO 4217 codes](https://en.wikipedia.org/wiki/ISO_4217), legacy codes, + and non-standard codes. For example, USD. + """ + currencyCode: CurrencyCode! +} + +""" +A precise monetary value and its associated currency. Combines a decimal amount +with a three-letter currency code to express prices, costs, and other financial +values throughout the API. For example, 12.99 USD. +""" +input MoneyV2Output { + """ + A monetary value in decimal format, allowing for precise representation of cents or fractional + currency. For example, 12.99. + """ + amount: Decimal! + + """ + The three-letter currency code that represents a world currency used in a store. Currency codes + include standard [standard ISO 4217 codes](https://en.wikipedia.org/wiki/ISO_4217), legacy codes, + and non-standard codes. For example, USD. + """ + currencyCode: CurrencyCode! +} + +""" +The root mutation for the API. +""" +type MutationRoot { + """ + Handles the Function result for the cart.fulfillment-options.generate.fetch target. + """ + fetch( + """ + The result of the Function. + """ + result: FunctionFetchResult! + ): Void! + + """ + Handles the Function result for the cart.fulfillment-options.generate.run target. + """ + run( + """ + The result of the Function. + """ + result: FunctionRunResult! + ): Void! +} + +""" +An operation to apply when generating fulfillment options. +""" +input Operation { + """ + Add a fulfillment option. + """ + fulfillmentOptionsAdd: FulfillmentOptionsAddOperation! +} + +""" +A package within a fulfillment. Carries one or more cart-line quantities +and, when available, the package's physical attributes. +""" +type Package { + """ + The cart-line quantities included in the package. + """ + lineQuantities: [LineQuantity!]! +} + +""" +The percentage value of a discount. +""" +type PricingPercentageValue { + """ + The percentage value of the discount. + """ + value: Decimal! +} + +""" +The price value for a discount application. +""" +union PricingValue = MoneyV2 | PricingPercentageValue + +""" +The goods and services that merchants offer to customers. Products can include details such as +title, vendor, and custom data stored in [metafields](https://shopify.dev/docs/apps/build/custom-data). +Products can be organized by grouping them into a collection. + +Learn more about [managing products in a merchant's store](https://help.shopify.com/manual/products). +""" +type Product implements HasMetafields { + """ + A unique, human-readable string of the product's title. A handle can contain letters, hyphens (`-`), and + numbers, but not spaces. The handle is used in the online store URL for the product. For example, if a product + is titled "Black Sunglasses", then the handle is `black-sunglasses`. + """ + handle: Handle! + + """ + Whether the product is associated with any of the specified tags. The product must have at least one tag + from the list to return `true`. + """ + hasAnyTag( + """ + A comma-separated list of searchable keywords that are associated with the product. For example, + `"sports, summer"` returns products with either the `sports` or `summer` tag. + """ + tags: [String!]! = [] + ): Boolean! + + """ + Whether the product is associated with the specified tags. + """ + hasTags( + """ + A comma-separated list of searchable keywords that are associated with the product. For example, + `"sports, summer"` returns products with both the `sports` and `summer` tags. + """ + tags: [String!]! = [] + ): [HasTagResponse!]! + + """ + A [globally-unique ID](https://shopify.dev/docs/api/usage/gids) + for the product. + """ + id: ID! + + """ + Whether the product is in any of the specified collections. The product must be in at least one collection + from the list to return `true`. + + A collection is a group of products that can be displayed in online stores and other sales channels in + categories, which makes it easy for customers to find them. For example, an athletics store might create + different collections for running attire and accessories. + """ + inAnyCollection( + """ + A comma-separated list of [globally-unique collection IDs](https://shopify.dev/docs/api/usage/gids) + that are associated with the product. For example, `gid://shopify/Collection/123`, `gid://shopify/Collection/456`. + """ + ids: [ID!]! = [] + ): Boolean! + + """ + Whether the product is in the specified collections. The product must be in all of the collections in the + list to return `true`. + + A collection is a group of products that can be displayed in online stores and other sales channels in + categories, which makes it easy for customers to find them. For example, an athletics store might create + different collections for running attire and accessories. + """ + inCollections( + """ + A comma-separated list of [globally-unique collection IDs](https://shopify.dev/docs/api/usage/gids) + that are associated with the product. For example, `gid://shopify/Collection/123`, `gid://shopify/Collection/456`. + """ + ids: [ID!]! = [] + ): [CollectionMembership!]! + + """ + Whether the product is a gift card. + """ + isGiftCard: Boolean! + + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield + + """ + A custom category for a product. Product types allow merchants to define categories other than the + ones available in Shopify's + [standard product categories](https://help.shopify.com/manual/products/details/product-type). + """ + productType: String + + """ + The localized name for the product that displays to customers. The title is used to construct the product's + handle, which is a unique, human-readable string of the product's title. For example, if a product is titled + "Black Sunglasses", then the handle is `black-sunglasses`. + """ + title: String! + + """ + The name of the product's vendor. + """ + vendor: String +} + +""" +A specific version of a product that comes in more than one option, such as size or color. For example, +if a merchant sells t-shirts with options for size and color, then a small, blue t-shirt would be one +product variant and a large, blue t-shirt would be another. +""" +type ProductVariant implements HasMetafields { + """ + A [globally-unique ID](https://shopify.dev/docs/api/usage/gids) + for the product variant. + """ + id: ID! + + """ + Whether the product variant is in any of the specified collections. The variant must be in at least one + collection from the list to return `true`. A variant is considered to be in a collection when the variant + itself is a member of the collection, or when its product is a member of the collection. + + A collection is a group of products that can be displayed in online stores and other sales channels in + categories, which makes it easy for customers to find them. For example, an athletics store might create + different collections for running attire and accessories. + """ + inAnyCollection( + """ + A list of [globally-unique collection IDs](https://shopify.dev/docs/api/usage/gids) + to check membership against. For example, `gid://shopify/Collection/123`, `gid://shopify/Collection/456`. + """ + ids: [ID!]! = [] + ): Boolean! + + """ + Whether the product variant is in each of the specified collections. A variant is considered to be in a + collection when the variant itself is a member of the collection, or when its product is a member of the + collection. + + A collection is a group of products that can be displayed in online stores and other sales channels in + categories, which makes it easy for customers to find them. For example, an athletics store might create + different collections for running attire and accessories. + """ + inCollections( + """ + A list of [globally-unique collection IDs](https://shopify.dev/docs/api/usage/gids) + to check membership against. For example, `gid://shopify/Collection/123`, `gid://shopify/Collection/456`. + """ + ids: [ID!]! = [] + ): [CollectionMembership!]! + + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield + + """ + The product associated with the product variant. For example, if a + merchant sells t-shirts with options for size and color, then a small, + blue t-shirt would be one product variant and a large, blue t-shirt would be another. + The product associated with the product variant would be the t-shirt itself. + """ + product: Product! + + """ + Whether the item needs to be shipped to the customer. For example, a + digital gift card doesn't need to be shipped, but a t-shirt does + need to be shipped. + """ + requiresShipping: Boolean! + + """ + A case-sensitive identifier for the product variant in the merchant's store. For example, `"BBC-1"`. + A product variant must have a SKU to be connected to a + [fulfillment service](https://shopify.dev/docs/apps/build/orders-fulfillment/fulfillment-service-apps/build-for-fulfillment-services). + """ + sku: String + + """ + The localized name for the product variant that displays to customers. + """ + title: String + + """ + The product variant's weight, in the system of measurement set in the `weightUnit` field. + """ + weight: Float + + """ + The unit of measurement for weight. + """ + weightUnit: WeightUnit! +} + +""" +A fulfillment option provider. Providers are +declared once in `References.providers` and referenced from individual +fulfillment options by their handle, to keep the payload small. +""" +input Provider { + """ + The provider's external id from the third-party service. + """ + externalId: String! + + """ + Stable handle identifying the provider within this run result. + """ + handle: Handle! + + """ + URL to the provider's logo. Must use the `https` scheme, be served + from the Shopify CDN host, and be RFC 3986 compliant. + """ + logoUrl: URL! + + """ + The provider's display name. + """ + name: String! +} + +""" +The company of a B2B customer that's interacting with the cart. +Used to manage and track purchases made by businesses rather than individual customers. +""" +type PurchasingCompany { + """ + The company associated to the order or draft order. + """ + company: Company! + + """ + The company contact associated to the order or draft order. + """ + contact: CompanyContact + + """ + The company location associated to the order or draft order. + """ + location: CompanyLocation! +} + +""" +Deduplicated lookup tables for values that operations reference by +handle. Grouping references together keeps the payload compact when a +small number of providers or service points is shared across many +operations. +""" +input References { + """ + Deduplicated list of providers referenced by `fulfillment_options_add.provider_handle`. + """ + providers: [Provider!] = [] + + """ + Deduplicated list of service points referenced by `fulfillment_options_add.destination_service_point_handle`. + """ + servicePoints: [ServicePoint!] = [] +} + +""" +Represents how products and variants can be sold and purchased. +""" +type SellingPlan implements HasMetafields { + """ + The description of the selling plan. + """ + description: String + + """ + A globally-unique identifier. + """ + id: ID! + + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield + + """ + The name of the selling plan. For example, '6 weeks of prepaid granola, delivered weekly'. + """ + name: String! + + """ + Whether purchasing the selling plan will result in multiple deliveries. + """ + recurringDeliveries: Boolean! +} + +""" +Represents an association between a variant and a selling plan. Selling plan +allocations describe the options offered for each variant, and the price of the +variant when purchased with a selling plan. +""" +type SellingPlanAllocation { + """ + A list of price adjustments, with a maximum of two. When there are two, the + first price adjustment goes into effect at the time of purchase, while the + second one starts after a certain number of orders. A price adjustment + represents how a selling plan affects pricing when a variant is purchased with + a selling plan. Prices display in the customer's currency if the shop is + configured for it. + """ + priceAdjustments: [SellingPlanAllocationPriceAdjustment!]! + + """ + A representation of how products and variants can be sold and purchased. For + example, an individual selling plan could be '6 weeks of prepaid granola, + delivered weekly'. + """ + sellingPlan: SellingPlan! +} + +""" +The resulting prices for variants when they're purchased with a specific selling plan. +""" +type SellingPlanAllocationPriceAdjustment { + """ + The effective price for a single delivery. For example, for a prepaid + subscription plan that includes 6 deliveries at the price of $48.00, the per + delivery price is $8.00. + """ + perDeliveryPrice: MoneyV2! + + """ + The price of the variant when it's purchased with a selling plan For example, + for a prepaid subscription plan that includes 6 deliveries of $10.00 granola, + where the customer gets 20% off, the price is 6 x $10.00 x 0.80 = $48.00. + """ + price: MoneyV2! +} + +""" +A geographical region a fulfillment can be sent to (e.g. a pickup-point +service area) where the precise address may not be known up front. Expressed +as a radius around a center address. +""" +type ServiceArea { + """ + The center address of the service area, when known. + """ + address: MailingAddress + + """ + Radius around the center address, in meters. + """ + radius: Int +} + +""" +A third-party service point (such as a pickup-point locker or partner +location) returned by the function as a fulfillment address. Combines a +physical address with operational metadata. +""" +input ServicePoint { + """ + Address line 1. + """ + address1: String! + + """ + Address line 2. + """ + address2: String + + """ + Operating hours. A day with no entry is considered closed. + """ + businessHours: [BusinessHours!] + + """ + City. + """ + city: String! + + """ + Country code. + """ + countryCode: CountryCode! + + """ + The provider's external id for this service point. Required + and non-blank. + """ + externalId: String! + + """ + Stable handle identifying this service point within the run result. Referenced + by `FulfillmentOptionsAddOperation.destination_service_point_handle`. + """ + handle: Handle! + + """ + Latitude. + """ + latitude: Float! + + """ + Longitude. + """ + longitude: Float! + + """ + The name the third-party service has assigned to this service point. + Identifies the physical location itself. + """ + name: String! + + """ + Contact phone number for the service point. + """ + phone: String + + """ + Province or state code. + """ + provinceCode: String + + """ + Postal or ZIP code. + """ + zip: String +} + +""" +Information about the store, including the store's timezone setting +and custom data stored in [metafields](https://shopify.dev/docs/apps/build/custom-data). +""" +type Shop implements HasMetafields { + """ + The current time based on the + [store's timezone setting](https://help.shopify.com/manual/intro-to-shopify/initial-setup/setup-business-settings). + """ + localTime: LocalTime! + + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield + + """ + Fetch a specific Metaobject by one of its unique identifiers. Only app-owned + metaobjects with the $app reserved prefix are accessible to functions. + """ + metaobject( + """ + The handle and type of the metaobject. + """ + handle: MetaobjectHandleInput + + """ + The ID of the metaobject. + """ + id: ID + ): Metaobject +} + +""" +Represents information about the buyer that is interacting with the cart. +""" +type ShopUser implements HasMetafields { + """ + A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information + about a Shopify resource, such as products, orders, and + [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). + Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) + enables you to customize the checkout experience. + """ + metafield( + """ + The unique identifier for the metafield within its namespace. A metafield is composed of a + namespace and a key, in the format `namespace.key`. + """ + key: String! + + """ + A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts + between different apps or different parts of the same app. If omitted, then the + [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) + is used. + """ + namespace: String + ): Metafield +} + +""" +A period of time bounded by two `TimePoint`s. `end` must be greater than +or equal to `start`. Reads as, e.g., +`{ "start": { "at": "2026-06-09T12:10:23Z" }, "end": { "after": "P2D" } }`. +""" +input TimePeriod { + """ + Upper bound of the period. Must be >= `start`. + """ + end: TimePoint! + + """ + Lower bound of the period. + """ + start: TimePoint! +} + +""" +A single point in time, expressed as exactly one of: + +- `at`: an absolute `DateTime` (e.g. "2026-06-09T12:10:23Z"). +- `after`: a relative ISO 8601 `Duration` measured from the + fulfillment's ready time (e.g. "P2D"). +""" +input TimePoint @oneOf { + """ + A point in time relative to the fulfillment's ready time, as an ISO 8601 duration. + """ + after: Duration + + """ + An absolute point in time. + """ + at: DateTime +} + +""" +A subset of the [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format that +includes the time but not the date or timezone which is determined from context. +For example, "05:43:21". +""" +scalar TimeWithoutTimezone + +""" +Represents an [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986) and +[RFC 3987](https://datatracker.ietf.org/doc/html/rfc3987)-compliant URI string. + +For example, `"https://example.myshopify.com"` is a valid URL. It includes a scheme (`https`) and a host +(`example.myshopify.com`). +""" +scalar URL + +""" +A void type that can be used to return a null value from a mutation. +""" +scalar Void + +""" +A day of the week. +""" +enum Weekday { + """ + Friday. + """ + FRIDAY + + """ + Monday. + """ + MONDAY + + """ + Saturday. + """ + SATURDAY + + """ + Sunday. + """ + SUNDAY + + """ + Thursday. + """ + THURSDAY + + """ + Tuesday. + """ + TUESDAY + + """ + Wednesday. + """ + WEDNESDAY +} + +""" +Units of measurement for weight. +""" +enum WeightUnit { + """ + Metric system unit of mass. + """ + GRAMS + + """ + 1 kilogram equals 1000 grams. + """ + KILOGRAMS + + """ + Imperial system unit of mass. + """ + OUNCES + + """ + 1 pound equals 16 ounces. + """ + POUNDS +} diff --git a/functions-fulfillment-option-generators-wasm/shopify.extension.toml.liquid b/functions-fulfillment-option-generators-wasm/shopify.extension.toml.liquid new file mode 100644 index 00000000..3203c37f --- /dev/null +++ b/functions-fulfillment-option-generators-wasm/shopify.extension.toml.liquid @@ -0,0 +1,24 @@ +api_version = "unstable" + +[[extensions]] +name = "t:name" +handle = "{{handle}}" +type = "function" +{% if uid %}uid = "{{ uid }}"{% endif %} + + [[extensions.targeting]] + target = "cart.fulfillment-options.generate.fetch" + input_query = "src/fetch.graphql" + export = "fetch" + + [[extensions.targeting]] + target = "cart.fulfillment-options.generate.run" + input_query = "src/run.graphql" + export = "run" + + [extensions.build] + command = "echo 'build the wasm'" + + [extensions.ui.paths] + create = "/" + details = "/" diff --git a/templates.json b/templates.json index 932f48ed..13a06d4d 100644 --- a/templates.json +++ b/templates.json @@ -1705,6 +1705,42 @@ } ] }, + { + "identifier": "fulfillment_option_generator", + "name": "Fulfillment option generator", + "defaultName": "fulfillment-option-generators", + "group": "Functions", + "sortPriority": null, + "supportLinks": [], + "url": "https://github.com/Shopify/extensions-templates", + "type": "function", + "extensionPoints": [], + "supportedFlavors": [ + { + "name": "Rust", + "value": "rust", + "path": "functions-fulfillment-option-generators-rs" + }, + { + "name": "JavaScript", + "value": "vanilla-js", + "path": "functions-fulfillment-option-generators-js" + }, + { + "name": "TypeScript", + "value": "typescript", + "path": "functions-fulfillment-option-generators-js" + }, + { + "name": "Wasm", + "value": "wasm", + "path": "functions-fulfillment-option-generators-wasm" + } + ], + "organizationExpFlags": [ + "abd45e54" + ] + }, { "identifier": "payment_customization", "name": "Payment customization",