@pintahub/shopify-next
v0.13.0
Published
Shopify Admin GraphQL client for pintahub services via shopify-gateway
Readme
@pintahub/shopify-next
Shopify Admin GraphQL client for Pintahub services. Calls flow through shopify-gateway instead of going directly to Shopify, which gives you automatic per-store rate limiting, concurrent-request locking, request logging to MongoDB, and zero access-token handling on the caller side.
Replacement for the older @pintahub/shopify-api with:
- Unified API version (
2026-04) instead of three different versions split per namespace. - Command pattern (AWS SDK v3 style) — tree-shakable, type-safe, easy to mock.
- First-class middleware — logging, retry, telemetry wrap once at the client level.
Quick start
Install
yarn add @pintahub/shopify-nextSet env
SHOPIFY_GATEWAY_URL=http://shopify-gateway.internal:6100Code
import {ShopifyClient, SearchMenusCommand, GetMenuCommand} from '@pintahub/shopify-next'
const client = new ShopifyClient('6543abc...')
// Query
const {items, pageInfo} = await client.send(new SearchMenusCommand({first: 50}))
// Get single
const menu = await client.send(new GetMenuCommand({id: items[0].id}))Architecture
┌───────────────┐
│ your service │
└───────┬───────┘
│ client.send(new XCommand({...}))
▼
┌───────────────┐
│ ShopifyClient │ ← middleware chain (optional)
└───────┬───────┘
│ HTTP POST /stores/<id>/<version>/graphql.json
▼
┌───────────────┐
│shopify-gateway│ ← rate limit, lock, MongoDB log, token lookup
└───────┬───────┘
│ HTTP POST <subdomain>/admin/api/<v>/graphql.json
▼
┌───────────────┐
│ Shopify │
└───────────────┘Middleware
Opt-in. Pass into the constructor:
import {ShopifyClient, type Middleware, SearchMenusCommand} from '@pintahub/shopify-next'
const loggingMiddleware: Middleware = (next) => async (command) => {
const t0 = Date.now()
try {
const result = await next(command)
console.log(`[shopify] ${command.name} ok ${Date.now() - t0}ms`)
return result
} catch (err) {
console.error(`[shopify] ${command.name} failed ${Date.now() - t0}ms`, err)
throw err
}
}
const client = new ShopifyClient(storeId, {
middleware: [loggingMiddleware],
})Override API version
const beta = new ShopifyClient(storeId, {apiVersion: 'unstable'})
const stable = new ShopifyClient(storeId, {apiVersion: '2026-01'}) // pin an older versionAPI surface
Each namespace maps to a folder under src/commands/. For the current implementation progress, see the "Implementation status" section in CLAUDE.md.
| Namespace | Main commands |
|---|---|
| Customers | CreateCustomerCommand |
| Payments | SearchPayoutsCommand |
| Menus | SearchMenusCommand, GetMenuCommand |
| Metaobjects | SearchMetaobjectsCommand, GetMetaobjectCommand, ListBannersCommand, ListFAQsCommand |
| Collections | SearchCollectionsCommand, GetCollectionCommand, UpdateCollectionCommand |
| Orders | SearchOrdersCommand, GetOrderCommand, GetOrderEventsCommand |
| Files | SearchImagesCommand, GetImageCommand, GetVideoCommand, UpdateFileCommand, DeleteFileCommand |
| Products | 16 commands (search/get/create/update/delete/publish + variants/options/media) |
Development
yarn install
yarn build # tsc → dist/
yarn typecheck # tsc --noEmit
yarn codegen # generate src/__generated__/types.ts from the 2026-04 schema
yarn dev # watch modeAdding a new Command
- Create a
.graphqlfile atsrc/commands/<namespace>/<Name>.graphql(named operation, using variables). - Create
<Name>Command.tsextendingCommand<Input, Output>. - Export it from
src/commands/<namespace>/index.ts. - Run
yarn codegen+yarn typecheckto verify against the 2026-04 schema.
Full checklist: see the "Checklist when adding a new Command" section in CLAUDE.md.
Migration from @pintahub/shopify-api
Services using @pintahub/shopify-api should migrate as two PRs each:
- Refactor v1 → v2 signature in the service code (still using the old dependency).
- Swap
@pintahub/shopify-api→@pintahub/shopify-next, replacenew AdminAPI(...)→new ShopifyClient(storeId)andadmin.x.y(...)→client.send(new YCommand(...)).
Important: three v1 mutations were removed by Shopify in 2026-04 — there is no *LegacyCommand shim, services must refactor:
| v1 (removed) | v2 (use this) |
|---|---|
| productCreate(input: ProductInput!) | productCreate(product: ProductCreateInput, media) |
| productUpdate(input: ProductInput!) | productUpdate(product: ProductUpdateInput, media) |
| productVariantUpdate | productVariantsBulkUpdate |
Concrete before/after diffs for each operation: docs/migration-guide.md.
Documentation
| File | Contents |
|---|---|
| CLAUDE.md | Project context for Claude Code — read before editing code |
| docs/admin-api-inventory.md | Inventory of 36 operations used across services |
| docs/admin-api-details.md | Input/Output schema + GraphQL SDL for every legacy operation |
| docs/api-shape-options.md | 3 design options + rationale for choosing Command pattern |
| docs/migration-verification.md | 6 verification approaches + schema diff results |
| docs/migration-guide.md | Before/after diff for every reimplemented operation |
| docs/schema-2026-04.graphql | Shopify Admin schema snapshot, codegen input |
