@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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thorprovider/adapters",
3
- "version": "4.3.0",
3
+ "version": "5.0.0",
4
4
  "description": "Framework-agnostic commerce adapters for Thor Commerce ecosystem - Multi-platform support with unified API",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org",
@@ -93,15 +93,5 @@ export function createBackendMetadataAdapter(
93
93
  return new MedusaMetadataAdapter(medusa);
94
94
  }
95
95
 
96
- if (provider === 'shopify') {
97
- // TODO: Implement Shopify metadata adapter
98
- throw new Error('Shopify metadata adapter not yet implemented');
99
- }
100
-
101
- if (provider === 'woocommerce') {
102
- // TODO: Implement WooCommerce metadata adapter
103
- throw new Error('WooCommerce metadata adapter not yet implemented');
104
- }
105
-
106
- throw new Error(`Unsupported provider: ${provider}`);
96
+ throw new Error(`Unsupported provider for metadata adapter: ${provider}. Only 'medusa' is currently supported.`);
107
97
  }
@@ -1,57 +1,93 @@
1
1
  /**
2
- * @thorprovider/adapters v2.0
3
- * Provider Factory - Create commerce providers dynamically
2
+ * @thorprovider/adapters v5.0
3
+ * Provider Factory - Dynamic registry pattern
4
4
  *
5
- * This factory is bound to SupportedProviderType from @thorprovider/types (L1).
6
- * When adding a new provider:
7
- * 1. Update SupportedProviderType enum in packages/types/src/provider.ts
8
- * 2. Add new discriminated union case here
9
- * 3. Create packages/adapters/src/providers/[platform]/
10
- * 4. Implement CommerceProvider interface
5
+ * Providers register themselves at import time via `registerProvider()`.
6
+ * The factory no longer statically imports every backend — only the ones
7
+ * the consumer explicitly imports will be available.
8
+ *
9
+ * Built-in providers (medusa, stelorder, mock) are registered automatically.
11
10
  */
12
11
 
13
12
  import type { CommerceProvider } from '../types';
14
13
  import { MedusaProvider, type MedusaProviderConfig } from '../providers/medusa';
15
- import { ShopifyProvider, type ShopifyProviderConfig } from '../providers/shopify';
16
- import { BigCommerceProvider, type BigCommerceProviderConfig } from '../providers/bigcommerce';
17
- import { WooCommerceProvider, type WooCommerceProviderConfig } from '../providers/woocommerce';
18
- import { SpreeProvider, type SpreeProviderConfig } from '../providers/spree';
19
- import { MagentoProvider, type MagentoProviderConfig } from '../providers/magento';
20
14
  import { StelOrderProvider, type StelOrderProviderConfig } from '../providers/stelorder';
21
15
  import { MockProvider, type MockProviderConfig } from '../providers/mock';
22
16
  import { ProviderNotFoundError, ConfigurationError } from '../core/errors';
23
17
  import type { ProviderTypeString } from '@thorprovider/types';
24
18
 
19
+ // ============================================
20
+ // Registry
21
+ // ============================================
22
+
23
+ type ProviderFactory = (config: any) => CommerceProvider;
24
+
25
+ const registry = new Map<string, ProviderFactory>();
26
+
27
+ /**
28
+ * Register a provider factory for a given type string.
29
+ * Call this to make a provider available to `createProvider()`.
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * import { registerProvider } from '@thorprovider/adapters';
34
+ * import { MyProvider } from './my-provider';
35
+ *
36
+ * registerProvider('my-provider', (config) => new MyProvider(config));
37
+ * ```
38
+ */
39
+ export function registerProvider(type: string, factory: ProviderFactory): void {
40
+ registry.set(type, factory);
41
+ }
42
+
25
43
  /**
26
- * Supported provider types (imported from @thorprovider/types L1)
27
- * Kept for backward compatibility; prefer ProviderTypeString from @thorprovider/types
44
+ * Get all registered provider type strings.
28
45
  */
29
- export type ProviderType = ProviderTypeString;
46
+ export function getRegisteredProviders(): string[] {
47
+ return Array.from(registry.keys());
48
+ }
49
+
50
+ // ============================================
51
+ // Built-in registrations
52
+ // ============================================
53
+
54
+ registerProvider('mock', (config) => new MockProvider(config));
55
+ registerProvider('medusa', (config) => new MedusaProvider(config));
56
+ registerProvider('stelorder', (config) => new StelOrderProvider(config));
57
+
58
+ // ============================================
59
+ // Types
60
+ // ============================================
61
+
62
+ /**
63
+ * Supported provider types
64
+ */
65
+ export type ProviderType = ProviderTypeString | (string & {});
30
66
 
31
67
  /**
32
- * Provider configuration discriminated union
68
+ * Provider configuration discriminated union (built-in providers)
33
69
  */
34
70
  export type ProviderFactoryConfig =
35
71
  | { provider: 'mock'; config: MockProviderConfig }
36
72
  | { provider: 'medusa'; config: MedusaProviderConfig }
37
73
  | { provider: 'stelorder'; config: StelOrderProviderConfig }
38
- | { provider: 'shopify'; config: ShopifyProviderConfig }
39
- | { provider: 'bigcommerce'; config: BigCommerceProviderConfig }
40
- | { provider: 'woocommerce'; config: WooCommerceProviderConfig }
41
- | { provider: 'spree'; config: SpreeProviderConfig }
42
- | { provider: 'magento'; config: MagentoProviderConfig };
74
+ | { provider: string; config: Record<string, unknown> };
43
75
 
44
76
  /**
45
- * Runtime provider configuration (accepts any ProviderTypeString from env vars)
77
+ * Runtime provider configuration (accepts any registered provider string)
46
78
  */
47
79
  export type RuntimeProviderConfig = {
48
- provider: ProviderTypeString;
80
+ provider: string;
49
81
  config: Record<string, unknown>;
50
82
  };
51
83
 
84
+ // ============================================
85
+ // Factory
86
+ // ============================================
87
+
52
88
  /**
53
- * Create a commerce provider instance
54
- *
89
+ * Create a commerce provider instance from the registry.
90
+ *
55
91
  * @example
56
92
  * ```ts
57
93
  * const commerce = createProvider({
@@ -61,42 +97,28 @@ export type RuntimeProviderConfig = {
61
97
  * publishableKey: process.env.MEDUSA_PUBLISHABLE_KEY,
62
98
  * }
63
99
  * });
64
- *
65
- * const products = await commerce.getProducts();
66
100
  * ```
67
101
  */
68
102
  export function createProvider(options: ProviderFactoryConfig | RuntimeProviderConfig): CommerceProvider {
69
103
  if (!options || !options.provider) {
70
104
  throw new ConfigurationError('Provider type is required');
71
105
  }
72
-
106
+
73
107
  if (!options.config) {
74
108
  throw new ConfigurationError('Provider configuration is required');
75
109
  }
76
-
77
- const config = options.config as any;
78
-
79
- switch (options.provider) {
80
- case 'mock':
81
- return new MockProvider(config);
82
- case 'medusa':
83
- return new MedusaProvider(config);
84
- case 'stelorder':
85
- return new StelOrderProvider(config);
86
- case 'shopify':
87
- return new ShopifyProvider(config);
88
- case 'bigcommerce':
89
- return new BigCommerceProvider(config);
90
- case 'woocommerce':
91
- return new WooCommerceProvider(config);
92
- case 'spree':
93
- return new SpreeProvider(config);
94
- case 'magento':
95
- return new MagentoProvider(config);
96
-
97
- default:
98
- throw new ProviderNotFoundError(String((options as any).provider));
110
+
111
+ const factory = registry.get(options.provider);
112
+
113
+ if (!factory) {
114
+ const available = getRegisteredProviders().join(', ');
115
+ throw new ProviderNotFoundError(
116
+ `Provider "${options.provider}" is not registered. Available: ${available}. ` +
117
+ `Did you forget to import the provider package?`
118
+ );
99
119
  }
120
+
121
+ return factory(options.config);
100
122
  }
101
123
 
102
124
  /**
package/src/index.ts CHANGED
@@ -41,11 +41,6 @@ export {
41
41
  MOCK_CAPABILITIES,
42
42
  MEDUSA_CAPABILITIES,
43
43
  STELORDER_CAPABILITIES,
44
- SHOPIFY_CAPABILITIES,
45
- BIGCOMMERCE_CAPABILITIES,
46
- WOOCOMMERCE_CAPABILITIES,
47
- SPREE_CAPABILITIES,
48
- MAGENTO_CAPABILITIES,
49
44
  isBackendCapabilities,
50
45
  getCapabilityDescription,
51
46
  } from './types/capabilities.types';
@@ -60,8 +55,11 @@ export {
60
55
  ResourceNotFoundError,
61
56
  ProviderAPIError,
62
57
  createLogger,
58
+ fetchWithRetry,
59
+ extractErrorMessage,
63
60
  type Logger,
64
61
  type LogLevel,
62
+ type RetryConfig,
65
63
  } from './core';
66
64
 
67
65
  // ============================================
@@ -183,6 +181,8 @@ export type {
183
181
  // ============================================
184
182
  export {
185
183
  createProvider,
184
+ registerProvider,
185
+ getRegisteredProviders,
186
186
  isProviderType,
187
187
  type ProviderType,
188
188
  type ProviderFactoryConfig,
@@ -198,14 +198,4 @@ export {
198
198
  type StelOrderProviderConfig,
199
199
  MockProvider,
200
200
  type MockProviderConfig,
201
- ShopifyProvider,
202
- type ShopifyProviderConfig,
203
- BigCommerceProvider,
204
- type BigCommerceProviderConfig,
205
- WooCommerceProvider,
206
- type WooCommerceProviderConfig,
207
- SpreeProvider,
208
- type SpreeProviderConfig,
209
- MagentoProvider,
210
- type MagentoProviderConfig,
211
201
  } from './providers';
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @thorprovider/adapters v2.0
2
+ * @thorprovider/adapters v5.0
3
3
  * Providers index
4
4
  */
5
5
 
@@ -9,20 +9,5 @@ export type { MedusaProviderConfig } from './medusa';
9
9
  export { StelOrderProvider } from './stelorder';
10
10
  export type { StelOrderProviderConfig } from './stelorder';
11
11
 
12
- export { ShopifyProvider } from './shopify';
13
- export type { ShopifyProviderConfig } from './shopify';
14
-
15
- export { BigCommerceProvider } from './bigcommerce';
16
- export type { BigCommerceProviderConfig } from './bigcommerce';
17
-
18
- export { WooCommerceProvider } from './woocommerce';
19
- export type { WooCommerceProviderConfig } from './woocommerce';
20
-
21
- export { SpreeProvider } from './spree';
22
- export type { SpreeProviderConfig } from './spree';
23
-
24
- export { MagentoProvider } from './magento';
25
- export type { MagentoProviderConfig } from './magento';
26
-
27
12
  export { MockProvider } from './mock';
28
13
  export type { MockProviderConfig } from './mock';
@@ -150,256 +150,6 @@ export const STELORDER_CAPABILITIES: Readonly<BackendCapabilities> = {
150
150
  loyaltyProgram: false,
151
151
  };
152
152
 
153
- /**
154
- * Shopify backend capabilities
155
- *
156
- * @see https://shopify.dev/docs/api/storefront
157
- */
158
- export const SHOPIFY_CAPABILITIES: Readonly<BackendCapabilities> = {
159
- // Profile Management
160
- updateProfile: true,
161
- updateEmail: true,
162
- changePasswordDirect: true,
163
- changePasswordViaEmail: true,
164
- deleteAccount: false, // Requires admin API
165
-
166
- // Avatar
167
- uploadAvatar: false,
168
- avatarViaMetadata: true,
169
-
170
- // Custom Attributes
171
- customAttributes: true,
172
-
173
- // Orders
174
- fetchOrders: true,
175
- cancelOrder: true,
176
-
177
- // Addresses
178
- manageAddresses: true,
179
- defaultAddress: true,
180
-
181
- // Cart/Checkout
182
- applyDiscounts: true,
183
- shippingCalculation: true,
184
- guestCheckout: true,
185
- savedPaymentMethods: true,
186
- listPaymentProviders: true,
187
- regionSpecificPayments: false, // Global payment methods
188
-
189
- // Wishlist
190
- wishlist: false, // Requires app
191
-
192
- // Search
193
- advancedSearch: true,
194
- facetedFilters: true,
195
-
196
- // Reviews
197
- productReviews: false, // Requires app
198
-
199
- // Loyalty
200
- loyaltyProgram: false, // Requires app
201
- };
202
-
203
- /**
204
- * BigCommerce backend capabilities
205
- *
206
- * @see https://developer.bigcommerce.com/docs/rest-storefront
207
- */
208
- export const BIGCOMMERCE_CAPABILITIES: Readonly<BackendCapabilities> = {
209
- // Profile Management
210
- updateProfile: true,
211
- updateEmail: true,
212
- changePasswordDirect: true,
213
- changePasswordViaEmail: true,
214
- deleteAccount: false,
215
-
216
- // Avatar
217
- uploadAvatar: false,
218
- avatarViaMetadata: false,
219
-
220
- // Custom Attributes
221
- customAttributes: true,
222
-
223
- // Orders
224
- fetchOrders: true,
225
- cancelOrder: false, // Admin API only
226
-
227
- // Addresses
228
- manageAddresses: true,
229
- defaultAddress: false,
230
-
231
- // Cart/Checkout
232
- applyDiscounts: true,
233
- shippingCalculation: true,
234
- guestCheckout: true,
235
- savedPaymentMethods: true,
236
- listPaymentProviders: true,
237
- regionSpecificPayments: false,
238
-
239
- // Wishlist
240
- wishlist: true, // Native support
241
-
242
- // Search
243
- advancedSearch: true,
244
- facetedFilters: true,
245
-
246
- // Reviews
247
- productReviews: true, // Native support
248
-
249
- // Loyalty
250
- loyaltyProgram: false,
251
- };
252
-
253
- /**
254
- * WooCommerce backend capabilities
255
- *
256
- * @see https://developer.woocommerce.com/docs/apis/store-api
257
- */
258
- export const WOOCOMMERCE_CAPABILITIES: Readonly<BackendCapabilities> = {
259
- // Profile Management
260
- updateProfile: true,
261
- updateEmail: true,
262
- changePasswordDirect: false, // WordPress handles auth
263
- changePasswordViaEmail: true,
264
- deleteAccount: false,
265
-
266
- // Avatar
267
- uploadAvatar: false,
268
- avatarViaMetadata: false, // Gravatar-based
269
-
270
- // Custom Attributes
271
- customAttributes: true, // Via meta_data
272
-
273
- // Orders
274
- fetchOrders: true,
275
- cancelOrder: true,
276
-
277
- // Addresses
278
- manageAddresses: true,
279
- defaultAddress: false, // Billing/shipping only
280
-
281
- // Cart/Checkout
282
- applyDiscounts: true, // Coupon codes
283
- shippingCalculation: true,
284
- guestCheckout: true,
285
- savedPaymentMethods: false,
286
- listPaymentProviders: true,
287
- regionSpecificPayments: false,
288
-
289
- // Wishlist
290
- wishlist: false, // Requires plugin
291
-
292
- // Search
293
- advancedSearch: false, // Basic WP search
294
- facetedFilters: false, // Requires plugin
295
-
296
- // Reviews
297
- productReviews: true, // Native WP reviews
298
-
299
- // Loyalty
300
- loyaltyProgram: false,
301
- };
302
-
303
- /**
304
- * Spree Commerce backend capabilities
305
- *
306
- * @see https://docs.spreecommerce.org/api-reference
307
- */
308
- export const SPREE_CAPABILITIES: Readonly<BackendCapabilities> = {
309
- // Profile Management
310
- updateProfile: true,
311
- updateEmail: true,
312
- changePasswordDirect: true,
313
- changePasswordViaEmail: true,
314
- deleteAccount: false,
315
-
316
- // Avatar
317
- uploadAvatar: false,
318
- avatarViaMetadata: false,
319
-
320
- // Custom Attributes
321
- customAttributes: false,
322
-
323
- // Orders
324
- fetchOrders: true,
325
- cancelOrder: true,
326
-
327
- // Addresses
328
- manageAddresses: true,
329
- defaultAddress: true,
330
-
331
- // Cart/Checkout
332
- applyDiscounts: true,
333
- shippingCalculation: true,
334
- guestCheckout: true,
335
- savedPaymentMethods: false,
336
- listPaymentProviders: true,
337
- regionSpecificPayments: false,
338
-
339
- // Wishlist
340
- wishlist: true, // Native support
341
-
342
- // Search
343
- advancedSearch: false,
344
- facetedFilters: true, // Taxon-based filtering
345
-
346
- // Reviews
347
- productReviews: false, // Requires extension
348
-
349
- // Loyalty
350
- loyaltyProgram: false,
351
- };
352
-
353
- /**
354
- * Adobe Commerce / Magento backend capabilities
355
- *
356
- * @see https://developer.adobe.com/commerce/webapi/graphql/
357
- */
358
- export const MAGENTO_CAPABILITIES: Readonly<BackendCapabilities> = {
359
- // Profile Management
360
- updateProfile: true,
361
- updateEmail: true,
362
- changePasswordDirect: true,
363
- changePasswordViaEmail: true,
364
- deleteAccount: false, // Admin only
365
-
366
- // Avatar
367
- uploadAvatar: false,
368
- avatarViaMetadata: false,
369
-
370
- // Custom Attributes
371
- customAttributes: true, // EAV model
372
-
373
- // Orders
374
- fetchOrders: true,
375
- cancelOrder: true,
376
-
377
- // Addresses
378
- manageAddresses: true,
379
- defaultAddress: true,
380
-
381
- // Cart/Checkout
382
- applyDiscounts: true,
383
- shippingCalculation: true,
384
- guestCheckout: true,
385
- savedPaymentMethods: true,
386
- listPaymentProviders: true,
387
- regionSpecificPayments: true, // Store-view scoped
388
-
389
- // Wishlist
390
- wishlist: true, // Native support
391
-
392
- // Search
393
- advancedSearch: true, // Elasticsearch/OpenSearch
394
- facetedFilters: true, // Layered navigation
395
-
396
- // Reviews
397
- productReviews: true, // Native support
398
-
399
- // Loyalty
400
- loyaltyProgram: false, // Requires extension
401
- };
402
-
403
153
  /**
404
154
  * Type guard to check if an object is a valid BackendCapabilities
405
155
  */
@@ -1,6 +0,0 @@
1
- /**
2
- * @thorprovider/adapters — BigCommerce Provider exports
3
- */
4
- export { BigCommerceProvider } from './index';
5
- export type { BigCommerceProviderConfig } from './index';
6
- export * from './transforms';