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 +9 -7
- package/dist/index.d.mts +166 -3
- package/dist/index.d.ts +166 -3
- package/dist/index.js +97 -2
- package/dist/index.mjs +97 -2
- package/package.json +1 -1
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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/[
|
|
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
|
|
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
|
|
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.
|
|
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",
|