Shopify Product Variant

This page documents the Shopify Product Variant model.

Data Shape

Gadget's database stores Shopify Product Variant records by storing and retrieving each of the fields defined on the model in the Gadget Editor to a managed database. Gadget has generated a GraphQL type matching the configured fields for Shopify Product Variant:

Shopify Product Variant Schema
1export interface ShopifyProductVariant {
2 __typename: "ShopifyProductVariant";
3
4 /** The globally unique, unchanging identifier for this record. Assigned and managed by Shopify. */
5 id: Scalars["GadgetID"];
6
7 /** The time at which this record was first created. Set once upon record creation and never changed. Managed by Gadget. */
8 createdAt: Scalars["DateTime"];
9
10 /** The time at which this record was last changed. Set each time the record is successfully acted upon by an action. Managed by Gadget. */
11 updatedAt: Scalars["DateTime"];
12
13 /** The current state this record is in. Changed by invoking actions. Managed by Gadget. */
14 state: Scalars["RecordState"];
15
16 barcode: Scalars["String"] | null;
17
18 compareAtPrice: Scalars["String"] | null;
19
20 shopifyCreatedAt: Scalars["DateTime"] | null;
21
22 fulfillmentService: Scalars["String"] | null;
23
24 grams: Scalars["Float"] | null;
25
26 inventoryManagement: Scalars["String"] | null;
27
28 inventoryPolicy: Scalars["String"] | null;
29
30 inventoryQuantity: Scalars["Float"] | null;
31
32 inventoryQuantityAdjustment: Scalars["Float"] | null;
33
34 oldInventoryQuantity: Scalars["Float"] | null;
35
36 option1: Scalars["String"] | null;
37
38 option2: Scalars["String"] | null;
39
40 option3: Scalars["String"] | null;
41
42 position: Scalars["Float"] | null;
43
44 presentmentPrices: Scalars["JSON"] | null;
45
46 price: Scalars["String"] | null;
47
48 requiresShipping: Scalars["Boolean"] | null;
49
50 sku: Scalars["String"] | null;
51
52 taxCode: Scalars["String"] | null;
53
54 taxable: Scalars["Boolean"] | null;
55
56 title: Scalars["String"] | null;
57
58 shopifyUpdatedAt: Scalars["DateTime"] | null;
59
60 weight: Scalars["Float"] | null;
61
62 weightUnit: Scalars["String"] | null;
63
64 product: ShopifyProduct | null;
65
66 productId: Scalars["GadgetID"] | null;
67
68 shop: ShopifyShop | null;
69
70 shopId: Scalars["GadgetID"] | null;
71
72 /** Get all the fields for this record. Useful for not having to list out all the fields you want to retrieve, but slower. */
73 _all: Scalars["JSONObject"];
74}
1type ShopifyProductVariant {
2 """
3 The globally unique, unchanging identifier for this record. Assigned and managed by Shopify.
4 """
5 id: GadgetID!
6
7 """
8 The time at which this record was first created. Set once upon record creation and never changed. Managed by Gadget.
9 """
10 createdAt: DateTime!
11
12 """
13 The time at which this record was last changed. Set each time the record is successfully acted upon by an action. Managed by Gadget.
14 """
15 updatedAt: DateTime!
16
17 """
18 The current state this record is in. Changed by invoking actions. Managed by Gadget.
19 """
20 state: RecordState!
21 barcode: String
22 compareAtPrice: String
23 shopifyCreatedAt: DateTime
24 fulfillmentService: String
25 grams: Float
26 inventoryManagement: String
27 inventoryPolicy: String
28 inventoryQuantity: Float
29 inventoryQuantityAdjustment: Float
30 oldInventoryQuantity: Float
31 option1: String
32 option2: String
33 option3: String
34 position: Float
35 presentmentPrices: JSON
36 price: String
37 requiresShipping: Boolean
38 sku: String
39 taxCode: String
40 taxable: Boolean
41 title: String
42 shopifyUpdatedAt: DateTime
43 weight: Float
44 weightUnit: String
45 product: ShopifyProduct
46 productId: GadgetID
47 shop: ShopifyShop
48 shopId: GadgetID
49
50 """
51 Get all the fields for this record. Useful for not having to list out all the fields you want to retrieve, but slower.
52 """
53 _all: JSONObject!
54}

You can preview what a real record's shape looks like by fetching it using the example-app API Playground.

Any fetched Shopify Product Variant record will have this same ShopifyProductVariant type, and expose the same data by default, regardless of if it's fetched by ID or as part of a findMany. This means you can select any of the record's fields wherever you like in a GraphQL query according to the use case at hand.

Retrieving one Shopify Product Variant record

Individual Shopify Product Variant records can be retrieved using the "find by ID" API endpoint. You can also return only some fields, or extra fields beyond what Gadget retrieves by default, using the select option.

The findOne function throws an error if no matching record is found, which you will need to catch and handle. Alternatively, you can use the maybeFindOne function, which returns null if no record is found, without throwing an error.

Similarly, the useFindOne React hook returns (but does not throw) an error when no matching record is found, while the useMaybeFindOne hook simply returns null if no record is found, without also returning an error.

Get one Shopify Product Variant
const shopifyProductVariantRecord = await api.shopifyProductVariant.findOne(
"some-id"
);
console.log(shopifyProductVariantRecord.id); //=> a string
console.log(shopifyProductVariantRecord.createdAt); //=> a Date object
const [result, refresh] = useFindOne(api.shopifyProductVariant, "some-id");
const { data, error, fetching } = result;
console.log(data?.id); //=> a string
console.log(data?.createdAt); //=> a Date object
1query GetOneShopifyProductVariant($id: GadgetID!) {
2 shopifyProductVariant(id: $id) {
3 __typename
4 id
5 state
6 barcode
7 compareAtPrice
8 createdAt
9 fulfillmentService
10 grams
11 inventoryManagement
12 inventoryPolicy
13 inventoryQuantity
14 inventoryQuantityAdjustment
15 oldInventoryQuantity
16 option1
17 option2
18 option3
19 position
20 presentmentPrices
21 price
22 requiresShipping
23 shopifyCreatedAt
24 shopifyUpdatedAt
25 sku
26 taxCode
27 taxable
28 title
29 updatedAt
30 weight
31 weightUnit
32 }
33}
Variables
json
{ "id": "some-id" }

Retrieving the first of many Shopify Product Variant records

The first record from a list of records can be retrieved using the "find first" API endpoint. The source list of records can be filtered using the filter option, sorted using the sort option, searched using the search option, though no pagination options are available on this endpoint. You can also return only some fields, or extra fields beyond what Gadget retrieves by default using the select option.

The findFirst function throws an error if no matching record is found, which you will need to catch and handle. Alternatively, you can use the maybeFindFirst function, which returns null if no record is found, without throwing an error.

Similarly, the useFindFirst React hook returns (but does not throw) an error when no matching record is found, while the useMaybeFindFirst hook simply returns null if no record is found, without also returning an error.

Get one Shopify Product Variant
const shopifyProductVariantRecord = await api.shopifyProductVariant.findFirst();
console.log(shopifyProductVariantRecord.id); //=> a string
console.log(shopifyProductVariantRecord.createdAt); //=> a Date object
const [result, refresh] = useFindFirst(api.shopifyProductVariant);
const { data, error, fetching } = result;
console.log(data?.id); //=> a string
console.log(data?.createdAt); //=> a Date object
1query FindManyShopifyProductVariants(
2 $first: Int
3 $search: String
4 $sort: [ShopifyProductVariantSort!]
5 $filter: [ShopifyProductVariantFilter!]
6) {
7 shopifyProductVariants(
8 first: $first
9 search: $search
10 sort: $sort
11 filter: $filter
12 ) {
13 edges {
14 node {
15 __typename
16 id
17 state
18 barcode
19 compareAtPrice
20 createdAt
21 fulfillmentService
22 grams
23 inventoryManagement
24 inventoryPolicy
25 inventoryQuantity
26 inventoryQuantityAdjustment
27 oldInventoryQuantity
28 option1
29 option2
30 option3
31 position
32 presentmentPrices
33 price
34 requiresShipping
35 shopifyCreatedAt
36 shopifyUpdatedAt
37 sku
38 taxCode
39 taxable
40 title
41 updatedAt
42 weight
43 weightUnit
44 }
45 }
46 }
47}
Variables
json
{ "first": 1 }

Retrieving many Shopify Product Variant records

Pages of Shopify Product Variant records can be retrieved by using the "find many" API endpoint. The returned records can be filtered using the filter option, sorted using the sort option, searched using the search option, and paginated using standard Relay-style pagination options. You can also return only some fields, or extra fields beyond what Gadget retrieves by default using the select option.

This GraphQL endpoint returns records in the Relay Connection style (as a list of edges with nodes and cursors) so they can be paginated. The shopifyProductVariants GraphQL endpoint works with any Relay-compatible caching client, or you can use Gadget's JS client for pagination with the findMany function.

Find a page of Shopify Product Variants

Fetch a page of records with the shopifyProductVariant.findMany JS method or the shopifyProductVariants GraphQL field. No options are required. The records returned will be implicitly sorted by ID ascending.

Find many Shopify Product Variants
const shopifyProductVariantRecords = await api.shopifyProductVariant.findMany();
console.log(shopifyProductVariantRecords.length); //=> a number
console.log(shopifyProductVariantRecords[0].id); //=> a string
const [result, refresh] = useFindMany(api.shopifyProductVariant);
const { data, error, fetching } = result;
console.log(data?.length); //=> a number
console.log(data?.[0].length); //=> a string
1query FindManyShopifyProductVariants {
2 shopifyProductVariants {
3 edges {
4 node {
5 __typename
6 id
7 state
8 # ...
9 createdAt
10 updatedAt
11 }
12 }
13 }
14}
Variables
json
{}

Sorting

Records can be sorted in the database to retrieve them in a certain order. Records are always implicitly sorted by ID ascending unless an explicit sort on the id field is defined. The GraphQL type ShopifyProductVariantSort defines which fields can be sorted by.

Records can be sorted by multiple different fields and in multiple different directions by passing a list of ShopifyProductVariantSort instead of just one.

GraphQL
1input ShopifyProductVariantSort {
2 id: SortOrder
3 createdAt: SortOrder
4 updatedAt: SortOrder
5 state: SortOrder
6 barcode: SortOrder
7 compareAtPrice: SortOrder
8 shopifyCreatedAt: SortOrder
9 fulfillmentService: SortOrder
10 grams: SortOrder
11 inventoryManagement: SortOrder
12 inventoryPolicy: SortOrder
13 inventoryQuantity: SortOrder
14 inventoryQuantityAdjustment: SortOrder
15 oldInventoryQuantity: SortOrder
16 option1: SortOrder
17 option2: SortOrder
18 option3: SortOrder
19 position: SortOrder
20 presentmentPrices: SortOrder
21 price: SortOrder
22 requiresShipping: SortOrder
23 sku: SortOrder
24 taxCode: SortOrder
25 taxable: SortOrder
26 title: SortOrder
27 shopifyUpdatedAt: SortOrder
28 weight: SortOrder
29 weightUnit: SortOrder
30}

Pass the sort option to the JS client, or the sort variable to a GraphQL query to sort the records returned.

Sort Shopify Product Variant by most recently created
const shopifyProductVariantRecords = await api.shopifyProductVariant.findMany({
sort: { createdAt: "Descending" },
});
const [result, refresh] = useFindMany(api.shopifyProductVariant, {
sort: { createdAt: "Descending" },
});
const { data, error, fetching } = result;
1query FindManyShopifyProductVariants($sort: [ShopifyProductVariantSort!]) {
2 shopifyProductVariants(sort: $sort) {
3 edges {
4 node {
5 __typename
6 id
7 state
8 # ...
9 createdAt
10 updatedAt
11 }
12 }
13 }
14}
Variables
json
{ "sort": { "createdAt": "Descending" } }

Sort by multiple fields by passing an array of { [field]: "Ascending" | "Descending" } objects.

Sort Shopify Product Variant by multiple fields
const shopifyProductVariantRecords = await api.shopifyProductVariant.findMany({
sort: [{ state: "Descending" }, { createdAt: "Ascending" }],
});
const [result, refresh] = useFindMany(api.shopifyProductVariant, {
sort: [{ state: "Descending" }, { createdAt: "Ascending" }],
});
const { data, error, fetching } = result;
1query FindManyShopifyProductVariants($sort: [ShopifyProductVariantSort!]) {
2 shopifyProductVariants(sort: $sort) {
3 edges {
4 node {
5 __typename
6 id
7 state
8 # ...
9 createdAt
10 updatedAt
11 }
12 }
13 }
14}
Variables
json
{ "sort": [{ "state": "Descending" }, { "createdAt": "Ascending" }] }

All primitive field types in Gadget are sortable so you are able to sort by fields you have added to a model as well.

Sort Shopify Product Variants by ID descending
const shopifyProductVariantRecords = await api.shopifyProductVariant.findMany({
sort: { id: "Descending" },
});
const [result, refresh] = useFindMany(api.shopifyProductVariant, {
sort: { id: "Descending" },
});
const { data, error, fetching } = result;
1query FindManyShopifyProductVariants($sort: [ShopifyProductVariantSort!]) {
2 shopifyProductVariants(sort: $sort) {
3 edges {
4 node {
5 __typename
6 id
7 state
8 # ...
9 createdAt
10 updatedAt
11 }
12 }
13 }
14}
Variables
json
{ "sort": { "id": "Descending" } }

Searching

Shopify Product Variant records can be searched using Gadget's built in full text search functionality. Gadget search is appropriate for powering autocompletes, searchable tables, or other experiences where humans are writing search queries. It's typo tolerant, synonym aware and supports simple search operators like ! to exclude search terms.

Search Shopify Product Variants by passing the search parameter with a search query string.

Search isn't field specific in Gadget -- all String or RichText field types are searched with the built in search functionality.

Full text search Shopify Product Variants
const shopifyProductVariantRecords = await api.shopifyProductVariant.findMany({
search: "a specific phrase to search for",
});
const [result, refresh] = useFindMany(api.shopifyProductVariant, {
search: "a specific phrase to search for",
});
const { data, error, fetching } = result;
1query FindManyShopifyProductVariants($search: String) {
2 shopifyProductVariants(search: $search) {
3 edges {
4 node {
5 __typename
6 id
7 state
8 # ...
9 createdAt
10 updatedAt
11 }
12 }
13 }
14}
Variables
json
{ "search": "a specific phrase to search for" }

Filtering

Shopify Product Variant records can be filtered to return only the appropriate records. Records can be filtered on any field, including those managed by Gadget or fields added by developers. Filters can be combined with sorts, searches and paginated using cursor-based Relay pagination.

Filter Shopify Product Variants by passing the filter parameter with a filter object. Filter objects are nestable boolean conditions expressed as JS objects capturing a key, an operator, and usually a value.

The GraphQL type ShopifyProductVariantFilter defines which fields can be filtered on.

Records can be filtered by multiple different fields. If you want to combine filters using boolean logic, nest them under the AND, OR, or NOT keys of a parent filter. Filters can be nested deeply by passing multiple levels boolean condition filters.

You can also pass a list of filters to the filter parameter which will be implicitly ANDed with one another such that they all need to match for a record to be returned.

Available filters
GraphQL
1input ShopifyProductVariantFilter {
2 AND: [ShopifyProductVariantFilter]
3 OR: [ShopifyProductVariantFilter]
4 NOT: [ShopifyProductVariantFilter]
5 id: IDFilter
6 createdAt: DateTimeFilter
7 updatedAt: DateTimeFilter
8 state: StateFilter
9 barcode: StringFilter
10 compareAtPrice: StringFilter
11 shopifyCreatedAt: DateTimeFilter
12 fulfillmentService: StringFilter
13 grams: FloatFilter
14 inventoryManagement: StringFilter
15 inventoryPolicy: StringFilter
16 inventoryQuantity: FloatFilter
17 inventoryQuantityAdjustment: FloatFilter
18 oldInventoryQuantity: FloatFilter
19 option1: StringFilter
20 option2: StringFilter
21 option3: StringFilter
22 position: FloatFilter
23 presentmentPrices: JSONFilter
24 price: StringFilter
25 requiresShipping: BooleanFilter
26 sku: StringFilter
27 taxCode: StringFilter
28 taxable: BooleanFilter
29 title: StringFilter
30 shopifyUpdatedAt: DateTimeFilter
31 weight: FloatFilter
32 weightUnit: StringFilter
33 product: IDFilter
34 shop: IDFilter
35}
Find Shopify Product Variants created in the last day
const yesterday = new Date(Date.now() - 864e5);
const shopifyProductVariantRecords = await api.shopifyProductVariant.findMany({
filter: { createdAt: { greaterThan: yesterday } },
});
const yesterday = new Date(Date.now() - 864e5);
const [result, refresh] = useFindMany(api.shopifyProductVariant, {
filter: { createdAt: { greaterThan: yesterday } },
});
const { data, error, fetching } = result;
1query FindManyShopifyProductVariants($filter: [ShopifyProductVariantFilter!]) {
2 shopifyProductVariants(filter: $filter) {
3 edges {
4 node {
5 __typename
6 id
7 state
8 # ...
9 createdAt
10 updatedAt
11 }
12 }
13 }
14}
Variables
json
{ "filter": { "createdAt": { "greaterThan": "2023-02-05T00:57:51.029Z" } } }
Shopify Product Variants created this week or updated today
1const yesterday = new Date(Date.now() - 86400000);
2const oneWeekAgo = new Date(Date.now() - 604800000);
3const shopifyProductVariantRecords = await api.shopifyProductVariant.findMany({
4 filter: {
5 OR: [
6 {
7 createdAt: { greaterThan: oneWeekAgo },
8 },
9 {
10 updated: { greaterThan: yesterday },
11 },
12 ],
13 },
14});
1const yesterday = new Date(Date.now() - 86400000);
2const oneWeekAgo = new Date(Date.now() - 604800000);
3const [result, refresh] = useFindMany(api.shopifyProductVariant, {
4 filter: {
5 OR: [
6 {
7 createdAt: { greaterThan: oneWeekAgo },
8 },
9 {
10 updated: { greaterThan: yesterday },
11 },
12 ],
13 },
14});
15const { data, error, fetching } = result;
1query FindManyShopifyProductVariants($filter: [ShopifyProductVariantFilter!]) {
2 shopifyProductVariants(filter: $filter) {
3 edges {
4 node {
5 __typename
6 id
7 state
8 # ...
9 createdAt
10 updatedAt
11 }
12 }
13 }
14}
Variables
json
1{
2 "filter": {
3 "OR": [
4 { "createdAt": { "greaterThan": "2023-01-30T00:57:51.029Z" } },
5 { "updated": { "greaterThan": "2023-02-05T00:57:51.029Z" } }
6 ]
7 }
8}
Filter records that are in the created state
const shopifyProductVariantRecords = await api.shopifyProductVariant.findMany({
filter: {
state: { inState: "created" },
},
});
1const [result, refresh] = useFindMany(api.shopifyProductVariant, {
2 filter: {
3 state: { inState: "created" },
4 },
5});
6const { data, error, fetching } = result;
1query FindManyShopifyProductVariants($filter: [ShopifyProductVariantFilter!]) {
2 shopifyProductVariants(filter: $filter) {
3 edges {
4 node {
5 __typename
6 id
7 state
8 # ...
9 createdAt
10 updatedAt
11 }
12 }
13 }
14}
Variables
json
{ "filter": { "state": { "inState": "created" } } }

Most field types in Gadget are filterable, so you are able to filter by fields you have added to a model as well.

const shopifyProductVariantRecords = await api.shopifyProductVariant.findMany({
filter: {
id: { isSet: true },
},
});
1const [result, refresh] = useFindMany(api.shopifyProductVariant, {
2 filter: {
3 id: { isSet: true },
4 },
5});
6const { data, error, fetching } = result;
1query FindManyShopifyProductVariants($filter: [ShopifyProductVariantFilter!]) {
2 shopifyProductVariants(filter: $filter) {
3 edges {
4 node {
5 __typename
6 id
7 state
8 # ...
9 createdAt
10 updatedAt
11 }
12 }
13 }
14}
Variables
json
{ "filter": { "id": { "isSet": true } } }

Pagination

All Gadget record lists, including the top level Shopify Product Variant finder as well as associations to Shopify Product Variant, are structured as GraphQL connections. GraphQL connections are the de facto standard for querying lists and support cursor-based forward and backward pagination. When querying via GraphQL, you must select the edges field and then the node field to get the Shopify Product Variant record. When querying using a Gadget API client, the GraphQL queries are generated for you and the records are unwrapped and returned as a GadgetRecordList ready for use.

Shopify Product Variant pagination supports the standard GraphQL connection pagination arguments: first + after, or last + before. Pagination is done using cursors, which you can retrieve from the edge.cursor field or the pageInfo.startCursor properties.

Get the first page of 25 Shopify Product Variants
const shopifyProductVariantRecords = await api.shopifyProductVariant.findMany({
first: 25,
});
console.log(shopifyProductVariantRecords.length); //=> no greater than 25
const [result, refresh] = useFindMany(api.shopifyProductVariant, { first: 25 });
const { data, error, fetching } = result;
console.log(data?.length); //=> no greater than 25
1query FindManyShopifyProductVariants($first: Int, $after: String) {
2 shopifyProductVariants(first: $first, after: $after) {
3 edges {
4 cursor
5 node {
6 __typename
7 id
8 state
9 # ...
10 createdAt
11 updatedAt
12 }
13 }
14 pageInfo {
15 endCursor
16 hasNextPage
17 hasPreviousPage
18 startCursor
19 }
20 }
21}
Variables
json
{ "first": 25 }

The after cursor used in this example data won't return any records if used in a real API request.

Next 25 Shopify Product Variant records after cursor
const shopifyProductVariantRecords = await api.shopifyProductVariant.findMany({
after: "abcdefg",
first: 25,
});
const [result, refresh] = useFindMany(api.shopifyProductVariant, {
after: "abcdefg",
first: 25,
});
const { data, error, fetching } = result;
1query FindManyShopifyProductVariants($first: Int, $after: String) {
2 shopifyProductVariants(first: $first, after: $after) {
3 edges {
4 cursor
5 node {
6 __typename
7 id
8 state
9 # ...
10 createdAt
11 updatedAt
12 }
13 }
14 pageInfo {
15 endCursor
16 hasNextPage
17 hasPreviousPage
18 startCursor
19 }
20 }
21}
Variables
json
{ "first": 25, "after": "abcdefg" }

Pagination Limits

Root-level record finders like shopifyProductVariants support a maximum page size of 250 records and a default page size of 50 records. The page size is controlled using the first or last GraphQL field arguments.

Related record finders that access lists of records through a has many or has many field support a maximum page size of 100 records and a default page size of 50 records.

Get the next or previous page

When using the generated JavaScript API client, including the api parameter in a Gadget code effect, the record lists returned from findMany calls can be paginated using the nextPage() or previousPage() option.

Both nextPage() and previousPage() will throw an error if the corresponding hasNextPage or hasPreviousPage is false.

JavaScript
1const shopifyProductVariantRecords = await api.shopifyProductVariant.findMany();
2if (shopifyProductVariantRecords.hasNextPage) {
3 const nextPage = await shopifyProductVariantRecords.nextPage();
4}
5if (shopifyProductVariantRecords.hasPreviousPage) {
6 const prevPage = await shopifyProductVariantRecords.previousPage();
7}

When using React and paging through records, you can use cursors to get the previous or next pages of records. This is an example of a React component that pages forward and backward through 2 records at a time for props.model.name.

React
1import { api } from "../api"; // your Gadget project's API Client
2import { useFindMany } from "@gadgetinc/react";
3import { useCallback, useState } from "react";
4
5export default function TestComponent() {
6 const NUM_ON_PAGE = 2; // the number of records per page
7
8 const [cursor, setCursor] = useState({ first: NUM_ON_PAGE });
9 // using Gadget React hooks to fetch records of shopifyProductVariant
10 const [{ data, fetching, error }] = useFindMany(api.shopifyProductVariant, {
11 ...cursor,
12 });
13
14 const getNextPage = useCallback(() => {
15 // use first + after to page forwards
16 setCursor({ first: NUM_ON_PAGE, after: data.endCursor });
17 }, [data]);
18
19 const getPreviousPage = useCallback(() => {
20 // use last + before to page backwards
21 setCursor({ last: NUM_ON_PAGE, before: data.startCursor });
22 }, [data]);
23
24 return (
25 <div>
26 <button onClick={getPreviousPage} disabled={!data?.hasPreviousPage}>
27 Previous page
28 </button>
29 <button onClick={getNextPage} disabled={!data?.hasNextPage}>
30 Next page
31 </button>
32 {!fetching && data.map((d) => <div>{d.id}</div>)}
33 </div>
34 );
35}

Get all records

If you need to get all available data for Shopify Product Variant, you will need to paginate through all pages of data. If you have a large amount of data, this can take a long time. Make sure you need to collect all data at once before writing a pagination loop that reads all records! If you are querying records for display in a UI and cannot display all your records at once, we don't recommend fetching all the data beforehand - instead, use the cursor to read additional data when the user needs it.

If you need all data for analytics applications or to collect some statistics on your data, consider options like intermediate models and pre-defined data rollups.

If you have determined that you need all your data, you can fetch it using cursors and a loop. We also suggest using select so that you only grab fields that are needed, in addition to applying a filter, if possible. Using first with the maximum allowable value will also allow you to grab the maximum number of records you can at once.

Page through all records
JavaScript
1const allRecords = []; // use allRecords to store all records
2let records = await api.shopifyProductVariant.findMany({
3 first: 250,
4 select: {
5 id: true,
6 },
7 filter: {
8 // add filter conditions, if possible
9 },
10});
11
12allRecords.push(...records);
13
14// loop through additional pages to get all protected orders
15while (records.hasNextPage) {
16 // paginate
17 records = await records.nextPage();
18 allRecords.push(...records);
19}

Selecting fields, and fields of fields

When using the JavaScript client, all of findOne, maybeFindOne, findMany, findFirst, maybeFindFirst, and various action functions, allow requesting specific fields of a Shopify Product Variant and its relationships. The select option controls which fields are selected in the generated GraphQL query sent to the Gadget API. Pass each field you want to select in an object, with true as the value for scalar fields, and a nested object of the same shape for nested fields.

Gadget has a default selection that will retrieve all of the scalar fields for a Shopify Product Variant. If you don't pass a select option to a record finder, this default selection will be used.

Select only some Shopify Product Variant fields
1// fetch only the id, state, and createdAt field
2const shopifyProductVariantRecords = await api.shopifyProductVariant.findMany({
3 select: { id: true, state: true, createdAt: true },
4});
5// fetch all the scalar fields for the model, but no relationship fields
6const shopifyProductVariantRecords = await api.shopifyProductVariant.findMany();
1// fetch only the id, state, and createdAt field
2const [result, refresh] = useFindMany(api.shopifyProductVariant, {
3 select: { id: true, state: true, createdAt: true },
4});
5const { data, error, fetching } = result;
6// fetch all the scalar fields for the model, but no relationship fields
7const [result, refresh] = useFindMany(api.shopifyProductVariant);
8const { data, error, fetching } = result;
Type Safety

The select option is fully type safe if you're using TypeScript. The returned GadgetRecord type will have a <Shape> exactly matching the fields and nested fields you selected. For more information, see Type Safety .

This behavior of selecting only some fields is built right into GraphQL. If you want to limit or expand what you retrieve from a GraphQL query, include or exclude those fields in your GraphQL query. For more information on executing GraphQL queries, see GraphQL.

Select nested Shopify Product Variant fields
1// fetch the id, state, and createdAt field, and fetch some nested fields from an example relationship field named `someRelatedObject`
2const shopifyProductVariantRecords = await api.shopifyProductVariant.findMany({
3 select: {
4 id: true,
5 state: true,
6 createdAt: true,
7 someRelatedObject: { id: true, createdAt: true },
8 },
9});
1// fetch the id, state, and createdAt field, and fetch some nested fields from an example relationship field named `someRelatedObject`
2const [result, refresh] = useFindMany(api.shopifyProductVariant, {
3 select: {
4 id: true,
5 state: true,
6 createdAt: true,
7 someRelatedObject: { id: true, createdAt: true },
8 },
9});
10const { data, error, fetching } = result;

Combining parameters

Sort, search, filtering, selection, and pagination parameters can be combined to access the exact set of records needed for your use case.

Combining Parameters
1const shopifyProductVariantRecords = await api.shopifyProductVariant.findMany({
2 search: "<some search query>",
3 sort: { createdAt: "Descending" },
4 filter: { updatedAt: { greaterThan: new Date(Date.now() - 864e5) } },
5 select: { id: true, createdAt: true },
6 first: 25,
7 after: "abcdefg",
8});
1const [result, refresh] = useFindMany(api.shopifyProductVariant, {
2 search: "<some search query>",
3 sort: { createdAt: "Descending" },
4 filter: { updatedAt: { greaterThan: new Date(Date.now() - 864e5) } },
5 select: { id: true, createdAt: true },
6 first: 25,
7 after: "abcdefg",
8});
9const { data, error, fetching } = result;
1query FindManyShopifyProductVariants(
2 $after: String
3 $before: String
4 $first: Int
5 $last: Int
6 $search: String
7 $sort: [ShopifyProductVariantSort!]
8 $filter: [ShopifyProductVariantFilter!]
9) {
10 shopifyProductVariants(
11 after: $after
12 before: $before
13 first: $first
14 last: $last
15 search: $search
16 sort: $sort
17 filter: $filter
18 ) {
19 edges {
20 cursor
21 node {
22 __typename
23 id
24 state
25 barcode
26 compareAtPrice
27 createdAt
28 fulfillmentService
29 grams
30 inventoryManagement
31 inventoryPolicy
32 inventoryQuantity
33 inventoryQuantityAdjustment
34 oldInventoryQuantity
35 option1
36 option2
37 option3
38 position
39 presentmentPrices
40 price
41 requiresShipping
42 shopifyCreatedAt
43 shopifyUpdatedAt
44 sku
45 taxCode
46 taxable
47 title
48 updatedAt
49 weight
50 weightUnit
51 }
52 }
53 pageInfo {
54 endCursor
55 hasNextPage
56 hasPreviousPage
57 startCursor
58 }
59 }
60}
Variables
json
1{
2 "search": "<some search query>",
3 "sort": { "createdAt": "Descending" },
4 "filter": { "updatedAt": { "greaterThan": "2023-02-05T00:57:51.239Z" } },
5 "first": 25,
6 "after": "abcdefg"
7}

Invoking Actions

Shopify Product Variant records are changed by invoking Actions. Actions are the things that "do" stuff -- update records, make API calls, call backend code, etc. Actions with a GraphQL API trigger each have one corresponding GraphQL mutation and a corresponding function available in the API client libraries. Nested Actions can also be invoked with the API client, by providing the actions as input to any relationship fields.

Action Result format

Each API action returns results in the same format that includes a success indicator, errors, and the actual result if the action succeeded. The result is the record that was acted on for a model action, or a list of records for a bulk action, or a JSON blob for Global Actions. Model actions that delete the record don't return the record.

The success field returns a boolean indicating if the action executed as expected. Any execution errors are returned in the errors object, which will always be null if success is true or contain ExecutionError objects if success is false.

ExecutionError objects always have a message describing what error prevented the action from succeeding, as well as a code attribute that gives a stable, searchable, human readable error class code for referencing this specific error. Details on each error code can be found in the Errors documentation. All ExecutionError object types returned by the GraphQL object can be one of many types of error, where some types have extra data that is useful for remedying the error. All error types will always have message and code properties, but some, like InvalidRecordError have extra fields for use by clients.

Errors when using the generated client

The generated JavaScript client automatically interprets errors from invoking actions and throws JavaScript Error instances if the action didn't succeed. The Error objects it throws are rich, and expose extra error properties beyond just message and code if they exist.

Errors thrown by the JavaScript client are easiest to catch by using a try/catch statement around an await, like so:

JavaScript
1import {
2 GadgetOperationError,
3 InvalidRecordError,
4} from "@gadget-client/example-app";
5
6// must be in an async function to use `await` syntax
7const runAction = async () => {
8 try {
9 return await api.exampleModel.create({
10 exampleModel: { name: "example record name" },
11 });
12 } catch (error) {
13 if (error instanceof GadgetOperationError) {
14 // a recognized general error has occurred, retry the operation or inspect error.code`
15 console.error(error);
16 } else if (error instanceof InvalidRecordError) {
17 // the submitted input data for the action was invalid, inspect the invalid fields which `InvalidRecordError` exposes
18 console.error(error.validationErrors);
19 } else {
20 // an unrecognized error occurred, like an HTTP connection interrupted error or a syntax error. Re-throw it because it's not clear what to do to fix ti
21 throw error;
22 }
23 }
24};

For more information on error codes, consult the Errors documentation.

Shopify Product Variant create

Input

create accepts the following input parameters:

create Input Data
1export interface CreateShopifyProductVariantInput {
2 id?: (Scalars["GadgetID"] | null) | null;
3
4 barcode?: (Scalars["String"] | null) | null;
5
6 compareAtPrice?: (Scalars["String"] | null) | null;
7
8 shopifyCreatedAt?: Date | Scalars["ISO8601DateString"] | null;
9
10 fulfillmentService?: (Scalars["String"] | null) | null;
11
12 grams?: (Scalars["Float"] | null) | null;
13
14 inventoryManagement?: (Scalars["String"] | null) | null;
15
16 inventoryPolicy?: (Scalars["String"] | null) | null;
17
18 inventoryQuantity?: (Scalars["Float"] | null) | null;
19
20 inventoryQuantityAdjustment?: (Scalars["Float"] | null) | null;
21
22 oldInventoryQuantity?: (Scalars["Float"] | null) | null;
23
24 option1?: (Scalars["String"] | null) | null;
25
26 option2?: (Scalars["String"] | null) | null;
27
28 option3?: (Scalars["String"] | null) | null;
29
30 position?: (Scalars["Float"] | null) | null;
31
32 presentmentPrices?: (Scalars["JSON"] | null) | null;
33
34 price?: (Scalars["String"] | null) | null;
35
36 requiresShipping?: (Scalars["Boolean"] | null) | null;
37
38 sku?: (Scalars["String"] | null) | null;
39
40 taxCode?: (Scalars["String"] | null) | null;
41
42 taxable?: (Scalars["Boolean"] | null) | null;
43
44 title?: (Scalars["String"] | null) | null;
45
46 shopifyUpdatedAt?: Date | Scalars["ISO8601DateString"] | null;
47
48 weight?: (Scalars["Float"] | null) | null;
49
50 weightUnit?: (Scalars["String"] | null) | null;
51
52 product?: ShopifyProductBelongsToInput | null;
53
54 shop?: ShopifyShopBelongsToInput | null;
55}
56
57export interface CreateShopifyProductVariantArguments {
58 shopifyProductVariant?: CreateShopifyProductVariantInput | null;
59}
1input CreateShopifyProductVariantInput {
2 id: GadgetID
3 barcode: String
4 compareAtPrice: String
5 shopifyCreatedAt: DateTime
6 fulfillmentService: String
7 grams: Float
8 inventoryManagement: String
9 inventoryPolicy: String
10 inventoryQuantity: Float
11 inventoryQuantityAdjustment: Float
12 oldInventoryQuantity: Float
13 option1: String
14 option2: String
15 option3: String
16 position: Float
17 presentmentPrices: JSON
18 price: String
19 requiresShipping: Boolean
20 sku: String
21 taxCode: String
22 taxable: Boolean
23 title: String
24 shopifyUpdatedAt: DateTime
25 weight: Float
26 weightUnit: String
27 product: ShopifyProductBelongsToInput
28 shop: ShopifyShopBelongsToInput
29}
30
31input CreateShopifyProductVariantArguments {
32 shopifyProductVariant: CreateShopifyProductVariantInput
33}
Example create Invocation
1const shopifyProductVariantRecord = await api.shopifyProductVariant.create({
2 shopifyProductVariant: {
3 // field values for Shopify Product Variant
4 },
5});
6console.log(shopifyProductVariantRecord.id); //=> a string
1const [result, createShopifyProductVariant] = useAction(
2 api.shopifyProductVariant.create
3);
4const { data, error, fetching } = result;
5await createShopifyProductVariant({
6 shopifyProductVariant: {
7 // field values for Shopify Product Variant
8 },
9});
10console.log(data?.id); //=> a string
1mutation ($shopifyProductVariant: CreateShopifyProductVariantInput) {
2 createShopifyProductVariant(shopifyProductVariant: $shopifyProductVariant) {
3 success
4 errors {
5 message
6 ... on InvalidRecordError {
7 validationErrors {
8 apiIdentifier
9 message
10 }
11 record
12 model {
13 apiIdentifier
14 }
15 }
16 }
17 shopifyProductVariant {
18 __typename
19 id
20 state
21 barcode
22 compareAtPrice
23 createdAt
24 fulfillmentService
25 grams
26 inventoryManagement
27 inventoryPolicy
28 inventoryQuantity
29 inventoryQuantityAdjustment
30 oldInventoryQuantity
31 option1
32 option2
33 option3
34 position
35 presentmentPrices
36 price
37 requiresShipping
38 shopifyCreatedAt
39 shopifyUpdatedAt
40 sku
41 taxCode
42 taxable
43 title
44 updatedAt
45 weight
46 weightUnit
47 }
48 }
49}
Variables
json
{ "shopifyProductVariant": {} }
Output

create returns the Shopify Product Variant. In the JS client, the fields returned can be controlled with the select option. In GraphQL, the return format is the action result format, which includes the record if the action was successful. You can include or exclude the fields you need right in the mutation itself.

create Output Data
type CreateShopifyProductVariantResult {
success: Boolean!
errors: [ExecutionError!]
shopifyProductVariant: ShopifyProductVariant
}

Shopify Product Variant update

Input

update operates on one Shopify Product Variant in particular, identified by the id variable.update accepts the following input parameters:

update Input Data
1export interface UpdateShopifyProductVariantInput {
2 id?: (Scalars["GadgetID"] | null) | null;
3
4 barcode?: (Scalars["String"] | null) | null;
5
6 compareAtPrice?: (Scalars["String"] | null) | null;
7
8 shopifyCreatedAt?: Date | Scalars["ISO8601DateString"] | null;
9
10 fulfillmentService?: (Scalars["String"] | null) | null;
11
12 grams?: (Scalars["Float"] | null) | null;
13
14 inventoryManagement?: (Scalars["String"] | null) | null;
15
16 inventoryPolicy?: (Scalars["String"] | null) | null;
17
18 inventoryQuantity?: (Scalars["Float"] | null) | null;
19
20 inventoryQuantityAdjustment?: (Scalars["Float"] | null) | null;
21
22 oldInventoryQuantity?: (Scalars["Float"] | null) | null;
23
24 option1?: (Scalars["String"] | null) | null;
25
26 option2?: (Scalars["String"] | null) | null;
27
28 option3?: (Scalars["String"] | null) | null;
29
30 position?: (Scalars["Float"] | null) | null;
31
32 presentmentPrices?: (Scalars["JSON"] | null) | null;
33
34 price?: (Scalars["String"] | null) | null;
35
36 requiresShipping?: (Scalars["Boolean"] | null) | null;
37
38 sku?: (Scalars["String"] | null) | null;
39
40 taxCode?: (Scalars["String"] | null) | null;
41
42 taxable?: (Scalars["Boolean"] | null) | null;
43
44 title?: (Scalars["String"] | null) | null;
45
46 shopifyUpdatedAt?: Date | Scalars["ISO8601DateString"] | null;
47
48 weight?: (Scalars["Float"] | null) | null;
49
50 weightUnit?: (Scalars["String"] | null) | null;
51
52 product?: ShopifyProductBelongsToInput | null;
53
54 shop?: ShopifyShopBelongsToInput | null;
55}
56
57export interface UpdateShopifyProductVariantArguments {
58 shopifyProductVariant?: UpdateShopifyProductVariantInput | null;
59}
1input UpdateShopifyProductVariantInput {
2 id: GadgetID
3 barcode: String
4 compareAtPrice: String
5 shopifyCreatedAt: DateTime
6 fulfillmentService: String
7 grams: Float
8 inventoryManagement: String
9 inventoryPolicy: String
10 inventoryQuantity: Float
11 inventoryQuantityAdjustment: Float
12 oldInventoryQuantity: Float
13 option1: String
14 option2: String
15 option3: String
16 position: Float
17 presentmentPrices: JSON
18 price: String
19 requiresShipping: Boolean
20 sku: String
21 taxCode: String
22 taxable: Boolean
23 title: String
24 shopifyUpdatedAt: DateTime
25 weight: Float
26 weightUnit: String
27 product: ShopifyProductBelongsToInput
28 shop: ShopifyShopBelongsToInput
29}
30
31input UpdateShopifyProductVariantArguments {
32 shopifyProductVariant: UpdateShopifyProductVariantInput
33}
Example update Invocation
1const shopifyProductVariantRecord = await api.shopifyProductVariant.update(
2 "some-id",
3 {
4 shopifyProductVariant: {
5 // field values for Shopify Product Variant
6 },
7 }
8);
9console.log(shopifyProductVariantRecord.id); //=> a string
1const [result, updateShopifyProductVariant] = useAction(
2 api.shopifyProductVariant.update
3);
4const { data, error, fetching } = result;
5await updateShopifyProductVariant({
6 id: "some-id",
7 shopifyProductVariant: {
8 // field values for Shopify Product Variant
9 },
10});
11console.log(data?.id); //=> a string
1mutation ($id: GadgetID!, $shopifyProductVariant: UpdateShopifyProductVariantInput) {
2 updateShopifyProductVariant(
3 id: $id
4 shopifyProductVariant: $shopifyProductVariant
5 ) {
6 success
7 errors {
8 message
9 ... on InvalidRecordError {
10 validationErrors {
11 apiIdentifier
12 message
13 }
14 record
15 model {
16 apiIdentifier
17 }
18 }
19 }
20 shopifyProductVariant {
21 __typename
22 id
23 state
24 barcode
25 compareAtPrice
26 createdAt
27 fulfillmentService
28 grams
29 inventoryManagement
30 inventoryPolicy
31 inventoryQuantity
32 inventoryQuantityAdjustment
33 oldInventoryQuantity
34 option1
35 option2
36 option3
37 position
38 presentmentPrices
39 price
40 requiresShipping
41 shopifyCreatedAt
42 shopifyUpdatedAt
43 sku
44 taxCode
45 taxable
46 title
47 updatedAt
48 weight
49 weightUnit
50 }
51 }
52}
Variables
json
{ "id": "some-id", "shopifyProductVariant": {} }
Output

update returns the Shopify Product Variant. In the JS client, the fields returned can be controlled with the select option. In GraphQL, the return format is the action result format, which includes the record if the action was successful. You can include or exclude the fields you need right in the mutation itself.

update Output Data
type UpdateShopifyProductVariantResult {
success: Boolean!
errors: [ExecutionError!]
shopifyProductVariant: ShopifyProductVariant
}

Shopify Product Variant delete

The delete action destroys the record.

Input

delete operates on one Shopify Product Variant in particular, identified by the id variable.

Example delete Invocation
await api.shopifyProductVariant.delete("some-id");
1const [result, deleteShopifyProductVariant] = useAction(
2 api.shopifyProductVariant.delete
3);
4const { data, error, fetching } = result;
5await deleteShopifyProductVariant({
6 id: "some-id",
7});
1mutation ($id: GadgetID!) {
2 deleteShopifyProductVariant(id: $id) {
3 success
4 errors {
5 message
6 ... on InvalidRecordError {
7 validationErrors {
8 apiIdentifier
9 message
10 }
11 record
12 model {
13 apiIdentifier
14 }
15 }
16 }
17 }
18}
Variables
json
{ "id": "some-id" }
Output

delete deletes the record, so it returns void in the JS client. In GraphQL it returns only the success and errors from the action result format.

delete Output Data
type DeleteShopifyProductVariantResult {
success: Boolean!
errors: [ExecutionError!]
}

Linking to an Existing Child Record

During a create or update operation, you can link to existing child records simply by nesting the data structure on your operation, using an update object wrapper around the child record's properties.

Existing nested child
1const shopifyProductRecord = await api.shopifyProduct.create({
2 shopifyProduct: {
3 body: "bodyValue",
4 variants: {
5 // Updates existing `shopifyProductVariant` record
6 // (`id` of record required),
7 // and links it to shopifyProduct.
8 update: {
9 id: "123",
10 barcode: "variantsBarcodeValue",
11 },
12 },
13 },
14});
15console.log(shopifyProductRecord.id); //=> a string
1const [result, createShopifyProduct] = useAction(api.shopifyProduct.create);
2const { data, error, fetching } = result;
3await createShopifyProduct({
4 shopifyProduct: {
5 body: "bodyValue",
6 variants: {
7 // Updates existing `shopifyProductVariant` record
8 // (`id` of record required),
9 // and links it to shopifyProduct.
10 update: {
11 id: "123",
12 barcode: "variantsBarcodeValue",
13 },
14 },
15 },
16});
17console.log(data?.id); //=> a string
1mutation ($shopifyProduct: CreateShopifyProductInput) {
2 createShopifyProduct(shopifyProduct: $shopifyProduct) {
3 success
4 errors {
5 message
6 }
7 shopifyProduct {
8 id
9 body
10 variants {
11 id
12 }
13 }
14 }
15}
Variables
json
{
"body": "bodyValue",
"variants": { "update": { "id": "123", "barcode": "variantsBarcodeValue" } }
}

Linking to a New Child Record

During a create or update operation, you can create linked child records simply by nesting the data structure on your operation, using a create object wrapper around the child record's properties.

New nested child
1const shopifyProductRecord = await api.shopifyProduct.create({
2 shopifyProduct: {
3 body: "bodyValue",
4 variants: {
5 // Creates `shopifyProductVariant` record,
6 // linked to shopifyProduct.
7 create: {
8 barcode: "variantsBarcodeValue",
9 },
10 },
11 },
12});
13console.log(shopifyProductRecord.id); //=> a string
1const [result, createShopifyProduct] = useAction(api.shopifyProduct.create);
2const { data, error, fetching } = result;
3await createShopifyProduct({
4 shopifyProduct: {
5 body: "bodyValue",
6 variants: {
7 // Creates `shopifyProductVariant` record,
8 // linked to shopifyProduct.
9 create: {
10 barcode: "variantsBarcodeValue",
11 },
12 },
13 },
14});
15console.log(data?.id); //=> a string
1mutation ($shopifyProduct: CreateShopifyProductInput) {
2 createShopifyProduct(shopifyProduct: $shopifyProduct) {
3 success
4 errors {
5 message
6 }
7 shopifyProduct {
8 id
9 body
10 variants {
11 id
12 }
13 }
14 }
15}
Variables
json
{
"body": "bodyValue",
"variants": { "create": { "barcode": "variantsBarcodeValue" } }
}

Linking to an Existing Parent Record

When you wish to link to an existing parent record, you must use a _link property in your data, with the id of the parent record that this child record will belong to.

Linked creation
1const shopifyProductVariantRecord = await api.shopifyProductVariant.create({
2 shopifyProductVariant: {
3 barcode: "barcodeValue",
4 product: {
5 _link: "123",
6 },
7 },
8});
9console.log(shopifyProductVariantRecord.id); //=> a string
1const [result, createShopifyProductVariant] = useAction(
2 api.shopifyProductVariant.create
3);
4const { data, error, fetching } = result;
5await createShopifyProductVariant({
6 shopifyProductVariant: {
7 barcode: "barcodeValue",
8 product: {
9 _link: "123",
10 },
11 },
12});
13console.log(data?.id); //=> a string
1mutation ($shopifyProductVariant: CreateShopifyProductVariantInput) {
2 createShopifyProductVariant(shopifyProductVariant: $shopifyProductVariant) {
3 success
4 errors {
5 message
6 }
7 shopifyProductVariant {
8 id
9 barcode
10 product {
11 id
12 }
13 }
14 }
15}
Variables
json
{ "barcode": "barcodeValue", "product": { "_link": "123" } }

Linking to a New Parent Record

You cannot directly link to a new parent record when creation a child record. However, you can jointly create both parent and child via the Linking to a New Child Record method.

Bulk Actions

Actions that support it can be performed in bulk. Bulk Actions are executed as a single GraphQL mutation and have a corresponding function available in the API client libraries. Bulk Actions are performed on a set of ids. Bulk Actions repeat the same action, with the same options and parameters, across all ids and should not be confused with batching up different actions in the same request.

Bulk Actions will be performed on the entire set. If an action fails on an individual record, the Bulk Action will still occur on the other records in the set. Only the records which completed the action successfully will be returned.

Bulk Shopify Product Variant delete

bulkDeleteShopifyProductVariants action destroys the records.

Input

bulkDeleteShopifyProductVariants operates on a set of Shopify Product Variants, identified by the ids variable.

Example bulkDeleteShopifyProductVariants Invocation
await api.shopifyProductVariant.bulkDelete(["some-id", "another-id"]);
const [shopifyProductVariantResult, bulkDelete] = useBulkAction(
api.shopifyProductVariant.bulkDelete
);
const { data, error, fetching } = result;
await bulkDelete({ ids: ["some-id", "another-id"] });
1mutation ($ids: [GadgetID!]!) {
2 bulkDeleteShopifyProductVariants(ids: $ids) {
3 success
4 errors {
5 message
6 }
7 }
8}
Variables
json
{ "ids": ["some-id", "another-id"] }
Output

bulkDeleteShopifyProductVariants deletes the record, so it returns void in the JS client. In GraphQL it returns only the success and errors from the action result format.

bulkDeleteShopifyProductVariants Output Data
type BulkDeleteShopifyProductVariantsResult {
success: Boolean!
errors: [ExecutionError!]
}