@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
@@ -1,75 +1,80 @@
1
1
  import 'dotenv/config';
2
- import type { RequestContext} from '@reactionary/core';
3
- import { NoOpCache, PriceSchema, createInitialRequestContext } from '@reactionary/core';
2
+ import type { RequestContext } from '@reactionary/core';
3
+ import {
4
+ NoOpCache,
5
+ PriceSchema,
6
+ createInitialRequestContext,
7
+ } from '@reactionary/core';
4
8
  import { getFakerTestConfiguration } from './test-utils.js';
5
9
  import { FakePriceProvider } from '../providers/price.provider.js';
10
+ import { describe, expect, it, beforeEach, assert } from 'vitest';
6
11
 
7
12
  const testData = {
8
13
  skuWithoutTiers: 'SGB-01',
9
- skuWithTiers: 'GMCT-01-with-tiers'
10
- }
14
+ skuWithTiers: 'GMCT-01-with-tiers',
15
+ };
11
16
 
12
17
  describe('Fake Price Provider', () => {
13
18
  let provider: FakePriceProvider;
14
19
  let reqCtx: RequestContext;
15
20
 
16
- beforeAll( () => {
17
- provider = new FakePriceProvider(getFakerTestConfiguration(), PriceSchema, new NoOpCache());
21
+ beforeEach(() => {
22
+ reqCtx = createInitialRequestContext();
23
+ provider = new FakePriceProvider(
24
+ getFakerTestConfiguration(),
25
+ new NoOpCache(),
26
+ reqCtx
27
+ );
18
28
  });
19
29
 
20
- beforeEach( () => {
21
- reqCtx = createInitialRequestContext()
22
- })
23
-
24
30
  it('should be able to get prices for a product without tiers', async () => {
25
- const result = await provider.getBySKU({ sku: { key: testData.skuWithoutTiers }}, reqCtx);
31
+ const result = await provider.getListPrice({
32
+ variant: { sku: testData.skuWithoutTiers },
33
+ });
26
34
 
27
- expect(result).toBeTruthy();
28
- if (result) {
29
- expect(result.identifier.sku.key).toBe(testData.skuWithoutTiers);
30
- expect(result.unitPrice.value).toBeGreaterThan(0);
31
- expect(result.unitPrice.currency).toBe('USD');
32
- expect(result.tieredPrices.length).toBe(0);
35
+ if (!result.success) {
36
+ assert.fail();
33
37
  }
38
+
39
+ expect(result.value.identifier.variant.sku).toBe(testData.skuWithoutTiers);
40
+ expect(result.value.unitPrice.value).toBeGreaterThan(0);
41
+ expect(result.value.unitPrice.currency).toBe('USD');
42
+ expect(result.value.tieredPrices.length).toBe(0);
34
43
  });
35
44
 
36
45
  it('should be able to get prices for a product with tiers', async () => {
37
- const result = await provider.getBySKU({ sku: { key: testData.skuWithTiers }}, reqCtx);
46
+ const result = await provider.getListPrice({
47
+ variant: { sku: testData.skuWithTiers },
48
+ });
38
49
 
39
- expect(result).toBeTruthy();
40
- if (result) {
41
- expect(result.identifier.sku.key).toBe(testData.skuWithTiers);
42
- expect(result.unitPrice.value).toBeGreaterThan(0);
43
- expect(result.unitPrice.currency).toBe('USD');
44
- expect(result.tieredPrices.length).toBeGreaterThan(0);
50
+ if (!result.success) {
51
+ assert.fail();
52
+ }
45
53
 
46
- expect(result.tieredPrices[0].minimumQuantity).toBeGreaterThan(0);
47
- expect(result.tieredPrices[0].price.value).toBeLessThanOrEqual(result.unitPrice.value);
48
- expect(result.tieredPrices[0].price.currency).toBe('USD');
54
+ expect(result.value.identifier.variant.sku).toBe(testData.skuWithTiers);
55
+ expect(result.value.unitPrice.value).toBeGreaterThan(0);
56
+ expect(result.value.unitPrice.currency).toBe('USD');
57
+ expect(result.value.tieredPrices.length).toBeGreaterThan(0);
49
58
 
50
- }
59
+ expect(result.value.tieredPrices[0].minimumQuantity).toBeGreaterThan(0);
60
+ expect(result.value.tieredPrices[0].price.value).toBeLessThanOrEqual(
61
+ result.value.unitPrice.value
62
+ );
63
+ expect(result.value.tieredPrices[0].price.currency).toBe('USD');
51
64
  });
52
65
 
53
66
  it('should return a placeholder price for an unknown SKU', async () => {
54
- const result = await provider.getBySKU({ sku: { key: 'unknown-sku' }}, reqCtx);
67
+ const result = await provider.getListPrice({
68
+ variant: { sku: 'unknown-sku' },
69
+ });
55
70
 
56
- expect(result).toBeTruthy();
57
- if (result) {
58
- expect(result.identifier.sku.key).toBe('unknown-sku');
59
- expect(result.unitPrice.value).toBe(-1);
60
- expect(result.unitPrice.currency).toBe('USD');
61
- expect(result.tieredPrices.length).toBe(0);
62
- expect(result.meta?.placeholder).toBe(true);
71
+ if (!result.success) {
72
+ assert.fail();
63
73
  }
64
- });
65
-
66
- it('can look up multiple prices at once', async () => {
67
- const skus = [testData.skuWithTiers, testData.skuWithoutTiers, 'unknown-sku'];
68
- const results = await Promise.all(skus.map( sku => provider.getBySKU({ sku: { key: sku }}, reqCtx)));
69
74
 
70
- expect(results).toHaveLength(skus.length);
71
- expect(results[0].identifier.sku.key).toBe(testData.skuWithTiers);
72
- expect(results[1].identifier.sku.key).toBe(testData.skuWithoutTiers);
73
- expect(results[2].identifier.sku.key).toBe('unknown-sku');
75
+ expect(result.value.identifier.variant.sku).toBe('unknown-sku');
76
+ expect(result.value.unitPrice.value).toBe(-1);
77
+ expect(result.value.unitPrice.currency).toBe('USD');
78
+ expect(result.value.tieredPrices.length).toBe(0);
74
79
  });
75
80
  });
@@ -1,27 +1,35 @@
1
1
  import 'dotenv/config';
2
2
 
3
3
  import type { RequestContext } from '@reactionary/core';
4
- import { createInitialRequestContext, MemoryCache, ProductSchema } from '@reactionary/core';
4
+ import { createInitialRequestContext, MemoryCache } from '@reactionary/core';
5
5
  import { getFakerTestConfiguration } from './test-utils.js';
6
6
  import { FakeProductProvider } from '../providers/index.js';
7
+ import { describe, expect, it, beforeEach, assert } from 'vitest';
7
8
 
8
9
  describe('Fake Product Provider', () => {
9
10
  let provider: FakeProductProvider;
10
11
  let reqCtx: RequestContext;
11
12
 
12
- beforeAll(async () => {
13
- provider = new FakeProductProvider(getFakerTestConfiguration(), ProductSchema, new MemoryCache());
14
- });
15
-
16
13
  beforeEach( () => {
17
14
  reqCtx = createInitialRequestContext();
15
+ provider = new FakeProductProvider(getFakerTestConfiguration(), new MemoryCache(), reqCtx);
18
16
  })
19
17
 
20
18
  it('should cache repeat product lookups by id', async () => {
21
- const first = await provider.getById({ id: '1234' }, reqCtx);
19
+ const first = await provider.getById({ identifier: { key : '1234' }});
20
+
21
+ if (!first.success) {
22
+ assert.fail();
23
+ }
24
+
22
25
  expect(first.meta.cache.hit).toBe(false);
23
26
 
24
- const second = await provider.getById({ id: '1234' }, reqCtx);
27
+ const second = await provider.getById({ identifier: { key : '1234' }});
28
+
29
+ if (!second.success) {
30
+ assert.fail();
31
+ }
32
+
25
33
  expect(second.meta.cache.hit).toBe(true);
26
34
  });
27
35
  });
@@ -0,0 +1,167 @@
1
+ import 'dotenv/config';
2
+ import type { RequestContext } from '@reactionary/core';
3
+ import { NoOpCache, createInitialRequestContext } from '@reactionary/core';
4
+ import { getFakerTestConfiguration } from './test-utils.js';
5
+ import { describe, expect, it, beforeEach, assert } from 'vitest';
6
+ import { FakeProfileProvider } from '../providers/profile.provider.js';
7
+
8
+ describe('Fake Profile Provider', () => {
9
+ let provider: FakeProfileProvider;
10
+ let reqCtx: RequestContext;
11
+
12
+ beforeEach(() => {
13
+ reqCtx = createInitialRequestContext();
14
+ provider = new FakeProfileProvider(
15
+ getFakerTestConfiguration(),
16
+ new NoOpCache(),
17
+ reqCtx
18
+ );
19
+ });
20
+
21
+ describe('should have operations return structurally valid data', () => {
22
+ it('for getById', async () => {
23
+ const result = await provider.getById({
24
+ identifier: {
25
+ userId: '1234',
26
+ },
27
+ });
28
+
29
+ if (!result.success) {
30
+ assert.fail();
31
+ }
32
+
33
+ expect(result.value.identifier.userId).toBe('1234');
34
+ });
35
+
36
+ it('for addShippingAddress', async () => {
37
+ const result = await provider.addShippingAddress({
38
+ address: {
39
+ city: 'City',
40
+ countryCode: 'DK',
41
+ firstName: 'FirstName',
42
+ lastName: 'LastName',
43
+ identifier: {
44
+ nickName: '1234Fake',
45
+ },
46
+ postalCode: '2300',
47
+ region: 'Region',
48
+ streetAddress: 'StreetAddress',
49
+ streetNumber: '42',
50
+ },
51
+ identifier: {
52
+ userId: '1234',
53
+ },
54
+ });
55
+
56
+ if (!result.success) {
57
+ assert.fail();
58
+ }
59
+
60
+ expect(result.value.identifier.userId).toBe('1234');
61
+ });
62
+
63
+ it('for makeShippingAddressDefault', async () => {
64
+ const result = await provider.makeShippingAddressDefault({
65
+ addressIdentifier: {
66
+ nickName: '1234Fake',
67
+ },
68
+ identifier: {
69
+ userId: '1234',
70
+ },
71
+ });
72
+
73
+ if (!result.success) {
74
+ assert.fail();
75
+ }
76
+
77
+ expect(result.value.identifier.userId).toBe('1234');
78
+ });
79
+
80
+ it('for removeShippingAddress', async () => {
81
+ const result = await provider.removeShippingAddress({
82
+ addressIdentifier: {
83
+ nickName: '1234Fake',
84
+ },
85
+ identifier: {
86
+ userId: '1234',
87
+ },
88
+ });
89
+
90
+ if (!result.success) {
91
+ assert.fail();
92
+ }
93
+
94
+ expect(result.value.identifier.userId).toBe('1234');
95
+ });
96
+
97
+ it('for setBillingAddress', async () => {
98
+ const result = await provider.setBillingAddress({
99
+ address: {
100
+ city: 'City',
101
+ countryCode: 'DK',
102
+ firstName: 'FirstName',
103
+ lastName: 'LastName',
104
+ identifier: {
105
+ nickName: '1234Fake',
106
+ },
107
+ postalCode: '2300',
108
+ region: 'Region',
109
+ streetAddress: 'StreetAddress',
110
+ streetNumber: '42',
111
+ },
112
+ identifier: {
113
+ userId: '1234',
114
+ },
115
+ });
116
+
117
+ if (!result.success) {
118
+ assert.fail();
119
+ }
120
+
121
+ expect(result.value.identifier.userId).toBe('1234');
122
+ });
123
+
124
+ it('for update', async () => {
125
+ const result = await provider.update({
126
+ email: 'foo@example.com',
127
+ identifier: {
128
+ userId: '1234',
129
+ },
130
+ phone: '40102030',
131
+ });
132
+
133
+ if (!result.success) {
134
+ assert.fail();
135
+ }
136
+
137
+ expect(result.value.identifier.userId).toBe('1234');
138
+ });
139
+
140
+ it('for updateShippingAddress', async () => {
141
+ const result = await provider.updateShippingAddress({
142
+ address: {
143
+ city: 'City',
144
+ countryCode: 'DK',
145
+ firstName: 'FirstName',
146
+ lastName: 'LastName',
147
+ identifier: {
148
+ nickName: '1234Fake',
149
+ },
150
+ postalCode: '2300',
151
+ region: 'Region',
152
+ streetAddress: 'StreetAddress',
153
+ streetNumber: '42',
154
+ },
155
+ identifier: {
156
+ userId: '1234',
157
+ },
158
+ });
159
+
160
+ if (!result.success) {
161
+ assert.fail();
162
+ }
163
+
164
+ expect(result.value.identifier.userId).toBe('1234');
165
+ });
166
+ });
167
+ });
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "extends": "../../tsconfig.base.json",
3
3
  "compilerOptions": {
4
- "module": "nodenext",
4
+ "module": "NodeNext",
5
5
  "moduleResolution": "nodenext",
6
6
  "forceConsistentCasingInFileNames": true,
7
7
  "strict": true,
@@ -6,6 +6,6 @@
6
6
  "types": ["node"]
7
7
  },
8
8
  "include": ["src/**/*.ts"],
9
- "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts", "src/**/test-utils.ts"]
9
+ "exclude": ["src/**/*.spec.ts", "src/**/*.test.ts", "src/**/test-utils.ts"]
10
10
 
11
11
  }
@@ -1,14 +1,4 @@
1
1
  {
2
- "extends": "./tsconfig.json",
3
- "compilerOptions": {
4
- "outDir": "../../dist/out-tsc",
5
- "types": ["jest", "node"]
6
- },
7
- "include": [
8
- "jest.config.cjs",
9
- "src/**/*.test.ts",
10
- "src/**/*.spec.ts",
11
- "src/**/test-utils.ts",
12
- "src/**/*.d.ts"
13
- ]
2
+ "extends": "./tsconfig.lib.json",
3
+ "exclude": []
14
4
  }
@@ -0,0 +1,14 @@
1
+ /// <reference types="vitest" />
2
+ import { defineConfig, defineProject } from 'vitest/config';
3
+ import { resolve } from 'path';
4
+ import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
5
+
6
+ export default defineProject({
7
+ plugins: [nxViteTsPaths()],
8
+ test: {
9
+ root: resolve(__dirname),
10
+ globals: true,
11
+ environment: 'node',
12
+ include: ['src/**/*.spec.ts', 'src/**/*.test.ts'],
13
+ },
14
+ });
@@ -0,0 +1,30 @@
1
+ # Medusa provider for Reactionary
2
+
3
+ ## Supports
4
+
5
+ | Feature | Support | Notes |
6
+ | ----------- | ----------- | --------- |
7
+ | product | Full (*) | Mandatory customization to support lookup by sku |
8
+ | productSearch | Partial | No facets in medusa search |
9
+ | identity | Planned | |
10
+ | cart | Full | |
11
+ | checkout | In progress | |
12
+ | order | Planned | |
13
+ | inventory | Planned | |
14
+ | price | Planned | |
15
+ | category | Planned | |
16
+ | store | Planned | |
17
+
18
+
19
+ ## Notes
20
+ Medusa is expected to be version 2.11+
21
+
22
+
23
+ ## Workarounds in place
24
+ Medusa needs an Admin key, to be able to do the following things
25
+ - Resolve product by SKU.
26
+
27
+ Since medusa can't search and filter on `sku`, you have to import the value for `sku` into `barcode`, `ean` or `upc`. Either will do.
28
+ The assumption is, that your SKU is either an semi-internal erp dictated partnumber, OR the products `gtin`.
29
+
30
+
@@ -0,0 +1,98 @@
1
+ # Medusa Provider Testing
2
+
3
+ This document describes the testing setup for the Medusa provider.
4
+
5
+ ## Test Setup
6
+
7
+ The Medusa provider uses [Vitest](https://vitest.dev/) for testing, which is already configured in the workspace.
8
+
9
+ ### Configuration
10
+
11
+ - **Test runner**: Vitest
12
+ - **Configuration**: `vitest.config.ts`
13
+ - **Test files**: `src/**/*.spec.ts` and `src/**/*.test.ts`
14
+ - **Coverage**: HTML and text reports
15
+
16
+ ### Running Tests
17
+
18
+ ```bash
19
+ # Run all tests
20
+ npx nx test medusa
21
+
22
+ # Run tests in watch mode
23
+ npx nx test:watch medusa
24
+
25
+ # Run tests with UI
26
+ npx nx test:ui medusa
27
+
28
+ # Run tests with coverage
29
+ npx nx test medusa --coverage
30
+ ```
31
+
32
+ ### Test Structure
33
+
34
+ Tests are organized by component:
35
+
36
+ - `src/core/client.spec.ts` - Tests for MedusaClient
37
+ - `src/providers/cart.provider.spec.ts` - Tests for MedusaCartProvider
38
+
39
+ ### Mocking
40
+
41
+ The tests use Vitest's built-in mocking capabilities:
42
+
43
+ - **Medusa SDK**: Mocked using `vi.mock('@medusajs/js-sdk')`
44
+ - **Debug**: Mocked using `vi.mock('debug')`
45
+ - **External dependencies**: Mocked as needed
46
+
47
+ ### Coverage
48
+
49
+ Coverage reports are generated in the `../../coverage/providers/medusa` directory and include:
50
+
51
+ - Line coverage
52
+ - Branch coverage
53
+ - Function coverage
54
+ - Statement coverage
55
+
56
+ HTML reports can be viewed by opening `coverage/index.html` in a browser.
57
+
58
+ ## Writing Tests
59
+
60
+ ### Example Test Structure
61
+
62
+ ```typescript
63
+ import { describe, it, expect, beforeEach, vi } from 'vitest';
64
+ import { MyClass } from './my-class.js';
65
+
66
+ // Mock external dependencies
67
+ vi.mock('external-library', () => ({
68
+ default: vi.fn(),
69
+ }));
70
+
71
+ describe('MyClass', () => {
72
+ let instance: MyClass;
73
+
74
+ beforeEach(() => {
75
+ instance = new MyClass();
76
+ });
77
+
78
+ describe('method', () => {
79
+ it('should do something', () => {
80
+ const result = instance.method();
81
+ expect(result).toBe(expected);
82
+ });
83
+ });
84
+ });
85
+ ```
86
+
87
+ ### Best Practices
88
+
89
+ 1. **Use descriptive test names** that explain what the test does
90
+ 2. **Group related tests** using `describe` blocks
91
+ 3. **Mock external dependencies** to keep tests isolated
92
+ 4. **Test both success and error cases**
93
+ 5. **Use beforeEach** for common setup
94
+ 6. **Assert on behavior**, not implementation details
95
+
96
+ ## Continuous Integration
97
+
98
+ Tests are automatically run as part of the CI/CD pipeline and must pass before code can be merged.
@@ -0,0 +1,19 @@
1
+ import baseConfig from '../../eslint.config.mjs';
2
+
3
+ export default [
4
+ ...baseConfig,
5
+ {
6
+ files: ['**/*.json'],
7
+ rules: {
8
+ '@nx/dependency-checks': [
9
+ 'error',
10
+ {
11
+ ignoredFiles: ['{projectRoot}/eslint.config.{js,cjs,mjs}'],
12
+ },
13
+ ],
14
+ },
15
+ languageOptions: {
16
+ parser: await import('jsonc-eslint-parser'),
17
+ },
18
+ },
19
+ ];
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "@reactionary/provider-medusa",
3
+ "version": "0.0.1",
4
+ "type": "module",
5
+ "main": "index.js",
6
+ "types": "src/index.d.ts",
7
+ "dependencies": {
8
+ "zod": "4.1.9",
9
+ "@reactionary/core": "0.0.1",
10
+ "@medusajs/js-sdk": "^2.0.0",
11
+ "debug": "^4.3.4",
12
+ "@medusajs/types": "^2.11.0",
13
+ "dotenv": "^17.2.2"
14
+ },
15
+ "devDependencies": {
16
+ "vitest": "*",
17
+ "@vitest/ui": "*",
18
+ "@vitest/coverage-v8": "*",
19
+ "vite-tsconfig-paths": "*"
20
+ },
21
+ "sideEffects": false
22
+ }
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "provider-medusa",
3
+ "$schema": "../../node_modules/nx/schemas/project-schema.json",
4
+ "sourceRoot": "providers/medusa/src",
5
+ "projectType": "library",
6
+ "release": {
7
+ "version": {
8
+ "currentVersionResolver": "git-tag",
9
+ "fallbackCurrentVersionResolver": "disk",
10
+ "preserveLocalDependencyProtocols": false,
11
+ "manifestRootsToUpdate": ["dist/{projectRoot}"]
12
+ }
13
+ },
14
+ "tags": [],
15
+ "targets": {
16
+ "build": {
17
+ "executor": "@nx/esbuild:esbuild",
18
+ "outputs": ["{options.outputPath}"],
19
+ "options": {
20
+ "outputPath": "dist/providers/medusa",
21
+ "main": "providers/medusa/src/index.ts",
22
+ "tsConfig": "providers/medusa/tsconfig.lib.json",
23
+ "assets": ["providers/medusa/*.md"],
24
+ "format": ["esm"],
25
+ "bundle": false
26
+ }
27
+ },
28
+ "nx-release-publish": {
29
+ "options": {
30
+ "packageRoot": "dist/{projectRoot}"
31
+ }
32
+ }
33
+ }
34
+ }