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 +2 -2
- package/dist/index.d.mts +144 -32
- package/dist/index.d.ts +144 -32
- package/dist/index.js +11 -6
- package/dist/index.mjs +11 -6
- package/package.json +10 -9
- package/LICENSE +0 -0
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;
|
|
605
|
-
canPurchase: boolean;
|
|
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
|
|
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
|
-
|
|
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?:
|
|
167
|
-
url: string;
|
|
168
|
-
} | null;
|
|
219
|
+
image?: unknown | null;
|
|
169
220
|
/** Display position/order for sorting variants */
|
|
170
|
-
position
|
|
221
|
+
position: number;
|
|
171
222
|
/** Variant status */
|
|
172
|
-
status?:
|
|
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
|
|
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
|
|
194
|
-
*
|
|
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
|
|
255
|
+
inStock: boolean;
|
|
197
256
|
/**
|
|
198
|
-
* Whether the item can be purchased
|
|
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
|
|
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
|
|
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
|
-
|
|
683
|
-
|
|
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
|
-
*
|
|
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?:
|
|
771
|
+
applicableProducts?: EntityRef[] | null;
|
|
690
772
|
/**
|
|
691
|
-
*
|
|
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?:
|
|
777
|
+
excludedProducts?: EntityRef[] | null;
|
|
695
778
|
/**
|
|
696
|
-
*
|
|
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?:
|
|
783
|
+
applicableCategories?: EntityRef[] | null;
|
|
700
784
|
/**
|
|
701
|
-
*
|
|
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?:
|
|
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
|
|
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
|
-
|
|
735
|
-
|
|
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
|
|
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
|
-
|
|
762
|
-
|
|
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
|
|
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
|
-
|
|
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?:
|
|
167
|
-
url: string;
|
|
168
|
-
} | null;
|
|
219
|
+
image?: unknown | null;
|
|
169
220
|
/** Display position/order for sorting variants */
|
|
170
|
-
position
|
|
221
|
+
position: number;
|
|
171
222
|
/** Variant status */
|
|
172
|
-
status?:
|
|
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
|
|
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
|
|
194
|
-
*
|
|
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
|
|
255
|
+
inStock: boolean;
|
|
197
256
|
/**
|
|
198
|
-
* Whether the item can be purchased
|
|
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
|
|
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
|
|
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
|
-
|
|
683
|
-
|
|
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
|
-
*
|
|
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?:
|
|
771
|
+
applicableProducts?: EntityRef[] | null;
|
|
690
772
|
/**
|
|
691
|
-
*
|
|
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?:
|
|
777
|
+
excludedProducts?: EntityRef[] | null;
|
|
695
778
|
/**
|
|
696
|
-
*
|
|
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?:
|
|
783
|
+
applicableCategories?: EntityRef[] | null;
|
|
700
784
|
/**
|
|
701
|
-
*
|
|
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?:
|
|
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
|
|
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
|
-
|
|
735
|
-
|
|
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
|
|
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
|
-
|
|
762
|
-
|
|
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
|
-
|
|
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 (
|
|
3617
|
+
if (excludedCategoryIds.some((catId) => productCategoryIds.includes(catId))) {
|
|
3613
3618
|
return false;
|
|
3614
3619
|
}
|
|
3615
|
-
if (
|
|
3616
|
-
if (!
|
|
3620
|
+
if (applicableProductIds.length > 0) {
|
|
3621
|
+
if (!applicableProductIds.includes(productId)) {
|
|
3617
3622
|
return false;
|
|
3618
3623
|
}
|
|
3619
3624
|
}
|
|
3620
|
-
if (
|
|
3621
|
-
if (!
|
|
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
|
-
|
|
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 (
|
|
3580
|
+
if (excludedCategoryIds.some((catId) => productCategoryIds.includes(catId))) {
|
|
3576
3581
|
return false;
|
|
3577
3582
|
}
|
|
3578
|
-
if (
|
|
3579
|
-
if (!
|
|
3583
|
+
if (applicableProductIds.length > 0) {
|
|
3584
|
+
if (!applicableProductIds.includes(productId)) {
|
|
3580
3585
|
return false;
|
|
3581
3586
|
}
|
|
3582
3587
|
}
|
|
3583
|
-
if (
|
|
3584
|
-
if (!
|
|
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.
|
|
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
|