@thorprovider/adapters 4.2.0 → 4.2.1

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.
@@ -0,0 +1,631 @@
1
+ import type {
2
+ Collection,
3
+ Customer,
4
+ Address,
5
+ FulfillmentStatus,
6
+ Image,
7
+ InventoryLevel,
8
+ Money,
9
+ Order,
10
+ OrderItem,
11
+ OrderStatus,
12
+ PaymentMethod,
13
+ PaymentMethodType,
14
+ PaymentStatus,
15
+ Product,
16
+ ProductCategory,
17
+ ProductVariant,
18
+ ShippingMethod,
19
+ StockLocation,
20
+ } from '@thorprovider/types';
21
+
22
+ export interface StelResource {
23
+ id?: number;
24
+ path?: string;
25
+ deleted?: boolean;
26
+ 'utc-last-modification-date'?: string;
27
+ }
28
+
29
+ export interface StelItemImage {
30
+ 'item-image-path'?: string;
31
+ order?: number;
32
+ }
33
+
34
+ export interface StelItemRate {
35
+ 'rate-id'?: number;
36
+ 'rate-path'?: string;
37
+ price?: number;
38
+ }
39
+
40
+ export interface StelProductWarehouse {
41
+ 'warehouse-id'?: number;
42
+ 'warehouse-path'?: string;
43
+ 'minimum-stock'?: number;
44
+ 'real-stock'?: number;
45
+ 'virtual-stock'?: number;
46
+ location?: string;
47
+ }
48
+
49
+ export interface StelProduct extends StelResource {
50
+ name?: string;
51
+ description?: string;
52
+ reference?: string;
53
+ 'full-reference'?: string;
54
+ barcode?: string;
55
+ 'sales-price'?: number;
56
+ 'purchase-price'?: number;
57
+ 'product-category-id'?: number;
58
+ 'product-category-path'?: string;
59
+ 'real-stock'?: number;
60
+ 'virtual-stock'?: number;
61
+ 'minimum-stock'?: number;
62
+ 'stock-enabled'?: boolean;
63
+ inactive?: boolean;
64
+ promotional?: boolean;
65
+ 'creation-date'?: string;
66
+ 'item-images'?: StelItemImage[];
67
+ 'item-rates'?: StelItemRate[];
68
+ 'product-warehouses'?: StelProductWarehouse[];
69
+ }
70
+
71
+ export interface StelProductCategory extends StelResource {
72
+ name?: string;
73
+ description?: string;
74
+ slug?: string;
75
+ 'parent-category-id'?: number;
76
+ }
77
+
78
+ export interface StelClient extends StelResource {
79
+ name?: string;
80
+ 'business-name'?: string;
81
+ email?: string;
82
+ phone?: string;
83
+ mobile?: string;
84
+ 'rate-id'?: number;
85
+ 'payment-option-id'?: number;
86
+ 'payment-term-id'?: number;
87
+ 'delivery-option-id'?: number;
88
+ 'main-address'?: StelAddress;
89
+ }
90
+
91
+ export interface StelAddress extends StelResource {
92
+ name?: string;
93
+ 'first-name'?: string;
94
+ 'last-name'?: string;
95
+ company?: string;
96
+ 'address-data'?: string;
97
+ 'postal-code'?: string;
98
+ 'city-town'?: string;
99
+ province?: string;
100
+ 'country-code'?: string;
101
+ phone?: string;
102
+ email?: string;
103
+ }
104
+
105
+ export interface StelDocumentLine {
106
+ 'item-id'?: number;
107
+ 'item-name'?: string;
108
+ 'item-description'?: string;
109
+ 'item-base-price'?: number;
110
+ 'primary-tax-percentage'?: number;
111
+ 'discount-percentage'?: number;
112
+ units?: number;
113
+ 'line-type'?: 'ITEM' | 'DOCUMENT' | 'SECTION' | 'COMPONENT';
114
+ }
115
+
116
+ export interface StelSalesOrder extends StelResource {
117
+ reference?: string;
118
+ status?: string;
119
+ email?: string;
120
+ 'client-id'?: number;
121
+ 'payment-option-id'?: number;
122
+ 'payment-term-id'?: number;
123
+ 'delivery-option-id'?: number;
124
+ 'creation-date'?: string;
125
+ 'total-base'?: number;
126
+ 'total-tax'?: number;
127
+ total?: number;
128
+ 'document-lines'?: StelDocumentLine[];
129
+ }
130
+
131
+ export interface StelPaymentOption extends StelResource {
132
+ name?: string;
133
+ description?: string;
134
+ }
135
+
136
+ export interface StelPaymentTerm extends StelResource {
137
+ name?: string;
138
+ description?: string;
139
+ }
140
+
141
+ export interface StelDeliveryOption extends StelResource {
142
+ name?: string;
143
+ description?: string;
144
+ }
145
+
146
+ export interface StelWarehouse extends StelResource {
147
+ name?: string;
148
+ description?: string;
149
+ }
150
+
151
+ export function normalizeStelCollection<T>(payload: T | T[] | null | undefined): T[] {
152
+ if (!payload) {
153
+ return [];
154
+ }
155
+
156
+ return Array.isArray(payload) ? payload : [payload];
157
+ }
158
+
159
+ export function normalizeStelEntity<T>(payload: T | T[] | null | undefined): T | undefined {
160
+ if (!payload) {
161
+ return undefined;
162
+ }
163
+
164
+ return Array.isArray(payload) ? payload[0] : payload;
165
+ }
166
+
167
+ export function transformStelMoney(
168
+ amount: number | string | null | undefined,
169
+ currencyCode: string = 'USD',
170
+ ): Money {
171
+ const normalizedAmount = typeof amount === 'string' ? Number.parseFloat(amount) : amount ?? 0;
172
+
173
+ return {
174
+ amount: Number.isFinite(normalizedAmount) ? normalizedAmount.toFixed(2) : '0.00',
175
+ currencyCode: currencyCode.toUpperCase(),
176
+ };
177
+ }
178
+
179
+ export function transformStelImage(url: string | null | undefined, altText: string = ''): Image | undefined {
180
+ const normalizedUrl = url?.trim();
181
+
182
+ if (!normalizedUrl) {
183
+ return undefined;
184
+ }
185
+
186
+ return {
187
+ url: normalizedUrl,
188
+ altText,
189
+ width: 800,
190
+ height: 800,
191
+ };
192
+ }
193
+
194
+ export function normalizeStelDate(value: string | null | undefined): string {
195
+ if (!value) {
196
+ return new Date().toISOString();
197
+ }
198
+
199
+ const parsed = new Date(value);
200
+ return Number.isNaN(parsed.getTime()) ? new Date().toISOString() : parsed.toISOString();
201
+ }
202
+
203
+ export function extractStelIdFromPath(path: string | null | undefined): string | undefined {
204
+ if (!path) {
205
+ return undefined;
206
+ }
207
+
208
+ const match = path.match(/\/([^/]+)$/);
209
+ return match?.[1];
210
+ }
211
+
212
+ export function toStelStringId(value: string | number | null | undefined): string {
213
+ if (value === null || value === undefined) {
214
+ return '';
215
+ }
216
+
217
+ return String(value);
218
+ }
219
+
220
+ function slugify(value: string): string {
221
+ return value
222
+ .normalize('NFKD')
223
+ .replace(/[\u0300-\u036f]/g, '')
224
+ .toLowerCase()
225
+ .replace(/[^a-z0-9]+/g, '-')
226
+ .replace(/^-+|-+$/g, '');
227
+ }
228
+
229
+ export function buildStelHandle(...candidates: Array<string | number | null | undefined>): string {
230
+ for (const candidate of candidates) {
231
+ if (candidate === null || candidate === undefined) {
232
+ continue;
233
+ }
234
+
235
+ const normalized = slugify(String(candidate).trim());
236
+ if (normalized) {
237
+ return normalized;
238
+ }
239
+ }
240
+
241
+ return 'stel-item';
242
+ }
243
+
244
+ // ---------------------------------------------------------------------------
245
+ // Product transforms
246
+ // ---------------------------------------------------------------------------
247
+
248
+ function transformStelProductImages(product: StelProduct): Image[] {
249
+ const images: Image[] = [];
250
+
251
+ if (!product['item-images']) {
252
+ return images;
253
+ }
254
+
255
+ const sorted = [...product['item-images']].sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
256
+
257
+ for (const img of sorted) {
258
+ const transformed = transformStelImage(img['item-image-path'], product.name ?? '');
259
+ if (transformed) {
260
+ images.push(transformed);
261
+ }
262
+ }
263
+
264
+ return images;
265
+ }
266
+
267
+ function deriveStelStockStatus(product: StelProduct): 'in_stock' | 'out_of_stock' | 'low_stock' {
268
+ if (!product['stock-enabled']) {
269
+ return 'in_stock';
270
+ }
271
+
272
+ const realStock = product['real-stock'] ?? 0;
273
+ const minimumStock = product['minimum-stock'] ?? 0;
274
+
275
+ if (realStock <= 0) {
276
+ return 'out_of_stock';
277
+ }
278
+
279
+ if (realStock <= minimumStock) {
280
+ return 'low_stock';
281
+ }
282
+
283
+ return 'in_stock';
284
+ }
285
+
286
+ /**
287
+ * Build a single synthetic variant from a STEL product.
288
+ * STEL products have no variant concept — every product is a single SKU.
289
+ */
290
+ function buildSyntheticVariant(product: StelProduct, currencyCode: string): ProductVariant {
291
+ const price = transformStelMoney(product['sales-price'], currencyCode);
292
+ const stockStatus = deriveStelStockStatus(product);
293
+ const quantityAvailable = product['stock-enabled'] ? (product['real-stock'] ?? 0) : undefined;
294
+ const image = product['item-images']?.[0]
295
+ ? transformStelImage(product['item-images'][0]['item-image-path'], product.name ?? '')
296
+ : undefined;
297
+
298
+ return {
299
+ id: toStelStringId(product.id),
300
+ title: 'Default',
301
+ sku: product.barcode ?? product['full-reference'] ?? undefined,
302
+ availableForSale: stockStatus !== 'out_of_stock',
303
+ selectedOptions: [],
304
+ price,
305
+ compareAtPrice: undefined,
306
+ quantityAvailable,
307
+ stockStatus,
308
+ image,
309
+ };
310
+ }
311
+
312
+ export function transformStelProduct(raw: StelProduct, currencyCode: string): Product {
313
+ const id = toStelStringId(raw.id);
314
+ const handle = buildStelHandle(raw['full-reference'], raw.reference, raw.name, raw.id);
315
+ const price = transformStelMoney(raw['sales-price'], currencyCode);
316
+ const images = transformStelProductImages(raw);
317
+ const variant = buildSyntheticVariant(raw, currencyCode);
318
+ const now = new Date().toISOString();
319
+
320
+ return {
321
+ id,
322
+ handle,
323
+ title: raw.name ?? '',
324
+ description: raw.description ?? '',
325
+ availableForSale: variant.availableForSale,
326
+ options: [],
327
+ variants: [variant],
328
+ featuredImage: images[0],
329
+ images,
330
+ priceRange: {
331
+ minVariantPrice: price,
332
+ maxVariantPrice: price,
333
+ },
334
+ productType: undefined,
335
+ vendor: undefined,
336
+ tags: raw.promotional ? ['promotional'] : [],
337
+ createdAt: normalizeStelDate(raw['creation-date']),
338
+ updatedAt: normalizeStelDate(raw['utc-last-modification-date']) || now,
339
+ metadata: {
340
+ stelFullReference: raw['full-reference'],
341
+ stelReference: raw.reference,
342
+ stelBarcode: raw.barcode,
343
+ stelCategoryId: raw['product-category-id'],
344
+ stelInactive: raw.inactive,
345
+ stelPromotional: raw.promotional,
346
+ stelPurchasePrice: raw['purchase-price'],
347
+ },
348
+ };
349
+ }
350
+
351
+ // ---------------------------------------------------------------------------
352
+ // Category transforms
353
+ // ---------------------------------------------------------------------------
354
+
355
+ export function transformStelCategory(raw: StelProductCategory): ProductCategory {
356
+ const id = toStelStringId(raw.id);
357
+ const handle = buildStelHandle(raw.slug, raw.name, raw.id);
358
+
359
+ return {
360
+ id,
361
+ name: raw.name ?? '',
362
+ handle,
363
+ description: raw.description ?? undefined,
364
+ parentCategoryId: raw['parent-category-id']
365
+ ? toStelStringId(raw['parent-category-id'])
366
+ : undefined,
367
+ metadata: {
368
+ stelSlug: raw.slug,
369
+ },
370
+ };
371
+ }
372
+
373
+ // ---------------------------------------------------------------------------
374
+ // Collection transforms (alias categories as collections)
375
+ // ---------------------------------------------------------------------------
376
+
377
+ export function transformStelCategoryToCollection(raw: StelProductCategory): Collection {
378
+ const id = toStelStringId(raw.id);
379
+ const handle = buildStelHandle(raw.slug, raw.name, raw.id);
380
+
381
+ return {
382
+ id,
383
+ handle,
384
+ title: raw.name ?? '',
385
+ description: raw.description ?? '',
386
+ path: `/collections/${handle}`,
387
+ updatedAt: normalizeStelDate(raw['utc-last-modification-date']),
388
+ };
389
+ }
390
+
391
+ // ---------------------------------------------------------------------------
392
+ // Inventory / warehouse transforms
393
+ // ---------------------------------------------------------------------------
394
+
395
+ export function transformStelWarehouseToStockLocation(raw: StelWarehouse): StockLocation {
396
+ return {
397
+ id: toStelStringId(raw.id),
398
+ name: raw.name ?? 'Warehouse',
399
+ };
400
+ }
401
+
402
+ export function transformStelProductWarehouseToInventoryLevel(
403
+ pw: StelProductWarehouse,
404
+ ): InventoryLevel {
405
+ return {
406
+ locationId: toStelStringId(pw['warehouse-id']),
407
+ locationName: pw['warehouse-path'] ?? `Warehouse ${pw['warehouse-id'] ?? 'unknown'}`,
408
+ availableQuantity: pw['real-stock'] ?? 0,
409
+ reservedQuantity: Math.max(0, (pw['virtual-stock'] ?? 0) - (pw['real-stock'] ?? 0)),
410
+ stockedQuantity: pw['virtual-stock'] ?? pw['real-stock'] ?? 0,
411
+ };
412
+ }
413
+
414
+ // ---------------------------------------------------------------------------
415
+ // Customer / Address transforms
416
+ // ---------------------------------------------------------------------------
417
+
418
+ function splitStelName(fullName: string | null | undefined): { firstName: string; lastName: string } {
419
+ if (!fullName?.trim()) {
420
+ return { firstName: '', lastName: '' };
421
+ }
422
+
423
+ const parts = fullName.trim().split(/\s+/);
424
+ const firstName = parts[0] ?? '';
425
+ const lastName = parts.length > 1 ? parts.slice(1).join(' ') : '';
426
+ return { firstName, lastName };
427
+ }
428
+
429
+ export function transformStelAddress(raw: StelAddress): Address {
430
+ const firstName = raw['first-name'] ?? '';
431
+ const lastName = raw['last-name'] ?? '';
432
+
433
+ // If first/last not present, attempt to split the 'name' field
434
+ const nameParts = !firstName && !lastName ? splitStelName(raw.name) : { firstName, lastName };
435
+
436
+ return {
437
+ id: raw.id ? toStelStringId(raw.id) : undefined,
438
+ firstName: nameParts.firstName,
439
+ lastName: nameParts.lastName,
440
+ company: raw.company ?? undefined,
441
+ address1: raw['address-data'] ?? '',
442
+ city: raw['city-town'] ?? '',
443
+ province: raw.province ?? undefined,
444
+ postalCode: raw['postal-code'] ?? '',
445
+ countryCode: raw['country-code'] ?? '',
446
+ phone: raw.phone ?? undefined,
447
+ isDefault: true,
448
+ metadata: {
449
+ stelEmail: raw.email,
450
+ },
451
+ };
452
+ }
453
+
454
+ export function transformStelClient(raw: StelClient): Customer {
455
+ const { firstName, lastName } = splitStelName(raw.name ?? raw['business-name']);
456
+
457
+ return {
458
+ id: toStelStringId(raw.id),
459
+ email: raw.email ?? '',
460
+ firstName: firstName || null,
461
+ lastName: lastName || null,
462
+ phone: raw.phone ?? raw.mobile ?? null,
463
+ hasAccount: true,
464
+ createdAt: normalizeStelDate(raw['utc-last-modification-date']),
465
+ updatedAt: normalizeStelDate(raw['utc-last-modification-date']),
466
+ metadata: {
467
+ stelBusinessName: raw['business-name'],
468
+ stelRateId: raw['rate-id'],
469
+ stelPaymentOptionId: raw['payment-option-id'],
470
+ stelPaymentTermId: raw['payment-term-id'],
471
+ stelDeliveryOptionId: raw['delivery-option-id'],
472
+ },
473
+ };
474
+ }
475
+
476
+ // ---------------------------------------------------------------------------
477
+ // Order transforms
478
+ // ---------------------------------------------------------------------------
479
+
480
+ function deriveStelOrderStatus(raw: StelSalesOrder): OrderStatus {
481
+ if (raw.deleted) {
482
+ return 'cancelled';
483
+ }
484
+
485
+ const status = (raw.status ?? '').toLowerCase();
486
+
487
+ if (status.includes('cancel') || status.includes('anulad')) {
488
+ return 'cancelled';
489
+ }
490
+ if (status.includes('complet') || status.includes('cerrad') || status.includes('settled')) {
491
+ return 'completed';
492
+ }
493
+ if (status.includes('process') || status.includes('confirm')) {
494
+ return 'processing';
495
+ }
496
+
497
+ return 'pending';
498
+ }
499
+
500
+ function deriveStelPaymentStatus(raw: StelSalesOrder): PaymentStatus {
501
+ const orderStatus = deriveStelOrderStatus(raw);
502
+
503
+ if (orderStatus === 'completed') {
504
+ return 'paid';
505
+ }
506
+ if (orderStatus === 'cancelled') {
507
+ return 'pending';
508
+ }
509
+
510
+ return 'pending';
511
+ }
512
+
513
+ function deriveStelFulfillmentStatus(raw: StelSalesOrder): FulfillmentStatus {
514
+ const orderStatus = deriveStelOrderStatus(raw);
515
+
516
+ if (orderStatus === 'completed') {
517
+ return 'fulfilled';
518
+ }
519
+
520
+ return 'unfulfilled';
521
+ }
522
+
523
+ function transformStelDocumentLine(
524
+ line: StelDocumentLine,
525
+ index: number,
526
+ currencyCode: string,
527
+ ): OrderItem {
528
+ const unitPrice = line['item-base-price'] ?? 0;
529
+ const quantity = line.units ?? 1;
530
+ const lineTotal = unitPrice * quantity;
531
+
532
+ return {
533
+ id: toStelStringId(line['item-id'] ?? index),
534
+ title: line['item-name'] ?? '',
535
+ variantTitle: undefined,
536
+ quantity,
537
+ price: transformStelMoney(unitPrice, currencyCode),
538
+ total: transformStelMoney(lineTotal, currencyCode),
539
+ sku: undefined,
540
+ productId: line['item-id'] ? toStelStringId(line['item-id']) : undefined,
541
+ };
542
+ }
543
+
544
+ export function transformStelSalesOrder(raw: StelSalesOrder, currencyCode: string): Order {
545
+ const id = toStelStringId(raw.id);
546
+ const now = new Date().toISOString();
547
+ const items = (raw['document-lines'] ?? [])
548
+ .filter((line) => line['line-type'] === 'ITEM' || !line['line-type'])
549
+ .map((line, i) => transformStelDocumentLine(line, i, currencyCode));
550
+
551
+ const status = deriveStelOrderStatus(raw);
552
+
553
+ return {
554
+ id,
555
+ orderNumber: raw.reference ?? id,
556
+ email: raw.email ?? '',
557
+ status,
558
+ paymentStatus: deriveStelPaymentStatus(raw),
559
+ fulfillmentStatus: deriveStelFulfillmentStatus(raw),
560
+ customerId: raw['client-id'] ? toStelStringId(raw['client-id']) : undefined,
561
+ items,
562
+ subtotal: transformStelMoney(raw['total-base'], currencyCode),
563
+ total: transformStelMoney(raw.total, currencyCode),
564
+ tax: raw['total-tax'] != null ? transformStelMoney(raw['total-tax'], currencyCode) : undefined,
565
+ createdAt: normalizeStelDate(raw['creation-date']),
566
+ updatedAt: normalizeStelDate(raw['utc-last-modification-date']) || now,
567
+ cancelledAt: status === 'cancelled' ? normalizeStelDate(raw['utc-last-modification-date']) : undefined,
568
+ completedAt: status === 'completed' ? normalizeStelDate(raw['utc-last-modification-date']) : undefined,
569
+ metadata: {
570
+ stelReference: raw.reference,
571
+ stelStatus: raw.status,
572
+ stelPaymentOptionId: raw['payment-option-id'],
573
+ stelPaymentTermId: raw['payment-term-id'],
574
+ stelDeliveryOptionId: raw['delivery-option-id'],
575
+ },
576
+ };
577
+ }
578
+
579
+ // ---------------------------------------------------------------------------
580
+ // Payment / delivery transforms
581
+ // ---------------------------------------------------------------------------
582
+
583
+ function inferPaymentMethodType(name: string | null | undefined): PaymentMethodType {
584
+ if (!name) {
585
+ return 'other';
586
+ }
587
+
588
+ const lower = name.toLowerCase();
589
+
590
+ if (lower.includes('transfer') || lower.includes('bank') || lower.includes('sepa') || lower.includes('iban')) {
591
+ return 'bank_transfer';
592
+ }
593
+ if (lower.includes('card') || lower.includes('tarjeta') || lower.includes('visa') || lower.includes('master')) {
594
+ return 'card';
595
+ }
596
+ if (lower.includes('paypal') || lower.includes('wallet') || lower.includes('apple') || lower.includes('google')) {
597
+ return 'wallet';
598
+ }
599
+ if (lower.includes('cash') || lower.includes('contrar') || lower.includes('efectivo') || lower.includes('cod')) {
600
+ return 'cash_on_delivery';
601
+ }
602
+ if (lower.includes('crypto') || lower.includes('bitcoin')) {
603
+ return 'crypto';
604
+ }
605
+
606
+ return 'other';
607
+ }
608
+
609
+ export function transformStelPaymentOption(raw: StelPaymentOption): PaymentMethod {
610
+ return {
611
+ id: toStelStringId(raw.id),
612
+ name: raw.name ?? 'Payment Option',
613
+ type: inferPaymentMethodType(raw.name),
614
+ isEnabled: !raw.deleted,
615
+ requiresSetup: false,
616
+ description: raw.description ?? undefined,
617
+ metadata: {
618
+ stelPath: raw.path,
619
+ source: 'paymentOption',
620
+ },
621
+ };
622
+ }
623
+
624
+ export function transformStelDeliveryOption(raw: StelDeliveryOption, currencyCode: string): ShippingMethod {
625
+ return {
626
+ id: toStelStringId(raw.id),
627
+ name: raw.name ?? 'Delivery Option',
628
+ price: transformStelMoney(0, currencyCode),
629
+ description: raw.description ?? undefined,
630
+ };
631
+ }
@@ -99,6 +99,57 @@ export const MEDUSA_CAPABILITIES: Readonly<BackendCapabilities> = {
99
99
  loyaltyProgram: false, // Requires custom implementation
100
100
  };
101
101
 
102
+ /**
103
+ * Stel Order backend capabilities
104
+ *
105
+ * ERP/document API with catalog, CRM, inventory visibility, and sales documents,
106
+ * but without cart, checkout, customer auth, or storefront-native payment flows.
107
+ */
108
+ export const STELORDER_CAPABILITIES: Readonly<BackendCapabilities> = {
109
+ // Profile Management
110
+ updateProfile: false,
111
+ updateEmail: false,
112
+ changePasswordDirect: false,
113
+ changePasswordViaEmail: false,
114
+ deleteAccount: false,
115
+
116
+ // Avatar
117
+ uploadAvatar: false,
118
+ avatarViaMetadata: false,
119
+
120
+ // Custom Attributes
121
+ customAttributes: false,
122
+
123
+ // Orders
124
+ fetchOrders: true,
125
+ cancelOrder: false,
126
+
127
+ // Addresses
128
+ manageAddresses: true,
129
+ defaultAddress: false,
130
+
131
+ // Cart/Checkout
132
+ applyDiscounts: false,
133
+ shippingCalculation: false,
134
+ guestCheckout: false,
135
+ savedPaymentMethods: false,
136
+ listPaymentProviders: true,
137
+ regionSpecificPayments: false,
138
+
139
+ // Wishlist
140
+ wishlist: false,
141
+
142
+ // Search
143
+ advancedSearch: false,
144
+ facetedFilters: false,
145
+
146
+ // Reviews
147
+ productReviews: false,
148
+
149
+ // Loyalty
150
+ loyaltyProgram: false,
151
+ };
152
+
102
153
  /**
103
154
  * Shopify backend capabilities
104
155
  *
@@ -0,0 +1,13 @@
1
+ import { defineConfig } from 'vitest/config'
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ environment: 'node',
6
+ globals: true,
7
+ setupFiles: ['./vitest.setup.ts'],
8
+ include: ['src/**/*.test.ts'],
9
+ restoreMocks: true,
10
+ clearMocks: true,
11
+ mockReset: true,
12
+ },
13
+ })
@@ -0,0 +1,6 @@
1
+ import { afterAll, afterEach, beforeAll } from 'vitest'
2
+ import { server } from './src/providers/stelorder/client.test-helpers'
3
+
4
+ beforeAll(() => server.listen({ onUnhandledRequest: 'error' }))
5
+ afterEach(() => server.resetHandlers())
6
+ afterAll(() => server.close())