chub-dev 0.1.0 → 0.1.2-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -0
- package/bin/chub-mcp +2 -0
- package/dist/airtable/docs/database/javascript/DOC.md +1437 -0
- package/dist/airtable/docs/database/python/DOC.md +1735 -0
- package/dist/amplitude/docs/analytics/javascript/DOC.md +1282 -0
- package/dist/amplitude/docs/analytics/python/DOC.md +1199 -0
- package/dist/anthropic/docs/claude-api/javascript/DOC.md +503 -0
- package/dist/anthropic/docs/claude-api/python/DOC.md +389 -0
- package/dist/asana/docs/tasks/DOC.md +1396 -0
- package/dist/assemblyai/docs/transcription/DOC.md +1043 -0
- package/dist/atlassian/docs/confluence/javascript/DOC.md +1347 -0
- package/dist/atlassian/docs/confluence/python/DOC.md +1604 -0
- package/dist/auth0/docs/identity/javascript/DOC.md +968 -0
- package/dist/auth0/docs/identity/python/DOC.md +1199 -0
- package/dist/aws/docs/s3/javascript/DOC.md +1773 -0
- package/dist/aws/docs/s3/python/DOC.md +1807 -0
- package/dist/binance/docs/trading/javascript/DOC.md +1315 -0
- package/dist/binance/docs/trading/python/DOC.md +1454 -0
- package/dist/braintree/docs/gateway/javascript/DOC.md +1278 -0
- package/dist/braintree/docs/gateway/python/DOC.md +1179 -0
- package/dist/chromadb/docs/embeddings-db/javascript/DOC.md +1263 -0
- package/dist/chromadb/docs/embeddings-db/python/DOC.md +1707 -0
- package/dist/clerk/docs/auth/javascript/DOC.md +1220 -0
- package/dist/clerk/docs/auth/python/DOC.md +274 -0
- package/dist/cloudflare/docs/workers/javascript/DOC.md +918 -0
- package/dist/cloudflare/docs/workers/python/DOC.md +994 -0
- package/dist/cockroachdb/docs/distributed-db/DOC.md +1500 -0
- package/dist/cohere/docs/llm/DOC.md +1335 -0
- package/dist/datadog/docs/monitoring/javascript/DOC.md +1740 -0
- package/dist/datadog/docs/monitoring/python/DOC.md +1815 -0
- package/dist/deepgram/docs/speech/javascript/DOC.md +885 -0
- package/dist/deepgram/docs/speech/python/DOC.md +685 -0
- package/dist/deepl/docs/translation/javascript/DOC.md +887 -0
- package/dist/deepl/docs/translation/python/DOC.md +944 -0
- package/dist/deepseek/docs/llm/DOC.md +1220 -0
- package/dist/directus/docs/headless-cms/javascript/DOC.md +1128 -0
- package/dist/directus/docs/headless-cms/python/DOC.md +1276 -0
- package/dist/discord/docs/bot/javascript/DOC.md +1090 -0
- package/dist/discord/docs/bot/python/DOC.md +1130 -0
- package/dist/elasticsearch/docs/search/DOC.md +1634 -0
- package/dist/elevenlabs/docs/text-to-speech/javascript/DOC.md +336 -0
- package/dist/elevenlabs/docs/text-to-speech/python/DOC.md +552 -0
- package/dist/firebase/docs/auth/DOC.md +1015 -0
- package/dist/gemini/docs/genai/javascript/DOC.md +691 -0
- package/dist/gemini/docs/genai/python/DOC.md +555 -0
- package/dist/github/docs/octokit/DOC.md +1560 -0
- package/dist/google/docs/bigquery/javascript/DOC.md +1688 -0
- package/dist/google/docs/bigquery/python/DOC.md +1503 -0
- package/dist/hubspot/docs/crm/javascript/DOC.md +1805 -0
- package/dist/hubspot/docs/crm/python/DOC.md +2033 -0
- package/dist/huggingface/docs/transformers/DOC.md +948 -0
- package/dist/intercom/docs/messaging/javascript/DOC.md +1844 -0
- package/dist/intercom/docs/messaging/python/DOC.md +1797 -0
- package/dist/jira/docs/issues/javascript/DOC.md +1420 -0
- package/dist/jira/docs/issues/python/DOC.md +1492 -0
- package/dist/kafka/docs/streaming/javascript/DOC.md +1671 -0
- package/dist/kafka/docs/streaming/python/DOC.md +1464 -0
- package/dist/landingai-ade/docs/api/DOC.md +620 -0
- package/dist/landingai-ade/docs/sdk/python/DOC.md +489 -0
- package/dist/landingai-ade/docs/sdk/typescript/DOC.md +542 -0
- package/dist/landingai-ade/skills/SKILL.md +489 -0
- package/dist/launchdarkly/docs/feature-flags/javascript/DOC.md +1191 -0
- package/dist/launchdarkly/docs/feature-flags/python/DOC.md +1671 -0
- package/dist/linear/docs/tracker/DOC.md +1554 -0
- package/dist/livekit/docs/realtime/javascript/DOC.md +303 -0
- package/dist/livekit/docs/realtime/python/DOC.md +163 -0
- package/dist/mailchimp/docs/marketing/DOC.md +1420 -0
- package/dist/meilisearch/docs/search/DOC.md +1241 -0
- package/dist/microsoft/docs/onedrive/javascript/DOC.md +1421 -0
- package/dist/microsoft/docs/onedrive/python/DOC.md +1549 -0
- package/dist/mongodb/docs/atlas/DOC.md +2041 -0
- package/dist/notion/docs/workspace-api/javascript/DOC.md +1435 -0
- package/dist/notion/docs/workspace-api/python/DOC.md +1400 -0
- package/dist/okta/docs/identity/javascript/DOC.md +1171 -0
- package/dist/okta/docs/identity/python/DOC.md +1401 -0
- package/dist/openai/docs/chat/javascript/DOC.md +407 -0
- package/dist/openai/docs/chat/python/DOC.md +568 -0
- package/dist/paypal/docs/checkout/DOC.md +278 -0
- package/dist/pinecone/docs/sdk/javascript/DOC.md +984 -0
- package/dist/pinecone/docs/sdk/python/DOC.md +1395 -0
- package/dist/plaid/docs/banking/javascript/DOC.md +1163 -0
- package/dist/plaid/docs/banking/python/DOC.md +1203 -0
- package/dist/playwright-community/skills/login-flows/SKILL.md +108 -0
- package/dist/postmark/docs/transactional-email/DOC.md +1168 -0
- package/dist/prisma/docs/orm/javascript/DOC.md +1419 -0
- package/dist/prisma/docs/orm/python/DOC.md +1317 -0
- package/dist/qdrant/docs/vector-search/javascript/DOC.md +1221 -0
- package/dist/qdrant/docs/vector-search/python/DOC.md +1653 -0
- package/dist/rabbitmq/docs/message-queue/javascript/DOC.md +1193 -0
- package/dist/rabbitmq/docs/message-queue/python/DOC.md +1243 -0
- package/dist/razorpay/docs/payments/javascript/DOC.md +1219 -0
- package/dist/razorpay/docs/payments/python/DOC.md +1330 -0
- package/dist/redis/docs/key-value/javascript/DOC.md +1851 -0
- package/dist/redis/docs/key-value/python/DOC.md +2054 -0
- package/dist/registry.json +2817 -0
- package/dist/replicate/docs/model-hosting/DOC.md +1318 -0
- package/dist/resend/docs/email/DOC.md +1271 -0
- package/dist/salesforce/docs/crm/javascript/DOC.md +1241 -0
- package/dist/salesforce/docs/crm/python/DOC.md +1183 -0
- package/dist/search-index.json +1 -0
- package/dist/sendgrid/docs/email-api/javascript/DOC.md +371 -0
- package/dist/sendgrid/docs/email-api/python/DOC.md +656 -0
- package/dist/sentry/docs/error-tracking/javascript/DOC.md +1073 -0
- package/dist/sentry/docs/error-tracking/python/DOC.md +1309 -0
- package/dist/shopify/docs/storefront/DOC.md +457 -0
- package/dist/slack/docs/workspace/javascript/DOC.md +933 -0
- package/dist/slack/docs/workspace/python/DOC.md +271 -0
- package/dist/square/docs/payments/javascript/DOC.md +1855 -0
- package/dist/square/docs/payments/python/DOC.md +1728 -0
- package/dist/stripe/docs/api/DOC.md +1727 -0
- package/dist/stripe/docs/payments/DOC.md +1726 -0
- package/dist/stytch/docs/auth/javascript/DOC.md +1813 -0
- package/dist/stytch/docs/auth/python/DOC.md +1962 -0
- package/dist/supabase/docs/client/DOC.md +1606 -0
- package/dist/twilio/docs/messaging/python/DOC.md +469 -0
- package/dist/twilio/docs/messaging/typescript/DOC.md +946 -0
- package/dist/vercel/docs/platform/DOC.md +1940 -0
- package/dist/weaviate/docs/vector-db/javascript/DOC.md +1268 -0
- package/dist/weaviate/docs/vector-db/python/DOC.md +1388 -0
- package/dist/zendesk/docs/support/javascript/DOC.md +2150 -0
- package/dist/zendesk/docs/support/python/DOC.md +2297 -0
- package/package.json +22 -6
- package/skills/get-api-docs/SKILL.md +84 -0
- package/src/commands/annotate.js +83 -0
- package/src/commands/build.js +12 -1
- package/src/commands/feedback.js +150 -0
- package/src/commands/get.js +83 -42
- package/src/commands/search.js +7 -0
- package/src/index.js +43 -17
- package/src/lib/analytics.js +90 -0
- package/src/lib/annotations.js +57 -0
- package/src/lib/bm25.js +170 -0
- package/src/lib/cache.js +69 -6
- package/src/lib/config.js +8 -3
- package/src/lib/identity.js +99 -0
- package/src/lib/registry.js +103 -20
- package/src/lib/telemetry.js +86 -0
- package/src/mcp/server.js +177 -0
- package/src/mcp/tools.js +251 -0
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: storefront
|
|
3
|
+
description: "Shopify Storefront API library for building ecommerce integrations with OAuth and the official JavaScript SDK"
|
|
4
|
+
metadata:
|
|
5
|
+
languages: "javascript"
|
|
6
|
+
versions: "12.1.0"
|
|
7
|
+
updated-on: "2026-03-01"
|
|
8
|
+
source: maintainer
|
|
9
|
+
tags: "shopify,storefront,ecommerce,api,oauth"
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Shopify API Library - Comprehensive Coding Guide
|
|
13
|
+
|
|
14
|
+
## 1. Golden Rule
|
|
15
|
+
|
|
16
|
+
**Always use the official `@shopify/shopify-api` package.**
|
|
17
|
+
|
|
18
|
+
**Installation command:**
|
|
19
|
+
```bash
|
|
20
|
+
pnpm add @shopify/shopify-api
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
**Warning:** Do not use deprecated packages like `shopify-api-node` or unofficial alternatives. This library is the official TypeScript/JavaScript SDK for Shopify's Admin API.
|
|
24
|
+
|
|
25
|
+
## 2. Installation
|
|
26
|
+
|
|
27
|
+
### Package Installation
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# npm
|
|
31
|
+
npm install @shopify/shopify-api
|
|
32
|
+
|
|
33
|
+
# yarn
|
|
34
|
+
yarn add @shopify/shopify-api
|
|
35
|
+
|
|
36
|
+
# pnpm (recommended)
|
|
37
|
+
pnpm add @shopify/shopify-api
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Environment Variables
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# Required environment variables
|
|
44
|
+
SHOPIFY_API_KEY=your_api_key_from_partners_dashboard
|
|
45
|
+
SHOPIFY_API_SECRET=your_api_secret_from_partners_dashboard
|
|
46
|
+
SHOPIFY_APP_URL=https://your-app-domain.com
|
|
47
|
+
SHOPIFY_SCOPES=read_products,write_products
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## 3. Initialization
|
|
51
|
+
|
|
52
|
+
### Runtime Adapter Import (Required First Step)
|
|
53
|
+
|
|
54
|
+
**Critical:** Import the appropriate runtime adapter before using the library.
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
// Node.js
|
|
58
|
+
import '@shopify/shopify-api/adapters/node';
|
|
59
|
+
|
|
60
|
+
// Cloudflare Workers
|
|
61
|
+
import '@shopify/shopify-api/adapters/cf-worker';
|
|
62
|
+
|
|
63
|
+
// Web API (generic runtimes)
|
|
64
|
+
import '@shopify/shopify-api/adapters/web-api';
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Basic Configuration
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
import '@shopify/shopify-api/adapters/node';
|
|
71
|
+
import { shopifyApi, ApiVersion } from '@shopify/shopify-api';
|
|
72
|
+
|
|
73
|
+
const shopify = shopifyApi({
|
|
74
|
+
apiKey: process.env.SHOPIFY_API_KEY,
|
|
75
|
+
apiSecretKey: process.env.SHOPIFY_API_SECRET,
|
|
76
|
+
scopes: ['read_products', 'write_products'],
|
|
77
|
+
hostName: process.env.SHOPIFY_APP_URL,
|
|
78
|
+
apiVersion: ApiVersion.July25,
|
|
79
|
+
});
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Custom Store App Configuration
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
const shopify = shopifyApi({
|
|
86
|
+
apiSecretKey: "App_API_secret_key",
|
|
87
|
+
apiVersion: ApiVersion.April23,
|
|
88
|
+
isCustomStoreApp: true,
|
|
89
|
+
adminApiAccessToken: "Admin_API_Access_Token",
|
|
90
|
+
isEmbeddedApp: false,
|
|
91
|
+
hostName: "my-shop.myshopify.com",
|
|
92
|
+
});
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## 4. Core API Surfaces
|
|
96
|
+
|
|
97
|
+
### Authentication & OAuth
|
|
98
|
+
|
|
99
|
+
#### Minimal Example - Begin OAuth
|
|
100
|
+
```typescript
|
|
101
|
+
await shopify.auth.begin({
|
|
102
|
+
shop: 'my-shop.myshopify.com',
|
|
103
|
+
callbackPath: '/auth/callback',
|
|
104
|
+
isOnline: true,
|
|
105
|
+
rawRequest: req,
|
|
106
|
+
rawResponse: res,
|
|
107
|
+
});
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
#### Advanced Example - OAuth Callback
|
|
111
|
+
```typescript
|
|
112
|
+
const callbackResponse = await shopify.auth.callback({
|
|
113
|
+
rawRequest: req,
|
|
114
|
+
rawResponse: res,
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
const { session } = callbackResponse;
|
|
118
|
+
// Store session for future API calls
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### REST API Client
|
|
122
|
+
|
|
123
|
+
#### Minimal Example
|
|
124
|
+
```typescript
|
|
125
|
+
const client = new shopify.clients.Rest({ session });
|
|
126
|
+
const response = await client.get({
|
|
127
|
+
path: 'products',
|
|
128
|
+
});
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
#### Advanced Example with REST Resources
|
|
132
|
+
```typescript
|
|
133
|
+
import { restResources } from '@shopify/shopify-api/rest/admin/2023-07';
|
|
134
|
+
|
|
135
|
+
const shopify = shopifyApi({
|
|
136
|
+
// ... other config
|
|
137
|
+
restResources,
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
// Using REST resources
|
|
141
|
+
const products = await shopify.rest.Product.all({
|
|
142
|
+
session,
|
|
143
|
+
limit: 50,
|
|
144
|
+
status: 'active',
|
|
145
|
+
});
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### GraphQL API Client
|
|
149
|
+
|
|
150
|
+
#### Minimal Example
|
|
151
|
+
```typescript
|
|
152
|
+
const client = new shopify.clients.Graphql({ session });
|
|
153
|
+
const response = await client.request(`
|
|
154
|
+
query getProducts($first: Int!) {
|
|
155
|
+
products(first: $first) {
|
|
156
|
+
edges {
|
|
157
|
+
node {
|
|
158
|
+
id
|
|
159
|
+
title
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
`, {
|
|
165
|
+
variables: { first: 10 }
|
|
166
|
+
});
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
#### Advanced Example with Types
|
|
170
|
+
```typescript
|
|
171
|
+
const response = await client.request(
|
|
172
|
+
`#graphql
|
|
173
|
+
query productHandles($first: Int!) {
|
|
174
|
+
products(first: $first) {
|
|
175
|
+
edges {
|
|
176
|
+
node {
|
|
177
|
+
handle
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}`,
|
|
182
|
+
{
|
|
183
|
+
variables: {
|
|
184
|
+
first: 10,
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
);
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Webhooks
|
|
191
|
+
|
|
192
|
+
#### Minimal Example - Registration
|
|
193
|
+
```typescript
|
|
194
|
+
await shopify.webhooks.register({
|
|
195
|
+
session,
|
|
196
|
+
});
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
#### Advanced Example - Processing
|
|
200
|
+
```typescript
|
|
201
|
+
const handleWebhookRequest = async (
|
|
202
|
+
topic: string,
|
|
203
|
+
shop: string,
|
|
204
|
+
webhookRequestBody: string,
|
|
205
|
+
webhookId: string,
|
|
206
|
+
apiVersion: string,
|
|
207
|
+
) => {
|
|
208
|
+
// Process webhook event
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
shopify.webhooks.addHandlers({
|
|
212
|
+
PRODUCTS_CREATE: [
|
|
213
|
+
{
|
|
214
|
+
deliveryMethod: DeliveryMethod.Http,
|
|
215
|
+
callbackUrl: '/webhooks',
|
|
216
|
+
callback: handleWebhookRequest,
|
|
217
|
+
},
|
|
218
|
+
],
|
|
219
|
+
});
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Billing
|
|
223
|
+
|
|
224
|
+
#### Minimal Example - Check Billing
|
|
225
|
+
```typescript
|
|
226
|
+
const billingCheck = await shopify.billing.check({
|
|
227
|
+
session,
|
|
228
|
+
plans: ['Basic Plan'],
|
|
229
|
+
isTest: true,
|
|
230
|
+
});
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
#### Advanced Example - Request Payment
|
|
234
|
+
```typescript
|
|
235
|
+
const billingResponse = await shopify.billing.request({
|
|
236
|
+
session,
|
|
237
|
+
plan: 'Premium Plan',
|
|
238
|
+
isTest: true,
|
|
239
|
+
returnUrl: 'https://myapp.com/billing/callback',
|
|
240
|
+
});
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
## 5. Advanced Features
|
|
244
|
+
|
|
245
|
+
### Error Handling
|
|
246
|
+
|
|
247
|
+
```typescript
|
|
248
|
+
import {
|
|
249
|
+
ShopifyError,
|
|
250
|
+
HttpResponseError,
|
|
251
|
+
BillingError
|
|
252
|
+
} from '@shopify/shopify-api';
|
|
253
|
+
|
|
254
|
+
try {
|
|
255
|
+
const response = await client.request(query);
|
|
256
|
+
} catch (error) {
|
|
257
|
+
if (error instanceof HttpResponseError) {
|
|
258
|
+
console.log('HTTP Error:', error.response.status);
|
|
259
|
+
} else if (error instanceof BillingError) {
|
|
260
|
+
console.log('Billing Error:', error.message);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### Retries and Timeouts
|
|
266
|
+
|
|
267
|
+
```typescript
|
|
268
|
+
const client = new shopify.clients.Graphql({
|
|
269
|
+
session,
|
|
270
|
+
retries: 3,
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
const response = await client.request(query, {
|
|
274
|
+
retries: 2,
|
|
275
|
+
});
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### Logging and Debugging
|
|
279
|
+
|
|
280
|
+
```typescript
|
|
281
|
+
const shopify = shopifyApi({
|
|
282
|
+
// ... other config
|
|
283
|
+
logger: {
|
|
284
|
+
level: LogSeverity.Debug,
|
|
285
|
+
timestamps: true,
|
|
286
|
+
httpRequests: true,
|
|
287
|
+
log: async (severity, message) => {
|
|
288
|
+
console.log(`[${severity}] ${message}`);
|
|
289
|
+
},
|
|
290
|
+
},
|
|
291
|
+
});
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### Pagination
|
|
295
|
+
|
|
296
|
+
```typescript
|
|
297
|
+
let pageInfo;
|
|
298
|
+
do {
|
|
299
|
+
const response = await shopify.rest.Product.all({
|
|
300
|
+
...pageInfo?.nextPage?.query,
|
|
301
|
+
session,
|
|
302
|
+
limit: 10,
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
const pageProducts = response.data;
|
|
306
|
+
pageInfo = response.pageInfo;
|
|
307
|
+
} while (pageInfo?.nextPage);
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
## 6. TypeScript Usage
|
|
311
|
+
|
|
312
|
+
### Type Imports
|
|
313
|
+
|
|
314
|
+
```typescript
|
|
315
|
+
import {
|
|
316
|
+
Session,
|
|
317
|
+
ApiVersion,
|
|
318
|
+
BillingInterval,
|
|
319
|
+
DeliveryMethod,
|
|
320
|
+
LogSeverity,
|
|
321
|
+
} from '@shopify/shopify-api';
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
### Type-Safe GraphQL
|
|
325
|
+
|
|
326
|
+
```typescript
|
|
327
|
+
// Install codegen preset
|
|
328
|
+
// pnpm add --save-dev @shopify/api-codegen-preset
|
|
329
|
+
|
|
330
|
+
// After running graphql-codegen, queries are automatically typed
|
|
331
|
+
const response = await client.request(
|
|
332
|
+
`#graphql
|
|
333
|
+
query getProduct($id: ID!) {
|
|
334
|
+
product(id: $id) {
|
|
335
|
+
id
|
|
336
|
+
title
|
|
337
|
+
handle
|
|
338
|
+
}
|
|
339
|
+
}`,
|
|
340
|
+
{
|
|
341
|
+
variables: { id: "gid://shopify/Product/123" }
|
|
342
|
+
}
|
|
343
|
+
);
|
|
344
|
+
|
|
345
|
+
// response.data.product is now fully typed
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
### Session Types
|
|
349
|
+
|
|
350
|
+
```typescript
|
|
351
|
+
const session: Session = {
|
|
352
|
+
id: 'session-id',
|
|
353
|
+
shop: 'my-shop.myshopify.com',
|
|
354
|
+
state: 'state-value',
|
|
355
|
+
isOnline: true,
|
|
356
|
+
accessToken: 'access-token',
|
|
357
|
+
scope: 'read_products,write_products',
|
|
358
|
+
};
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
## 7. Best Practices
|
|
362
|
+
|
|
363
|
+
### Session Management
|
|
364
|
+
|
|
365
|
+
```typescript
|
|
366
|
+
// Always validate sessions before API calls
|
|
367
|
+
const sessionId = await shopify.session.getCurrentId({
|
|
368
|
+
isOnline: true,
|
|
369
|
+
rawRequest: req,
|
|
370
|
+
rawResponse: res,
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
const session = await getSessionFromStorage(sessionId);
|
|
374
|
+
if (!session) {
|
|
375
|
+
// Redirect to OAuth
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
### Rate Limit Handling
|
|
381
|
+
|
|
382
|
+
```typescript
|
|
383
|
+
// Use built-in retry logic
|
|
384
|
+
const client = new shopify.clients.Graphql({
|
|
385
|
+
session,
|
|
386
|
+
retries: 3, // Will retry on rate limit errors
|
|
387
|
+
});
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
### Custom Store Apps
|
|
391
|
+
|
|
392
|
+
```typescript
|
|
393
|
+
// For custom store apps, create sessions manually
|
|
394
|
+
const session = shopify.session.customAppSession("my-shop.myshopify.com");
|
|
395
|
+
|
|
396
|
+
const productCount = await shopify.rest.Product.count({ session });
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
## 8. Production Checklist
|
|
400
|
+
|
|
401
|
+
### Pin SDK Version
|
|
402
|
+
|
|
403
|
+
```json
|
|
404
|
+
{
|
|
405
|
+
"dependencies": {
|
|
406
|
+
"@shopify/shopify-api": "^12.0.0"
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
### Robust Error Handling
|
|
412
|
+
|
|
413
|
+
```typescript
|
|
414
|
+
try {
|
|
415
|
+
const response = await client.request(query);
|
|
416
|
+
return response.data;
|
|
417
|
+
} catch (error) {
|
|
418
|
+
if (error instanceof HttpResponseError) {
|
|
419
|
+
// Log and handle HTTP errors
|
|
420
|
+
logger.error('API Error:', error.response.status);
|
|
421
|
+
throw new Error('API request failed');
|
|
422
|
+
}
|
|
423
|
+
throw error;
|
|
424
|
+
}
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
### Environment Configuration
|
|
428
|
+
|
|
429
|
+
```typescript
|
|
430
|
+
const shopify = shopifyApi({
|
|
431
|
+
apiKey: process.env.SHOPIFY_API_KEY!,
|
|
432
|
+
apiSecretKey: process.env.SHOPIFY_API_SECRET!,
|
|
433
|
+
scopes: process.env.SHOPIFY_SCOPES!.split(','),
|
|
434
|
+
hostName: process.env.SHOPIFY_APP_URL!,
|
|
435
|
+
apiVersion: ApiVersion.July25, // Use stable versions
|
|
436
|
+
logger: {
|
|
437
|
+
level: process.env.NODE_ENV === 'production'
|
|
438
|
+
? LogSeverity.Error
|
|
439
|
+
: LogSeverity.Debug,
|
|
440
|
+
},
|
|
441
|
+
});
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
### Webhook Security
|
|
445
|
+
|
|
446
|
+
```typescript
|
|
447
|
+
// Always validate webhook HMAC
|
|
448
|
+
await shopify.webhooks.process({
|
|
449
|
+
rawBody: req.body,
|
|
450
|
+
rawRequest: req,
|
|
451
|
+
rawResponse: res,
|
|
452
|
+
});
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
## Notes
|
|
456
|
+
|
|
457
|
+
This guide covers the `@shopify/shopify-api` library which provides comprehensive TypeScript/JavaScript support for Shopify's Admin API, including OAuth flows, REST/GraphQL clients, webhook processing, and billing functionality. The library uses a factory pattern centered around `shopifyApi()` and requires runtime adapters for cross-platform compatibility.
|