@reactionary/source 0.0.52 → 0.2.15

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 (292) 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 +159 -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 +137 -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 +201 -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 +16 -0
  240. package/providers/meilisearch/src/index.ts +5 -0
  241. package/providers/meilisearch/src/providers/index.ts +1 -0
  242. package/providers/meilisearch/src/providers/product-search.provider.ts +251 -0
  243. package/providers/meilisearch/src/schema/capabilities.schema.ts +9 -0
  244. package/providers/meilisearch/src/schema/configuration.schema.ts +10 -0
  245. package/providers/meilisearch/src/schema/index.ts +3 -0
  246. package/providers/meilisearch/src/schema/search.schema.ts +14 -0
  247. package/providers/meilisearch/tsconfig.json +24 -0
  248. package/providers/meilisearch/tsconfig.lib.json +10 -0
  249. package/providers/meilisearch/tsconfig.spec.json +4 -0
  250. package/providers/meilisearch/vitest.config.ts +14 -0
  251. package/providers/posthog/package.json +2 -1
  252. package/providers/posthog/tsconfig.json +1 -1
  253. package/tsconfig.base.json +5 -0
  254. package/vitest.config.ts +10 -0
  255. package/core/src/providers/search.provider.ts +0 -18
  256. package/core/src/schemas/models/search.model.ts +0 -36
  257. package/core/src/schemas/queries/search.query.ts +0 -9
  258. package/examples/next/.swcrc +0 -30
  259. package/examples/next/eslint.config.mjs +0 -21
  260. package/examples/next/index.d.ts +0 -6
  261. package/examples/next/next-env.d.ts +0 -5
  262. package/examples/next/next.config.js +0 -31
  263. package/examples/next/project.json +0 -9
  264. package/examples/next/public/.gitkeep +0 -0
  265. package/examples/next/public/favicon.ico +0 -0
  266. package/examples/next/src/app/global.css +0 -0
  267. package/examples/next/src/app/layout.tsx +0 -18
  268. package/examples/next/src/app/page.module.scss +0 -2
  269. package/examples/next/src/app/page.tsx +0 -47
  270. package/examples/next/src/instrumentation.ts +0 -9
  271. package/examples/next/tsconfig.json +0 -44
  272. package/examples/node/jest.config.ts +0 -10
  273. package/jest.config.ts +0 -6
  274. package/jest.preset.js +0 -3
  275. package/providers/algolia/jest.config.ts +0 -10
  276. package/providers/algolia/src/providers/product.provider.ts +0 -66
  277. package/providers/algolia/src/providers/search.provider.ts +0 -106
  278. package/providers/algolia/src/test/search.provider.spec.ts +0 -91
  279. package/providers/commercetools/jest.config.cjs +0 -10
  280. package/providers/commercetools/src/providers/search.provider.ts +0 -96
  281. package/providers/commercetools/src/test/cart.provider.spec.ts +0 -199
  282. package/providers/commercetools/src/test/category.provider.spec.ts +0 -168
  283. package/providers/commercetools/src/test/checkout.provider.spec.ts +0 -312
  284. package/providers/commercetools/src/test/identity.provider.spec.ts +0 -88
  285. package/providers/commercetools/src/test/inventory.provider.spec.ts +0 -41
  286. package/providers/commercetools/src/test/price.provider.spec.ts +0 -81
  287. package/providers/commercetools/src/test/product.provider.spec.ts +0 -80
  288. package/providers/commercetools/src/test/profile.provider.spec.ts +0 -49
  289. package/providers/commercetools/src/test/search.provider.spec.ts +0 -61
  290. package/providers/commercetools/src/test/store.provider.spec.ts +0 -37
  291. package/providers/fake/jest.config.cjs +0 -10
  292. package/providers/fake/src/providers/search.provider.ts +0 -132
package/package.json CHANGED
@@ -1,130 +1,58 @@
1
1
  {
2
2
  "name": "@reactionary/source",
3
- "version": "0.0.52",
3
+ "version": "0.2.15",
4
4
  "license": "MIT",
5
5
  "private": false,
6
6
  "dependencies": {
7
- "@angular/common": "~19.2.0",
8
- "@angular/compiler": "~19.2.0",
9
- "@angular/core": "~19.2.0",
10
- "@angular/forms": "~19.2.0",
11
- "@angular/platform-browser": "~19.2.0",
12
- "@angular/platform-browser-dynamic": "~19.2.0",
13
- "@angular/router": "~19.2.0",
14
7
  "@commercetools/platform-sdk": "^8.16.0",
15
8
  "@commercetools/ts-client": "^4.2.1",
16
- "@commercetools/ts-sdk-apm": "^4.0.0",
17
9
  "@faker-js/faker": "^9.8.0",
10
+ "@medusajs/js-sdk": "^2.13.0",
18
11
  "@opentelemetry/api": "^1.9.0",
19
12
  "@opentelemetry/core": "^2.0.1",
20
- "@opentelemetry/exporter-metrics-otlp-http": "^0.203.0",
21
- "@opentelemetry/exporter-trace-otlp-http": "^0.203.0",
22
- "@opentelemetry/instrumentation": "^0.203.0",
23
- "@opentelemetry/instrumentation-express": "^0.52.0",
24
- "@opentelemetry/instrumentation-http": "^0.203.0",
25
- "@opentelemetry/resources": "^2.0.1",
26
- "@opentelemetry/sdk-metrics": "^2.0.1",
27
- "@opentelemetry/sdk-node": "^0.203.0",
28
13
  "@opentelemetry/sdk-trace-base": "^2.0.1",
29
14
  "@opentelemetry/sdk-trace-node": "^2.0.1",
30
- "@opentelemetry/semantic-conventions": "^1.36.0",
31
- "@trpc/client": "^11.1.2",
32
- "@trpc/server": "^11.1.2",
33
15
  "@upstash/redis": "^1.34.9",
34
16
  "algoliasearch": "^5.23.4",
35
- "connect-redis": "^8.1.0",
36
- "cors": "^2.8.5",
37
17
  "debug": "^4.4.3",
38
18
  "dotenv": "^17.2.2",
39
- "express": "^5.1.0",
40
- "express-session": "^1.18.1",
41
- "ioredis": "^5.6.1",
42
- "next": "~15.2.4",
19
+ "meilisearch": "^0.55.0",
43
20
  "node-object-hash": "^3.1.1",
44
- "posthog-node": "^4.18.0",
45
- "react": "19.0.0",
46
- "react-dom": "19.0.0",
47
- "reflect-metadata": "^0.2.2",
48
- "rxjs": "~7.8.0",
21
+ "posthog-node": "^5.24.0",
49
22
  "search-insights": "^2.17.3",
50
- "superjson": "^2.2.2",
51
- "vue": "^3.5.13",
52
- "zod": "4.1.9",
53
- "zone.js": "~0.15.0"
23
+ "zod": "4.1.9"
54
24
  },
55
25
  "devDependencies": {
56
- "@angular-devkit/build-angular": "~19.2.0",
57
- "@angular-devkit/core": "~19.2.0",
58
- "@angular-devkit/schematics": "~19.2.0",
59
- "@angular/cli": "~19.2.0",
60
- "@angular/compiler-cli": "~19.2.0",
61
- "@angular/language-service": "~19.2.0",
62
26
  "@eslint/compat": "^1.1.1",
63
27
  "@eslint/eslintrc": "^2.1.1",
64
28
  "@eslint/js": "^9.8.0",
65
- "@next/eslint-plugin-next": "^15.2.4",
66
- "@nx/angular": "21.1.2",
67
- "@nx/devkit": "21.1.2",
68
- "@nx/esbuild": "21.1.2",
69
- "@nx/eslint": "21.1.2",
70
- "@nx/eslint-plugin": "21.1.2",
71
- "@nx/jest": "21.1.2",
72
- "@nx/js": "21.1.2",
73
- "@nx/next": "21.1.2",
74
- "@nx/node": "21.1.2",
75
- "@nx/playwright": "21.1.2",
76
- "@nx/vite": "21.1.2",
77
- "@nx/vue": "21.1.2",
78
- "@nx/web": "21.1.2",
79
- "@nx/workspace": "21.1.2",
80
- "@playwright/test": "^1.36.0",
81
- "@schematics/angular": "~19.2.0",
29
+ "@medusajs/types": "^2.11.0",
30
+ "@nx/devkit": "22.4.5",
31
+ "@nx/esbuild": "22.4.5",
32
+ "@nx/eslint": "22.4.5",
33
+ "@nx/eslint-plugin": "22.4.5",
34
+ "@nx/js": "22.4.5",
35
+ "@nx/node": "22.4.5",
36
+ "@nx/playwright": "22.4.5",
37
+ "@nx/vite": "22.4.5",
38
+ "@nx/vitest": "22.4.5",
39
+ "@nx/workspace": "22.4.5",
82
40
  "@swc-node/register": "~1.9.1",
83
41
  "@swc/cli": "~0.6.0",
84
42
  "@swc/core": "~1.5.7",
85
43
  "@swc/helpers": "~0.5.11",
86
44
  "@types/debug": "^4.1.12",
87
- "@types/jest": "^29.5.12",
88
- "@types/node": "18.16.9",
89
- "@types/react": "19.0.0",
90
- "@types/react-dom": "19.0.0",
91
- "@typescript-eslint/utils": "^8.19.0",
92
- "@vitejs/plugin-vue": "^5.2.3",
93
- "@vitest/coverage-v8": "^3.0.5",
94
- "@vitest/ui": "^3.0.0",
95
- "@vue/eslint-config-prettier": "7.1.0",
96
- "@vue/eslint-config-typescript": "^11.0.3",
97
- "@vue/test-utils": "^2.4.6",
98
- "angular-eslint": "^19.2.0",
99
- "esbuild": "^0.19.2",
100
- "eslint": "^9.8.0",
101
- "eslint-config-next": "^15.2.4",
102
- "eslint-config-prettier": "^10.0.0",
103
- "eslint-plugin-import": "2.31.0",
104
- "eslint-plugin-jsx-a11y": "6.10.1",
105
- "eslint-plugin-playwright": "^1.6.2",
106
- "eslint-plugin-react": "7.35.0",
107
- "eslint-plugin-react-hooks": "5.0.0",
108
- "eslint-plugin-vue": "^9.16.1",
109
- "jest": "^29.7.0",
110
- "jest-environment-jsdom": "^29.7.0",
111
- "jest-environment-node": "^29.7.0",
112
- "jest-preset-angular": "~14.4.0",
113
- "jiti": "2.4.2",
114
- "jsdom": "~22.1.0",
115
- "jsonc-eslint-parser": "^2.1.0",
116
- "nx": "21.1.2",
45
+ "@types/node": "^24.0.0",
46
+ "@typescript-eslint/utils": "^8.33.1",
47
+ "nx": "22.4.5",
117
48
  "prettier": "^2.6.2",
118
- "sass": "1.62.1",
119
- "ts-jest": "^29.1.0",
120
49
  "ts-node": "10.9.1",
121
50
  "tslib": "^2.3.0",
122
- "typescript": "~5.7.2",
123
- "typescript-eslint": "^8.19.0",
124
- "verdaccio": "^6.0.5",
125
- "vite": "^6.0.0",
126
- "vitest": "^3.0.0",
127
- "vue-tsc": "^2.2.8"
51
+ "typescript": "5.9.3",
52
+ "typescript-eslint": "^8.33.1",
53
+ "vite": "7.1.9",
54
+ "vite-tsconfig-paths": "^5.1.4",
55
+ "vitest": "^4.0.9"
128
56
  },
129
57
  "nx": {
130
58
  "includedScripts": []
@@ -1,6 +1,43 @@
1
- # provider-algolia
1
+ # Algolia provider for Reactionary
2
+
3
+ ## Supports
4
+
5
+
6
+ | Feature | Support | Notes |
7
+ | ----------- | ----------- | --------- |
8
+ | product | Full | |
9
+ | productSearch | Full | |
10
+ | identity | N/A | |
11
+ | cart | N/A | |
12
+ | checkout | N/A | |
13
+ | order | N/A | Possibly later |
14
+ | inventory | N/A | |
15
+ | price | N/A | |
16
+ | category | N/A | Possibly later |
17
+ | store | N/A | Possibly later |
18
+
19
+
20
+ ## Notes
21
+ The expected Algolia schema must contain at least these fields
22
+
23
+ ```json
24
+ {
25
+ objectID: string;
26
+ slug:string;
27
+ name: string;
28
+ variants: [
29
+ {
30
+ variantID: string;
31
+ image: string;
32
+ }
33
+ ]
34
+ }
35
+ ```
36
+
37
+ You can have more, for use with facets, and additional searchable fields, but these must be in the index, and constitutes what we are expecting to get back.
38
+
39
+ The `objectID` corrosponds to your productIdentifier, and `variantID` should match your SKU
2
40
 
3
- This library was generated with [Nx](https://nx.dev).
4
41
 
5
42
  ## Building
6
43
 
@@ -8,5 +8,6 @@
8
8
  "algoliasearch": "^5.23.4",
9
9
  "zod": "4.1.9"
10
10
  },
11
- "type": "module"
11
+ "type": "module",
12
+ "sideEffects": false
12
13
  }
@@ -1,21 +1,14 @@
1
- import type { Client, Cache } from "@reactionary/core";
2
- import { ProductSchema } from "@reactionary/core";
3
- import { AlgoliaProductProvider } from "../providers/product.provider.js";
4
- import { AlgoliaSearchProvider } from "../providers/search.provider.js";
1
+ import type { Cache, ClientFromCapabilities, RequestContext } from "@reactionary/core";
2
+ import { AlgoliaSearchProvider } from "../providers/product-search.provider.js";
5
3
  import type { AlgoliaCapabilities } from "../schema/capabilities.schema.js";
6
4
  import type { AlgoliaConfiguration } from "../schema/configuration.schema.js";
7
- import { AlgoliaSearchResultSchema } from "../schema/search.schema.js";
8
5
 
9
- export function withAlgoliaCapabilities(configuration: AlgoliaConfiguration, capabilities: AlgoliaCapabilities) {
10
- return (cache: Cache) => {
11
- const client: Partial<Client> = {};
6
+ export function withAlgoliaCapabilities<T extends AlgoliaCapabilities>(configuration: AlgoliaConfiguration, capabilities: T) {
7
+ return (cache: Cache, context: RequestContext): ClientFromCapabilities<T> => {
8
+ const client: any = {};
12
9
 
13
- if (capabilities.product) {
14
- client.product = new AlgoliaProductProvider(configuration, ProductSchema, cache);
15
- }
16
-
17
- if (capabilities.search) {
18
- client.search = new AlgoliaSearchProvider(configuration, AlgoliaSearchResultSchema, cache);
10
+ if (capabilities.productSearch) {
11
+ client.productSearch = new AlgoliaSearchProvider(configuration, cache, context);
19
12
  }
20
13
 
21
14
  return client;
@@ -1,7 +1,5 @@
1
1
  export * from './core/initialize.js';
2
-
3
- export * from './providers/product.provider.js';
4
- export * from './providers/search.provider.js';
2
+ export * from './providers/product-search.provider.js';
5
3
 
6
4
  export * from './schema/configuration.schema.js';
7
- export * from './schema/capabilities.schema.js';
5
+ export * from './schema/capabilities.schema.js';
@@ -0,0 +1 @@
1
+ export * from './product-search.provider.js';
@@ -0,0 +1,241 @@
1
+ import {
2
+ type Cache,
3
+ type FacetIdentifier,
4
+ FacetIdentifierSchema,
5
+ type FacetValueIdentifier,
6
+ FacetValueIdentifierSchema,
7
+ ImageSchema,
8
+ ProductSearchProvider,
9
+ type ProductSearchQueryByTerm,
10
+ ProductSearchQueryByTermSchema,
11
+ type ProductSearchQueryCreateNavigationFilter,
12
+ type ProductSearchResult,
13
+ type ProductSearchResultFacet,
14
+ ProductSearchResultFacetSchema,
15
+ type ProductSearchResultFacetValue,
16
+ ProductSearchResultFacetValueSchema,
17
+ type ProductSearchResultItem,
18
+ type ProductSearchResultItemVariant,
19
+ ProductSearchResultItemVariantSchema,
20
+ ProductSearchResultSchema,
21
+ Reactionary,
22
+ type RequestContext,
23
+ type Result,
24
+ success
25
+ } from '@reactionary/core';
26
+ import { algoliasearch, type SearchResponse } from 'algoliasearch';
27
+ import type { AlgoliaConfiguration } from '../schema/configuration.schema.js';
28
+ import type { AlgoliaProductSearchResult } from '../schema/search.schema.js';
29
+
30
+ interface AlgoliaNativeVariant {
31
+ sku: string;
32
+ image: string;
33
+ }
34
+
35
+ interface AlgoliaNativeRecord {
36
+ objectID: string;
37
+ slug?:string;
38
+ name?: string;
39
+ variants: Array<AlgoliaNativeVariant>;
40
+ }
41
+
42
+
43
+ export class AlgoliaSearchProvider extends ProductSearchProvider {
44
+ protected config: AlgoliaConfiguration;
45
+
46
+ constructor(config: AlgoliaConfiguration, cache: Cache, context: RequestContext) {
47
+ super(cache, context);
48
+ this.config = config;
49
+ }
50
+
51
+ @Reactionary({
52
+ inputSchema: ProductSearchQueryByTermSchema,
53
+ outputSchema: ProductSearchResultSchema
54
+ })
55
+ public override async queryByTerm(
56
+ payload: ProductSearchQueryByTerm
57
+ ): Promise<Result<ProductSearchResult>> {
58
+ const client = algoliasearch(this.config.appId, this.config.apiKey);
59
+
60
+ const facetsThatAreNotCategory = payload.search.facets.filter(x => x.facet.key !== 'categories');
61
+ const categoryFacet = payload.search.facets.find(x => x.facet.key === 'categories') || payload.search.categoryFilter;
62
+
63
+ const finalFilters = [...payload.search.filters || []];
64
+
65
+
66
+ const finalFacetFilters = [
67
+ ...facetsThatAreNotCategory.map(
68
+ (x) => `${x.facet.key}:${x.key}`
69
+ ),
70
+ ]
71
+ if (categoryFacet) {
72
+ finalFilters.push(`categories:"${categoryFacet.key}"`);
73
+ }
74
+
75
+
76
+ const remote = await client.search<AlgoliaNativeRecord>({
77
+ requests: [
78
+ {
79
+ indexName: this.config.indexName,
80
+ query: payload.search.term,
81
+ page: payload.search.paginationOptions.pageNumber - 1,
82
+ hitsPerPage: payload.search.paginationOptions.pageSize,
83
+ facets: ['*'],
84
+ analytics: true,
85
+ clickAnalytics: true,
86
+ facetFilters: finalFacetFilters,
87
+ filters: (finalFilters || [])
88
+ .join(' AND '),
89
+ },
90
+ ],
91
+ });
92
+
93
+ const input = remote.results[0] as SearchResponse<AlgoliaNativeRecord>;
94
+ const result = this.parsePaginatedResult(input, payload) as AlgoliaProductSearchResult;
95
+
96
+ // mark selected facets as active
97
+ for(const selectedFacet of payload.search.facets) {
98
+ const facet = result.facets.find((f) => f.identifier.key === selectedFacet.facet.key);
99
+ if(facet) {
100
+ const value = facet.values.find((v) => v.identifier.key === selectedFacet.key);
101
+ if(value) {
102
+ value.active = true;
103
+ }
104
+ }
105
+ }
106
+
107
+ return success(result);
108
+ }
109
+
110
+ public override async createCategoryNavigationFilter(payload: ProductSearchQueryCreateNavigationFilter): Promise<Result<FacetValueIdentifier>> {
111
+
112
+ const facetIdentifier = FacetIdentifierSchema.parse({
113
+ key: 'categories'
114
+ });
115
+ const facetValueIdentifier = FacetValueIdentifierSchema.parse({
116
+ facet: facetIdentifier,
117
+ key: payload.categoryPath.map(c => c.name).join(' > ')
118
+ });
119
+ return success(facetValueIdentifier);
120
+ }
121
+
122
+
123
+ protected parseSingle(body: AlgoliaNativeRecord) {
124
+ const product = {
125
+ identifier: { key: body.objectID },
126
+ name: body.name || body.objectID,
127
+ slug: body.slug || body.objectID,
128
+ variants: [ ... (body.variants || []) ].map(variant => this.parseVariant(variant, body)),
129
+ } satisfies ProductSearchResultItem;
130
+
131
+ return product;
132
+ }
133
+
134
+ protected override parseVariant(variant: AlgoliaNativeVariant, product: AlgoliaNativeRecord): ProductSearchResultItemVariant {
135
+ const result = ProductSearchResultItemVariantSchema.parse({
136
+ variant: {
137
+ sku: variant.sku
138
+ },
139
+ image: ImageSchema.parse({
140
+ sourceUrl: variant.image,
141
+ altText: product.name || '',
142
+ })
143
+ } satisfies Partial<ProductSearchResultItemVariant>);
144
+
145
+ return result;
146
+ }
147
+
148
+ protected parsePaginatedResult(body: SearchResponse<AlgoliaNativeRecord>, query: ProductSearchQueryByTerm) {
149
+ const items = body.hits.map((hit) => this.parseSingle(hit));
150
+ let facets: ProductSearchResultFacet[] = [];
151
+ for (const id in body.facets) {
152
+ const f = body.facets[id];
153
+ const facetId = FacetIdentifierSchema.parse({
154
+ key: id
155
+ })
156
+ const facet = this.parseFacet(facetId, f);
157
+ facets.push(facet);
158
+ }
159
+
160
+
161
+ // we do something to convert the hierachy.lvl.n facet values into something more usable
162
+ const selectedCategoryFacet = query.search.facets.find(x => x.facet.key === 'categories') || query.search.categoryFilter;
163
+ let subCategoryFacet;
164
+ if(selectedCategoryFacet) {
165
+ const valueDepth = selectedCategoryFacet.key.split(' > ').length;
166
+ // ok, so input defined a facet value from level X, we return hierarchy.lvl.(X+1) as subcategories.
167
+ // hierarchy counts from 0, so length is already pointing to 'lvl.(X+1)'
168
+ subCategoryFacet = facets.find(f => f.identifier.key === `hierarchy.lvl${valueDepth}`);
169
+ } else {
170
+ // and remap lvl0 to 'categories'
171
+ subCategoryFacet = facets.find(f => f.identifier.key === 'hierarchy.lvl0');
172
+ }
173
+
174
+ if(subCategoryFacet) {
175
+ // remap to 'categories' facet
176
+ subCategoryFacet.identifier = FacetIdentifierSchema.parse({
177
+ key: 'categories'
178
+ });
179
+ subCategoryFacet.name = 'Categories';
180
+ for(const v of subCategoryFacet.values) {
181
+ const pathParts = v.identifier.key.split(' > ');
182
+ v.identifier.facet = subCategoryFacet.identifier;
183
+ v.name = pathParts[pathParts.length -1];
184
+ }
185
+ }
186
+
187
+ // remove other hierarchy facets
188
+ facets = facets.filter(f => !f.identifier.key.startsWith('hierarchy.lvl'));
189
+
190
+
191
+
192
+ const result = {
193
+ identifier: {
194
+ term: query.search.term,
195
+ facets: query.search.facets,
196
+ filters: query.search.filters,
197
+ paginationOptions: query.search.paginationOptions,
198
+
199
+ },
200
+ pageNumber: (body.page || 0) + 1,
201
+ pageSize: body.hitsPerPage || 0,
202
+ totalCount: body.nbHits || 0,
203
+ totalPages: body.nbPages || 0,
204
+ items: items,
205
+ facets,
206
+ } satisfies ProductSearchResult;
207
+
208
+ return result;
209
+ }
210
+
211
+ protected parseFacet(facetIdentifier: FacetIdentifier, facetValues: Record<string, number>) : ProductSearchResultFacet {
212
+ const result: ProductSearchResultFacet = ProductSearchResultFacetSchema.parse({
213
+ identifier: facetIdentifier,
214
+ name: facetIdentifier.key,
215
+ values: []
216
+ });
217
+
218
+ for (const vid in facetValues) {
219
+ const fv = facetValues[vid];
220
+
221
+ const facetValueIdentifier = FacetValueIdentifierSchema.parse({
222
+ facet: facetIdentifier,
223
+ key: vid
224
+ } satisfies Partial<FacetValueIdentifier>);
225
+
226
+ result.values.push(this.parseFacetValue(facetValueIdentifier, vid, fv));
227
+ }
228
+ return result;
229
+ }
230
+
231
+ protected parseFacetValue(facetValueIdentifier: FacetValueIdentifier, label: string, count: number) : ProductSearchResultFacetValue {
232
+ return ProductSearchResultFacetValueSchema.parse({
233
+ identifier: facetValueIdentifier,
234
+ name: label,
235
+ count: count,
236
+ active: false,
237
+ } satisfies Partial<ProductSearchResultFacetValue>);
238
+ }
239
+
240
+
241
+ }
@@ -2,9 +2,8 @@ import { CapabilitiesSchema } from "@reactionary/core";
2
2
  import type { z } from 'zod';
3
3
 
4
4
  export const AlgoliaCapabilitiesSchema = CapabilitiesSchema.pick({
5
- product: true,
6
- search: true,
5
+ productSearch: true,
7
6
  analytics: true
8
7
  }).partial();
9
8
 
10
- export type AlgoliaCapabilities = z.infer<typeof AlgoliaCapabilitiesSchema>;
9
+ export type AlgoliaCapabilities = z.infer<typeof AlgoliaCapabilitiesSchema>;
@@ -0,0 +1,3 @@
1
+ export * from './capabilities.schema.js';
2
+ export * from './configuration.schema.js';
3
+ export * from './search.schema.js';
@@ -1,14 +1,14 @@
1
- import { SearchIdentifierSchema, SearchResultSchema } from '@reactionary/core';
1
+ import { ProductSearchIdentifierSchema, ProductSearchResultSchema } from '@reactionary/core';
2
2
  import { z } from 'zod';
3
3
 
4
- export const AlgoliaSearchIdentifierSchema = SearchIdentifierSchema.extend({
5
- key: z.string().default(''),
6
- index: z.string().default('')
4
+ export const AlgoliaProductSearchIdentifierSchema = ProductSearchIdentifierSchema.extend({
5
+ key: z.string(),
6
+ index: z.string(),
7
7
  });
8
8
 
9
- export const AlgoliaSearchResultSchema = SearchResultSchema.extend({
10
- identifier: AlgoliaSearchIdentifierSchema.default(() => AlgoliaSearchIdentifierSchema.parse({}))
9
+ export const AlgoliaProductSearchResultSchema = ProductSearchResultSchema.extend({
10
+ identifier: AlgoliaProductSearchIdentifierSchema.default(() => AlgoliaProductSearchIdentifierSchema.parse({}))
11
11
  });
12
12
 
13
- export type AlgoliaSearchResult = z.infer<typeof AlgoliaSearchResultSchema>;
14
- export type AlgoliaSearchIdentifier = z.infer<typeof AlgoliaSearchIdentifierSchema>;
13
+ export type AlgoliaProductSearchResult = z.infer<typeof AlgoliaProductSearchResultSchema>;
14
+ export type AlgoliaProductSearchIdentifier = z.infer<typeof AlgoliaProductSearchIdentifierSchema>;
@@ -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,5 +6,5 @@
6
6
  "types": ["node"]
7
7
  },
8
8
  "include": ["src/**/*.ts"],
9
- "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"]
9
+ "exclude": ["src/**/*.spec.ts", "vitest.config.ts"]
10
10
  }
@@ -1,16 +1,4 @@
1
1
  {
2
- "extends": "./tsconfig.json",
3
- "compilerOptions": {
4
- "module": "commonjs",
5
- "moduleResolution": "node",
6
- "verbatimModuleSyntax": false,
7
- "outDir": "../../dist/out-tsc",
8
- "types": ["jest", "node"]
9
- },
10
- "include": [
11
- "jest.config.ts",
12
- "src/**/*.test.ts",
13
- "src/**/*.spec.ts",
14
- "src/**/*.d.ts"
15
- ]
2
+ "extends": "./tsconfig.lib.json",
3
+ "exclude": []
16
4
  }
@@ -0,0 +1,14 @@
1
+ import { defineConfig, defineProject } from 'vitest/config';
2
+ import tsconfigPaths from 'vite-tsconfig-paths';
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'],
13
+ },
14
+ });
@@ -1,6 +1,33 @@
1
- # provider-commercetools
1
+ # Commmercetools provider for Reactionary
2
+
3
+ ## Supports
4
+
5
+
6
+ | Feature | Support | Notes |
7
+ | ----------- | ----------- | --------- |
8
+ | product | Full | |
9
+ | productSearch | Full | |
10
+ | identity | Full | |
11
+ | cart | Full | |
12
+ | checkout | Full | |
13
+ | order | Full | |
14
+ | inventory | Full | |
15
+ | price | Full | |
16
+ | category | Full | |
17
+ | store | Full | |
18
+
19
+
20
+ ## Notes
21
+
22
+
23
+
24
+
25
+
26
+
27
+
28
+
29
+
2
30
 
3
- This library was generated with [Nx](https://nx.dev).
4
31
 
5
32
  ## Building
6
33
 
@@ -11,7 +38,7 @@ Run `nx build provider-commercetools` to build the library.
11
38
  Run `nx test provider-commercetools` to execute the unit tests via [Jest](https://jestjs.io).
12
39
 
13
40
 
14
- # ASSUMPTIONS for backend config
41
+ ## Assumptions for backend config
15
42
 
16
43
  - You will have 2 different channels for prices, one called `Offer Price` and one called `List Price`
17
44
  - ProductVariants will all have unique SKU values.
@@ -10,5 +10,6 @@
10
10
  "@commercetools/ts-client": "^4.2.1",
11
11
  "@commercetools/platform-sdk": "^8.8.0"
12
12
  },
13
- "type": "module"
13
+ "type": "module",
14
+ "sideEffects": false
14
15
  }