omni-sync-sdk 0.17.2 → 0.17.4

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/LICENSE ADDED
File without changes
package/README.md CHANGED
@@ -20,21 +20,21 @@ yarn add omni-sync-sdk
20
20
 
21
21
  The SDK exports these utility functions for common UI tasks:
22
22
 
23
- | Function | Purpose | Example |
24
- | ---------------------------------------------- | -------------------------------------- | ---------------------------------------------- |
25
- | `formatPrice(amount, currency?, locale?)` | Format prices for display | `formatPrice(99.99, 'USD')` → `$99.99` |
26
- | `getPriceDisplay(amount, currency?, locale?)` | Alias for `formatPrice` | Same as above |
27
- | `getDescriptionContent(product)` | Get product description (HTML or text) | `getDescriptionContent(product)` |
28
- | `isHtmlDescription(product)` | Check if description is HTML | `isHtmlDescription(product)` → `true/false` |
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" }]` |
37
- | `isCouponApplicableToProduct(coupon, product)` | Check if coupon applies | `isCouponApplicableToProduct(coupon, product)` |
23
+ | Function | Purpose | Example |
24
+ | ---------------------------------------------- | -------------------------------------- | ------------------------------------------------------ |
25
+ | `formatPrice(amount, { currency?, locale? })` | Format prices for display | `formatPrice("99.99", { currency: 'USD' })` → `$99.99` |
26
+ | `getPriceDisplay(amount, currency?, locale?)` | Alias for `formatPrice` | Same as above |
27
+ | `getDescriptionContent(product)` | Get product description (HTML or text) | `getDescriptionContent(product)` |
28
+ | `isHtmlDescription(product)` | Check if description is HTML | `isHtmlDescription(product)` → `true/false` |
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" }]` |
37
+ | `isCouponApplicableToProduct(coupon, product)` | Check if coupon applies | `isCouponApplicableToProduct(coupon, product)` |
38
38
 
39
39
  ```typescript
40
40
  import {
@@ -49,7 +49,7 @@ import {
49
49
  } from 'omni-sync-sdk';
50
50
 
51
51
  // Format price for display
52
- const priceText = formatPrice(product.basePrice, 'USD'); // "$99.99"
52
+ const priceText = formatPrice(product.basePrice, { currency: 'USD' }); // "$99.99"
53
53
 
54
54
  // Get product description (handles HTML vs plain text)
55
55
  const description = getDescriptionContent(product);
@@ -600,6 +600,9 @@ interface InventoryInfo {
600
600
  total: number;
601
601
  reserved: number;
602
602
  available: number;
603
+ trackingMode?: 'TRACKED' | 'UNLIMITED' | 'DISABLED';
604
+ inStock: boolean; // Pre-calculated - use this for display!
605
+ canPurchase: boolean; // Pre-calculated - use this for add-to-cart
603
606
  }
604
607
  ```
605
608
 
@@ -2466,11 +2469,13 @@ export default function ProductPage({ params }: { params: { slug: string } }) {
2466
2469
  {adding ? 'Adding...' : 'Add to Cart'}
2467
2470
  </button>
2468
2471
 
2469
- {/* Stock Status */}
2472
+ {/* Stock Status - use inStock which handles UNLIMITED variants */}
2470
2473
  {product.inventory && (
2471
2474
  <p className="mt-4 text-sm">
2472
- {product.inventory.available > 0
2473
- ? `${product.inventory.available} in stock`
2475
+ {product.inventory.inStock
2476
+ ? (product.inventory.trackingMode === 'UNLIMITED'
2477
+ ? 'In Stock'
2478
+ : `${product.inventory.available} in stock`)
2474
2479
  : 'Out of stock'}
2475
2480
  </p>
2476
2481
  )}
package/dist/index.js CHANGED
@@ -3503,12 +3503,22 @@ function getStockStatus(inventory, options) {
3503
3503
  if (inventory.trackingMode === "UNLIMITED") {
3504
3504
  return options?.unlimitedText ?? options?.inStockText ?? "In Stock";
3505
3505
  }
3506
+ if (inventory.inStock === true) {
3507
+ const available2 = inventory.available;
3508
+ const lowStockThreshold2 = options?.lowStockThreshold ?? 0;
3509
+ if (inventory.trackingMode === "TRACKED" && lowStockThreshold2 > 0 && available2 > 0 && available2 <= lowStockThreshold2) {
3510
+ return options?.lowStockText ?? "Low Stock";
3511
+ }
3512
+ return options?.inStockText ?? "In Stock";
3513
+ }
3514
+ if (inventory.inStock === false) {
3515
+ return options?.outOfStockText ?? "Out of Stock";
3516
+ }
3506
3517
  const available = inventory.available;
3507
- const inStock = inventory.inStock ?? available > 0;
3508
- const lowStockThreshold = options?.lowStockThreshold ?? 0;
3509
- if (!inStock || available <= 0) {
3518
+ if (available <= 0) {
3510
3519
  return options?.outOfStockText ?? "Out of Stock";
3511
3520
  }
3521
+ const lowStockThreshold = options?.lowStockThreshold ?? 0;
3512
3522
  if (lowStockThreshold > 0 && available <= lowStockThreshold) {
3513
3523
  return options?.lowStockText ?? "Low Stock";
3514
3524
  }
package/dist/index.mjs CHANGED
@@ -3466,12 +3466,22 @@ function getStockStatus(inventory, options) {
3466
3466
  if (inventory.trackingMode === "UNLIMITED") {
3467
3467
  return options?.unlimitedText ?? options?.inStockText ?? "In Stock";
3468
3468
  }
3469
+ if (inventory.inStock === true) {
3470
+ const available2 = inventory.available;
3471
+ const lowStockThreshold2 = options?.lowStockThreshold ?? 0;
3472
+ if (inventory.trackingMode === "TRACKED" && lowStockThreshold2 > 0 && available2 > 0 && available2 <= lowStockThreshold2) {
3473
+ return options?.lowStockText ?? "Low Stock";
3474
+ }
3475
+ return options?.inStockText ?? "In Stock";
3476
+ }
3477
+ if (inventory.inStock === false) {
3478
+ return options?.outOfStockText ?? "Out of Stock";
3479
+ }
3469
3480
  const available = inventory.available;
3470
- const inStock = inventory.inStock ?? available > 0;
3471
- const lowStockThreshold = options?.lowStockThreshold ?? 0;
3472
- if (!inStock || available <= 0) {
3481
+ if (available <= 0) {
3473
3482
  return options?.outOfStockText ?? "Out of Stock";
3474
3483
  }
3484
+ const lowStockThreshold = options?.lowStockThreshold ?? 0;
3475
3485
  if (lowStockThreshold > 0 && available <= lowStockThreshold) {
3476
3486
  return options?.lowStockText ?? "Low Stock";
3477
3487
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omni-sync-sdk",
3
- "version": "0.17.2",
3
+ "version": "0.17.4",
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,14 +16,6 @@
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
- },
27
19
  "keywords": [
28
20
  "omni-sync",
29
21
  "e-commerce",
@@ -72,5 +64,12 @@
72
64
  "typescript": {
73
65
  "optional": true
74
66
  }
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"
75
74
  }
76
- }
75
+ }