@thorprovider/adapters 3.0.2

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.
Files changed (95) hide show
  1. package/.turbo/turbo-build.log +18 -0
  2. package/.turbo/turbo-test.log +1 -0
  3. package/.turbo/turbo-type-check.log +0 -0
  4. package/AGENTS.md +1 -0
  5. package/CHANGELOG.md +271 -0
  6. package/README.md +634 -0
  7. package/dist/.tsbuildinfo +1 -0
  8. package/dist/index.d.mts +2524 -0
  9. package/dist/index.d.ts +2524 -0
  10. package/dist/index.js +8136 -0
  11. package/dist/index.js.map +1 -0
  12. package/dist/index.mjs +8045 -0
  13. package/dist/index.mjs.map +1 -0
  14. package/docs/RETRY_SOLUTION_SUMMARY.md +55 -0
  15. package/docs/authentication.md +165 -0
  16. package/docs/capabilities-system.md +143 -0
  17. package/docs/category-customization.md +309 -0
  18. package/docs/fetch-reliability-solution.md +399 -0
  19. package/docs/getting-started.md +154 -0
  20. package/docs/multi-tenant-channel-scoping.md +225 -0
  21. package/docs/profile-management.md +147 -0
  22. package/docs/providers-overview.md +85 -0
  23. package/docs/services-overview.md +135 -0
  24. package/docs/update-documentation.md +113 -0
  25. package/package.json +43 -0
  26. package/publish.log +93 -0
  27. package/quick-reference.md +169 -0
  28. package/src/admin/AdminAuthService.ts +88 -0
  29. package/src/admin/AdminSessionService.ts +91 -0
  30. package/src/admin/MetricsService.ts +145 -0
  31. package/src/admin/index.ts +13 -0
  32. package/src/backend/BackendMetadataAdapter.ts +88 -0
  33. package/src/backend/factory.ts +107 -0
  34. package/src/backend/index.ts +12 -0
  35. package/src/backend/medusa/MedusaMetadataAdapter.ts +139 -0
  36. package/src/core/errors.js +161 -0
  37. package/src/core/errors.ts +132 -0
  38. package/src/core/fetch-utils.js +240 -0
  39. package/src/core/fetch-utils.ts +227 -0
  40. package/src/core/index.ts +8 -0
  41. package/src/core/logger.js +63 -0
  42. package/src/core/logger.ts +37 -0
  43. package/src/factory/index.ts +102 -0
  44. package/src/index.ts +205 -0
  45. package/src/lib/money-transform.ts +80 -0
  46. package/src/metadata/channel-scope-validation.js +136 -0
  47. package/src/metadata/channel-scope-validation.ts +151 -0
  48. package/src/metadata/channel-scope.js +174 -0
  49. package/src/metadata/channel-scope.ts +215 -0
  50. package/src/metadata/index.js +31 -0
  51. package/src/metadata/index.ts +37 -0
  52. package/src/providers/bigcommerce/bigcommerce.ts +6 -0
  53. package/src/providers/bigcommerce/index.ts +315 -0
  54. package/src/providers/bigcommerce/transforms.ts +227 -0
  55. package/src/providers/index.ts +22 -0
  56. package/src/providers/magento/index.ts +387 -0
  57. package/src/providers/magento/magento.ts +5 -0
  58. package/src/providers/magento/queries.ts +267 -0
  59. package/src/providers/magento/transforms.ts +249 -0
  60. package/src/providers/medusa/auth.js +601 -0
  61. package/src/providers/medusa/auth.ts +496 -0
  62. package/src/providers/medusa/fulfillment-planner.ts +225 -0
  63. package/src/providers/medusa/index.js +2485 -0
  64. package/src/providers/medusa/index.ts +4239 -0
  65. package/src/providers/medusa/medusa.ts +8 -0
  66. package/src/providers/medusa/payment.js +265 -0
  67. package/src/providers/medusa/payment.ts +269 -0
  68. package/src/providers/medusa/transforms.js +505 -0
  69. package/src/providers/medusa/transforms.ts +625 -0
  70. package/src/providers/shopify/index.ts +444 -0
  71. package/src/providers/shopify/mutations.ts +102 -0
  72. package/src/providers/shopify/queries.ts +324 -0
  73. package/src/providers/shopify/shopify.ts +7 -0
  74. package/src/providers/shopify/transforms.ts +270 -0
  75. package/src/providers/spree/index.ts +344 -0
  76. package/src/providers/spree/spree.ts +5 -0
  77. package/src/providers/spree/transforms.ts +254 -0
  78. package/src/providers/woocommerce/index.ts +310 -0
  79. package/src/providers/woocommerce/transforms.ts +254 -0
  80. package/src/providers/woocommerce/woocommerce.ts +5 -0
  81. package/src/resilience/README.md +299 -0
  82. package/src/resilience/circuit-breaker.ts +222 -0
  83. package/src/resilience/index.ts +10 -0
  84. package/src/types/capabilities.types.js +141 -0
  85. package/src/types/capabilities.types.ts +366 -0
  86. package/src/types/index.ts +24 -0
  87. package/src/types/provider.js +9 -0
  88. package/src/types/provider.ts +9 -0
  89. package/src/types/ui-responses.ts +261 -0
  90. package/src/utils/city-coordinates.ts +40 -0
  91. package/src/utils/geolocation.ts +52 -0
  92. package/src/utils/payment-utils.js +152 -0
  93. package/src/utils/payment-utils.ts +203 -0
  94. package/tsconfig.json +15 -0
  95. package/tsup.config.ts +14 -0
@@ -0,0 +1,249 @@
1
+ /**
2
+ * Adobe Commerce (Magento) Transform Functions
3
+ * Converts Magento GraphQL / REST API responses to @thorprovider/types
4
+ *
5
+ * Magento returns price as { regularPrice: { amount: { value, currency } } }
6
+ * Images have url + label directly.
7
+ */
8
+
9
+ import type { Product, ProductVariant, ProductOption, Image, Collection, Cart, CartItem, Order, OrderItem, Customer, Address, Money } from '@thorprovider/types';
10
+
11
+ // ============================================
12
+ // Money / Price Helpers
13
+ // ============================================
14
+
15
+ function toMoney(value: number | undefined, currencyCode: string): Money {
16
+ return { amount: (value ?? 0).toFixed(2), currencyCode };
17
+ }
18
+
19
+ function extractPrice(priceRange: any, currencyCode: string): { min: Money; max: Money } {
20
+ const minPrice = priceRange?.minimum_price?.regular_price?.value ?? priceRange?.minimum_price?.final_price?.value ?? 0;
21
+ const maxPrice = priceRange?.maximum_price?.regular_price?.value ?? priceRange?.maximum_price?.final_price?.value ?? minPrice;
22
+ const currency = priceRange?.minimum_price?.regular_price?.currency ?? currencyCode;
23
+ return {
24
+ min: toMoney(minPrice, currency),
25
+ max: toMoney(maxPrice, currency),
26
+ };
27
+ }
28
+
29
+ // ============================================
30
+ // Product Transforms
31
+ // ============================================
32
+
33
+ export function transformProduct(data: any, currencyCode: string = 'USD'): Product {
34
+ const id = String(data.id ?? data.uid ?? '');
35
+ const { min, max } = extractPrice(data.price_range, currencyCode);
36
+
37
+ // Images
38
+ const images: Image[] = (data.media_gallery ?? data.media_gallery_entries ?? []).map((img: any) => ({
39
+ url: img.url ?? (img.file ? `${img.file}` : ''),
40
+ altText: img.label ?? data.name ?? '',
41
+ width: undefined,
42
+ height: undefined,
43
+ }));
44
+
45
+ // Small image fallback
46
+ if (images.length === 0 && data.small_image?.url) {
47
+ images.push({ url: data.small_image.url, altText: data.small_image.label ?? data.name ?? '' });
48
+ }
49
+ if (images.length === 0 && data.image?.url) {
50
+ images.push({ url: data.image.url, altText: data.image.label ?? data.name ?? '' });
51
+ }
52
+
53
+ // Variants from configurable_options / variants
54
+ const variants: ProductVariant[] = [];
55
+ if (data.variants && Array.isArray(data.variants)) {
56
+ for (const v of data.variants) {
57
+ const product = v.product ?? {};
58
+ const vPrice = product.price_range?.minimum_price?.final_price ?? {};
59
+ variants.push({
60
+ id: String(product.id ?? product.uid ?? product.sku ?? ''),
61
+ title: product.name ?? product.sku ?? '',
62
+ availableForSale: product.stock_status === 'IN_STOCK',
63
+ price: toMoney(vPrice.value ?? min.amount, vPrice.currency ?? currencyCode),
64
+ compareAtPrice: undefined,
65
+ selectedOptions: (v.attributes ?? []).map((attr: any) => ({
66
+ name: attr.label ?? '',
67
+ value: attr.value_index != null ? String(attr.value_index) : '',
68
+ })),
69
+ });
70
+ }
71
+ }
72
+
73
+ // Default variant if simple product
74
+ if (variants.length === 0) {
75
+ variants.push({
76
+ id: data.sku ?? id,
77
+ title: data.name ?? '',
78
+ availableForSale: data.stock_status === 'IN_STOCK',
79
+ price: min,
80
+ compareAtPrice: undefined,
81
+ selectedOptions: [],
82
+ });
83
+ }
84
+
85
+ // Options
86
+ const options: ProductOption[] = (data.configurable_options ?? []).map((opt: any) => ({
87
+ id: String(opt.attribute_id ?? opt.attribute_code ?? ''),
88
+ name: opt.label ?? opt.attribute_code ?? '',
89
+ values: (opt.values ?? []).map((v: any) => v.label ?? v.store_label ?? String(v.value_index ?? '')),
90
+ }));
91
+
92
+ return {
93
+ id,
94
+ handle: data.url_key ?? data.sku ?? id,
95
+ title: data.name ?? '',
96
+ description: data.short_description?.html ?? data.description?.html ?? '',
97
+ descriptionHtml: data.description?.html ?? '',
98
+ availableForSale: data.stock_status === 'IN_STOCK',
99
+ priceRange: { minVariantPrice: min, maxVariantPrice: max },
100
+ variants,
101
+ options,
102
+ images,
103
+ featuredImage: images[0] ?? { url: '', altText: data.name ?? '' },
104
+ tags: [],
105
+ seo: {
106
+ title: data.meta_title ?? data.name ?? '',
107
+ description: data.meta_description ?? '',
108
+ },
109
+ updatedAt: data.updated_at ?? new Date().toISOString(),
110
+ createdAt: data.created_at ?? new Date().toISOString(),
111
+ };
112
+ }
113
+
114
+ // ============================================
115
+ // Collection Transforms (Magento Categories)
116
+ // ============================================
117
+
118
+ export function transformCollection(data: any): Collection {
119
+ return {
120
+ id: String(data.id ?? data.uid ?? ''),
121
+ handle: data.url_key ?? data.url_path ?? String(data.id ?? data.uid ?? ''),
122
+ title: data.name ?? '',
123
+ description: data.description ?? '',
124
+ seo: {
125
+ title: data.meta_title ?? data.name ?? '',
126
+ description: data.meta_description ?? '',
127
+ },
128
+ updatedAt: data.updated_at ?? new Date().toISOString(),
129
+ path: `/collections/${data.url_key ?? data.url_path ?? data.id}`,
130
+ };
131
+ }
132
+
133
+ // ============================================
134
+ // Cart Transforms (Magento Cart / Quote)
135
+ // ============================================
136
+
137
+ export function transformCart(data: any, currencyCode: string = 'USD'): Cart {
138
+ const items: CartItem[] = (data.items ?? []).map((item: any): CartItem => {
139
+ const product = item.product ?? {};
140
+ const priceVal = item.prices?.price?.value ?? product.price_range?.minimum_price?.final_price?.value ?? 0;
141
+ const totalVal = item.prices?.row_total?.value ?? priceVal * (item.quantity ?? 1);
142
+
143
+ return {
144
+ id: String(item.id ?? item.uid ?? ''),
145
+ quantity: item.quantity ?? 1,
146
+ cost: {
147
+ totalAmount: toMoney(totalVal, item.prices?.price?.currency ?? currencyCode),
148
+ },
149
+ merchandise: {
150
+ id: String(product.sku ?? item.id ?? ''),
151
+ title: product.name ?? item.product?.name ?? '',
152
+ selectedOptions: (item.configurable_options ?? []).map((opt: any) => ({
153
+ name: opt.option_label ?? '',
154
+ value: opt.value_label ?? '',
155
+ })),
156
+ product: {
157
+ id: String(product.id ?? product.uid ?? ''),
158
+ handle: product.url_key ?? '',
159
+ title: product.name ?? '',
160
+ featuredImage: {
161
+ url: product.small_image?.url ?? product.thumbnail?.url ?? '',
162
+ altText: product.name ?? '',
163
+ },
164
+ },
165
+ },
166
+ };
167
+ });
168
+
169
+ const totalVal = data.prices?.grand_total?.value ?? 0;
170
+ const subtotalVal = data.prices?.subtotal_excluding_tax?.value ?? data.prices?.subtotal_including_tax?.value ?? totalVal;
171
+ const taxVal = (data.prices?.applied_taxes ?? []).reduce((sum: number, t: any) => sum + (t.amount?.value ?? 0), 0);
172
+
173
+ return {
174
+ id: String(data.id ?? ''),
175
+ checkoutUrl: '',
176
+ totalQuantity: items.reduce((sum, i) => sum + i.quantity, 0),
177
+ cost: {
178
+ subtotalAmount: toMoney(subtotalVal, data.prices?.grand_total?.currency ?? currencyCode),
179
+ totalAmount: toMoney(totalVal, data.prices?.grand_total?.currency ?? currencyCode),
180
+ totalTaxAmount: toMoney(taxVal, currencyCode),
181
+ },
182
+ lines: items,
183
+ };
184
+ }
185
+
186
+ // ============================================
187
+ // Customer Transforms
188
+ // ============================================
189
+
190
+ export function transformCustomer(data: any): Customer {
191
+ return {
192
+ id: String(data.id ?? ''),
193
+ email: data.email ?? '',
194
+ firstName: data.firstname ?? data.first_name ?? '',
195
+ lastName: data.lastname ?? data.last_name ?? '',
196
+ phone: data.phone ?? '',
197
+ hasAccount: true,
198
+ };
199
+ }
200
+
201
+ function transformAddress(addr: any): Address {
202
+ return {
203
+ id: String(addr.id ?? ''),
204
+ firstName: addr.firstname ?? '',
205
+ lastName: addr.lastname ?? '',
206
+ company: addr.company ?? '',
207
+ address1: Array.isArray(addr.street) ? addr.street[0] ?? '' : addr.street ?? '',
208
+ address2: Array.isArray(addr.street) ? addr.street[1] ?? '' : '',
209
+ city: addr.city ?? '',
210
+ province: addr.region?.region ?? '',
211
+ postalCode: addr.postcode ?? '',
212
+ countryCode: addr.country_code ?? addr.country_id ?? '',
213
+ phone: addr.telephone ?? '',
214
+ };
215
+ }
216
+
217
+ // ============================================
218
+ // Order Transforms
219
+ // ============================================
220
+
221
+ export function transformOrder(data: any, currencyCode: string = 'USD'): Order {
222
+ const items: OrderItem[] = (data.items ?? []).map((item: any) => ({
223
+ id: String(item.id ?? ''),
224
+ title: item.product_name ?? '',
225
+ quantity: item.quantity_ordered ?? item.quantity ?? 1,
226
+ price: toMoney(item.product_sale_price?.value ?? item.price ?? 0, currencyCode),
227
+ total: toMoney((item.product_sale_price?.value ?? item.price ?? 0) * (item.quantity_ordered ?? item.quantity ?? 1), currencyCode),
228
+ sku: item.product_sku ?? item.sku,
229
+ productId: String(item.product_id ?? ''),
230
+ }));
231
+
232
+ return {
233
+ id: String(data.id ?? data.order_number ?? ''),
234
+ orderNumber: data.order_number ?? data.number ?? String(data.id ?? ''),
235
+ email: data.email ?? '',
236
+ status: (data.status === 'complete' ? 'completed' : data.status === 'canceled' ? 'cancelled' : data.status === 'closed' ? 'refunded' : 'pending') as any,
237
+ paymentStatus: (data.payment_status === 'paid' ? 'paid' : 'pending') as any,
238
+ fulfillmentStatus: (data.shipment_status === 'shipped' ? 'fulfilled' : 'unfulfilled') as any,
239
+ items,
240
+ total: toMoney(data.total?.grand_total?.value ?? data.grand_total ?? 0, currencyCode),
241
+ subtotal: toMoney(data.total?.subtotal?.value ?? data.subtotal ?? 0, currencyCode),
242
+ tax: toMoney(data.total?.total_tax?.value ?? data.tax_amount ?? 0, currencyCode),
243
+ shipping: toMoney(data.total?.total_shipping?.value ?? data.shipping_amount ?? 0, currencyCode),
244
+ shippingAddress: data.shipping_address ? transformAddress(data.shipping_address) : undefined,
245
+ billingAddress: data.billing_address ? transformAddress(data.billing_address) : undefined,
246
+ createdAt: data.order_date ?? data.created_at ?? new Date().toISOString(),
247
+ updatedAt: data.updated_at ?? data.order_date ?? new Date().toISOString(),
248
+ };
249
+ }