@reactionary/source 0.0.52 → 0.2.16
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/.env-template +19 -0
- package/.github/workflows/pull-request.yml +3 -1
- package/.github/workflows/release.yml +9 -0
- package/.vscode/extensions.json +0 -2
- package/LICENSE +21 -0
- package/README.md +175 -23
- package/core/package.json +6 -3
- package/core/src/cache/cache.interface.ts +1 -0
- package/core/src/cache/index.ts +4 -0
- package/core/src/cache/memory-cache.ts +30 -2
- package/core/src/cache/noop-cache.ts +15 -1
- package/core/src/cache/redis-cache.ts +20 -0
- package/core/src/client/client-builder.ts +71 -54
- package/core/src/client/client.ts +9 -47
- package/core/src/client/index.ts +2 -0
- package/core/src/decorators/index.ts +1 -0
- package/core/src/decorators/reactionary.decorator.ts +203 -34
- package/core/src/index.ts +6 -19
- package/core/src/initialization.ts +1 -18
- package/core/src/metrics/metrics.ts +67 -0
- package/core/src/providers/analytics.provider.ts +1 -6
- package/core/src/providers/base.provider.ts +5 -69
- package/core/src/providers/cart.provider.ts +15 -55
- package/core/src/providers/category.provider.ts +7 -11
- package/core/src/providers/checkout.provider.ts +17 -15
- package/core/src/providers/identity.provider.ts +6 -8
- package/core/src/providers/index.ts +2 -1
- package/core/src/providers/inventory.provider.ts +15 -5
- package/core/src/providers/order-search.provider.ts +29 -0
- package/core/src/providers/order.provider.ts +47 -15
- package/core/src/providers/price.provider.ts +30 -36
- package/core/src/providers/product-search.provider.ts +61 -0
- package/core/src/providers/product.provider.ts +71 -12
- package/core/src/providers/profile.provider.ts +74 -14
- package/core/src/providers/store.provider.ts +3 -5
- package/core/src/schemas/capabilities.schema.ts +10 -3
- package/core/src/schemas/errors/generic.error.ts +9 -0
- package/core/src/schemas/errors/index.ts +4 -0
- package/core/src/schemas/errors/invalid-input.error.ts +9 -0
- package/core/src/schemas/errors/invalid-output.error.ts +9 -0
- package/core/src/schemas/errors/not-found.error.ts +9 -0
- package/core/src/schemas/index.ts +7 -0
- package/core/src/schemas/models/analytics.model.ts +2 -1
- package/core/src/schemas/models/base.model.ts +6 -24
- package/core/src/schemas/models/cart.model.ts +5 -8
- package/core/src/schemas/models/category.model.ts +4 -9
- package/core/src/schemas/models/checkout.model.ts +6 -7
- package/core/src/schemas/models/cost.model.ts +4 -3
- package/core/src/schemas/models/currency.model.ts +2 -1
- package/core/src/schemas/models/identifiers.model.ts +106 -62
- package/core/src/schemas/models/identity.model.ts +10 -19
- package/core/src/schemas/models/index.ts +2 -1
- package/core/src/schemas/models/inventory.model.ts +8 -5
- package/core/src/schemas/models/order-search.model.ts +28 -0
- package/core/src/schemas/models/order.model.ts +20 -26
- package/core/src/schemas/models/payment.model.ts +14 -17
- package/core/src/schemas/models/price.model.ts +11 -11
- package/core/src/schemas/models/product-search.model.ts +42 -0
- package/core/src/schemas/models/product.model.ts +64 -22
- package/core/src/schemas/models/profile.model.ts +19 -22
- package/core/src/schemas/models/shipping-method.model.ts +24 -29
- package/core/src/schemas/models/store.model.ts +9 -5
- package/core/src/schemas/mutations/analytics.mutation.ts +8 -7
- package/core/src/schemas/mutations/base.mutation.ts +2 -1
- package/core/src/schemas/mutations/cart.mutation.ts +33 -33
- package/core/src/schemas/mutations/checkout.mutation.ts +23 -30
- package/core/src/schemas/mutations/identity.mutation.ts +4 -3
- package/core/src/schemas/mutations/profile.mutation.ts +38 -3
- package/core/src/schemas/queries/base.query.ts +2 -1
- package/core/src/schemas/queries/cart.query.ts +3 -3
- package/core/src/schemas/queries/category.query.ts +18 -18
- package/core/src/schemas/queries/checkout.query.ts +7 -9
- package/core/src/schemas/queries/identity.query.ts +2 -1
- package/core/src/schemas/queries/index.ts +2 -1
- package/core/src/schemas/queries/inventory.query.ts +5 -5
- package/core/src/schemas/queries/order-search.query.ts +10 -0
- package/core/src/schemas/queries/order.query.ts +3 -2
- package/core/src/schemas/queries/price.query.ts +10 -4
- package/core/src/schemas/queries/product-search.query.ts +16 -0
- package/core/src/schemas/queries/product.query.ts +13 -6
- package/core/src/schemas/queries/profile.query.ts +5 -2
- package/core/src/schemas/queries/store.query.ts +6 -5
- package/core/src/schemas/result.ts +107 -0
- package/core/src/schemas/session.schema.ts +4 -4
- package/core/src/test/reactionary.decorator.spec.ts +249 -0
- package/core/src/zod-utils.ts +19 -0
- package/core/tsconfig.json +1 -1
- package/core/tsconfig.spec.json +2 -26
- package/core/vitest.config.ts +14 -0
- package/documentation/1-purpose.md +114 -0
- package/documentation/2-getting-started.md +229 -0
- package/documentation/3-querying-and-changing-data.md +74 -0
- package/documentation/4-product-data.md +107 -0
- package/documentation/5-cart-and-checkout.md +211 -0
- package/documentation/6-product-search.md +143 -0
- package/documentation/7-marketing.md +3 -0
- package/eslint.config.mjs +1 -0
- package/examples/node/eslint.config.mjs +1 -4
- package/examples/node/package.json +10 -3
- package/examples/node/project.json +4 -1
- package/examples/node/src/basic/basic-node-provider-model-extension.spec.ts +22 -23
- package/examples/node/src/basic/basic-node-provider-query-extension.spec.ts +15 -11
- package/examples/node/src/basic/basic-node-setup.spec.ts +44 -28
- package/examples/node/src/basic/client-creation.spec.ts +53 -0
- package/examples/node/src/capabilities/cart.spec.ts +255 -0
- package/examples/node/src/capabilities/category.spec.ts +193 -0
- package/examples/node/src/capabilities/checkout.spec.ts +341 -0
- package/examples/node/src/capabilities/identity.spec.ts +93 -0
- package/examples/node/src/capabilities/inventory.spec.ts +66 -0
- package/examples/node/src/capabilities/order-search.spec.ts +265 -0
- package/examples/node/src/capabilities/order.spec.ts +91 -0
- package/examples/node/src/capabilities/price.spec.ts +51 -0
- package/examples/node/src/capabilities/product-search.spec.ts +293 -0
- package/examples/node/src/capabilities/product.spec.ts +122 -0
- package/examples/node/src/capabilities/profile.spec.ts +316 -0
- package/examples/node/src/capabilities/store.spec.ts +26 -0
- package/examples/node/src/utils.ts +147 -0
- package/examples/node/tsconfig.json +9 -12
- package/examples/node/tsconfig.lib.json +1 -2
- package/examples/node/tsconfig.spec.json +2 -14
- package/examples/node/vitest.config.ts +14 -0
- package/migrations.json +22 -5
- package/nx.json +8 -47
- package/package.json +24 -96
- package/providers/algolia/README.md +39 -2
- package/providers/algolia/package.json +2 -1
- package/providers/algolia/src/core/initialize.ts +7 -14
- package/providers/algolia/src/index.ts +2 -4
- package/providers/algolia/src/providers/index.ts +1 -0
- package/providers/algolia/src/providers/product-search.provider.ts +241 -0
- package/providers/algolia/src/schema/capabilities.schema.ts +2 -3
- package/providers/algolia/src/schema/index.ts +3 -0
- package/providers/algolia/src/schema/search.schema.ts +8 -8
- package/providers/algolia/tsconfig.json +1 -1
- package/providers/algolia/tsconfig.lib.json +1 -1
- package/providers/algolia/tsconfig.spec.json +2 -14
- package/providers/algolia/vitest.config.ts +14 -0
- package/providers/commercetools/README.md +30 -3
- package/providers/commercetools/package.json +2 -1
- package/providers/commercetools/src/core/client.ts +178 -99
- package/providers/commercetools/src/core/initialize.ts +130 -74
- package/providers/commercetools/src/core/token-cache.ts +45 -0
- package/providers/commercetools/src/index.ts +3 -2
- package/providers/commercetools/src/providers/cart.provider.ts +281 -341
- package/providers/commercetools/src/providers/category.provider.ts +223 -138
- package/providers/commercetools/src/providers/checkout.provider.ts +631 -449
- package/providers/commercetools/src/providers/identity.provider.ts +50 -29
- package/providers/commercetools/src/providers/index.ts +2 -2
- package/providers/commercetools/src/providers/inventory.provider.ts +76 -74
- package/providers/commercetools/src/providers/order-search.provider.ts +220 -0
- package/providers/commercetools/src/providers/order.provider.ts +96 -61
- package/providers/commercetools/src/providers/price.provider.ts +147 -117
- package/providers/commercetools/src/providers/product-search.provider.ts +528 -0
- package/providers/commercetools/src/providers/product.provider.ts +249 -74
- package/providers/commercetools/src/providers/profile.provider.ts +445 -28
- package/providers/commercetools/src/providers/store.provider.ts +54 -40
- package/providers/commercetools/src/schema/capabilities.schema.ts +3 -1
- package/providers/commercetools/src/schema/commercetools.schema.ts +17 -3
- package/providers/commercetools/src/schema/configuration.schema.ts +1 -0
- package/providers/commercetools/src/schema/session.schema.ts +7 -0
- package/providers/commercetools/src/test/caching.spec.ts +82 -0
- package/providers/commercetools/src/test/identity.spec.ts +109 -0
- package/providers/commercetools/src/test/test-utils.ts +21 -19
- package/providers/commercetools/tsconfig.json +1 -1
- package/providers/commercetools/tsconfig.lib.json +1 -1
- package/providers/commercetools/tsconfig.spec.json +2 -14
- package/providers/commercetools/vitest.config.ts +15 -0
- package/providers/fake/README.md +20 -4
- package/providers/fake/package.json +2 -1
- package/providers/fake/src/core/initialize.ts +47 -49
- package/providers/fake/src/providers/analytics.provider.ts +5 -7
- package/providers/fake/src/providers/cart.provider.ts +163 -92
- package/providers/fake/src/providers/category.provider.ts +78 -50
- package/providers/fake/src/providers/checkout.provider.ts +254 -0
- package/providers/fake/src/providers/identity.provider.ts +57 -65
- package/providers/fake/src/providers/index.ts +6 -2
- package/providers/fake/src/providers/inventory.provider.ts +40 -36
- package/providers/fake/src/providers/order-search.provider.ts +78 -0
- package/providers/fake/src/providers/order.provider.ts +106 -0
- package/providers/fake/src/providers/price.provider.ts +93 -41
- package/providers/fake/src/providers/product-search.provider.ts +206 -0
- package/providers/fake/src/providers/product.provider.ts +56 -41
- package/providers/fake/src/providers/profile.provider.ts +147 -0
- package/providers/fake/src/providers/store.provider.ts +30 -20
- package/providers/fake/src/schema/capabilities.schema.ts +5 -1
- package/providers/fake/src/test/cart.provider.spec.ts +59 -80
- package/providers/fake/src/test/category.provider.spec.ts +145 -87
- package/providers/fake/src/test/checkout.provider.spec.ts +222 -0
- package/providers/fake/src/test/order-search.provider.spec.ts +50 -0
- package/providers/fake/src/test/order.provider.spec.ts +44 -0
- package/providers/fake/src/test/price.provider.spec.ts +50 -45
- package/providers/fake/src/test/product.provider.spec.ts +15 -7
- package/providers/fake/src/test/profile.provider.spec.ts +167 -0
- package/providers/fake/tsconfig.json +1 -1
- package/providers/fake/tsconfig.lib.json +1 -1
- package/providers/fake/tsconfig.spec.json +2 -12
- package/providers/fake/vitest.config.ts +14 -0
- package/providers/medusa/README.md +30 -0
- package/providers/medusa/TESTING.md +98 -0
- package/providers/medusa/eslint.config.mjs +19 -0
- package/providers/medusa/package.json +22 -0
- package/providers/medusa/project.json +34 -0
- package/providers/medusa/src/core/client.ts +370 -0
- package/providers/medusa/src/core/initialize.ts +78 -0
- package/providers/medusa/src/index.ts +13 -0
- package/providers/medusa/src/providers/cart.provider.ts +575 -0
- package/providers/medusa/src/providers/category.provider.ts +247 -0
- package/providers/medusa/src/providers/checkout.provider.ts +636 -0
- package/providers/medusa/src/providers/identity.provider.ts +137 -0
- package/providers/medusa/src/providers/inventory.provider.ts +173 -0
- package/providers/medusa/src/providers/order-search.provider.ts +202 -0
- package/providers/medusa/src/providers/order.provider.ts +226 -0
- package/providers/medusa/src/providers/price.provider.ts +140 -0
- package/providers/medusa/src/providers/product-search.provider.ts +243 -0
- package/providers/medusa/src/providers/product.provider.ts +261 -0
- package/providers/medusa/src/providers/profile.provider.ts +392 -0
- package/providers/medusa/src/schema/capabilities.schema.ts +18 -0
- package/providers/medusa/src/schema/configuration.schema.ts +11 -0
- package/providers/medusa/src/schema/medusa.schema.ts +31 -0
- package/providers/medusa/src/test/cart.provider.spec.ts +240 -0
- package/providers/medusa/src/test/category.provider.spec.ts +231 -0
- package/providers/medusa/src/test/checkout.spec.ts +349 -0
- package/providers/medusa/src/test/identity.provider.spec.ts +122 -0
- package/providers/medusa/src/test/inventory.provider.spec.ts +88 -0
- package/providers/medusa/src/test/large-cart.provider.spec.ts +103 -0
- package/providers/medusa/src/test/price.provider.spec.ts +104 -0
- package/providers/medusa/src/test/product.provider.spec.ts +146 -0
- package/providers/medusa/src/test/search.provider.spec.ts +203 -0
- package/providers/medusa/src/test/test-utils.ts +13 -0
- package/providers/medusa/src/utils/medusa-helpers.ts +89 -0
- package/providers/medusa/tsconfig.json +21 -0
- package/providers/medusa/tsconfig.lib.json +9 -0
- package/providers/medusa/tsconfig.spec.json +4 -0
- package/providers/medusa/vitest.config.ts +15 -0
- package/providers/meilisearch/README.md +48 -0
- package/providers/meilisearch/eslint.config.mjs +22 -0
- package/providers/meilisearch/package.json +13 -0
- package/providers/meilisearch/project.json +34 -0
- package/providers/meilisearch/src/core/initialize.ts +21 -0
- package/providers/meilisearch/src/index.ts +6 -0
- package/providers/meilisearch/src/providers/index.ts +1 -0
- package/providers/meilisearch/src/providers/order-search.provider.ts +222 -0
- package/providers/meilisearch/src/providers/product-search.provider.ts +251 -0
- package/providers/meilisearch/src/schema/capabilities.schema.ts +10 -0
- package/providers/meilisearch/src/schema/configuration.schema.ts +11 -0
- package/providers/meilisearch/src/schema/index.ts +3 -0
- package/providers/meilisearch/src/schema/search.schema.ts +14 -0
- package/providers/meilisearch/tsconfig.json +24 -0
- package/providers/meilisearch/tsconfig.lib.json +10 -0
- package/providers/meilisearch/tsconfig.spec.json +4 -0
- package/providers/meilisearch/vitest.config.ts +14 -0
- package/providers/posthog/package.json +2 -1
- package/providers/posthog/tsconfig.json +1 -1
- package/tsconfig.base.json +5 -0
- package/vitest.config.ts +10 -0
- package/core/src/providers/search.provider.ts +0 -18
- package/core/src/schemas/models/search.model.ts +0 -36
- package/core/src/schemas/queries/search.query.ts +0 -9
- package/examples/next/.swcrc +0 -30
- package/examples/next/eslint.config.mjs +0 -21
- package/examples/next/index.d.ts +0 -6
- package/examples/next/next-env.d.ts +0 -5
- package/examples/next/next.config.js +0 -31
- package/examples/next/project.json +0 -9
- package/examples/next/public/.gitkeep +0 -0
- package/examples/next/public/favicon.ico +0 -0
- package/examples/next/src/app/global.css +0 -0
- package/examples/next/src/app/layout.tsx +0 -18
- package/examples/next/src/app/page.module.scss +0 -2
- package/examples/next/src/app/page.tsx +0 -47
- package/examples/next/src/instrumentation.ts +0 -9
- package/examples/next/tsconfig.json +0 -44
- package/examples/node/jest.config.ts +0 -10
- package/jest.config.ts +0 -6
- package/jest.preset.js +0 -3
- package/providers/algolia/jest.config.ts +0 -10
- package/providers/algolia/src/providers/product.provider.ts +0 -66
- package/providers/algolia/src/providers/search.provider.ts +0 -106
- package/providers/algolia/src/test/search.provider.spec.ts +0 -91
- package/providers/commercetools/jest.config.cjs +0 -10
- package/providers/commercetools/src/providers/search.provider.ts +0 -96
- package/providers/commercetools/src/test/cart.provider.spec.ts +0 -199
- package/providers/commercetools/src/test/category.provider.spec.ts +0 -168
- package/providers/commercetools/src/test/checkout.provider.spec.ts +0 -312
- package/providers/commercetools/src/test/identity.provider.spec.ts +0 -88
- package/providers/commercetools/src/test/inventory.provider.spec.ts +0 -41
- package/providers/commercetools/src/test/price.provider.spec.ts +0 -81
- package/providers/commercetools/src/test/product.provider.spec.ts +0 -80
- package/providers/commercetools/src/test/profile.provider.spec.ts +0 -49
- package/providers/commercetools/src/test/search.provider.spec.ts +0 -61
- package/providers/commercetools/src/test/store.provider.spec.ts +0 -37
- package/providers/fake/jest.config.cjs +0 -10
- package/providers/fake/src/providers/search.provider.ts +0 -132
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
import { Admin, Auth, Client, type Config, Store } from '@medusajs/js-sdk';
|
|
2
|
+
|
|
3
|
+
import type { MedusaConfiguration } from '../schema/configuration.schema.js';
|
|
4
|
+
import {
|
|
5
|
+
AnonymousIdentitySchema,
|
|
6
|
+
Reactionary,
|
|
7
|
+
RegisteredIdentitySchema,
|
|
8
|
+
type AnonymousIdentity,
|
|
9
|
+
type Currency,
|
|
10
|
+
type RegisteredIdentity,
|
|
11
|
+
type RequestContext,
|
|
12
|
+
} from '@reactionary/core';
|
|
13
|
+
import createDebug from 'debug';
|
|
14
|
+
import {
|
|
15
|
+
MedusaSessionSchema,
|
|
16
|
+
type MedusaRegion,
|
|
17
|
+
type MedusaSession,
|
|
18
|
+
} from '../index.js';
|
|
19
|
+
import type { StoreProduct } from '@medusajs/types';
|
|
20
|
+
const debug = createDebug('reactionary:medusa');
|
|
21
|
+
|
|
22
|
+
export const SESSION_KEY = 'MEDUSA_PROVIDER';
|
|
23
|
+
|
|
24
|
+
export interface MedusaAuthToken {
|
|
25
|
+
token: string;
|
|
26
|
+
expires_at?: Date;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface MedusaCustomStorage {
|
|
30
|
+
getItem(key: string): Promise<string | null>;
|
|
31
|
+
setItem(key: string, value: string): Promise<void>;
|
|
32
|
+
removeItem(key: string): Promise<void>;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export class RequestContextTokenStore implements MedusaCustomStorage {
|
|
36
|
+
constructor(protected context: RequestContext, public keyPrefix = '__x') {}
|
|
37
|
+
|
|
38
|
+
getItem(key: string): Promise<string | null> {
|
|
39
|
+
if (this.context.session[SESSION_KEY] === undefined) {
|
|
40
|
+
this.context.session[SESSION_KEY] = {};
|
|
41
|
+
}
|
|
42
|
+
const retVal = this.context.session[SESSION_KEY]
|
|
43
|
+
? this.context.session[SESSION_KEY][this.keyPrefix + '_' + key] || null
|
|
44
|
+
: null;
|
|
45
|
+
if (debug.enabled) {
|
|
46
|
+
debug(
|
|
47
|
+
`Getting token item for key: ${this.keyPrefix + '_' + key} - Found: ${
|
|
48
|
+
retVal ? 'Yes' : 'No'
|
|
49
|
+
}`
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
return Promise.resolve(retVal);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
setItem(key: string, value: string): Promise<void> {
|
|
56
|
+
if (this.context.session[SESSION_KEY] === undefined) {
|
|
57
|
+
this.context.session[SESSION_KEY] = {};
|
|
58
|
+
}
|
|
59
|
+
if (debug.enabled) {
|
|
60
|
+
debug(
|
|
61
|
+
`Setting token item for key: ${
|
|
62
|
+
this.keyPrefix + '_' + key
|
|
63
|
+
} - Value: ${value}`
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
this.context.session[SESSION_KEY][this.keyPrefix + '_' + key] = value;
|
|
67
|
+
return Promise.resolve();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
removeItem(key: string): Promise<void> {
|
|
71
|
+
if (this.context.session[SESSION_KEY] === undefined) {
|
|
72
|
+
this.context.session[SESSION_KEY] = {};
|
|
73
|
+
}
|
|
74
|
+
if (debug.enabled) {
|
|
75
|
+
debug(`Removing token item for key: ${this.keyPrefix + '_' + key}`);
|
|
76
|
+
}
|
|
77
|
+
delete this.context.session[SESSION_KEY][this.keyPrefix + '_' + key];
|
|
78
|
+
return Promise.resolve();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
class Medusa {
|
|
83
|
+
public client: Client;
|
|
84
|
+
|
|
85
|
+
public admin: Admin;
|
|
86
|
+
public store: Store;
|
|
87
|
+
public auth: Auth;
|
|
88
|
+
|
|
89
|
+
constructor(config: Config) {
|
|
90
|
+
this.client = new Client(config);
|
|
91
|
+
|
|
92
|
+
this.admin = new Admin(this.client);
|
|
93
|
+
this.store = new Store(this.client);
|
|
94
|
+
this.auth = new Auth(this.client, config);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export class MedusaAdminAPI {
|
|
99
|
+
protected config: MedusaConfiguration;
|
|
100
|
+
protected client: Medusa;
|
|
101
|
+
protected context: RequestContext;
|
|
102
|
+
|
|
103
|
+
constructor(config: MedusaConfiguration, context: RequestContext) {
|
|
104
|
+
this.config = config;
|
|
105
|
+
this.context = context;
|
|
106
|
+
console.log(
|
|
107
|
+
'MedusaAdminClient config:',
|
|
108
|
+
this.config,
|
|
109
|
+
'Debug enabled:',
|
|
110
|
+
debug.enabled
|
|
111
|
+
);
|
|
112
|
+
this.client = new Medusa({
|
|
113
|
+
baseUrl: this.config.apiUrl,
|
|
114
|
+
apiKey: this.config.adminApiKey,
|
|
115
|
+
debug: true,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
public async getClient(): Promise<Medusa> {
|
|
120
|
+
return this.client;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export class MedusaAPI {
|
|
125
|
+
protected config: MedusaConfiguration;
|
|
126
|
+
protected client: Promise<Medusa> | undefined;
|
|
127
|
+
protected context: RequestContext;
|
|
128
|
+
|
|
129
|
+
constructor(config: MedusaConfiguration, context: RequestContext) {
|
|
130
|
+
this.config = config;
|
|
131
|
+
this.context = context;
|
|
132
|
+
|
|
133
|
+
console.log(
|
|
134
|
+
'MedusaClient config:',
|
|
135
|
+
this.config,
|
|
136
|
+
'Debug enabled:',
|
|
137
|
+
debug.enabled
|
|
138
|
+
);
|
|
139
|
+
this.client = undefined;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
public async getActiveRegion() {
|
|
143
|
+
const session = this.getSessionData();
|
|
144
|
+
if (session.selectedRegion) {
|
|
145
|
+
return session.selectedRegion;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const regions = await (await this.getClient()).store.region.list();
|
|
149
|
+
const allRegions: MedusaRegion[] = [];
|
|
150
|
+
for (const region of regions.regions) {
|
|
151
|
+
allRegions.push({
|
|
152
|
+
id: region.id,
|
|
153
|
+
name: region.name,
|
|
154
|
+
currency_code: region.currency_code,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
const selectedRegion =
|
|
158
|
+
allRegions.find(
|
|
159
|
+
(r) =>
|
|
160
|
+
r.currency_code ===
|
|
161
|
+
this.context.languageContext.currencyCode.toLowerCase()
|
|
162
|
+
) || allRegions[0];
|
|
163
|
+
this.context.languageContext.currencyCode = (
|
|
164
|
+
selectedRegion || allRegions[0]
|
|
165
|
+
).currency_code.toUpperCase() as Currency;
|
|
166
|
+
|
|
167
|
+
this.setSessionData({
|
|
168
|
+
allRegions,
|
|
169
|
+
selectedRegion: selectedRegion,
|
|
170
|
+
});
|
|
171
|
+
return selectedRegion;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
public async resolveProductForSKU(sku: string): Promise<StoreProduct> {
|
|
175
|
+
const adminClient = await new MedusaAdminAPI(
|
|
176
|
+
this.config,
|
|
177
|
+
this.context
|
|
178
|
+
).getClient();
|
|
179
|
+
|
|
180
|
+
const productsResponse = await adminClient.admin.product.list({
|
|
181
|
+
limit: 1,
|
|
182
|
+
offset: 0,
|
|
183
|
+
fields: '+metadata.*,+categories.metadata.*',
|
|
184
|
+
variants: {
|
|
185
|
+
$or: [{ ean: sku }, { upc: sku }, { barcode: sku }],
|
|
186
|
+
},
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
const product = productsResponse.products[0];
|
|
190
|
+
if (!product) {
|
|
191
|
+
throw new Error(`Product with SKU ${sku} not found`);
|
|
192
|
+
}
|
|
193
|
+
return product;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* This function should not need to exist.
|
|
198
|
+
* It returns a product-id, given a SKU.
|
|
199
|
+
* @param sku
|
|
200
|
+
* @returns
|
|
201
|
+
*/
|
|
202
|
+
public async resolveVariantId(sku: string): Promise<string> {
|
|
203
|
+
// FIXME: Medusa does not support searching by SKU directly, so we have to use the admin client to search for products with variants matching the SKU
|
|
204
|
+
const product = await this.resolveProductForSKU(sku);
|
|
205
|
+
|
|
206
|
+
const variant = product.variants?.find((v) => v.sku === sku);
|
|
207
|
+
if (!variant) {
|
|
208
|
+
throw new Error(`Variant with SKU ${sku} not found`);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return variant.id;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
public async getClient(): Promise<Medusa> {
|
|
215
|
+
if (!this.client) {
|
|
216
|
+
this.client = this.createAuthenticatedClient(this.context);
|
|
217
|
+
}
|
|
218
|
+
return await this.client;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
public getSessionData(): MedusaSession {
|
|
222
|
+
return this.context.session[SESSION_KEY]
|
|
223
|
+
? this.context.session[SESSION_KEY]
|
|
224
|
+
: MedusaSessionSchema.parse({});
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
public setSessionData(sessionData: Partial<MedusaSession>): void {
|
|
228
|
+
const existingData = this.context.session[SESSION_KEY];
|
|
229
|
+
|
|
230
|
+
this.context.session[SESSION_KEY] = {
|
|
231
|
+
...existingData,
|
|
232
|
+
...sessionData,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
public async register(
|
|
237
|
+
email: string,
|
|
238
|
+
password: string,
|
|
239
|
+
firstName: string,
|
|
240
|
+
lastName: string,
|
|
241
|
+
reqCtx: RequestContext
|
|
242
|
+
) {
|
|
243
|
+
try {
|
|
244
|
+
// Create customer account
|
|
245
|
+
const client = await this.getClient();
|
|
246
|
+
const tokenResponse = await client.auth.register(
|
|
247
|
+
'customer',
|
|
248
|
+
'emailpass',
|
|
249
|
+
{
|
|
250
|
+
email,
|
|
251
|
+
password,
|
|
252
|
+
}
|
|
253
|
+
);
|
|
254
|
+
|
|
255
|
+
const customer = await client.store.customer.create({
|
|
256
|
+
email,
|
|
257
|
+
first_name: firstName,
|
|
258
|
+
last_name: lastName,
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
// Automatically log in after registration
|
|
262
|
+
const identity = await this.login(email, password, reqCtx);
|
|
263
|
+
|
|
264
|
+
return identity;
|
|
265
|
+
} catch (error) {
|
|
266
|
+
debug('Registration failed:', error);
|
|
267
|
+
throw new Error(
|
|
268
|
+
`Registration failed: ${
|
|
269
|
+
error instanceof Error ? error.message : 'Unknown error'
|
|
270
|
+
}`
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
public async login(email: string, password: string, reqCtx: RequestContext) {
|
|
276
|
+
try {
|
|
277
|
+
const client = await this.getClient();
|
|
278
|
+
// Authenticate with Medusa
|
|
279
|
+
const authResult = await client.auth.login('customer', 'emailpass', {
|
|
280
|
+
email,
|
|
281
|
+
password,
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
if (typeof authResult === 'string') {
|
|
285
|
+
const token = authResult;
|
|
286
|
+
if (token) {
|
|
287
|
+
// await tokenStore.setToken(token);
|
|
288
|
+
await client.client.setToken(token);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// Get customer details
|
|
293
|
+
const customerResponse = await client.store.customer.retrieve();
|
|
294
|
+
|
|
295
|
+
if (customerResponse.customer) {
|
|
296
|
+
const identity = {
|
|
297
|
+
id: {
|
|
298
|
+
userId: customerResponse.customer.id,
|
|
299
|
+
},
|
|
300
|
+
type: 'Registered',
|
|
301
|
+
} satisfies RegisteredIdentity;
|
|
302
|
+
return identity;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
return {
|
|
306
|
+
type: 'Anonymous',
|
|
307
|
+
} satisfies AnonymousIdentity;
|
|
308
|
+
} catch (error) {
|
|
309
|
+
debug('Login failed:', error);
|
|
310
|
+
throw new Error(
|
|
311
|
+
`Login failed: ${
|
|
312
|
+
error instanceof Error ? error.message : 'Unknown error'
|
|
313
|
+
}`
|
|
314
|
+
);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
public async logout(reqCtx: RequestContext) {
|
|
319
|
+
const identity = {
|
|
320
|
+
type: 'Anonymous',
|
|
321
|
+
} satisfies AnonymousIdentity;
|
|
322
|
+
|
|
323
|
+
const client = await this.getClient();
|
|
324
|
+
try {
|
|
325
|
+
// Clear the session on Medusa side
|
|
326
|
+
await client.auth.logout();
|
|
327
|
+
await client.client.clearToken();
|
|
328
|
+
|
|
329
|
+
return identity;
|
|
330
|
+
} catch (error) {
|
|
331
|
+
debug('Logout failed:', error);
|
|
332
|
+
await client.client.clearToken();
|
|
333
|
+
|
|
334
|
+
return identity;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
protected async createAuthenticatedClient(
|
|
339
|
+
reqCtx: RequestContext
|
|
340
|
+
): Promise<Medusa> {
|
|
341
|
+
const tokenStore = new RequestContextTokenStore(reqCtx);
|
|
342
|
+
|
|
343
|
+
// Create a client instance
|
|
344
|
+
const authenticatedClient = new Medusa({
|
|
345
|
+
baseUrl: this.config.apiUrl,
|
|
346
|
+
publishableKey: this.config.publishable_key,
|
|
347
|
+
debug: true,
|
|
348
|
+
|
|
349
|
+
auth: {
|
|
350
|
+
type: 'jwt',
|
|
351
|
+
jwtTokenStorageMethod: 'custom',
|
|
352
|
+
storage: tokenStore,
|
|
353
|
+
},
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
// If we have a token, set it for authenticated requests
|
|
357
|
+
/*
|
|
358
|
+
if (initialToken) {
|
|
359
|
+
// Set the authorization header for authenticated requests
|
|
360
|
+
await authenticatedClient.client.setToken(initialToken);
|
|
361
|
+
const token = await authenticatedClient.client.getToken()
|
|
362
|
+
if (!token) {
|
|
363
|
+
debug('Token validation failed, clearing token');
|
|
364
|
+
await tokenStore.clearToken();
|
|
365
|
+
}
|
|
366
|
+
}*/
|
|
367
|
+
|
|
368
|
+
return authenticatedClient;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
Cache,
|
|
3
|
+
ClientFromCapabilities,
|
|
4
|
+
RequestContext
|
|
5
|
+
} from "@reactionary/core";
|
|
6
|
+
import { MedusaCartProvider } from "../providers/cart.provider.js";
|
|
7
|
+
import { MedusaCategoryProvider } from "../providers/category.provider.js";
|
|
8
|
+
import { MedusaCheckoutProvider } from "../providers/checkout.provider.js";
|
|
9
|
+
import { MedusaIdentityProvider } from "../providers/identity.provider.js";
|
|
10
|
+
import { MedusaInventoryProvider } from "../providers/inventory.provider.js";
|
|
11
|
+
import { MedusaOrderSearchProvider } from "../providers/order-search.provider.js";
|
|
12
|
+
import { MedusaOrderProvider } from "../providers/order.provider.js";
|
|
13
|
+
import { MedusaPriceProvider } from "../providers/price.provider.js";
|
|
14
|
+
import { MedusaSearchProvider } from "../providers/product-search.provider.js";
|
|
15
|
+
import { MedusaProductProvider } from "../providers/product.provider.js";
|
|
16
|
+
import { MedusaProfileProvider } from "../providers/profile.provider.js";
|
|
17
|
+
import { MedusaCapabilitiesSchema, type MedusaCapabilities } from "../schema/capabilities.schema.js";
|
|
18
|
+
import { MedusaConfigurationSchema, type MedusaConfiguration } from "../schema/configuration.schema.js";
|
|
19
|
+
import { MedusaAPI } from "./client.js";
|
|
20
|
+
|
|
21
|
+
export function withMedusaCapabilities<T extends MedusaCapabilities>(
|
|
22
|
+
configuration: MedusaConfiguration,
|
|
23
|
+
capabilities: T
|
|
24
|
+
) {
|
|
25
|
+
return (cache: Cache, context: RequestContext): ClientFromCapabilities<T> => {
|
|
26
|
+
const client: any = {};
|
|
27
|
+
const config = MedusaConfigurationSchema.parse(configuration);
|
|
28
|
+
const caps = MedusaCapabilitiesSchema.parse(capabilities);
|
|
29
|
+
|
|
30
|
+
const medusaApi = new MedusaAPI(config, context);
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
if (caps.productSearch) {
|
|
34
|
+
client.productSearch = new MedusaSearchProvider(configuration, cache, context, medusaApi);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (caps.category) {
|
|
38
|
+
client.category = new MedusaCategoryProvider(configuration, cache, context, medusaApi);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (caps.checkout) {
|
|
42
|
+
client.checkout = new MedusaCheckoutProvider(configuration, cache, context, medusaApi);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (caps.product) {
|
|
46
|
+
client.product = new MedusaProductProvider(configuration, cache, context, medusaApi);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (caps.cart) {
|
|
50
|
+
client.cart = new MedusaCartProvider(configuration, cache, context, medusaApi);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (caps.price) {
|
|
54
|
+
client.price = new MedusaPriceProvider(configuration, cache, context, medusaApi);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (caps.inventory) {
|
|
58
|
+
client.inventory = new MedusaInventoryProvider(configuration, cache, context, medusaApi);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (caps.identity) {
|
|
62
|
+
client.identity = new MedusaIdentityProvider(configuration, cache, context, medusaApi);
|
|
63
|
+
}
|
|
64
|
+
if (caps.profile) {
|
|
65
|
+
client.profile = new MedusaProfileProvider(configuration, cache, context, medusaApi);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (caps.order) {
|
|
69
|
+
client.order = new MedusaOrderProvider(configuration, cache, context, medusaApi);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if(caps.orderSearch) {
|
|
73
|
+
client.orderSearch = new MedusaOrderSearchProvider(configuration, cache, context, medusaApi);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return client;
|
|
77
|
+
};
|
|
78
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export * from './schema/configuration.schema.js';
|
|
2
|
+
export * from './schema/medusa.schema.js';
|
|
3
|
+
export * from './schema/capabilities.schema.js';
|
|
4
|
+
export * from './core/initialize.js';
|
|
5
|
+
export * from './core/client.js';
|
|
6
|
+
export * from './providers/cart.provider.js';
|
|
7
|
+
export * from './providers/identity.provider.js';
|
|
8
|
+
export * from './providers/inventory.provider.js';
|
|
9
|
+
export * from './providers/order.provider.js';
|
|
10
|
+
export * from './providers/order-search.provider.js';
|
|
11
|
+
export * from './providers/price.provider.js';
|
|
12
|
+
export * from './providers/product-search.provider.js';
|
|
13
|
+
export * from './providers/profile.provider.js';
|