@thorprovider/adapters 4.0.1 → 4.2.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.
@@ -1,23 +1,25 @@
1
- # Getting Started
2
-
3
1
  ---
2
+ title: "Getting started"
3
+ purpose: "Provide a quick setup guide for integrating Thor adapters in mock or live backend mode"
4
+ lastReviewed: "2026-05-01"
4
5
  type: how-to
5
6
  tags: [setup, installation, adapters, medusa, configuration]
6
7
  related:
7
8
  - services-overview.md
8
9
  - providers-overview.md
9
10
  - authentication.md
10
- updated: 2026-02-28
11
11
  ---
12
12
 
13
- Quick setup guide for integrating Thor adapters into our project.
13
+ # Getting Started
14
+
15
+ Quick setup guide for integrating Thor adapters into our project. Start with `mock` for backend-optional development, or configure a real backend immediately.
14
16
 
15
17
  ## Prerequisites
16
18
 
17
19
  - Node.js 18+
18
20
  - Yarn 4+ (PnP mode)
19
- - Access to a Medusa.js v2 backend
20
- - Medusa Publishable API Key
21
+ - Optional: access to a Medusa.js v2 backend
22
+ - Optional: Medusa Publishable API Key
21
23
 
22
24
  ## Quick Example
23
25
 
@@ -25,6 +27,14 @@ Quick setup guide for integrating Thor adapters into our project.
25
27
  import { createProvider } from '@thorprovider/adapters';
26
28
 
27
29
  const commerce = createProvider({
30
+ provider: 'mock',
31
+ config: {
32
+ currencyCode: 'USD',
33
+ },
34
+ });
35
+
36
+ // Or use a real backend
37
+ const liveCommerce = createProvider({
28
38
  provider: 'medusa',
29
39
  config: {
30
40
  baseUrl: process.env.NEXT_PUBLIC_COMMERCE_API_URL!,
@@ -53,6 +63,14 @@ Create a shared instance for our application.
53
63
  import { createProvider } from '@thorprovider/adapters';
54
64
 
55
65
  export const commerce = createProvider({
66
+ provider: 'mock',
67
+ config: {
68
+ debug: process.env.NODE_ENV === 'development',
69
+ },
70
+ });
71
+
72
+ // Switch to a real backend when ready
73
+ export const liveCommerce = createProvider({
56
74
  provider: 'medusa',
57
75
  config: {
58
76
  baseUrl: process.env.NEXT_PUBLIC_COMMERCE_API_URL!,
@@ -64,14 +82,17 @@ export const commerce = createProvider({
64
82
 
65
83
  ### Step 3: Configure Environment Variables
66
84
 
67
- Create `.env.local` to store backend credentials.
85
+ Create `.env.local` to store runtime configuration.
68
86
 
69
87
  ```env
70
- # Backend Configuration
71
- NEXT_PUBLIC_COMMERCE_PROVIDER=medusa
88
+ # Mock-first configuration
89
+ NEXT_PUBLIC_COMMERCE_PROVIDER=mock
90
+ NEXT_PUBLIC_DEFAULT_CURRENCY=USD
91
+
92
+ # Live backend configuration (only required for real providers)
93
+ # NEXT_PUBLIC_COMMERCE_PROVIDER=medusa
72
94
  NEXT_PUBLIC_COMMERCE_API_URL=http://localhost:9000
73
95
  NEXT_PUBLIC_COMMERCE_API_KEY=your_publishable_key_here
74
- NEXT_PUBLIC_DEFAULT_CURRENCY=USD
75
96
  ```
76
97
 
77
98
  ### Step 4: Use in Server Components (Next.js)
@@ -96,7 +117,7 @@ export default async function ProductsPage() {
96
117
  ## ✅ DO's
97
118
 
98
119
  1. **Use Singleton Pattern:** Create one instance of the provider and export it.
99
- 2. **Handle Environment Variables:** Always use `!` or validation to ensure `baseUrl` exists.
120
+ 2. **Handle Environment Variables:** Require `baseUrl` only for real backends.
100
121
  3. **Prefer Server-Side:** Fetch data in Server Components whenever possible.
101
122
  4. **Use TypeScript Types:** Leverage the exported types from `@thorprovider/adapters` for better DX.
102
123
  5. **Configure Debug Mode:** Enable `debug: true` during development to trace API issues.
@@ -1,15 +1,17 @@
1
- # Providers Overview
2
-
3
1
  ---
2
+ title: "Providers overview"
3
+ purpose: "Describe the supported commerce providers and how Thor Adapters abstracts them behind a unified interface"
4
+ lastReviewed: "2026-05-01"
4
5
  type: guide
5
6
  tags: [architecture, providers, medusa, shopify, roadmap]
6
7
  related:
7
8
  - capabilities-system.md
8
9
  - services-overview.md
9
10
  - getting-started.md
10
- updated: 2026-02-28
11
11
  ---
12
12
 
13
+ # Providers Overview
14
+
13
15
  Overview of the e-commerce platforms supported by Thor Adapters and how they are abstracted into a unified interface.
14
16
 
15
17
  ## Overview
@@ -28,6 +30,10 @@ Thor Adapters eliminate these problems by wrapping the data layer in a consisten
28
30
 
29
31
  ## Current Support Matrix
30
32
 
33
+ ### Mock
34
+ **Status:** ✅ Production Ready
35
+ Fixture-backed provider for local development, previews, design-mode storefront work, and backend-optional scaffolds.
36
+
31
37
  ### Medusa (v2.0)
32
38
  **Status:** ✅ Production Ready
33
39
  Our primary integration, highly optimized for headless performance.
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@thorprovider/adapters",
3
- "version": "4.0.1",
3
+ "version": "4.2.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",
7
- "access": "restricted"
7
+ "access": "public"
8
8
  },
9
9
  "main": "dist/index.js",
10
10
  "types": "dist/index.d.ts",
@@ -17,6 +17,7 @@ import { BigCommerceProvider, type BigCommerceProviderConfig } from '../provider
17
17
  import { WooCommerceProvider, type WooCommerceProviderConfig } from '../providers/woocommerce';
18
18
  import { SpreeProvider, type SpreeProviderConfig } from '../providers/spree';
19
19
  import { MagentoProvider, type MagentoProviderConfig } from '../providers/magento';
20
+ import { MockProvider, type MockProviderConfig } from '../providers/mock';
20
21
  import { ProviderNotFoundError, ConfigurationError } from '../core/errors';
21
22
  import type { ProviderTypeString } from '@thorprovider/types';
22
23
 
@@ -30,6 +31,7 @@ export type ProviderType = ProviderTypeString;
30
31
  * Provider configuration discriminated union
31
32
  */
32
33
  export type ProviderFactoryConfig =
34
+ | { provider: 'mock'; config: MockProviderConfig }
33
35
  | { provider: 'medusa'; config: MedusaProviderConfig }
34
36
  | { provider: 'shopify'; config: ShopifyProviderConfig }
35
37
  | { provider: 'bigcommerce'; config: BigCommerceProviderConfig }
@@ -73,6 +75,8 @@ export function createProvider(options: ProviderFactoryConfig | RuntimeProviderC
73
75
  const config = options.config as any;
74
76
 
75
77
  switch (options.provider) {
78
+ case 'mock':
79
+ return new MockProvider(config);
76
80
  case 'medusa':
77
81
  return new MedusaProvider(config);
78
82
  case 'shopify':
package/src/index.ts CHANGED
@@ -38,6 +38,7 @@ export {
38
38
  // Capabilities
39
39
  // ============================================
40
40
  export {
41
+ MOCK_CAPABILITIES,
41
42
  MEDUSA_CAPABILITIES,
42
43
  SHOPIFY_CAPABILITIES,
43
44
  BIGCOMMERCE_CAPABILITIES,
@@ -192,6 +193,8 @@ export {
192
193
  export {
193
194
  MedusaProvider,
194
195
  type MedusaProviderConfig,
196
+ MockProvider,
197
+ type MockProviderConfig,
195
198
  ShopifyProvider,
196
199
  type ShopifyProviderConfig,
197
200
  BigCommerceProvider,
@@ -0,0 +1,101 @@
1
+ import type { AuthConfig } from '@thorprovider/types';
2
+
3
+ type StoredValue = string | null;
4
+
5
+ function isBrowserStorageAvailable(): boolean {
6
+ return typeof window !== 'undefined';
7
+ }
8
+
9
+ function getStorage(config: AuthConfig): Storage | null {
10
+ if (!isBrowserStorageAvailable()) {
11
+ return null;
12
+ }
13
+
14
+ switch (config.storage) {
15
+ case 'localStorage':
16
+ return window.localStorage;
17
+ case 'sessionStorage':
18
+ return window.sessionStorage;
19
+ default:
20
+ return null;
21
+ }
22
+ }
23
+
24
+ export class AuthStorage {
25
+ private memory = new Map<string, string>();
26
+
27
+ constructor(
28
+ private readonly config: AuthConfig,
29
+ private readonly namespace: string,
30
+ ) {}
31
+
32
+ private key(suffix: string): string {
33
+ return `${this.namespace}:${suffix}`;
34
+ }
35
+
36
+ async getString(suffix: string): Promise<StoredValue> {
37
+ const key = this.key(suffix);
38
+
39
+ if (this.config.customStorage) {
40
+ return (await this.config.customStorage.getItem(key)) ?? null;
41
+ }
42
+
43
+ const browserStorage = getStorage(this.config);
44
+ if (browserStorage) {
45
+ return browserStorage.getItem(key);
46
+ }
47
+
48
+ return this.memory.get(key) ?? null;
49
+ }
50
+
51
+ async setString(suffix: string, value: string): Promise<void> {
52
+ const key = this.key(suffix);
53
+
54
+ if (this.config.customStorage) {
55
+ await this.config.customStorage.setItem(key, value);
56
+ return;
57
+ }
58
+
59
+ const browserStorage = getStorage(this.config);
60
+ if (browserStorage) {
61
+ browserStorage.setItem(key, value);
62
+ return;
63
+ }
64
+
65
+ this.memory.set(key, value);
66
+ }
67
+
68
+ async remove(suffix: string): Promise<void> {
69
+ const key = this.key(suffix);
70
+
71
+ if (this.config.customStorage) {
72
+ await this.config.customStorage.removeItem(key);
73
+ return;
74
+ }
75
+
76
+ const browserStorage = getStorage(this.config);
77
+ if (browserStorage) {
78
+ browserStorage.removeItem(key);
79
+ return;
80
+ }
81
+
82
+ this.memory.delete(key);
83
+ }
84
+
85
+ async getJson<T>(suffix: string): Promise<T | null> {
86
+ const value = await this.getString(suffix);
87
+ if (!value) {
88
+ return null;
89
+ }
90
+
91
+ try {
92
+ return JSON.parse(value) as T;
93
+ } catch {
94
+ return null;
95
+ }
96
+ }
97
+
98
+ async setJson(suffix: string, value: unknown): Promise<void> {
99
+ await this.setString(suffix, JSON.stringify(value));
100
+ }
101
+ }
@@ -20,3 +20,6 @@ export type { SpreeProviderConfig } from './spree';
20
20
 
21
21
  export { MagentoProvider } from './magento';
22
22
  export type { MagentoProviderConfig } from './magento';
23
+
24
+ export { MockProvider } from './mock';
25
+ export type { MockProviderConfig } from './mock';