@ekomerc/storefront 0.1.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 +452 -0
- package/dist/errors.cjs +60 -0
- package/dist/errors.cjs.map +1 -0
- package/dist/errors.d.ts +80 -0
- package/dist/errors.js +60 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.cjs +3266 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +952 -0
- package/dist/index.js +3267 -0
- package/dist/index.js.map +1 -0
- package/dist/types.cjs +2 -0
- package/dist/types.cjs.map +1 -0
- package/dist/types.d.ts +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +68 -0
package/README.md
ADDED
|
@@ -0,0 +1,452 @@
|
|
|
1
|
+
# @ekomerc/storefront
|
|
2
|
+
|
|
3
|
+
TypeScript SDK for building headless storefronts with ekomerc. Provides typed helpers for products, collections, cart, and checkout operations.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @ekomerc/storefront
|
|
9
|
+
# or
|
|
10
|
+
npm install @ekomerc/storefront
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import { createStorefrontClient } from "@ekomerc/storefront";
|
|
17
|
+
|
|
18
|
+
const client = createStorefrontClient({
|
|
19
|
+
endpoint: "https://api.yourstore.com/graphql",
|
|
20
|
+
apiKey: "sfk_your_api_key",
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
// Fetch products
|
|
24
|
+
const result = await client.products.list({ first: 10, filter: { search: "shirt" } });
|
|
25
|
+
if (result.isOk()) {
|
|
26
|
+
console.log(result.value.items);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Add to cart (variantId is the GID from product queries, e.g. variant.id)
|
|
30
|
+
await client.cart.create();
|
|
31
|
+
const addResult = await client.cart.addItem(variant.id, 1);
|
|
32
|
+
if (addResult.isOk()) {
|
|
33
|
+
console.log("Added to cart:", addResult.value);
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Configuration
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
interface StorefrontClientConfig {
|
|
41
|
+
endpoint: string; // Full Storefront GraphQL URL (absolute)
|
|
42
|
+
apiKey: string; // API key (sfk_...)
|
|
43
|
+
storage?: StorageAdapter; // Cart token storage (default: auto-detect)
|
|
44
|
+
cacheTTL?: number; // Query cache TTL in ms (default: 5 minutes)
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Custom Endpoint URLs
|
|
49
|
+
|
|
50
|
+
`endpoint` is used exactly as provided. The SDK sends `POST` requests directly to that URL and does not rewrite hosts or paths.
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
const client = createStorefrontClient({
|
|
54
|
+
endpoint: "https://edge.example.com/custom/storefront/v1/graphql",
|
|
55
|
+
apiKey: "sfk_test_placeholder",
|
|
56
|
+
});
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Supported examples:
|
|
60
|
+
- `https://api.example.com/graphql`
|
|
61
|
+
- `https://edge.example.com/custom/storefront/v1/graphql`
|
|
62
|
+
- `https://staging.example.net/gql/storefront`
|
|
63
|
+
|
|
64
|
+
### Auth And Request Headers
|
|
65
|
+
|
|
66
|
+
For each request the SDK sends:
|
|
67
|
+
- `content-type: application/json`
|
|
68
|
+
- `x-storefront-key: <apiKey>` (always)
|
|
69
|
+
- `x-cart-token: <cartToken>` (when cart token exists)
|
|
70
|
+
- `authorization: Bearer <customerToken>` (when customer token exists)
|
|
71
|
+
|
|
72
|
+
### Storage Adapters
|
|
73
|
+
|
|
74
|
+
The SDK stores the cart token to persist the cart across page loads.
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
import {
|
|
78
|
+
createStorefrontClient,
|
|
79
|
+
createLocalStorageAdapter, // Browser localStorage
|
|
80
|
+
createMemoryAdapter, // In-memory (SSR/testing)
|
|
81
|
+
createDefaultAdapter, // Auto-detects environment
|
|
82
|
+
} from "@ekomerc/storefront";
|
|
83
|
+
|
|
84
|
+
// Browser (default)
|
|
85
|
+
const client = createStorefrontClient({
|
|
86
|
+
endpoint: "https://api.yourstore.com/graphql",
|
|
87
|
+
apiKey: "sfk_...",
|
|
88
|
+
// Uses localStorage by default in browser
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
// SSR / Server-side
|
|
92
|
+
const client = createStorefrontClient({
|
|
93
|
+
endpoint: "https://api.yourstore.com/graphql",
|
|
94
|
+
apiKey: "sfk_...",
|
|
95
|
+
storage: createMemoryAdapter(),
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// Custom storage
|
|
99
|
+
const client = createStorefrontClient({
|
|
100
|
+
endpoint: "https://api.yourstore.com/graphql",
|
|
101
|
+
apiKey: "sfk_...",
|
|
102
|
+
storage: {
|
|
103
|
+
get: (key) => sessionStorage.getItem(key),
|
|
104
|
+
set: (key, value) => sessionStorage.setItem(key, value),
|
|
105
|
+
remove: (key) => sessionStorage.removeItem(key),
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## API Reference
|
|
111
|
+
|
|
112
|
+
All methods return `Promise<Result<T, StorefrontError>>` from [neverthrow](https://github.com/supermacro/neverthrow).
|
|
113
|
+
|
|
114
|
+
### Products
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
// List products with pagination
|
|
118
|
+
const result = await client.products.list({
|
|
119
|
+
first: 10, // Number of products (default: 20)
|
|
120
|
+
after: cursor, // Pagination cursor
|
|
121
|
+
filter: { search: "shirt" }, // Search query
|
|
122
|
+
sort: "BEST_SELLING"
|
|
123
|
+
});
|
|
124
|
+
// Returns: { items: Product[], pageInfo: PageInfo }
|
|
125
|
+
|
|
126
|
+
// Get single product by handle or ID
|
|
127
|
+
const result = await client.products.get("blue-shirt");
|
|
128
|
+
const result = await client.products.get("UHJvZHVjdDoxMjM="); // Global ID
|
|
129
|
+
|
|
130
|
+
// Batch fetch by handles
|
|
131
|
+
const result = await client.products.getByHandles(["shirt-1", "shirt-2"]);
|
|
132
|
+
// Returns: (Product | null)[]
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Collections
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
// List collections
|
|
139
|
+
const result = await client.collections.list({
|
|
140
|
+
first: 10,
|
|
141
|
+
after: cursor,
|
|
142
|
+
search: "summer"
|
|
143
|
+
});
|
|
144
|
+
// Returns: { items: Collection[], pageInfo: PageInfo }
|
|
145
|
+
|
|
146
|
+
// Get single collection
|
|
147
|
+
const result = await client.collections.get("summer-collection");
|
|
148
|
+
|
|
149
|
+
// Get products in a collection
|
|
150
|
+
const result = await client.collections.getProducts("summer-collection", {
|
|
151
|
+
first: 20,
|
|
152
|
+
after: cursor,
|
|
153
|
+
});
|
|
154
|
+
// Returns: { items: Product[], pageInfo: PageInfo }
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Cart
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
// Get current cart (from stored token)
|
|
161
|
+
const result = await client.cart.get();
|
|
162
|
+
// Returns: Cart | null
|
|
163
|
+
|
|
164
|
+
// Create new cart
|
|
165
|
+
const result = await client.cart.create();
|
|
166
|
+
// Returns: Cart
|
|
167
|
+
|
|
168
|
+
// Add item to cart
|
|
169
|
+
// variantId must be a Global ID (GID) — use variant.id from product queries
|
|
170
|
+
const result = await client.cart.addItem(variantId, quantity);
|
|
171
|
+
// Returns: Cart
|
|
172
|
+
|
|
173
|
+
// Update item quantity
|
|
174
|
+
// variantId must be a Global ID (GID) — use variant.id from product queries
|
|
175
|
+
const result = await client.cart.updateItem(variantId, newQuantity);
|
|
176
|
+
// Returns: Cart
|
|
177
|
+
|
|
178
|
+
// Remove item from cart
|
|
179
|
+
// variantId must be a Global ID (GID) — use variant.id from product queries
|
|
180
|
+
const result = await client.cart.removeItem(variantId);
|
|
181
|
+
// Returns: Cart
|
|
182
|
+
|
|
183
|
+
// Clear all items
|
|
184
|
+
const result = await client.cart.clear();
|
|
185
|
+
// Returns: Cart
|
|
186
|
+
|
|
187
|
+
// Apply a promo code
|
|
188
|
+
const result = await client.cart.applyPromoCode("SAVE10");
|
|
189
|
+
if (result.isErr()) {
|
|
190
|
+
// ValidationError with reason (e.g. "Invalid or expired code")
|
|
191
|
+
}
|
|
192
|
+
// Returns: Cart (with appliedPromoCode populated)
|
|
193
|
+
|
|
194
|
+
// Remove applied promo code
|
|
195
|
+
const result = await client.cart.removePromoCode();
|
|
196
|
+
// Returns: Cart (with appliedPromoCode cleared)
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Note: `variantId` in `cart.addItem`, `cart.updateItem`, and `cart.removeItem` must be a GraphQL Global ID (GID), not a raw UUID. Use variant IDs returned by product queries.
|
|
200
|
+
|
|
201
|
+
### Pricing Display
|
|
202
|
+
|
|
203
|
+
Product variants include sale and quantity pricing information:
|
|
204
|
+
|
|
205
|
+
```typescript
|
|
206
|
+
const result = await client.products.get("my-product");
|
|
207
|
+
if (result.isOk()) {
|
|
208
|
+
const variant = result.value.variants[0];
|
|
209
|
+
|
|
210
|
+
// Sale price detection
|
|
211
|
+
if (variant.isOnSale) {
|
|
212
|
+
console.log(`Was: ${variant.compareAtPrice}, Now: ${variant.price}`);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// Quantity tier pricing
|
|
216
|
+
for (const tier of variant.quantityPricing) {
|
|
217
|
+
console.log(`Buy ${tier.minQuantity}+ at ${tier.price}/unit`);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Cart items expose the resolved effective unit price (considering sale + quantity tier):
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
const cart = (await client.cart.get()).unwrapOr(null);
|
|
226
|
+
if (cart) {
|
|
227
|
+
for (const item of cart.items) {
|
|
228
|
+
console.log(`Base price: ${item.price.amount}`);
|
|
229
|
+
console.log(`Effective price: ${item.effectiveUnitPrice.amount}`);
|
|
230
|
+
console.log(`Line total: ${item.totalPrice.amount}`);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Discount information
|
|
234
|
+
console.log(`Discount: ${cart.discountTotal.amount}`);
|
|
235
|
+
if (cart.appliedPromoCode) {
|
|
236
|
+
console.log(`Promo: ${cart.appliedPromoCode.code} (-${cart.appliedPromoCode.discountAmount})`);
|
|
237
|
+
}
|
|
238
|
+
for (const discount of cart.appliedDiscounts) {
|
|
239
|
+
console.log(`${discount.description}: -${discount.discountAmount}`);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### Checkout
|
|
245
|
+
|
|
246
|
+
```typescript
|
|
247
|
+
// Start checkout (transitions cart to checkout state)
|
|
248
|
+
const result = await client.checkout.start();
|
|
249
|
+
// Returns: Cart (with status: "checkout")
|
|
250
|
+
|
|
251
|
+
// Update checkout info
|
|
252
|
+
const result = await client.checkout.update({
|
|
253
|
+
email: "customer@example.com",
|
|
254
|
+
phone: "+381...",
|
|
255
|
+
shippingAddress: {
|
|
256
|
+
firstName: "John",
|
|
257
|
+
lastName: "Doe",
|
|
258
|
+
address1: "123 Main St",
|
|
259
|
+
city: "Belgrade",
|
|
260
|
+
country: "Serbia",
|
|
261
|
+
countryCode: "RS",
|
|
262
|
+
zip: "11000",
|
|
263
|
+
},
|
|
264
|
+
billingAddress: { ... },
|
|
265
|
+
notes: "Leave at door",
|
|
266
|
+
emailMarketingConsent: true,
|
|
267
|
+
});
|
|
268
|
+
// Returns: Cart
|
|
269
|
+
|
|
270
|
+
// Complete checkout (creates order)
|
|
271
|
+
const result = await client.checkout.complete();
|
|
272
|
+
// Returns: Order
|
|
273
|
+
|
|
274
|
+
// Abandon checkout (returns cart to active state)
|
|
275
|
+
const result = await client.checkout.abandon();
|
|
276
|
+
// Returns: Cart
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Cache
|
|
280
|
+
|
|
281
|
+
```typescript
|
|
282
|
+
// Clear the query cache
|
|
283
|
+
client.cache.clear();
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### Cart Token Management
|
|
287
|
+
|
|
288
|
+
```typescript
|
|
289
|
+
// Get current cart token
|
|
290
|
+
const token = client.getCartToken();
|
|
291
|
+
|
|
292
|
+
// Set cart token manually
|
|
293
|
+
client.setCartToken("cart-token-uuid");
|
|
294
|
+
|
|
295
|
+
// Clear cart token
|
|
296
|
+
client.clearCartToken();
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
## Error Handling
|
|
300
|
+
|
|
301
|
+
The SDK uses Result types for error handling. Errors are typed and categorized:
|
|
302
|
+
|
|
303
|
+
```typescript
|
|
304
|
+
import {
|
|
305
|
+
StorefrontError, // Base error class
|
|
306
|
+
NetworkError, // Network/fetch failures
|
|
307
|
+
AuthError, // Invalid/revoked API key
|
|
308
|
+
ValidationError, // Validation errors from mutations
|
|
309
|
+
NotFoundError, // Resource not found
|
|
310
|
+
StateError, // Invalid cart state transition
|
|
311
|
+
GraphQLError, // Unexpected GraphQL errors
|
|
312
|
+
} from "@ekomerc/storefront";
|
|
313
|
+
|
|
314
|
+
const result = await client.products.get("nonexistent");
|
|
315
|
+
|
|
316
|
+
if (result.isErr()) {
|
|
317
|
+
const error = result.error;
|
|
318
|
+
|
|
319
|
+
if (error instanceof NotFoundError) {
|
|
320
|
+
console.log("Product not found");
|
|
321
|
+
} else if (error instanceof AuthError) {
|
|
322
|
+
console.log("Invalid API key");
|
|
323
|
+
} else if (error instanceof StateError) {
|
|
324
|
+
console.log(`Cart state error: ${error.state}`);
|
|
325
|
+
} else if (error instanceof ValidationError) {
|
|
326
|
+
console.log("Validation errors:", error.userErrors);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// Or use pattern matching
|
|
331
|
+
result.match(
|
|
332
|
+
(product) => console.log("Found:", product.title),
|
|
333
|
+
(error) => console.error("Error:", error.message)
|
|
334
|
+
);
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### Troubleshooting Endpoint/Auth Issues
|
|
338
|
+
|
|
339
|
+
1. `AuthError` (`401`/`403`)
|
|
340
|
+
`x-storefront-key` is missing, invalid, revoked, or scoped for a different store. Rotate/regenerate the key and verify the exact value loaded in your runtime env.
|
|
341
|
+
|
|
342
|
+
2. Browser CORS failure
|
|
343
|
+
If browser console shows CORS errors, your API origin must allow your storefront origin and headers:
|
|
344
|
+
`content-type, x-storefront-key, x-cart-token, authorization`.
|
|
345
|
+
|
|
346
|
+
3. Malformed endpoint URL
|
|
347
|
+
Always use a full absolute URL like `https://api.example.com/storefront`. The SDK does not validate the URL at initialization — requests will fail at runtime if the endpoint is malformed.
|
|
348
|
+
|
|
349
|
+
### Cart State Errors
|
|
350
|
+
|
|
351
|
+
Cart operations are only allowed when the cart is in `active` state. Attempting to modify a cart in `checkout`, `converted`, `abandoned`, or `expired` state returns a `StateError`:
|
|
352
|
+
|
|
353
|
+
```typescript
|
|
354
|
+
// Cart is in checkout state
|
|
355
|
+
const result = await client.cart.addItem(variantId, 1);
|
|
356
|
+
|
|
357
|
+
if (result.isErr() && result.error instanceof StateError) {
|
|
358
|
+
console.log(`Cannot modify cart: ${result.error.message}`);
|
|
359
|
+
// "Cannot modify cart in 'checkout' state. Cart operations are only allowed when cart is in 'active' state."
|
|
360
|
+
}
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
## Types
|
|
364
|
+
|
|
365
|
+
All types are exported for TypeScript users:
|
|
366
|
+
|
|
367
|
+
```typescript
|
|
368
|
+
import type {
|
|
369
|
+
// Client
|
|
370
|
+
StorefrontClient,
|
|
371
|
+
StorefrontClientConfig,
|
|
372
|
+
StorageAdapter,
|
|
373
|
+
|
|
374
|
+
// Products
|
|
375
|
+
Product,
|
|
376
|
+
ProductVariant,
|
|
377
|
+
ProductOption,
|
|
378
|
+
ProductImage,
|
|
379
|
+
QuantityPricingTier,
|
|
380
|
+
|
|
381
|
+
// Collections
|
|
382
|
+
Collection,
|
|
383
|
+
|
|
384
|
+
// Cart
|
|
385
|
+
Cart,
|
|
386
|
+
CartItem,
|
|
387
|
+
CartStatus,
|
|
388
|
+
AppliedPromoCode,
|
|
389
|
+
AppliedDiscount,
|
|
390
|
+
|
|
391
|
+
// Checkout
|
|
392
|
+
CheckoutData,
|
|
393
|
+
Address,
|
|
394
|
+
Order,
|
|
395
|
+
|
|
396
|
+
// Pagination
|
|
397
|
+
PageInfo,
|
|
398
|
+
PaginatedResult,
|
|
399
|
+
|
|
400
|
+
// Common
|
|
401
|
+
Money,
|
|
402
|
+
Store,
|
|
403
|
+
} from "@ekomerc/storefront";
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
## SSR / Server-Side Rendering
|
|
407
|
+
|
|
408
|
+
For SSR frameworks (Next.js, Remix, etc.), use the memory adapter on the server:
|
|
409
|
+
|
|
410
|
+
```typescript
|
|
411
|
+
import {
|
|
412
|
+
createStorefrontClient,
|
|
413
|
+
createMemoryAdapter,
|
|
414
|
+
createLocalStorageAdapter,
|
|
415
|
+
} from "@ekomerc/storefront";
|
|
416
|
+
|
|
417
|
+
const client = createStorefrontClient({
|
|
418
|
+
endpoint: process.env.STOREFRONT_API_URL,
|
|
419
|
+
apiKey: process.env.STOREFRONT_API_KEY,
|
|
420
|
+
storage: typeof window === "undefined"
|
|
421
|
+
? createMemoryAdapter()
|
|
422
|
+
: createLocalStorageAdapter(),
|
|
423
|
+
});
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
## React Integration
|
|
427
|
+
|
|
428
|
+
For React applications, use the `@ekomerc/storefront-react` package which provides hooks and context:
|
|
429
|
+
|
|
430
|
+
```typescript
|
|
431
|
+
import { StorefrontProvider, useProducts, useCart } from "@ekomerc/storefront-react";
|
|
432
|
+
|
|
433
|
+
function App() {
|
|
434
|
+
return (
|
|
435
|
+
<StorefrontProvider client={client}>
|
|
436
|
+
<Shop />
|
|
437
|
+
</StorefrontProvider>
|
|
438
|
+
);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
function Shop() {
|
|
442
|
+
const { products, loading, error } = useProducts();
|
|
443
|
+
const { cart, addItem } = useCart();
|
|
444
|
+
// ...
|
|
445
|
+
}
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
See the `@ekomerc/storefront-react` package for full documentation.
|
|
449
|
+
|
|
450
|
+
## License
|
|
451
|
+
|
|
452
|
+
MIT
|
package/dist/errors.cjs
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
class StorefrontError extends Error {
|
|
4
|
+
code;
|
|
5
|
+
constructor(message, code, options) {
|
|
6
|
+
super(message, options);
|
|
7
|
+
this.name = "StorefrontError";
|
|
8
|
+
this.code = code;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
class NetworkError extends StorefrontError {
|
|
12
|
+
constructor(message, options) {
|
|
13
|
+
super(message, "NETWORK_ERROR", options);
|
|
14
|
+
this.name = "NetworkError";
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
class AuthError extends StorefrontError {
|
|
18
|
+
constructor(message, options) {
|
|
19
|
+
super(message, "AUTH_ERROR", options);
|
|
20
|
+
this.name = "AuthError";
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
class ValidationError extends StorefrontError {
|
|
24
|
+
userErrors;
|
|
25
|
+
constructor(message, userErrors, options) {
|
|
26
|
+
super(message, "VALIDATION_ERROR", options);
|
|
27
|
+
this.name = "ValidationError";
|
|
28
|
+
this.userErrors = userErrors;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
class NotFoundError extends StorefrontError {
|
|
32
|
+
constructor(message, options) {
|
|
33
|
+
super(message, "NOT_FOUND", options);
|
|
34
|
+
this.name = "NotFoundError";
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
class StateError extends StorefrontError {
|
|
38
|
+
state;
|
|
39
|
+
constructor(message, state, options) {
|
|
40
|
+
super(message, "STATE_ERROR", options);
|
|
41
|
+
this.name = "StateError";
|
|
42
|
+
this.state = state;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
class GraphQLError extends StorefrontError {
|
|
46
|
+
graphqlErrors;
|
|
47
|
+
constructor(message, graphqlErrors, options) {
|
|
48
|
+
super(message, "GRAPHQL_ERROR", options);
|
|
49
|
+
this.name = "GraphQLError";
|
|
50
|
+
this.graphqlErrors = graphqlErrors;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
exports.AuthError = AuthError;
|
|
54
|
+
exports.GraphQLError = GraphQLError;
|
|
55
|
+
exports.NetworkError = NetworkError;
|
|
56
|
+
exports.NotFoundError = NotFoundError;
|
|
57
|
+
exports.StateError = StateError;
|
|
58
|
+
exports.StorefrontError = StorefrontError;
|
|
59
|
+
exports.ValidationError = ValidationError;
|
|
60
|
+
//# sourceMappingURL=errors.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.cjs","sources":["../src/errors.ts"],"sourcesContent":["/**\n * Base class for all Storefront SDK errors\n */\nexport class StorefrontError extends Error {\n readonly code: string;\n\n constructor(message: string, code: string, options?: { cause?: Error }) {\n super(message, options);\n this.name = \"StorefrontError\";\n this.code = code;\n }\n}\n\n/**\n * Network error - fetch failed, connection issues\n */\nexport class NetworkError extends StorefrontError {\n constructor(message: string, options?: { cause?: Error }) {\n super(message, \"NETWORK_ERROR\", options);\n this.name = \"NetworkError\";\n }\n}\n\n/**\n * Authentication error - invalid/revoked API key, 401/403 responses\n */\nexport class AuthError extends StorefrontError {\n constructor(message: string, options?: { cause?: Error }) {\n super(message, \"AUTH_ERROR\", options);\n this.name = \"AuthError\";\n }\n}\n\n/**\n * Validation error - userErrors from mutations\n */\nexport class ValidationError extends StorefrontError {\n readonly userErrors: Array<{ field: string | null; message: string }>;\n\n constructor(\n message: string,\n userErrors: Array<{ field: string | null; message: string }>,\n options?: { cause?: Error },\n ) {\n super(message, \"VALIDATION_ERROR\", options);\n this.name = \"ValidationError\";\n this.userErrors = userErrors;\n }\n}\n\n/**\n * Not found error - resource doesn't exist\n */\nexport class NotFoundError extends StorefrontError {\n constructor(message: string, options?: { cause?: Error }) {\n super(message, \"NOT_FOUND\", options);\n this.name = \"NotFoundError\";\n }\n}\n\n/**\n * State error - invalid cart state transition\n */\nexport class StateError extends StorefrontError {\n readonly state: string;\n\n constructor(message: string, state: string, options?: { cause?: Error }) {\n super(message, \"STATE_ERROR\", options);\n this.name = \"StateError\";\n this.state = state;\n }\n}\n\n/**\n * GraphQL error - unexpected GraphQL errors\n */\nexport class GraphQLError extends StorefrontError {\n readonly graphqlErrors: Array<{ message: string; path?: readonly (string | number)[] }>;\n\n constructor(\n message: string,\n graphqlErrors: Array<{ message: string; path?: readonly (string | number)[] }>,\n options?: { cause?: Error },\n ) {\n super(message, \"GRAPHQL_ERROR\", options);\n this.name = \"GraphQLError\";\n this.graphqlErrors = graphqlErrors;\n }\n}\n"],"names":[],"mappings":";;AAGO,MAAM,wBAAwB,MAAM;AAAA,EAChC;AAAA,EAET,YAAY,SAAiB,MAAc,SAA6B;AACtE,UAAM,SAAS,OAAO;AACtB,SAAK,OAAO;AACZ,SAAK,OAAO;AAAA,EACd;AACF;AAKO,MAAM,qBAAqB,gBAAgB;AAAA,EAChD,YAAY,SAAiB,SAA6B;AACxD,UAAM,SAAS,iBAAiB,OAAO;AACvC,SAAK,OAAO;AAAA,EACd;AACF;AAKO,MAAM,kBAAkB,gBAAgB;AAAA,EAC7C,YAAY,SAAiB,SAA6B;AACxD,UAAM,SAAS,cAAc,OAAO;AACpC,SAAK,OAAO;AAAA,EACd;AACF;AAKO,MAAM,wBAAwB,gBAAgB;AAAA,EAC1C;AAAA,EAET,YACE,SACA,YACA,SACA;AACA,UAAM,SAAS,oBAAoB,OAAO;AAC1C,SAAK,OAAO;AACZ,SAAK,aAAa;AAAA,EACpB;AACF;AAKO,MAAM,sBAAsB,gBAAgB;AAAA,EACjD,YAAY,SAAiB,SAA6B;AACxD,UAAM,SAAS,aAAa,OAAO;AACnC,SAAK,OAAO;AAAA,EACd;AACF;AAKO,MAAM,mBAAmB,gBAAgB;AAAA,EACrC;AAAA,EAET,YAAY,SAAiB,OAAe,SAA6B;AACvE,UAAM,SAAS,eAAe,OAAO;AACrC,SAAK,OAAO;AACZ,SAAK,QAAQ;AAAA,EACf;AACF;AAKO,MAAM,qBAAqB,gBAAgB;AAAA,EACvC;AAAA,EAET,YACE,SACA,eACA,SACA;AACA,UAAM,SAAS,iBAAiB,OAAO;AACvC,SAAK,OAAO;AACZ,SAAK,gBAAgB;AAAA,EACvB;AACF;;;;;;;;"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authentication error - invalid/revoked API key, 401/403 responses
|
|
3
|
+
*/
|
|
4
|
+
export declare class AuthError extends StorefrontError {
|
|
5
|
+
constructor(message: string, options?: {
|
|
6
|
+
cause?: Error;
|
|
7
|
+
});
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* GraphQL error - unexpected GraphQL errors
|
|
12
|
+
*/
|
|
13
|
+
export declare class GraphQLError extends StorefrontError {
|
|
14
|
+
readonly graphqlErrors: Array<{
|
|
15
|
+
message: string;
|
|
16
|
+
path?: readonly (string | number)[];
|
|
17
|
+
}>;
|
|
18
|
+
constructor(message: string, graphqlErrors: Array<{
|
|
19
|
+
message: string;
|
|
20
|
+
path?: readonly (string | number)[];
|
|
21
|
+
}>, options?: {
|
|
22
|
+
cause?: Error;
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Network error - fetch failed, connection issues
|
|
28
|
+
*/
|
|
29
|
+
export declare class NetworkError extends StorefrontError {
|
|
30
|
+
constructor(message: string, options?: {
|
|
31
|
+
cause?: Error;
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Not found error - resource doesn't exist
|
|
37
|
+
*/
|
|
38
|
+
export declare class NotFoundError extends StorefrontError {
|
|
39
|
+
constructor(message: string, options?: {
|
|
40
|
+
cause?: Error;
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* State error - invalid cart state transition
|
|
46
|
+
*/
|
|
47
|
+
export declare class StateError extends StorefrontError {
|
|
48
|
+
readonly state: string;
|
|
49
|
+
constructor(message: string, state: string, options?: {
|
|
50
|
+
cause?: Error;
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Base class for all Storefront SDK errors
|
|
56
|
+
*/
|
|
57
|
+
export declare class StorefrontError extends Error {
|
|
58
|
+
readonly code: string;
|
|
59
|
+
constructor(message: string, code: string, options?: {
|
|
60
|
+
cause?: Error;
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Validation error - userErrors from mutations
|
|
66
|
+
*/
|
|
67
|
+
export declare class ValidationError extends StorefrontError {
|
|
68
|
+
readonly userErrors: Array<{
|
|
69
|
+
field: string | null;
|
|
70
|
+
message: string;
|
|
71
|
+
}>;
|
|
72
|
+
constructor(message: string, userErrors: Array<{
|
|
73
|
+
field: string | null;
|
|
74
|
+
message: string;
|
|
75
|
+
}>, options?: {
|
|
76
|
+
cause?: Error;
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export { }
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
class StorefrontError extends Error {
|
|
2
|
+
code;
|
|
3
|
+
constructor(message, code, options) {
|
|
4
|
+
super(message, options);
|
|
5
|
+
this.name = "StorefrontError";
|
|
6
|
+
this.code = code;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
class NetworkError extends StorefrontError {
|
|
10
|
+
constructor(message, options) {
|
|
11
|
+
super(message, "NETWORK_ERROR", options);
|
|
12
|
+
this.name = "NetworkError";
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
class AuthError extends StorefrontError {
|
|
16
|
+
constructor(message, options) {
|
|
17
|
+
super(message, "AUTH_ERROR", options);
|
|
18
|
+
this.name = "AuthError";
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
class ValidationError extends StorefrontError {
|
|
22
|
+
userErrors;
|
|
23
|
+
constructor(message, userErrors, options) {
|
|
24
|
+
super(message, "VALIDATION_ERROR", options);
|
|
25
|
+
this.name = "ValidationError";
|
|
26
|
+
this.userErrors = userErrors;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
class NotFoundError extends StorefrontError {
|
|
30
|
+
constructor(message, options) {
|
|
31
|
+
super(message, "NOT_FOUND", options);
|
|
32
|
+
this.name = "NotFoundError";
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
class StateError extends StorefrontError {
|
|
36
|
+
state;
|
|
37
|
+
constructor(message, state, options) {
|
|
38
|
+
super(message, "STATE_ERROR", options);
|
|
39
|
+
this.name = "StateError";
|
|
40
|
+
this.state = state;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
class GraphQLError extends StorefrontError {
|
|
44
|
+
graphqlErrors;
|
|
45
|
+
constructor(message, graphqlErrors, options) {
|
|
46
|
+
super(message, "GRAPHQL_ERROR", options);
|
|
47
|
+
this.name = "GraphQLError";
|
|
48
|
+
this.graphqlErrors = graphqlErrors;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
export {
|
|
52
|
+
AuthError,
|
|
53
|
+
GraphQLError,
|
|
54
|
+
NetworkError,
|
|
55
|
+
NotFoundError,
|
|
56
|
+
StateError,
|
|
57
|
+
StorefrontError,
|
|
58
|
+
ValidationError
|
|
59
|
+
};
|
|
60
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sources":["../src/errors.ts"],"sourcesContent":["/**\n * Base class for all Storefront SDK errors\n */\nexport class StorefrontError extends Error {\n readonly code: string;\n\n constructor(message: string, code: string, options?: { cause?: Error }) {\n super(message, options);\n this.name = \"StorefrontError\";\n this.code = code;\n }\n}\n\n/**\n * Network error - fetch failed, connection issues\n */\nexport class NetworkError extends StorefrontError {\n constructor(message: string, options?: { cause?: Error }) {\n super(message, \"NETWORK_ERROR\", options);\n this.name = \"NetworkError\";\n }\n}\n\n/**\n * Authentication error - invalid/revoked API key, 401/403 responses\n */\nexport class AuthError extends StorefrontError {\n constructor(message: string, options?: { cause?: Error }) {\n super(message, \"AUTH_ERROR\", options);\n this.name = \"AuthError\";\n }\n}\n\n/**\n * Validation error - userErrors from mutations\n */\nexport class ValidationError extends StorefrontError {\n readonly userErrors: Array<{ field: string | null; message: string }>;\n\n constructor(\n message: string,\n userErrors: Array<{ field: string | null; message: string }>,\n options?: { cause?: Error },\n ) {\n super(message, \"VALIDATION_ERROR\", options);\n this.name = \"ValidationError\";\n this.userErrors = userErrors;\n }\n}\n\n/**\n * Not found error - resource doesn't exist\n */\nexport class NotFoundError extends StorefrontError {\n constructor(message: string, options?: { cause?: Error }) {\n super(message, \"NOT_FOUND\", options);\n this.name = \"NotFoundError\";\n }\n}\n\n/**\n * State error - invalid cart state transition\n */\nexport class StateError extends StorefrontError {\n readonly state: string;\n\n constructor(message: string, state: string, options?: { cause?: Error }) {\n super(message, \"STATE_ERROR\", options);\n this.name = \"StateError\";\n this.state = state;\n }\n}\n\n/**\n * GraphQL error - unexpected GraphQL errors\n */\nexport class GraphQLError extends StorefrontError {\n readonly graphqlErrors: Array<{ message: string; path?: readonly (string | number)[] }>;\n\n constructor(\n message: string,\n graphqlErrors: Array<{ message: string; path?: readonly (string | number)[] }>,\n options?: { cause?: Error },\n ) {\n super(message, \"GRAPHQL_ERROR\", options);\n this.name = \"GraphQLError\";\n this.graphqlErrors = graphqlErrors;\n }\n}\n"],"names":[],"mappings":"AAGO,MAAM,wBAAwB,MAAM;AAAA,EAChC;AAAA,EAET,YAAY,SAAiB,MAAc,SAA6B;AACtE,UAAM,SAAS,OAAO;AACtB,SAAK,OAAO;AACZ,SAAK,OAAO;AAAA,EACd;AACF;AAKO,MAAM,qBAAqB,gBAAgB;AAAA,EAChD,YAAY,SAAiB,SAA6B;AACxD,UAAM,SAAS,iBAAiB,OAAO;AACvC,SAAK,OAAO;AAAA,EACd;AACF;AAKO,MAAM,kBAAkB,gBAAgB;AAAA,EAC7C,YAAY,SAAiB,SAA6B;AACxD,UAAM,SAAS,cAAc,OAAO;AACpC,SAAK,OAAO;AAAA,EACd;AACF;AAKO,MAAM,wBAAwB,gBAAgB;AAAA,EAC1C;AAAA,EAET,YACE,SACA,YACA,SACA;AACA,UAAM,SAAS,oBAAoB,OAAO;AAC1C,SAAK,OAAO;AACZ,SAAK,aAAa;AAAA,EACpB;AACF;AAKO,MAAM,sBAAsB,gBAAgB;AAAA,EACjD,YAAY,SAAiB,SAA6B;AACxD,UAAM,SAAS,aAAa,OAAO;AACnC,SAAK,OAAO;AAAA,EACd;AACF;AAKO,MAAM,mBAAmB,gBAAgB;AAAA,EACrC;AAAA,EAET,YAAY,SAAiB,OAAe,SAA6B;AACvE,UAAM,SAAS,eAAe,OAAO;AACrC,SAAK,OAAO;AACZ,SAAK,QAAQ;AAAA,EACf;AACF;AAKO,MAAM,qBAAqB,gBAAgB;AAAA,EACvC;AAAA,EAET,YACE,SACA,eACA,SACA;AACA,UAAM,SAAS,iBAAiB,OAAO;AACvC,SAAK,OAAO;AACZ,SAAK,gBAAgB;AAAA,EACvB;AACF;"}
|