@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.
Files changed (293) hide show
  1. package/.env-template +19 -0
  2. package/.github/workflows/pull-request.yml +3 -1
  3. package/.github/workflows/release.yml +9 -0
  4. package/.vscode/extensions.json +0 -2
  5. package/LICENSE +21 -0
  6. package/README.md +175 -23
  7. package/core/package.json +6 -3
  8. package/core/src/cache/cache.interface.ts +1 -0
  9. package/core/src/cache/index.ts +4 -0
  10. package/core/src/cache/memory-cache.ts +30 -2
  11. package/core/src/cache/noop-cache.ts +15 -1
  12. package/core/src/cache/redis-cache.ts +20 -0
  13. package/core/src/client/client-builder.ts +71 -54
  14. package/core/src/client/client.ts +9 -47
  15. package/core/src/client/index.ts +2 -0
  16. package/core/src/decorators/index.ts +1 -0
  17. package/core/src/decorators/reactionary.decorator.ts +203 -34
  18. package/core/src/index.ts +6 -19
  19. package/core/src/initialization.ts +1 -18
  20. package/core/src/metrics/metrics.ts +67 -0
  21. package/core/src/providers/analytics.provider.ts +1 -6
  22. package/core/src/providers/base.provider.ts +5 -69
  23. package/core/src/providers/cart.provider.ts +15 -55
  24. package/core/src/providers/category.provider.ts +7 -11
  25. package/core/src/providers/checkout.provider.ts +17 -15
  26. package/core/src/providers/identity.provider.ts +6 -8
  27. package/core/src/providers/index.ts +2 -1
  28. package/core/src/providers/inventory.provider.ts +15 -5
  29. package/core/src/providers/order-search.provider.ts +29 -0
  30. package/core/src/providers/order.provider.ts +47 -15
  31. package/core/src/providers/price.provider.ts +30 -36
  32. package/core/src/providers/product-search.provider.ts +61 -0
  33. package/core/src/providers/product.provider.ts +71 -12
  34. package/core/src/providers/profile.provider.ts +74 -14
  35. package/core/src/providers/store.provider.ts +3 -5
  36. package/core/src/schemas/capabilities.schema.ts +10 -3
  37. package/core/src/schemas/errors/generic.error.ts +9 -0
  38. package/core/src/schemas/errors/index.ts +4 -0
  39. package/core/src/schemas/errors/invalid-input.error.ts +9 -0
  40. package/core/src/schemas/errors/invalid-output.error.ts +9 -0
  41. package/core/src/schemas/errors/not-found.error.ts +9 -0
  42. package/core/src/schemas/index.ts +7 -0
  43. package/core/src/schemas/models/analytics.model.ts +2 -1
  44. package/core/src/schemas/models/base.model.ts +6 -24
  45. package/core/src/schemas/models/cart.model.ts +5 -8
  46. package/core/src/schemas/models/category.model.ts +4 -9
  47. package/core/src/schemas/models/checkout.model.ts +6 -7
  48. package/core/src/schemas/models/cost.model.ts +4 -3
  49. package/core/src/schemas/models/currency.model.ts +2 -1
  50. package/core/src/schemas/models/identifiers.model.ts +106 -62
  51. package/core/src/schemas/models/identity.model.ts +10 -19
  52. package/core/src/schemas/models/index.ts +2 -1
  53. package/core/src/schemas/models/inventory.model.ts +8 -5
  54. package/core/src/schemas/models/order-search.model.ts +28 -0
  55. package/core/src/schemas/models/order.model.ts +20 -26
  56. package/core/src/schemas/models/payment.model.ts +14 -17
  57. package/core/src/schemas/models/price.model.ts +11 -11
  58. package/core/src/schemas/models/product-search.model.ts +42 -0
  59. package/core/src/schemas/models/product.model.ts +64 -22
  60. package/core/src/schemas/models/profile.model.ts +19 -22
  61. package/core/src/schemas/models/shipping-method.model.ts +24 -29
  62. package/core/src/schemas/models/store.model.ts +9 -5
  63. package/core/src/schemas/mutations/analytics.mutation.ts +8 -7
  64. package/core/src/schemas/mutations/base.mutation.ts +2 -1
  65. package/core/src/schemas/mutations/cart.mutation.ts +33 -33
  66. package/core/src/schemas/mutations/checkout.mutation.ts +23 -30
  67. package/core/src/schemas/mutations/identity.mutation.ts +4 -3
  68. package/core/src/schemas/mutations/profile.mutation.ts +38 -3
  69. package/core/src/schemas/queries/base.query.ts +2 -1
  70. package/core/src/schemas/queries/cart.query.ts +3 -3
  71. package/core/src/schemas/queries/category.query.ts +18 -18
  72. package/core/src/schemas/queries/checkout.query.ts +7 -9
  73. package/core/src/schemas/queries/identity.query.ts +2 -1
  74. package/core/src/schemas/queries/index.ts +2 -1
  75. package/core/src/schemas/queries/inventory.query.ts +5 -5
  76. package/core/src/schemas/queries/order-search.query.ts +10 -0
  77. package/core/src/schemas/queries/order.query.ts +3 -2
  78. package/core/src/schemas/queries/price.query.ts +10 -4
  79. package/core/src/schemas/queries/product-search.query.ts +16 -0
  80. package/core/src/schemas/queries/product.query.ts +13 -6
  81. package/core/src/schemas/queries/profile.query.ts +5 -2
  82. package/core/src/schemas/queries/store.query.ts +6 -5
  83. package/core/src/schemas/result.ts +107 -0
  84. package/core/src/schemas/session.schema.ts +4 -4
  85. package/core/src/test/reactionary.decorator.spec.ts +249 -0
  86. package/core/src/zod-utils.ts +19 -0
  87. package/core/tsconfig.json +1 -1
  88. package/core/tsconfig.spec.json +2 -26
  89. package/core/vitest.config.ts +14 -0
  90. package/documentation/1-purpose.md +114 -0
  91. package/documentation/2-getting-started.md +229 -0
  92. package/documentation/3-querying-and-changing-data.md +74 -0
  93. package/documentation/4-product-data.md +107 -0
  94. package/documentation/5-cart-and-checkout.md +211 -0
  95. package/documentation/6-product-search.md +143 -0
  96. package/documentation/7-marketing.md +3 -0
  97. package/eslint.config.mjs +1 -0
  98. package/examples/node/eslint.config.mjs +1 -4
  99. package/examples/node/package.json +10 -3
  100. package/examples/node/project.json +4 -1
  101. package/examples/node/src/basic/basic-node-provider-model-extension.spec.ts +22 -23
  102. package/examples/node/src/basic/basic-node-provider-query-extension.spec.ts +15 -11
  103. package/examples/node/src/basic/basic-node-setup.spec.ts +44 -28
  104. package/examples/node/src/basic/client-creation.spec.ts +53 -0
  105. package/examples/node/src/capabilities/cart.spec.ts +255 -0
  106. package/examples/node/src/capabilities/category.spec.ts +193 -0
  107. package/examples/node/src/capabilities/checkout.spec.ts +341 -0
  108. package/examples/node/src/capabilities/identity.spec.ts +93 -0
  109. package/examples/node/src/capabilities/inventory.spec.ts +66 -0
  110. package/examples/node/src/capabilities/order-search.spec.ts +265 -0
  111. package/examples/node/src/capabilities/order.spec.ts +91 -0
  112. package/examples/node/src/capabilities/price.spec.ts +51 -0
  113. package/examples/node/src/capabilities/product-search.spec.ts +293 -0
  114. package/examples/node/src/capabilities/product.spec.ts +122 -0
  115. package/examples/node/src/capabilities/profile.spec.ts +316 -0
  116. package/examples/node/src/capabilities/store.spec.ts +26 -0
  117. package/examples/node/src/utils.ts +147 -0
  118. package/examples/node/tsconfig.json +9 -12
  119. package/examples/node/tsconfig.lib.json +1 -2
  120. package/examples/node/tsconfig.spec.json +2 -14
  121. package/examples/node/vitest.config.ts +14 -0
  122. package/migrations.json +22 -5
  123. package/nx.json +8 -47
  124. package/package.json +24 -96
  125. package/providers/algolia/README.md +39 -2
  126. package/providers/algolia/package.json +2 -1
  127. package/providers/algolia/src/core/initialize.ts +7 -14
  128. package/providers/algolia/src/index.ts +2 -4
  129. package/providers/algolia/src/providers/index.ts +1 -0
  130. package/providers/algolia/src/providers/product-search.provider.ts +241 -0
  131. package/providers/algolia/src/schema/capabilities.schema.ts +2 -3
  132. package/providers/algolia/src/schema/index.ts +3 -0
  133. package/providers/algolia/src/schema/search.schema.ts +8 -8
  134. package/providers/algolia/tsconfig.json +1 -1
  135. package/providers/algolia/tsconfig.lib.json +1 -1
  136. package/providers/algolia/tsconfig.spec.json +2 -14
  137. package/providers/algolia/vitest.config.ts +14 -0
  138. package/providers/commercetools/README.md +30 -3
  139. package/providers/commercetools/package.json +2 -1
  140. package/providers/commercetools/src/core/client.ts +178 -99
  141. package/providers/commercetools/src/core/initialize.ts +130 -74
  142. package/providers/commercetools/src/core/token-cache.ts +45 -0
  143. package/providers/commercetools/src/index.ts +3 -2
  144. package/providers/commercetools/src/providers/cart.provider.ts +281 -341
  145. package/providers/commercetools/src/providers/category.provider.ts +223 -138
  146. package/providers/commercetools/src/providers/checkout.provider.ts +631 -449
  147. package/providers/commercetools/src/providers/identity.provider.ts +50 -29
  148. package/providers/commercetools/src/providers/index.ts +2 -2
  149. package/providers/commercetools/src/providers/inventory.provider.ts +76 -74
  150. package/providers/commercetools/src/providers/order-search.provider.ts +220 -0
  151. package/providers/commercetools/src/providers/order.provider.ts +96 -61
  152. package/providers/commercetools/src/providers/price.provider.ts +147 -117
  153. package/providers/commercetools/src/providers/product-search.provider.ts +528 -0
  154. package/providers/commercetools/src/providers/product.provider.ts +249 -74
  155. package/providers/commercetools/src/providers/profile.provider.ts +445 -28
  156. package/providers/commercetools/src/providers/store.provider.ts +54 -40
  157. package/providers/commercetools/src/schema/capabilities.schema.ts +3 -1
  158. package/providers/commercetools/src/schema/commercetools.schema.ts +17 -3
  159. package/providers/commercetools/src/schema/configuration.schema.ts +1 -0
  160. package/providers/commercetools/src/schema/session.schema.ts +7 -0
  161. package/providers/commercetools/src/test/caching.spec.ts +82 -0
  162. package/providers/commercetools/src/test/identity.spec.ts +109 -0
  163. package/providers/commercetools/src/test/test-utils.ts +21 -19
  164. package/providers/commercetools/tsconfig.json +1 -1
  165. package/providers/commercetools/tsconfig.lib.json +1 -1
  166. package/providers/commercetools/tsconfig.spec.json +2 -14
  167. package/providers/commercetools/vitest.config.ts +15 -0
  168. package/providers/fake/README.md +20 -4
  169. package/providers/fake/package.json +2 -1
  170. package/providers/fake/src/core/initialize.ts +47 -49
  171. package/providers/fake/src/providers/analytics.provider.ts +5 -7
  172. package/providers/fake/src/providers/cart.provider.ts +163 -92
  173. package/providers/fake/src/providers/category.provider.ts +78 -50
  174. package/providers/fake/src/providers/checkout.provider.ts +254 -0
  175. package/providers/fake/src/providers/identity.provider.ts +57 -65
  176. package/providers/fake/src/providers/index.ts +6 -2
  177. package/providers/fake/src/providers/inventory.provider.ts +40 -36
  178. package/providers/fake/src/providers/order-search.provider.ts +78 -0
  179. package/providers/fake/src/providers/order.provider.ts +106 -0
  180. package/providers/fake/src/providers/price.provider.ts +93 -41
  181. package/providers/fake/src/providers/product-search.provider.ts +206 -0
  182. package/providers/fake/src/providers/product.provider.ts +56 -41
  183. package/providers/fake/src/providers/profile.provider.ts +147 -0
  184. package/providers/fake/src/providers/store.provider.ts +30 -20
  185. package/providers/fake/src/schema/capabilities.schema.ts +5 -1
  186. package/providers/fake/src/test/cart.provider.spec.ts +59 -80
  187. package/providers/fake/src/test/category.provider.spec.ts +145 -87
  188. package/providers/fake/src/test/checkout.provider.spec.ts +222 -0
  189. package/providers/fake/src/test/order-search.provider.spec.ts +50 -0
  190. package/providers/fake/src/test/order.provider.spec.ts +44 -0
  191. package/providers/fake/src/test/price.provider.spec.ts +50 -45
  192. package/providers/fake/src/test/product.provider.spec.ts +15 -7
  193. package/providers/fake/src/test/profile.provider.spec.ts +167 -0
  194. package/providers/fake/tsconfig.json +1 -1
  195. package/providers/fake/tsconfig.lib.json +1 -1
  196. package/providers/fake/tsconfig.spec.json +2 -12
  197. package/providers/fake/vitest.config.ts +14 -0
  198. package/providers/medusa/README.md +30 -0
  199. package/providers/medusa/TESTING.md +98 -0
  200. package/providers/medusa/eslint.config.mjs +19 -0
  201. package/providers/medusa/package.json +22 -0
  202. package/providers/medusa/project.json +34 -0
  203. package/providers/medusa/src/core/client.ts +370 -0
  204. package/providers/medusa/src/core/initialize.ts +78 -0
  205. package/providers/medusa/src/index.ts +13 -0
  206. package/providers/medusa/src/providers/cart.provider.ts +575 -0
  207. package/providers/medusa/src/providers/category.provider.ts +247 -0
  208. package/providers/medusa/src/providers/checkout.provider.ts +636 -0
  209. package/providers/medusa/src/providers/identity.provider.ts +137 -0
  210. package/providers/medusa/src/providers/inventory.provider.ts +173 -0
  211. package/providers/medusa/src/providers/order-search.provider.ts +202 -0
  212. package/providers/medusa/src/providers/order.provider.ts +226 -0
  213. package/providers/medusa/src/providers/price.provider.ts +140 -0
  214. package/providers/medusa/src/providers/product-search.provider.ts +243 -0
  215. package/providers/medusa/src/providers/product.provider.ts +261 -0
  216. package/providers/medusa/src/providers/profile.provider.ts +392 -0
  217. package/providers/medusa/src/schema/capabilities.schema.ts +18 -0
  218. package/providers/medusa/src/schema/configuration.schema.ts +11 -0
  219. package/providers/medusa/src/schema/medusa.schema.ts +31 -0
  220. package/providers/medusa/src/test/cart.provider.spec.ts +240 -0
  221. package/providers/medusa/src/test/category.provider.spec.ts +231 -0
  222. package/providers/medusa/src/test/checkout.spec.ts +349 -0
  223. package/providers/medusa/src/test/identity.provider.spec.ts +122 -0
  224. package/providers/medusa/src/test/inventory.provider.spec.ts +88 -0
  225. package/providers/medusa/src/test/large-cart.provider.spec.ts +103 -0
  226. package/providers/medusa/src/test/price.provider.spec.ts +104 -0
  227. package/providers/medusa/src/test/product.provider.spec.ts +146 -0
  228. package/providers/medusa/src/test/search.provider.spec.ts +203 -0
  229. package/providers/medusa/src/test/test-utils.ts +13 -0
  230. package/providers/medusa/src/utils/medusa-helpers.ts +89 -0
  231. package/providers/medusa/tsconfig.json +21 -0
  232. package/providers/medusa/tsconfig.lib.json +9 -0
  233. package/providers/medusa/tsconfig.spec.json +4 -0
  234. package/providers/medusa/vitest.config.ts +15 -0
  235. package/providers/meilisearch/README.md +48 -0
  236. package/providers/meilisearch/eslint.config.mjs +22 -0
  237. package/providers/meilisearch/package.json +13 -0
  238. package/providers/meilisearch/project.json +34 -0
  239. package/providers/meilisearch/src/core/initialize.ts +21 -0
  240. package/providers/meilisearch/src/index.ts +6 -0
  241. package/providers/meilisearch/src/providers/index.ts +1 -0
  242. package/providers/meilisearch/src/providers/order-search.provider.ts +222 -0
  243. package/providers/meilisearch/src/providers/product-search.provider.ts +251 -0
  244. package/providers/meilisearch/src/schema/capabilities.schema.ts +10 -0
  245. package/providers/meilisearch/src/schema/configuration.schema.ts +11 -0
  246. package/providers/meilisearch/src/schema/index.ts +3 -0
  247. package/providers/meilisearch/src/schema/search.schema.ts +14 -0
  248. package/providers/meilisearch/tsconfig.json +24 -0
  249. package/providers/meilisearch/tsconfig.lib.json +10 -0
  250. package/providers/meilisearch/tsconfig.spec.json +4 -0
  251. package/providers/meilisearch/vitest.config.ts +14 -0
  252. package/providers/posthog/package.json +2 -1
  253. package/providers/posthog/tsconfig.json +1 -1
  254. package/tsconfig.base.json +5 -0
  255. package/vitest.config.ts +10 -0
  256. package/core/src/providers/search.provider.ts +0 -18
  257. package/core/src/schemas/models/search.model.ts +0 -36
  258. package/core/src/schemas/queries/search.query.ts +0 -9
  259. package/examples/next/.swcrc +0 -30
  260. package/examples/next/eslint.config.mjs +0 -21
  261. package/examples/next/index.d.ts +0 -6
  262. package/examples/next/next-env.d.ts +0 -5
  263. package/examples/next/next.config.js +0 -31
  264. package/examples/next/project.json +0 -9
  265. package/examples/next/public/.gitkeep +0 -0
  266. package/examples/next/public/favicon.ico +0 -0
  267. package/examples/next/src/app/global.css +0 -0
  268. package/examples/next/src/app/layout.tsx +0 -18
  269. package/examples/next/src/app/page.module.scss +0 -2
  270. package/examples/next/src/app/page.tsx +0 -47
  271. package/examples/next/src/instrumentation.ts +0 -9
  272. package/examples/next/tsconfig.json +0 -44
  273. package/examples/node/jest.config.ts +0 -10
  274. package/jest.config.ts +0 -6
  275. package/jest.preset.js +0 -3
  276. package/providers/algolia/jest.config.ts +0 -10
  277. package/providers/algolia/src/providers/product.provider.ts +0 -66
  278. package/providers/algolia/src/providers/search.provider.ts +0 -106
  279. package/providers/algolia/src/test/search.provider.spec.ts +0 -91
  280. package/providers/commercetools/jest.config.cjs +0 -10
  281. package/providers/commercetools/src/providers/search.provider.ts +0 -96
  282. package/providers/commercetools/src/test/cart.provider.spec.ts +0 -199
  283. package/providers/commercetools/src/test/category.provider.spec.ts +0 -168
  284. package/providers/commercetools/src/test/checkout.provider.spec.ts +0 -312
  285. package/providers/commercetools/src/test/identity.provider.spec.ts +0 -88
  286. package/providers/commercetools/src/test/inventory.provider.spec.ts +0 -41
  287. package/providers/commercetools/src/test/price.provider.spec.ts +0 -81
  288. package/providers/commercetools/src/test/product.provider.spec.ts +0 -80
  289. package/providers/commercetools/src/test/profile.provider.spec.ts +0 -49
  290. package/providers/commercetools/src/test/search.provider.spec.ts +0 -61
  291. package/providers/commercetools/src/test/store.provider.spec.ts +0 -37
  292. package/providers/fake/jest.config.cjs +0 -10
  293. 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';