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.mjs CHANGED
@@ -11,6 +11,10 @@ var DEFAULT_TIMEOUT = 3e4;
11
11
  var OmniSyncClient = class {
12
12
  constructor(options) {
13
13
  this.customerToken = null;
14
+ // -------------------- Local Cart (Client-Side for Guests) --------------------
15
+ // These methods store cart data in localStorage - NO API calls!
16
+ // Use for guest users in vibe-coded sites
17
+ this.LOCAL_CART_KEY = "omni_cart";
14
18
  if (!options.apiKey && !options.storeId && !options.connectionId) {
15
19
  throw new Error("OmniSyncClient: either connectionId, apiKey, or storeId is required");
16
20
  }
@@ -1074,6 +1078,9 @@ var OmniSyncClient = class {
1074
1078
  * ```
1075
1079
  */
1076
1080
  async createCart() {
1081
+ if (this.isVibeCodedMode()) {
1082
+ return this.vibeCodedRequest("POST", "/cart");
1083
+ }
1077
1084
  if (this.storeId && !this.apiKey) {
1078
1085
  return this.storefrontRequest("POST", "/cart");
1079
1086
  }
@@ -1113,6 +1120,9 @@ var OmniSyncClient = class {
1113
1120
  * Get a cart by ID
1114
1121
  */
1115
1122
  async getCart(cartId) {
1123
+ if (this.isVibeCodedMode()) {
1124
+ return this.vibeCodedRequest("GET", `/cart/${cartId}`);
1125
+ }
1116
1126
  if (this.storeId && !this.apiKey) {
1117
1127
  return this.storefrontRequest("GET", `/cart/${cartId}`);
1118
1128
  }
@@ -1131,6 +1141,9 @@ var OmniSyncClient = class {
1131
1141
  * ```
1132
1142
  */
1133
1143
  async addToCart(cartId, item) {
1144
+ if (this.isVibeCodedMode()) {
1145
+ return this.vibeCodedRequest("POST", `/cart/${cartId}/items`, item);
1146
+ }
1134
1147
  if (this.storeId && !this.apiKey) {
1135
1148
  return this.storefrontRequest("POST", `/cart/${cartId}/items`, item);
1136
1149
  }
@@ -1145,6 +1158,9 @@ var OmniSyncClient = class {
1145
1158
  * ```
1146
1159
  */
1147
1160
  async updateCartItem(cartId, itemId, data) {
1161
+ if (this.isVibeCodedMode()) {
1162
+ return this.vibeCodedRequest("PATCH", `/cart/${cartId}/items/${itemId}`, data);
1163
+ }
1148
1164
  if (this.storeId && !this.apiKey) {
1149
1165
  return this.storefrontRequest("PATCH", `/cart/${cartId}/items/${itemId}`, data);
1150
1166
  }
@@ -1159,6 +1175,9 @@ var OmniSyncClient = class {
1159
1175
  * ```
1160
1176
  */
1161
1177
  async removeCartItem(cartId, itemId) {
1178
+ if (this.isVibeCodedMode()) {
1179
+ return this.vibeCodedRequest("DELETE", `/cart/${cartId}/items/${itemId}`);
1180
+ }
1162
1181
  if (this.storeId && !this.apiKey) {
1163
1182
  return this.storefrontRequest("DELETE", `/cart/${cartId}/items/${itemId}`);
1164
1183
  }
@@ -1173,11 +1192,15 @@ var OmniSyncClient = class {
1173
1192
  * ```
1174
1193
  */
1175
1194
  async clearCart(cartId) {
1195
+ if (this.isVibeCodedMode()) {
1196
+ return this.vibeCodedRequest("DELETE", `/cart/${cartId}`);
1197
+ }
1176
1198
  if (this.storeId && !this.apiKey) {
1177
1199
  await this.storefrontRequest("DELETE", `/cart/${cartId}/items`);
1178
- return;
1200
+ return {};
1179
1201
  }
1180
1202
  await this.adminRequest("DELETE", `/api/v1/cart/${cartId}/items`);
1203
+ return {};
1181
1204
  }
1182
1205
  /**
1183
1206
  * Apply a coupon to the cart
@@ -1189,6 +1212,9 @@ var OmniSyncClient = class {
1189
1212
  * ```
1190
1213
  */
1191
1214
  async applyCoupon(cartId, code) {
1215
+ if (this.isVibeCodedMode()) {
1216
+ return this.vibeCodedRequest("POST", `/cart/${cartId}/coupon`, { code });
1217
+ }
1192
1218
  if (this.storeId && !this.apiKey) {
1193
1219
  return this.storefrontRequest("POST", `/cart/${cartId}/coupon`, { code });
1194
1220
  }
@@ -1203,6 +1229,9 @@ var OmniSyncClient = class {
1203
1229
  * ```
1204
1230
  */
1205
1231
  async removeCoupon(cartId) {
1232
+ if (this.isVibeCodedMode()) {
1233
+ return this.vibeCodedRequest("DELETE", `/cart/${cartId}/coupon`);
1234
+ }
1206
1235
  if (this.storeId && !this.apiKey) {
1207
1236
  return this.storefrontRequest("DELETE", `/cart/${cartId}/coupon`);
1208
1237
  }
@@ -1239,6 +1268,9 @@ var OmniSyncClient = class {
1239
1268
  * ```
1240
1269
  */
1241
1270
  async createCheckout(data) {
1271
+ if (this.isVibeCodedMode()) {
1272
+ return this.vibeCodedRequest("POST", "/checkout", data);
1273
+ }
1242
1274
  if (this.storeId && !this.apiKey) {
1243
1275
  return this.storefrontRequest("POST", "/checkout", data);
1244
1276
  }
@@ -1254,6 +1286,9 @@ var OmniSyncClient = class {
1254
1286
  * ```
1255
1287
  */
1256
1288
  async getCheckout(checkoutId) {
1289
+ if (this.isVibeCodedMode()) {
1290
+ return this.vibeCodedRequest("GET", `/checkout/${checkoutId}`);
1291
+ }
1257
1292
  if (this.storeId && !this.apiKey) {
1258
1293
  return this.storefrontRequest("GET", `/checkout/${checkoutId}`);
1259
1294
  }
@@ -1272,6 +1307,9 @@ var OmniSyncClient = class {
1272
1307
  * ```
1273
1308
  */
1274
1309
  async setCheckoutCustomer(checkoutId, data) {
1310
+ if (this.isVibeCodedMode()) {
1311
+ return this.vibeCodedRequest("PATCH", `/checkout/${checkoutId}/customer`, data);
1312
+ }
1275
1313
  if (this.storeId && !this.apiKey) {
1276
1314
  return this.storefrontRequest("PATCH", `/checkout/${checkoutId}/customer`, data);
1277
1315
  }
@@ -1296,6 +1334,13 @@ var OmniSyncClient = class {
1296
1334
  * ```
1297
1335
  */
1298
1336
  async setShippingAddress(checkoutId, address) {
1337
+ if (this.isVibeCodedMode()) {
1338
+ return this.vibeCodedRequest(
1339
+ "PATCH",
1340
+ `/checkout/${checkoutId}/shipping-address`,
1341
+ address
1342
+ );
1343
+ }
1299
1344
  if (this.storeId && !this.apiKey) {
1300
1345
  return this.storefrontRequest(
1301
1346
  "PATCH",
@@ -1320,6 +1365,13 @@ var OmniSyncClient = class {
1320
1365
  * ```
1321
1366
  */
1322
1367
  async getShippingRates(checkoutId) {
1368
+ if (this.isVibeCodedMode()) {
1369
+ const result = await this.vibeCodedRequest(
1370
+ "GET",
1371
+ `/checkout/${checkoutId}/shipping-rates`
1372
+ );
1373
+ return result.rates;
1374
+ }
1323
1375
  if (this.storeId && !this.apiKey) {
1324
1376
  return this.storefrontRequest(
1325
1377
  "GET",
@@ -1341,6 +1393,11 @@ var OmniSyncClient = class {
1341
1393
  * ```
1342
1394
  */
1343
1395
  async selectShippingMethod(checkoutId, shippingRateId) {
1396
+ if (this.isVibeCodedMode()) {
1397
+ return this.vibeCodedRequest("PATCH", `/checkout/${checkoutId}/shipping-method`, {
1398
+ shippingMethodId: shippingRateId
1399
+ });
1400
+ }
1344
1401
  if (this.storeId && !this.apiKey) {
1345
1402
  return this.storefrontRequest("PATCH", `/checkout/${checkoutId}/shipping-method`, {
1346
1403
  shippingRateId
@@ -1375,6 +1432,13 @@ var OmniSyncClient = class {
1375
1432
  * ```
1376
1433
  */
1377
1434
  async setBillingAddress(checkoutId, address) {
1435
+ if (this.isVibeCodedMode()) {
1436
+ return this.vibeCodedRequest(
1437
+ "PATCH",
1438
+ `/checkout/${checkoutId}/billing-address`,
1439
+ address
1440
+ );
1441
+ }
1378
1442
  if (this.storeId && !this.apiKey) {
1379
1443
  return this.storefrontRequest(
1380
1444
  "PATCH",
@@ -1399,6 +1463,12 @@ var OmniSyncClient = class {
1399
1463
  * ```
1400
1464
  */
1401
1465
  async completeCheckout(checkoutId) {
1466
+ if (this.isVibeCodedMode()) {
1467
+ return this.vibeCodedRequest(
1468
+ "POST",
1469
+ `/checkout/${checkoutId}/complete`
1470
+ );
1471
+ }
1402
1472
  if (this.storeId && !this.apiKey) {
1403
1473
  return this.storefrontRequest(
1404
1474
  "POST",
@@ -1410,6 +1480,268 @@ var OmniSyncClient = class {
1410
1480
  `/api/v1/checkout/${checkoutId}/complete`
1411
1481
  );
1412
1482
  }
1483
+ /**
1484
+ * Check if localStorage is available (browser environment)
1485
+ */
1486
+ isLocalStorageAvailable() {
1487
+ try {
1488
+ if (typeof window === "undefined" || !window.localStorage) {
1489
+ return false;
1490
+ }
1491
+ const test = "__omni_test__";
1492
+ window.localStorage.setItem(test, test);
1493
+ window.localStorage.removeItem(test);
1494
+ return true;
1495
+ } catch {
1496
+ return false;
1497
+ }
1498
+ }
1499
+ /**
1500
+ * Get local cart from localStorage
1501
+ * Returns empty cart if none exists
1502
+ *
1503
+ * @example
1504
+ * ```typescript
1505
+ * const cart = omni.getLocalCart();
1506
+ * console.log('Items in cart:', cart.items.length);
1507
+ * ```
1508
+ */
1509
+ getLocalCart() {
1510
+ if (!this.isLocalStorageAvailable()) {
1511
+ return { items: [], updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
1512
+ }
1513
+ try {
1514
+ const stored = window.localStorage.getItem(this.LOCAL_CART_KEY);
1515
+ if (stored) {
1516
+ return JSON.parse(stored);
1517
+ }
1518
+ } catch {
1519
+ }
1520
+ return { items: [], updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
1521
+ }
1522
+ /**
1523
+ * Save local cart to localStorage
1524
+ */
1525
+ saveLocalCart(cart) {
1526
+ if (!this.isLocalStorageAvailable()) {
1527
+ return;
1528
+ }
1529
+ cart.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
1530
+ window.localStorage.setItem(this.LOCAL_CART_KEY, JSON.stringify(cart));
1531
+ }
1532
+ /**
1533
+ * Add item to local cart (NO API call)
1534
+ * If item already exists, updates quantity
1535
+ *
1536
+ * @example
1537
+ * ```typescript
1538
+ * omni.addToLocalCart({
1539
+ * productId: 'prod_123',
1540
+ * quantity: 2,
1541
+ * name: 'Cool Shirt',
1542
+ * price: '29.99',
1543
+ * });
1544
+ * ```
1545
+ */
1546
+ addToLocalCart(item) {
1547
+ const cart = this.getLocalCart();
1548
+ const existingIndex = cart.items.findIndex(
1549
+ (i) => i.productId === item.productId && i.variantId === item.variantId
1550
+ );
1551
+ if (existingIndex >= 0) {
1552
+ cart.items[existingIndex].quantity += item.quantity;
1553
+ if (item.name) cart.items[existingIndex].name = item.name;
1554
+ if (item.price) cart.items[existingIndex].price = item.price;
1555
+ if (item.image) cart.items[existingIndex].image = item.image;
1556
+ } else {
1557
+ cart.items.push({
1558
+ ...item,
1559
+ addedAt: (/* @__PURE__ */ new Date()).toISOString()
1560
+ });
1561
+ }
1562
+ this.saveLocalCart(cart);
1563
+ return cart;
1564
+ }
1565
+ /**
1566
+ * Update item quantity in local cart
1567
+ * Set quantity to 0 to remove item
1568
+ *
1569
+ * @example
1570
+ * ```typescript
1571
+ * omni.updateLocalCartItem('prod_123', 3); // Set quantity to 3
1572
+ * omni.updateLocalCartItem('prod_123', 0); // Remove item
1573
+ * ```
1574
+ */
1575
+ updateLocalCartItem(productId, quantity, variantId) {
1576
+ const cart = this.getLocalCart();
1577
+ const index = cart.items.findIndex(
1578
+ (i) => i.productId === productId && i.variantId === variantId
1579
+ );
1580
+ if (index >= 0) {
1581
+ if (quantity <= 0) {
1582
+ cart.items.splice(index, 1);
1583
+ } else {
1584
+ cart.items[index].quantity = quantity;
1585
+ }
1586
+ this.saveLocalCart(cart);
1587
+ }
1588
+ return cart;
1589
+ }
1590
+ /**
1591
+ * Remove item from local cart
1592
+ *
1593
+ * @example
1594
+ * ```typescript
1595
+ * omni.removeFromLocalCart('prod_123');
1596
+ * omni.removeFromLocalCart('prod_456', 'variant_789');
1597
+ * ```
1598
+ */
1599
+ removeFromLocalCart(productId, variantId) {
1600
+ return this.updateLocalCartItem(productId, 0, variantId);
1601
+ }
1602
+ /**
1603
+ * Clear all items from local cart
1604
+ *
1605
+ * @example
1606
+ * ```typescript
1607
+ * omni.clearLocalCart();
1608
+ * ```
1609
+ */
1610
+ clearLocalCart() {
1611
+ const cart = { items: [], updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
1612
+ this.saveLocalCart(cart);
1613
+ return cart;
1614
+ }
1615
+ /**
1616
+ * Set customer info on local cart
1617
+ *
1618
+ * @example
1619
+ * ```typescript
1620
+ * omni.setLocalCartCustomer({
1621
+ * email: 'john@example.com',
1622
+ * firstName: 'John',
1623
+ * lastName: 'Doe',
1624
+ * });
1625
+ * ```
1626
+ */
1627
+ setLocalCartCustomer(customer) {
1628
+ const cart = this.getLocalCart();
1629
+ cart.customer = customer;
1630
+ this.saveLocalCart(cart);
1631
+ return cart;
1632
+ }
1633
+ /**
1634
+ * Set shipping address on local cart
1635
+ *
1636
+ * @example
1637
+ * ```typescript
1638
+ * omni.setLocalCartShippingAddress({
1639
+ * firstName: 'John',
1640
+ * lastName: 'Doe',
1641
+ * line1: '123 Main St',
1642
+ * city: 'Tel Aviv',
1643
+ * postalCode: '6100000',
1644
+ * country: 'IL',
1645
+ * });
1646
+ * ```
1647
+ */
1648
+ setLocalCartShippingAddress(address) {
1649
+ const cart = this.getLocalCart();
1650
+ cart.shippingAddress = address;
1651
+ this.saveLocalCart(cart);
1652
+ return cart;
1653
+ }
1654
+ /**
1655
+ * Set billing address on local cart
1656
+ */
1657
+ setLocalCartBillingAddress(address) {
1658
+ const cart = this.getLocalCart();
1659
+ cart.billingAddress = address;
1660
+ this.saveLocalCart(cart);
1661
+ return cart;
1662
+ }
1663
+ /**
1664
+ * Set coupon code on local cart
1665
+ */
1666
+ setLocalCartCoupon(couponCode) {
1667
+ const cart = this.getLocalCart();
1668
+ cart.couponCode = couponCode;
1669
+ this.saveLocalCart(cart);
1670
+ return cart;
1671
+ }
1672
+ /**
1673
+ * Get total items count in local cart
1674
+ */
1675
+ getLocalCartItemCount() {
1676
+ const cart = this.getLocalCart();
1677
+ return cart.items.reduce((sum, item) => sum + item.quantity, 0);
1678
+ }
1679
+ // -------------------- Guest Order (Direct Checkout) --------------------
1680
+ /**
1681
+ * Create order directly from local cart (guest checkout)
1682
+ * This is the main checkout method for vibe-coded sites!
1683
+ * Sends cart data to server and creates order in ONE API call.
1684
+ *
1685
+ * @example
1686
+ * ```typescript
1687
+ * // Build up the local cart first
1688
+ * omni.addToLocalCart({ productId: 'prod_123', quantity: 2 });
1689
+ * omni.setLocalCartCustomer({ email: 'john@example.com', firstName: 'John' });
1690
+ * omni.setLocalCartShippingAddress({ ... });
1691
+ *
1692
+ * // Then submit the order
1693
+ * const result = await omni.submitGuestOrder();
1694
+ * console.log('Order created:', result.orderId);
1695
+ *
1696
+ * // Clear cart after successful order
1697
+ * omni.clearLocalCart();
1698
+ * ```
1699
+ */
1700
+ async submitGuestOrder(options) {
1701
+ const cart = this.getLocalCart();
1702
+ if (cart.items.length === 0) {
1703
+ throw new OmniSyncError("Cart is empty", 400);
1704
+ }
1705
+ if (!cart.customer?.email) {
1706
+ throw new OmniSyncError("Customer email is required", 400);
1707
+ }
1708
+ if (!cart.shippingAddress) {
1709
+ throw new OmniSyncError("Shipping address is required", 400);
1710
+ }
1711
+ const orderData = {
1712
+ items: cart.items.map((item) => ({
1713
+ productId: item.productId,
1714
+ variantId: item.variantId,
1715
+ quantity: item.quantity
1716
+ })),
1717
+ customer: cart.customer,
1718
+ shippingAddress: cart.shippingAddress,
1719
+ billingAddress: cart.billingAddress,
1720
+ couponCode: cart.couponCode,
1721
+ notes: cart.notes
1722
+ };
1723
+ const result = await this.vibeCodedRequest("POST", "/orders", orderData);
1724
+ if (options?.clearCartOnSuccess !== false) {
1725
+ this.clearLocalCart();
1726
+ }
1727
+ return result;
1728
+ }
1729
+ /**
1730
+ * Create order from custom data (not from local cart)
1731
+ * Use this if you manage cart state yourself
1732
+ *
1733
+ * @example
1734
+ * ```typescript
1735
+ * const result = await omni.createGuestOrder({
1736
+ * items: [{ productId: 'prod_123', quantity: 2 }],
1737
+ * customer: { email: 'john@example.com' },
1738
+ * shippingAddress: { firstName: 'John', ... },
1739
+ * });
1740
+ * ```
1741
+ */
1742
+ async createGuestOrder(data) {
1743
+ return this.vibeCodedRequest("POST", "/orders", data);
1744
+ }
1413
1745
  // -------------------- Storefront Customer Self-Service --------------------
1414
1746
  // These methods require customerToken to be set (call setCustomerToken after login)
1415
1747
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omni-sync-sdk",
3
- "version": "0.4.1",
3
+ "version": "0.6.0",
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",