@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 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
@@ -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;;;;;;;;"}
@@ -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;"}