omni-sync-sdk 0.14.2 → 0.14.3

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 CHANGED
@@ -479,7 +479,7 @@ function SearchInput() {
479
479
  {suggestions && (
480
480
  <div className="suggestions">
481
481
  {suggestions.products.map((product) => (
482
- <a key={product.id} href={`/products/${product.id}`}>
482
+ <a key={product.id} href={`/products/${product.slug}`}>
483
483
  <img src={product.image || '/placeholder.png'} alt={product.name} />
484
484
  <span>{product.name}</span>
485
485
  <span>${product.basePrice}</span>
@@ -2128,7 +2128,7 @@ export default function HomePage() {
2128
2128
  return (
2129
2129
  <div className="grid grid-cols-2 md:grid-cols-4 gap-6">
2130
2130
  {products.map((product) => (
2131
- <a key={product.id} href={`/products/${product.id}`} className="group">
2131
+ <a key={product.id} href={`/products/${product.slug}`} className="group">
2132
2132
  <img
2133
2133
  src={product.images?.[0]?.url || '/placeholder.jpg'}
2134
2134
  alt={product.name}
@@ -2185,7 +2185,7 @@ export default function ProductsPage() {
2185
2185
  <div>
2186
2186
  <div className="grid grid-cols-3 gap-6">
2187
2187
  {data.data.map((product) => (
2188
- <a key={product.id} href={`/products/${product.id}`}>
2188
+ <a key={product.id} href={`/products/${product.slug}`}>
2189
2189
  <img src={product.images?.[0]?.url} alt={product.name} />
2190
2190
  <h3>{product.name}</h3>
2191
2191
  <p>${product.salePrice || product.basePrice}</p>
@@ -2217,7 +2217,8 @@ import { omni } from '@/lib/omni-sync';
2217
2217
  import { isHtmlDescription } from 'omni-sync-sdk';
2218
2218
  import type { Product } from 'omni-sync-sdk';
2219
2219
 
2220
- export default function ProductPage({ params }: { params: { id: string } }) {
2220
+ // Route: /products/[slug]/page.tsx - uses URL-friendly slug instead of ID
2221
+ export default function ProductPage({ params }: { params: { slug: string } }) {
2221
2222
  const [product, setProduct] = useState<Product | null>(null);
2222
2223
  const [selectedVariant, setSelectedVariant] = useState<string | null>(null);
2223
2224
  const [quantity, setQuantity] = useState(1);
@@ -2226,7 +2227,8 @@ export default function ProductPage({ params }: { params: { id: string } }) {
2226
2227
  useEffect(() => {
2227
2228
  async function load() {
2228
2229
  try {
2229
- const p = await omni.getProduct(params.id);
2230
+ // Use getProductBySlug for SEO-friendly URLs
2231
+ const p = await omni.getProductBySlug(params.slug);
2230
2232
  setProduct(p);
2231
2233
  if (p.variants && p.variants.length > 0) {
2232
2234
  setSelectedVariant(p.variants[0].id);
@@ -2236,7 +2238,7 @@ export default function ProductPage({ params }: { params: { id: string } }) {
2236
2238
  }
2237
2239
  }
2238
2240
  load();
2239
- }, [params.id]);
2241
+ }, [params.slug]);
2240
2242
 
2241
2243
  const handleAddToCart = () => {
2242
2244
  if (!product) return;
@@ -3336,7 +3338,7 @@ When building a store, implement these pages:
3336
3338
 
3337
3339
  - [ ] **Home** (`/`) - Product grid
3338
3340
  - [ ] **Products** (`/products`) - Product list with pagination
3339
- - [ ] **Product Detail** (`/products/[id]`) - Single product with Add to Cart
3341
+ - [ ] **Product Detail** (`/products/[slug]`) - Single product with Add to Cart (use `getProductBySlug(slug)`)
3340
3342
  - [ ] **Cart** (`/cart`) - Cart items, update quantity, remove
3341
3343
  - [ ] **Checkout** (`/checkout`) - Multi-step checkout flow
3342
3344
  - [ ] **⚠️ Payment** (`/checkout/payment`) - **REQUIRED!** Use `getPaymentProviders()` to show Stripe/PayPal forms
package/dist/index.d.mts CHANGED
@@ -349,6 +349,7 @@ interface ProductQueryParams {
349
349
  interface ProductSuggestion {
350
350
  id: string;
351
351
  name: string;
352
+ slug: string | null;
352
353
  image: string | null;
353
354
  basePrice: number;
354
355
  salePrice?: number | null;
@@ -914,6 +915,12 @@ interface Cart {
914
915
  createdAt: string;
915
916
  /** ISO timestamp when cart was last updated */
916
917
  updatedAt: string;
918
+ /**
919
+ * Reservation information (only present when reservation strategy is ON_CART).
920
+ * Use this to display countdown timer to customers.
921
+ * @see ReservationInfo
922
+ */
923
+ reservation?: ReservationInfo;
917
924
  }
918
925
  interface AddToCartDto {
919
926
  productId: string;
@@ -1342,6 +1349,12 @@ interface Checkout {
1342
1349
  createdAt: string;
1343
1350
  /** Last update timestamp */
1344
1351
  updatedAt: string;
1352
+ /**
1353
+ * Reservation information (present when reservation strategy is ON_CHECKOUT or ON_CART).
1354
+ * Use this to display countdown timer to customers.
1355
+ * @see ReservationInfo
1356
+ */
1357
+ reservation?: ReservationInfo;
1345
1358
  }
1346
1359
  interface CreateCheckoutDto {
1347
1360
  cartId: string;
@@ -1667,6 +1680,8 @@ interface PaymentProviderConfig {
1667
1680
  name: string;
1668
1681
  /** Public/publishable key (safe to expose) */
1669
1682
  publicKey: string;
1683
+ /** Stripe Connect account ID (for OAuth-connected accounts) */
1684
+ stripeAccountId?: string;
1670
1685
  /** Supported payment methods: ['card', 'ideal', 'bancontact'] */
1671
1686
  supportedMethods: string[];
1672
1687
  /** Whether this is test/sandbox mode */
@@ -1692,7 +1707,10 @@ interface PaymentProviderConfig {
1692
1707
  * const paypalProvider = providers.find(p => p.provider === 'paypal');
1693
1708
  *
1694
1709
  * if (stripeProvider) {
1695
- * // Initialize Stripe.js with stripeProvider.publicKey
1710
+ * // Initialize Stripe.js with options for Connect
1711
+ * const stripe = await loadStripe(stripeProvider.publicKey, {
1712
+ * stripeAccount: stripeProvider.stripeAccountId, // For Stripe Connect
1713
+ * });
1696
1714
  * }
1697
1715
  * if (paypalProvider) {
1698
1716
  * // Initialize PayPal SDK with paypalProvider.publicKey as clientId
@@ -1756,6 +1774,83 @@ interface PaymentStatus {
1756
1774
  /** Payment intent ID from provider */
1757
1775
  paymentIntentId?: string;
1758
1776
  }
1777
+ /**
1778
+ * When inventory is reserved for customers.
1779
+ * Configured per vibe-coded connection by the store owner.
1780
+ *
1781
+ * - ON_PAYMENT: Stock is only reserved when payment is completed (default, safest)
1782
+ * - ON_CHECKOUT: Stock is reserved when checkout is created
1783
+ * - ON_CART: Stock is reserved immediately when added to cart (most aggressive)
1784
+ */
1785
+ type InventoryReservationStrategy = 'ON_PAYMENT' | 'ON_CHECKOUT' | 'ON_CART';
1786
+ /**
1787
+ * Information about a customer's inventory reservation.
1788
+ * Included in cart/checkout responses when reservations are active.
1789
+ *
1790
+ * @example
1791
+ * ```typescript
1792
+ * const cart = await omni.getCart(cartId);
1793
+ * if (cart.reservation?.hasReservation) {
1794
+ * const remaining = cart.reservation.remainingSeconds;
1795
+ * console.log(`Items reserved for ${remaining} seconds`);
1796
+ * }
1797
+ * ```
1798
+ */
1799
+ interface ReservationInfo {
1800
+ /** Whether there is an active reservation */
1801
+ hasReservation: boolean;
1802
+ /** ISO timestamp when reservation expires */
1803
+ expiresAt?: string;
1804
+ /** Remaining time in seconds before reservation expires */
1805
+ remainingSeconds?: number;
1806
+ /** The reservation strategy in use */
1807
+ strategy: InventoryReservationStrategy;
1808
+ /** Custom message from store owner (supports {time} placeholder) */
1809
+ countdownMessage?: string;
1810
+ }
1811
+ /**
1812
+ * Product availability including reserved quantities.
1813
+ * Use this to show accurate stock to customers when reservations are enabled.
1814
+ *
1815
+ * @example
1816
+ * ```typescript
1817
+ * const availability = await omni.getAvailability(['prod_123', 'prod_456']);
1818
+ * availability.forEach(item => {
1819
+ * if (!item.canPurchase) {
1820
+ * console.log(`${item.productId}: Cannot purchase`);
1821
+ * } else if (item.lowStock) {
1822
+ * console.log(`${item.productId}: Only ${item.available} left!`);
1823
+ * }
1824
+ * });
1825
+ * ```
1826
+ */
1827
+ interface ProductAvailability {
1828
+ /** Product ID */
1829
+ productId: string;
1830
+ /** Variant ID (null for simple products) */
1831
+ variantId?: string | null;
1832
+ /** Inventory tracking mode */
1833
+ trackingMode: InventoryTrackingMode;
1834
+ /** Total stock quantity */
1835
+ total: number;
1836
+ /** Quantity currently reserved by other customers */
1837
+ reserved: number;
1838
+ /** Available for purchase (total - reserved) */
1839
+ available: number;
1840
+ /** Whether the product can be purchased */
1841
+ canPurchase: boolean;
1842
+ /** Whether stock is below low stock threshold */
1843
+ lowStock?: boolean;
1844
+ }
1845
+ /**
1846
+ * Response from extending a reservation
1847
+ */
1848
+ interface ExtendReservationResponse {
1849
+ /** Whether the extension was successful */
1850
+ success: boolean;
1851
+ /** Updated reservation info */
1852
+ reservation: ReservationInfo;
1853
+ }
1759
1854
  interface OmniSyncApiError {
1760
1855
  statusCode: number;
1761
1856
  message: string;
@@ -2992,9 +3087,11 @@ declare class OmniSyncClient {
2992
3087
  * const stripeProvider = providers.find(p => p.provider === 'stripe');
2993
3088
  * const paypalProvider = providers.find(p => p.provider === 'paypal');
2994
3089
  *
2995
- * // Initialize Stripe if available
3090
+ * // Initialize Stripe if available (with Connect account support)
2996
3091
  * if (stripeProvider) {
2997
- * const stripe = await loadStripe(stripeProvider.publicKey);
3092
+ * const stripe = await loadStripe(stripeProvider.publicKey, {
3093
+ * stripeAccount: stripeProvider.stripeAccountId, // For Stripe Connect
3094
+ * });
2998
3095
  * // Show Stripe payment form
2999
3096
  * }
3000
3097
  *
@@ -3398,6 +3495,72 @@ declare class OmniSyncClient {
3398
3495
  * ```
3399
3496
  */
3400
3497
  testCustomApiConnection(integrationId: string): Promise<CustomApiTestResult>;
3498
+ /**
3499
+ * Get product availability including reserved quantities.
3500
+ * Use this to show accurate stock to customers when reservations are enabled.
3501
+ *
3502
+ * **Vibe-coded mode only** - requires connectionId
3503
+ *
3504
+ * @param productIds - Array of product IDs to check availability for
3505
+ * @returns Array of availability info for each product
3506
+ *
3507
+ * @example
3508
+ * ```typescript
3509
+ * const availability = await omni.getAvailability(['prod_123', 'prod_456']);
3510
+ * availability.forEach(item => {
3511
+ * if (!item.canPurchase) {
3512
+ * console.log(`${item.productId}: Cannot purchase`);
3513
+ * } else if (item.lowStock) {
3514
+ * console.log(`${item.productId}: Only ${item.available} left!`);
3515
+ * } else {
3516
+ * console.log(`${item.productId}: ${item.available} available`);
3517
+ * }
3518
+ * });
3519
+ * ```
3520
+ */
3521
+ getAvailability(productIds: string[]): Promise<ProductAvailability[]>;
3522
+ /**
3523
+ * Extend an active reservation to prevent it from expiring.
3524
+ * Call this when a customer is still active in checkout to keep their items reserved.
3525
+ *
3526
+ * **Vibe-coded mode only** - requires connectionId
3527
+ * Only works when reservation strategy is ON_CART or ON_CHECKOUT
3528
+ *
3529
+ * @param options - Either cartId or checkoutId to identify the reservation
3530
+ * @returns Updated reservation info
3531
+ *
3532
+ * @example
3533
+ * ```typescript
3534
+ * // Extend reservation when customer shows activity
3535
+ * const result = await omni.extendReservation({ checkoutId: 'chk_123' });
3536
+ * if (result.success) {
3537
+ * console.log(`Reservation extended until ${result.reservation.expiresAt}`);
3538
+ * }
3539
+ * ```
3540
+ */
3541
+ extendReservation(options: {
3542
+ cartId?: string;
3543
+ checkoutId?: string;
3544
+ }): Promise<ExtendReservationResponse>;
3545
+ /**
3546
+ * Release an active reservation, returning items to available stock.
3547
+ * Call this when a customer abandons their cart/checkout.
3548
+ *
3549
+ * **Vibe-coded mode only** - requires connectionId
3550
+ * Only works when reservation strategy is ON_CART or ON_CHECKOUT
3551
+ *
3552
+ * @param options - Either cartId or checkoutId to identify the reservation
3553
+ *
3554
+ * @example
3555
+ * ```typescript
3556
+ * // Release reservation when customer abandons checkout
3557
+ * await omni.releaseReservation({ checkoutId: 'chk_123' });
3558
+ * ```
3559
+ */
3560
+ releaseReservation(options: {
3561
+ cartId?: string;
3562
+ checkoutId?: string;
3563
+ }): Promise<void>;
3401
3564
  }
3402
3565
  /**
3403
3566
  * Custom error class for Omni-Sync API errors
package/dist/index.d.ts CHANGED
@@ -349,6 +349,7 @@ interface ProductQueryParams {
349
349
  interface ProductSuggestion {
350
350
  id: string;
351
351
  name: string;
352
+ slug: string | null;
352
353
  image: string | null;
353
354
  basePrice: number;
354
355
  salePrice?: number | null;
@@ -914,6 +915,12 @@ interface Cart {
914
915
  createdAt: string;
915
916
  /** ISO timestamp when cart was last updated */
916
917
  updatedAt: string;
918
+ /**
919
+ * Reservation information (only present when reservation strategy is ON_CART).
920
+ * Use this to display countdown timer to customers.
921
+ * @see ReservationInfo
922
+ */
923
+ reservation?: ReservationInfo;
917
924
  }
918
925
  interface AddToCartDto {
919
926
  productId: string;
@@ -1342,6 +1349,12 @@ interface Checkout {
1342
1349
  createdAt: string;
1343
1350
  /** Last update timestamp */
1344
1351
  updatedAt: string;
1352
+ /**
1353
+ * Reservation information (present when reservation strategy is ON_CHECKOUT or ON_CART).
1354
+ * Use this to display countdown timer to customers.
1355
+ * @see ReservationInfo
1356
+ */
1357
+ reservation?: ReservationInfo;
1345
1358
  }
1346
1359
  interface CreateCheckoutDto {
1347
1360
  cartId: string;
@@ -1667,6 +1680,8 @@ interface PaymentProviderConfig {
1667
1680
  name: string;
1668
1681
  /** Public/publishable key (safe to expose) */
1669
1682
  publicKey: string;
1683
+ /** Stripe Connect account ID (for OAuth-connected accounts) */
1684
+ stripeAccountId?: string;
1670
1685
  /** Supported payment methods: ['card', 'ideal', 'bancontact'] */
1671
1686
  supportedMethods: string[];
1672
1687
  /** Whether this is test/sandbox mode */
@@ -1692,7 +1707,10 @@ interface PaymentProviderConfig {
1692
1707
  * const paypalProvider = providers.find(p => p.provider === 'paypal');
1693
1708
  *
1694
1709
  * if (stripeProvider) {
1695
- * // Initialize Stripe.js with stripeProvider.publicKey
1710
+ * // Initialize Stripe.js with options for Connect
1711
+ * const stripe = await loadStripe(stripeProvider.publicKey, {
1712
+ * stripeAccount: stripeProvider.stripeAccountId, // For Stripe Connect
1713
+ * });
1696
1714
  * }
1697
1715
  * if (paypalProvider) {
1698
1716
  * // Initialize PayPal SDK with paypalProvider.publicKey as clientId
@@ -1756,6 +1774,83 @@ interface PaymentStatus {
1756
1774
  /** Payment intent ID from provider */
1757
1775
  paymentIntentId?: string;
1758
1776
  }
1777
+ /**
1778
+ * When inventory is reserved for customers.
1779
+ * Configured per vibe-coded connection by the store owner.
1780
+ *
1781
+ * - ON_PAYMENT: Stock is only reserved when payment is completed (default, safest)
1782
+ * - ON_CHECKOUT: Stock is reserved when checkout is created
1783
+ * - ON_CART: Stock is reserved immediately when added to cart (most aggressive)
1784
+ */
1785
+ type InventoryReservationStrategy = 'ON_PAYMENT' | 'ON_CHECKOUT' | 'ON_CART';
1786
+ /**
1787
+ * Information about a customer's inventory reservation.
1788
+ * Included in cart/checkout responses when reservations are active.
1789
+ *
1790
+ * @example
1791
+ * ```typescript
1792
+ * const cart = await omni.getCart(cartId);
1793
+ * if (cart.reservation?.hasReservation) {
1794
+ * const remaining = cart.reservation.remainingSeconds;
1795
+ * console.log(`Items reserved for ${remaining} seconds`);
1796
+ * }
1797
+ * ```
1798
+ */
1799
+ interface ReservationInfo {
1800
+ /** Whether there is an active reservation */
1801
+ hasReservation: boolean;
1802
+ /** ISO timestamp when reservation expires */
1803
+ expiresAt?: string;
1804
+ /** Remaining time in seconds before reservation expires */
1805
+ remainingSeconds?: number;
1806
+ /** The reservation strategy in use */
1807
+ strategy: InventoryReservationStrategy;
1808
+ /** Custom message from store owner (supports {time} placeholder) */
1809
+ countdownMessage?: string;
1810
+ }
1811
+ /**
1812
+ * Product availability including reserved quantities.
1813
+ * Use this to show accurate stock to customers when reservations are enabled.
1814
+ *
1815
+ * @example
1816
+ * ```typescript
1817
+ * const availability = await omni.getAvailability(['prod_123', 'prod_456']);
1818
+ * availability.forEach(item => {
1819
+ * if (!item.canPurchase) {
1820
+ * console.log(`${item.productId}: Cannot purchase`);
1821
+ * } else if (item.lowStock) {
1822
+ * console.log(`${item.productId}: Only ${item.available} left!`);
1823
+ * }
1824
+ * });
1825
+ * ```
1826
+ */
1827
+ interface ProductAvailability {
1828
+ /** Product ID */
1829
+ productId: string;
1830
+ /** Variant ID (null for simple products) */
1831
+ variantId?: string | null;
1832
+ /** Inventory tracking mode */
1833
+ trackingMode: InventoryTrackingMode;
1834
+ /** Total stock quantity */
1835
+ total: number;
1836
+ /** Quantity currently reserved by other customers */
1837
+ reserved: number;
1838
+ /** Available for purchase (total - reserved) */
1839
+ available: number;
1840
+ /** Whether the product can be purchased */
1841
+ canPurchase: boolean;
1842
+ /** Whether stock is below low stock threshold */
1843
+ lowStock?: boolean;
1844
+ }
1845
+ /**
1846
+ * Response from extending a reservation
1847
+ */
1848
+ interface ExtendReservationResponse {
1849
+ /** Whether the extension was successful */
1850
+ success: boolean;
1851
+ /** Updated reservation info */
1852
+ reservation: ReservationInfo;
1853
+ }
1759
1854
  interface OmniSyncApiError {
1760
1855
  statusCode: number;
1761
1856
  message: string;
@@ -2992,9 +3087,11 @@ declare class OmniSyncClient {
2992
3087
  * const stripeProvider = providers.find(p => p.provider === 'stripe');
2993
3088
  * const paypalProvider = providers.find(p => p.provider === 'paypal');
2994
3089
  *
2995
- * // Initialize Stripe if available
3090
+ * // Initialize Stripe if available (with Connect account support)
2996
3091
  * if (stripeProvider) {
2997
- * const stripe = await loadStripe(stripeProvider.publicKey);
3092
+ * const stripe = await loadStripe(stripeProvider.publicKey, {
3093
+ * stripeAccount: stripeProvider.stripeAccountId, // For Stripe Connect
3094
+ * });
2998
3095
  * // Show Stripe payment form
2999
3096
  * }
3000
3097
  *
@@ -3398,6 +3495,72 @@ declare class OmniSyncClient {
3398
3495
  * ```
3399
3496
  */
3400
3497
  testCustomApiConnection(integrationId: string): Promise<CustomApiTestResult>;
3498
+ /**
3499
+ * Get product availability including reserved quantities.
3500
+ * Use this to show accurate stock to customers when reservations are enabled.
3501
+ *
3502
+ * **Vibe-coded mode only** - requires connectionId
3503
+ *
3504
+ * @param productIds - Array of product IDs to check availability for
3505
+ * @returns Array of availability info for each product
3506
+ *
3507
+ * @example
3508
+ * ```typescript
3509
+ * const availability = await omni.getAvailability(['prod_123', 'prod_456']);
3510
+ * availability.forEach(item => {
3511
+ * if (!item.canPurchase) {
3512
+ * console.log(`${item.productId}: Cannot purchase`);
3513
+ * } else if (item.lowStock) {
3514
+ * console.log(`${item.productId}: Only ${item.available} left!`);
3515
+ * } else {
3516
+ * console.log(`${item.productId}: ${item.available} available`);
3517
+ * }
3518
+ * });
3519
+ * ```
3520
+ */
3521
+ getAvailability(productIds: string[]): Promise<ProductAvailability[]>;
3522
+ /**
3523
+ * Extend an active reservation to prevent it from expiring.
3524
+ * Call this when a customer is still active in checkout to keep their items reserved.
3525
+ *
3526
+ * **Vibe-coded mode only** - requires connectionId
3527
+ * Only works when reservation strategy is ON_CART or ON_CHECKOUT
3528
+ *
3529
+ * @param options - Either cartId or checkoutId to identify the reservation
3530
+ * @returns Updated reservation info
3531
+ *
3532
+ * @example
3533
+ * ```typescript
3534
+ * // Extend reservation when customer shows activity
3535
+ * const result = await omni.extendReservation({ checkoutId: 'chk_123' });
3536
+ * if (result.success) {
3537
+ * console.log(`Reservation extended until ${result.reservation.expiresAt}`);
3538
+ * }
3539
+ * ```
3540
+ */
3541
+ extendReservation(options: {
3542
+ cartId?: string;
3543
+ checkoutId?: string;
3544
+ }): Promise<ExtendReservationResponse>;
3545
+ /**
3546
+ * Release an active reservation, returning items to available stock.
3547
+ * Call this when a customer abandons their cart/checkout.
3548
+ *
3549
+ * **Vibe-coded mode only** - requires connectionId
3550
+ * Only works when reservation strategy is ON_CART or ON_CHECKOUT
3551
+ *
3552
+ * @param options - Either cartId or checkoutId to identify the reservation
3553
+ *
3554
+ * @example
3555
+ * ```typescript
3556
+ * // Release reservation when customer abandons checkout
3557
+ * await omni.releaseReservation({ checkoutId: 'chk_123' });
3558
+ * ```
3559
+ */
3560
+ releaseReservation(options: {
3561
+ cartId?: string;
3562
+ checkoutId?: string;
3563
+ }): Promise<void>;
3401
3564
  }
3402
3565
  /**
3403
3566
  * Custom error class for Omni-Sync API errors
package/dist/index.js CHANGED
@@ -2117,9 +2117,11 @@ var OmniSyncClient = class {
2117
2117
  * const stripeProvider = providers.find(p => p.provider === 'stripe');
2118
2118
  * const paypalProvider = providers.find(p => p.provider === 'paypal');
2119
2119
  *
2120
- * // Initialize Stripe if available
2120
+ * // Initialize Stripe if available (with Connect account support)
2121
2121
  * if (stripeProvider) {
2122
- * const stripe = await loadStripe(stripeProvider.publicKey);
2122
+ * const stripe = await loadStripe(stripeProvider.publicKey, {
2123
+ * stripeAccount: stripeProvider.stripeAccountId, // For Stripe Connect
2124
+ * });
2123
2125
  * // Show Stripe payment form
2124
2126
  * }
2125
2127
  *
@@ -2866,6 +2868,99 @@ var OmniSyncClient = class {
2866
2868
  `/api/v1/custom-api/${integrationId}/test`
2867
2869
  );
2868
2870
  }
2871
+ // -------------------- Inventory Reservations --------------------
2872
+ // These methods are only available in vibe-coded mode when reservation strategy
2873
+ // is set to ON_CART or ON_CHECKOUT
2874
+ /**
2875
+ * Get product availability including reserved quantities.
2876
+ * Use this to show accurate stock to customers when reservations are enabled.
2877
+ *
2878
+ * **Vibe-coded mode only** - requires connectionId
2879
+ *
2880
+ * @param productIds - Array of product IDs to check availability for
2881
+ * @returns Array of availability info for each product
2882
+ *
2883
+ * @example
2884
+ * ```typescript
2885
+ * const availability = await omni.getAvailability(['prod_123', 'prod_456']);
2886
+ * availability.forEach(item => {
2887
+ * if (!item.canPurchase) {
2888
+ * console.log(`${item.productId}: Cannot purchase`);
2889
+ * } else if (item.lowStock) {
2890
+ * console.log(`${item.productId}: Only ${item.available} left!`);
2891
+ * } else {
2892
+ * console.log(`${item.productId}: ${item.available} available`);
2893
+ * }
2894
+ * });
2895
+ * ```
2896
+ */
2897
+ async getAvailability(productIds) {
2898
+ if (!this.isVibeCodedMode()) {
2899
+ throw new OmniSyncError(
2900
+ "getAvailability is only available in vibe-coded mode (use connectionId)",
2901
+ 400
2902
+ );
2903
+ }
2904
+ return this.vibeCodedRequest("POST", "/availability", { productIds });
2905
+ }
2906
+ /**
2907
+ * Extend an active reservation to prevent it from expiring.
2908
+ * Call this when a customer is still active in checkout to keep their items reserved.
2909
+ *
2910
+ * **Vibe-coded mode only** - requires connectionId
2911
+ * Only works when reservation strategy is ON_CART or ON_CHECKOUT
2912
+ *
2913
+ * @param options - Either cartId or checkoutId to identify the reservation
2914
+ * @returns Updated reservation info
2915
+ *
2916
+ * @example
2917
+ * ```typescript
2918
+ * // Extend reservation when customer shows activity
2919
+ * const result = await omni.extendReservation({ checkoutId: 'chk_123' });
2920
+ * if (result.success) {
2921
+ * console.log(`Reservation extended until ${result.reservation.expiresAt}`);
2922
+ * }
2923
+ * ```
2924
+ */
2925
+ async extendReservation(options) {
2926
+ if (!this.isVibeCodedMode()) {
2927
+ throw new OmniSyncError(
2928
+ "extendReservation is only available in vibe-coded mode (use connectionId)",
2929
+ 400
2930
+ );
2931
+ }
2932
+ if (!options.cartId && !options.checkoutId) {
2933
+ throw new OmniSyncError("Either cartId or checkoutId is required", 400);
2934
+ }
2935
+ return this.vibeCodedRequest("POST", "/reservation/extend", options);
2936
+ }
2937
+ /**
2938
+ * Release an active reservation, returning items to available stock.
2939
+ * Call this when a customer abandons their cart/checkout.
2940
+ *
2941
+ * **Vibe-coded mode only** - requires connectionId
2942
+ * Only works when reservation strategy is ON_CART or ON_CHECKOUT
2943
+ *
2944
+ * @param options - Either cartId or checkoutId to identify the reservation
2945
+ *
2946
+ * @example
2947
+ * ```typescript
2948
+ * // Release reservation when customer abandons checkout
2949
+ * await omni.releaseReservation({ checkoutId: 'chk_123' });
2950
+ * ```
2951
+ */
2952
+ async releaseReservation(options) {
2953
+ if (!this.isVibeCodedMode()) {
2954
+ throw new OmniSyncError(
2955
+ "releaseReservation is only available in vibe-coded mode (use connectionId)",
2956
+ 400
2957
+ );
2958
+ }
2959
+ if (!options.cartId && !options.checkoutId) {
2960
+ throw new OmniSyncError("Either cartId or checkoutId is required", 400);
2961
+ }
2962
+ await this.vibeCodedRequest("POST", "/reservation/release", options);
2963
+ }
2869
2964
  };
2870
2965
  var OmniSyncError = class extends Error {
2871
2966
  constructor(message, statusCode, details) {
package/dist/index.mjs CHANGED
@@ -2088,9 +2088,11 @@ var OmniSyncClient = class {
2088
2088
  * const stripeProvider = providers.find(p => p.provider === 'stripe');
2089
2089
  * const paypalProvider = providers.find(p => p.provider === 'paypal');
2090
2090
  *
2091
- * // Initialize Stripe if available
2091
+ * // Initialize Stripe if available (with Connect account support)
2092
2092
  * if (stripeProvider) {
2093
- * const stripe = await loadStripe(stripeProvider.publicKey);
2093
+ * const stripe = await loadStripe(stripeProvider.publicKey, {
2094
+ * stripeAccount: stripeProvider.stripeAccountId, // For Stripe Connect
2095
+ * });
2094
2096
  * // Show Stripe payment form
2095
2097
  * }
2096
2098
  *
@@ -2837,6 +2839,99 @@ var OmniSyncClient = class {
2837
2839
  `/api/v1/custom-api/${integrationId}/test`
2838
2840
  );
2839
2841
  }
2842
+ // -------------------- Inventory Reservations --------------------
2843
+ // These methods are only available in vibe-coded mode when reservation strategy
2844
+ // is set to ON_CART or ON_CHECKOUT
2845
+ /**
2846
+ * Get product availability including reserved quantities.
2847
+ * Use this to show accurate stock to customers when reservations are enabled.
2848
+ *
2849
+ * **Vibe-coded mode only** - requires connectionId
2850
+ *
2851
+ * @param productIds - Array of product IDs to check availability for
2852
+ * @returns Array of availability info for each product
2853
+ *
2854
+ * @example
2855
+ * ```typescript
2856
+ * const availability = await omni.getAvailability(['prod_123', 'prod_456']);
2857
+ * availability.forEach(item => {
2858
+ * if (!item.canPurchase) {
2859
+ * console.log(`${item.productId}: Cannot purchase`);
2860
+ * } else if (item.lowStock) {
2861
+ * console.log(`${item.productId}: Only ${item.available} left!`);
2862
+ * } else {
2863
+ * console.log(`${item.productId}: ${item.available} available`);
2864
+ * }
2865
+ * });
2866
+ * ```
2867
+ */
2868
+ async getAvailability(productIds) {
2869
+ if (!this.isVibeCodedMode()) {
2870
+ throw new OmniSyncError(
2871
+ "getAvailability is only available in vibe-coded mode (use connectionId)",
2872
+ 400
2873
+ );
2874
+ }
2875
+ return this.vibeCodedRequest("POST", "/availability", { productIds });
2876
+ }
2877
+ /**
2878
+ * Extend an active reservation to prevent it from expiring.
2879
+ * Call this when a customer is still active in checkout to keep their items reserved.
2880
+ *
2881
+ * **Vibe-coded mode only** - requires connectionId
2882
+ * Only works when reservation strategy is ON_CART or ON_CHECKOUT
2883
+ *
2884
+ * @param options - Either cartId or checkoutId to identify the reservation
2885
+ * @returns Updated reservation info
2886
+ *
2887
+ * @example
2888
+ * ```typescript
2889
+ * // Extend reservation when customer shows activity
2890
+ * const result = await omni.extendReservation({ checkoutId: 'chk_123' });
2891
+ * if (result.success) {
2892
+ * console.log(`Reservation extended until ${result.reservation.expiresAt}`);
2893
+ * }
2894
+ * ```
2895
+ */
2896
+ async extendReservation(options) {
2897
+ if (!this.isVibeCodedMode()) {
2898
+ throw new OmniSyncError(
2899
+ "extendReservation is only available in vibe-coded mode (use connectionId)",
2900
+ 400
2901
+ );
2902
+ }
2903
+ if (!options.cartId && !options.checkoutId) {
2904
+ throw new OmniSyncError("Either cartId or checkoutId is required", 400);
2905
+ }
2906
+ return this.vibeCodedRequest("POST", "/reservation/extend", options);
2907
+ }
2908
+ /**
2909
+ * Release an active reservation, returning items to available stock.
2910
+ * Call this when a customer abandons their cart/checkout.
2911
+ *
2912
+ * **Vibe-coded mode only** - requires connectionId
2913
+ * Only works when reservation strategy is ON_CART or ON_CHECKOUT
2914
+ *
2915
+ * @param options - Either cartId or checkoutId to identify the reservation
2916
+ *
2917
+ * @example
2918
+ * ```typescript
2919
+ * // Release reservation when customer abandons checkout
2920
+ * await omni.releaseReservation({ checkoutId: 'chk_123' });
2921
+ * ```
2922
+ */
2923
+ async releaseReservation(options) {
2924
+ if (!this.isVibeCodedMode()) {
2925
+ throw new OmniSyncError(
2926
+ "releaseReservation is only available in vibe-coded mode (use connectionId)",
2927
+ 400
2928
+ );
2929
+ }
2930
+ if (!options.cartId && !options.checkoutId) {
2931
+ throw new OmniSyncError("Either cartId or checkoutId is required", 400);
2932
+ }
2933
+ await this.vibeCodedRequest("POST", "/reservation/release", options);
2934
+ }
2840
2935
  };
2841
2936
  var OmniSyncError = class extends Error {
2842
2937
  constructor(message, statusCode, details) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omni-sync-sdk",
3
- "version": "0.14.2",
3
+ "version": "0.14.3",
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",