omni-sync-sdk 0.17.4 → 0.18.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/README.md CHANGED
@@ -601,8 +601,8 @@ interface InventoryInfo {
601
601
  reserved: number;
602
602
  available: number;
603
603
  trackingMode?: 'TRACKED' | 'UNLIMITED' | 'DISABLED';
604
- inStock: boolean; // Pre-calculated - use this for display!
605
- canPurchase: boolean; // Pre-calculated - use this for add-to-cart
604
+ inStock: boolean; // Pre-calculated - use this for display!
605
+ canPurchase: boolean; // Pre-calculated - use this for add-to-cart
606
606
  }
607
607
  ```
608
608
 
package/dist/index.d.mts CHANGED
@@ -113,17 +113,27 @@ interface CustomerProfile {
113
113
  updatedAt: string;
114
114
  }
115
115
  interface ProductMetafield {
116
+ id?: string;
117
+ definitionId?: string;
118
+ /** Key from definition (alias: definitionKey) */
116
119
  key: string;
120
+ /** Alias for key from backend */
121
+ definitionKey?: string;
117
122
  value: string;
123
+ /** Display name (maps to definitionName in backend) */
118
124
  name?: string;
125
+ /** Alias for name from backend */
126
+ definitionName?: string;
119
127
  type?: string;
128
+ /** Variant ID if this metafield is variant-specific */
129
+ variantId?: string | null;
120
130
  }
121
131
  interface Product {
122
132
  id: string;
123
133
  name: string;
124
134
  slug?: string | null;
125
135
  description?: string | null;
126
- descriptionFormat?: 'text' | 'html' | 'markdown';
136
+ descriptionFormat?: 'text' | 'html' | 'markdown' | null;
127
137
  sku: string;
128
138
  /** Base price as string (e.g., "29.99"). Use parseFloat() for calculations. */
129
139
  basePrice: string;
@@ -131,16 +141,57 @@ interface Product {
131
141
  salePrice?: string | null;
132
142
  /** Cost price as string. Use parseFloat() for calculations. */
133
143
  costPrice?: string | null;
134
- status: 'active' | 'draft' | 'archived';
144
+ status?: string | null;
135
145
  type: 'SIMPLE' | 'VARIABLE';
136
146
  isDownloadable?: boolean;
137
147
  images?: ProductImage[];
138
148
  inventory?: InventoryInfo | null;
139
149
  variants?: ProductVariant[];
140
- categories?: string[];
150
+ /** Categories as objects with id and name */
151
+ categories?: Array<{
152
+ id: string;
153
+ name: string;
154
+ }>;
155
+ /** Brands as objects with id and name */
156
+ brands?: Array<{
157
+ id: string;
158
+ name: string;
159
+ }>;
141
160
  tags?: string[];
142
161
  metafields?: ProductMetafield[];
143
162
  channels?: Record<string, Record<string, unknown>>;
163
+ /** Shopify product ID (admin mode only) */
164
+ shopifyProductId?: string | null;
165
+ /** Whether product needs sync to platforms (admin mode only) */
166
+ needsSync?: boolean;
167
+ /** Last sync timestamp (admin mode only) */
168
+ lastSyncedAt?: string | null;
169
+ /** Menu/display order */
170
+ menuOrder?: number | null;
171
+ /** Full attribute options for variant selection (admin mode only) */
172
+ productAttributeOptions?: Array<{
173
+ id: string;
174
+ attributeId: string;
175
+ attributeOptionId: string;
176
+ platform: string;
177
+ attribute: {
178
+ id: string;
179
+ name: string;
180
+ } | null;
181
+ attributeOption: {
182
+ id: string;
183
+ name: string;
184
+ value?: string | null;
185
+ } | null;
186
+ }>;
187
+ /** Vibe-coded sites this product is published to (admin mode only) */
188
+ vibeCodedPublishes?: Array<{
189
+ connection: {
190
+ id: string;
191
+ name: string;
192
+ connectionId: string;
193
+ };
194
+ }>;
144
195
  createdAt: string;
145
196
  updatedAt: string;
146
197
  }
@@ -153,6 +204,8 @@ interface ProductImage {
153
204
  }
154
205
  interface ProductVariant {
155
206
  id: string;
207
+ /** Parent product ID */
208
+ productId: string;
156
209
  sku?: string | null;
157
210
  name?: string | null;
158
211
  /** Variant price as string. Use parseFloat() for calculations. */
@@ -160,16 +213,16 @@ interface ProductVariant {
160
213
  /** Variant sale price as string. Use parseFloat() for calculations. */
161
214
  salePrice?: string | null;
162
215
  /** Variant attributes (e.g., { "Color": "Red", "Size": "M" }) */
163
- attributes?: Record<string, unknown>;
216
+ attributes?: Record<string, unknown> | null;
164
217
  inventory?: InventoryInfo | null;
165
218
  /** Variant image URL or image object */
166
- image?: string | {
167
- url: string;
168
- } | null;
219
+ image?: unknown | null;
169
220
  /** Display position/order for sorting variants */
170
- position?: number;
221
+ position: number;
171
222
  /** Variant status */
172
- status?: 'active' | 'draft' | 'archived';
223
+ status?: string | null;
224
+ createdAt: string;
225
+ updatedAt: string;
173
226
  }
174
227
  /**
175
228
  * Inventory tracking mode determines how stock is managed:
@@ -180,24 +233,32 @@ interface ProductVariant {
180
233
  type InventoryTrackingMode = 'TRACKED' | 'UNLIMITED' | 'DISABLED';
181
234
  interface InventoryInfo {
182
235
  total: number;
183
- reserved?: number;
236
+ reserved: number;
184
237
  available: number;
185
238
  /**
186
239
  * Inventory tracking mode
187
240
  * - TRACKED: Normal inventory with quantity tracking
188
241
  * - UNLIMITED: Always in stock
189
242
  * - DISABLED: Cannot be purchased
243
+ *
244
+ * Note: For VARIABLE products, this is aggregated from variants:
245
+ * - All UNLIMITED → UNLIMITED
246
+ * - All DISABLED → DISABLED
247
+ * - Mixed → TRACKED
190
248
  */
191
249
  trackingMode?: InventoryTrackingMode;
192
250
  /**
193
- * Whether the item is in stock (available > 0)
194
- * Always present in vibe-coded API responses
251
+ * Whether the item is in stock.
252
+ * Pre-calculated by backend - USE THIS instead of checking `available > 0`!
253
+ * For VARIABLE products, true if ANY variant is available.
195
254
  */
196
- inStock?: boolean;
255
+ inStock: boolean;
197
256
  /**
198
- * Whether the item can be purchased (trackingMode !== 'DISABLED')
257
+ * Whether the item can be purchased.
258
+ * Pre-calculated by backend - USE THIS for add-to-cart button state!
259
+ * false if trackingMode is DISABLED or if out of stock.
199
260
  */
200
- canPurchase?: boolean;
261
+ canPurchase: boolean;
201
262
  }
202
263
  /**
203
264
  * Check if a product description contains HTML and should be rendered with dangerouslySetInnerHTML
@@ -664,6 +725,23 @@ interface SyncJob {
664
725
  message?: string;
665
726
  }
666
727
  type ConnectorPlatform = 'SHOPIFY' | 'TIKTOK' | 'META' | 'WOOCOMMERCE' | 'CUSTOM';
728
+ /**
729
+ * Reference to an entity with ID and name.
730
+ * Used for products, categories, and other related entities.
731
+ */
732
+ interface EntityRef {
733
+ id: string;
734
+ name: string;
735
+ }
736
+ /**
737
+ * Customer targeting restrictions for coupons.
738
+ */
739
+ interface CustomerRestrictionsDto {
740
+ type: 'all' | 'emails' | 'customers' | 'segments';
741
+ emails?: string[];
742
+ customerIds?: string[];
743
+ segmentIds?: string[];
744
+ }
667
745
  type CouponType = 'PERCENTAGE' | 'FIXED_AMOUNT' | 'FREE_SHIPPING' | 'BUY_X_GET_Y';
668
746
  type CouponStatus = 'ACTIVE' | 'SCHEDULED' | 'EXPIRED' | 'DISABLED';
669
747
  interface Coupon {
@@ -672,38 +750,56 @@ interface Coupon {
672
750
  title?: string | null;
673
751
  description?: string | null;
674
752
  type: CouponType;
675
- value: number;
753
+ /** Coupon value as string (Decimal). Use parseFloat() for calculations. */
754
+ value: string;
676
755
  startsAt?: string | null;
677
756
  endsAt?: string | null;
678
757
  status: CouponStatus;
679
758
  usageLimit?: number | null;
680
759
  usageLimitPerCustomer?: number | null;
681
760
  usageCount: number;
682
- minimumOrderAmount?: number | null;
683
- maximumDiscount?: number | null;
761
+ /** Minimum order amount as string (Decimal). Use parseFloat() for calculations. */
762
+ minimumOrderAmount?: string | null;
763
+ /** Maximum discount amount as string (Decimal). Use parseFloat() for calculations. */
764
+ maximumDiscount?: string | null;
684
765
  conditions?: Record<string, unknown> | null;
685
766
  /**
686
- * Product IDs this coupon applies to.
767
+ * Products this coupon applies to.
687
768
  * If set, coupon only applies to these specific products.
769
+ * Returns objects with id and name from backend.
688
770
  */
689
- applicableProducts?: string[] | null;
771
+ applicableProducts?: EntityRef[] | null;
690
772
  /**
691
- * Product IDs excluded from this coupon.
773
+ * Products excluded from this coupon.
692
774
  * These products will not receive the discount even if in applicable categories.
775
+ * Returns objects with id and name from backend.
693
776
  */
694
- excludedProducts?: string[] | null;
777
+ excludedProducts?: EntityRef[] | null;
695
778
  /**
696
- * Category IDs this coupon applies to.
779
+ * Categories this coupon applies to.
697
780
  * If set, coupon only applies to products in these categories.
781
+ * Returns objects with id and name from backend.
698
782
  */
699
- applicableCategories?: string[] | null;
783
+ applicableCategories?: EntityRef[] | null;
700
784
  /**
701
- * Category IDs excluded from this coupon.
785
+ * Categories excluded from this coupon.
702
786
  * Products in these categories will not receive the discount.
787
+ * Returns objects with id and name from backend.
703
788
  */
704
- excludedCategories?: string[] | null;
789
+ excludedCategories?: EntityRef[] | null;
705
790
  combinesWithOther: boolean;
706
791
  freeShipping: boolean;
792
+ combinesWithOrderDiscounts?: boolean | null;
793
+ combinesWithProductDiscounts?: boolean | null;
794
+ combinesWithShippingDiscounts?: boolean | null;
795
+ customerRestrictions?: CustomerRestrictionsDto | null;
796
+ minimumQuantity?: number | null;
797
+ /** Whether coupon needs sync to platforms */
798
+ needsSync?: boolean;
799
+ /** Last sync timestamp */
800
+ lastSyncedAt?: string | null;
801
+ /** Per-platform channel overrides */
802
+ channels?: Record<string, Record<string, unknown>> | null;
707
803
  shopifyCouponId?: string | null;
708
804
  woocommerceCouponId?: string | null;
709
805
  tiktokCouponId?: string | null;
@@ -725,14 +821,17 @@ interface CreateCouponDto {
725
821
  title?: string;
726
822
  description?: string;
727
823
  type: CouponType;
728
- value: number;
824
+ /** Coupon value - accepts number or string (will be converted to Decimal) */
825
+ value: number | string;
729
826
  startsAt?: string;
730
827
  endsAt?: string;
731
828
  status?: CouponStatus;
732
829
  usageLimit?: number;
733
830
  usageLimitPerCustomer?: number;
734
- minimumOrderAmount?: number;
735
- maximumDiscount?: number;
831
+ /** Minimum order amount - accepts number or string */
832
+ minimumOrderAmount?: number | string;
833
+ /** Maximum discount amount - accepts number or string */
834
+ maximumDiscount?: number | string;
736
835
  conditions?: Record<string, unknown>;
737
836
  /** Product IDs this coupon applies to */
738
837
  applicableProducts?: string[];
@@ -744,6 +843,11 @@ interface CreateCouponDto {
744
843
  excludedCategories?: string[];
745
844
  combinesWithOther?: boolean;
746
845
  freeShipping?: boolean;
846
+ combinesWithOrderDiscounts?: boolean;
847
+ combinesWithProductDiscounts?: boolean;
848
+ combinesWithShippingDiscounts?: boolean;
849
+ customerRestrictions?: CustomerRestrictionsDto;
850
+ minimumQuantity?: number;
747
851
  /** Platforms to publish this coupon to */
748
852
  platforms?: ConnectorPlatform[];
749
853
  }
@@ -752,14 +856,17 @@ interface UpdateCouponDto {
752
856
  title?: string;
753
857
  description?: string;
754
858
  type?: CouponType;
755
- value?: number;
859
+ /** Coupon value - accepts number or string (will be converted to Decimal) */
860
+ value?: number | string;
756
861
  startsAt?: string | null;
757
862
  endsAt?: string | null;
758
863
  status?: CouponStatus;
759
864
  usageLimit?: number | null;
760
865
  usageLimitPerCustomer?: number | null;
761
- minimumOrderAmount?: number | null;
762
- maximumDiscount?: number | null;
866
+ /** Minimum order amount - accepts number or string */
867
+ minimumOrderAmount?: number | string | null;
868
+ /** Maximum discount amount - accepts number or string */
869
+ maximumDiscount?: number | string | null;
763
870
  conditions?: Record<string, unknown> | null;
764
871
  applicableProducts?: string[] | null;
765
872
  excludedProducts?: string[] | null;
@@ -767,6 +874,11 @@ interface UpdateCouponDto {
767
874
  excludedCategories?: string[] | null;
768
875
  combinesWithOther?: boolean;
769
876
  freeShipping?: boolean;
877
+ combinesWithOrderDiscounts?: boolean | null;
878
+ combinesWithProductDiscounts?: boolean | null;
879
+ combinesWithShippingDiscounts?: boolean | null;
880
+ customerRestrictions?: CustomerRestrictionsDto | null;
881
+ minimumQuantity?: number | null;
770
882
  }
771
883
  /**
772
884
  * Validation warning returned when syncing coupons to platforms
package/dist/index.d.ts CHANGED
@@ -113,17 +113,27 @@ interface CustomerProfile {
113
113
  updatedAt: string;
114
114
  }
115
115
  interface ProductMetafield {
116
+ id?: string;
117
+ definitionId?: string;
118
+ /** Key from definition (alias: definitionKey) */
116
119
  key: string;
120
+ /** Alias for key from backend */
121
+ definitionKey?: string;
117
122
  value: string;
123
+ /** Display name (maps to definitionName in backend) */
118
124
  name?: string;
125
+ /** Alias for name from backend */
126
+ definitionName?: string;
119
127
  type?: string;
128
+ /** Variant ID if this metafield is variant-specific */
129
+ variantId?: string | null;
120
130
  }
121
131
  interface Product {
122
132
  id: string;
123
133
  name: string;
124
134
  slug?: string | null;
125
135
  description?: string | null;
126
- descriptionFormat?: 'text' | 'html' | 'markdown';
136
+ descriptionFormat?: 'text' | 'html' | 'markdown' | null;
127
137
  sku: string;
128
138
  /** Base price as string (e.g., "29.99"). Use parseFloat() for calculations. */
129
139
  basePrice: string;
@@ -131,16 +141,57 @@ interface Product {
131
141
  salePrice?: string | null;
132
142
  /** Cost price as string. Use parseFloat() for calculations. */
133
143
  costPrice?: string | null;
134
- status: 'active' | 'draft' | 'archived';
144
+ status?: string | null;
135
145
  type: 'SIMPLE' | 'VARIABLE';
136
146
  isDownloadable?: boolean;
137
147
  images?: ProductImage[];
138
148
  inventory?: InventoryInfo | null;
139
149
  variants?: ProductVariant[];
140
- categories?: string[];
150
+ /** Categories as objects with id and name */
151
+ categories?: Array<{
152
+ id: string;
153
+ name: string;
154
+ }>;
155
+ /** Brands as objects with id and name */
156
+ brands?: Array<{
157
+ id: string;
158
+ name: string;
159
+ }>;
141
160
  tags?: string[];
142
161
  metafields?: ProductMetafield[];
143
162
  channels?: Record<string, Record<string, unknown>>;
163
+ /** Shopify product ID (admin mode only) */
164
+ shopifyProductId?: string | null;
165
+ /** Whether product needs sync to platforms (admin mode only) */
166
+ needsSync?: boolean;
167
+ /** Last sync timestamp (admin mode only) */
168
+ lastSyncedAt?: string | null;
169
+ /** Menu/display order */
170
+ menuOrder?: number | null;
171
+ /** Full attribute options for variant selection (admin mode only) */
172
+ productAttributeOptions?: Array<{
173
+ id: string;
174
+ attributeId: string;
175
+ attributeOptionId: string;
176
+ platform: string;
177
+ attribute: {
178
+ id: string;
179
+ name: string;
180
+ } | null;
181
+ attributeOption: {
182
+ id: string;
183
+ name: string;
184
+ value?: string | null;
185
+ } | null;
186
+ }>;
187
+ /** Vibe-coded sites this product is published to (admin mode only) */
188
+ vibeCodedPublishes?: Array<{
189
+ connection: {
190
+ id: string;
191
+ name: string;
192
+ connectionId: string;
193
+ };
194
+ }>;
144
195
  createdAt: string;
145
196
  updatedAt: string;
146
197
  }
@@ -153,6 +204,8 @@ interface ProductImage {
153
204
  }
154
205
  interface ProductVariant {
155
206
  id: string;
207
+ /** Parent product ID */
208
+ productId: string;
156
209
  sku?: string | null;
157
210
  name?: string | null;
158
211
  /** Variant price as string. Use parseFloat() for calculations. */
@@ -160,16 +213,16 @@ interface ProductVariant {
160
213
  /** Variant sale price as string. Use parseFloat() for calculations. */
161
214
  salePrice?: string | null;
162
215
  /** Variant attributes (e.g., { "Color": "Red", "Size": "M" }) */
163
- attributes?: Record<string, unknown>;
216
+ attributes?: Record<string, unknown> | null;
164
217
  inventory?: InventoryInfo | null;
165
218
  /** Variant image URL or image object */
166
- image?: string | {
167
- url: string;
168
- } | null;
219
+ image?: unknown | null;
169
220
  /** Display position/order for sorting variants */
170
- position?: number;
221
+ position: number;
171
222
  /** Variant status */
172
- status?: 'active' | 'draft' | 'archived';
223
+ status?: string | null;
224
+ createdAt: string;
225
+ updatedAt: string;
173
226
  }
174
227
  /**
175
228
  * Inventory tracking mode determines how stock is managed:
@@ -180,24 +233,32 @@ interface ProductVariant {
180
233
  type InventoryTrackingMode = 'TRACKED' | 'UNLIMITED' | 'DISABLED';
181
234
  interface InventoryInfo {
182
235
  total: number;
183
- reserved?: number;
236
+ reserved: number;
184
237
  available: number;
185
238
  /**
186
239
  * Inventory tracking mode
187
240
  * - TRACKED: Normal inventory with quantity tracking
188
241
  * - UNLIMITED: Always in stock
189
242
  * - DISABLED: Cannot be purchased
243
+ *
244
+ * Note: For VARIABLE products, this is aggregated from variants:
245
+ * - All UNLIMITED → UNLIMITED
246
+ * - All DISABLED → DISABLED
247
+ * - Mixed → TRACKED
190
248
  */
191
249
  trackingMode?: InventoryTrackingMode;
192
250
  /**
193
- * Whether the item is in stock (available > 0)
194
- * Always present in vibe-coded API responses
251
+ * Whether the item is in stock.
252
+ * Pre-calculated by backend - USE THIS instead of checking `available > 0`!
253
+ * For VARIABLE products, true if ANY variant is available.
195
254
  */
196
- inStock?: boolean;
255
+ inStock: boolean;
197
256
  /**
198
- * Whether the item can be purchased (trackingMode !== 'DISABLED')
257
+ * Whether the item can be purchased.
258
+ * Pre-calculated by backend - USE THIS for add-to-cart button state!
259
+ * false if trackingMode is DISABLED or if out of stock.
199
260
  */
200
- canPurchase?: boolean;
261
+ canPurchase: boolean;
201
262
  }
202
263
  /**
203
264
  * Check if a product description contains HTML and should be rendered with dangerouslySetInnerHTML
@@ -664,6 +725,23 @@ interface SyncJob {
664
725
  message?: string;
665
726
  }
666
727
  type ConnectorPlatform = 'SHOPIFY' | 'TIKTOK' | 'META' | 'WOOCOMMERCE' | 'CUSTOM';
728
+ /**
729
+ * Reference to an entity with ID and name.
730
+ * Used for products, categories, and other related entities.
731
+ */
732
+ interface EntityRef {
733
+ id: string;
734
+ name: string;
735
+ }
736
+ /**
737
+ * Customer targeting restrictions for coupons.
738
+ */
739
+ interface CustomerRestrictionsDto {
740
+ type: 'all' | 'emails' | 'customers' | 'segments';
741
+ emails?: string[];
742
+ customerIds?: string[];
743
+ segmentIds?: string[];
744
+ }
667
745
  type CouponType = 'PERCENTAGE' | 'FIXED_AMOUNT' | 'FREE_SHIPPING' | 'BUY_X_GET_Y';
668
746
  type CouponStatus = 'ACTIVE' | 'SCHEDULED' | 'EXPIRED' | 'DISABLED';
669
747
  interface Coupon {
@@ -672,38 +750,56 @@ interface Coupon {
672
750
  title?: string | null;
673
751
  description?: string | null;
674
752
  type: CouponType;
675
- value: number;
753
+ /** Coupon value as string (Decimal). Use parseFloat() for calculations. */
754
+ value: string;
676
755
  startsAt?: string | null;
677
756
  endsAt?: string | null;
678
757
  status: CouponStatus;
679
758
  usageLimit?: number | null;
680
759
  usageLimitPerCustomer?: number | null;
681
760
  usageCount: number;
682
- minimumOrderAmount?: number | null;
683
- maximumDiscount?: number | null;
761
+ /** Minimum order amount as string (Decimal). Use parseFloat() for calculations. */
762
+ minimumOrderAmount?: string | null;
763
+ /** Maximum discount amount as string (Decimal). Use parseFloat() for calculations. */
764
+ maximumDiscount?: string | null;
684
765
  conditions?: Record<string, unknown> | null;
685
766
  /**
686
- * Product IDs this coupon applies to.
767
+ * Products this coupon applies to.
687
768
  * If set, coupon only applies to these specific products.
769
+ * Returns objects with id and name from backend.
688
770
  */
689
- applicableProducts?: string[] | null;
771
+ applicableProducts?: EntityRef[] | null;
690
772
  /**
691
- * Product IDs excluded from this coupon.
773
+ * Products excluded from this coupon.
692
774
  * These products will not receive the discount even if in applicable categories.
775
+ * Returns objects with id and name from backend.
693
776
  */
694
- excludedProducts?: string[] | null;
777
+ excludedProducts?: EntityRef[] | null;
695
778
  /**
696
- * Category IDs this coupon applies to.
779
+ * Categories this coupon applies to.
697
780
  * If set, coupon only applies to products in these categories.
781
+ * Returns objects with id and name from backend.
698
782
  */
699
- applicableCategories?: string[] | null;
783
+ applicableCategories?: EntityRef[] | null;
700
784
  /**
701
- * Category IDs excluded from this coupon.
785
+ * Categories excluded from this coupon.
702
786
  * Products in these categories will not receive the discount.
787
+ * Returns objects with id and name from backend.
703
788
  */
704
- excludedCategories?: string[] | null;
789
+ excludedCategories?: EntityRef[] | null;
705
790
  combinesWithOther: boolean;
706
791
  freeShipping: boolean;
792
+ combinesWithOrderDiscounts?: boolean | null;
793
+ combinesWithProductDiscounts?: boolean | null;
794
+ combinesWithShippingDiscounts?: boolean | null;
795
+ customerRestrictions?: CustomerRestrictionsDto | null;
796
+ minimumQuantity?: number | null;
797
+ /** Whether coupon needs sync to platforms */
798
+ needsSync?: boolean;
799
+ /** Last sync timestamp */
800
+ lastSyncedAt?: string | null;
801
+ /** Per-platform channel overrides */
802
+ channels?: Record<string, Record<string, unknown>> | null;
707
803
  shopifyCouponId?: string | null;
708
804
  woocommerceCouponId?: string | null;
709
805
  tiktokCouponId?: string | null;
@@ -725,14 +821,17 @@ interface CreateCouponDto {
725
821
  title?: string;
726
822
  description?: string;
727
823
  type: CouponType;
728
- value: number;
824
+ /** Coupon value - accepts number or string (will be converted to Decimal) */
825
+ value: number | string;
729
826
  startsAt?: string;
730
827
  endsAt?: string;
731
828
  status?: CouponStatus;
732
829
  usageLimit?: number;
733
830
  usageLimitPerCustomer?: number;
734
- minimumOrderAmount?: number;
735
- maximumDiscount?: number;
831
+ /** Minimum order amount - accepts number or string */
832
+ minimumOrderAmount?: number | string;
833
+ /** Maximum discount amount - accepts number or string */
834
+ maximumDiscount?: number | string;
736
835
  conditions?: Record<string, unknown>;
737
836
  /** Product IDs this coupon applies to */
738
837
  applicableProducts?: string[];
@@ -744,6 +843,11 @@ interface CreateCouponDto {
744
843
  excludedCategories?: string[];
745
844
  combinesWithOther?: boolean;
746
845
  freeShipping?: boolean;
846
+ combinesWithOrderDiscounts?: boolean;
847
+ combinesWithProductDiscounts?: boolean;
848
+ combinesWithShippingDiscounts?: boolean;
849
+ customerRestrictions?: CustomerRestrictionsDto;
850
+ minimumQuantity?: number;
747
851
  /** Platforms to publish this coupon to */
748
852
  platforms?: ConnectorPlatform[];
749
853
  }
@@ -752,14 +856,17 @@ interface UpdateCouponDto {
752
856
  title?: string;
753
857
  description?: string;
754
858
  type?: CouponType;
755
- value?: number;
859
+ /** Coupon value - accepts number or string (will be converted to Decimal) */
860
+ value?: number | string;
756
861
  startsAt?: string | null;
757
862
  endsAt?: string | null;
758
863
  status?: CouponStatus;
759
864
  usageLimit?: number | null;
760
865
  usageLimitPerCustomer?: number | null;
761
- minimumOrderAmount?: number | null;
762
- maximumDiscount?: number | null;
866
+ /** Minimum order amount - accepts number or string */
867
+ minimumOrderAmount?: number | string | null;
868
+ /** Maximum discount amount - accepts number or string */
869
+ maximumDiscount?: number | string | null;
763
870
  conditions?: Record<string, unknown> | null;
764
871
  applicableProducts?: string[] | null;
765
872
  excludedProducts?: string[] | null;
@@ -767,6 +874,11 @@ interface UpdateCouponDto {
767
874
  excludedCategories?: string[] | null;
768
875
  combinesWithOther?: boolean;
769
876
  freeShipping?: boolean;
877
+ combinesWithOrderDiscounts?: boolean | null;
878
+ combinesWithProductDiscounts?: boolean | null;
879
+ combinesWithShippingDiscounts?: boolean | null;
880
+ customerRestrictions?: CustomerRestrictionsDto | null;
881
+ minimumQuantity?: number | null;
770
882
  }
771
883
  /**
772
884
  * Validation warning returned when syncing coupons to platforms
package/dist/index.js CHANGED
@@ -3606,19 +3606,24 @@ function getVariantOptions(variant) {
3606
3606
  return Object.entries(variant.attributes).filter(([, value]) => typeof value === "string").map(([name, value]) => ({ name, value }));
3607
3607
  }
3608
3608
  function isCouponApplicableToProduct(coupon, productId, productCategoryIds) {
3609
- if (coupon.excludedProducts?.includes(productId)) {
3609
+ const getIds = (refs) => refs?.map((ref) => ref.id) ?? [];
3610
+ const excludedProductIds = getIds(coupon.excludedProducts);
3611
+ const excludedCategoryIds = getIds(coupon.excludedCategories);
3612
+ const applicableProductIds = getIds(coupon.applicableProducts);
3613
+ const applicableCategoryIds = getIds(coupon.applicableCategories);
3614
+ if (excludedProductIds.includes(productId)) {
3610
3615
  return false;
3611
3616
  }
3612
- if (coupon.excludedCategories?.some((cat) => productCategoryIds.includes(cat))) {
3617
+ if (excludedCategoryIds.some((catId) => productCategoryIds.includes(catId))) {
3613
3618
  return false;
3614
3619
  }
3615
- if (coupon.applicableProducts && coupon.applicableProducts.length > 0) {
3616
- if (!coupon.applicableProducts.includes(productId)) {
3620
+ if (applicableProductIds.length > 0) {
3621
+ if (!applicableProductIds.includes(productId)) {
3617
3622
  return false;
3618
3623
  }
3619
3624
  }
3620
- if (coupon.applicableCategories && coupon.applicableCategories.length > 0) {
3621
- if (!coupon.applicableCategories.some((cat) => productCategoryIds.includes(cat))) {
3625
+ if (applicableCategoryIds.length > 0) {
3626
+ if (!applicableCategoryIds.some((catId) => productCategoryIds.includes(catId))) {
3622
3627
  return false;
3623
3628
  }
3624
3629
  }
package/dist/index.mjs CHANGED
@@ -3569,19 +3569,24 @@ function getVariantOptions(variant) {
3569
3569
  return Object.entries(variant.attributes).filter(([, value]) => typeof value === "string").map(([name, value]) => ({ name, value }));
3570
3570
  }
3571
3571
  function isCouponApplicableToProduct(coupon, productId, productCategoryIds) {
3572
- if (coupon.excludedProducts?.includes(productId)) {
3572
+ const getIds = (refs) => refs?.map((ref) => ref.id) ?? [];
3573
+ const excludedProductIds = getIds(coupon.excludedProducts);
3574
+ const excludedCategoryIds = getIds(coupon.excludedCategories);
3575
+ const applicableProductIds = getIds(coupon.applicableProducts);
3576
+ const applicableCategoryIds = getIds(coupon.applicableCategories);
3577
+ if (excludedProductIds.includes(productId)) {
3573
3578
  return false;
3574
3579
  }
3575
- if (coupon.excludedCategories?.some((cat) => productCategoryIds.includes(cat))) {
3580
+ if (excludedCategoryIds.some((catId) => productCategoryIds.includes(catId))) {
3576
3581
  return false;
3577
3582
  }
3578
- if (coupon.applicableProducts && coupon.applicableProducts.length > 0) {
3579
- if (!coupon.applicableProducts.includes(productId)) {
3583
+ if (applicableProductIds.length > 0) {
3584
+ if (!applicableProductIds.includes(productId)) {
3580
3585
  return false;
3581
3586
  }
3582
3587
  }
3583
- if (coupon.applicableCategories && coupon.applicableCategories.length > 0) {
3584
- if (!coupon.applicableCategories.some((cat) => productCategoryIds.includes(cat))) {
3588
+ if (applicableCategoryIds.length > 0) {
3589
+ if (!applicableCategoryIds.some((catId) => productCategoryIds.includes(catId))) {
3585
3590
  return false;
3586
3591
  }
3587
3592
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omni-sync-sdk",
3
- "version": "0.17.4",
3
+ "version": "0.18.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",
@@ -16,6 +16,14 @@
16
16
  "dist",
17
17
  "README.md"
18
18
  ],
19
+ "scripts": {
20
+ "build": "tsup src/index.ts --format cjs,esm --dts",
21
+ "dev": "tsup src/index.ts --format cjs,esm --dts --watch",
22
+ "lint": "eslint \"src/**/*.ts\"",
23
+ "test": "vitest run",
24
+ "test:watch": "vitest",
25
+ "prepublishOnly": "pnpm build"
26
+ },
19
27
  "keywords": [
20
28
  "omni-sync",
21
29
  "e-commerce",
@@ -64,12 +72,5 @@
64
72
  "typescript": {
65
73
  "optional": true
66
74
  }
67
- },
68
- "scripts": {
69
- "build": "tsup src/index.ts --format cjs,esm --dts",
70
- "dev": "tsup src/index.ts --format cjs,esm --dts --watch",
71
- "lint": "eslint \"src/**/*.ts\"",
72
- "test": "vitest run",
73
- "test:watch": "vitest"
74
75
  }
75
- }
76
+ }
package/LICENSE DELETED
File without changes