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