omni-sync-sdk 0.16.2 → 0.17.2
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 +37 -9
- package/dist/index.d.mts +202 -4
- package/dist/index.d.ts +202 -4
- package/dist/index.js +181 -0
- package/dist/index.mjs +174 -0
- package/package.json +10 -9
- package/LICENSE +0 -0
package/README.md
CHANGED
|
@@ -26,15 +26,26 @@ The SDK exports these utility functions for common UI tasks:
|
|
|
26
26
|
| `getPriceDisplay(amount, currency?, locale?)` | Alias for `formatPrice` | Same as above |
|
|
27
27
|
| `getDescriptionContent(product)` | Get product description (HTML or text) | `getDescriptionContent(product)` |
|
|
28
28
|
| `isHtmlDescription(product)` | Check if description is HTML | `isHtmlDescription(product)` → `true/false` |
|
|
29
|
-
| `getStockStatus(
|
|
29
|
+
| `getStockStatus(inventory)` | Get human-readable stock status | `getStockStatus(inventory)` → `"In Stock"` |
|
|
30
|
+
| `getProductPrice(product)` | Get effective price (handles sales) | `getProductPrice(product)` → `29.99` |
|
|
31
|
+
| `getProductPriceInfo(product)` | Get price + sale info + discount % | `{ price, isOnSale, discountPercent }` |
|
|
32
|
+
| `getVariantPrice(variant, basePrice)` | Get variant price with fallback | `getVariantPrice(variant, '29.99')` → `34.99` |
|
|
33
|
+
| `getCartTotals(cart, shippingPrice?)` | Calculate cart subtotal/discount/total | `{ subtotal, discount, shipping, total }` |
|
|
34
|
+
| `getCartItemName(item)` | Get name from nested cart item | `getCartItemName(item)` → `"Blue T-Shirt"` |
|
|
35
|
+
| `getCartItemImage(item)` | Get image URL from cart item | `getCartItemImage(item)` → `"https://..."` |
|
|
36
|
+
| `getVariantOptions(variant)` | Get variant attributes as array | `[{ name: "Color", value: "Red" }]` |
|
|
30
37
|
| `isCouponApplicableToProduct(coupon, product)` | Check if coupon applies | `isCouponApplicableToProduct(coupon, product)` |
|
|
31
38
|
|
|
32
39
|
```typescript
|
|
33
40
|
import {
|
|
34
41
|
formatPrice,
|
|
35
|
-
getPriceDisplay, // Alias for formatPrice
|
|
36
42
|
getDescriptionContent,
|
|
37
43
|
getStockStatus,
|
|
44
|
+
getProductPrice,
|
|
45
|
+
getProductPriceInfo,
|
|
46
|
+
getCartTotals,
|
|
47
|
+
getCartItemName,
|
|
48
|
+
getCartItemImage,
|
|
38
49
|
} from 'omni-sync-sdk';
|
|
39
50
|
|
|
40
51
|
// Format price for display
|
|
@@ -44,9 +55,26 @@ const priceText = formatPrice(product.basePrice, 'USD'); // "$99.99"
|
|
|
44
55
|
const description = getDescriptionContent(product);
|
|
45
56
|
|
|
46
57
|
// Get stock status text
|
|
47
|
-
const stockText = getStockStatus(product.
|
|
58
|
+
const stockText = getStockStatus(product.inventory); // "In Stock", "Low Stock", "Out of Stock"
|
|
59
|
+
|
|
60
|
+
// Get effective price (handles sale prices automatically)
|
|
61
|
+
const price = getProductPrice(product); // Returns number: 29.99
|
|
62
|
+
|
|
63
|
+
// Get full price info including sale status
|
|
64
|
+
const priceInfo = getProductPriceInfo(product);
|
|
65
|
+
// { price: 19.99, originalPrice: 29.99, isOnSale: true, discountPercent: 33 }
|
|
66
|
+
|
|
67
|
+
// Calculate cart totals
|
|
68
|
+
const totals = getCartTotals(cart, shippingRate?.price);
|
|
69
|
+
// { subtotal: 59.98, discount: 10, shipping: 5.99, total: 55.97 }
|
|
70
|
+
|
|
71
|
+
// Access cart item details (handles nested structure)
|
|
72
|
+
const itemName = getCartItemName(cartItem); // "Blue T-Shirt - Large"
|
|
73
|
+
const itemImage = getCartItemImage(cartItem); // "https://..."
|
|
48
74
|
```
|
|
49
75
|
|
|
76
|
+
> **⚠️ DO NOT CREATE YOUR OWN UTILITY FILES!** All helper functions above are exported from `omni-sync-sdk`. Never create `utils/format.ts`, `lib/helpers.ts`, or similar files - use the SDK exports directly.
|
|
77
|
+
|
|
50
78
|
---
|
|
51
79
|
|
|
52
80
|
## ⚠️ CRITICAL: Payment Integration Required!
|
|
@@ -440,9 +468,9 @@ const response: PaginatedResponse<Product> = await omni.getProducts({
|
|
|
440
468
|
sortOrder: 'desc', // Optional: 'asc' | 'desc'
|
|
441
469
|
});
|
|
442
470
|
|
|
443
|
-
console.log(response.
|
|
444
|
-
console.log(response.total); // Total number of products
|
|
445
|
-
console.log(response.totalPages); // Total pages
|
|
471
|
+
console.log(response.data); // Product[]
|
|
472
|
+
console.log(response.meta.total); // Total number of products
|
|
473
|
+
console.log(response.meta.totalPages); // Total pages
|
|
446
474
|
```
|
|
447
475
|
|
|
448
476
|
#### Get Single Product
|
|
@@ -2306,8 +2334,8 @@ export default function ProductsPage() {
|
|
|
2306
2334
|
<button onClick={() => setPage(p => Math.max(1, p - 1))} disabled={page === 1}>
|
|
2307
2335
|
Previous
|
|
2308
2336
|
</button>
|
|
2309
|
-
<span>Page {data.page} of {data.totalPages}</span>
|
|
2310
|
-
<button onClick={() => setPage(p => p + 1)} disabled={page >= data.totalPages}>
|
|
2337
|
+
<span>Page {data.meta.page} of {data.meta.totalPages}</span>
|
|
2338
|
+
<button onClick={() => setPage(p => p + 1)} disabled={page >= data.meta.totalPages}>
|
|
2311
2339
|
Next
|
|
2312
2340
|
</button>
|
|
2313
2341
|
</div>
|
|
@@ -3205,7 +3233,7 @@ export default function AccountPage() {
|
|
|
3205
3233
|
omni.getMyOrders({ limit: 10 }),
|
|
3206
3234
|
]);
|
|
3207
3235
|
setProfile(p);
|
|
3208
|
-
setOrders(o.
|
|
3236
|
+
setOrders(o.data);
|
|
3209
3237
|
} finally {
|
|
3210
3238
|
setLoading(false);
|
|
3211
3239
|
}
|
package/dist/index.d.mts
CHANGED
|
@@ -148,6 +148,8 @@ interface ProductImage {
|
|
|
148
148
|
url: string;
|
|
149
149
|
position?: number;
|
|
150
150
|
isMain?: boolean;
|
|
151
|
+
/** Alt text for accessibility */
|
|
152
|
+
alt?: string;
|
|
151
153
|
}
|
|
152
154
|
interface ProductVariant {
|
|
153
155
|
id: string;
|
|
@@ -160,6 +162,14 @@ interface ProductVariant {
|
|
|
160
162
|
/** Variant attributes (e.g., { "Color": "Red", "Size": "M" }) */
|
|
161
163
|
attributes?: Record<string, unknown>;
|
|
162
164
|
inventory?: InventoryInfo | null;
|
|
165
|
+
/** Variant image URL or image object */
|
|
166
|
+
image?: string | {
|
|
167
|
+
url: string;
|
|
168
|
+
} | null;
|
|
169
|
+
/** Display position/order for sorting variants */
|
|
170
|
+
position?: number;
|
|
171
|
+
/** Variant status */
|
|
172
|
+
status?: 'active' | 'draft' | 'archived';
|
|
163
173
|
}
|
|
164
174
|
/**
|
|
165
175
|
* Inventory tracking mode determines how stock is managed:
|
|
@@ -328,6 +338,155 @@ interface FormatPriceOptions {
|
|
|
328
338
|
* ```
|
|
329
339
|
*/
|
|
330
340
|
declare function formatPrice(priceString: string | undefined | null, options?: FormatPriceOptions): string | number;
|
|
341
|
+
/**
|
|
342
|
+
* Get the effective price of a product (sale price if on sale, otherwise base price).
|
|
343
|
+
* Returns the price as a NUMBER, not string.
|
|
344
|
+
*
|
|
345
|
+
* @param product - Product or object with basePrice and optional salePrice
|
|
346
|
+
* @returns The effective price as a number
|
|
347
|
+
*
|
|
348
|
+
* @example
|
|
349
|
+
* ```typescript
|
|
350
|
+
* const product = await omni.getProduct('prod_123');
|
|
351
|
+
* const price = getProductPrice(product); // Returns number, e.g., 29.99
|
|
352
|
+
*
|
|
353
|
+
* // Check if on sale
|
|
354
|
+
* const { price, isOnSale, originalPrice } = getProductPriceInfo(product);
|
|
355
|
+
* ```
|
|
356
|
+
*/
|
|
357
|
+
declare function getProductPrice(product: Pick<Product, 'basePrice' | 'salePrice'> | null | undefined): number;
|
|
358
|
+
/**
|
|
359
|
+
* Get detailed price information for a product including sale status.
|
|
360
|
+
*
|
|
361
|
+
* @param product - Product or object with basePrice and optional salePrice
|
|
362
|
+
* @returns Object with price, originalPrice, isOnSale, and discount info
|
|
363
|
+
*
|
|
364
|
+
* @example
|
|
365
|
+
* ```typescript
|
|
366
|
+
* const info = getProductPriceInfo(product);
|
|
367
|
+
* // info = {
|
|
368
|
+
* // price: 19.99, // Current/effective price
|
|
369
|
+
* // originalPrice: 29.99, // Original price (same as price if not on sale)
|
|
370
|
+
* // isOnSale: true,
|
|
371
|
+
* // discountAmount: 10, // How much is saved
|
|
372
|
+
* // discountPercent: 33 // Percentage off (rounded)
|
|
373
|
+
* // }
|
|
374
|
+
*
|
|
375
|
+
* // In React component:
|
|
376
|
+
* if (info.isOnSale) {
|
|
377
|
+
* return (
|
|
378
|
+
* <div>
|
|
379
|
+
* <span className="text-red-600">${info.price}</span>
|
|
380
|
+
* <span className="line-through">${info.originalPrice}</span>
|
|
381
|
+
* <span className="badge">-{info.discountPercent}%</span>
|
|
382
|
+
* </div>
|
|
383
|
+
* );
|
|
384
|
+
* }
|
|
385
|
+
* ```
|
|
386
|
+
*/
|
|
387
|
+
declare function getProductPriceInfo(product: Pick<Product, 'basePrice' | 'salePrice'> | null | undefined): {
|
|
388
|
+
price: number;
|
|
389
|
+
originalPrice: number;
|
|
390
|
+
isOnSale: boolean;
|
|
391
|
+
discountAmount: number;
|
|
392
|
+
discountPercent: number;
|
|
393
|
+
};
|
|
394
|
+
/**
|
|
395
|
+
* Get the price of a variant, falling back to product base price if not set.
|
|
396
|
+
* Returns the price as a NUMBER.
|
|
397
|
+
*
|
|
398
|
+
* @param variant - The product variant
|
|
399
|
+
* @param productBasePrice - The product's base price as fallback
|
|
400
|
+
* @returns The variant price as a number
|
|
401
|
+
*
|
|
402
|
+
* @example
|
|
403
|
+
* ```typescript
|
|
404
|
+
* product.variants?.forEach(variant => {
|
|
405
|
+
* const price = getVariantPrice(variant, product.basePrice);
|
|
406
|
+
* console.log(`${variant.name}: $${price}`);
|
|
407
|
+
* });
|
|
408
|
+
* ```
|
|
409
|
+
*/
|
|
410
|
+
declare function getVariantPrice(variant: Pick<ProductVariant, 'price' | 'salePrice'> | null | undefined, productBasePrice: string): number;
|
|
411
|
+
/**
|
|
412
|
+
* Calculate the total for a cart.
|
|
413
|
+
* Cart does NOT have a 'total' field - use this helper!
|
|
414
|
+
*
|
|
415
|
+
* @param cart - The cart object
|
|
416
|
+
* @param shippingPrice - Optional shipping price (string or number)
|
|
417
|
+
* @returns Object with subtotal, discount, shipping, and total
|
|
418
|
+
*
|
|
419
|
+
* @example
|
|
420
|
+
* ```typescript
|
|
421
|
+
* const cart = await omni.getCart(cartId);
|
|
422
|
+
* const totals = getCartTotals(cart);
|
|
423
|
+
* // totals = { subtotal: 59.98, discount: 10, shipping: 0, total: 49.98 }
|
|
424
|
+
*
|
|
425
|
+
* // With shipping
|
|
426
|
+
* const totals = getCartTotals(cart, selectedRate?.price);
|
|
427
|
+
* // totals = { subtotal: 59.98, discount: 0, shipping: 5.99, total: 65.97 }
|
|
428
|
+
* ```
|
|
429
|
+
*/
|
|
430
|
+
declare function getCartTotals(cart: Pick<Cart, 'subtotal' | 'discountAmount'> | null | undefined, shippingPrice?: string | number | null): {
|
|
431
|
+
subtotal: number;
|
|
432
|
+
discount: number;
|
|
433
|
+
shipping: number;
|
|
434
|
+
total: number;
|
|
435
|
+
};
|
|
436
|
+
/**
|
|
437
|
+
* Get the display name for a cart item.
|
|
438
|
+
* Handles the nested product/variant structure - uses variant name if available,
|
|
439
|
+
* otherwise falls back to product name.
|
|
440
|
+
*
|
|
441
|
+
* @param item - The cart item
|
|
442
|
+
* @returns The display name for the item
|
|
443
|
+
*
|
|
444
|
+
* @example
|
|
445
|
+
* ```typescript
|
|
446
|
+
* cart.items.forEach(item => {
|
|
447
|
+
* const name = getCartItemName(item);
|
|
448
|
+
* console.log(`${name} x ${item.quantity}`);
|
|
449
|
+
* });
|
|
450
|
+
* ```
|
|
451
|
+
*/
|
|
452
|
+
declare function getCartItemName(item: CartItem): string;
|
|
453
|
+
/**
|
|
454
|
+
* Get the image URL for a cart item.
|
|
455
|
+
* Checks variant image first, then falls back to the first product image.
|
|
456
|
+
*
|
|
457
|
+
* @param item - The cart item
|
|
458
|
+
* @returns The image URL or undefined if no image exists
|
|
459
|
+
*
|
|
460
|
+
* @example
|
|
461
|
+
* ```typescript
|
|
462
|
+
* const imageUrl = getCartItemImage(item);
|
|
463
|
+
* if (imageUrl) {
|
|
464
|
+
* return <img src={imageUrl} alt={getCartItemName(item)} />;
|
|
465
|
+
* }
|
|
466
|
+
* ```
|
|
467
|
+
*/
|
|
468
|
+
declare function getCartItemImage(item: CartItem): string | undefined;
|
|
469
|
+
/**
|
|
470
|
+
* Convert variant attributes to an array of name/value pairs.
|
|
471
|
+
* Transforms { "Color": "Red", "Size": "M" } to [{ name: "Color", value: "Red" }, ...]
|
|
472
|
+
*
|
|
473
|
+
* @param variant - The product variant (or object with attributes)
|
|
474
|
+
* @returns Array of { name, value } objects
|
|
475
|
+
*
|
|
476
|
+
* @example
|
|
477
|
+
* ```typescript
|
|
478
|
+
* const options = getVariantOptions(selectedVariant);
|
|
479
|
+
* // options = [{ name: "Color", value: "Red" }, { name: "Size", value: "M" }]
|
|
480
|
+
*
|
|
481
|
+
* options.forEach(opt => {
|
|
482
|
+
* console.log(`${opt.name}: ${opt.value}`);
|
|
483
|
+
* });
|
|
484
|
+
* ```
|
|
485
|
+
*/
|
|
486
|
+
declare function getVariantOptions(variant: Pick<ProductVariant, 'attributes'> | null | undefined): Array<{
|
|
487
|
+
name: string;
|
|
488
|
+
value: string;
|
|
489
|
+
}>;
|
|
331
490
|
interface ProductQueryParams {
|
|
332
491
|
page?: number;
|
|
333
492
|
limit?: number;
|
|
@@ -419,10 +578,22 @@ interface UpdateProductDto {
|
|
|
419
578
|
interface Order {
|
|
420
579
|
id: string;
|
|
421
580
|
externalId?: string;
|
|
581
|
+
/** Human-readable order number (e.g., "#1001") */
|
|
582
|
+
orderNumber?: string;
|
|
422
583
|
status: OrderStatus;
|
|
423
|
-
|
|
424
|
-
|
|
584
|
+
/** Total amount as string (e.g., "99.99"). Use parseFloat() for calculations. */
|
|
585
|
+
totalAmount: string;
|
|
586
|
+
/** Currency code (e.g., "USD", "ILS") */
|
|
587
|
+
currency?: string;
|
|
588
|
+
/** Customer info (may be null for guest orders) */
|
|
589
|
+
customer?: OrderCustomer | null;
|
|
425
590
|
items: OrderItem[];
|
|
591
|
+
/** Number of items in the order */
|
|
592
|
+
itemCount?: number;
|
|
593
|
+
/** Shipping address for the order */
|
|
594
|
+
shippingAddress?: OrderAddress;
|
|
595
|
+
/** Billing address for the order */
|
|
596
|
+
billingAddress?: OrderAddress;
|
|
426
597
|
platform?: string;
|
|
427
598
|
createdAt: string;
|
|
428
599
|
}
|
|
@@ -434,20 +605,32 @@ interface OrderCustomer {
|
|
|
434
605
|
address?: OrderAddress;
|
|
435
606
|
}
|
|
436
607
|
interface OrderAddress {
|
|
608
|
+
firstName?: string;
|
|
609
|
+
lastName?: string;
|
|
610
|
+
company?: string;
|
|
437
611
|
line1: string;
|
|
438
612
|
line2?: string;
|
|
439
613
|
city: string;
|
|
614
|
+
/** State/Province (alias: use `state` or `region`) */
|
|
440
615
|
state?: string;
|
|
616
|
+
/** Region/Province (alias: use `state` or `region`) */
|
|
617
|
+
region?: string;
|
|
441
618
|
postalCode: string;
|
|
442
619
|
country: string;
|
|
620
|
+
phone?: string;
|
|
443
621
|
}
|
|
444
622
|
interface OrderItem {
|
|
445
623
|
productId: string;
|
|
624
|
+
variantId?: string;
|
|
446
625
|
sku?: string;
|
|
447
626
|
name?: string;
|
|
448
627
|
quantity: number;
|
|
628
|
+
/** Price per unit as number */
|
|
449
629
|
price: number;
|
|
450
|
-
|
|
630
|
+
/** Unit price as string (for consistency with Cart/Checkout) */
|
|
631
|
+
unitPrice?: string;
|
|
632
|
+
/** Product image URL */
|
|
633
|
+
image?: string;
|
|
451
634
|
}
|
|
452
635
|
interface OrderQueryParams {
|
|
453
636
|
page?: number;
|
|
@@ -1995,6 +2178,11 @@ declare class OmniSyncClient {
|
|
|
1995
2178
|
private readonly timeout;
|
|
1996
2179
|
private customerToken;
|
|
1997
2180
|
private customerCartId;
|
|
2181
|
+
/**
|
|
2182
|
+
* Virtual cart ID used for localStorage carts (guest users not logged in).
|
|
2183
|
+
* When a cart has this ID, operations use localStorage instead of server API.
|
|
2184
|
+
*/
|
|
2185
|
+
private readonly VIRTUAL_LOCAL_CART_ID;
|
|
1998
2186
|
private readonly onAuthError?;
|
|
1999
2187
|
constructor(options: OmniSyncClientOptions);
|
|
2000
2188
|
/**
|
|
@@ -3454,6 +3642,16 @@ declare class OmniSyncClient {
|
|
|
3454
3642
|
* Save local cart to localStorage
|
|
3455
3643
|
*/
|
|
3456
3644
|
private saveLocalCart;
|
|
3645
|
+
/**
|
|
3646
|
+
* Calculate subtotal for a local cart
|
|
3647
|
+
*/
|
|
3648
|
+
private calculateLocalCartSubtotal;
|
|
3649
|
+
/**
|
|
3650
|
+
* Convert LocalCart to Cart format for consistent API.
|
|
3651
|
+
* This allows cart methods to return the same Cart type regardless
|
|
3652
|
+
* of whether data is stored locally or on the server.
|
|
3653
|
+
*/
|
|
3654
|
+
private localCartToCart;
|
|
3457
3655
|
/**
|
|
3458
3656
|
* Add item to local cart (NO API call)
|
|
3459
3657
|
* If item already exists, updates quantity
|
|
@@ -3923,4 +4121,4 @@ declare function isWebhookEventType(event: WebhookEvent, type: WebhookEventType)
|
|
|
3923
4121
|
*/
|
|
3924
4122
|
declare function createWebhookHandler(handlers: Partial<Record<WebhookEventType, (event: WebhookEvent) => Promise<void>>>): (payload: unknown) => Promise<void>;
|
|
3925
4123
|
|
|
3926
|
-
export { type AddToCartDto, type AppliedDiscount, type ApplyCouponDto, type BulkInventoryResponse, type BulkSaveVariantsDto, type BulkSaveVariantsResponse, type BulkVariantInput, type Cart, type CartItem, type CartStatus, type CategorySuggestion, type Checkout, type CheckoutAddress, type CheckoutLineItem, type CheckoutPrefillData, type CheckoutStatus, type CompleteCheckoutResponse, type CompleteDraftDto, type ConnectorPlatform, type Coupon, type CouponCreateResponse, type CouponQueryParams, type CouponStatus, type CouponType, type CouponValidationWarning, type CreateAddressDto, type CreateCheckoutDto, type CreateCouponDto, type CreateCustomApiDto, type CreateCustomerDto, type CreateGuestOrderDto, type CreateOrderDto, type CreateProductDto, type CreateRefundDto, type CreateVariantDto, type CustomApiAuthType, type CustomApiConnectionStatus, type CustomApiCredentials, type CustomApiIntegration, type CustomApiSyncConfig, type CustomApiSyncDirection, type CustomApiTestResult, type Customer, type CustomerAddress, type CustomerAuthResponse, type CustomerOAuthProvider, type CustomerProfile, type CustomerQueryParams, type DraftLineItem, type EditInventoryDto, type EmailVerificationResponse, type FormatPriceOptions, type FulfillOrderDto, type GuestCheckoutStartResponse, type GuestOrderResponse, type InsufficientStockError, type InventoryInfo, type InventorySyncStatus, type LocalCart, type LocalCartItem, type MergeCartsDto, type OAuthAuthorizeResponse, type OAuthCallbackResponse, type OAuthConnection, type OAuthConnectionsResponse, type OAuthProvidersResponse, type OmniSyncApiError, OmniSyncClient, type OmniSyncClientOptions, OmniSyncError, type Order, type OrderAddress, type OrderCustomer, type OrderItem, type OrderQueryParams, type OrderStatus, type PaginatedResponse, type PaymentConfig, type PaymentIntent, type PaymentProviderConfig, type PaymentProvidersConfig, type PaymentStatus, type PlatformCouponCapabilities, type Product, type ProductAttributeInput, type ProductImage, type ProductQueryParams, type ProductSuggestion, type ProductVariant, type PublishProductResponse, type ReconcileInventoryResponse, type Refund, type RefundLineItem, type RefundLineItemResponse, type RefundType, type RegisterCustomerDto, type SearchSuggestions, type SelectShippingMethodDto, type SendInvoiceDto, type SetBillingAddressDto, type SetCheckoutCustomerDto, type SetShippingAddressDto, type SetShippingAddressResponse, type ShippingLine, type ShippingRate, type StockAvailabilityRequest, type StockAvailabilityResponse, type StockAvailabilityResult, type StoreInfo, type SyncJob, type UpdateAddressDto, type UpdateCartItemDto, type UpdateCouponDto, type UpdateCustomApiDto, type UpdateCustomerDto, type UpdateDraftDto, type UpdateInventoryDto, type UpdateOrderDto, type UpdateOrderShippingDto, type UpdateProductDto, type UpdateVariantDto, type UpdateVariantInventoryDto, type VariantInventoryResponse, type VariantPlatformOverlay, type VariantStatus, type WaitForOrderOptions, type WaitForOrderResult, type WebhookEvent, type WebhookEventType, createWebhookHandler, formatPrice, getDescriptionContent, formatPrice as getPriceDisplay, getStockStatus, isCouponApplicableToProduct, isHtmlDescription, isWebhookEventType, parseWebhookEvent, verifyWebhook };
|
|
4124
|
+
export { type AddToCartDto, type AppliedDiscount, type ApplyCouponDto, type BulkInventoryResponse, type BulkSaveVariantsDto, type BulkSaveVariantsResponse, type BulkVariantInput, type Cart, type CartItem, type CartStatus, type CategorySuggestion, type Checkout, type CheckoutAddress, type CheckoutLineItem, type CheckoutPrefillData, type CheckoutStatus, type CompleteCheckoutResponse, type CompleteDraftDto, type ConnectorPlatform, type Coupon, type CouponCreateResponse, type CouponQueryParams, type CouponStatus, type CouponType, type CouponValidationWarning, type CreateAddressDto, type CreateCheckoutDto, type CreateCouponDto, type CreateCustomApiDto, type CreateCustomerDto, type CreateGuestOrderDto, type CreateOrderDto, type CreateProductDto, type CreateRefundDto, type CreateVariantDto, type CustomApiAuthType, type CustomApiConnectionStatus, type CustomApiCredentials, type CustomApiIntegration, type CustomApiSyncConfig, type CustomApiSyncDirection, type CustomApiTestResult, type Customer, type CustomerAddress, type CustomerAuthResponse, type CustomerOAuthProvider, type CustomerProfile, type CustomerQueryParams, type DraftLineItem, type EditInventoryDto, type EmailVerificationResponse, type ExtendReservationResponse, type FormatPriceOptions, type FulfillOrderDto, type GuestCheckoutStartResponse, type GuestOrderResponse, type InsufficientStockError, type InventoryInfo, type InventoryReservationStrategy, type InventorySyncStatus, type InventoryTrackingMode, type LocalCart, type LocalCartItem, type MergeCartsDto, type OAuthAuthorizeResponse, type OAuthCallbackResponse, type OAuthConnection, type OAuthConnectionsResponse, type OAuthProvidersResponse, type OmniSyncApiError, OmniSyncClient, type OmniSyncClientOptions, OmniSyncError, type Order, type OrderAddress, type OrderCustomer, type OrderItem, type OrderQueryParams, type OrderStatus, type PaginatedResponse, type PaymentConfig, type PaymentIntent, type PaymentProviderConfig, type PaymentProvidersConfig, type PaymentStatus, type PlatformCouponCapabilities, type Product, type ProductAttributeInput, type ProductAvailability, type ProductImage, type ProductMetafield, type ProductQueryParams, type ProductSuggestion, type ProductVariant, type PublishProductResponse, type ReconcileInventoryResponse, type Refund, type RefundLineItem, type RefundLineItemResponse, type RefundType, type RegisterCustomerDto, type ReservationInfo, type SearchSuggestions, type SelectShippingMethodDto, type SendInvoiceDto, type SetBillingAddressDto, type SetCheckoutCustomerDto, type SetShippingAddressDto, type SetShippingAddressResponse, type ShippingLine, type ShippingRate, type StockAvailabilityRequest, type StockAvailabilityResponse, type StockAvailabilityResult, type StoreInfo, type SyncJob, type TaxBreakdown, type TaxBreakdownItem, type UpdateAddressDto, type UpdateCartItemDto, type UpdateCouponDto, type UpdateCustomApiDto, type UpdateCustomerDto, type UpdateDraftDto, type UpdateInventoryDto, type UpdateOrderDto, type UpdateOrderShippingDto, type UpdateProductDto, type UpdateVariantDto, type UpdateVariantInventoryDto, type VariantInventoryResponse, type VariantPlatformOverlay, type VariantStatus, type WaitForOrderOptions, type WaitForOrderResult, type WebhookEvent, type WebhookEventType, createWebhookHandler, formatPrice, getCartItemImage, getCartItemName, getCartTotals, getDescriptionContent, formatPrice as getPriceDisplay, getProductPrice, getProductPriceInfo, getStockStatus, getVariantOptions, getVariantPrice, isCouponApplicableToProduct, isHtmlDescription, isWebhookEventType, parseWebhookEvent, verifyWebhook };
|
package/dist/index.d.ts
CHANGED
|
@@ -148,6 +148,8 @@ interface ProductImage {
|
|
|
148
148
|
url: string;
|
|
149
149
|
position?: number;
|
|
150
150
|
isMain?: boolean;
|
|
151
|
+
/** Alt text for accessibility */
|
|
152
|
+
alt?: string;
|
|
151
153
|
}
|
|
152
154
|
interface ProductVariant {
|
|
153
155
|
id: string;
|
|
@@ -160,6 +162,14 @@ interface ProductVariant {
|
|
|
160
162
|
/** Variant attributes (e.g., { "Color": "Red", "Size": "M" }) */
|
|
161
163
|
attributes?: Record<string, unknown>;
|
|
162
164
|
inventory?: InventoryInfo | null;
|
|
165
|
+
/** Variant image URL or image object */
|
|
166
|
+
image?: string | {
|
|
167
|
+
url: string;
|
|
168
|
+
} | null;
|
|
169
|
+
/** Display position/order for sorting variants */
|
|
170
|
+
position?: number;
|
|
171
|
+
/** Variant status */
|
|
172
|
+
status?: 'active' | 'draft' | 'archived';
|
|
163
173
|
}
|
|
164
174
|
/**
|
|
165
175
|
* Inventory tracking mode determines how stock is managed:
|
|
@@ -328,6 +338,155 @@ interface FormatPriceOptions {
|
|
|
328
338
|
* ```
|
|
329
339
|
*/
|
|
330
340
|
declare function formatPrice(priceString: string | undefined | null, options?: FormatPriceOptions): string | number;
|
|
341
|
+
/**
|
|
342
|
+
* Get the effective price of a product (sale price if on sale, otherwise base price).
|
|
343
|
+
* Returns the price as a NUMBER, not string.
|
|
344
|
+
*
|
|
345
|
+
* @param product - Product or object with basePrice and optional salePrice
|
|
346
|
+
* @returns The effective price as a number
|
|
347
|
+
*
|
|
348
|
+
* @example
|
|
349
|
+
* ```typescript
|
|
350
|
+
* const product = await omni.getProduct('prod_123');
|
|
351
|
+
* const price = getProductPrice(product); // Returns number, e.g., 29.99
|
|
352
|
+
*
|
|
353
|
+
* // Check if on sale
|
|
354
|
+
* const { price, isOnSale, originalPrice } = getProductPriceInfo(product);
|
|
355
|
+
* ```
|
|
356
|
+
*/
|
|
357
|
+
declare function getProductPrice(product: Pick<Product, 'basePrice' | 'salePrice'> | null | undefined): number;
|
|
358
|
+
/**
|
|
359
|
+
* Get detailed price information for a product including sale status.
|
|
360
|
+
*
|
|
361
|
+
* @param product - Product or object with basePrice and optional salePrice
|
|
362
|
+
* @returns Object with price, originalPrice, isOnSale, and discount info
|
|
363
|
+
*
|
|
364
|
+
* @example
|
|
365
|
+
* ```typescript
|
|
366
|
+
* const info = getProductPriceInfo(product);
|
|
367
|
+
* // info = {
|
|
368
|
+
* // price: 19.99, // Current/effective price
|
|
369
|
+
* // originalPrice: 29.99, // Original price (same as price if not on sale)
|
|
370
|
+
* // isOnSale: true,
|
|
371
|
+
* // discountAmount: 10, // How much is saved
|
|
372
|
+
* // discountPercent: 33 // Percentage off (rounded)
|
|
373
|
+
* // }
|
|
374
|
+
*
|
|
375
|
+
* // In React component:
|
|
376
|
+
* if (info.isOnSale) {
|
|
377
|
+
* return (
|
|
378
|
+
* <div>
|
|
379
|
+
* <span className="text-red-600">${info.price}</span>
|
|
380
|
+
* <span className="line-through">${info.originalPrice}</span>
|
|
381
|
+
* <span className="badge">-{info.discountPercent}%</span>
|
|
382
|
+
* </div>
|
|
383
|
+
* );
|
|
384
|
+
* }
|
|
385
|
+
* ```
|
|
386
|
+
*/
|
|
387
|
+
declare function getProductPriceInfo(product: Pick<Product, 'basePrice' | 'salePrice'> | null | undefined): {
|
|
388
|
+
price: number;
|
|
389
|
+
originalPrice: number;
|
|
390
|
+
isOnSale: boolean;
|
|
391
|
+
discountAmount: number;
|
|
392
|
+
discountPercent: number;
|
|
393
|
+
};
|
|
394
|
+
/**
|
|
395
|
+
* Get the price of a variant, falling back to product base price if not set.
|
|
396
|
+
* Returns the price as a NUMBER.
|
|
397
|
+
*
|
|
398
|
+
* @param variant - The product variant
|
|
399
|
+
* @param productBasePrice - The product's base price as fallback
|
|
400
|
+
* @returns The variant price as a number
|
|
401
|
+
*
|
|
402
|
+
* @example
|
|
403
|
+
* ```typescript
|
|
404
|
+
* product.variants?.forEach(variant => {
|
|
405
|
+
* const price = getVariantPrice(variant, product.basePrice);
|
|
406
|
+
* console.log(`${variant.name}: $${price}`);
|
|
407
|
+
* });
|
|
408
|
+
* ```
|
|
409
|
+
*/
|
|
410
|
+
declare function getVariantPrice(variant: Pick<ProductVariant, 'price' | 'salePrice'> | null | undefined, productBasePrice: string): number;
|
|
411
|
+
/**
|
|
412
|
+
* Calculate the total for a cart.
|
|
413
|
+
* Cart does NOT have a 'total' field - use this helper!
|
|
414
|
+
*
|
|
415
|
+
* @param cart - The cart object
|
|
416
|
+
* @param shippingPrice - Optional shipping price (string or number)
|
|
417
|
+
* @returns Object with subtotal, discount, shipping, and total
|
|
418
|
+
*
|
|
419
|
+
* @example
|
|
420
|
+
* ```typescript
|
|
421
|
+
* const cart = await omni.getCart(cartId);
|
|
422
|
+
* const totals = getCartTotals(cart);
|
|
423
|
+
* // totals = { subtotal: 59.98, discount: 10, shipping: 0, total: 49.98 }
|
|
424
|
+
*
|
|
425
|
+
* // With shipping
|
|
426
|
+
* const totals = getCartTotals(cart, selectedRate?.price);
|
|
427
|
+
* // totals = { subtotal: 59.98, discount: 0, shipping: 5.99, total: 65.97 }
|
|
428
|
+
* ```
|
|
429
|
+
*/
|
|
430
|
+
declare function getCartTotals(cart: Pick<Cart, 'subtotal' | 'discountAmount'> | null | undefined, shippingPrice?: string | number | null): {
|
|
431
|
+
subtotal: number;
|
|
432
|
+
discount: number;
|
|
433
|
+
shipping: number;
|
|
434
|
+
total: number;
|
|
435
|
+
};
|
|
436
|
+
/**
|
|
437
|
+
* Get the display name for a cart item.
|
|
438
|
+
* Handles the nested product/variant structure - uses variant name if available,
|
|
439
|
+
* otherwise falls back to product name.
|
|
440
|
+
*
|
|
441
|
+
* @param item - The cart item
|
|
442
|
+
* @returns The display name for the item
|
|
443
|
+
*
|
|
444
|
+
* @example
|
|
445
|
+
* ```typescript
|
|
446
|
+
* cart.items.forEach(item => {
|
|
447
|
+
* const name = getCartItemName(item);
|
|
448
|
+
* console.log(`${name} x ${item.quantity}`);
|
|
449
|
+
* });
|
|
450
|
+
* ```
|
|
451
|
+
*/
|
|
452
|
+
declare function getCartItemName(item: CartItem): string;
|
|
453
|
+
/**
|
|
454
|
+
* Get the image URL for a cart item.
|
|
455
|
+
* Checks variant image first, then falls back to the first product image.
|
|
456
|
+
*
|
|
457
|
+
* @param item - The cart item
|
|
458
|
+
* @returns The image URL or undefined if no image exists
|
|
459
|
+
*
|
|
460
|
+
* @example
|
|
461
|
+
* ```typescript
|
|
462
|
+
* const imageUrl = getCartItemImage(item);
|
|
463
|
+
* if (imageUrl) {
|
|
464
|
+
* return <img src={imageUrl} alt={getCartItemName(item)} />;
|
|
465
|
+
* }
|
|
466
|
+
* ```
|
|
467
|
+
*/
|
|
468
|
+
declare function getCartItemImage(item: CartItem): string | undefined;
|
|
469
|
+
/**
|
|
470
|
+
* Convert variant attributes to an array of name/value pairs.
|
|
471
|
+
* Transforms { "Color": "Red", "Size": "M" } to [{ name: "Color", value: "Red" }, ...]
|
|
472
|
+
*
|
|
473
|
+
* @param variant - The product variant (or object with attributes)
|
|
474
|
+
* @returns Array of { name, value } objects
|
|
475
|
+
*
|
|
476
|
+
* @example
|
|
477
|
+
* ```typescript
|
|
478
|
+
* const options = getVariantOptions(selectedVariant);
|
|
479
|
+
* // options = [{ name: "Color", value: "Red" }, { name: "Size", value: "M" }]
|
|
480
|
+
*
|
|
481
|
+
* options.forEach(opt => {
|
|
482
|
+
* console.log(`${opt.name}: ${opt.value}`);
|
|
483
|
+
* });
|
|
484
|
+
* ```
|
|
485
|
+
*/
|
|
486
|
+
declare function getVariantOptions(variant: Pick<ProductVariant, 'attributes'> | null | undefined): Array<{
|
|
487
|
+
name: string;
|
|
488
|
+
value: string;
|
|
489
|
+
}>;
|
|
331
490
|
interface ProductQueryParams {
|
|
332
491
|
page?: number;
|
|
333
492
|
limit?: number;
|
|
@@ -419,10 +578,22 @@ interface UpdateProductDto {
|
|
|
419
578
|
interface Order {
|
|
420
579
|
id: string;
|
|
421
580
|
externalId?: string;
|
|
581
|
+
/** Human-readable order number (e.g., "#1001") */
|
|
582
|
+
orderNumber?: string;
|
|
422
583
|
status: OrderStatus;
|
|
423
|
-
|
|
424
|
-
|
|
584
|
+
/** Total amount as string (e.g., "99.99"). Use parseFloat() for calculations. */
|
|
585
|
+
totalAmount: string;
|
|
586
|
+
/** Currency code (e.g., "USD", "ILS") */
|
|
587
|
+
currency?: string;
|
|
588
|
+
/** Customer info (may be null for guest orders) */
|
|
589
|
+
customer?: OrderCustomer | null;
|
|
425
590
|
items: OrderItem[];
|
|
591
|
+
/** Number of items in the order */
|
|
592
|
+
itemCount?: number;
|
|
593
|
+
/** Shipping address for the order */
|
|
594
|
+
shippingAddress?: OrderAddress;
|
|
595
|
+
/** Billing address for the order */
|
|
596
|
+
billingAddress?: OrderAddress;
|
|
426
597
|
platform?: string;
|
|
427
598
|
createdAt: string;
|
|
428
599
|
}
|
|
@@ -434,20 +605,32 @@ interface OrderCustomer {
|
|
|
434
605
|
address?: OrderAddress;
|
|
435
606
|
}
|
|
436
607
|
interface OrderAddress {
|
|
608
|
+
firstName?: string;
|
|
609
|
+
lastName?: string;
|
|
610
|
+
company?: string;
|
|
437
611
|
line1: string;
|
|
438
612
|
line2?: string;
|
|
439
613
|
city: string;
|
|
614
|
+
/** State/Province (alias: use `state` or `region`) */
|
|
440
615
|
state?: string;
|
|
616
|
+
/** Region/Province (alias: use `state` or `region`) */
|
|
617
|
+
region?: string;
|
|
441
618
|
postalCode: string;
|
|
442
619
|
country: string;
|
|
620
|
+
phone?: string;
|
|
443
621
|
}
|
|
444
622
|
interface OrderItem {
|
|
445
623
|
productId: string;
|
|
624
|
+
variantId?: string;
|
|
446
625
|
sku?: string;
|
|
447
626
|
name?: string;
|
|
448
627
|
quantity: number;
|
|
628
|
+
/** Price per unit as number */
|
|
449
629
|
price: number;
|
|
450
|
-
|
|
630
|
+
/** Unit price as string (for consistency with Cart/Checkout) */
|
|
631
|
+
unitPrice?: string;
|
|
632
|
+
/** Product image URL */
|
|
633
|
+
image?: string;
|
|
451
634
|
}
|
|
452
635
|
interface OrderQueryParams {
|
|
453
636
|
page?: number;
|
|
@@ -1995,6 +2178,11 @@ declare class OmniSyncClient {
|
|
|
1995
2178
|
private readonly timeout;
|
|
1996
2179
|
private customerToken;
|
|
1997
2180
|
private customerCartId;
|
|
2181
|
+
/**
|
|
2182
|
+
* Virtual cart ID used for localStorage carts (guest users not logged in).
|
|
2183
|
+
* When a cart has this ID, operations use localStorage instead of server API.
|
|
2184
|
+
*/
|
|
2185
|
+
private readonly VIRTUAL_LOCAL_CART_ID;
|
|
1998
2186
|
private readonly onAuthError?;
|
|
1999
2187
|
constructor(options: OmniSyncClientOptions);
|
|
2000
2188
|
/**
|
|
@@ -3454,6 +3642,16 @@ declare class OmniSyncClient {
|
|
|
3454
3642
|
* Save local cart to localStorage
|
|
3455
3643
|
*/
|
|
3456
3644
|
private saveLocalCart;
|
|
3645
|
+
/**
|
|
3646
|
+
* Calculate subtotal for a local cart
|
|
3647
|
+
*/
|
|
3648
|
+
private calculateLocalCartSubtotal;
|
|
3649
|
+
/**
|
|
3650
|
+
* Convert LocalCart to Cart format for consistent API.
|
|
3651
|
+
* This allows cart methods to return the same Cart type regardless
|
|
3652
|
+
* of whether data is stored locally or on the server.
|
|
3653
|
+
*/
|
|
3654
|
+
private localCartToCart;
|
|
3457
3655
|
/**
|
|
3458
3656
|
* Add item to local cart (NO API call)
|
|
3459
3657
|
* If item already exists, updates quantity
|
|
@@ -3923,4 +4121,4 @@ declare function isWebhookEventType(event: WebhookEvent, type: WebhookEventType)
|
|
|
3923
4121
|
*/
|
|
3924
4122
|
declare function createWebhookHandler(handlers: Partial<Record<WebhookEventType, (event: WebhookEvent) => Promise<void>>>): (payload: unknown) => Promise<void>;
|
|
3925
4123
|
|
|
3926
|
-
export { type AddToCartDto, type AppliedDiscount, type ApplyCouponDto, type BulkInventoryResponse, type BulkSaveVariantsDto, type BulkSaveVariantsResponse, type BulkVariantInput, type Cart, type CartItem, type CartStatus, type CategorySuggestion, type Checkout, type CheckoutAddress, type CheckoutLineItem, type CheckoutPrefillData, type CheckoutStatus, type CompleteCheckoutResponse, type CompleteDraftDto, type ConnectorPlatform, type Coupon, type CouponCreateResponse, type CouponQueryParams, type CouponStatus, type CouponType, type CouponValidationWarning, type CreateAddressDto, type CreateCheckoutDto, type CreateCouponDto, type CreateCustomApiDto, type CreateCustomerDto, type CreateGuestOrderDto, type CreateOrderDto, type CreateProductDto, type CreateRefundDto, type CreateVariantDto, type CustomApiAuthType, type CustomApiConnectionStatus, type CustomApiCredentials, type CustomApiIntegration, type CustomApiSyncConfig, type CustomApiSyncDirection, type CustomApiTestResult, type Customer, type CustomerAddress, type CustomerAuthResponse, type CustomerOAuthProvider, type CustomerProfile, type CustomerQueryParams, type DraftLineItem, type EditInventoryDto, type EmailVerificationResponse, type FormatPriceOptions, type FulfillOrderDto, type GuestCheckoutStartResponse, type GuestOrderResponse, type InsufficientStockError, type InventoryInfo, type InventorySyncStatus, type LocalCart, type LocalCartItem, type MergeCartsDto, type OAuthAuthorizeResponse, type OAuthCallbackResponse, type OAuthConnection, type OAuthConnectionsResponse, type OAuthProvidersResponse, type OmniSyncApiError, OmniSyncClient, type OmniSyncClientOptions, OmniSyncError, type Order, type OrderAddress, type OrderCustomer, type OrderItem, type OrderQueryParams, type OrderStatus, type PaginatedResponse, type PaymentConfig, type PaymentIntent, type PaymentProviderConfig, type PaymentProvidersConfig, type PaymentStatus, type PlatformCouponCapabilities, type Product, type ProductAttributeInput, type ProductImage, type ProductQueryParams, type ProductSuggestion, type ProductVariant, type PublishProductResponse, type ReconcileInventoryResponse, type Refund, type RefundLineItem, type RefundLineItemResponse, type RefundType, type RegisterCustomerDto, type SearchSuggestions, type SelectShippingMethodDto, type SendInvoiceDto, type SetBillingAddressDto, type SetCheckoutCustomerDto, type SetShippingAddressDto, type SetShippingAddressResponse, type ShippingLine, type ShippingRate, type StockAvailabilityRequest, type StockAvailabilityResponse, type StockAvailabilityResult, type StoreInfo, type SyncJob, type UpdateAddressDto, type UpdateCartItemDto, type UpdateCouponDto, type UpdateCustomApiDto, type UpdateCustomerDto, type UpdateDraftDto, type UpdateInventoryDto, type UpdateOrderDto, type UpdateOrderShippingDto, type UpdateProductDto, type UpdateVariantDto, type UpdateVariantInventoryDto, type VariantInventoryResponse, type VariantPlatformOverlay, type VariantStatus, type WaitForOrderOptions, type WaitForOrderResult, type WebhookEvent, type WebhookEventType, createWebhookHandler, formatPrice, getDescriptionContent, formatPrice as getPriceDisplay, getStockStatus, isCouponApplicableToProduct, isHtmlDescription, isWebhookEventType, parseWebhookEvent, verifyWebhook };
|
|
4124
|
+
export { type AddToCartDto, type AppliedDiscount, type ApplyCouponDto, type BulkInventoryResponse, type BulkSaveVariantsDto, type BulkSaveVariantsResponse, type BulkVariantInput, type Cart, type CartItem, type CartStatus, type CategorySuggestion, type Checkout, type CheckoutAddress, type CheckoutLineItem, type CheckoutPrefillData, type CheckoutStatus, type CompleteCheckoutResponse, type CompleteDraftDto, type ConnectorPlatform, type Coupon, type CouponCreateResponse, type CouponQueryParams, type CouponStatus, type CouponType, type CouponValidationWarning, type CreateAddressDto, type CreateCheckoutDto, type CreateCouponDto, type CreateCustomApiDto, type CreateCustomerDto, type CreateGuestOrderDto, type CreateOrderDto, type CreateProductDto, type CreateRefundDto, type CreateVariantDto, type CustomApiAuthType, type CustomApiConnectionStatus, type CustomApiCredentials, type CustomApiIntegration, type CustomApiSyncConfig, type CustomApiSyncDirection, type CustomApiTestResult, type Customer, type CustomerAddress, type CustomerAuthResponse, type CustomerOAuthProvider, type CustomerProfile, type CustomerQueryParams, type DraftLineItem, type EditInventoryDto, type EmailVerificationResponse, type ExtendReservationResponse, type FormatPriceOptions, type FulfillOrderDto, type GuestCheckoutStartResponse, type GuestOrderResponse, type InsufficientStockError, type InventoryInfo, type InventoryReservationStrategy, type InventorySyncStatus, type InventoryTrackingMode, type LocalCart, type LocalCartItem, type MergeCartsDto, type OAuthAuthorizeResponse, type OAuthCallbackResponse, type OAuthConnection, type OAuthConnectionsResponse, type OAuthProvidersResponse, type OmniSyncApiError, OmniSyncClient, type OmniSyncClientOptions, OmniSyncError, type Order, type OrderAddress, type OrderCustomer, type OrderItem, type OrderQueryParams, type OrderStatus, type PaginatedResponse, type PaymentConfig, type PaymentIntent, type PaymentProviderConfig, type PaymentProvidersConfig, type PaymentStatus, type PlatformCouponCapabilities, type Product, type ProductAttributeInput, type ProductAvailability, type ProductImage, type ProductMetafield, type ProductQueryParams, type ProductSuggestion, type ProductVariant, type PublishProductResponse, type ReconcileInventoryResponse, type Refund, type RefundLineItem, type RefundLineItemResponse, type RefundType, type RegisterCustomerDto, type ReservationInfo, type SearchSuggestions, type SelectShippingMethodDto, type SendInvoiceDto, type SetBillingAddressDto, type SetCheckoutCustomerDto, type SetShippingAddressDto, type SetShippingAddressResponse, type ShippingLine, type ShippingRate, type StockAvailabilityRequest, type StockAvailabilityResponse, type StockAvailabilityResult, type StoreInfo, type SyncJob, type TaxBreakdown, type TaxBreakdownItem, type UpdateAddressDto, type UpdateCartItemDto, type UpdateCouponDto, type UpdateCustomApiDto, type UpdateCustomerDto, type UpdateDraftDto, type UpdateInventoryDto, type UpdateOrderDto, type UpdateOrderShippingDto, type UpdateProductDto, type UpdateVariantDto, type UpdateVariantInventoryDto, type VariantInventoryResponse, type VariantPlatformOverlay, type VariantStatus, type WaitForOrderOptions, type WaitForOrderResult, type WebhookEvent, type WebhookEventType, createWebhookHandler, formatPrice, getCartItemImage, getCartItemName, getCartTotals, getDescriptionContent, formatPrice as getPriceDisplay, getProductPrice, getProductPriceInfo, getStockStatus, getVariantOptions, getVariantPrice, isCouponApplicableToProduct, isHtmlDescription, isWebhookEventType, parseWebhookEvent, verifyWebhook };
|
package/dist/index.js
CHANGED
|
@@ -24,9 +24,16 @@ __export(index_exports, {
|
|
|
24
24
|
OmniSyncError: () => OmniSyncError,
|
|
25
25
|
createWebhookHandler: () => createWebhookHandler,
|
|
26
26
|
formatPrice: () => formatPrice,
|
|
27
|
+
getCartItemImage: () => getCartItemImage,
|
|
28
|
+
getCartItemName: () => getCartItemName,
|
|
29
|
+
getCartTotals: () => getCartTotals,
|
|
27
30
|
getDescriptionContent: () => getDescriptionContent,
|
|
28
31
|
getPriceDisplay: () => formatPrice,
|
|
32
|
+
getProductPrice: () => getProductPrice,
|
|
33
|
+
getProductPriceInfo: () => getProductPriceInfo,
|
|
29
34
|
getStockStatus: () => getStockStatus,
|
|
35
|
+
getVariantOptions: () => getVariantOptions,
|
|
36
|
+
getVariantPrice: () => getVariantPrice,
|
|
30
37
|
isCouponApplicableToProduct: () => isCouponApplicableToProduct,
|
|
31
38
|
isHtmlDescription: () => isHtmlDescription,
|
|
32
39
|
isWebhookEventType: () => isWebhookEventType,
|
|
@@ -42,6 +49,11 @@ var OmniSyncClient = class {
|
|
|
42
49
|
constructor(options) {
|
|
43
50
|
this.customerToken = null;
|
|
44
51
|
this.customerCartId = null;
|
|
52
|
+
/**
|
|
53
|
+
* Virtual cart ID used for localStorage carts (guest users not logged in).
|
|
54
|
+
* When a cart has this ID, operations use localStorage instead of server API.
|
|
55
|
+
*/
|
|
56
|
+
this.VIRTUAL_LOCAL_CART_ID = "__local__";
|
|
45
57
|
// -------------------- Local Cart (Client-Side for Guests) --------------------
|
|
46
58
|
// These methods store cart data in localStorage - NO API calls!
|
|
47
59
|
// Use for guest users in vibe-coded sites
|
|
@@ -1633,6 +1645,10 @@ var OmniSyncClient = class {
|
|
|
1633
1645
|
* ```
|
|
1634
1646
|
*/
|
|
1635
1647
|
async createCart() {
|
|
1648
|
+
if (this.isVibeCodedMode() && !this.isCustomerLoggedIn()) {
|
|
1649
|
+
const localCart = this.getLocalCart();
|
|
1650
|
+
return this.localCartToCart(localCart);
|
|
1651
|
+
}
|
|
1636
1652
|
if (this.isVibeCodedMode()) {
|
|
1637
1653
|
return this.vibeCodedRequest("POST", "/cart");
|
|
1638
1654
|
}
|
|
@@ -1675,6 +1691,9 @@ var OmniSyncClient = class {
|
|
|
1675
1691
|
* Get a cart by ID
|
|
1676
1692
|
*/
|
|
1677
1693
|
async getCart(cartId) {
|
|
1694
|
+
if (cartId === this.VIRTUAL_LOCAL_CART_ID) {
|
|
1695
|
+
return this.localCartToCart(this.getLocalCart());
|
|
1696
|
+
}
|
|
1678
1697
|
if (this.isVibeCodedMode()) {
|
|
1679
1698
|
return this.vibeCodedRequest("GET", `/cart/${cartId}`);
|
|
1680
1699
|
}
|
|
@@ -1696,6 +1715,14 @@ var OmniSyncClient = class {
|
|
|
1696
1715
|
* ```
|
|
1697
1716
|
*/
|
|
1698
1717
|
async addToCart(cartId, item) {
|
|
1718
|
+
if (cartId === this.VIRTUAL_LOCAL_CART_ID) {
|
|
1719
|
+
this.addToLocalCart({
|
|
1720
|
+
productId: item.productId,
|
|
1721
|
+
variantId: item.variantId,
|
|
1722
|
+
quantity: item.quantity
|
|
1723
|
+
});
|
|
1724
|
+
return this.localCartToCart(this.getLocalCart());
|
|
1725
|
+
}
|
|
1699
1726
|
if (this.isVibeCodedMode()) {
|
|
1700
1727
|
return this.vibeCodedRequest("POST", `/cart/${cartId}/items`, item);
|
|
1701
1728
|
}
|
|
@@ -1713,6 +1740,15 @@ var OmniSyncClient = class {
|
|
|
1713
1740
|
* ```
|
|
1714
1741
|
*/
|
|
1715
1742
|
async updateCartItem(cartId, itemId, data) {
|
|
1743
|
+
if (cartId === this.VIRTUAL_LOCAL_CART_ID) {
|
|
1744
|
+
const index = parseInt(itemId.replace("local_", ""), 10);
|
|
1745
|
+
const localCart = this.getLocalCart();
|
|
1746
|
+
if (index >= 0 && index < localCart.items.length) {
|
|
1747
|
+
const item = localCart.items[index];
|
|
1748
|
+
this.updateLocalCartItem(item.productId, data.quantity, item.variantId);
|
|
1749
|
+
}
|
|
1750
|
+
return this.localCartToCart(this.getLocalCart());
|
|
1751
|
+
}
|
|
1716
1752
|
if (this.isVibeCodedMode()) {
|
|
1717
1753
|
return this.vibeCodedRequest("PATCH", `/cart/${cartId}/items/${itemId}`, data);
|
|
1718
1754
|
}
|
|
@@ -1730,6 +1766,15 @@ var OmniSyncClient = class {
|
|
|
1730
1766
|
* ```
|
|
1731
1767
|
*/
|
|
1732
1768
|
async removeCartItem(cartId, itemId) {
|
|
1769
|
+
if (cartId === this.VIRTUAL_LOCAL_CART_ID) {
|
|
1770
|
+
const index = parseInt(itemId.replace("local_", ""), 10);
|
|
1771
|
+
const localCart = this.getLocalCart();
|
|
1772
|
+
if (index >= 0 && index < localCart.items.length) {
|
|
1773
|
+
const item = localCart.items[index];
|
|
1774
|
+
this.removeFromLocalCart(item.productId, item.variantId);
|
|
1775
|
+
}
|
|
1776
|
+
return this.localCartToCart(this.getLocalCart());
|
|
1777
|
+
}
|
|
1733
1778
|
if (this.isVibeCodedMode()) {
|
|
1734
1779
|
return this.vibeCodedRequest("DELETE", `/cart/${cartId}/items/${itemId}`);
|
|
1735
1780
|
}
|
|
@@ -1747,6 +1792,10 @@ var OmniSyncClient = class {
|
|
|
1747
1792
|
* ```
|
|
1748
1793
|
*/
|
|
1749
1794
|
async clearCart(cartId) {
|
|
1795
|
+
if (cartId === this.VIRTUAL_LOCAL_CART_ID) {
|
|
1796
|
+
this.clearLocalCart();
|
|
1797
|
+
return this.localCartToCart(this.getLocalCart());
|
|
1798
|
+
}
|
|
1750
1799
|
if (this.isVibeCodedMode()) {
|
|
1751
1800
|
return this.vibeCodedRequest("DELETE", `/cart/${cartId}`);
|
|
1752
1801
|
}
|
|
@@ -2561,6 +2610,62 @@ var OmniSyncClient = class {
|
|
|
2561
2610
|
cart.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
2562
2611
|
window.localStorage.setItem(this.LOCAL_CART_KEY, JSON.stringify(cart));
|
|
2563
2612
|
}
|
|
2613
|
+
/**
|
|
2614
|
+
* Calculate subtotal for a local cart
|
|
2615
|
+
*/
|
|
2616
|
+
calculateLocalCartSubtotal(localCart) {
|
|
2617
|
+
const total = localCart.items.reduce((sum, item) => {
|
|
2618
|
+
return sum + parseFloat(item.price || "0") * item.quantity;
|
|
2619
|
+
}, 0);
|
|
2620
|
+
return total.toFixed(2);
|
|
2621
|
+
}
|
|
2622
|
+
/**
|
|
2623
|
+
* Convert LocalCart to Cart format for consistent API.
|
|
2624
|
+
* This allows cart methods to return the same Cart type regardless
|
|
2625
|
+
* of whether data is stored locally or on the server.
|
|
2626
|
+
*/
|
|
2627
|
+
localCartToCart(localCart) {
|
|
2628
|
+
return {
|
|
2629
|
+
id: this.VIRTUAL_LOCAL_CART_ID,
|
|
2630
|
+
sessionToken: null,
|
|
2631
|
+
customerId: null,
|
|
2632
|
+
status: "ACTIVE",
|
|
2633
|
+
currency: "USD",
|
|
2634
|
+
// Default currency
|
|
2635
|
+
notes: localCart.notes || null,
|
|
2636
|
+
subtotal: this.calculateLocalCartSubtotal(localCart),
|
|
2637
|
+
discountAmount: "0",
|
|
2638
|
+
couponCode: localCart.couponCode || null,
|
|
2639
|
+
items: localCart.items.map((item, index) => ({
|
|
2640
|
+
id: `local_${index}`,
|
|
2641
|
+
productId: item.productId,
|
|
2642
|
+
variantId: item.variantId || null,
|
|
2643
|
+
quantity: item.quantity,
|
|
2644
|
+
unitPrice: item.price || "0",
|
|
2645
|
+
discountAmount: "0",
|
|
2646
|
+
notes: null,
|
|
2647
|
+
metadata: null,
|
|
2648
|
+
product: {
|
|
2649
|
+
id: item.productId,
|
|
2650
|
+
name: item.name || "Unknown Product",
|
|
2651
|
+
sku: item.sku || "",
|
|
2652
|
+
images: item.image ? [{ url: item.image }] : []
|
|
2653
|
+
},
|
|
2654
|
+
variant: item.variantId ? {
|
|
2655
|
+
id: item.variantId,
|
|
2656
|
+
name: null,
|
|
2657
|
+
sku: null,
|
|
2658
|
+
image: null
|
|
2659
|
+
} : null,
|
|
2660
|
+
createdAt: item.addedAt,
|
|
2661
|
+
updatedAt: item.addedAt
|
|
2662
|
+
})),
|
|
2663
|
+
itemCount: localCart.items.reduce((sum, i) => sum + i.quantity, 0),
|
|
2664
|
+
expiresAt: null,
|
|
2665
|
+
createdAt: localCart.updatedAt,
|
|
2666
|
+
updatedAt: localCart.updatedAt
|
|
2667
|
+
};
|
|
2668
|
+
}
|
|
2564
2669
|
/**
|
|
2565
2670
|
* Add item to local cart (NO API call)
|
|
2566
2671
|
* If item already exists, updates quantity
|
|
@@ -3421,6 +3526,75 @@ function formatPrice(priceString, options) {
|
|
|
3421
3526
|
currency
|
|
3422
3527
|
}).format(isNaN(value) ? 0 : value);
|
|
3423
3528
|
}
|
|
3529
|
+
function getProductPrice(product) {
|
|
3530
|
+
if (!product) return 0;
|
|
3531
|
+
const basePrice = parseFloat(product.basePrice) || 0;
|
|
3532
|
+
const salePrice = product.salePrice ? parseFloat(product.salePrice) : null;
|
|
3533
|
+
if (salePrice !== null && salePrice < basePrice) {
|
|
3534
|
+
return salePrice;
|
|
3535
|
+
}
|
|
3536
|
+
return basePrice;
|
|
3537
|
+
}
|
|
3538
|
+
function getProductPriceInfo(product) {
|
|
3539
|
+
if (!product) {
|
|
3540
|
+
return { price: 0, originalPrice: 0, isOnSale: false, discountAmount: 0, discountPercent: 0 };
|
|
3541
|
+
}
|
|
3542
|
+
const basePrice = parseFloat(product.basePrice) || 0;
|
|
3543
|
+
const salePrice = product.salePrice ? parseFloat(product.salePrice) : null;
|
|
3544
|
+
const isOnSale = salePrice !== null && salePrice < basePrice;
|
|
3545
|
+
const effectivePrice = isOnSale ? salePrice : basePrice;
|
|
3546
|
+
const discountAmount = isOnSale ? basePrice - salePrice : 0;
|
|
3547
|
+
const discountPercent = isOnSale && basePrice > 0 ? Math.round(discountAmount / basePrice * 100) : 0;
|
|
3548
|
+
return {
|
|
3549
|
+
price: effectivePrice,
|
|
3550
|
+
originalPrice: basePrice,
|
|
3551
|
+
isOnSale,
|
|
3552
|
+
discountAmount,
|
|
3553
|
+
discountPercent
|
|
3554
|
+
};
|
|
3555
|
+
}
|
|
3556
|
+
function getVariantPrice(variant, productBasePrice) {
|
|
3557
|
+
if (!variant) return parseFloat(productBasePrice) || 0;
|
|
3558
|
+
const variantPrice = variant.price ? parseFloat(variant.price) : null;
|
|
3559
|
+
const variantSalePrice = variant.salePrice ? parseFloat(variant.salePrice) : null;
|
|
3560
|
+
const basePrice = parseFloat(productBasePrice) || 0;
|
|
3561
|
+
if (variantSalePrice !== null && variantPrice !== null && variantSalePrice < variantPrice) {
|
|
3562
|
+
return variantSalePrice;
|
|
3563
|
+
}
|
|
3564
|
+
if (variantPrice !== null) {
|
|
3565
|
+
return variantPrice;
|
|
3566
|
+
}
|
|
3567
|
+
return basePrice;
|
|
3568
|
+
}
|
|
3569
|
+
function getCartTotals(cart, shippingPrice) {
|
|
3570
|
+
if (!cart) {
|
|
3571
|
+
return { subtotal: 0, discount: 0, shipping: 0, total: 0 };
|
|
3572
|
+
}
|
|
3573
|
+
const subtotal = parseFloat(cart.subtotal) || 0;
|
|
3574
|
+
const discount = parseFloat(cart.discountAmount) || 0;
|
|
3575
|
+
const shipping = typeof shippingPrice === "string" ? parseFloat(shippingPrice) || 0 : shippingPrice || 0;
|
|
3576
|
+
const total = subtotal - discount + shipping;
|
|
3577
|
+
return { subtotal, discount, shipping, total };
|
|
3578
|
+
}
|
|
3579
|
+
function getCartItemName(item) {
|
|
3580
|
+
return item.variant?.name || item.product.name;
|
|
3581
|
+
}
|
|
3582
|
+
function getCartItemImage(item) {
|
|
3583
|
+
if (item.variant?.image) {
|
|
3584
|
+
if (typeof item.variant.image === "string") {
|
|
3585
|
+
return item.variant.image;
|
|
3586
|
+
}
|
|
3587
|
+
if (typeof item.variant.image === "object" && item.variant.image !== null) {
|
|
3588
|
+
const imgObj = item.variant.image;
|
|
3589
|
+
if (imgObj.url) return imgObj.url;
|
|
3590
|
+
}
|
|
3591
|
+
}
|
|
3592
|
+
return item.product.images?.[0]?.url;
|
|
3593
|
+
}
|
|
3594
|
+
function getVariantOptions(variant) {
|
|
3595
|
+
if (!variant?.attributes) return [];
|
|
3596
|
+
return Object.entries(variant.attributes).filter(([, value]) => typeof value === "string").map(([name, value]) => ({ name, value }));
|
|
3597
|
+
}
|
|
3424
3598
|
function isCouponApplicableToProduct(coupon, productId, productCategoryIds) {
|
|
3425
3599
|
if (coupon.excludedProducts?.includes(productId)) {
|
|
3426
3600
|
return false;
|
|
@@ -3446,9 +3620,16 @@ function isCouponApplicableToProduct(coupon, productId, productCategoryIds) {
|
|
|
3446
3620
|
OmniSyncError,
|
|
3447
3621
|
createWebhookHandler,
|
|
3448
3622
|
formatPrice,
|
|
3623
|
+
getCartItemImage,
|
|
3624
|
+
getCartItemName,
|
|
3625
|
+
getCartTotals,
|
|
3449
3626
|
getDescriptionContent,
|
|
3450
3627
|
getPriceDisplay,
|
|
3628
|
+
getProductPrice,
|
|
3629
|
+
getProductPriceInfo,
|
|
3451
3630
|
getStockStatus,
|
|
3631
|
+
getVariantOptions,
|
|
3632
|
+
getVariantPrice,
|
|
3452
3633
|
isCouponApplicableToProduct,
|
|
3453
3634
|
isHtmlDescription,
|
|
3454
3635
|
isWebhookEventType,
|
package/dist/index.mjs
CHANGED
|
@@ -12,6 +12,11 @@ var OmniSyncClient = class {
|
|
|
12
12
|
constructor(options) {
|
|
13
13
|
this.customerToken = null;
|
|
14
14
|
this.customerCartId = null;
|
|
15
|
+
/**
|
|
16
|
+
* Virtual cart ID used for localStorage carts (guest users not logged in).
|
|
17
|
+
* When a cart has this ID, operations use localStorage instead of server API.
|
|
18
|
+
*/
|
|
19
|
+
this.VIRTUAL_LOCAL_CART_ID = "__local__";
|
|
15
20
|
// -------------------- Local Cart (Client-Side for Guests) --------------------
|
|
16
21
|
// These methods store cart data in localStorage - NO API calls!
|
|
17
22
|
// Use for guest users in vibe-coded sites
|
|
@@ -1603,6 +1608,10 @@ var OmniSyncClient = class {
|
|
|
1603
1608
|
* ```
|
|
1604
1609
|
*/
|
|
1605
1610
|
async createCart() {
|
|
1611
|
+
if (this.isVibeCodedMode() && !this.isCustomerLoggedIn()) {
|
|
1612
|
+
const localCart = this.getLocalCart();
|
|
1613
|
+
return this.localCartToCart(localCart);
|
|
1614
|
+
}
|
|
1606
1615
|
if (this.isVibeCodedMode()) {
|
|
1607
1616
|
return this.vibeCodedRequest("POST", "/cart");
|
|
1608
1617
|
}
|
|
@@ -1645,6 +1654,9 @@ var OmniSyncClient = class {
|
|
|
1645
1654
|
* Get a cart by ID
|
|
1646
1655
|
*/
|
|
1647
1656
|
async getCart(cartId) {
|
|
1657
|
+
if (cartId === this.VIRTUAL_LOCAL_CART_ID) {
|
|
1658
|
+
return this.localCartToCart(this.getLocalCart());
|
|
1659
|
+
}
|
|
1648
1660
|
if (this.isVibeCodedMode()) {
|
|
1649
1661
|
return this.vibeCodedRequest("GET", `/cart/${cartId}`);
|
|
1650
1662
|
}
|
|
@@ -1666,6 +1678,14 @@ var OmniSyncClient = class {
|
|
|
1666
1678
|
* ```
|
|
1667
1679
|
*/
|
|
1668
1680
|
async addToCart(cartId, item) {
|
|
1681
|
+
if (cartId === this.VIRTUAL_LOCAL_CART_ID) {
|
|
1682
|
+
this.addToLocalCart({
|
|
1683
|
+
productId: item.productId,
|
|
1684
|
+
variantId: item.variantId,
|
|
1685
|
+
quantity: item.quantity
|
|
1686
|
+
});
|
|
1687
|
+
return this.localCartToCart(this.getLocalCart());
|
|
1688
|
+
}
|
|
1669
1689
|
if (this.isVibeCodedMode()) {
|
|
1670
1690
|
return this.vibeCodedRequest("POST", `/cart/${cartId}/items`, item);
|
|
1671
1691
|
}
|
|
@@ -1683,6 +1703,15 @@ var OmniSyncClient = class {
|
|
|
1683
1703
|
* ```
|
|
1684
1704
|
*/
|
|
1685
1705
|
async updateCartItem(cartId, itemId, data) {
|
|
1706
|
+
if (cartId === this.VIRTUAL_LOCAL_CART_ID) {
|
|
1707
|
+
const index = parseInt(itemId.replace("local_", ""), 10);
|
|
1708
|
+
const localCart = this.getLocalCart();
|
|
1709
|
+
if (index >= 0 && index < localCart.items.length) {
|
|
1710
|
+
const item = localCart.items[index];
|
|
1711
|
+
this.updateLocalCartItem(item.productId, data.quantity, item.variantId);
|
|
1712
|
+
}
|
|
1713
|
+
return this.localCartToCart(this.getLocalCart());
|
|
1714
|
+
}
|
|
1686
1715
|
if (this.isVibeCodedMode()) {
|
|
1687
1716
|
return this.vibeCodedRequest("PATCH", `/cart/${cartId}/items/${itemId}`, data);
|
|
1688
1717
|
}
|
|
@@ -1700,6 +1729,15 @@ var OmniSyncClient = class {
|
|
|
1700
1729
|
* ```
|
|
1701
1730
|
*/
|
|
1702
1731
|
async removeCartItem(cartId, itemId) {
|
|
1732
|
+
if (cartId === this.VIRTUAL_LOCAL_CART_ID) {
|
|
1733
|
+
const index = parseInt(itemId.replace("local_", ""), 10);
|
|
1734
|
+
const localCart = this.getLocalCart();
|
|
1735
|
+
if (index >= 0 && index < localCart.items.length) {
|
|
1736
|
+
const item = localCart.items[index];
|
|
1737
|
+
this.removeFromLocalCart(item.productId, item.variantId);
|
|
1738
|
+
}
|
|
1739
|
+
return this.localCartToCart(this.getLocalCart());
|
|
1740
|
+
}
|
|
1703
1741
|
if (this.isVibeCodedMode()) {
|
|
1704
1742
|
return this.vibeCodedRequest("DELETE", `/cart/${cartId}/items/${itemId}`);
|
|
1705
1743
|
}
|
|
@@ -1717,6 +1755,10 @@ var OmniSyncClient = class {
|
|
|
1717
1755
|
* ```
|
|
1718
1756
|
*/
|
|
1719
1757
|
async clearCart(cartId) {
|
|
1758
|
+
if (cartId === this.VIRTUAL_LOCAL_CART_ID) {
|
|
1759
|
+
this.clearLocalCart();
|
|
1760
|
+
return this.localCartToCart(this.getLocalCart());
|
|
1761
|
+
}
|
|
1720
1762
|
if (this.isVibeCodedMode()) {
|
|
1721
1763
|
return this.vibeCodedRequest("DELETE", `/cart/${cartId}`);
|
|
1722
1764
|
}
|
|
@@ -2531,6 +2573,62 @@ var OmniSyncClient = class {
|
|
|
2531
2573
|
cart.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
2532
2574
|
window.localStorage.setItem(this.LOCAL_CART_KEY, JSON.stringify(cart));
|
|
2533
2575
|
}
|
|
2576
|
+
/**
|
|
2577
|
+
* Calculate subtotal for a local cart
|
|
2578
|
+
*/
|
|
2579
|
+
calculateLocalCartSubtotal(localCart) {
|
|
2580
|
+
const total = localCart.items.reduce((sum, item) => {
|
|
2581
|
+
return sum + parseFloat(item.price || "0") * item.quantity;
|
|
2582
|
+
}, 0);
|
|
2583
|
+
return total.toFixed(2);
|
|
2584
|
+
}
|
|
2585
|
+
/**
|
|
2586
|
+
* Convert LocalCart to Cart format for consistent API.
|
|
2587
|
+
* This allows cart methods to return the same Cart type regardless
|
|
2588
|
+
* of whether data is stored locally or on the server.
|
|
2589
|
+
*/
|
|
2590
|
+
localCartToCart(localCart) {
|
|
2591
|
+
return {
|
|
2592
|
+
id: this.VIRTUAL_LOCAL_CART_ID,
|
|
2593
|
+
sessionToken: null,
|
|
2594
|
+
customerId: null,
|
|
2595
|
+
status: "ACTIVE",
|
|
2596
|
+
currency: "USD",
|
|
2597
|
+
// Default currency
|
|
2598
|
+
notes: localCart.notes || null,
|
|
2599
|
+
subtotal: this.calculateLocalCartSubtotal(localCart),
|
|
2600
|
+
discountAmount: "0",
|
|
2601
|
+
couponCode: localCart.couponCode || null,
|
|
2602
|
+
items: localCart.items.map((item, index) => ({
|
|
2603
|
+
id: `local_${index}`,
|
|
2604
|
+
productId: item.productId,
|
|
2605
|
+
variantId: item.variantId || null,
|
|
2606
|
+
quantity: item.quantity,
|
|
2607
|
+
unitPrice: item.price || "0",
|
|
2608
|
+
discountAmount: "0",
|
|
2609
|
+
notes: null,
|
|
2610
|
+
metadata: null,
|
|
2611
|
+
product: {
|
|
2612
|
+
id: item.productId,
|
|
2613
|
+
name: item.name || "Unknown Product",
|
|
2614
|
+
sku: item.sku || "",
|
|
2615
|
+
images: item.image ? [{ url: item.image }] : []
|
|
2616
|
+
},
|
|
2617
|
+
variant: item.variantId ? {
|
|
2618
|
+
id: item.variantId,
|
|
2619
|
+
name: null,
|
|
2620
|
+
sku: null,
|
|
2621
|
+
image: null
|
|
2622
|
+
} : null,
|
|
2623
|
+
createdAt: item.addedAt,
|
|
2624
|
+
updatedAt: item.addedAt
|
|
2625
|
+
})),
|
|
2626
|
+
itemCount: localCart.items.reduce((sum, i) => sum + i.quantity, 0),
|
|
2627
|
+
expiresAt: null,
|
|
2628
|
+
createdAt: localCart.updatedAt,
|
|
2629
|
+
updatedAt: localCart.updatedAt
|
|
2630
|
+
};
|
|
2631
|
+
}
|
|
2534
2632
|
/**
|
|
2535
2633
|
* Add item to local cart (NO API call)
|
|
2536
2634
|
* If item already exists, updates quantity
|
|
@@ -3391,6 +3489,75 @@ function formatPrice(priceString, options) {
|
|
|
3391
3489
|
currency
|
|
3392
3490
|
}).format(isNaN(value) ? 0 : value);
|
|
3393
3491
|
}
|
|
3492
|
+
function getProductPrice(product) {
|
|
3493
|
+
if (!product) return 0;
|
|
3494
|
+
const basePrice = parseFloat(product.basePrice) || 0;
|
|
3495
|
+
const salePrice = product.salePrice ? parseFloat(product.salePrice) : null;
|
|
3496
|
+
if (salePrice !== null && salePrice < basePrice) {
|
|
3497
|
+
return salePrice;
|
|
3498
|
+
}
|
|
3499
|
+
return basePrice;
|
|
3500
|
+
}
|
|
3501
|
+
function getProductPriceInfo(product) {
|
|
3502
|
+
if (!product) {
|
|
3503
|
+
return { price: 0, originalPrice: 0, isOnSale: false, discountAmount: 0, discountPercent: 0 };
|
|
3504
|
+
}
|
|
3505
|
+
const basePrice = parseFloat(product.basePrice) || 0;
|
|
3506
|
+
const salePrice = product.salePrice ? parseFloat(product.salePrice) : null;
|
|
3507
|
+
const isOnSale = salePrice !== null && salePrice < basePrice;
|
|
3508
|
+
const effectivePrice = isOnSale ? salePrice : basePrice;
|
|
3509
|
+
const discountAmount = isOnSale ? basePrice - salePrice : 0;
|
|
3510
|
+
const discountPercent = isOnSale && basePrice > 0 ? Math.round(discountAmount / basePrice * 100) : 0;
|
|
3511
|
+
return {
|
|
3512
|
+
price: effectivePrice,
|
|
3513
|
+
originalPrice: basePrice,
|
|
3514
|
+
isOnSale,
|
|
3515
|
+
discountAmount,
|
|
3516
|
+
discountPercent
|
|
3517
|
+
};
|
|
3518
|
+
}
|
|
3519
|
+
function getVariantPrice(variant, productBasePrice) {
|
|
3520
|
+
if (!variant) return parseFloat(productBasePrice) || 0;
|
|
3521
|
+
const variantPrice = variant.price ? parseFloat(variant.price) : null;
|
|
3522
|
+
const variantSalePrice = variant.salePrice ? parseFloat(variant.salePrice) : null;
|
|
3523
|
+
const basePrice = parseFloat(productBasePrice) || 0;
|
|
3524
|
+
if (variantSalePrice !== null && variantPrice !== null && variantSalePrice < variantPrice) {
|
|
3525
|
+
return variantSalePrice;
|
|
3526
|
+
}
|
|
3527
|
+
if (variantPrice !== null) {
|
|
3528
|
+
return variantPrice;
|
|
3529
|
+
}
|
|
3530
|
+
return basePrice;
|
|
3531
|
+
}
|
|
3532
|
+
function getCartTotals(cart, shippingPrice) {
|
|
3533
|
+
if (!cart) {
|
|
3534
|
+
return { subtotal: 0, discount: 0, shipping: 0, total: 0 };
|
|
3535
|
+
}
|
|
3536
|
+
const subtotal = parseFloat(cart.subtotal) || 0;
|
|
3537
|
+
const discount = parseFloat(cart.discountAmount) || 0;
|
|
3538
|
+
const shipping = typeof shippingPrice === "string" ? parseFloat(shippingPrice) || 0 : shippingPrice || 0;
|
|
3539
|
+
const total = subtotal - discount + shipping;
|
|
3540
|
+
return { subtotal, discount, shipping, total };
|
|
3541
|
+
}
|
|
3542
|
+
function getCartItemName(item) {
|
|
3543
|
+
return item.variant?.name || item.product.name;
|
|
3544
|
+
}
|
|
3545
|
+
function getCartItemImage(item) {
|
|
3546
|
+
if (item.variant?.image) {
|
|
3547
|
+
if (typeof item.variant.image === "string") {
|
|
3548
|
+
return item.variant.image;
|
|
3549
|
+
}
|
|
3550
|
+
if (typeof item.variant.image === "object" && item.variant.image !== null) {
|
|
3551
|
+
const imgObj = item.variant.image;
|
|
3552
|
+
if (imgObj.url) return imgObj.url;
|
|
3553
|
+
}
|
|
3554
|
+
}
|
|
3555
|
+
return item.product.images?.[0]?.url;
|
|
3556
|
+
}
|
|
3557
|
+
function getVariantOptions(variant) {
|
|
3558
|
+
if (!variant?.attributes) return [];
|
|
3559
|
+
return Object.entries(variant.attributes).filter(([, value]) => typeof value === "string").map(([name, value]) => ({ name, value }));
|
|
3560
|
+
}
|
|
3394
3561
|
function isCouponApplicableToProduct(coupon, productId, productCategoryIds) {
|
|
3395
3562
|
if (coupon.excludedProducts?.includes(productId)) {
|
|
3396
3563
|
return false;
|
|
@@ -3415,9 +3582,16 @@ export {
|
|
|
3415
3582
|
OmniSyncError,
|
|
3416
3583
|
createWebhookHandler,
|
|
3417
3584
|
formatPrice,
|
|
3585
|
+
getCartItemImage,
|
|
3586
|
+
getCartItemName,
|
|
3587
|
+
getCartTotals,
|
|
3418
3588
|
getDescriptionContent,
|
|
3419
3589
|
formatPrice as getPriceDisplay,
|
|
3590
|
+
getProductPrice,
|
|
3591
|
+
getProductPriceInfo,
|
|
3420
3592
|
getStockStatus,
|
|
3593
|
+
getVariantOptions,
|
|
3594
|
+
getVariantPrice,
|
|
3421
3595
|
isCouponApplicableToProduct,
|
|
3422
3596
|
isHtmlDescription,
|
|
3423
3597
|
isWebhookEventType,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omni-sync-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.2",
|
|
4
4
|
"description": "Official SDK for building e-commerce storefronts with OmniSync Platform. Perfect for vibe-coded sites, AI-built stores (Cursor, Lovable, v0), and custom storefronts.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -16,6 +16,14 @@
|
|
|
16
16
|
"dist",
|
|
17
17
|
"README.md"
|
|
18
18
|
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsup src/index.ts --format cjs,esm --dts",
|
|
21
|
+
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
22
|
+
"lint": "eslint \"src/**/*.ts\"",
|
|
23
|
+
"test": "vitest run",
|
|
24
|
+
"test:watch": "vitest",
|
|
25
|
+
"prepublishOnly": "pnpm build"
|
|
26
|
+
},
|
|
19
27
|
"keywords": [
|
|
20
28
|
"omni-sync",
|
|
21
29
|
"e-commerce",
|
|
@@ -64,12 +72,5 @@
|
|
|
64
72
|
"typescript": {
|
|
65
73
|
"optional": true
|
|
66
74
|
}
|
|
67
|
-
},
|
|
68
|
-
"scripts": {
|
|
69
|
-
"build": "tsup src/index.ts --format cjs,esm --dts",
|
|
70
|
-
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
71
|
-
"lint": "eslint \"src/**/*.ts\"",
|
|
72
|
-
"test": "vitest run",
|
|
73
|
-
"test:watch": "vitest"
|
|
74
75
|
}
|
|
75
|
-
}
|
|
76
|
+
}
|
package/LICENSE
DELETED
|
File without changes
|