omni-sync-sdk 0.4.1 → 0.6.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/dist/index.js CHANGED
@@ -36,6 +36,10 @@ var DEFAULT_TIMEOUT = 3e4;
36
36
  var OmniSyncClient = class {
37
37
  constructor(options) {
38
38
  this.customerToken = null;
39
+ // -------------------- Local Cart (Client-Side for Guests) --------------------
40
+ // These methods store cart data in localStorage - NO API calls!
41
+ // Use for guest users in vibe-coded sites
42
+ this.LOCAL_CART_KEY = "omni_cart";
39
43
  if (!options.apiKey && !options.storeId && !options.connectionId) {
40
44
  throw new Error("OmniSyncClient: either connectionId, apiKey, or storeId is required");
41
45
  }
@@ -1099,6 +1103,9 @@ var OmniSyncClient = class {
1099
1103
  * ```
1100
1104
  */
1101
1105
  async createCart() {
1106
+ if (this.isVibeCodedMode()) {
1107
+ return this.vibeCodedRequest("POST", "/cart");
1108
+ }
1102
1109
  if (this.storeId && !this.apiKey) {
1103
1110
  return this.storefrontRequest("POST", "/cart");
1104
1111
  }
@@ -1138,6 +1145,9 @@ var OmniSyncClient = class {
1138
1145
  * Get a cart by ID
1139
1146
  */
1140
1147
  async getCart(cartId) {
1148
+ if (this.isVibeCodedMode()) {
1149
+ return this.vibeCodedRequest("GET", `/cart/${cartId}`);
1150
+ }
1141
1151
  if (this.storeId && !this.apiKey) {
1142
1152
  return this.storefrontRequest("GET", `/cart/${cartId}`);
1143
1153
  }
@@ -1156,6 +1166,9 @@ var OmniSyncClient = class {
1156
1166
  * ```
1157
1167
  */
1158
1168
  async addToCart(cartId, item) {
1169
+ if (this.isVibeCodedMode()) {
1170
+ return this.vibeCodedRequest("POST", `/cart/${cartId}/items`, item);
1171
+ }
1159
1172
  if (this.storeId && !this.apiKey) {
1160
1173
  return this.storefrontRequest("POST", `/cart/${cartId}/items`, item);
1161
1174
  }
@@ -1170,6 +1183,9 @@ var OmniSyncClient = class {
1170
1183
  * ```
1171
1184
  */
1172
1185
  async updateCartItem(cartId, itemId, data) {
1186
+ if (this.isVibeCodedMode()) {
1187
+ return this.vibeCodedRequest("PATCH", `/cart/${cartId}/items/${itemId}`, data);
1188
+ }
1173
1189
  if (this.storeId && !this.apiKey) {
1174
1190
  return this.storefrontRequest("PATCH", `/cart/${cartId}/items/${itemId}`, data);
1175
1191
  }
@@ -1184,6 +1200,9 @@ var OmniSyncClient = class {
1184
1200
  * ```
1185
1201
  */
1186
1202
  async removeCartItem(cartId, itemId) {
1203
+ if (this.isVibeCodedMode()) {
1204
+ return this.vibeCodedRequest("DELETE", `/cart/${cartId}/items/${itemId}`);
1205
+ }
1187
1206
  if (this.storeId && !this.apiKey) {
1188
1207
  return this.storefrontRequest("DELETE", `/cart/${cartId}/items/${itemId}`);
1189
1208
  }
@@ -1198,11 +1217,15 @@ var OmniSyncClient = class {
1198
1217
  * ```
1199
1218
  */
1200
1219
  async clearCart(cartId) {
1220
+ if (this.isVibeCodedMode()) {
1221
+ return this.vibeCodedRequest("DELETE", `/cart/${cartId}`);
1222
+ }
1201
1223
  if (this.storeId && !this.apiKey) {
1202
1224
  await this.storefrontRequest("DELETE", `/cart/${cartId}/items`);
1203
- return;
1225
+ return {};
1204
1226
  }
1205
1227
  await this.adminRequest("DELETE", `/api/v1/cart/${cartId}/items`);
1228
+ return {};
1206
1229
  }
1207
1230
  /**
1208
1231
  * Apply a coupon to the cart
@@ -1214,6 +1237,9 @@ var OmniSyncClient = class {
1214
1237
  * ```
1215
1238
  */
1216
1239
  async applyCoupon(cartId, code) {
1240
+ if (this.isVibeCodedMode()) {
1241
+ return this.vibeCodedRequest("POST", `/cart/${cartId}/coupon`, { code });
1242
+ }
1217
1243
  if (this.storeId && !this.apiKey) {
1218
1244
  return this.storefrontRequest("POST", `/cart/${cartId}/coupon`, { code });
1219
1245
  }
@@ -1228,6 +1254,9 @@ var OmniSyncClient = class {
1228
1254
  * ```
1229
1255
  */
1230
1256
  async removeCoupon(cartId) {
1257
+ if (this.isVibeCodedMode()) {
1258
+ return this.vibeCodedRequest("DELETE", `/cart/${cartId}/coupon`);
1259
+ }
1231
1260
  if (this.storeId && !this.apiKey) {
1232
1261
  return this.storefrontRequest("DELETE", `/cart/${cartId}/coupon`);
1233
1262
  }
@@ -1264,6 +1293,9 @@ var OmniSyncClient = class {
1264
1293
  * ```
1265
1294
  */
1266
1295
  async createCheckout(data) {
1296
+ if (this.isVibeCodedMode()) {
1297
+ return this.vibeCodedRequest("POST", "/checkout", data);
1298
+ }
1267
1299
  if (this.storeId && !this.apiKey) {
1268
1300
  return this.storefrontRequest("POST", "/checkout", data);
1269
1301
  }
@@ -1279,6 +1311,9 @@ var OmniSyncClient = class {
1279
1311
  * ```
1280
1312
  */
1281
1313
  async getCheckout(checkoutId) {
1314
+ if (this.isVibeCodedMode()) {
1315
+ return this.vibeCodedRequest("GET", `/checkout/${checkoutId}`);
1316
+ }
1282
1317
  if (this.storeId && !this.apiKey) {
1283
1318
  return this.storefrontRequest("GET", `/checkout/${checkoutId}`);
1284
1319
  }
@@ -1297,6 +1332,9 @@ var OmniSyncClient = class {
1297
1332
  * ```
1298
1333
  */
1299
1334
  async setCheckoutCustomer(checkoutId, data) {
1335
+ if (this.isVibeCodedMode()) {
1336
+ return this.vibeCodedRequest("PATCH", `/checkout/${checkoutId}/customer`, data);
1337
+ }
1300
1338
  if (this.storeId && !this.apiKey) {
1301
1339
  return this.storefrontRequest("PATCH", `/checkout/${checkoutId}/customer`, data);
1302
1340
  }
@@ -1321,6 +1359,13 @@ var OmniSyncClient = class {
1321
1359
  * ```
1322
1360
  */
1323
1361
  async setShippingAddress(checkoutId, address) {
1362
+ if (this.isVibeCodedMode()) {
1363
+ return this.vibeCodedRequest(
1364
+ "PATCH",
1365
+ `/checkout/${checkoutId}/shipping-address`,
1366
+ address
1367
+ );
1368
+ }
1324
1369
  if (this.storeId && !this.apiKey) {
1325
1370
  return this.storefrontRequest(
1326
1371
  "PATCH",
@@ -1345,6 +1390,13 @@ var OmniSyncClient = class {
1345
1390
  * ```
1346
1391
  */
1347
1392
  async getShippingRates(checkoutId) {
1393
+ if (this.isVibeCodedMode()) {
1394
+ const result = await this.vibeCodedRequest(
1395
+ "GET",
1396
+ `/checkout/${checkoutId}/shipping-rates`
1397
+ );
1398
+ return result.rates;
1399
+ }
1348
1400
  if (this.storeId && !this.apiKey) {
1349
1401
  return this.storefrontRequest(
1350
1402
  "GET",
@@ -1366,6 +1418,11 @@ var OmniSyncClient = class {
1366
1418
  * ```
1367
1419
  */
1368
1420
  async selectShippingMethod(checkoutId, shippingRateId) {
1421
+ if (this.isVibeCodedMode()) {
1422
+ return this.vibeCodedRequest("PATCH", `/checkout/${checkoutId}/shipping-method`, {
1423
+ shippingMethodId: shippingRateId
1424
+ });
1425
+ }
1369
1426
  if (this.storeId && !this.apiKey) {
1370
1427
  return this.storefrontRequest("PATCH", `/checkout/${checkoutId}/shipping-method`, {
1371
1428
  shippingRateId
@@ -1400,6 +1457,13 @@ var OmniSyncClient = class {
1400
1457
  * ```
1401
1458
  */
1402
1459
  async setBillingAddress(checkoutId, address) {
1460
+ if (this.isVibeCodedMode()) {
1461
+ return this.vibeCodedRequest(
1462
+ "PATCH",
1463
+ `/checkout/${checkoutId}/billing-address`,
1464
+ address
1465
+ );
1466
+ }
1403
1467
  if (this.storeId && !this.apiKey) {
1404
1468
  return this.storefrontRequest(
1405
1469
  "PATCH",
@@ -1424,6 +1488,12 @@ var OmniSyncClient = class {
1424
1488
  * ```
1425
1489
  */
1426
1490
  async completeCheckout(checkoutId) {
1491
+ if (this.isVibeCodedMode()) {
1492
+ return this.vibeCodedRequest(
1493
+ "POST",
1494
+ `/checkout/${checkoutId}/complete`
1495
+ );
1496
+ }
1427
1497
  if (this.storeId && !this.apiKey) {
1428
1498
  return this.storefrontRequest(
1429
1499
  "POST",
@@ -1435,6 +1505,268 @@ var OmniSyncClient = class {
1435
1505
  `/api/v1/checkout/${checkoutId}/complete`
1436
1506
  );
1437
1507
  }
1508
+ /**
1509
+ * Check if localStorage is available (browser environment)
1510
+ */
1511
+ isLocalStorageAvailable() {
1512
+ try {
1513
+ if (typeof window === "undefined" || !window.localStorage) {
1514
+ return false;
1515
+ }
1516
+ const test = "__omni_test__";
1517
+ window.localStorage.setItem(test, test);
1518
+ window.localStorage.removeItem(test);
1519
+ return true;
1520
+ } catch {
1521
+ return false;
1522
+ }
1523
+ }
1524
+ /**
1525
+ * Get local cart from localStorage
1526
+ * Returns empty cart if none exists
1527
+ *
1528
+ * @example
1529
+ * ```typescript
1530
+ * const cart = omni.getLocalCart();
1531
+ * console.log('Items in cart:', cart.items.length);
1532
+ * ```
1533
+ */
1534
+ getLocalCart() {
1535
+ if (!this.isLocalStorageAvailable()) {
1536
+ return { items: [], updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
1537
+ }
1538
+ try {
1539
+ const stored = window.localStorage.getItem(this.LOCAL_CART_KEY);
1540
+ if (stored) {
1541
+ return JSON.parse(stored);
1542
+ }
1543
+ } catch {
1544
+ }
1545
+ return { items: [], updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
1546
+ }
1547
+ /**
1548
+ * Save local cart to localStorage
1549
+ */
1550
+ saveLocalCart(cart) {
1551
+ if (!this.isLocalStorageAvailable()) {
1552
+ return;
1553
+ }
1554
+ cart.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
1555
+ window.localStorage.setItem(this.LOCAL_CART_KEY, JSON.stringify(cart));
1556
+ }
1557
+ /**
1558
+ * Add item to local cart (NO API call)
1559
+ * If item already exists, updates quantity
1560
+ *
1561
+ * @example
1562
+ * ```typescript
1563
+ * omni.addToLocalCart({
1564
+ * productId: 'prod_123',
1565
+ * quantity: 2,
1566
+ * name: 'Cool Shirt',
1567
+ * price: '29.99',
1568
+ * });
1569
+ * ```
1570
+ */
1571
+ addToLocalCart(item) {
1572
+ const cart = this.getLocalCart();
1573
+ const existingIndex = cart.items.findIndex(
1574
+ (i) => i.productId === item.productId && i.variantId === item.variantId
1575
+ );
1576
+ if (existingIndex >= 0) {
1577
+ cart.items[existingIndex].quantity += item.quantity;
1578
+ if (item.name) cart.items[existingIndex].name = item.name;
1579
+ if (item.price) cart.items[existingIndex].price = item.price;
1580
+ if (item.image) cart.items[existingIndex].image = item.image;
1581
+ } else {
1582
+ cart.items.push({
1583
+ ...item,
1584
+ addedAt: (/* @__PURE__ */ new Date()).toISOString()
1585
+ });
1586
+ }
1587
+ this.saveLocalCart(cart);
1588
+ return cart;
1589
+ }
1590
+ /**
1591
+ * Update item quantity in local cart
1592
+ * Set quantity to 0 to remove item
1593
+ *
1594
+ * @example
1595
+ * ```typescript
1596
+ * omni.updateLocalCartItem('prod_123', 3); // Set quantity to 3
1597
+ * omni.updateLocalCartItem('prod_123', 0); // Remove item
1598
+ * ```
1599
+ */
1600
+ updateLocalCartItem(productId, quantity, variantId) {
1601
+ const cart = this.getLocalCart();
1602
+ const index = cart.items.findIndex(
1603
+ (i) => i.productId === productId && i.variantId === variantId
1604
+ );
1605
+ if (index >= 0) {
1606
+ if (quantity <= 0) {
1607
+ cart.items.splice(index, 1);
1608
+ } else {
1609
+ cart.items[index].quantity = quantity;
1610
+ }
1611
+ this.saveLocalCart(cart);
1612
+ }
1613
+ return cart;
1614
+ }
1615
+ /**
1616
+ * Remove item from local cart
1617
+ *
1618
+ * @example
1619
+ * ```typescript
1620
+ * omni.removeFromLocalCart('prod_123');
1621
+ * omni.removeFromLocalCart('prod_456', 'variant_789');
1622
+ * ```
1623
+ */
1624
+ removeFromLocalCart(productId, variantId) {
1625
+ return this.updateLocalCartItem(productId, 0, variantId);
1626
+ }
1627
+ /**
1628
+ * Clear all items from local cart
1629
+ *
1630
+ * @example
1631
+ * ```typescript
1632
+ * omni.clearLocalCart();
1633
+ * ```
1634
+ */
1635
+ clearLocalCart() {
1636
+ const cart = { items: [], updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
1637
+ this.saveLocalCart(cart);
1638
+ return cart;
1639
+ }
1640
+ /**
1641
+ * Set customer info on local cart
1642
+ *
1643
+ * @example
1644
+ * ```typescript
1645
+ * omni.setLocalCartCustomer({
1646
+ * email: 'john@example.com',
1647
+ * firstName: 'John',
1648
+ * lastName: 'Doe',
1649
+ * });
1650
+ * ```
1651
+ */
1652
+ setLocalCartCustomer(customer) {
1653
+ const cart = this.getLocalCart();
1654
+ cart.customer = customer;
1655
+ this.saveLocalCart(cart);
1656
+ return cart;
1657
+ }
1658
+ /**
1659
+ * Set shipping address on local cart
1660
+ *
1661
+ * @example
1662
+ * ```typescript
1663
+ * omni.setLocalCartShippingAddress({
1664
+ * firstName: 'John',
1665
+ * lastName: 'Doe',
1666
+ * line1: '123 Main St',
1667
+ * city: 'Tel Aviv',
1668
+ * postalCode: '6100000',
1669
+ * country: 'IL',
1670
+ * });
1671
+ * ```
1672
+ */
1673
+ setLocalCartShippingAddress(address) {
1674
+ const cart = this.getLocalCart();
1675
+ cart.shippingAddress = address;
1676
+ this.saveLocalCart(cart);
1677
+ return cart;
1678
+ }
1679
+ /**
1680
+ * Set billing address on local cart
1681
+ */
1682
+ setLocalCartBillingAddress(address) {
1683
+ const cart = this.getLocalCart();
1684
+ cart.billingAddress = address;
1685
+ this.saveLocalCart(cart);
1686
+ return cart;
1687
+ }
1688
+ /**
1689
+ * Set coupon code on local cart
1690
+ */
1691
+ setLocalCartCoupon(couponCode) {
1692
+ const cart = this.getLocalCart();
1693
+ cart.couponCode = couponCode;
1694
+ this.saveLocalCart(cart);
1695
+ return cart;
1696
+ }
1697
+ /**
1698
+ * Get total items count in local cart
1699
+ */
1700
+ getLocalCartItemCount() {
1701
+ const cart = this.getLocalCart();
1702
+ return cart.items.reduce((sum, item) => sum + item.quantity, 0);
1703
+ }
1704
+ // -------------------- Guest Order (Direct Checkout) --------------------
1705
+ /**
1706
+ * Create order directly from local cart (guest checkout)
1707
+ * This is the main checkout method for vibe-coded sites!
1708
+ * Sends cart data to server and creates order in ONE API call.
1709
+ *
1710
+ * @example
1711
+ * ```typescript
1712
+ * // Build up the local cart first
1713
+ * omni.addToLocalCart({ productId: 'prod_123', quantity: 2 });
1714
+ * omni.setLocalCartCustomer({ email: 'john@example.com', firstName: 'John' });
1715
+ * omni.setLocalCartShippingAddress({ ... });
1716
+ *
1717
+ * // Then submit the order
1718
+ * const result = await omni.submitGuestOrder();
1719
+ * console.log('Order created:', result.orderId);
1720
+ *
1721
+ * // Clear cart after successful order
1722
+ * omni.clearLocalCart();
1723
+ * ```
1724
+ */
1725
+ async submitGuestOrder(options) {
1726
+ const cart = this.getLocalCart();
1727
+ if (cart.items.length === 0) {
1728
+ throw new OmniSyncError("Cart is empty", 400);
1729
+ }
1730
+ if (!cart.customer?.email) {
1731
+ throw new OmniSyncError("Customer email is required", 400);
1732
+ }
1733
+ if (!cart.shippingAddress) {
1734
+ throw new OmniSyncError("Shipping address is required", 400);
1735
+ }
1736
+ const orderData = {
1737
+ items: cart.items.map((item) => ({
1738
+ productId: item.productId,
1739
+ variantId: item.variantId,
1740
+ quantity: item.quantity
1741
+ })),
1742
+ customer: cart.customer,
1743
+ shippingAddress: cart.shippingAddress,
1744
+ billingAddress: cart.billingAddress,
1745
+ couponCode: cart.couponCode,
1746
+ notes: cart.notes
1747
+ };
1748
+ const result = await this.vibeCodedRequest("POST", "/orders", orderData);
1749
+ if (options?.clearCartOnSuccess !== false) {
1750
+ this.clearLocalCart();
1751
+ }
1752
+ return result;
1753
+ }
1754
+ /**
1755
+ * Create order from custom data (not from local cart)
1756
+ * Use this if you manage cart state yourself
1757
+ *
1758
+ * @example
1759
+ * ```typescript
1760
+ * const result = await omni.createGuestOrder({
1761
+ * items: [{ productId: 'prod_123', quantity: 2 }],
1762
+ * customer: { email: 'john@example.com' },
1763
+ * shippingAddress: { firstName: 'John', ... },
1764
+ * });
1765
+ * ```
1766
+ */
1767
+ async createGuestOrder(data) {
1768
+ return this.vibeCodedRequest("POST", "/orders", data);
1769
+ }
1438
1770
  // -------------------- Storefront Customer Self-Service --------------------
1439
1771
  // These methods require customerToken to be set (call setCustomerToken after login)
1440
1772
  /**