@thorprovider/adapters 4.3.0 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +66 -387
- package/dist/index.d.ts +66 -387
- package/dist/index.js +70 -2901
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +66 -2891
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/backend/factory.ts +1 -11
- package/src/factory/index.ts +74 -52
- package/src/index.ts +5 -15
- package/src/providers/index.ts +1 -16
- package/src/types/capabilities.types.ts +0 -250
- package/src/providers/bigcommerce/bigcommerce.ts +0 -6
- package/src/providers/bigcommerce/index.ts +0 -315
- package/src/providers/bigcommerce/transforms.ts +0 -227
- package/src/providers/magento/index.ts +0 -387
- package/src/providers/magento/magento.ts +0 -5
- package/src/providers/magento/queries.ts +0 -267
- package/src/providers/magento/transforms.ts +0 -249
- package/src/providers/shopify/auth.ts +0 -408
- package/src/providers/shopify/index.ts +0 -444
- package/src/providers/shopify/mutations.ts +0 -247
- package/src/providers/shopify/queries.ts +0 -324
- package/src/providers/shopify/shopify.ts +0 -7
- package/src/providers/shopify/transforms.ts +0 -275
- package/src/providers/spree/index.ts +0 -344
- package/src/providers/spree/spree.ts +0 -5
- package/src/providers/spree/transforms.ts +0 -254
- package/src/providers/woocommerce/index.ts +0 -310
- package/src/providers/woocommerce/transforms.ts +0 -254
- package/src/providers/woocommerce/woocommerce.ts +0 -5
package/dist/index.mjs
CHANGED
|
@@ -106,209 +106,6 @@ var STELORDER_CAPABILITIES = {
|
|
|
106
106
|
// Loyalty
|
|
107
107
|
loyaltyProgram: false
|
|
108
108
|
};
|
|
109
|
-
var SHOPIFY_CAPABILITIES = {
|
|
110
|
-
// Profile Management
|
|
111
|
-
updateProfile: true,
|
|
112
|
-
updateEmail: true,
|
|
113
|
-
changePasswordDirect: true,
|
|
114
|
-
changePasswordViaEmail: true,
|
|
115
|
-
deleteAccount: false,
|
|
116
|
-
// Requires admin API
|
|
117
|
-
// Avatar
|
|
118
|
-
uploadAvatar: false,
|
|
119
|
-
avatarViaMetadata: true,
|
|
120
|
-
// Custom Attributes
|
|
121
|
-
customAttributes: true,
|
|
122
|
-
// Orders
|
|
123
|
-
fetchOrders: true,
|
|
124
|
-
cancelOrder: true,
|
|
125
|
-
// Addresses
|
|
126
|
-
manageAddresses: true,
|
|
127
|
-
defaultAddress: true,
|
|
128
|
-
// Cart/Checkout
|
|
129
|
-
applyDiscounts: true,
|
|
130
|
-
shippingCalculation: true,
|
|
131
|
-
guestCheckout: true,
|
|
132
|
-
savedPaymentMethods: true,
|
|
133
|
-
listPaymentProviders: true,
|
|
134
|
-
regionSpecificPayments: false,
|
|
135
|
-
// Global payment methods
|
|
136
|
-
// Wishlist
|
|
137
|
-
wishlist: false,
|
|
138
|
-
// Requires app
|
|
139
|
-
// Search
|
|
140
|
-
advancedSearch: true,
|
|
141
|
-
facetedFilters: true,
|
|
142
|
-
// Reviews
|
|
143
|
-
productReviews: false,
|
|
144
|
-
// Requires app
|
|
145
|
-
// Loyalty
|
|
146
|
-
loyaltyProgram: false
|
|
147
|
-
// Requires app
|
|
148
|
-
};
|
|
149
|
-
var BIGCOMMERCE_CAPABILITIES = {
|
|
150
|
-
// Profile Management
|
|
151
|
-
updateProfile: true,
|
|
152
|
-
updateEmail: true,
|
|
153
|
-
changePasswordDirect: true,
|
|
154
|
-
changePasswordViaEmail: true,
|
|
155
|
-
deleteAccount: false,
|
|
156
|
-
// Avatar
|
|
157
|
-
uploadAvatar: false,
|
|
158
|
-
avatarViaMetadata: false,
|
|
159
|
-
// Custom Attributes
|
|
160
|
-
customAttributes: true,
|
|
161
|
-
// Orders
|
|
162
|
-
fetchOrders: true,
|
|
163
|
-
cancelOrder: false,
|
|
164
|
-
// Admin API only
|
|
165
|
-
// Addresses
|
|
166
|
-
manageAddresses: true,
|
|
167
|
-
defaultAddress: false,
|
|
168
|
-
// Cart/Checkout
|
|
169
|
-
applyDiscounts: true,
|
|
170
|
-
shippingCalculation: true,
|
|
171
|
-
guestCheckout: true,
|
|
172
|
-
savedPaymentMethods: true,
|
|
173
|
-
listPaymentProviders: true,
|
|
174
|
-
regionSpecificPayments: false,
|
|
175
|
-
// Wishlist
|
|
176
|
-
wishlist: true,
|
|
177
|
-
// Native support
|
|
178
|
-
// Search
|
|
179
|
-
advancedSearch: true,
|
|
180
|
-
facetedFilters: true,
|
|
181
|
-
// Reviews
|
|
182
|
-
productReviews: true,
|
|
183
|
-
// Native support
|
|
184
|
-
// Loyalty
|
|
185
|
-
loyaltyProgram: false
|
|
186
|
-
};
|
|
187
|
-
var WOOCOMMERCE_CAPABILITIES = {
|
|
188
|
-
// Profile Management
|
|
189
|
-
updateProfile: true,
|
|
190
|
-
updateEmail: true,
|
|
191
|
-
changePasswordDirect: false,
|
|
192
|
-
// WordPress handles auth
|
|
193
|
-
changePasswordViaEmail: true,
|
|
194
|
-
deleteAccount: false,
|
|
195
|
-
// Avatar
|
|
196
|
-
uploadAvatar: false,
|
|
197
|
-
avatarViaMetadata: false,
|
|
198
|
-
// Gravatar-based
|
|
199
|
-
// Custom Attributes
|
|
200
|
-
customAttributes: true,
|
|
201
|
-
// Via meta_data
|
|
202
|
-
// Orders
|
|
203
|
-
fetchOrders: true,
|
|
204
|
-
cancelOrder: true,
|
|
205
|
-
// Addresses
|
|
206
|
-
manageAddresses: true,
|
|
207
|
-
defaultAddress: false,
|
|
208
|
-
// Billing/shipping only
|
|
209
|
-
// Cart/Checkout
|
|
210
|
-
applyDiscounts: true,
|
|
211
|
-
// Coupon codes
|
|
212
|
-
shippingCalculation: true,
|
|
213
|
-
guestCheckout: true,
|
|
214
|
-
savedPaymentMethods: false,
|
|
215
|
-
listPaymentProviders: true,
|
|
216
|
-
regionSpecificPayments: false,
|
|
217
|
-
// Wishlist
|
|
218
|
-
wishlist: false,
|
|
219
|
-
// Requires plugin
|
|
220
|
-
// Search
|
|
221
|
-
advancedSearch: false,
|
|
222
|
-
// Basic WP search
|
|
223
|
-
facetedFilters: false,
|
|
224
|
-
// Requires plugin
|
|
225
|
-
// Reviews
|
|
226
|
-
productReviews: true,
|
|
227
|
-
// Native WP reviews
|
|
228
|
-
// Loyalty
|
|
229
|
-
loyaltyProgram: false
|
|
230
|
-
};
|
|
231
|
-
var SPREE_CAPABILITIES = {
|
|
232
|
-
// Profile Management
|
|
233
|
-
updateProfile: true,
|
|
234
|
-
updateEmail: true,
|
|
235
|
-
changePasswordDirect: true,
|
|
236
|
-
changePasswordViaEmail: true,
|
|
237
|
-
deleteAccount: false,
|
|
238
|
-
// Avatar
|
|
239
|
-
uploadAvatar: false,
|
|
240
|
-
avatarViaMetadata: false,
|
|
241
|
-
// Custom Attributes
|
|
242
|
-
customAttributes: false,
|
|
243
|
-
// Orders
|
|
244
|
-
fetchOrders: true,
|
|
245
|
-
cancelOrder: true,
|
|
246
|
-
// Addresses
|
|
247
|
-
manageAddresses: true,
|
|
248
|
-
defaultAddress: true,
|
|
249
|
-
// Cart/Checkout
|
|
250
|
-
applyDiscounts: true,
|
|
251
|
-
shippingCalculation: true,
|
|
252
|
-
guestCheckout: true,
|
|
253
|
-
savedPaymentMethods: false,
|
|
254
|
-
listPaymentProviders: true,
|
|
255
|
-
regionSpecificPayments: false,
|
|
256
|
-
// Wishlist
|
|
257
|
-
wishlist: true,
|
|
258
|
-
// Native support
|
|
259
|
-
// Search
|
|
260
|
-
advancedSearch: false,
|
|
261
|
-
facetedFilters: true,
|
|
262
|
-
// Taxon-based filtering
|
|
263
|
-
// Reviews
|
|
264
|
-
productReviews: false,
|
|
265
|
-
// Requires extension
|
|
266
|
-
// Loyalty
|
|
267
|
-
loyaltyProgram: false
|
|
268
|
-
};
|
|
269
|
-
var MAGENTO_CAPABILITIES = {
|
|
270
|
-
// Profile Management
|
|
271
|
-
updateProfile: true,
|
|
272
|
-
updateEmail: true,
|
|
273
|
-
changePasswordDirect: true,
|
|
274
|
-
changePasswordViaEmail: true,
|
|
275
|
-
deleteAccount: false,
|
|
276
|
-
// Admin only
|
|
277
|
-
// Avatar
|
|
278
|
-
uploadAvatar: false,
|
|
279
|
-
avatarViaMetadata: false,
|
|
280
|
-
// Custom Attributes
|
|
281
|
-
customAttributes: true,
|
|
282
|
-
// EAV model
|
|
283
|
-
// Orders
|
|
284
|
-
fetchOrders: true,
|
|
285
|
-
cancelOrder: true,
|
|
286
|
-
// Addresses
|
|
287
|
-
manageAddresses: true,
|
|
288
|
-
defaultAddress: true,
|
|
289
|
-
// Cart/Checkout
|
|
290
|
-
applyDiscounts: true,
|
|
291
|
-
shippingCalculation: true,
|
|
292
|
-
guestCheckout: true,
|
|
293
|
-
savedPaymentMethods: true,
|
|
294
|
-
listPaymentProviders: true,
|
|
295
|
-
regionSpecificPayments: true,
|
|
296
|
-
// Store-view scoped
|
|
297
|
-
// Wishlist
|
|
298
|
-
wishlist: true,
|
|
299
|
-
// Native support
|
|
300
|
-
// Search
|
|
301
|
-
advancedSearch: true,
|
|
302
|
-
// Elasticsearch/OpenSearch
|
|
303
|
-
facetedFilters: true,
|
|
304
|
-
// Layered navigation
|
|
305
|
-
// Reviews
|
|
306
|
-
productReviews: true,
|
|
307
|
-
// Native support
|
|
308
|
-
// Loyalty
|
|
309
|
-
loyaltyProgram: false
|
|
310
|
-
// Requires extension
|
|
311
|
-
};
|
|
312
109
|
function isBackendCapabilities(obj) {
|
|
313
110
|
if (typeof obj !== "object" || obj === null) return false;
|
|
314
111
|
const capabilities = obj;
|
|
@@ -1528,13 +1325,7 @@ function createBackendMetadataAdapter(config) {
|
|
|
1528
1325
|
});
|
|
1529
1326
|
return new MedusaMetadataAdapter(medusa);
|
|
1530
1327
|
}
|
|
1531
|
-
|
|
1532
|
-
throw new Error("Shopify metadata adapter not yet implemented");
|
|
1533
|
-
}
|
|
1534
|
-
if (provider === "woocommerce") {
|
|
1535
|
-
throw new Error("WooCommerce metadata adapter not yet implemented");
|
|
1536
|
-
}
|
|
1537
|
-
throw new Error(`Unsupported provider: ${provider}`);
|
|
1328
|
+
throw new Error(`Unsupported provider for metadata adapter: ${provider}. Only 'medusa' is currently supported.`);
|
|
1538
1329
|
}
|
|
1539
1330
|
|
|
1540
1331
|
// src/metadata/channel-scope.ts
|
|
@@ -5787,2669 +5578,62 @@ var MedusaProvider = class {
|
|
|
5787
5578
|
}
|
|
5788
5579
|
};
|
|
5789
5580
|
|
|
5790
|
-
// src/providers/
|
|
5791
|
-
function
|
|
5792
|
-
|
|
5793
|
-
|
|
5794
|
-
|
|
5795
|
-
|
|
5796
|
-
}
|
|
5797
|
-
function transformImage2(shopifyImage) {
|
|
5798
|
-
return {
|
|
5799
|
-
url: shopifyImage?.url ?? "",
|
|
5800
|
-
altText: shopifyImage?.altText ?? "",
|
|
5801
|
-
width: shopifyImage?.width ?? 800,
|
|
5802
|
-
height: shopifyImage?.height ?? 800
|
|
5803
|
-
};
|
|
5581
|
+
// src/providers/stelorder/transforms.ts
|
|
5582
|
+
function normalizeStelCollection(payload) {
|
|
5583
|
+
if (!payload) {
|
|
5584
|
+
return [];
|
|
5585
|
+
}
|
|
5586
|
+
return Array.isArray(payload) ? payload : [payload];
|
|
5804
5587
|
}
|
|
5805
|
-
function
|
|
5806
|
-
|
|
5807
|
-
|
|
5808
|
-
|
|
5809
|
-
|
|
5810
|
-
price: transformMoney2(raw.price),
|
|
5811
|
-
compareAtPrice: raw.compareAtPrice ? transformMoney2(raw.compareAtPrice) : void 0,
|
|
5812
|
-
selectedOptions: (raw.selectedOptions ?? []).map((opt) => ({
|
|
5813
|
-
name: opt.name,
|
|
5814
|
-
value: opt.value
|
|
5815
|
-
})),
|
|
5816
|
-
image: raw.image ? transformImage2(raw.image) : void 0
|
|
5817
|
-
};
|
|
5588
|
+
function normalizeStelEntity(payload) {
|
|
5589
|
+
if (!payload) {
|
|
5590
|
+
return void 0;
|
|
5591
|
+
}
|
|
5592
|
+
return Array.isArray(payload) ? payload[0] : payload;
|
|
5818
5593
|
}
|
|
5819
|
-
function
|
|
5594
|
+
function transformStelMoney(amount, currencyCode = "USD") {
|
|
5595
|
+
const normalizedAmount = typeof amount === "string" ? Number.parseFloat(amount) : amount ?? 0;
|
|
5820
5596
|
return {
|
|
5821
|
-
|
|
5822
|
-
|
|
5823
|
-
values: raw.values ?? []
|
|
5597
|
+
amount: Number.isFinite(normalizedAmount) ? normalizedAmount.toFixed(2) : "0.00",
|
|
5598
|
+
currencyCode: currencyCode.toUpperCase()
|
|
5824
5599
|
};
|
|
5825
5600
|
}
|
|
5826
|
-
function
|
|
5827
|
-
const
|
|
5828
|
-
|
|
5601
|
+
function transformStelImage(url, altText = "") {
|
|
5602
|
+
const normalizedUrl = url?.trim();
|
|
5603
|
+
if (!normalizedUrl) {
|
|
5604
|
+
return void 0;
|
|
5605
|
+
}
|
|
5829
5606
|
return {
|
|
5830
|
-
|
|
5831
|
-
|
|
5832
|
-
|
|
5833
|
-
|
|
5834
|
-
descriptionHtml: raw.descriptionHtml ?? "",
|
|
5835
|
-
availableForSale: raw.availableForSale ?? true,
|
|
5836
|
-
featuredImage: raw.featuredImage ? transformImage2(raw.featuredImage) : images[0] ?? { url: "", altText: "", width: 800, height: 800 },
|
|
5837
|
-
images,
|
|
5838
|
-
options: (raw.options ?? []).map(transformOption),
|
|
5839
|
-
variants,
|
|
5840
|
-
priceRange: {
|
|
5841
|
-
minVariantPrice: transformMoney2(raw.priceRange?.minVariantPrice),
|
|
5842
|
-
maxVariantPrice: transformMoney2(raw.priceRange?.maxVariantPrice)
|
|
5843
|
-
},
|
|
5844
|
-
seo: {
|
|
5845
|
-
title: raw.seo?.title ?? raw.title ?? "",
|
|
5846
|
-
description: raw.seo?.description ?? raw.description ?? ""
|
|
5847
|
-
},
|
|
5848
|
-
tags: raw.tags ?? [],
|
|
5849
|
-
createdAt: raw.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
5850
|
-
updatedAt: raw.updatedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
5851
|
-
vendor: raw.vendor,
|
|
5852
|
-
productType: raw.productType
|
|
5607
|
+
url: normalizedUrl,
|
|
5608
|
+
altText,
|
|
5609
|
+
width: 800,
|
|
5610
|
+
height: 800
|
|
5853
5611
|
};
|
|
5854
5612
|
}
|
|
5855
|
-
function
|
|
5856
|
-
|
|
5857
|
-
|
|
5858
|
-
|
|
5859
|
-
|
|
5860
|
-
|
|
5861
|
-
seo: {
|
|
5862
|
-
title: raw.seo?.title ?? raw.title ?? "",
|
|
5863
|
-
description: raw.seo?.description ?? raw.description ?? ""
|
|
5864
|
-
},
|
|
5865
|
-
updatedAt: raw.updatedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
5866
|
-
path: `/collections/${raw.handle}`
|
|
5867
|
-
};
|
|
5613
|
+
function normalizeStelDate(value) {
|
|
5614
|
+
if (!value) {
|
|
5615
|
+
return (/* @__PURE__ */ new Date()).toISOString();
|
|
5616
|
+
}
|
|
5617
|
+
const parsed = new Date(value);
|
|
5618
|
+
return Number.isNaN(parsed.getTime()) ? (/* @__PURE__ */ new Date()).toISOString() : parsed.toISOString();
|
|
5868
5619
|
}
|
|
5869
|
-
function
|
|
5870
|
-
|
|
5871
|
-
|
|
5872
|
-
|
|
5873
|
-
|
|
5874
|
-
quantity: raw.quantity ?? 1,
|
|
5875
|
-
cost: {
|
|
5876
|
-
totalAmount: transformMoney2(raw.cost?.totalAmount)
|
|
5877
|
-
},
|
|
5878
|
-
merchandise: {
|
|
5879
|
-
id: merchandise.id ?? "",
|
|
5880
|
-
title: merchandise.title ?? "",
|
|
5881
|
-
selectedOptions: (merchandise.selectedOptions ?? []).map((opt) => ({
|
|
5882
|
-
name: opt.name,
|
|
5883
|
-
value: opt.value
|
|
5884
|
-
})),
|
|
5885
|
-
product: {
|
|
5886
|
-
id: product.id ?? "",
|
|
5887
|
-
handle: product.handle ?? "",
|
|
5888
|
-
title: product.title ?? "",
|
|
5889
|
-
featuredImage: product.featuredImage ? transformImage2(product.featuredImage) : { url: "", altText: "", width: 800, height: 800 }
|
|
5890
|
-
}
|
|
5891
|
-
}
|
|
5892
|
-
};
|
|
5620
|
+
function toStelStringId(value) {
|
|
5621
|
+
if (value === null || value === void 0) {
|
|
5622
|
+
return "";
|
|
5623
|
+
}
|
|
5624
|
+
return String(value);
|
|
5893
5625
|
}
|
|
5894
|
-
function
|
|
5895
|
-
|
|
5896
|
-
return {
|
|
5897
|
-
id: raw.id,
|
|
5898
|
-
checkoutUrl: raw.checkoutUrl ?? "",
|
|
5899
|
-
totalQuantity: raw.totalQuantity ?? 0,
|
|
5900
|
-
cost: {
|
|
5901
|
-
subtotalAmount: transformMoney2(raw.cost?.subtotalAmount),
|
|
5902
|
-
totalAmount: transformMoney2(raw.cost?.totalAmount),
|
|
5903
|
-
totalTaxAmount: raw.cost?.totalTaxAmount ? transformMoney2(raw.cost.totalTaxAmount) : void 0
|
|
5904
|
-
},
|
|
5905
|
-
lines
|
|
5906
|
-
};
|
|
5626
|
+
function slugify(value) {
|
|
5627
|
+
return value.normalize("NFKD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
5907
5628
|
}
|
|
5908
|
-
|
|
5909
|
-
|
|
5910
|
-
|
|
5911
|
-
|
|
5912
|
-
id
|
|
5913
|
-
title
|
|
5914
|
-
handle
|
|
5915
|
-
description
|
|
5916
|
-
descriptionHtml
|
|
5917
|
-
vendor
|
|
5918
|
-
productType
|
|
5919
|
-
tags
|
|
5920
|
-
availableForSale
|
|
5921
|
-
createdAt
|
|
5922
|
-
updatedAt
|
|
5923
|
-
seo {
|
|
5924
|
-
title
|
|
5925
|
-
description
|
|
5926
|
-
}
|
|
5927
|
-
featuredImage {
|
|
5928
|
-
url
|
|
5929
|
-
altText
|
|
5930
|
-
width
|
|
5931
|
-
height
|
|
5932
|
-
}
|
|
5933
|
-
images(first: 10) {
|
|
5934
|
-
edges {
|
|
5935
|
-
node {
|
|
5936
|
-
url
|
|
5937
|
-
altText
|
|
5938
|
-
width
|
|
5939
|
-
height
|
|
5940
|
-
}
|
|
5941
|
-
}
|
|
5942
|
-
}
|
|
5943
|
-
priceRange {
|
|
5944
|
-
minVariantPrice {
|
|
5945
|
-
amount
|
|
5946
|
-
currencyCode
|
|
5947
|
-
}
|
|
5948
|
-
maxVariantPrice {
|
|
5949
|
-
amount
|
|
5950
|
-
currencyCode
|
|
5951
|
-
}
|
|
5952
|
-
}
|
|
5953
|
-
options {
|
|
5954
|
-
id
|
|
5955
|
-
name
|
|
5956
|
-
values
|
|
5957
|
-
}
|
|
5958
|
-
variants(first: 100) {
|
|
5959
|
-
edges {
|
|
5960
|
-
node {
|
|
5961
|
-
id
|
|
5962
|
-
title
|
|
5963
|
-
availableForSale
|
|
5964
|
-
price {
|
|
5965
|
-
amount
|
|
5966
|
-
currencyCode
|
|
5967
|
-
}
|
|
5968
|
-
compareAtPrice {
|
|
5969
|
-
amount
|
|
5970
|
-
currencyCode
|
|
5971
|
-
}
|
|
5972
|
-
selectedOptions {
|
|
5973
|
-
name
|
|
5974
|
-
value
|
|
5975
|
-
}
|
|
5976
|
-
image {
|
|
5977
|
-
url
|
|
5978
|
-
altText
|
|
5979
|
-
width
|
|
5980
|
-
height
|
|
5981
|
-
}
|
|
5982
|
-
}
|
|
5983
|
-
}
|
|
5629
|
+
function buildStelHandle(...candidates) {
|
|
5630
|
+
for (const candidate of candidates) {
|
|
5631
|
+
if (candidate === null || candidate === void 0) {
|
|
5632
|
+
continue;
|
|
5984
5633
|
}
|
|
5985
|
-
|
|
5986
|
-
|
|
5987
|
-
|
|
5988
|
-
query GetProductByHandle($handle: String!) {
|
|
5989
|
-
product(handle: $handle) {
|
|
5990
|
-
...ProductFields
|
|
5991
|
-
}
|
|
5992
|
-
}
|
|
5993
|
-
${PRODUCT_FRAGMENT}
|
|
5994
|
-
`;
|
|
5995
|
-
var GET_PRODUCTS = `
|
|
5996
|
-
query GetProducts($first: Int!, $query: String, $sortKey: ProductSortKeys, $reverse: Boolean, $after: String) {
|
|
5997
|
-
products(first: $first, query: $query, sortKey: $sortKey, reverse: $reverse, after: $after) {
|
|
5998
|
-
edges {
|
|
5999
|
-
node {
|
|
6000
|
-
...ProductFields
|
|
6001
|
-
}
|
|
6002
|
-
cursor
|
|
6003
|
-
}
|
|
6004
|
-
pageInfo {
|
|
6005
|
-
hasNextPage
|
|
6006
|
-
hasPreviousPage
|
|
6007
|
-
}
|
|
6008
|
-
}
|
|
6009
|
-
}
|
|
6010
|
-
${PRODUCT_FRAGMENT}
|
|
6011
|
-
`;
|
|
6012
|
-
var GET_PRODUCT_RECOMMENDATIONS = `
|
|
6013
|
-
query GetProductRecommendations($productId: ID!) {
|
|
6014
|
-
productRecommendations(productId: $productId) {
|
|
6015
|
-
...ProductFields
|
|
6016
|
-
}
|
|
6017
|
-
}
|
|
6018
|
-
${PRODUCT_FRAGMENT}
|
|
6019
|
-
`;
|
|
6020
|
-
var COLLECTION_FRAGMENT = `
|
|
6021
|
-
fragment CollectionFields on Collection {
|
|
6022
|
-
id
|
|
6023
|
-
title
|
|
6024
|
-
handle
|
|
6025
|
-
description
|
|
6026
|
-
image {
|
|
6027
|
-
url
|
|
6028
|
-
altText
|
|
6029
|
-
width
|
|
6030
|
-
height
|
|
6031
|
-
}
|
|
6032
|
-
seo {
|
|
6033
|
-
title
|
|
6034
|
-
description
|
|
6035
|
-
}
|
|
6036
|
-
updatedAt
|
|
6037
|
-
}
|
|
6038
|
-
`;
|
|
6039
|
-
var GET_COLLECTION_BY_HANDLE = `
|
|
6040
|
-
query GetCollectionByHandle($handle: String!) {
|
|
6041
|
-
collection(handle: $handle) {
|
|
6042
|
-
...CollectionFields
|
|
6043
|
-
}
|
|
6044
|
-
}
|
|
6045
|
-
${COLLECTION_FRAGMENT}
|
|
6046
|
-
`;
|
|
6047
|
-
var GET_COLLECTIONS = `
|
|
6048
|
-
query GetCollections($first: Int!) {
|
|
6049
|
-
collections(first: $first) {
|
|
6050
|
-
edges {
|
|
6051
|
-
node {
|
|
6052
|
-
...CollectionFields
|
|
6053
|
-
}
|
|
6054
|
-
}
|
|
6055
|
-
}
|
|
6056
|
-
}
|
|
6057
|
-
${COLLECTION_FRAGMENT}
|
|
6058
|
-
`;
|
|
6059
|
-
var GET_COLLECTION_PRODUCTS = `
|
|
6060
|
-
query GetCollectionProducts($handle: String!, $first: Int!, $sortKey: ProductCollectionSortKeys, $reverse: Boolean, $after: String) {
|
|
6061
|
-
collection(handle: $handle) {
|
|
6062
|
-
products(first: $first, sortKey: $sortKey, reverse: $reverse, after: $after) {
|
|
6063
|
-
edges {
|
|
6064
|
-
node {
|
|
6065
|
-
...ProductFields
|
|
6066
|
-
}
|
|
6067
|
-
cursor
|
|
6068
|
-
}
|
|
6069
|
-
pageInfo {
|
|
6070
|
-
hasNextPage
|
|
6071
|
-
}
|
|
6072
|
-
}
|
|
6073
|
-
}
|
|
6074
|
-
}
|
|
6075
|
-
${PRODUCT_FRAGMENT}
|
|
6076
|
-
`;
|
|
6077
|
-
var CART_FRAGMENT = `
|
|
6078
|
-
fragment CartFields on Cart {
|
|
6079
|
-
id
|
|
6080
|
-
checkoutUrl
|
|
6081
|
-
totalQuantity
|
|
6082
|
-
cost {
|
|
6083
|
-
subtotalAmount {
|
|
6084
|
-
amount
|
|
6085
|
-
currencyCode
|
|
6086
|
-
}
|
|
6087
|
-
totalAmount {
|
|
6088
|
-
amount
|
|
6089
|
-
currencyCode
|
|
6090
|
-
}
|
|
6091
|
-
totalTaxAmount {
|
|
6092
|
-
amount
|
|
6093
|
-
currencyCode
|
|
6094
|
-
}
|
|
6095
|
-
}
|
|
6096
|
-
lines(first: 100) {
|
|
6097
|
-
edges {
|
|
6098
|
-
node {
|
|
6099
|
-
id
|
|
6100
|
-
quantity
|
|
6101
|
-
cost {
|
|
6102
|
-
totalAmount {
|
|
6103
|
-
amount
|
|
6104
|
-
currencyCode
|
|
6105
|
-
}
|
|
6106
|
-
}
|
|
6107
|
-
merchandise {
|
|
6108
|
-
... on ProductVariant {
|
|
6109
|
-
id
|
|
6110
|
-
title
|
|
6111
|
-
selectedOptions {
|
|
6112
|
-
name
|
|
6113
|
-
value
|
|
6114
|
-
}
|
|
6115
|
-
product {
|
|
6116
|
-
id
|
|
6117
|
-
handle
|
|
6118
|
-
title
|
|
6119
|
-
featuredImage {
|
|
6120
|
-
url
|
|
6121
|
-
altText
|
|
6122
|
-
width
|
|
6123
|
-
height
|
|
6124
|
-
}
|
|
6125
|
-
}
|
|
6126
|
-
}
|
|
6127
|
-
}
|
|
6128
|
-
}
|
|
6129
|
-
}
|
|
6130
|
-
}
|
|
6131
|
-
}
|
|
6132
|
-
`;
|
|
6133
|
-
var GET_CART = `
|
|
6134
|
-
query GetCart($cartId: ID!) {
|
|
6135
|
-
cart(id: $cartId) {
|
|
6136
|
-
...CartFields
|
|
6137
|
-
}
|
|
6138
|
-
}
|
|
6139
|
-
${CART_FRAGMENT}
|
|
6140
|
-
`;
|
|
6141
|
-
|
|
6142
|
-
// src/providers/shopify/mutations.ts
|
|
6143
|
-
var CART_CREATE = `
|
|
6144
|
-
mutation CartCreate($input: CartInput!) {
|
|
6145
|
-
cartCreate(input: $input) {
|
|
6146
|
-
cart {
|
|
6147
|
-
...CartFields
|
|
6148
|
-
}
|
|
6149
|
-
userErrors {
|
|
6150
|
-
field
|
|
6151
|
-
message
|
|
6152
|
-
code
|
|
6153
|
-
}
|
|
6154
|
-
}
|
|
6155
|
-
}
|
|
6156
|
-
${CART_FRAGMENT}
|
|
6157
|
-
`;
|
|
6158
|
-
var CART_LINES_ADD = `
|
|
6159
|
-
mutation CartLinesAdd($cartId: ID!, $lines: [CartLineInput!]!) {
|
|
6160
|
-
cartLinesAdd(cartId: $cartId, lines: $lines) {
|
|
6161
|
-
cart {
|
|
6162
|
-
...CartFields
|
|
6163
|
-
}
|
|
6164
|
-
userErrors {
|
|
6165
|
-
field
|
|
6166
|
-
message
|
|
6167
|
-
code
|
|
6168
|
-
}
|
|
6169
|
-
}
|
|
6170
|
-
}
|
|
6171
|
-
${CART_FRAGMENT}
|
|
6172
|
-
`;
|
|
6173
|
-
var CART_LINES_UPDATE = `
|
|
6174
|
-
mutation CartLinesUpdate($cartId: ID!, $lines: [CartLineUpdateInput!]!) {
|
|
6175
|
-
cartLinesUpdate(cartId: $cartId, lines: $lines) {
|
|
6176
|
-
cart {
|
|
6177
|
-
...CartFields
|
|
6178
|
-
}
|
|
6179
|
-
userErrors {
|
|
6180
|
-
field
|
|
6181
|
-
message
|
|
6182
|
-
code
|
|
6183
|
-
}
|
|
6184
|
-
}
|
|
6185
|
-
}
|
|
6186
|
-
${CART_FRAGMENT}
|
|
6187
|
-
`;
|
|
6188
|
-
var CART_LINES_REMOVE = `
|
|
6189
|
-
mutation CartLinesRemove($cartId: ID!, $lineIds: [ID!]!) {
|
|
6190
|
-
cartLinesRemove(cartId: $cartId, lineIds: $lineIds) {
|
|
6191
|
-
cart {
|
|
6192
|
-
...CartFields
|
|
6193
|
-
}
|
|
6194
|
-
userErrors {
|
|
6195
|
-
field
|
|
6196
|
-
message
|
|
6197
|
-
code
|
|
6198
|
-
}
|
|
6199
|
-
}
|
|
6200
|
-
}
|
|
6201
|
-
${CART_FRAGMENT}
|
|
6202
|
-
`;
|
|
6203
|
-
var CART_DISCOUNT_CODES_UPDATE = `
|
|
6204
|
-
mutation CartDiscountCodesUpdate($cartId: ID!, $discountCodes: [String!]!) {
|
|
6205
|
-
cartDiscountCodesUpdate(cartId: $cartId, discountCodes: $discountCodes) {
|
|
6206
|
-
cart {
|
|
6207
|
-
...CartFields
|
|
6208
|
-
}
|
|
6209
|
-
userErrors {
|
|
6210
|
-
field
|
|
6211
|
-
message
|
|
6212
|
-
code
|
|
6213
|
-
}
|
|
6214
|
-
}
|
|
6215
|
-
}
|
|
6216
|
-
${CART_FRAGMENT}
|
|
6217
|
-
`;
|
|
6218
|
-
|
|
6219
|
-
// src/providers/shopify/index.ts
|
|
6220
|
-
var ShopifyProvider = class {
|
|
6221
|
-
name = "shopify";
|
|
6222
|
-
version = "1.0.0";
|
|
6223
|
-
capabilities = SHOPIFY_CAPABILITIES;
|
|
6224
|
-
logger;
|
|
6225
|
-
storeDomain;
|
|
6226
|
-
apiVersion;
|
|
6227
|
-
endpoint;
|
|
6228
|
-
headers;
|
|
6229
|
-
constructor(config) {
|
|
6230
|
-
this.logger = createLogger("ShopifyProvider", config.debug);
|
|
6231
|
-
this.storeDomain = config.storeDomain.replace(/^https?:\/\//, "").replace(/\/$/, "");
|
|
6232
|
-
this.apiVersion = config.apiVersion ?? "2026-04";
|
|
6233
|
-
this.endpoint = `https://${this.storeDomain}/api/${this.apiVersion}/graphql.json`;
|
|
6234
|
-
this.headers = {
|
|
6235
|
-
"Content-Type": "application/json",
|
|
6236
|
-
...config.privateAccessToken ? { "Shopify-Storefront-Private-Token": config.privateAccessToken } : { "X-Shopify-Storefront-Access-Token": config.publicAccessToken }
|
|
6237
|
-
};
|
|
6238
|
-
this.logger.info("Initializing Shopify Provider", {
|
|
6239
|
-
storeDomain: this.storeDomain,
|
|
6240
|
-
apiVersion: this.apiVersion,
|
|
6241
|
-
authType: config.privateAccessToken ? "private" : "public"
|
|
6242
|
-
});
|
|
6243
|
-
}
|
|
6244
|
-
// ============================================
|
|
6245
|
-
// GraphQL Client
|
|
6246
|
-
// ============================================
|
|
6247
|
-
async query(gql, variables) {
|
|
6248
|
-
const response = await fetch(this.endpoint, {
|
|
6249
|
-
method: "POST",
|
|
6250
|
-
headers: this.headers,
|
|
6251
|
-
body: JSON.stringify({ query: gql, variables })
|
|
6252
|
-
});
|
|
6253
|
-
if (!response.ok) {
|
|
6254
|
-
throw new ProviderAPIError(
|
|
6255
|
-
`Shopify API error: ${response.status} ${response.statusText}`,
|
|
6256
|
-
"SHOPIFY_API_ERROR",
|
|
6257
|
-
response.status
|
|
6258
|
-
);
|
|
6259
|
-
}
|
|
6260
|
-
const json = await response.json();
|
|
6261
|
-
if (json.errors?.length) {
|
|
6262
|
-
const message = json.errors.map((e) => e.message).join("; ");
|
|
6263
|
-
throw new ProviderAPIError(`Shopify GraphQL error: ${message}`, "SHOPIFY_GRAPHQL_ERROR");
|
|
6264
|
-
}
|
|
6265
|
-
return json.data;
|
|
6266
|
-
}
|
|
6267
|
-
// ============================================
|
|
6268
|
-
// Product Operations
|
|
6269
|
-
// ============================================
|
|
6270
|
-
async getProduct(handle) {
|
|
6271
|
-
const data = await this.query(GET_PRODUCT_BY_HANDLE, { handle });
|
|
6272
|
-
return data.product ? transformProduct2(data.product) : void 0;
|
|
6273
|
-
}
|
|
6274
|
-
async getProducts(options) {
|
|
6275
|
-
const first = options?.first ?? 20;
|
|
6276
|
-
const sortKeyMap = {
|
|
6277
|
-
"title-asc": "TITLE",
|
|
6278
|
-
"title-desc": "TITLE",
|
|
6279
|
-
"price-asc": "PRICE",
|
|
6280
|
-
"price-desc": "PRICE",
|
|
6281
|
-
"best-selling": "BEST_SELLING",
|
|
6282
|
-
"created-desc": "CREATED_AT",
|
|
6283
|
-
"relevance": "RELEVANCE"
|
|
6284
|
-
};
|
|
6285
|
-
const sortKey = options?.sortKey ? sortKeyMap[options.sortKey] ?? "RELEVANCE" : "RELEVANCE";
|
|
6286
|
-
const reverse = options?.sortKey?.endsWith("-desc") ?? false;
|
|
6287
|
-
const data = await this.query(GET_PRODUCTS, {
|
|
6288
|
-
first,
|
|
6289
|
-
query: options?.query,
|
|
6290
|
-
sortKey,
|
|
6291
|
-
reverse
|
|
6292
|
-
});
|
|
6293
|
-
return data.products.edges.map((edge) => transformProduct2(edge.node));
|
|
6294
|
-
}
|
|
6295
|
-
async getProductRecommendations(productId) {
|
|
6296
|
-
const data = await this.query(GET_PRODUCT_RECOMMENDATIONS, {
|
|
6297
|
-
productId
|
|
6298
|
-
});
|
|
6299
|
-
return (data.productRecommendations ?? []).map(transformProduct2);
|
|
6300
|
-
}
|
|
6301
|
-
// ============================================
|
|
6302
|
-
// Collection Operations
|
|
6303
|
-
// ============================================
|
|
6304
|
-
async getCollection(handle) {
|
|
6305
|
-
const data = await this.query(GET_COLLECTION_BY_HANDLE, { handle });
|
|
6306
|
-
return data.collection ? transformCollection2(data.collection) : void 0;
|
|
6307
|
-
}
|
|
6308
|
-
async getCollections(options) {
|
|
6309
|
-
const data = await this.query(GET_COLLECTIONS, {
|
|
6310
|
-
first: options?.limit ?? 50
|
|
6311
|
-
});
|
|
6312
|
-
return data.collections.edges.map((edge) => transformCollection2(edge.node));
|
|
6313
|
-
}
|
|
6314
|
-
async getCollectionProducts(handle, options) {
|
|
6315
|
-
const data = await this.query(
|
|
6316
|
-
GET_COLLECTION_PRODUCTS,
|
|
6317
|
-
{
|
|
6318
|
-
handle,
|
|
6319
|
-
first: options?.first ?? 20,
|
|
6320
|
-
sortKey: options?.sortKey === "price-asc" || options?.sortKey === "price-desc" ? "PRICE" : "BEST_SELLING",
|
|
6321
|
-
reverse: options?.sortKey?.endsWith("-desc") ?? false
|
|
6322
|
-
}
|
|
6323
|
-
);
|
|
6324
|
-
return (data.collection?.products?.edges ?? []).map((edge) => transformProduct2(edge.node));
|
|
6325
|
-
}
|
|
6326
|
-
// ============================================
|
|
6327
|
-
// Category Operations (Shopify does not have native categories)
|
|
6328
|
-
// ============================================
|
|
6329
|
-
async getCategory() {
|
|
6330
|
-
this.logger.warn("Shopify does not support native categories. Use collections instead.");
|
|
6331
|
-
return void 0;
|
|
6332
|
-
}
|
|
6333
|
-
async getCategories() {
|
|
6334
|
-
return [];
|
|
6335
|
-
}
|
|
6336
|
-
async getCategoryProducts() {
|
|
6337
|
-
return [];
|
|
6338
|
-
}
|
|
6339
|
-
// ============================================
|
|
6340
|
-
// Cart Operations
|
|
6341
|
-
// ============================================
|
|
6342
|
-
async createCart() {
|
|
6343
|
-
const data = await this.query(CART_CREATE, {
|
|
6344
|
-
input: {}
|
|
6345
|
-
});
|
|
6346
|
-
if (data.cartCreate.userErrors?.length) {
|
|
6347
|
-
throw new ProviderAPIError(
|
|
6348
|
-
`Cart creation failed: ${data.cartCreate.userErrors.map((e) => e.message).join("; ")}`,
|
|
6349
|
-
"SHOPIFY_CART_ERROR"
|
|
6350
|
-
);
|
|
6351
|
-
}
|
|
6352
|
-
return transformCart2(data.cartCreate.cart);
|
|
6353
|
-
}
|
|
6354
|
-
async getCart(cartId) {
|
|
6355
|
-
const data = await this.query(GET_CART, { cartId });
|
|
6356
|
-
return data.cart ? transformCart2(data.cart) : void 0;
|
|
6357
|
-
}
|
|
6358
|
-
async addToCart(cartId, lines) {
|
|
6359
|
-
const data = await this.query(CART_LINES_ADD, {
|
|
6360
|
-
cartId,
|
|
6361
|
-
lines: lines.map((l) => ({ merchandiseId: l.merchandiseId, quantity: l.quantity }))
|
|
6362
|
-
});
|
|
6363
|
-
if (data.cartLinesAdd.userErrors?.length) {
|
|
6364
|
-
throw new ProviderAPIError(
|
|
6365
|
-
`Add to cart failed: ${data.cartLinesAdd.userErrors.map((e) => e.message).join("; ")}`,
|
|
6366
|
-
"SHOPIFY_CART_ERROR"
|
|
6367
|
-
);
|
|
6368
|
-
}
|
|
6369
|
-
return transformCart2(data.cartLinesAdd.cart);
|
|
6370
|
-
}
|
|
6371
|
-
async removeFromCart(cartId, lineIds) {
|
|
6372
|
-
const data = await this.query(CART_LINES_REMOVE, {
|
|
6373
|
-
cartId,
|
|
6374
|
-
lineIds
|
|
6375
|
-
});
|
|
6376
|
-
if (data.cartLinesRemove.userErrors?.length) {
|
|
6377
|
-
throw new ProviderAPIError(
|
|
6378
|
-
`Remove from cart failed: ${data.cartLinesRemove.userErrors.map((e) => e.message).join("; ")}`,
|
|
6379
|
-
"SHOPIFY_CART_ERROR"
|
|
6380
|
-
);
|
|
6381
|
-
}
|
|
6382
|
-
return transformCart2(data.cartLinesRemove.cart);
|
|
6383
|
-
}
|
|
6384
|
-
async updateCart(cartId, lines) {
|
|
6385
|
-
const data = await this.query(CART_LINES_UPDATE, {
|
|
6386
|
-
cartId,
|
|
6387
|
-
lines: lines.map((l) => ({ id: l.id, quantity: l.quantity }))
|
|
6388
|
-
});
|
|
6389
|
-
if (data.cartLinesUpdate.userErrors?.length) {
|
|
6390
|
-
throw new ProviderAPIError(
|
|
6391
|
-
`Update cart failed: ${data.cartLinesUpdate.userErrors.map((e) => e.message).join("; ")}`,
|
|
6392
|
-
"SHOPIFY_CART_ERROR"
|
|
6393
|
-
);
|
|
6394
|
-
}
|
|
6395
|
-
return transformCart2(data.cartLinesUpdate.cart);
|
|
6396
|
-
}
|
|
6397
|
-
// ============================================
|
|
6398
|
-
// Checkout Operations
|
|
6399
|
-
// ============================================
|
|
6400
|
-
async completeCheckout(_cartId) {
|
|
6401
|
-
throw new ProviderAPIError(
|
|
6402
|
-
"Shopify uses hosted checkout. Redirect the buyer to cart.checkoutUrl instead of calling completeCheckout().",
|
|
6403
|
-
"SHOPIFY_HOSTED_CHECKOUT"
|
|
6404
|
-
);
|
|
6405
|
-
}
|
|
6406
|
-
async getShippingMethods(_cartId) {
|
|
6407
|
-
return [];
|
|
6408
|
-
}
|
|
6409
|
-
async getRegionCountries() {
|
|
6410
|
-
return [];
|
|
6411
|
-
}
|
|
6412
|
-
async addShippingMethod(_cartId, _methodId) {
|
|
6413
|
-
throw new ProviderAPIError(
|
|
6414
|
-
"Shopify handles shipping selection in hosted checkout.",
|
|
6415
|
-
"SHOPIFY_HOSTED_CHECKOUT"
|
|
6416
|
-
);
|
|
6417
|
-
}
|
|
6418
|
-
async initiatePaymentSession(_cartId, _providerId) {
|
|
6419
|
-
throw new ProviderAPIError(
|
|
6420
|
-
"Shopify handles payment in hosted checkout.",
|
|
6421
|
-
"SHOPIFY_HOSTED_CHECKOUT"
|
|
6422
|
-
);
|
|
6423
|
-
}
|
|
6424
|
-
async applyDiscountCode(cartId, code) {
|
|
6425
|
-
const currentCart = await this.getCart(cartId);
|
|
6426
|
-
const existingCodes = [];
|
|
6427
|
-
existingCodes.push(code);
|
|
6428
|
-
const data = await this.query(
|
|
6429
|
-
CART_DISCOUNT_CODES_UPDATE,
|
|
6430
|
-
{ cartId, discountCodes: existingCodes }
|
|
6431
|
-
);
|
|
6432
|
-
if (data.cartDiscountCodesUpdate.userErrors?.length) {
|
|
6433
|
-
throw new ProviderAPIError(
|
|
6434
|
-
`Discount code failed: ${data.cartDiscountCodesUpdate.userErrors.map((e) => e.message).join("; ")}`,
|
|
6435
|
-
"SHOPIFY_DISCOUNT_ERROR"
|
|
6436
|
-
);
|
|
6437
|
-
}
|
|
6438
|
-
return transformCart2(data.cartDiscountCodesUpdate.cart);
|
|
6439
|
-
}
|
|
6440
|
-
async removeDiscountCode(cartId, _code) {
|
|
6441
|
-
const data = await this.query(
|
|
6442
|
-
CART_DISCOUNT_CODES_UPDATE,
|
|
6443
|
-
{ cartId, discountCodes: [] }
|
|
6444
|
-
);
|
|
6445
|
-
return transformCart2(data.cartDiscountCodesUpdate.cart);
|
|
6446
|
-
}
|
|
6447
|
-
// ============================================
|
|
6448
|
-
// Customer Operations
|
|
6449
|
-
// ============================================
|
|
6450
|
-
async getOrders(options) {
|
|
6451
|
-
this.logger.warn("Shopify orders require Customer Account API (planned upgrade path).");
|
|
6452
|
-
return [];
|
|
6453
|
-
}
|
|
6454
|
-
// ============================================
|
|
6455
|
-
// Payment Operations
|
|
6456
|
-
// ============================================
|
|
6457
|
-
async getPaymentMethods(_options) {
|
|
6458
|
-
return [];
|
|
6459
|
-
}
|
|
6460
|
-
// ============================================
|
|
6461
|
-
// Inventory Operations (not available via Storefront API)
|
|
6462
|
-
// ============================================
|
|
6463
|
-
async getStockLocations() {
|
|
6464
|
-
return [];
|
|
6465
|
-
}
|
|
6466
|
-
async checkInventoryLevels() {
|
|
6467
|
-
return [];
|
|
6468
|
-
}
|
|
6469
|
-
async validateCartStock() {
|
|
6470
|
-
return { allAvailable: true, unavailableItems: [] };
|
|
6471
|
-
}
|
|
6472
|
-
async getFulfillmentOptions() {
|
|
6473
|
-
return [];
|
|
6474
|
-
}
|
|
6475
|
-
// ============================================
|
|
6476
|
-
// Admin Operations (not available via Storefront API)
|
|
6477
|
-
// ============================================
|
|
6478
|
-
async cancelOrder(_orderId) {
|
|
6479
|
-
throw new ProviderAPIError(
|
|
6480
|
-
"Order cancellation requires Shopify Admin API (not available in Storefront API).",
|
|
6481
|
-
"SHOPIFY_ADMIN_REQUIRED"
|
|
6482
|
-
);
|
|
6483
|
-
}
|
|
6484
|
-
async createFulfillment(_orderId) {
|
|
6485
|
-
throw new ProviderAPIError(
|
|
6486
|
-
"Fulfillment requires Shopify Admin API.",
|
|
6487
|
-
"SHOPIFY_ADMIN_REQUIRED"
|
|
6488
|
-
);
|
|
6489
|
-
}
|
|
6490
|
-
async createRefund(_orderId) {
|
|
6491
|
-
throw new ProviderAPIError(
|
|
6492
|
-
"Refunds require Shopify Admin API.",
|
|
6493
|
-
"SHOPIFY_ADMIN_REQUIRED"
|
|
6494
|
-
);
|
|
6495
|
-
}
|
|
6496
|
-
async getAdminOrders() {
|
|
6497
|
-
return { orders: [], count: 0 };
|
|
6498
|
-
}
|
|
6499
|
-
// ============================================
|
|
6500
|
-
// Storefront / Multi-Tenant
|
|
6501
|
-
// ============================================
|
|
6502
|
-
async getStorefrontContext() {
|
|
6503
|
-
return {
|
|
6504
|
-
id: this.storeDomain,
|
|
6505
|
-
name: this.storeDomain,
|
|
6506
|
-
platformType: "shopify",
|
|
6507
|
-
requiresProductScoping: false,
|
|
6508
|
-
currencyCode: "USD"
|
|
6509
|
-
};
|
|
6510
|
-
}
|
|
6511
|
-
isStorefrontRequired() {
|
|
6512
|
-
return false;
|
|
6513
|
-
}
|
|
6514
|
-
};
|
|
6515
|
-
|
|
6516
|
-
// src/providers/bigcommerce/transforms.ts
|
|
6517
|
-
function transformMoney3(amount, currencyCode = "USD") {
|
|
6518
|
-
const numAmount = typeof amount === "string" ? parseFloat(amount) : amount ?? 0;
|
|
6519
|
-
return {
|
|
6520
|
-
amount: numAmount.toFixed(2),
|
|
6521
|
-
currencyCode: currencyCode.toUpperCase()
|
|
6522
|
-
};
|
|
6523
|
-
}
|
|
6524
|
-
function transformImage3(url, alt = "") {
|
|
6525
|
-
return { url, altText: alt, width: 800, height: 800 };
|
|
6526
|
-
}
|
|
6527
|
-
function transformProduct3(raw, currencyCode = "USD") {
|
|
6528
|
-
const images = (raw.images ?? []).map(
|
|
6529
|
-
(img) => transformImage3(img.url_standard ?? img.url_thumbnail ?? "", img.description ?? "")
|
|
6530
|
-
);
|
|
6531
|
-
const variants = (raw.variants ?? []).map((v) => ({
|
|
6532
|
-
id: String(v.id),
|
|
6533
|
-
title: v.option_display_name ?? `Variant ${v.id}`,
|
|
6534
|
-
availableForSale: v.purchasing_disabled !== true,
|
|
6535
|
-
price: transformMoney3(v.price ?? raw.price, currencyCode),
|
|
6536
|
-
compareAtPrice: v.sale_price ? transformMoney3(v.sale_price, currencyCode) : void 0,
|
|
6537
|
-
selectedOptions: (v.option_values ?? []).map((ov) => ({
|
|
6538
|
-
name: ov.option_display_name ?? "",
|
|
6539
|
-
value: ov.label ?? ""
|
|
6540
|
-
}))
|
|
6541
|
-
}));
|
|
6542
|
-
const options = (raw.options ?? []).map((opt) => ({
|
|
6543
|
-
id: String(opt.id),
|
|
6544
|
-
name: opt.display_name ?? "",
|
|
6545
|
-
values: (opt.option_values ?? []).map((val) => val.label ?? "")
|
|
6546
|
-
}));
|
|
6547
|
-
const price = raw.price ?? raw.calculated_price?.as_entered ?? 0;
|
|
6548
|
-
return {
|
|
6549
|
-
id: String(raw.id),
|
|
6550
|
-
handle: raw.custom_url?.url?.replace(/^\//, "").replace(/\/$/, "") ?? String(raw.id),
|
|
6551
|
-
title: raw.name ?? "",
|
|
6552
|
-
description: raw.plain_text_description ?? raw.description ?? "",
|
|
6553
|
-
descriptionHtml: raw.description ?? "",
|
|
6554
|
-
availableForSale: raw.availability === "available" || raw.is_visible !== false,
|
|
6555
|
-
featuredImage: images[0] ?? { url: "", altText: "", width: 800, height: 800 },
|
|
6556
|
-
images,
|
|
6557
|
-
options,
|
|
6558
|
-
variants,
|
|
6559
|
-
priceRange: {
|
|
6560
|
-
minVariantPrice: transformMoney3(price, currencyCode),
|
|
6561
|
-
maxVariantPrice: transformMoney3(price, currencyCode)
|
|
6562
|
-
},
|
|
6563
|
-
seo: {
|
|
6564
|
-
title: raw.page_title ?? raw.name ?? "",
|
|
6565
|
-
description: raw.meta_description ?? ""
|
|
6566
|
-
},
|
|
6567
|
-
tags: [],
|
|
6568
|
-
createdAt: raw.date_created ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
6569
|
-
updatedAt: raw.date_modified ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
6570
|
-
};
|
|
6571
|
-
}
|
|
6572
|
-
function transformCollection3(raw) {
|
|
6573
|
-
return {
|
|
6574
|
-
id: String(raw.id ?? ""),
|
|
6575
|
-
handle: raw.custom_url?.url?.replace(/^\//, "").replace(/\/$/, "") ?? String(raw.id),
|
|
6576
|
-
title: raw.name ?? "",
|
|
6577
|
-
description: raw.description ?? "",
|
|
6578
|
-
seo: {
|
|
6579
|
-
title: raw.page_title ?? raw.name ?? "",
|
|
6580
|
-
description: raw.meta_description ?? ""
|
|
6581
|
-
},
|
|
6582
|
-
updatedAt: raw.date_modified ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
6583
|
-
path: `/collections/${raw.custom_url?.url?.replace(/^\//, "").replace(/\/$/, "") ?? raw.id}`
|
|
6584
|
-
};
|
|
6585
|
-
}
|
|
6586
|
-
function transformCart3(raw, currencyCode = "USD") {
|
|
6587
|
-
const lineItems = Object.values(raw.line_items ?? {}).flat();
|
|
6588
|
-
const lines = lineItems.map((item) => ({
|
|
6589
|
-
id: item.id,
|
|
6590
|
-
quantity: item.quantity ?? 1,
|
|
6591
|
-
cost: {
|
|
6592
|
-
totalAmount: transformMoney3(item.extended_sale_price ?? item.sale_price ?? 0, currencyCode)
|
|
6593
|
-
},
|
|
6594
|
-
merchandise: {
|
|
6595
|
-
id: String(item.variant_id ?? item.product_id),
|
|
6596
|
-
title: item.name ?? "",
|
|
6597
|
-
selectedOptions: (item.options ?? []).map((opt) => ({
|
|
6598
|
-
name: opt.name ?? "",
|
|
6599
|
-
value: opt.value ?? ""
|
|
6600
|
-
})),
|
|
6601
|
-
product: {
|
|
6602
|
-
id: String(item.product_id),
|
|
6603
|
-
handle: String(item.product_id),
|
|
6604
|
-
title: item.name ?? "",
|
|
6605
|
-
featuredImage: item.image_url ? transformImage3(item.image_url) : { url: "", altText: "", width: 800, height: 800 }
|
|
6606
|
-
}
|
|
6607
|
-
}
|
|
6608
|
-
}));
|
|
6609
|
-
return {
|
|
6610
|
-
id: raw.id,
|
|
6611
|
-
checkoutUrl: raw.redirect_urls?.checkout_url ?? "",
|
|
6612
|
-
totalQuantity: lines.reduce((sum, l) => sum + l.quantity, 0),
|
|
6613
|
-
cost: {
|
|
6614
|
-
subtotalAmount: transformMoney3(raw.base_amount ?? 0, currencyCode),
|
|
6615
|
-
totalAmount: transformMoney3(raw.cart_amount ?? 0, currencyCode)
|
|
6616
|
-
},
|
|
6617
|
-
lines
|
|
6618
|
-
};
|
|
6619
|
-
}
|
|
6620
|
-
|
|
6621
|
-
// src/providers/bigcommerce/index.ts
|
|
6622
|
-
var BigCommerceProvider = class {
|
|
6623
|
-
name = "bigcommerce";
|
|
6624
|
-
version = "1.0.0";
|
|
6625
|
-
capabilities = BIGCOMMERCE_CAPABILITIES;
|
|
6626
|
-
logger;
|
|
6627
|
-
storefrontApiUrl;
|
|
6628
|
-
storeHash;
|
|
6629
|
-
channelId;
|
|
6630
|
-
currencyCode;
|
|
6631
|
-
headers;
|
|
6632
|
-
constructor(config) {
|
|
6633
|
-
this.logger = createLogger("BigCommerceProvider", config.debug);
|
|
6634
|
-
this.storefrontApiUrl = config.storefrontApiUrl.replace(/\/$/, "");
|
|
6635
|
-
this.storeHash = config.storeHash;
|
|
6636
|
-
this.channelId = config.channelId;
|
|
6637
|
-
this.currencyCode = config.currencyCode ?? "USD";
|
|
6638
|
-
this.headers = {
|
|
6639
|
-
"Content-Type": "application/json",
|
|
6640
|
-
"Authorization": `Bearer ${config.storefrontApiToken}`
|
|
6641
|
-
};
|
|
6642
|
-
this.logger.info("Initializing BigCommerce Provider", { storeHash: this.storeHash, channelId: this.channelId });
|
|
6643
|
-
}
|
|
6644
|
-
async fetchApi(path, init) {
|
|
6645
|
-
const url = `${this.storefrontApiUrl}${path}`;
|
|
6646
|
-
const response = await fetch(url, {
|
|
6647
|
-
...init,
|
|
6648
|
-
headers: { ...this.headers, ...init?.headers }
|
|
6649
|
-
});
|
|
6650
|
-
if (!response.ok) {
|
|
6651
|
-
throw new ProviderAPIError(
|
|
6652
|
-
`BigCommerce API error: ${response.status} ${response.statusText}`,
|
|
6653
|
-
"BIGCOMMERCE_API_ERROR",
|
|
6654
|
-
response.status
|
|
6655
|
-
);
|
|
6656
|
-
}
|
|
6657
|
-
return response.json();
|
|
6658
|
-
}
|
|
6659
|
-
// ============================================
|
|
6660
|
-
// Product Operations
|
|
6661
|
-
// ============================================
|
|
6662
|
-
async getProduct(handle) {
|
|
6663
|
-
try {
|
|
6664
|
-
const data = await this.fetchApi(`/api/storefront/products?include=variants,options,images&keyword=${encodeURIComponent(handle)}`);
|
|
6665
|
-
const product = data.data?.[0];
|
|
6666
|
-
return product ? transformProduct3(product, this.currencyCode) : void 0;
|
|
6667
|
-
} catch {
|
|
6668
|
-
return void 0;
|
|
6669
|
-
}
|
|
6670
|
-
}
|
|
6671
|
-
async getProducts(options) {
|
|
6672
|
-
const limit = options?.first ?? 20;
|
|
6673
|
-
let path = `/api/storefront/products?include=variants,options,images&limit=${limit}`;
|
|
6674
|
-
if (options?.query) path += `&keyword=${encodeURIComponent(options.query)}`;
|
|
6675
|
-
const data = await this.fetchApi(path);
|
|
6676
|
-
return (data.data ?? []).map((p) => transformProduct3(p, this.currencyCode));
|
|
6677
|
-
}
|
|
6678
|
-
async getProductRecommendations(_productId) {
|
|
6679
|
-
return [];
|
|
6680
|
-
}
|
|
6681
|
-
// ============================================
|
|
6682
|
-
// Collection Operations (BigCommerce Categories)
|
|
6683
|
-
// ============================================
|
|
6684
|
-
async getCollection(handle) {
|
|
6685
|
-
try {
|
|
6686
|
-
const data = await this.fetchApi(`/api/storefront/categories?url=/${handle}/`);
|
|
6687
|
-
const cat = data.data?.[0];
|
|
6688
|
-
return cat ? transformCollection3(cat) : void 0;
|
|
6689
|
-
} catch {
|
|
6690
|
-
return void 0;
|
|
6691
|
-
}
|
|
6692
|
-
}
|
|
6693
|
-
async getCollections(options) {
|
|
6694
|
-
const limit = options?.limit ?? 50;
|
|
6695
|
-
const data = await this.fetchApi(`/api/storefront/categories?limit=${limit}`);
|
|
6696
|
-
return (data.data ?? []).map(transformCollection3);
|
|
6697
|
-
}
|
|
6698
|
-
async getCollectionProducts(handle, options) {
|
|
6699
|
-
const limit = options?.first ?? 20;
|
|
6700
|
-
const data = await this.fetchApi(
|
|
6701
|
-
`/api/storefront/products?include=variants,options,images&categories:in=${handle}&limit=${limit}`
|
|
6702
|
-
);
|
|
6703
|
-
return (data.data ?? []).map((p) => transformProduct3(p, this.currencyCode));
|
|
6704
|
-
}
|
|
6705
|
-
// ============================================
|
|
6706
|
-
// Category Operations
|
|
6707
|
-
// ============================================
|
|
6708
|
-
async getCategory(idOrHandle) {
|
|
6709
|
-
return this.getCollection(idOrHandle);
|
|
6710
|
-
}
|
|
6711
|
-
async getCategories(options) {
|
|
6712
|
-
return this.getCollections(options);
|
|
6713
|
-
}
|
|
6714
|
-
async getCategoryProducts(handle, options) {
|
|
6715
|
-
return this.getCollectionProducts(handle, options);
|
|
6716
|
-
}
|
|
6717
|
-
// ============================================
|
|
6718
|
-
// Cart Operations
|
|
6719
|
-
// ============================================
|
|
6720
|
-
async createCart() {
|
|
6721
|
-
const data = await this.fetchApi("/api/storefront/carts", {
|
|
6722
|
-
method: "POST",
|
|
6723
|
-
body: JSON.stringify({ line_items: [] })
|
|
6724
|
-
});
|
|
6725
|
-
return transformCart3(data.data ?? data, this.currencyCode);
|
|
6726
|
-
}
|
|
6727
|
-
async getCart(cartId) {
|
|
6728
|
-
try {
|
|
6729
|
-
const data = await this.fetchApi(`/api/storefront/carts/${cartId}?include=line_items.physical_items.options`);
|
|
6730
|
-
return transformCart3(data.data ?? data, this.currencyCode);
|
|
6731
|
-
} catch {
|
|
6732
|
-
return void 0;
|
|
6733
|
-
}
|
|
6734
|
-
}
|
|
6735
|
-
async addToCart(cartId, lines) {
|
|
6736
|
-
const lineItems = lines.map((l) => ({
|
|
6737
|
-
product_id: parseInt(l.merchandiseId, 10),
|
|
6738
|
-
quantity: l.quantity
|
|
6739
|
-
}));
|
|
6740
|
-
const data = await this.fetchApi(`/api/storefront/carts/${cartId}/items`, {
|
|
6741
|
-
method: "POST",
|
|
6742
|
-
body: JSON.stringify({ line_items: lineItems })
|
|
6743
|
-
});
|
|
6744
|
-
return transformCart3(data.data ?? data, this.currencyCode);
|
|
6745
|
-
}
|
|
6746
|
-
async removeFromCart(cartId, lineIds) {
|
|
6747
|
-
for (const lineId of lineIds) {
|
|
6748
|
-
await this.fetchApi(`/api/storefront/carts/${cartId}/items/${lineId}`, { method: "DELETE" });
|
|
6749
|
-
}
|
|
6750
|
-
const cart = await this.getCart(cartId);
|
|
6751
|
-
if (!cart) throw new ProviderAPIError("Cart not found after removal", "BIGCOMMERCE_CART_ERROR");
|
|
6752
|
-
return cart;
|
|
6753
|
-
}
|
|
6754
|
-
async updateCart(cartId, lines) {
|
|
6755
|
-
for (const line of lines) {
|
|
6756
|
-
await this.fetchApi(`/api/storefront/carts/${cartId}/items/${line.id}`, {
|
|
6757
|
-
method: "PUT",
|
|
6758
|
-
body: JSON.stringify({ line_item: { quantity: line.quantity } })
|
|
6759
|
-
});
|
|
6760
|
-
}
|
|
6761
|
-
const cart = await this.getCart(cartId);
|
|
6762
|
-
if (!cart) throw new ProviderAPIError("Cart not found after update", "BIGCOMMERCE_CART_ERROR");
|
|
6763
|
-
return cart;
|
|
6764
|
-
}
|
|
6765
|
-
// ============================================
|
|
6766
|
-
// Checkout Operations (Hosted)
|
|
6767
|
-
// ============================================
|
|
6768
|
-
async completeCheckout(_cartId) {
|
|
6769
|
-
throw new ProviderAPIError(
|
|
6770
|
-
"BigCommerce uses Embedded Checkout. Redirect the buyer to cart.checkoutUrl.",
|
|
6771
|
-
"BIGCOMMERCE_HOSTED_CHECKOUT"
|
|
6772
|
-
);
|
|
6773
|
-
}
|
|
6774
|
-
async getShippingMethods(_cartId) {
|
|
6775
|
-
return [];
|
|
6776
|
-
}
|
|
6777
|
-
async getRegionCountries() {
|
|
6778
|
-
return [];
|
|
6779
|
-
}
|
|
6780
|
-
async addShippingMethod(_cartId, _methodId) {
|
|
6781
|
-
throw new ProviderAPIError("BigCommerce handles shipping in Embedded Checkout.", "BIGCOMMERCE_HOSTED_CHECKOUT");
|
|
6782
|
-
}
|
|
6783
|
-
async initiatePaymentSession(_cartId, _providerId) {
|
|
6784
|
-
throw new ProviderAPIError("BigCommerce handles payment in Embedded Checkout.", "BIGCOMMERCE_HOSTED_CHECKOUT");
|
|
6785
|
-
}
|
|
6786
|
-
async applyDiscountCode(cartId, code) {
|
|
6787
|
-
const data = await this.fetchApi(`/api/storefront/carts/${cartId}/coupons`, {
|
|
6788
|
-
method: "POST",
|
|
6789
|
-
body: JSON.stringify({ coupon_code: code })
|
|
6790
|
-
});
|
|
6791
|
-
return transformCart3(data.data ?? data, this.currencyCode);
|
|
6792
|
-
}
|
|
6793
|
-
async removeDiscountCode(cartId, code) {
|
|
6794
|
-
await this.fetchApi(`/api/storefront/carts/${cartId}/coupons/${encodeURIComponent(code)}`, { method: "DELETE" });
|
|
6795
|
-
const cart = await this.getCart(cartId);
|
|
6796
|
-
if (!cart) throw new ProviderAPIError("Cart not found after coupon removal", "BIGCOMMERCE_CART_ERROR");
|
|
6797
|
-
return cart;
|
|
6798
|
-
}
|
|
6799
|
-
// ============================================
|
|
6800
|
-
// Customer, Order, Payment, Inventory, Admin
|
|
6801
|
-
// ============================================
|
|
6802
|
-
async getOrders(_options) {
|
|
6803
|
-
return [];
|
|
6804
|
-
}
|
|
6805
|
-
async getPaymentMethods(_options) {
|
|
6806
|
-
return [];
|
|
6807
|
-
}
|
|
6808
|
-
async getStockLocations() {
|
|
6809
|
-
return [];
|
|
6810
|
-
}
|
|
6811
|
-
async checkInventoryLevels() {
|
|
6812
|
-
return [];
|
|
6813
|
-
}
|
|
6814
|
-
async validateCartStock() {
|
|
6815
|
-
return { allAvailable: true, unavailableItems: [] };
|
|
6816
|
-
}
|
|
6817
|
-
async getFulfillmentOptions() {
|
|
6818
|
-
return [];
|
|
6819
|
-
}
|
|
6820
|
-
async cancelOrder(_orderId) {
|
|
6821
|
-
throw new ProviderAPIError("Order cancellation requires BigCommerce Management API.", "BIGCOMMERCE_ADMIN_REQUIRED");
|
|
6822
|
-
}
|
|
6823
|
-
async createFulfillment(_orderId) {
|
|
6824
|
-
throw new ProviderAPIError("Fulfillment requires BigCommerce Management API.", "BIGCOMMERCE_ADMIN_REQUIRED");
|
|
6825
|
-
}
|
|
6826
|
-
async createRefund(_orderId) {
|
|
6827
|
-
throw new ProviderAPIError("Refunds require BigCommerce Management API.", "BIGCOMMERCE_ADMIN_REQUIRED");
|
|
6828
|
-
}
|
|
6829
|
-
async getAdminOrders() {
|
|
6830
|
-
return { orders: [], count: 0 };
|
|
6831
|
-
}
|
|
6832
|
-
async getStorefrontContext() {
|
|
6833
|
-
return {
|
|
6834
|
-
id: this.channelId,
|
|
6835
|
-
name: `BigCommerce Store ${this.storeHash}`,
|
|
6836
|
-
platformType: "bigcommerce",
|
|
6837
|
-
requiresProductScoping: false,
|
|
6838
|
-
currencyCode: this.currencyCode
|
|
6839
|
-
};
|
|
6840
|
-
}
|
|
6841
|
-
isStorefrontRequired() {
|
|
6842
|
-
return false;
|
|
6843
|
-
}
|
|
6844
|
-
};
|
|
6845
|
-
|
|
6846
|
-
// src/providers/woocommerce/transforms.ts
|
|
6847
|
-
function transformMoney4(amount, currencyCode = "USD") {
|
|
6848
|
-
const numAmount = typeof amount === "string" ? parseFloat(amount) : amount ?? 0;
|
|
6849
|
-
return {
|
|
6850
|
-
amount: isNaN(numAmount) ? "0.00" : numAmount.toFixed(2),
|
|
6851
|
-
currencyCode: currencyCode.toUpperCase()
|
|
6852
|
-
};
|
|
6853
|
-
}
|
|
6854
|
-
function transformImage4(url, alt = "") {
|
|
6855
|
-
return { url, altText: alt, width: 800, height: 800 };
|
|
6856
|
-
}
|
|
6857
|
-
function transformProduct4(raw, currencyCode = "USD") {
|
|
6858
|
-
const images = (raw.images ?? []).map(
|
|
6859
|
-
(img) => transformImage4(img.src ?? "", img.alt ?? img.name ?? "")
|
|
6860
|
-
);
|
|
6861
|
-
const variants = (raw.variations ?? []).map((v) => ({
|
|
6862
|
-
id: String(v.id),
|
|
6863
|
-
title: v.name ?? "",
|
|
6864
|
-
availableForSale: v.in_stock !== false,
|
|
6865
|
-
price: transformMoney4(v.prices?.price ?? v.price, currencyCode),
|
|
6866
|
-
compareAtPrice: v.prices?.regular_price ? transformMoney4(v.prices.regular_price, currencyCode) : void 0,
|
|
6867
|
-
selectedOptions: (v.attributes ?? []).map((attr) => ({
|
|
6868
|
-
name: attr.name ?? "",
|
|
6869
|
-
value: attr.value ?? ""
|
|
6870
|
-
}))
|
|
6871
|
-
}));
|
|
6872
|
-
const options = (raw.attributes ?? []).filter((attr) => attr.variation === true || attr.has_options === true).map((attr) => ({
|
|
6873
|
-
id: String(attr.id),
|
|
6874
|
-
name: attr.name ?? "",
|
|
6875
|
-
values: (attr.terms ?? attr.options ?? []).map(
|
|
6876
|
-
(t) => typeof t === "string" ? t : t.name ?? t.value ?? ""
|
|
6877
|
-
)
|
|
6878
|
-
}));
|
|
6879
|
-
const priceMinor = raw.prices?.price ?? "0";
|
|
6880
|
-
const priceDecimalPlaces = raw.prices?.currency_minor_unit ?? 2;
|
|
6881
|
-
const priceMajor = parseInt(priceMinor, 10) / Math.pow(10, priceDecimalPlaces);
|
|
6882
|
-
return {
|
|
6883
|
-
id: String(raw.id),
|
|
6884
|
-
handle: raw.slug ?? String(raw.id),
|
|
6885
|
-
title: raw.name ?? "",
|
|
6886
|
-
description: raw.short_description ?? raw.description ?? "",
|
|
6887
|
-
descriptionHtml: raw.description ?? "",
|
|
6888
|
-
availableForSale: raw.is_purchasable !== false && raw.is_in_stock !== false,
|
|
6889
|
-
featuredImage: images[0] ?? { url: "", altText: "", width: 800, height: 800 },
|
|
6890
|
-
images,
|
|
6891
|
-
options,
|
|
6892
|
-
variants,
|
|
6893
|
-
priceRange: {
|
|
6894
|
-
minVariantPrice: transformMoney4(priceMajor, currencyCode),
|
|
6895
|
-
maxVariantPrice: transformMoney4(priceMajor, currencyCode)
|
|
6896
|
-
},
|
|
6897
|
-
seo: {
|
|
6898
|
-
title: raw.name ?? "",
|
|
6899
|
-
description: raw.short_description?.replace(/<[^>]*>/g, "") ?? ""
|
|
6900
|
-
},
|
|
6901
|
-
tags: [],
|
|
6902
|
-
createdAt: raw.date_created ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
6903
|
-
updatedAt: raw.date_modified ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
6904
|
-
};
|
|
6905
|
-
}
|
|
6906
|
-
function transformCollection4(raw) {
|
|
6907
|
-
return {
|
|
6908
|
-
id: String(raw.id ?? ""),
|
|
6909
|
-
handle: raw.slug ?? String(raw.id),
|
|
6910
|
-
title: raw.name ?? "",
|
|
6911
|
-
description: raw.description ?? "",
|
|
6912
|
-
seo: {
|
|
6913
|
-
title: raw.name ?? "",
|
|
6914
|
-
description: raw.description?.replace(/<[^>]*>/g, "") ?? ""
|
|
6915
|
-
},
|
|
6916
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6917
|
-
path: `/collections/${raw.slug ?? raw.id}`
|
|
6918
|
-
};
|
|
6919
|
-
}
|
|
6920
|
-
function transformCart4(raw, currencyCode = "USD") {
|
|
6921
|
-
const lines = (raw.items ?? []).map((item) => {
|
|
6922
|
-
const minorUnit2 = item.prices?.currency_minor_unit ?? 2;
|
|
6923
|
-
const divisor2 = Math.pow(10, minorUnit2);
|
|
6924
|
-
const lineTotal = parseInt(item.totals?.line_total ?? "0", 10) / divisor2;
|
|
6925
|
-
return {
|
|
6926
|
-
id: item.key ?? String(item.id),
|
|
6927
|
-
quantity: item.quantity ?? 1,
|
|
6928
|
-
cost: {
|
|
6929
|
-
totalAmount: transformMoney4(lineTotal, currencyCode)
|
|
6930
|
-
},
|
|
6931
|
-
merchandise: {
|
|
6932
|
-
id: String(item.id),
|
|
6933
|
-
title: item.name ?? "",
|
|
6934
|
-
selectedOptions: (item.variation ?? []).map((v) => ({
|
|
6935
|
-
name: v.attribute ?? "",
|
|
6936
|
-
value: v.value ?? ""
|
|
6937
|
-
})),
|
|
6938
|
-
product: {
|
|
6939
|
-
id: String(item.id),
|
|
6940
|
-
handle: item.slug ?? String(item.id),
|
|
6941
|
-
title: item.name ?? "",
|
|
6942
|
-
featuredImage: item.images?.[0] ? transformImage4(item.images[0].src, item.images[0].alt ?? "") : { url: "", altText: "", width: 800, height: 800 }
|
|
6943
|
-
}
|
|
6944
|
-
}
|
|
6945
|
-
};
|
|
6946
|
-
});
|
|
6947
|
-
const minorUnit = raw.totals?.currency_minor_unit ?? 2;
|
|
6948
|
-
const divisor = Math.pow(10, minorUnit);
|
|
6949
|
-
const subtotal = parseInt(raw.totals?.total_items ?? "0", 10) / divisor;
|
|
6950
|
-
const total = parseInt(raw.totals?.total_price ?? "0", 10) / divisor;
|
|
6951
|
-
return {
|
|
6952
|
-
id: raw.cart_key ?? void 0,
|
|
6953
|
-
checkoutUrl: "",
|
|
6954
|
-
// WooCommerce handles checkout via its own /checkout page
|
|
6955
|
-
totalQuantity: raw.items_count ?? lines.reduce((sum, l) => sum + l.quantity, 0),
|
|
6956
|
-
cost: {
|
|
6957
|
-
subtotalAmount: transformMoney4(subtotal, currencyCode),
|
|
6958
|
-
totalAmount: transformMoney4(total, currencyCode)
|
|
6959
|
-
},
|
|
6960
|
-
lines
|
|
6961
|
-
};
|
|
6962
|
-
}
|
|
6963
|
-
function transformWooAddress(raw) {
|
|
6964
|
-
return {
|
|
6965
|
-
id: void 0,
|
|
6966
|
-
firstName: raw.first_name ?? "",
|
|
6967
|
-
lastName: raw.last_name ?? "",
|
|
6968
|
-
address1: raw.address_1 ?? "",
|
|
6969
|
-
address2: raw.address_2 ?? "",
|
|
6970
|
-
city: raw.city ?? "",
|
|
6971
|
-
province: raw.state ?? "",
|
|
6972
|
-
countryCode: raw.country ?? "",
|
|
6973
|
-
postalCode: raw.postcode ?? "",
|
|
6974
|
-
phone: raw.phone ?? "",
|
|
6975
|
-
company: raw.company ?? ""
|
|
6976
|
-
};
|
|
6977
|
-
}
|
|
6978
|
-
function transformOrder4(raw, currencyCode = "USD") {
|
|
6979
|
-
const items = (raw.line_items ?? []).map((item) => ({
|
|
6980
|
-
id: String(item.id),
|
|
6981
|
-
title: item.name ?? "",
|
|
6982
|
-
quantity: item.quantity ?? 1,
|
|
6983
|
-
price: transformMoney4(item.price ?? 0, currencyCode),
|
|
6984
|
-
total: transformMoney4(item.total ?? 0, currencyCode),
|
|
6985
|
-
productId: String(item.product_id),
|
|
6986
|
-
variantId: item.variation_id ? String(item.variation_id) : void 0
|
|
6987
|
-
}));
|
|
6988
|
-
const statusMap = {
|
|
6989
|
-
pending: "pending",
|
|
6990
|
-
processing: "processing",
|
|
6991
|
-
"on-hold": "pending",
|
|
6992
|
-
completed: "completed",
|
|
6993
|
-
cancelled: "cancelled",
|
|
6994
|
-
refunded: "refunded",
|
|
6995
|
-
failed: "cancelled"
|
|
6996
|
-
};
|
|
6997
|
-
const paymentMap = {
|
|
6998
|
-
pending: "pending",
|
|
6999
|
-
processing: "authorized",
|
|
7000
|
-
completed: "paid",
|
|
7001
|
-
refunded: "refunded"
|
|
7002
|
-
};
|
|
7003
|
-
return {
|
|
7004
|
-
id: String(raw.id),
|
|
7005
|
-
orderNumber: String(raw.number ?? raw.id),
|
|
7006
|
-
email: raw.billing?.email ?? "",
|
|
7007
|
-
status: statusMap[raw.status] ?? "pending",
|
|
7008
|
-
paymentStatus: paymentMap[raw.status] ?? "pending",
|
|
7009
|
-
fulfillmentStatus: raw.status === "completed" ? "fulfilled" : "unfulfilled",
|
|
7010
|
-
items,
|
|
7011
|
-
total: transformMoney4(raw.total ?? 0, currencyCode),
|
|
7012
|
-
subtotal: transformMoney4(raw.subtotal ?? 0, currencyCode),
|
|
7013
|
-
tax: transformMoney4(raw.total_tax ?? 0, currencyCode),
|
|
7014
|
-
shipping: transformMoney4(raw.shipping_total ?? 0, currencyCode),
|
|
7015
|
-
shippingAddress: raw.shipping ? transformWooAddress(raw.shipping) : void 0,
|
|
7016
|
-
billingAddress: raw.billing ? transformWooAddress(raw.billing) : void 0,
|
|
7017
|
-
createdAt: raw.date_created ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
7018
|
-
updatedAt: raw.date_modified ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
7019
|
-
};
|
|
7020
|
-
}
|
|
7021
|
-
|
|
7022
|
-
// src/providers/woocommerce/index.ts
|
|
7023
|
-
var WooCommerceProvider = class {
|
|
7024
|
-
name = "woocommerce";
|
|
7025
|
-
version = "1.0.0";
|
|
7026
|
-
capabilities = WOOCOMMERCE_CAPABILITIES;
|
|
7027
|
-
logger;
|
|
7028
|
-
baseUrl;
|
|
7029
|
-
storeApiBase;
|
|
7030
|
-
restApiBase;
|
|
7031
|
-
currencyCode;
|
|
7032
|
-
authHeader;
|
|
7033
|
-
constructor(config) {
|
|
7034
|
-
this.logger = createLogger("WooCommerceProvider", config.debug);
|
|
7035
|
-
this.baseUrl = config.url.replace(/\/$/, "");
|
|
7036
|
-
this.storeApiBase = `${this.baseUrl}/wp-json/wc/store/v1`;
|
|
7037
|
-
this.restApiBase = `${this.baseUrl}/wp-json/wc/v3`;
|
|
7038
|
-
this.currencyCode = config.currencyCode ?? "USD";
|
|
7039
|
-
if (config.consumerKey && config.consumerSecret) {
|
|
7040
|
-
this.authHeader = "Basic " + btoa(`${config.consumerKey}:${config.consumerSecret}`);
|
|
7041
|
-
}
|
|
7042
|
-
this.logger.info("Initializing WooCommerce Provider", { baseUrl: this.baseUrl });
|
|
7043
|
-
}
|
|
7044
|
-
async storeApiFetch(path, init) {
|
|
7045
|
-
const response = await fetch(`${this.storeApiBase}${path}`, {
|
|
7046
|
-
...init,
|
|
7047
|
-
headers: { "Content-Type": "application/json", ...init?.headers }
|
|
7048
|
-
});
|
|
7049
|
-
if (!response.ok) {
|
|
7050
|
-
throw new ProviderAPIError(`WooCommerce Store API error: ${response.status}`, "WOOCOMMERCE_API_ERROR", response.status);
|
|
7051
|
-
}
|
|
7052
|
-
return response.json();
|
|
7053
|
-
}
|
|
7054
|
-
async restApiFetch(path, init) {
|
|
7055
|
-
if (!this.authHeader) {
|
|
7056
|
-
throw new ProviderAPIError("WooCommerce REST API requires consumer key/secret.", "WOOCOMMERCE_AUTH_REQUIRED");
|
|
7057
|
-
}
|
|
7058
|
-
const response = await fetch(`${this.restApiBase}${path}`, {
|
|
7059
|
-
...init,
|
|
7060
|
-
headers: { "Content-Type": "application/json", "Authorization": this.authHeader, ...init?.headers }
|
|
7061
|
-
});
|
|
7062
|
-
if (!response.ok) {
|
|
7063
|
-
throw new ProviderAPIError(`WooCommerce REST API error: ${response.status}`, "WOOCOMMERCE_API_ERROR", response.status);
|
|
7064
|
-
}
|
|
7065
|
-
return response.json();
|
|
7066
|
-
}
|
|
7067
|
-
// ============================================
|
|
7068
|
-
// Product Operations (Store API)
|
|
7069
|
-
// ============================================
|
|
7070
|
-
async getProduct(handle) {
|
|
7071
|
-
try {
|
|
7072
|
-
const products = await this.storeApiFetch(`/products?slug=${encodeURIComponent(handle)}`);
|
|
7073
|
-
return products[0] ? transformProduct4(products[0], this.currencyCode) : void 0;
|
|
7074
|
-
} catch {
|
|
7075
|
-
return void 0;
|
|
7076
|
-
}
|
|
7077
|
-
}
|
|
7078
|
-
async getProducts(options) {
|
|
7079
|
-
let path = `/products?per_page=${options?.first ?? 20}`;
|
|
7080
|
-
if (options?.query) path += `&search=${encodeURIComponent(options.query)}`;
|
|
7081
|
-
if (options?.sortKey) {
|
|
7082
|
-
const [orderby, order] = options.sortKey.includes("-desc") ? [options.sortKey.replace("-desc", ""), "desc"] : [options.sortKey.replace("-asc", ""), "asc"];
|
|
7083
|
-
path += `&orderby=${orderby}&order=${order}`;
|
|
7084
|
-
}
|
|
7085
|
-
const products = await this.storeApiFetch(path);
|
|
7086
|
-
return products.map((p) => transformProduct4(p, this.currencyCode));
|
|
7087
|
-
}
|
|
7088
|
-
async getProductRecommendations(_productId) {
|
|
7089
|
-
return [];
|
|
7090
|
-
}
|
|
7091
|
-
// ============================================
|
|
7092
|
-
// Collection/Category Operations (Store API)
|
|
7093
|
-
// ============================================
|
|
7094
|
-
async getCollection(handle) {
|
|
7095
|
-
try {
|
|
7096
|
-
const cats = await this.storeApiFetch(`/products/categories?slug=${encodeURIComponent(handle)}`);
|
|
7097
|
-
return cats[0] ? transformCollection4(cats[0]) : void 0;
|
|
7098
|
-
} catch {
|
|
7099
|
-
return void 0;
|
|
7100
|
-
}
|
|
7101
|
-
}
|
|
7102
|
-
async getCollections(options) {
|
|
7103
|
-
const cats = await this.storeApiFetch(`/products/categories?per_page=${options?.limit ?? 50}`);
|
|
7104
|
-
return cats.map(transformCollection4);
|
|
7105
|
-
}
|
|
7106
|
-
async getCollectionProducts(handle, options) {
|
|
7107
|
-
const products = await this.storeApiFetch(
|
|
7108
|
-
`/products?category=${encodeURIComponent(handle)}&per_page=${options?.first ?? 20}`
|
|
7109
|
-
);
|
|
7110
|
-
return products.map((p) => transformProduct4(p, this.currencyCode));
|
|
7111
|
-
}
|
|
7112
|
-
async getCategory(idOrHandle) {
|
|
7113
|
-
return this.getCollection(idOrHandle);
|
|
7114
|
-
}
|
|
7115
|
-
async getCategories(options) {
|
|
7116
|
-
return this.getCollections(options);
|
|
7117
|
-
}
|
|
7118
|
-
async getCategoryProducts(handle, options) {
|
|
7119
|
-
return this.getCollectionProducts(handle, options);
|
|
7120
|
-
}
|
|
7121
|
-
// ============================================
|
|
7122
|
-
// Cart Operations (Store API)
|
|
7123
|
-
// ============================================
|
|
7124
|
-
async createCart() {
|
|
7125
|
-
const cart = await this.storeApiFetch("/cart");
|
|
7126
|
-
return transformCart4(cart, this.currencyCode);
|
|
7127
|
-
}
|
|
7128
|
-
async getCart(_cartId) {
|
|
7129
|
-
try {
|
|
7130
|
-
const cart = await this.storeApiFetch("/cart");
|
|
7131
|
-
return transformCart4(cart, this.currencyCode);
|
|
7132
|
-
} catch {
|
|
7133
|
-
return void 0;
|
|
7134
|
-
}
|
|
7135
|
-
}
|
|
7136
|
-
async addToCart(_cartId, lines) {
|
|
7137
|
-
for (const line of lines) {
|
|
7138
|
-
await this.storeApiFetch("/cart/add-item", {
|
|
7139
|
-
method: "POST",
|
|
7140
|
-
body: JSON.stringify({ id: parseInt(line.merchandiseId, 10), quantity: line.quantity })
|
|
7141
|
-
});
|
|
7142
|
-
}
|
|
7143
|
-
const cart = await this.storeApiFetch("/cart");
|
|
7144
|
-
return transformCart4(cart, this.currencyCode);
|
|
7145
|
-
}
|
|
7146
|
-
async removeFromCart(_cartId, lineIds) {
|
|
7147
|
-
for (const key of lineIds) {
|
|
7148
|
-
await this.storeApiFetch("/cart/remove-item", {
|
|
7149
|
-
method: "POST",
|
|
7150
|
-
body: JSON.stringify({ key })
|
|
7151
|
-
});
|
|
7152
|
-
}
|
|
7153
|
-
const cart = await this.storeApiFetch("/cart");
|
|
7154
|
-
return transformCart4(cart, this.currencyCode);
|
|
7155
|
-
}
|
|
7156
|
-
async updateCart(_cartId, lines) {
|
|
7157
|
-
for (const line of lines) {
|
|
7158
|
-
await this.storeApiFetch("/cart/update-item", {
|
|
7159
|
-
method: "POST",
|
|
7160
|
-
body: JSON.stringify({ key: line.id, quantity: line.quantity })
|
|
7161
|
-
});
|
|
7162
|
-
}
|
|
7163
|
-
const cart = await this.storeApiFetch("/cart");
|
|
7164
|
-
return transformCart4(cart, this.currencyCode);
|
|
7165
|
-
}
|
|
7166
|
-
// ============================================
|
|
7167
|
-
// Checkout Operations (Store API)
|
|
7168
|
-
// ============================================
|
|
7169
|
-
async completeCheckout(_cartId) {
|
|
7170
|
-
const result = await this.storeApiFetch("/checkout", { method: "POST", body: JSON.stringify({}) });
|
|
7171
|
-
return transformOrder4(result, this.currencyCode);
|
|
7172
|
-
}
|
|
7173
|
-
async getShippingMethods(_cartId) {
|
|
7174
|
-
return [];
|
|
7175
|
-
}
|
|
7176
|
-
async getRegionCountries() {
|
|
7177
|
-
return [];
|
|
7178
|
-
}
|
|
7179
|
-
async addShippingMethod(_cartId, methodId) {
|
|
7180
|
-
await this.storeApiFetch("/cart/select-shipping-rate", {
|
|
7181
|
-
method: "POST",
|
|
7182
|
-
body: JSON.stringify({ rate_id: methodId })
|
|
7183
|
-
});
|
|
7184
|
-
const cart = await this.storeApiFetch("/cart");
|
|
7185
|
-
return transformCart4(cart, this.currencyCode);
|
|
7186
|
-
}
|
|
7187
|
-
async initiatePaymentSession(_cartId, _providerId) {
|
|
7188
|
-
}
|
|
7189
|
-
async applyDiscountCode(_cartId, code) {
|
|
7190
|
-
await this.storeApiFetch("/cart/apply-coupon", {
|
|
7191
|
-
method: "POST",
|
|
7192
|
-
body: JSON.stringify({ code })
|
|
7193
|
-
});
|
|
7194
|
-
const cart = await this.storeApiFetch("/cart");
|
|
7195
|
-
return transformCart4(cart, this.currencyCode);
|
|
7196
|
-
}
|
|
7197
|
-
async removeDiscountCode(_cartId, code) {
|
|
7198
|
-
await this.storeApiFetch("/cart/remove-coupon", {
|
|
7199
|
-
method: "POST",
|
|
7200
|
-
body: JSON.stringify({ code })
|
|
7201
|
-
});
|
|
7202
|
-
const cart = await this.storeApiFetch("/cart");
|
|
7203
|
-
return transformCart4(cart, this.currencyCode);
|
|
7204
|
-
}
|
|
7205
|
-
// ============================================
|
|
7206
|
-
// Customer, Order, Payment, Inventory, Admin
|
|
7207
|
-
// ============================================
|
|
7208
|
-
async getOrders(_options) {
|
|
7209
|
-
return [];
|
|
7210
|
-
}
|
|
7211
|
-
async getPaymentMethods(_options) {
|
|
7212
|
-
return [];
|
|
7213
|
-
}
|
|
7214
|
-
async getStockLocations() {
|
|
7215
|
-
return [];
|
|
7216
|
-
}
|
|
7217
|
-
async checkInventoryLevels() {
|
|
7218
|
-
return [];
|
|
7219
|
-
}
|
|
7220
|
-
async validateCartStock() {
|
|
7221
|
-
return { allAvailable: true, unavailableItems: [] };
|
|
7222
|
-
}
|
|
7223
|
-
async getFulfillmentOptions() {
|
|
7224
|
-
return [];
|
|
7225
|
-
}
|
|
7226
|
-
async cancelOrder(_orderId) {
|
|
7227
|
-
throw new ProviderAPIError("Order cancellation requires WooCommerce REST API v3.", "WOOCOMMERCE_AUTH_REQUIRED");
|
|
7228
|
-
}
|
|
7229
|
-
async createFulfillment(_orderId) {
|
|
7230
|
-
throw new ProviderAPIError("Fulfillment requires WooCommerce REST API v3.", "WOOCOMMERCE_AUTH_REQUIRED");
|
|
7231
|
-
}
|
|
7232
|
-
async createRefund(_orderId) {
|
|
7233
|
-
throw new ProviderAPIError("Refunds require WooCommerce REST API v3.", "WOOCOMMERCE_AUTH_REQUIRED");
|
|
7234
|
-
}
|
|
7235
|
-
async getAdminOrders() {
|
|
7236
|
-
return { orders: [], count: 0 };
|
|
7237
|
-
}
|
|
7238
|
-
async getStorefrontContext() {
|
|
7239
|
-
return {
|
|
7240
|
-
id: this.baseUrl,
|
|
7241
|
-
name: `WooCommerce ${this.baseUrl}`,
|
|
7242
|
-
platformType: "woocommerce",
|
|
7243
|
-
requiresProductScoping: false,
|
|
7244
|
-
currencyCode: this.currencyCode
|
|
7245
|
-
};
|
|
7246
|
-
}
|
|
7247
|
-
isStorefrontRequired() {
|
|
7248
|
-
return false;
|
|
7249
|
-
}
|
|
7250
|
-
};
|
|
7251
|
-
|
|
7252
|
-
// src/providers/spree/transforms.ts
|
|
7253
|
-
function toMoney(amount, currencyCode) {
|
|
7254
|
-
const num = typeof amount === "string" ? parseFloat(amount) || 0 : amount;
|
|
7255
|
-
return { amount: num.toFixed(2), currencyCode };
|
|
7256
|
-
}
|
|
7257
|
-
function transformProduct5(data, included = [], currencyCode = "USD") {
|
|
7258
|
-
const attrs = data.attributes ?? data;
|
|
7259
|
-
const id = String(data.id ?? "");
|
|
7260
|
-
const images = [];
|
|
7261
|
-
const imageRels = data.relationships?.images?.data ?? [];
|
|
7262
|
-
for (const imgRef of imageRels) {
|
|
7263
|
-
const imgIncluded = included.find((i) => i.type === "image" && String(i.id) === String(imgRef.id));
|
|
7264
|
-
if (imgIncluded) {
|
|
7265
|
-
images.push({
|
|
7266
|
-
url: imgIncluded.attributes?.original_url ?? imgIncluded.attributes?.styles?.[0]?.url ?? "",
|
|
7267
|
-
altText: imgIncluded.attributes?.alt ?? attrs.name ?? "",
|
|
7268
|
-
width: void 0,
|
|
7269
|
-
height: void 0
|
|
7270
|
-
});
|
|
7271
|
-
}
|
|
7272
|
-
}
|
|
7273
|
-
if (images.length === 0 && Array.isArray(attrs.images)) {
|
|
7274
|
-
for (const img of attrs.images) {
|
|
7275
|
-
images.push({
|
|
7276
|
-
url: img.original_url ?? img.url ?? "",
|
|
7277
|
-
altText: img.alt ?? attrs.name ?? "",
|
|
7278
|
-
width: void 0,
|
|
7279
|
-
height: void 0
|
|
7280
|
-
});
|
|
7281
|
-
}
|
|
7282
|
-
}
|
|
7283
|
-
const variants = [];
|
|
7284
|
-
const variantRels = data.relationships?.variants?.data ?? [];
|
|
7285
|
-
for (const varRef of variantRels) {
|
|
7286
|
-
const varIncluded = included.find((i) => i.type === "variant" && String(i.id) === String(varRef.id));
|
|
7287
|
-
if (varIncluded) {
|
|
7288
|
-
const vAttrs = varIncluded.attributes ?? {};
|
|
7289
|
-
variants.push({
|
|
7290
|
-
id: String(varIncluded.id),
|
|
7291
|
-
title: vAttrs.name ?? vAttrs.sku ?? `Variant ${varIncluded.id}`,
|
|
7292
|
-
availableForSale: vAttrs.in_stock !== false && vAttrs.purchasable !== false,
|
|
7293
|
-
price: toMoney(vAttrs.price ?? vAttrs.display_price ?? "0", currencyCode),
|
|
7294
|
-
compareAtPrice: vAttrs.compare_at_price ? toMoney(vAttrs.compare_at_price, currencyCode) : void 0,
|
|
7295
|
-
selectedOptions: (vAttrs.option_values ?? []).map((ov) => ({
|
|
7296
|
-
name: ov.option_type_name ?? "Option",
|
|
7297
|
-
value: ov.name ?? ov.presentation ?? ""
|
|
7298
|
-
}))
|
|
7299
|
-
});
|
|
7300
|
-
}
|
|
7301
|
-
}
|
|
7302
|
-
if (variants.length === 0) {
|
|
7303
|
-
variants.push({
|
|
7304
|
-
id: attrs.default_variant_id ? String(attrs.default_variant_id) : id,
|
|
7305
|
-
title: "Default",
|
|
7306
|
-
availableForSale: attrs.in_stock !== false && attrs.purchasable !== false,
|
|
7307
|
-
price: toMoney(attrs.price ?? attrs.display_price ?? "0", currencyCode),
|
|
7308
|
-
compareAtPrice: attrs.compare_at_price ? toMoney(attrs.compare_at_price, currencyCode) : void 0,
|
|
7309
|
-
selectedOptions: []
|
|
7310
|
-
});
|
|
7311
|
-
}
|
|
7312
|
-
const options = (attrs.option_types ?? []).map((ot) => ({
|
|
7313
|
-
id: String(ot.id ?? ot.name ?? ""),
|
|
7314
|
-
name: ot.presentation ?? ot.name ?? "",
|
|
7315
|
-
values: (ot.option_values ?? []).map((ov) => ov.presentation ?? ov.name ?? "")
|
|
7316
|
-
}));
|
|
7317
|
-
return {
|
|
7318
|
-
id,
|
|
7319
|
-
handle: attrs.slug ?? id,
|
|
7320
|
-
title: attrs.name ?? "",
|
|
7321
|
-
description: attrs.description ?? "",
|
|
7322
|
-
descriptionHtml: attrs.description ?? "",
|
|
7323
|
-
availableForSale: attrs.in_stock !== false && attrs.purchasable !== false,
|
|
7324
|
-
priceRange: {
|
|
7325
|
-
minVariantPrice: variants.reduce(
|
|
7326
|
-
(min, v) => v.price.amount < min.amount ? v.price : min,
|
|
7327
|
-
variants[0]?.price ?? toMoney("0", currencyCode)
|
|
7328
|
-
),
|
|
7329
|
-
maxVariantPrice: variants.reduce(
|
|
7330
|
-
(max, v) => v.price.amount > max.amount ? v.price : max,
|
|
7331
|
-
variants[0]?.price ?? toMoney("0", currencyCode)
|
|
7332
|
-
)
|
|
7333
|
-
},
|
|
7334
|
-
variants,
|
|
7335
|
-
options,
|
|
7336
|
-
images,
|
|
7337
|
-
featuredImage: images[0] ?? { url: "", altText: attrs.name ?? "" },
|
|
7338
|
-
tags: [],
|
|
7339
|
-
seo: {
|
|
7340
|
-
title: attrs.meta_title ?? attrs.name ?? "",
|
|
7341
|
-
description: attrs.meta_description ?? ""
|
|
7342
|
-
},
|
|
7343
|
-
updatedAt: attrs.updated_at ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
7344
|
-
createdAt: attrs.created_at ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
7345
|
-
};
|
|
7346
|
-
}
|
|
7347
|
-
function transformCollection5(data) {
|
|
7348
|
-
const attrs = data.attributes ?? data;
|
|
7349
|
-
return {
|
|
7350
|
-
id: String(data.id ?? ""),
|
|
7351
|
-
handle: attrs.permalink ?? attrs.slug ?? String(data.id ?? ""),
|
|
7352
|
-
title: attrs.name ?? "",
|
|
7353
|
-
description: attrs.description ?? "",
|
|
7354
|
-
seo: {
|
|
7355
|
-
title: attrs.meta_title ?? attrs.name ?? "",
|
|
7356
|
-
description: attrs.meta_description ?? ""
|
|
7357
|
-
},
|
|
7358
|
-
updatedAt: attrs.updated_at ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
7359
|
-
path: `/collections/${attrs.permalink ?? attrs.slug ?? data.id}`
|
|
7360
|
-
};
|
|
7361
|
-
}
|
|
7362
|
-
function transformCart5(data, currencyCode = "USD") {
|
|
7363
|
-
const attrs = data.attributes ?? data;
|
|
7364
|
-
const items = (attrs.line_items ?? data.included?.filter((i) => i.type === "line_item") ?? []).map(
|
|
7365
|
-
(item) => {
|
|
7366
|
-
const itemAttrs = item.attributes ?? item;
|
|
7367
|
-
return {
|
|
7368
|
-
id: String(item.id ?? itemAttrs.id ?? ""),
|
|
7369
|
-
quantity: itemAttrs.quantity ?? 1,
|
|
7370
|
-
cost: {
|
|
7371
|
-
totalAmount: toMoney(itemAttrs.total ?? itemAttrs.display_total ?? "0", currencyCode)
|
|
7372
|
-
},
|
|
7373
|
-
merchandise: {
|
|
7374
|
-
id: String(itemAttrs.variant_id ?? item.id ?? ""),
|
|
7375
|
-
title: itemAttrs.name ?? "",
|
|
7376
|
-
selectedOptions: [],
|
|
7377
|
-
product: {
|
|
7378
|
-
id: String(itemAttrs.product_id ?? ""),
|
|
7379
|
-
handle: itemAttrs.slug ?? "",
|
|
7380
|
-
title: itemAttrs.name ?? "",
|
|
7381
|
-
featuredImage: { url: itemAttrs.image_url ?? "", altText: itemAttrs.name ?? "" }
|
|
7382
|
-
}
|
|
7383
|
-
}
|
|
7384
|
-
};
|
|
7385
|
-
}
|
|
7386
|
-
);
|
|
7387
|
-
return {
|
|
7388
|
-
id: String(data.id ?? attrs.token ?? ""),
|
|
7389
|
-
checkoutUrl: "",
|
|
7390
|
-
totalQuantity: items.reduce((sum, i) => sum + i.quantity, 0),
|
|
7391
|
-
cost: {
|
|
7392
|
-
subtotalAmount: toMoney(attrs.item_total ?? attrs.display_item_total ?? "0", currencyCode),
|
|
7393
|
-
totalAmount: toMoney(attrs.total ?? attrs.display_total ?? "0", currencyCode),
|
|
7394
|
-
totalTaxAmount: toMoney(attrs.tax_total ?? attrs.display_tax_total ?? "0", currencyCode)
|
|
7395
|
-
},
|
|
7396
|
-
lines: items
|
|
7397
|
-
};
|
|
7398
|
-
}
|
|
7399
|
-
function transformAddress2(addr) {
|
|
7400
|
-
return {
|
|
7401
|
-
id: String(addr.id ?? ""),
|
|
7402
|
-
firstName: addr.first_name ?? addr.firstname ?? "",
|
|
7403
|
-
lastName: addr.last_name ?? addr.lastname ?? "",
|
|
7404
|
-
company: addr.company ?? "",
|
|
7405
|
-
address1: addr.address1 ?? "",
|
|
7406
|
-
address2: addr.address2 ?? "",
|
|
7407
|
-
city: addr.city ?? "",
|
|
7408
|
-
province: addr.state_name ?? addr.state ?? "",
|
|
7409
|
-
postalCode: addr.zipcode ?? addr.zip ?? "",
|
|
7410
|
-
countryCode: addr.country_iso ?? addr.country_code ?? "",
|
|
7411
|
-
phone: addr.phone ?? ""
|
|
7412
|
-
};
|
|
7413
|
-
}
|
|
7414
|
-
function transformOrder5(data, currencyCode = "USD") {
|
|
7415
|
-
const attrs = data.attributes ?? data;
|
|
7416
|
-
const items = (attrs.line_items ?? []).map((item) => ({
|
|
7417
|
-
id: String(item.id ?? ""),
|
|
7418
|
-
title: item.name ?? "",
|
|
7419
|
-
quantity: item.quantity ?? 1,
|
|
7420
|
-
price: toMoney(item.price ?? "0", currencyCode),
|
|
7421
|
-
total: toMoney(item.total ?? "0", currencyCode),
|
|
7422
|
-
productId: String(item.product_id ?? ""),
|
|
7423
|
-
variantId: String(item.variant_id ?? "")
|
|
7424
|
-
}));
|
|
7425
|
-
return {
|
|
7426
|
-
id: String(data.id ?? attrs.number ?? ""),
|
|
7427
|
-
orderNumber: attrs.number ?? String(data.id ?? ""),
|
|
7428
|
-
email: attrs.email ?? "",
|
|
7429
|
-
status: attrs.state === "complete" ? "completed" : attrs.state === "canceled" ? "cancelled" : "pending",
|
|
7430
|
-
paymentStatus: attrs.payment_state === "paid" ? "paid" : attrs.payment_state === "balance_due" ? "pending" : "pending",
|
|
7431
|
-
fulfillmentStatus: attrs.shipment_state === "shipped" ? "fulfilled" : attrs.shipment_state === "partial" ? "partially_fulfilled" : "unfulfilled",
|
|
7432
|
-
items,
|
|
7433
|
-
total: toMoney(attrs.total ?? "0", currencyCode),
|
|
7434
|
-
subtotal: toMoney(attrs.item_total ?? "0", currencyCode),
|
|
7435
|
-
tax: toMoney(attrs.tax_total ?? "0", currencyCode),
|
|
7436
|
-
shipping: toMoney(attrs.ship_total ?? "0", currencyCode),
|
|
7437
|
-
shippingAddress: attrs.ship_address ? transformAddress2(attrs.ship_address) : void 0,
|
|
7438
|
-
billingAddress: attrs.bill_address ? transformAddress2(attrs.bill_address) : void 0,
|
|
7439
|
-
createdAt: attrs.created_at ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
7440
|
-
updatedAt: attrs.updated_at ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
7441
|
-
};
|
|
7442
|
-
}
|
|
7443
|
-
|
|
7444
|
-
// src/providers/spree/index.ts
|
|
7445
|
-
var SpreeProvider = class {
|
|
7446
|
-
name = "spree";
|
|
7447
|
-
version = "1.0.0";
|
|
7448
|
-
capabilities = SPREE_CAPABILITIES;
|
|
7449
|
-
logger;
|
|
7450
|
-
baseUrl;
|
|
7451
|
-
apiBase;
|
|
7452
|
-
currencyCode;
|
|
7453
|
-
bearerToken;
|
|
7454
|
-
orderToken;
|
|
7455
|
-
// guest cart token
|
|
7456
|
-
constructor(config) {
|
|
7457
|
-
this.logger = createLogger("SpreeProvider", config.debug);
|
|
7458
|
-
this.baseUrl = config.baseUrl.replace(/\/$/, "");
|
|
7459
|
-
this.apiBase = `${this.baseUrl}/api/v2/storefront`;
|
|
7460
|
-
this.currencyCode = config.currencyCode ?? "USD";
|
|
7461
|
-
this.bearerToken = config.bearerToken;
|
|
7462
|
-
this.logger.info("Initializing Spree Provider", { baseUrl: this.baseUrl });
|
|
7463
|
-
}
|
|
7464
|
-
async apiFetch(path, init) {
|
|
7465
|
-
const headers = {
|
|
7466
|
-
"Content-Type": "application/vnd.api+json",
|
|
7467
|
-
"Accept": "application/vnd.api+json",
|
|
7468
|
-
...init?.headers ?? {}
|
|
7469
|
-
};
|
|
7470
|
-
if (this.bearerToken) {
|
|
7471
|
-
headers["Authorization"] = `Bearer ${this.bearerToken}`;
|
|
7472
|
-
}
|
|
7473
|
-
if (this.orderToken) {
|
|
7474
|
-
headers["X-Spree-Order-Token"] = this.orderToken;
|
|
7475
|
-
}
|
|
7476
|
-
const response = await fetch(`${this.apiBase}${path}`, {
|
|
7477
|
-
...init,
|
|
7478
|
-
headers
|
|
7479
|
-
});
|
|
7480
|
-
if (!response.ok) {
|
|
7481
|
-
throw new ProviderAPIError(
|
|
7482
|
-
`Spree API error: ${response.status}`,
|
|
7483
|
-
"SPREE_API_ERROR",
|
|
7484
|
-
response.status
|
|
7485
|
-
);
|
|
7486
|
-
}
|
|
7487
|
-
return response.json();
|
|
7488
|
-
}
|
|
7489
|
-
// ============================================
|
|
7490
|
-
// Product Operations
|
|
7491
|
-
// ============================================
|
|
7492
|
-
async getProduct(handle) {
|
|
7493
|
-
try {
|
|
7494
|
-
const { data, included } = await this.apiFetch(
|
|
7495
|
-
`/products/${encodeURIComponent(handle)}?include=images,variants,option_types`
|
|
7496
|
-
);
|
|
7497
|
-
return transformProduct5(data, included ?? [], this.currencyCode);
|
|
7498
|
-
} catch {
|
|
7499
|
-
return void 0;
|
|
7500
|
-
}
|
|
7501
|
-
}
|
|
7502
|
-
async getProducts(options) {
|
|
7503
|
-
let path = `/products?include=images,variants&per_page=${options?.first ?? 20}`;
|
|
7504
|
-
if (options?.query) path += `&filter[name]=${encodeURIComponent(options.query)}`;
|
|
7505
|
-
if (options?.sortKey) {
|
|
7506
|
-
const sortMap = {
|
|
7507
|
-
"price-asc": "price",
|
|
7508
|
-
"price-desc": "-price",
|
|
7509
|
-
"title-asc": "name",
|
|
7510
|
-
"title-desc": "-name",
|
|
7511
|
-
"created-desc": "-created_at"
|
|
7512
|
-
};
|
|
7513
|
-
if (sortMap[options.sortKey]) path += `&sort=${sortMap[options.sortKey]}`;
|
|
7514
|
-
}
|
|
7515
|
-
const { data, included } = await this.apiFetch(path);
|
|
7516
|
-
return (Array.isArray(data) ? data : []).map((p) => transformProduct5(p, included ?? [], this.currencyCode));
|
|
7517
|
-
}
|
|
7518
|
-
async getProductRecommendations(_productId) {
|
|
7519
|
-
return [];
|
|
7520
|
-
}
|
|
7521
|
-
// ============================================
|
|
7522
|
-
// Collection/Taxon Operations
|
|
7523
|
-
// ============================================
|
|
7524
|
-
async getCollection(handle) {
|
|
7525
|
-
try {
|
|
7526
|
-
const { data } = await this.apiFetch(`/taxons/${encodeURIComponent(handle)}`);
|
|
7527
|
-
return transformCollection5(data);
|
|
7528
|
-
} catch {
|
|
7529
|
-
return void 0;
|
|
7530
|
-
}
|
|
7531
|
-
}
|
|
7532
|
-
async getCollections(options) {
|
|
7533
|
-
const { data } = await this.apiFetch(`/taxons?per_page=${options?.limit ?? 50}`);
|
|
7534
|
-
return (Array.isArray(data) ? data : []).map(transformCollection5);
|
|
7535
|
-
}
|
|
7536
|
-
async getCollectionProducts(handle, options) {
|
|
7537
|
-
const { data, included } = await this.apiFetch(
|
|
7538
|
-
`/products?include=images,variants&filter[taxons]=${encodeURIComponent(handle)}&per_page=${options?.first ?? 20}`
|
|
7539
|
-
);
|
|
7540
|
-
return (Array.isArray(data) ? data : []).map((p) => transformProduct5(p, included ?? [], this.currencyCode));
|
|
7541
|
-
}
|
|
7542
|
-
async getCategory(handle) {
|
|
7543
|
-
return this.getCollection(handle);
|
|
7544
|
-
}
|
|
7545
|
-
async getCategories(options) {
|
|
7546
|
-
return this.getCollections(options);
|
|
7547
|
-
}
|
|
7548
|
-
async getCategoryProducts(handle, options) {
|
|
7549
|
-
return this.getCollectionProducts(handle, options);
|
|
7550
|
-
}
|
|
7551
|
-
// ============================================
|
|
7552
|
-
// Cart Operations
|
|
7553
|
-
// ============================================
|
|
7554
|
-
async createCart() {
|
|
7555
|
-
const { data } = await this.apiFetch("/cart", {
|
|
7556
|
-
method: "POST",
|
|
7557
|
-
body: JSON.stringify({})
|
|
7558
|
-
});
|
|
7559
|
-
if (data.attributes?.token) {
|
|
7560
|
-
this.orderToken = data.attributes.token;
|
|
7561
|
-
}
|
|
7562
|
-
return transformCart5(data, this.currencyCode);
|
|
7563
|
-
}
|
|
7564
|
-
async getCart(_cartId) {
|
|
7565
|
-
try {
|
|
7566
|
-
const { data } = await this.apiFetch("/cart?include=line_items");
|
|
7567
|
-
return transformCart5(data, this.currencyCode);
|
|
7568
|
-
} catch {
|
|
7569
|
-
return void 0;
|
|
7570
|
-
}
|
|
7571
|
-
}
|
|
7572
|
-
async addToCart(_cartId, lines) {
|
|
7573
|
-
for (const line of lines) {
|
|
7574
|
-
await this.apiFetch("/cart/add_item", {
|
|
7575
|
-
method: "POST",
|
|
7576
|
-
body: JSON.stringify({ variant_id: line.merchandiseId, quantity: line.quantity })
|
|
7577
|
-
});
|
|
7578
|
-
}
|
|
7579
|
-
const { data } = await this.apiFetch("/cart?include=line_items");
|
|
7580
|
-
return transformCart5(data, this.currencyCode);
|
|
7581
|
-
}
|
|
7582
|
-
async removeFromCart(_cartId, lineIds) {
|
|
7583
|
-
for (const id of lineIds) {
|
|
7584
|
-
await this.apiFetch(`/cart/remove_line_item/${id}`, { method: "DELETE" });
|
|
7585
|
-
}
|
|
7586
|
-
const { data } = await this.apiFetch("/cart?include=line_items");
|
|
7587
|
-
return transformCart5(data, this.currencyCode);
|
|
7588
|
-
}
|
|
7589
|
-
async updateCart(_cartId, lines) {
|
|
7590
|
-
for (const line of lines) {
|
|
7591
|
-
await this.apiFetch(`/cart/set_quantity`, {
|
|
7592
|
-
method: "PATCH",
|
|
7593
|
-
body: JSON.stringify({ line_item_id: line.id, quantity: line.quantity })
|
|
7594
|
-
});
|
|
7595
|
-
}
|
|
7596
|
-
const { data } = await this.apiFetch("/cart?include=line_items");
|
|
7597
|
-
return transformCart5(data, this.currencyCode);
|
|
7598
|
-
}
|
|
7599
|
-
// ============================================
|
|
7600
|
-
// Checkout Operations
|
|
7601
|
-
// ============================================
|
|
7602
|
-
async completeCheckout(_cartId) {
|
|
7603
|
-
const { data } = await this.apiFetch("/checkout/complete", { method: "PATCH" });
|
|
7604
|
-
return transformOrder5(data, this.currencyCode);
|
|
7605
|
-
}
|
|
7606
|
-
async getShippingMethods(_cartId) {
|
|
7607
|
-
try {
|
|
7608
|
-
const { data } = await this.apiFetch("/checkout/shipping_rates");
|
|
7609
|
-
return (Array.isArray(data) ? data : []).map((rate) => ({
|
|
7610
|
-
id: String(rate.id),
|
|
7611
|
-
name: rate.attributes?.name ?? rate.name ?? "",
|
|
7612
|
-
price: { amount: String(parseFloat(rate.attributes?.final_price ?? rate.attributes?.cost ?? "0").toFixed(2)), currencyCode: this.currencyCode }
|
|
7613
|
-
}));
|
|
7614
|
-
} catch {
|
|
7615
|
-
return [];
|
|
7616
|
-
}
|
|
7617
|
-
}
|
|
7618
|
-
async getRegionCountries() {
|
|
7619
|
-
return [];
|
|
7620
|
-
}
|
|
7621
|
-
async addShippingMethod(_cartId, methodId) {
|
|
7622
|
-
await this.apiFetch("/checkout", {
|
|
7623
|
-
method: "PATCH",
|
|
7624
|
-
body: JSON.stringify({ order: { shipments_attributes: [{ selected_shipping_rate_id: methodId }] } })
|
|
7625
|
-
});
|
|
7626
|
-
const { data } = await this.apiFetch("/cart?include=line_items");
|
|
7627
|
-
return transformCart5(data, this.currencyCode);
|
|
7628
|
-
}
|
|
7629
|
-
async initiatePaymentSession(_cartId, _providerId) {
|
|
7630
|
-
}
|
|
7631
|
-
async applyDiscountCode(_cartId, code) {
|
|
7632
|
-
await this.apiFetch("/cart/apply_coupon_code", {
|
|
7633
|
-
method: "PATCH",
|
|
7634
|
-
body: JSON.stringify({ coupon_code: code })
|
|
7635
|
-
});
|
|
7636
|
-
const { data } = await this.apiFetch("/cart?include=line_items");
|
|
7637
|
-
return transformCart5(data, this.currencyCode);
|
|
7638
|
-
}
|
|
7639
|
-
async removeDiscountCode(_cartId, code) {
|
|
7640
|
-
await this.apiFetch(`/cart/remove_coupon_code/${encodeURIComponent(code)}`, { method: "DELETE" });
|
|
7641
|
-
const { data } = await this.apiFetch("/cart?include=line_items");
|
|
7642
|
-
return transformCart5(data, this.currencyCode);
|
|
7643
|
-
}
|
|
7644
|
-
// ============================================
|
|
7645
|
-
// Customer, Order, Payment, Inventory, Admin
|
|
7646
|
-
// ============================================
|
|
7647
|
-
async getOrders(_options) {
|
|
7648
|
-
try {
|
|
7649
|
-
const { data } = await this.apiFetch("/account/orders");
|
|
7650
|
-
return (Array.isArray(data) ? data : []).map((o) => transformOrder5(o, this.currencyCode));
|
|
7651
|
-
} catch {
|
|
7652
|
-
return [];
|
|
7653
|
-
}
|
|
7654
|
-
}
|
|
7655
|
-
async getPaymentMethods(_options) {
|
|
7656
|
-
try {
|
|
7657
|
-
const { data } = await this.apiFetch("/checkout/payment_methods");
|
|
7658
|
-
return (Array.isArray(data) ? data : []).map((pm) => ({
|
|
7659
|
-
id: String(pm.id),
|
|
7660
|
-
name: pm.attributes?.name ?? "",
|
|
7661
|
-
type: "other",
|
|
7662
|
-
isEnabled: true,
|
|
7663
|
-
requiresSetup: false
|
|
7664
|
-
}));
|
|
7665
|
-
} catch {
|
|
7666
|
-
return [];
|
|
7667
|
-
}
|
|
7668
|
-
}
|
|
7669
|
-
async getStockLocations() {
|
|
7670
|
-
return [];
|
|
7671
|
-
}
|
|
7672
|
-
async checkInventoryLevels() {
|
|
7673
|
-
return [];
|
|
7674
|
-
}
|
|
7675
|
-
async validateCartStock() {
|
|
7676
|
-
return { allAvailable: true, unavailableItems: [] };
|
|
7677
|
-
}
|
|
7678
|
-
async getFulfillmentOptions() {
|
|
7679
|
-
return [];
|
|
7680
|
-
}
|
|
7681
|
-
async cancelOrder(_orderId) {
|
|
7682
|
-
throw new ProviderAPIError("Order cancellation requires Spree Admin API.", "SPREE_ADMIN_REQUIRED");
|
|
7683
|
-
}
|
|
7684
|
-
async createFulfillment(_orderId) {
|
|
7685
|
-
throw new ProviderAPIError("Fulfillment requires Spree Admin API.", "SPREE_ADMIN_REQUIRED");
|
|
7686
|
-
}
|
|
7687
|
-
async createRefund(_orderId) {
|
|
7688
|
-
throw new ProviderAPIError("Refunds require Spree Admin API.", "SPREE_ADMIN_REQUIRED");
|
|
7689
|
-
}
|
|
7690
|
-
async getAdminOrders() {
|
|
7691
|
-
return { orders: [], count: 0 };
|
|
7692
|
-
}
|
|
7693
|
-
async getStorefrontContext() {
|
|
7694
|
-
return {
|
|
7695
|
-
id: this.baseUrl,
|
|
7696
|
-
name: `Spree ${this.baseUrl}`,
|
|
7697
|
-
platformType: "spree",
|
|
7698
|
-
requiresProductScoping: true,
|
|
7699
|
-
currencyCode: this.currencyCode
|
|
7700
|
-
};
|
|
7701
|
-
}
|
|
7702
|
-
isStorefrontRequired() {
|
|
7703
|
-
return true;
|
|
7704
|
-
}
|
|
7705
|
-
};
|
|
7706
|
-
|
|
7707
|
-
// src/providers/magento/transforms.ts
|
|
7708
|
-
function toMoney2(value, currencyCode) {
|
|
7709
|
-
return { amount: (value ?? 0).toFixed(2), currencyCode };
|
|
7710
|
-
}
|
|
7711
|
-
function extractPrice(priceRange, currencyCode) {
|
|
7712
|
-
const minPrice = priceRange?.minimum_price?.regular_price?.value ?? priceRange?.minimum_price?.final_price?.value ?? 0;
|
|
7713
|
-
const maxPrice = priceRange?.maximum_price?.regular_price?.value ?? priceRange?.maximum_price?.final_price?.value ?? minPrice;
|
|
7714
|
-
const currency = priceRange?.minimum_price?.regular_price?.currency ?? currencyCode;
|
|
7715
|
-
return {
|
|
7716
|
-
min: toMoney2(minPrice, currency),
|
|
7717
|
-
max: toMoney2(maxPrice, currency)
|
|
7718
|
-
};
|
|
7719
|
-
}
|
|
7720
|
-
function transformProduct6(data, currencyCode = "USD") {
|
|
7721
|
-
const id = String(data.id ?? data.uid ?? "");
|
|
7722
|
-
const { min, max } = extractPrice(data.price_range, currencyCode);
|
|
7723
|
-
const images = (data.media_gallery ?? data.media_gallery_entries ?? []).map((img) => ({
|
|
7724
|
-
url: img.url ?? (img.file ? `${img.file}` : ""),
|
|
7725
|
-
altText: img.label ?? data.name ?? "",
|
|
7726
|
-
width: void 0,
|
|
7727
|
-
height: void 0
|
|
7728
|
-
}));
|
|
7729
|
-
if (images.length === 0 && data.small_image?.url) {
|
|
7730
|
-
images.push({ url: data.small_image.url, altText: data.small_image.label ?? data.name ?? "" });
|
|
7731
|
-
}
|
|
7732
|
-
if (images.length === 0 && data.image?.url) {
|
|
7733
|
-
images.push({ url: data.image.url, altText: data.image.label ?? data.name ?? "" });
|
|
7734
|
-
}
|
|
7735
|
-
const variants = [];
|
|
7736
|
-
if (data.variants && Array.isArray(data.variants)) {
|
|
7737
|
-
for (const v of data.variants) {
|
|
7738
|
-
const product = v.product ?? {};
|
|
7739
|
-
const vPrice = product.price_range?.minimum_price?.final_price ?? {};
|
|
7740
|
-
variants.push({
|
|
7741
|
-
id: String(product.id ?? product.uid ?? product.sku ?? ""),
|
|
7742
|
-
title: product.name ?? product.sku ?? "",
|
|
7743
|
-
availableForSale: product.stock_status === "IN_STOCK",
|
|
7744
|
-
price: toMoney2(vPrice.value ?? min.amount, vPrice.currency ?? currencyCode),
|
|
7745
|
-
compareAtPrice: void 0,
|
|
7746
|
-
selectedOptions: (v.attributes ?? []).map((attr) => ({
|
|
7747
|
-
name: attr.label ?? "",
|
|
7748
|
-
value: attr.value_index != null ? String(attr.value_index) : ""
|
|
7749
|
-
}))
|
|
7750
|
-
});
|
|
7751
|
-
}
|
|
7752
|
-
}
|
|
7753
|
-
if (variants.length === 0) {
|
|
7754
|
-
variants.push({
|
|
7755
|
-
id: data.sku ?? id,
|
|
7756
|
-
title: data.name ?? "",
|
|
7757
|
-
availableForSale: data.stock_status === "IN_STOCK",
|
|
7758
|
-
price: min,
|
|
7759
|
-
compareAtPrice: void 0,
|
|
7760
|
-
selectedOptions: []
|
|
7761
|
-
});
|
|
7762
|
-
}
|
|
7763
|
-
const options = (data.configurable_options ?? []).map((opt) => ({
|
|
7764
|
-
id: String(opt.attribute_id ?? opt.attribute_code ?? ""),
|
|
7765
|
-
name: opt.label ?? opt.attribute_code ?? "",
|
|
7766
|
-
values: (opt.values ?? []).map((v) => v.label ?? v.store_label ?? String(v.value_index ?? ""))
|
|
7767
|
-
}));
|
|
7768
|
-
return {
|
|
7769
|
-
id,
|
|
7770
|
-
handle: data.url_key ?? data.sku ?? id,
|
|
7771
|
-
title: data.name ?? "",
|
|
7772
|
-
description: data.short_description?.html ?? data.description?.html ?? "",
|
|
7773
|
-
descriptionHtml: data.description?.html ?? "",
|
|
7774
|
-
availableForSale: data.stock_status === "IN_STOCK",
|
|
7775
|
-
priceRange: { minVariantPrice: min, maxVariantPrice: max },
|
|
7776
|
-
variants,
|
|
7777
|
-
options,
|
|
7778
|
-
images,
|
|
7779
|
-
featuredImage: images[0] ?? { url: "", altText: data.name ?? "" },
|
|
7780
|
-
tags: [],
|
|
7781
|
-
seo: {
|
|
7782
|
-
title: data.meta_title ?? data.name ?? "",
|
|
7783
|
-
description: data.meta_description ?? ""
|
|
7784
|
-
},
|
|
7785
|
-
updatedAt: data.updated_at ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
7786
|
-
createdAt: data.created_at ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
7787
|
-
};
|
|
7788
|
-
}
|
|
7789
|
-
function transformCollection6(data) {
|
|
7790
|
-
return {
|
|
7791
|
-
id: String(data.id ?? data.uid ?? ""),
|
|
7792
|
-
handle: data.url_key ?? data.url_path ?? String(data.id ?? data.uid ?? ""),
|
|
7793
|
-
title: data.name ?? "",
|
|
7794
|
-
description: data.description ?? "",
|
|
7795
|
-
seo: {
|
|
7796
|
-
title: data.meta_title ?? data.name ?? "",
|
|
7797
|
-
description: data.meta_description ?? ""
|
|
7798
|
-
},
|
|
7799
|
-
updatedAt: data.updated_at ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
7800
|
-
path: `/collections/${data.url_key ?? data.url_path ?? data.id}`
|
|
7801
|
-
};
|
|
7802
|
-
}
|
|
7803
|
-
function transformCart6(data, currencyCode = "USD") {
|
|
7804
|
-
const items = (data.items ?? []).map((item) => {
|
|
7805
|
-
const product = item.product ?? {};
|
|
7806
|
-
const priceVal = item.prices?.price?.value ?? product.price_range?.minimum_price?.final_price?.value ?? 0;
|
|
7807
|
-
const totalVal2 = item.prices?.row_total?.value ?? priceVal * (item.quantity ?? 1);
|
|
7808
|
-
return {
|
|
7809
|
-
id: String(item.id ?? item.uid ?? ""),
|
|
7810
|
-
quantity: item.quantity ?? 1,
|
|
7811
|
-
cost: {
|
|
7812
|
-
totalAmount: toMoney2(totalVal2, item.prices?.price?.currency ?? currencyCode)
|
|
7813
|
-
},
|
|
7814
|
-
merchandise: {
|
|
7815
|
-
id: String(product.sku ?? item.id ?? ""),
|
|
7816
|
-
title: product.name ?? item.product?.name ?? "",
|
|
7817
|
-
selectedOptions: (item.configurable_options ?? []).map((opt) => ({
|
|
7818
|
-
name: opt.option_label ?? "",
|
|
7819
|
-
value: opt.value_label ?? ""
|
|
7820
|
-
})),
|
|
7821
|
-
product: {
|
|
7822
|
-
id: String(product.id ?? product.uid ?? ""),
|
|
7823
|
-
handle: product.url_key ?? "",
|
|
7824
|
-
title: product.name ?? "",
|
|
7825
|
-
featuredImage: {
|
|
7826
|
-
url: product.small_image?.url ?? product.thumbnail?.url ?? "",
|
|
7827
|
-
altText: product.name ?? ""
|
|
7828
|
-
}
|
|
7829
|
-
}
|
|
7830
|
-
}
|
|
7831
|
-
};
|
|
7832
|
-
});
|
|
7833
|
-
const totalVal = data.prices?.grand_total?.value ?? 0;
|
|
7834
|
-
const subtotalVal = data.prices?.subtotal_excluding_tax?.value ?? data.prices?.subtotal_including_tax?.value ?? totalVal;
|
|
7835
|
-
const taxVal = (data.prices?.applied_taxes ?? []).reduce((sum, t) => sum + (t.amount?.value ?? 0), 0);
|
|
7836
|
-
return {
|
|
7837
|
-
id: String(data.id ?? ""),
|
|
7838
|
-
checkoutUrl: "",
|
|
7839
|
-
totalQuantity: items.reduce((sum, i) => sum + i.quantity, 0),
|
|
7840
|
-
cost: {
|
|
7841
|
-
subtotalAmount: toMoney2(subtotalVal, data.prices?.grand_total?.currency ?? currencyCode),
|
|
7842
|
-
totalAmount: toMoney2(totalVal, data.prices?.grand_total?.currency ?? currencyCode),
|
|
7843
|
-
totalTaxAmount: toMoney2(taxVal, currencyCode)
|
|
7844
|
-
},
|
|
7845
|
-
lines: items
|
|
7846
|
-
};
|
|
7847
|
-
}
|
|
7848
|
-
function transformAddress3(addr) {
|
|
7849
|
-
return {
|
|
7850
|
-
id: String(addr.id ?? ""),
|
|
7851
|
-
firstName: addr.firstname ?? "",
|
|
7852
|
-
lastName: addr.lastname ?? "",
|
|
7853
|
-
company: addr.company ?? "",
|
|
7854
|
-
address1: Array.isArray(addr.street) ? addr.street[0] ?? "" : addr.street ?? "",
|
|
7855
|
-
address2: Array.isArray(addr.street) ? addr.street[1] ?? "" : "",
|
|
7856
|
-
city: addr.city ?? "",
|
|
7857
|
-
province: addr.region?.region ?? "",
|
|
7858
|
-
postalCode: addr.postcode ?? "",
|
|
7859
|
-
countryCode: addr.country_code ?? addr.country_id ?? "",
|
|
7860
|
-
phone: addr.telephone ?? ""
|
|
7861
|
-
};
|
|
7862
|
-
}
|
|
7863
|
-
function transformOrder6(data, currencyCode = "USD") {
|
|
7864
|
-
const items = (data.items ?? []).map((item) => ({
|
|
7865
|
-
id: String(item.id ?? ""),
|
|
7866
|
-
title: item.product_name ?? "",
|
|
7867
|
-
quantity: item.quantity_ordered ?? item.quantity ?? 1,
|
|
7868
|
-
price: toMoney2(item.product_sale_price?.value ?? item.price ?? 0, currencyCode),
|
|
7869
|
-
total: toMoney2((item.product_sale_price?.value ?? item.price ?? 0) * (item.quantity_ordered ?? item.quantity ?? 1), currencyCode),
|
|
7870
|
-
sku: item.product_sku ?? item.sku,
|
|
7871
|
-
productId: String(item.product_id ?? "")
|
|
7872
|
-
}));
|
|
7873
|
-
return {
|
|
7874
|
-
id: String(data.id ?? data.order_number ?? ""),
|
|
7875
|
-
orderNumber: data.order_number ?? data.number ?? String(data.id ?? ""),
|
|
7876
|
-
email: data.email ?? "",
|
|
7877
|
-
status: data.status === "complete" ? "completed" : data.status === "canceled" ? "cancelled" : data.status === "closed" ? "refunded" : "pending",
|
|
7878
|
-
paymentStatus: data.payment_status === "paid" ? "paid" : "pending",
|
|
7879
|
-
fulfillmentStatus: data.shipment_status === "shipped" ? "fulfilled" : "unfulfilled",
|
|
7880
|
-
items,
|
|
7881
|
-
total: toMoney2(data.total?.grand_total?.value ?? data.grand_total ?? 0, currencyCode),
|
|
7882
|
-
subtotal: toMoney2(data.total?.subtotal?.value ?? data.subtotal ?? 0, currencyCode),
|
|
7883
|
-
tax: toMoney2(data.total?.total_tax?.value ?? data.tax_amount ?? 0, currencyCode),
|
|
7884
|
-
shipping: toMoney2(data.total?.total_shipping?.value ?? data.shipping_amount ?? 0, currencyCode),
|
|
7885
|
-
shippingAddress: data.shipping_address ? transformAddress3(data.shipping_address) : void 0,
|
|
7886
|
-
billingAddress: data.billing_address ? transformAddress3(data.billing_address) : void 0,
|
|
7887
|
-
createdAt: data.order_date ?? data.created_at ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
7888
|
-
updatedAt: data.updated_at ?? data.order_date ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
7889
|
-
};
|
|
7890
|
-
}
|
|
7891
|
-
|
|
7892
|
-
// src/providers/magento/queries.ts
|
|
7893
|
-
var PRODUCT_FIELDS = `
|
|
7894
|
-
id
|
|
7895
|
-
uid
|
|
7896
|
-
sku
|
|
7897
|
-
name
|
|
7898
|
-
url_key
|
|
7899
|
-
stock_status
|
|
7900
|
-
short_description { html }
|
|
7901
|
-
description { html }
|
|
7902
|
-
meta_title
|
|
7903
|
-
meta_description
|
|
7904
|
-
created_at
|
|
7905
|
-
updated_at
|
|
7906
|
-
price_range {
|
|
7907
|
-
minimum_price {
|
|
7908
|
-
regular_price { value currency }
|
|
7909
|
-
final_price { value currency }
|
|
7910
|
-
}
|
|
7911
|
-
maximum_price {
|
|
7912
|
-
regular_price { value currency }
|
|
7913
|
-
final_price { value currency }
|
|
7914
|
-
}
|
|
7915
|
-
}
|
|
7916
|
-
small_image { url label }
|
|
7917
|
-
image { url label }
|
|
7918
|
-
media_gallery {
|
|
7919
|
-
url
|
|
7920
|
-
label
|
|
7921
|
-
}
|
|
7922
|
-
... on ConfigurableProduct {
|
|
7923
|
-
configurable_options {
|
|
7924
|
-
attribute_code
|
|
7925
|
-
attribute_id
|
|
7926
|
-
label
|
|
7927
|
-
values {
|
|
7928
|
-
label
|
|
7929
|
-
value_index
|
|
7930
|
-
}
|
|
7931
|
-
}
|
|
7932
|
-
variants {
|
|
7933
|
-
product {
|
|
7934
|
-
id uid sku name
|
|
7935
|
-
stock_status
|
|
7936
|
-
price_range {
|
|
7937
|
-
minimum_price {
|
|
7938
|
-
final_price { value currency }
|
|
7939
|
-
}
|
|
7940
|
-
}
|
|
7941
|
-
small_image { url label }
|
|
7942
|
-
}
|
|
7943
|
-
attributes {
|
|
7944
|
-
label
|
|
7945
|
-
value_index
|
|
7946
|
-
}
|
|
7947
|
-
}
|
|
7948
|
-
}
|
|
7949
|
-
`;
|
|
7950
|
-
var GET_PRODUCTS2 = `
|
|
7951
|
-
query GetProducts($search: String, $pageSize: Int, $currentPage: Int, $sort: ProductAttributeSortInput) {
|
|
7952
|
-
products(search: $search, pageSize: $pageSize, currentPage: $currentPage, sort: $sort) {
|
|
7953
|
-
items { ${PRODUCT_FIELDS} }
|
|
7954
|
-
total_count
|
|
7955
|
-
}
|
|
7956
|
-
}
|
|
7957
|
-
`;
|
|
7958
|
-
var GET_PRODUCT_BY_URL_KEY = `
|
|
7959
|
-
query GetProductByUrlKey($urlKey: String!) {
|
|
7960
|
-
products(filter: { url_key: { eq: $urlKey } }, pageSize: 1) {
|
|
7961
|
-
items { ${PRODUCT_FIELDS} }
|
|
7962
|
-
}
|
|
7963
|
-
}
|
|
7964
|
-
`;
|
|
7965
|
-
var GET_CATEGORIES = `
|
|
7966
|
-
query GetCategories($pageSize: Int) {
|
|
7967
|
-
categories(pageSize: $pageSize) {
|
|
7968
|
-
items {
|
|
7969
|
-
id uid name url_key url_path description meta_title meta_description
|
|
7970
|
-
}
|
|
7971
|
-
}
|
|
7972
|
-
}
|
|
7973
|
-
`;
|
|
7974
|
-
var GET_CATEGORY_BY_URL_KEY = `
|
|
7975
|
-
query GetCategoryByUrlKey($urlKey: String!) {
|
|
7976
|
-
categories(filters: { url_key: { eq: $urlKey } }, pageSize: 1) {
|
|
7977
|
-
items {
|
|
7978
|
-
id uid name url_key url_path description meta_title meta_description
|
|
7979
|
-
}
|
|
7980
|
-
}
|
|
7981
|
-
}
|
|
7982
|
-
`;
|
|
7983
|
-
var GET_CATEGORY_PRODUCTS = `
|
|
7984
|
-
query GetCategoryProducts($urlKey: String!, $pageSize: Int) {
|
|
7985
|
-
products(filter: { category_url_key: { eq: $urlKey } }, pageSize: $pageSize) {
|
|
7986
|
-
items { ${PRODUCT_FIELDS} }
|
|
7987
|
-
total_count
|
|
7988
|
-
}
|
|
7989
|
-
}
|
|
7990
|
-
`;
|
|
7991
|
-
var GET_CART2 = `
|
|
7992
|
-
query GetCart($cartId: String!) {
|
|
7993
|
-
cart(cart_id: $cartId) {
|
|
7994
|
-
id
|
|
7995
|
-
items {
|
|
7996
|
-
id uid quantity
|
|
7997
|
-
product {
|
|
7998
|
-
id uid sku name url_key
|
|
7999
|
-
small_image { url }
|
|
8000
|
-
thumbnail { url }
|
|
8001
|
-
price_range {
|
|
8002
|
-
minimum_price {
|
|
8003
|
-
final_price { value currency }
|
|
8004
|
-
}
|
|
8005
|
-
}
|
|
8006
|
-
}
|
|
8007
|
-
prices {
|
|
8008
|
-
price { value currency }
|
|
8009
|
-
row_total { value currency }
|
|
8010
|
-
}
|
|
8011
|
-
... on ConfigurableCartItem {
|
|
8012
|
-
configurable_options {
|
|
8013
|
-
option_label
|
|
8014
|
-
value_label
|
|
8015
|
-
}
|
|
8016
|
-
}
|
|
8017
|
-
}
|
|
8018
|
-
prices {
|
|
8019
|
-
grand_total { value currency }
|
|
8020
|
-
subtotal_excluding_tax { value currency }
|
|
8021
|
-
subtotal_including_tax { value currency }
|
|
8022
|
-
applied_taxes {
|
|
8023
|
-
amount { value currency }
|
|
8024
|
-
label
|
|
8025
|
-
}
|
|
8026
|
-
}
|
|
8027
|
-
}
|
|
8028
|
-
}
|
|
8029
|
-
`;
|
|
8030
|
-
var CREATE_EMPTY_CART = `
|
|
8031
|
-
mutation CreateEmptyCart {
|
|
8032
|
-
createEmptyCart
|
|
8033
|
-
}
|
|
8034
|
-
`;
|
|
8035
|
-
var ADD_TO_CART = `
|
|
8036
|
-
mutation AddToCart($cartId: String!, $cartItems: [CartItemInput!]!) {
|
|
8037
|
-
addProductsToCart(cartId: $cartId, cartItems: $cartItems) {
|
|
8038
|
-
cart {
|
|
8039
|
-
id
|
|
8040
|
-
items { id uid quantity product { sku name } prices { price { value currency } row_total { value currency } } }
|
|
8041
|
-
prices { grand_total { value currency } subtotal_excluding_tax { value currency } }
|
|
8042
|
-
}
|
|
8043
|
-
user_errors { code message }
|
|
8044
|
-
}
|
|
8045
|
-
}
|
|
8046
|
-
`;
|
|
8047
|
-
var REMOVE_FROM_CART = `
|
|
8048
|
-
mutation RemoveFromCart($cartId: String!, $cartItemUid: ID!) {
|
|
8049
|
-
removeItemFromCart(input: { cart_id: $cartId, cart_item_uid: $cartItemUid }) {
|
|
8050
|
-
cart {
|
|
8051
|
-
id
|
|
8052
|
-
items { id uid quantity product { sku name } prices { price { value currency } row_total { value currency } } }
|
|
8053
|
-
prices { grand_total { value currency } subtotal_excluding_tax { value currency } }
|
|
8054
|
-
}
|
|
8055
|
-
}
|
|
8056
|
-
}
|
|
8057
|
-
`;
|
|
8058
|
-
var UPDATE_CART_ITEMS = `
|
|
8059
|
-
mutation UpdateCartItems($cartId: String!, $cartItems: [CartItemUpdateInput!]!) {
|
|
8060
|
-
updateCartItems(input: { cart_id: $cartId, cart_items: $cartItems }) {
|
|
8061
|
-
cart {
|
|
8062
|
-
id
|
|
8063
|
-
items { id uid quantity product { sku name } prices { price { value currency } row_total { value currency } } }
|
|
8064
|
-
prices { grand_total { value currency } subtotal_excluding_tax { value currency } }
|
|
8065
|
-
}
|
|
8066
|
-
}
|
|
8067
|
-
}
|
|
8068
|
-
`;
|
|
8069
|
-
var APPLY_COUPON = `
|
|
8070
|
-
mutation ApplyCoupon($cartId: String!, $couponCode: String!) {
|
|
8071
|
-
applyCouponToCart(input: { cart_id: $cartId, coupon_code: $couponCode }) {
|
|
8072
|
-
cart {
|
|
8073
|
-
id
|
|
8074
|
-
prices { grand_total { value currency } subtotal_excluding_tax { value currency } }
|
|
8075
|
-
}
|
|
8076
|
-
}
|
|
8077
|
-
}
|
|
8078
|
-
`;
|
|
8079
|
-
var REMOVE_COUPON = `
|
|
8080
|
-
mutation RemoveCoupon($cartId: String!) {
|
|
8081
|
-
removeCouponFromCart(input: { cart_id: $cartId }) {
|
|
8082
|
-
cart {
|
|
8083
|
-
id
|
|
8084
|
-
prices { grand_total { value currency } subtotal_excluding_tax { value currency } }
|
|
8085
|
-
}
|
|
8086
|
-
}
|
|
8087
|
-
}
|
|
8088
|
-
`;
|
|
8089
|
-
var GET_CUSTOMER_ORDERS = `
|
|
8090
|
-
query GetCustomerOrders($pageSize: Int, $currentPage: Int) {
|
|
8091
|
-
customer {
|
|
8092
|
-
orders(pageSize: $pageSize, currentPage: $currentPage) {
|
|
8093
|
-
items {
|
|
8094
|
-
id order_number order_date status
|
|
8095
|
-
total {
|
|
8096
|
-
grand_total { value currency }
|
|
8097
|
-
subtotal { value currency }
|
|
8098
|
-
total_tax { value currency }
|
|
8099
|
-
total_shipping { value currency }
|
|
8100
|
-
}
|
|
8101
|
-
items {
|
|
8102
|
-
id product_name product_sku
|
|
8103
|
-
quantity_ordered
|
|
8104
|
-
product_sale_price { value currency }
|
|
8105
|
-
}
|
|
8106
|
-
shipping_address {
|
|
8107
|
-
firstname lastname street city
|
|
8108
|
-
region postcode country_code telephone
|
|
8109
|
-
}
|
|
8110
|
-
billing_address {
|
|
8111
|
-
firstname lastname street city
|
|
8112
|
-
region postcode country_code telephone
|
|
8113
|
-
}
|
|
8114
|
-
}
|
|
8115
|
-
total_count
|
|
8116
|
-
}
|
|
8117
|
-
}
|
|
8118
|
-
}
|
|
8119
|
-
`;
|
|
8120
|
-
|
|
8121
|
-
// src/providers/magento/index.ts
|
|
8122
|
-
var MagentoProvider = class {
|
|
8123
|
-
name = "magento";
|
|
8124
|
-
version = "1.0.0";
|
|
8125
|
-
capabilities = MAGENTO_CAPABILITIES;
|
|
8126
|
-
logger;
|
|
8127
|
-
baseUrl;
|
|
8128
|
-
storeCode;
|
|
8129
|
-
currencyCode;
|
|
8130
|
-
graphqlEndpoint;
|
|
8131
|
-
customerToken;
|
|
8132
|
-
accessToken;
|
|
8133
|
-
constructor(config) {
|
|
8134
|
-
this.logger = createLogger("MagentoProvider", config.debug);
|
|
8135
|
-
this.baseUrl = config.baseUrl.replace(/\/$/, "");
|
|
8136
|
-
this.storeCode = config.storeCode ?? "default";
|
|
8137
|
-
this.currencyCode = config.currencyCode ?? "USD";
|
|
8138
|
-
this.graphqlEndpoint = `${this.baseUrl}/graphql`;
|
|
8139
|
-
this.customerToken = config.customerToken;
|
|
8140
|
-
this.accessToken = config.accessToken;
|
|
8141
|
-
this.logger.info("Initializing Magento Provider", {
|
|
8142
|
-
baseUrl: this.baseUrl,
|
|
8143
|
-
storeCode: this.storeCode
|
|
8144
|
-
});
|
|
8145
|
-
}
|
|
8146
|
-
async graphql(query, variables) {
|
|
8147
|
-
const headers = {
|
|
8148
|
-
"Content-Type": "application/json",
|
|
8149
|
-
"Store": this.storeCode
|
|
8150
|
-
};
|
|
8151
|
-
if (this.customerToken) {
|
|
8152
|
-
headers["Authorization"] = `Bearer ${this.customerToken}`;
|
|
8153
|
-
}
|
|
8154
|
-
const response = await fetch(this.graphqlEndpoint, {
|
|
8155
|
-
method: "POST",
|
|
8156
|
-
headers,
|
|
8157
|
-
body: JSON.stringify({ query, variables })
|
|
8158
|
-
});
|
|
8159
|
-
if (!response.ok) {
|
|
8160
|
-
throw new ProviderAPIError(
|
|
8161
|
-
`Magento GraphQL error: ${response.status}`,
|
|
8162
|
-
"MAGENTO_API_ERROR",
|
|
8163
|
-
response.status
|
|
8164
|
-
);
|
|
8165
|
-
}
|
|
8166
|
-
const json = await response.json();
|
|
8167
|
-
if (json.errors?.length) {
|
|
8168
|
-
const message = json.errors.map((e) => e.message).join("; ");
|
|
8169
|
-
throw new ProviderAPIError(`Magento GraphQL error: ${message}`, "MAGENTO_GRAPHQL_ERROR");
|
|
8170
|
-
}
|
|
8171
|
-
return json.data;
|
|
8172
|
-
}
|
|
8173
|
-
// ============================================
|
|
8174
|
-
// Product Operations (GraphQL)
|
|
8175
|
-
// ============================================
|
|
8176
|
-
async getProduct(handle) {
|
|
8177
|
-
try {
|
|
8178
|
-
const data = await this.graphql(GET_PRODUCT_BY_URL_KEY, { urlKey: handle });
|
|
8179
|
-
return data.products.items[0] ? transformProduct6(data.products.items[0], this.currencyCode) : void 0;
|
|
8180
|
-
} catch {
|
|
8181
|
-
return void 0;
|
|
8182
|
-
}
|
|
8183
|
-
}
|
|
8184
|
-
async getProducts(options) {
|
|
8185
|
-
const variables = {
|
|
8186
|
-
pageSize: options?.first ?? 20,
|
|
8187
|
-
currentPage: 1
|
|
8188
|
-
};
|
|
8189
|
-
if (options?.query) variables.search = options.query;
|
|
8190
|
-
if (options?.sortKey) {
|
|
8191
|
-
const sortMap = {
|
|
8192
|
-
"price-asc": { price: "ASC" },
|
|
8193
|
-
"price-desc": { price: "DESC" },
|
|
8194
|
-
"title-asc": { name: "ASC" },
|
|
8195
|
-
"title-desc": { name: "DESC" },
|
|
8196
|
-
"created-desc": { created_at: "DESC" },
|
|
8197
|
-
"relevance": { relevance: "DESC" }
|
|
8198
|
-
};
|
|
8199
|
-
variables.sort = sortMap[options.sortKey] ?? { relevance: "DESC" };
|
|
8200
|
-
}
|
|
8201
|
-
const data = await this.graphql(GET_PRODUCTS2, variables);
|
|
8202
|
-
return (data.products?.items ?? []).map((p) => transformProduct6(p, this.currencyCode));
|
|
8203
|
-
}
|
|
8204
|
-
async getProductRecommendations(_productId) {
|
|
8205
|
-
return [];
|
|
8206
|
-
}
|
|
8207
|
-
// ============================================
|
|
8208
|
-
// Collection/Category Operations (GraphQL)
|
|
8209
|
-
// ============================================
|
|
8210
|
-
async getCollection(handle) {
|
|
8211
|
-
try {
|
|
8212
|
-
const data = await this.graphql(GET_CATEGORY_BY_URL_KEY, { urlKey: handle });
|
|
8213
|
-
return data.categories.items[0] ? transformCollection6(data.categories.items[0]) : void 0;
|
|
8214
|
-
} catch {
|
|
8215
|
-
return void 0;
|
|
8216
|
-
}
|
|
8217
|
-
}
|
|
8218
|
-
async getCollections(options) {
|
|
8219
|
-
const data = await this.graphql(GET_CATEGORIES, {
|
|
8220
|
-
pageSize: options?.limit ?? 50
|
|
8221
|
-
});
|
|
8222
|
-
return (data.categories?.items ?? []).map(transformCollection6);
|
|
8223
|
-
}
|
|
8224
|
-
async getCollectionProducts(handle, options) {
|
|
8225
|
-
const data = await this.graphql(GET_CATEGORY_PRODUCTS, {
|
|
8226
|
-
urlKey: handle,
|
|
8227
|
-
pageSize: options?.first ?? 20
|
|
8228
|
-
});
|
|
8229
|
-
return (data.products?.items ?? []).map((p) => transformProduct6(p, this.currencyCode));
|
|
8230
|
-
}
|
|
8231
|
-
async getCategory(handle) {
|
|
8232
|
-
return this.getCollection(handle);
|
|
8233
|
-
}
|
|
8234
|
-
async getCategories(options) {
|
|
8235
|
-
return this.getCollections(options);
|
|
8236
|
-
}
|
|
8237
|
-
async getCategoryProducts(handle, options) {
|
|
8238
|
-
return this.getCollectionProducts(handle, options);
|
|
8239
|
-
}
|
|
8240
|
-
// ============================================
|
|
8241
|
-
// Cart Operations (GraphQL)
|
|
8242
|
-
// ============================================
|
|
8243
|
-
async createCart() {
|
|
8244
|
-
const data = await this.graphql(CREATE_EMPTY_CART);
|
|
8245
|
-
const cartId = data.createEmptyCart;
|
|
8246
|
-
const cartData = await this.graphql(GET_CART2, { cartId });
|
|
8247
|
-
return transformCart6(cartData.cart ?? { id: cartId, items: [], prices: {} }, this.currencyCode);
|
|
8248
|
-
}
|
|
8249
|
-
async getCart(cartId) {
|
|
8250
|
-
try {
|
|
8251
|
-
const data = await this.graphql(GET_CART2, { cartId });
|
|
8252
|
-
return data.cart ? transformCart6(data.cart, this.currencyCode) : void 0;
|
|
8253
|
-
} catch {
|
|
8254
|
-
return void 0;
|
|
8255
|
-
}
|
|
8256
|
-
}
|
|
8257
|
-
async addToCart(cartId, lines) {
|
|
8258
|
-
const cartItems = lines.map((l) => ({
|
|
8259
|
-
sku: l.merchandiseId,
|
|
8260
|
-
quantity: l.quantity
|
|
8261
|
-
}));
|
|
8262
|
-
const data = await this.graphql(ADD_TO_CART, {
|
|
8263
|
-
cartId,
|
|
8264
|
-
cartItems
|
|
8265
|
-
});
|
|
8266
|
-
if (data.addProductsToCart.user_errors?.length) {
|
|
8267
|
-
throw new ProviderAPIError(
|
|
8268
|
-
`Add to cart failed: ${data.addProductsToCart.user_errors.map((e) => e.message).join("; ")}`,
|
|
8269
|
-
"MAGENTO_CART_ERROR"
|
|
8270
|
-
);
|
|
8271
|
-
}
|
|
8272
|
-
return transformCart6(data.addProductsToCart.cart, this.currencyCode);
|
|
8273
|
-
}
|
|
8274
|
-
async removeFromCart(cartId, lineIds) {
|
|
8275
|
-
let cart;
|
|
8276
|
-
for (const itemUid of lineIds) {
|
|
8277
|
-
const data = await this.graphql(REMOVE_FROM_CART, {
|
|
8278
|
-
cartId,
|
|
8279
|
-
cartItemUid: itemUid
|
|
8280
|
-
});
|
|
8281
|
-
cart = data.removeItemFromCart.cart;
|
|
8282
|
-
}
|
|
8283
|
-
return transformCart6(cart ?? { id: cartId, items: [], prices: {} }, this.currencyCode);
|
|
8284
|
-
}
|
|
8285
|
-
async updateCart(cartId, lines) {
|
|
8286
|
-
const cartItems = lines.map((l) => ({
|
|
8287
|
-
cart_item_uid: l.id,
|
|
8288
|
-
quantity: l.quantity
|
|
8289
|
-
}));
|
|
8290
|
-
const data = await this.graphql(UPDATE_CART_ITEMS, {
|
|
8291
|
-
cartId,
|
|
8292
|
-
cartItems
|
|
8293
|
-
});
|
|
8294
|
-
return transformCart6(data.updateCartItems.cart, this.currencyCode);
|
|
8295
|
-
}
|
|
8296
|
-
// ============================================
|
|
8297
|
-
// Checkout Operations
|
|
8298
|
-
// ============================================
|
|
8299
|
-
async completeCheckout(_cartId) {
|
|
8300
|
-
throw new ProviderAPIError(
|
|
8301
|
-
"Magento checkout requires multi-step process (set addresses, shipping, payment, place order). Use the Magento checkout flow.",
|
|
8302
|
-
"MAGENTO_CHECKOUT_MULTI_STEP"
|
|
8303
|
-
);
|
|
8304
|
-
}
|
|
8305
|
-
async getShippingMethods(_cartId) {
|
|
8306
|
-
return [];
|
|
8307
|
-
}
|
|
8308
|
-
async getRegionCountries() {
|
|
8309
|
-
return [];
|
|
8310
|
-
}
|
|
8311
|
-
async addShippingMethod(_cartId, _methodId) {
|
|
8312
|
-
throw new ProviderAPIError(
|
|
8313
|
-
"Magento shipping selection requires set-shipping-methods mutation.",
|
|
8314
|
-
"MAGENTO_CHECKOUT_MULTI_STEP"
|
|
8315
|
-
);
|
|
8316
|
-
}
|
|
8317
|
-
async initiatePaymentSession(_cartId, _providerId) {
|
|
8318
|
-
}
|
|
8319
|
-
async applyDiscountCode(cartId, code) {
|
|
8320
|
-
const data = await this.graphql(APPLY_COUPON, {
|
|
8321
|
-
cartId,
|
|
8322
|
-
couponCode: code
|
|
8323
|
-
});
|
|
8324
|
-
return transformCart6(data.applyCouponToCart.cart, this.currencyCode);
|
|
8325
|
-
}
|
|
8326
|
-
async removeDiscountCode(cartId, _code) {
|
|
8327
|
-
const data = await this.graphql(REMOVE_COUPON, {
|
|
8328
|
-
cartId
|
|
8329
|
-
});
|
|
8330
|
-
return transformCart6(data.removeCouponFromCart.cart, this.currencyCode);
|
|
8331
|
-
}
|
|
8332
|
-
// ============================================
|
|
8333
|
-
// Customer & Orders (GraphQL — requires customerToken)
|
|
8334
|
-
// ============================================
|
|
8335
|
-
async getOrders(_options) {
|
|
8336
|
-
if (!this.customerToken) return [];
|
|
8337
|
-
try {
|
|
8338
|
-
const data = await this.graphql(GET_CUSTOMER_ORDERS, {
|
|
8339
|
-
pageSize: 20,
|
|
8340
|
-
currentPage: 1
|
|
8341
|
-
});
|
|
8342
|
-
return (data.customer?.orders?.items ?? []).map((o) => transformOrder6(o, this.currencyCode));
|
|
8343
|
-
} catch {
|
|
8344
|
-
return [];
|
|
8345
|
-
}
|
|
8346
|
-
}
|
|
8347
|
-
async getPaymentMethods(_options) {
|
|
8348
|
-
return [];
|
|
8349
|
-
}
|
|
8350
|
-
// ============================================
|
|
8351
|
-
// Inventory
|
|
8352
|
-
// ============================================
|
|
8353
|
-
async getStockLocations() {
|
|
8354
|
-
return [];
|
|
8355
|
-
}
|
|
8356
|
-
async checkInventoryLevels() {
|
|
8357
|
-
return [];
|
|
8358
|
-
}
|
|
8359
|
-
async validateCartStock() {
|
|
8360
|
-
return { allAvailable: true, unavailableItems: [] };
|
|
8361
|
-
}
|
|
8362
|
-
async getFulfillmentOptions() {
|
|
8363
|
-
return [];
|
|
8364
|
-
}
|
|
8365
|
-
// ============================================
|
|
8366
|
-
// Admin Operations
|
|
8367
|
-
// ============================================
|
|
8368
|
-
async cancelOrder(_orderId) {
|
|
8369
|
-
throw new ProviderAPIError("Order cancellation requires Magento Admin API.", "MAGENTO_ADMIN_REQUIRED");
|
|
8370
|
-
}
|
|
8371
|
-
async createFulfillment(_orderId) {
|
|
8372
|
-
throw new ProviderAPIError("Fulfillment requires Magento Admin API.", "MAGENTO_ADMIN_REQUIRED");
|
|
8373
|
-
}
|
|
8374
|
-
async createRefund(_orderId) {
|
|
8375
|
-
throw new ProviderAPIError("Refunds require Magento Admin API.", "MAGENTO_ADMIN_REQUIRED");
|
|
8376
|
-
}
|
|
8377
|
-
async getAdminOrders() {
|
|
8378
|
-
return { orders: [], count: 0 };
|
|
8379
|
-
}
|
|
8380
|
-
// ============================================
|
|
8381
|
-
// Storefront / Multi-Tenant
|
|
8382
|
-
// ============================================
|
|
8383
|
-
async getStorefrontContext() {
|
|
8384
|
-
return {
|
|
8385
|
-
id: this.storeCode,
|
|
8386
|
-
name: `Magento ${this.storeCode}`,
|
|
8387
|
-
platformType: "magento",
|
|
8388
|
-
requiresProductScoping: true,
|
|
8389
|
-
currencyCode: this.currencyCode
|
|
8390
|
-
};
|
|
8391
|
-
}
|
|
8392
|
-
isStorefrontRequired() {
|
|
8393
|
-
return true;
|
|
8394
|
-
}
|
|
8395
|
-
};
|
|
8396
|
-
|
|
8397
|
-
// src/providers/stelorder/transforms.ts
|
|
8398
|
-
function normalizeStelCollection(payload) {
|
|
8399
|
-
if (!payload) {
|
|
8400
|
-
return [];
|
|
8401
|
-
}
|
|
8402
|
-
return Array.isArray(payload) ? payload : [payload];
|
|
8403
|
-
}
|
|
8404
|
-
function normalizeStelEntity(payload) {
|
|
8405
|
-
if (!payload) {
|
|
8406
|
-
return void 0;
|
|
8407
|
-
}
|
|
8408
|
-
return Array.isArray(payload) ? payload[0] : payload;
|
|
8409
|
-
}
|
|
8410
|
-
function transformStelMoney(amount, currencyCode = "USD") {
|
|
8411
|
-
const normalizedAmount = typeof amount === "string" ? Number.parseFloat(amount) : amount ?? 0;
|
|
8412
|
-
return {
|
|
8413
|
-
amount: Number.isFinite(normalizedAmount) ? normalizedAmount.toFixed(2) : "0.00",
|
|
8414
|
-
currencyCode: currencyCode.toUpperCase()
|
|
8415
|
-
};
|
|
8416
|
-
}
|
|
8417
|
-
function transformStelImage(url, altText = "") {
|
|
8418
|
-
const normalizedUrl = url?.trim();
|
|
8419
|
-
if (!normalizedUrl) {
|
|
8420
|
-
return void 0;
|
|
8421
|
-
}
|
|
8422
|
-
return {
|
|
8423
|
-
url: normalizedUrl,
|
|
8424
|
-
altText,
|
|
8425
|
-
width: 800,
|
|
8426
|
-
height: 800
|
|
8427
|
-
};
|
|
8428
|
-
}
|
|
8429
|
-
function normalizeStelDate(value) {
|
|
8430
|
-
if (!value) {
|
|
8431
|
-
return (/* @__PURE__ */ new Date()).toISOString();
|
|
8432
|
-
}
|
|
8433
|
-
const parsed = new Date(value);
|
|
8434
|
-
return Number.isNaN(parsed.getTime()) ? (/* @__PURE__ */ new Date()).toISOString() : parsed.toISOString();
|
|
8435
|
-
}
|
|
8436
|
-
function toStelStringId(value) {
|
|
8437
|
-
if (value === null || value === void 0) {
|
|
8438
|
-
return "";
|
|
8439
|
-
}
|
|
8440
|
-
return String(value);
|
|
8441
|
-
}
|
|
8442
|
-
function slugify(value) {
|
|
8443
|
-
return value.normalize("NFKD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
8444
|
-
}
|
|
8445
|
-
function buildStelHandle(...candidates) {
|
|
8446
|
-
for (const candidate of candidates) {
|
|
8447
|
-
if (candidate === null || candidate === void 0) {
|
|
8448
|
-
continue;
|
|
8449
|
-
}
|
|
8450
|
-
const normalized = slugify(String(candidate).trim());
|
|
8451
|
-
if (normalized) {
|
|
8452
|
-
return normalized;
|
|
5634
|
+
const normalized = slugify(String(candidate).trim());
|
|
5635
|
+
if (normalized) {
|
|
5636
|
+
return normalized;
|
|
8453
5637
|
}
|
|
8454
5638
|
}
|
|
8455
5639
|
return "stel-item";
|
|
@@ -10425,6 +7609,16 @@ var MockProvider = class {
|
|
|
10425
7609
|
};
|
|
10426
7610
|
|
|
10427
7611
|
// src/factory/index.ts
|
|
7612
|
+
var registry = /* @__PURE__ */ new Map();
|
|
7613
|
+
function registerProvider(type, factory) {
|
|
7614
|
+
registry.set(type, factory);
|
|
7615
|
+
}
|
|
7616
|
+
function getRegisteredProviders() {
|
|
7617
|
+
return Array.from(registry.keys());
|
|
7618
|
+
}
|
|
7619
|
+
registerProvider("mock", (config) => new MockProvider(config));
|
|
7620
|
+
registerProvider("medusa", (config) => new MedusaProvider(config));
|
|
7621
|
+
registerProvider("stelorder", (config) => new StelOrderProvider(config));
|
|
10428
7622
|
function createProvider(options) {
|
|
10429
7623
|
if (!options || !options.provider) {
|
|
10430
7624
|
throw new ConfigurationError("Provider type is required");
|
|
@@ -10432,27 +7626,14 @@ function createProvider(options) {
|
|
|
10432
7626
|
if (!options.config) {
|
|
10433
7627
|
throw new ConfigurationError("Provider configuration is required");
|
|
10434
7628
|
}
|
|
10435
|
-
const
|
|
10436
|
-
|
|
10437
|
-
|
|
10438
|
-
|
|
10439
|
-
|
|
10440
|
-
|
|
10441
|
-
case "stelorder":
|
|
10442
|
-
return new StelOrderProvider(config);
|
|
10443
|
-
case "shopify":
|
|
10444
|
-
return new ShopifyProvider(config);
|
|
10445
|
-
case "bigcommerce":
|
|
10446
|
-
return new BigCommerceProvider(config);
|
|
10447
|
-
case "woocommerce":
|
|
10448
|
-
return new WooCommerceProvider(config);
|
|
10449
|
-
case "spree":
|
|
10450
|
-
return new SpreeProvider(config);
|
|
10451
|
-
case "magento":
|
|
10452
|
-
return new MagentoProvider(config);
|
|
10453
|
-
default:
|
|
10454
|
-
throw new ProviderNotFoundError(String(options.provider));
|
|
7629
|
+
const factory = registry.get(options.provider);
|
|
7630
|
+
if (!factory) {
|
|
7631
|
+
const available = getRegisteredProviders().join(", ");
|
|
7632
|
+
throw new ProviderNotFoundError(
|
|
7633
|
+
`Provider "${options.provider}" is not registered. Available: ${available}. Did you forget to import the provider package?`
|
|
7634
|
+
);
|
|
10455
7635
|
}
|
|
7636
|
+
return factory(options.config);
|
|
10456
7637
|
}
|
|
10457
7638
|
function isProviderType(provider, type) {
|
|
10458
7639
|
return provider.name === type;
|
|
@@ -10460,8 +7641,6 @@ function isProviderType(provider, type) {
|
|
|
10460
7641
|
export {
|
|
10461
7642
|
AdminAuthService,
|
|
10462
7643
|
AdminSessionService,
|
|
10463
|
-
BIGCOMMERCE_CAPABILITIES,
|
|
10464
|
-
BigCommerceProvider,
|
|
10465
7644
|
CHANNEL_ASSIGNED_AT_KEY,
|
|
10466
7645
|
CHANNEL_ASSIGNED_BY_KEY,
|
|
10467
7646
|
CHANNEL_SCOPE_KEY,
|
|
@@ -10470,10 +7649,8 @@ export {
|
|
|
10470
7649
|
CircuitBreakerOpenError,
|
|
10471
7650
|
CommerceError,
|
|
10472
7651
|
ConfigurationError,
|
|
10473
|
-
MAGENTO_CAPABILITIES,
|
|
10474
7652
|
MEDUSA_CAPABILITIES,
|
|
10475
7653
|
MOCK_CAPABILITIES,
|
|
10476
|
-
MagentoProvider,
|
|
10477
7654
|
MedusaMetadataAdapter,
|
|
10478
7655
|
MedusaProvider,
|
|
10479
7656
|
MetricsService,
|
|
@@ -10481,15 +7658,9 @@ export {
|
|
|
10481
7658
|
ProviderAPIError,
|
|
10482
7659
|
ProviderNotFoundError,
|
|
10483
7660
|
ResourceNotFoundError,
|
|
10484
|
-
SHOPIFY_CAPABILITIES,
|
|
10485
|
-
SPREE_CAPABILITIES,
|
|
10486
7661
|
STELORDER_CAPABILITIES,
|
|
10487
|
-
ShopifyProvider,
|
|
10488
|
-
SpreeProvider,
|
|
10489
7662
|
StelOrderProvider,
|
|
10490
7663
|
StorefrontConfigError2 as StorefrontConfigError,
|
|
10491
|
-
WOOCOMMERCE_CAPABILITIES,
|
|
10492
|
-
WooCommerceProvider,
|
|
10493
7664
|
assertEntityBelongsToChannel,
|
|
10494
7665
|
backendCircuitBreaker,
|
|
10495
7666
|
buildChannelScopeMetadata,
|
|
@@ -10497,12 +7668,15 @@ export {
|
|
|
10497
7668
|
createBackendMetadataAdapter,
|
|
10498
7669
|
createLogger,
|
|
10499
7670
|
createProvider,
|
|
7671
|
+
extractErrorMessage,
|
|
7672
|
+
fetchWithRetry,
|
|
10500
7673
|
filterByChannel,
|
|
10501
7674
|
filterGlobalOnly,
|
|
10502
7675
|
geocodeAddress,
|
|
10503
7676
|
getBackendProviderId,
|
|
10504
7677
|
getCapabilityDescription,
|
|
10505
7678
|
getChannelScope,
|
|
7679
|
+
getRegisteredProviders,
|
|
10506
7680
|
isBackendCapabilities,
|
|
10507
7681
|
isGlobalEntity,
|
|
10508
7682
|
isProviderType,
|
|
@@ -10512,6 +7686,7 @@ export {
|
|
|
10512
7686
|
numberToMoney,
|
|
10513
7687
|
partitionByChannel,
|
|
10514
7688
|
planFulfillment,
|
|
7689
|
+
registerProvider,
|
|
10515
7690
|
transformFulfillmentOption,
|
|
10516
7691
|
transformInventoryLevel,
|
|
10517
7692
|
transformStockLocation,
|