@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
@@ -1,47 +0,0 @@
1
- import styles from './page.module.scss';
2
- import { ClientBuilder, createInitialRequestContext, NoOpCache } from '@reactionary/core';
3
- import { withFakeCapabilities } from '@reactionary/provider-fake';
4
-
5
- export default async function Index() {
6
- const client = new ClientBuilder()
7
- .withCapability(
8
- withFakeCapabilities(
9
- {
10
- jitter: {
11
- mean: 0,
12
- deviation: 0,
13
- },
14
- seeds: {
15
- product: 1,
16
- search: 1,
17
- category: 1,
18
- },
19
- },
20
- { search: true, product: true, identity: false }
21
- )
22
- )
23
- .withCache(new NoOpCache())
24
- .build();
25
-
26
- const reqCtx = createInitialRequestContext();
27
- reqCtx.correlationId = 'nextjs-request-' + (new Date().getTime());
28
- const search = await client.search.queryByTerm(
29
- {
30
- search: {
31
- facets: [],
32
- page: 1,
33
- pageSize: 12,
34
- term: 'glass',
35
- },
36
- },
37
- reqCtx
38
- );
39
-
40
- return (
41
- <div className={styles.page}>
42
- {search.products.map((product, index) => (
43
- <div key={index}>{product.name}</div>
44
- ))}
45
- </div>
46
- );
47
- }
@@ -1,9 +0,0 @@
1
- export async function register() {
2
- if (process.env.NEXT_RUNTIME === 'nodejs') {
3
- const { NodeSDK } = await import('@opentelemetry/sdk-node');
4
-
5
- const sdk = new NodeSDK();
6
-
7
- sdk.start();
8
- }
9
- }
@@ -1,44 +0,0 @@
1
- {
2
- "extends": "../../tsconfig.base.json",
3
- "compilerOptions": {
4
- "jsx": "preserve",
5
- "strict": true,
6
- "noEmit": true,
7
- "emitDeclarationOnly": false,
8
- "esModuleInterop": true,
9
- "module": "esnext",
10
- "moduleResolution": "bundler",
11
- "resolveJsonModule": true,
12
- "isolatedModules": true,
13
- "lib": [
14
- "dom",
15
- "dom.iterable",
16
- "esnext"
17
- ],
18
- "allowJs": true,
19
- "allowSyntheticDefaultImports": true,
20
- "forceConsistentCasingInFileNames": true,
21
- "incremental": true,
22
- "plugins": [
23
- {
24
- "name": "next"
25
- }
26
- ]
27
- },
28
- "include": [
29
- "**/*.js",
30
- "**/*.jsx",
31
- "**/*.ts",
32
- "**/*.tsx",
33
- "../../dist/examples/next/.next/types/**/*.ts",
34
- "../../examples/next/.next/types/**/*.ts",
35
- "next-env.d.ts",
36
- ".next/types/**/*.ts"
37
- ],
38
- "exclude": [
39
- "node_modules",
40
- "jest.config.ts",
41
- "**/*.spec.ts",
42
- "**/*.test.ts"
43
- ]
44
- }
@@ -1,10 +0,0 @@
1
- export default {
2
- displayName: 'examples-node',
3
- preset: '../../jest.preset.js',
4
- testEnvironment: 'node',
5
- transform: {
6
- '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
7
- },
8
- moduleFileExtensions: ['ts', 'js', 'html'],
9
- coverageDirectory: '../../coverage/examples/node',
10
- };
package/jest.config.ts DELETED
@@ -1,6 +0,0 @@
1
- import type { Config } from 'jest';
2
- import { getJestProjectsAsync } from '@nx/jest';
3
-
4
- export default async (): Promise<Config> => ({
5
- projects: await getJestProjectsAsync(),
6
- });
package/jest.preset.js DELETED
@@ -1,3 +0,0 @@
1
- const nxPreset = require('@nx/jest/preset').default;
2
-
3
- module.exports = { ...nxPreset };
@@ -1,10 +0,0 @@
1
- export default {
2
- displayName: 'provider-algolia',
3
- preset: '../../jest.preset.js',
4
- testEnvironment: 'node',
5
- transform: {
6
- '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
7
- },
8
- moduleFileExtensions: ['ts', 'js', 'html'],
9
- coverageDirectory: '../../coverage/providers/algolia',
10
- };
@@ -1,66 +0,0 @@
1
- import type {
2
- Product,
3
- ProductQueryById,
4
- ProductQueryBySlug,
5
- RequestContext,
6
- Cache,
7
- ProductQueryBySKU
8
- } from '@reactionary/core';
9
- import {
10
- ProductProvider
11
- } from '@reactionary/core';
12
- import type { z } from 'zod';
13
- import type { AlgoliaConfiguration } from '../schema/configuration.schema.js';
14
-
15
- export class AlgoliaProductProvider<
16
- T extends Product = Product
17
- > extends ProductProvider<T> {
18
- protected config: AlgoliaConfiguration;
19
-
20
- constructor(config: AlgoliaConfiguration, schema: z.ZodType<T>, cache: Cache) {
21
- super(schema, cache);
22
-
23
- this.config = config;
24
- }
25
-
26
- public override async getById(
27
- payload: ProductQueryById,
28
- _reqCtx: RequestContext
29
- ): Promise<T> {
30
- // TODO: Implement Algolia product fetch by ID
31
- const result = this.newModel();
32
- result.identifier = { key: payload.id };
33
- result.name = `Algolia Product ${payload.id}`;
34
- result.slug = payload.id;
35
- result.description = 'Product from Algolia';
36
- result.meta = {
37
- cache: { hit: false, key: payload.id },
38
- placeholder: true
39
- };
40
-
41
- return this.assert(result);
42
- }
43
-
44
- public override async getBySlug(
45
- payload: ProductQueryBySlug,
46
- _reqCtx: RequestContext
47
- ): Promise<T> {
48
- // TODO: Implement Algolia product fetch by slug
49
- const result = this.newModel();
50
- result.identifier = { key: payload.slug };
51
- result.name = `Algolia Product ${payload.slug}`;
52
- result.slug = payload.slug;
53
- result.description = 'Product from Algolia';
54
- result.meta = {
55
- cache: { hit: false, key: payload.slug },
56
- placeholder: true
57
- };
58
-
59
- return this.assert(result);
60
- }
61
-
62
- public override getBySKU(payload: ProductQueryBySKU, reqCtx: RequestContext): Promise<T> {
63
- throw new Error('Method not implemented.');
64
- }
65
-
66
- }
@@ -1,106 +0,0 @@
1
- import {
2
- type SearchQueryByTerm,
3
- type SearchResult,
4
- type SearchResultFacet,
5
- type SearchResultProduct,
6
- type RequestContext,
7
- type Cache,
8
- SearchProvider,
9
- } from '@reactionary/core';
10
- import { algoliasearch } from 'algoliasearch';
11
- import type { z } from 'zod';
12
- import type { AlgoliaConfiguration } from '../schema/configuration.schema.js';
13
-
14
- export class AlgoliaSearchProvider<
15
- T extends SearchResult = SearchResult
16
- > extends SearchProvider<T> {
17
- protected config: AlgoliaConfiguration;
18
-
19
- constructor(config: AlgoliaConfiguration, schema: z.ZodType<T>, cache: Cache) {
20
- super(schema, cache);
21
-
22
- this.config = config;
23
- }
24
-
25
- public override async queryByTerm(
26
- payload: SearchQueryByTerm,
27
- _reqCtx: RequestContext
28
- ): Promise<SearchResult> {
29
- const client = algoliasearch(this.config.appId, this.config.apiKey);
30
- const remote = await client.search<unknown>({
31
- requests: [
32
- {
33
- indexName: this.config.indexName,
34
- query: payload.search.term,
35
- page: payload.search.page,
36
- hitsPerPage: payload.search.pageSize,
37
- facets: ['*'],
38
- analytics: true,
39
- clickAnalytics: true,
40
- facetFilters: payload.search.facets.map(
41
- (x) => `${encodeURIComponent(x.facet.key)}:${x.key}`
42
- ),
43
- },
44
- ],
45
- });
46
-
47
- return this.parseSearchResult(remote, payload);
48
- }
49
-
50
- protected parseSearchResult(remote: unknown, payload: SearchQueryByTerm): T {
51
- const result = this.newModel();
52
- const remoteData = remote as { results: Array<{ facets: Record<string, Record<string, number>>; hits: Array<{ objectID: string; slug?: string; name?: string; image?: string }>; index: string; queryID: string; nbPages: number }> };
53
- const remoteProducts = remoteData.results[0];
54
-
55
- // Parse facets
56
- for (const id in remoteProducts.facets) {
57
- const f = remoteProducts.facets[id];
58
-
59
- const facet = {
60
- identifier: { key: id },
61
- name: id,
62
- values: []
63
- } as SearchResultFacet;
64
-
65
- for (const vid in f) {
66
- const fv = f[vid];
67
- const isActive = payload.search.facets.find(
68
- (x) => x.facet.key === id && x.key === vid
69
- );
70
-
71
- facet.values.push({
72
- identifier: { key: vid, facet: { key: id } },
73
- count: fv,
74
- name: vid,
75
- active: !!isActive
76
- });
77
- }
78
-
79
- result.facets.push(facet);
80
- }
81
-
82
- // Parse products
83
- for (const p of remoteProducts.hits) {
84
- result.products.push({
85
- identifier: { key: p.objectID },
86
- slug: p.slug,
87
- name: p.name,
88
- image: p.image
89
- } as SearchResultProduct);
90
- }
91
-
92
- // Set result metadata
93
- result.identifier = {
94
- ...payload.search,
95
- index: remoteProducts.index,
96
- key: remoteProducts.queryID
97
- };
98
- result.pages = remoteProducts.nbPages;
99
- result.meta = {
100
- cache: { hit: false, key: payload.search.term },
101
- placeholder: false
102
- };
103
-
104
- return this.assert(result);
105
- }
106
- }
@@ -1,91 +0,0 @@
1
- import 'dotenv/config';
2
- import { createInitialRequestContext, NoOpCache, SearchResultSchema } from '@reactionary/core';
3
- import { AlgoliaSearchProvider } from '../providers/search.provider.js';
4
-
5
- describe('Algolia Search Provider', () => {
6
- const provider = new AlgoliaSearchProvider(
7
- {
8
- apiKey: process.env['ALGOLIA_API_KEY'] || '',
9
- appId: process.env['ALGOLIA_APP_ID'] || '',
10
- indexName: process.env['ALGOLIA_INDEX'] || '',
11
- },
12
- SearchResultSchema,
13
- new NoOpCache()
14
- );
15
-
16
- const reqCtx = createInitialRequestContext();
17
-
18
- it('should be able to get a result by term', async () => {
19
- const result = await provider.queryByTerm({ search: {
20
- term: 'glass',
21
- page: 0,
22
- pageSize: 20,
23
- facets: [],
24
- }}, reqCtx);
25
-
26
- expect(result.products.length).toBeGreaterThan(0);
27
- expect(result.facets.length).toBe(2);
28
- expect(result.facets[0].values.length).toBeGreaterThan(0);
29
- expect(result.facets[1].values.length).toBeGreaterThan(0);
30
- });
31
-
32
- it('should be able to paginate', async () => {
33
- const firstPage = await provider.queryByTerm({ search: {
34
- term: 'glass',
35
- page: 0,
36
- pageSize: 20,
37
- facets: [],
38
- }}, reqCtx);
39
-
40
- const secondPage = await provider.queryByTerm({ search: {
41
- term: 'glass',
42
- page: 1,
43
- pageSize: 20,
44
- facets: [],
45
- }}, reqCtx);
46
-
47
- expect(firstPage.identifier.page).toBe(0);
48
- expect(secondPage.identifier.page).toBe(1);
49
- expect(firstPage.products[0].identifier.key).not.toEqual(
50
- secondPage.products[0].identifier.key
51
- );
52
- });
53
-
54
- it('should be able to change page size', async () => {
55
- const smallPage = await provider.queryByTerm({ search: {
56
- term: 'glass',
57
- page: 0,
58
- pageSize: 2,
59
- facets: [],
60
- }}, reqCtx);
61
- const largePage = await provider.queryByTerm({ search: {
62
- term: 'glass',
63
- page: 0,
64
- pageSize: 30,
65
- facets: [],
66
- }}, reqCtx);
67
-
68
- expect(smallPage.products.length).toBe(2);
69
- expect(smallPage.identifier.pageSize).toBe(2);
70
- expect(largePage.products.length).toBe(30);
71
- expect(largePage.identifier.pageSize).toBe(30);
72
- });
73
-
74
- it('should be able to apply facets', async () => {
75
- const initial = await provider.queryByTerm({ search: {
76
- term: 'glass',
77
- page: 0,
78
- pageSize: 2,
79
- facets: [],
80
- }}, reqCtx);
81
-
82
- const filtered = await provider.queryByTerm({ search: {
83
- term: 'glass',
84
- page: 0,
85
- pageSize: 2,
86
- facets: [initial.facets[0].values[0].identifier],
87
- }}, reqCtx);
88
-
89
- expect(initial.pages).toBeGreaterThan(filtered.pages);
90
- });
91
- });
@@ -1,10 +0,0 @@
1
- module.exports = {
2
- displayName: 'provider-commercetools',
3
- preset: '../../jest.preset.js',
4
- testEnvironment: 'node',
5
- transform: {
6
- '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
7
- },
8
- moduleFileExtensions: ['ts', 'js', 'html'],
9
- coverageDirectory: '../../coverage/providers/commercetools',
10
- };
@@ -1,96 +0,0 @@
1
- import { SearchProvider } from '@reactionary/core';
2
- import type {
3
- SearchResult,
4
- SearchResultProduct,
5
- Cache,
6
- SearchQueryByTerm,
7
- RequestContext,
8
- } from '@reactionary/core';
9
-
10
- import { CommercetoolsClient } from '../core/client.js';
11
- import type z from 'zod';
12
- import type { CommercetoolsConfiguration } from '../schema/configuration.schema.js';
13
-
14
- export class CommercetoolsSearchProvider<
15
- T extends SearchResult = SearchResult
16
- > extends SearchProvider<T> {
17
- protected config: CommercetoolsConfiguration;
18
-
19
- constructor(
20
- config: CommercetoolsConfiguration,
21
- schema: z.ZodType<T>,
22
- cache: Cache
23
- ) {
24
- super(schema, cache);
25
-
26
- this.config = config;
27
- }
28
-
29
- protected async getClient(reqCtx: RequestContext) {
30
- const client = await new CommercetoolsClient(this.config).getClient(reqCtx);
31
- return client.withProjectKey({ projectKey: this.config.projectKey }).productProjections();
32
- }
33
-
34
-
35
- public override async queryByTerm(
36
- payload: SearchQueryByTerm,
37
- reqCtx: RequestContext
38
- ): Promise<T> {
39
- const client = await this.getClient(reqCtx);
40
-
41
- const remote = await client
42
- .search()
43
- .get({
44
- queryArgs: {
45
- limit: payload.search.pageSize,
46
- offset: (payload.search.page - 1) * payload.search.pageSize,
47
- [`text.${reqCtx.languageContext.locale}`]: payload.search.term,
48
- },
49
- })
50
- .execute();
51
-
52
- return this.parseSearchResult(remote, payload, reqCtx);
53
- }
54
-
55
- protected parseSearchResult(
56
- remote: unknown,
57
- payload: SearchQueryByTerm,
58
- reqCtx: RequestContext
59
- ): T {
60
- const result = this.newModel();
61
- const remoteData = remote as {
62
- body: {
63
- results: Array<{
64
- id: string;
65
- name: Record<string, string>;
66
- slug?: Record<string, string>;
67
- masterVariant: { images?: Array<{ url?: string }> };
68
- }>;
69
- total?: number;
70
- };
71
- };
72
-
73
- result.identifier = payload.search;
74
-
75
- for (const p of remoteData.body.results) {
76
- const product: SearchResultProduct = {
77
- identifier: { key: p.id },
78
- name: p.name[reqCtx.languageContext.locale] || p.id,
79
- slug: p.slug?.[reqCtx.languageContext.locale] || p.id,
80
- image: p.masterVariant.images?.[0]?.url || 'https://placehold.co/400',
81
- };
82
-
83
- result.products.push(product);
84
- }
85
-
86
- result.pages = Math.ceil(
87
- (remoteData.body.total || 0) / payload.search.pageSize
88
- );
89
- result.meta = {
90
- cache: { hit: false, key: payload.search.term },
91
- placeholder: false,
92
- };
93
-
94
- return this.assert(result);
95
- }
96
- }