@dmkishi/shopify-provider
v2.1.0
Published
Simple wrapper over the Shopify GraphQL Admin API w/ handy abstraction for bulk operations.
Readme
Shopify Provider
Simple wrapper over the Shopify GraphQL Admin API with a handy abstraction for bulk operations.
Install
pnpm add @dmkishi/shopify-providerUsage
Import library and create a Shopify API client
import {
createShopifyProvider,
GraphQlError,
BulkOperationUserError,
BulkOperationError,
type ShopifyProvider,
} from '@dmkishi/shopify-provider';
const shopifyProvider = createShopifyProvider({
storeDomain: 'example.myshopify.com',
apiVersion: '2026-01',
accessToken: 'shpat_EXAMPLE',
});Make a GraphQL request
The variables argument is optional.
type ProductData = {
product: {
title: string;
tags: string[];
} | null;
};
let data: ProductData;
try {
data = await shopifyProvider.graphQl<ProductData>(
/* graphql */`
query GetProduct($id: ID!) {
product(id: $id) {
title
tags
}
}
`,
{
variables: { id: 'gid://shopify/Product/1234567890' },
}
);
} catch (error) {
if (error instanceof GraphQlError) {
throw new Error(error.publicMessage, { cause: error });
}
throw error;
}
if (data.product !== null) {
console.log(data.product); // { title: "Title", tags: ["Tag"] }
}Make a bulk operation request
type Product = {
title: string;
tags: string[];
};
/**
* Optionally pass an `AbortSignal` to allow canceling a running bulk operation.
* In this example, cancel the request after 1 minute.
*/
const controller = new AbortController();
setTimeout(() => controller.abort(), 60_000);
let products: Product[];
try {
products = await shopifyProvider.bulkOperation<Product>(
/* graphql */`
{
products {
edges {
node {
title
tags
}
}
}
}
`,
{
pollFrequencyMs: 2_500,
signal: controller.signal,
}
);
} catch (error) {
if (error instanceof GraphQlError) {
throw new Error(`GraphQL error: ${error.message}`, { cause: error });
}
if (error instanceof BulkOperationUserError) {
throw new Error(`Bulk operation user error: ${error.code}`, { cause: error });
}
if (error instanceof BulkOperationError) {
throw new Error(`Bulk operation error: ${error.code}`, { cause: error });
}
throw error;
}
console.log(products); // [{ title: "Title", tags: ["Tag"] }, ... ]Access the underlying Admin API client
The underlying @shopify/admin-api-client
instance is exposed as client for use cases not covered.
const { data, errors } = await shopifyProvider.client.request(
/* graphql */`
query {
shop {
name
}
}
`
);Utilities
Shopify-related helpers are available from a separate /utils entry point, so
they can be used without creating a provider.
numericId
Extracts the numeric identifier from a Shopify global ID (GID). The id is
returned as a string to avoid precision loss, and any trailing query string is
ignored. Throws a RangeError if the input is not a valid GID.
import { numericId } from '@dmkishi/shopify-provider/utils';
numericId('gid://shopify/Product/1234567890'); // '1234567890'
numericId('gid://shopify/ProductVariant/42?namespace=foo'); // '42'Develop
# Lint, build, and then publish.
pnpm publish