@reactionary/source 0.0.51 → 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 (325) 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 -2
  8. package/core/src/cache/cache.interface.ts +2 -1
  9. package/core/src/cache/index.ts +4 -0
  10. package/core/src/cache/memory-cache.ts +32 -4
  11. package/core/src/cache/noop-cache.ts +16 -2
  12. package/core/src/cache/redis-cache.ts +21 -1
  13. package/core/src/client/client-builder.ts +71 -54
  14. package/core/src/client/client.ts +17 -55
  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 +210 -21
  18. package/core/src/index.ts +6 -19
  19. package/core/src/initialization.ts +2 -19
  20. package/core/src/metrics/metrics.ts +67 -0
  21. package/core/src/providers/analytics.provider.ts +2 -7
  22. package/core/src/providers/base.provider.ts +6 -70
  23. package/core/src/providers/cart.provider.ts +17 -57
  24. package/core/src/providers/category.provider.ts +9 -18
  25. package/core/src/providers/checkout.provider.ts +21 -19
  26. package/core/src/providers/identity.provider.ts +10 -12
  27. package/core/src/providers/index.ts +14 -13
  28. package/core/src/providers/inventory.provider.ts +18 -8
  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 +32 -38
  32. package/core/src/providers/product-search.provider.ts +61 -0
  33. package/core/src/providers/product.provider.ts +75 -16
  34. package/core/src/providers/profile.provider.ts +77 -17
  35. package/core/src/providers/store.provider.ts +6 -8
  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 +3 -2
  44. package/core/src/schemas/models/base.model.ts +6 -24
  45. package/core/src/schemas/models/cart.model.ts +7 -16
  46. package/core/src/schemas/models/category.model.ts +6 -11
  47. package/core/src/schemas/models/checkout.model.ts +11 -14
  48. package/core/src/schemas/models/cost.model.ts +5 -4
  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 +12 -21
  52. package/core/src/schemas/models/index.ts +20 -19
  53. package/core/src/schemas/models/inventory.model.ts +10 -7
  54. package/core/src/schemas/models/order-search.model.ts +28 -0
  55. package/core/src/schemas/models/order.model.ts +25 -32
  56. package/core/src/schemas/models/payment.model.ts +17 -20
  57. package/core/src/schemas/models/price.model.ts +14 -14
  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 +21 -24
  61. package/core/src/schemas/models/shipping-method.model.ts +28 -33
  62. package/core/src/schemas/models/store.model.ts +10 -6
  63. package/core/src/schemas/mutations/analytics.mutation.ts +9 -8
  64. package/core/src/schemas/mutations/base.mutation.ts +2 -1
  65. package/core/src/schemas/mutations/cart.mutation.ts +37 -37
  66. package/core/src/schemas/mutations/checkout.mutation.ts +24 -31
  67. package/core/src/schemas/mutations/identity.mutation.ts +5 -4
  68. package/core/src/schemas/mutations/index.ts +10 -10
  69. package/core/src/schemas/mutations/profile.mutation.ts +39 -4
  70. package/core/src/schemas/queries/base.query.ts +2 -1
  71. package/core/src/schemas/queries/cart.query.ts +5 -5
  72. package/core/src/schemas/queries/category.query.ts +21 -21
  73. package/core/src/schemas/queries/checkout.query.ts +9 -11
  74. package/core/src/schemas/queries/identity.query.ts +3 -2
  75. package/core/src/schemas/queries/index.ts +14 -13
  76. package/core/src/schemas/queries/inventory.query.ts +6 -6
  77. package/core/src/schemas/queries/order-search.query.ts +10 -0
  78. package/core/src/schemas/queries/order.query.ts +5 -4
  79. package/core/src/schemas/queries/price.query.ts +11 -5
  80. package/core/src/schemas/queries/product-search.query.ts +16 -0
  81. package/core/src/schemas/queries/product.query.ts +14 -7
  82. package/core/src/schemas/queries/profile.query.ts +6 -3
  83. package/core/src/schemas/queries/store.query.ts +7 -6
  84. package/core/src/schemas/result.ts +107 -0
  85. package/core/src/schemas/session.schema.ts +6 -6
  86. package/core/src/test/reactionary.decorator.spec.ts +249 -0
  87. package/core/src/zod-utils.ts +19 -0
  88. package/core/tsconfig.json +3 -2
  89. package/core/tsconfig.spec.json +2 -26
  90. package/core/vitest.config.ts +14 -0
  91. package/documentation/1-purpose.md +114 -0
  92. package/documentation/2-getting-started.md +229 -0
  93. package/documentation/3-querying-and-changing-data.md +74 -0
  94. package/documentation/4-product-data.md +107 -0
  95. package/documentation/5-cart-and-checkout.md +211 -0
  96. package/documentation/6-product-search.md +143 -0
  97. package/documentation/7-marketing.md +3 -0
  98. package/eslint.config.mjs +1 -0
  99. package/examples/node/eslint.config.mjs +1 -4
  100. package/examples/node/package.json +11 -3
  101. package/examples/node/project.json +4 -1
  102. package/examples/node/src/basic/basic-node-provider-model-extension.spec.ts +22 -23
  103. package/examples/node/src/basic/basic-node-provider-query-extension.spec.ts +15 -11
  104. package/examples/node/src/basic/basic-node-setup.spec.ts +44 -28
  105. package/examples/node/src/basic/client-creation.spec.ts +53 -0
  106. package/examples/node/src/capabilities/cart.spec.ts +255 -0
  107. package/examples/node/src/capabilities/category.spec.ts +193 -0
  108. package/examples/node/src/capabilities/checkout.spec.ts +341 -0
  109. package/examples/node/src/capabilities/identity.spec.ts +93 -0
  110. package/examples/node/src/capabilities/inventory.spec.ts +66 -0
  111. package/examples/node/src/capabilities/order-search.spec.ts +159 -0
  112. package/examples/node/src/capabilities/order.spec.ts +91 -0
  113. package/examples/node/src/capabilities/price.spec.ts +51 -0
  114. package/examples/node/src/capabilities/product-search.spec.ts +293 -0
  115. package/examples/node/src/capabilities/product.spec.ts +122 -0
  116. package/examples/node/src/capabilities/profile.spec.ts +316 -0
  117. package/examples/node/src/capabilities/store.spec.ts +26 -0
  118. package/examples/node/src/utils.ts +137 -0
  119. package/examples/node/tsconfig.json +9 -11
  120. package/examples/node/tsconfig.lib.json +1 -2
  121. package/examples/node/tsconfig.spec.json +2 -13
  122. package/examples/node/vitest.config.ts +14 -0
  123. package/migrations.json +22 -5
  124. package/nx.json +8 -47
  125. package/package.json +24 -96
  126. package/providers/algolia/README.md +39 -2
  127. package/providers/algolia/package.json +3 -1
  128. package/providers/algolia/src/core/initialize.ts +9 -16
  129. package/providers/algolia/src/index.ts +4 -6
  130. package/providers/algolia/src/providers/index.ts +1 -0
  131. package/providers/algolia/src/providers/product-search.provider.ts +241 -0
  132. package/providers/algolia/src/schema/capabilities.schema.ts +2 -3
  133. package/providers/algolia/src/schema/index.ts +3 -0
  134. package/providers/algolia/src/schema/search.schema.ts +8 -8
  135. package/providers/algolia/tsconfig.json +2 -1
  136. package/providers/algolia/tsconfig.lib.json +1 -1
  137. package/providers/algolia/tsconfig.spec.json +2 -13
  138. package/providers/algolia/vitest.config.ts +14 -0
  139. package/providers/commercetools/README.md +30 -3
  140. package/providers/commercetools/package.json +3 -2
  141. package/providers/commercetools/src/core/client.ts +179 -100
  142. package/providers/commercetools/src/core/initialize.ts +131 -75
  143. package/providers/commercetools/src/core/token-cache.ts +45 -0
  144. package/providers/commercetools/src/index.ts +11 -10
  145. package/providers/commercetools/src/providers/cart.provider.ts +282 -356
  146. package/providers/commercetools/src/providers/category.provider.ts +223 -147
  147. package/providers/commercetools/src/providers/checkout.provider.ts +631 -449
  148. package/providers/commercetools/src/providers/identity.provider.ts +51 -30
  149. package/providers/commercetools/src/providers/index.ts +12 -12
  150. package/providers/commercetools/src/providers/inventory.provider.ts +77 -77
  151. package/providers/commercetools/src/providers/order-search.provider.ts +220 -0
  152. package/providers/commercetools/src/providers/order.provider.ts +97 -64
  153. package/providers/commercetools/src/providers/price.provider.ts +148 -118
  154. package/providers/commercetools/src/providers/product-search.provider.ts +528 -0
  155. package/providers/commercetools/src/providers/product.provider.ts +251 -81
  156. package/providers/commercetools/src/providers/profile.provider.ts +446 -29
  157. package/providers/commercetools/src/providers/store.provider.ts +56 -42
  158. package/providers/commercetools/src/schema/capabilities.schema.ts +3 -1
  159. package/providers/commercetools/src/schema/commercetools.schema.ts +17 -3
  160. package/providers/commercetools/src/schema/configuration.schema.ts +1 -0
  161. package/providers/commercetools/src/schema/session.schema.ts +7 -0
  162. package/providers/commercetools/src/test/caching.spec.ts +82 -0
  163. package/providers/commercetools/src/test/identity.spec.ts +109 -0
  164. package/providers/commercetools/src/test/test-utils.ts +21 -19
  165. package/providers/commercetools/tsconfig.json +2 -1
  166. package/providers/commercetools/tsconfig.lib.json +1 -1
  167. package/providers/commercetools/tsconfig.spec.json +2 -13
  168. package/providers/commercetools/vitest.config.ts +15 -0
  169. package/providers/fake/README.md +20 -4
  170. package/providers/fake/package.json +3 -2
  171. package/providers/fake/src/core/initialize.ts +52 -54
  172. package/providers/fake/src/index.ts +4 -4
  173. package/providers/fake/src/providers/analytics.provider.ts +6 -8
  174. package/providers/fake/src/providers/cart.provider.ts +165 -94
  175. package/providers/fake/src/providers/category.provider.ts +79 -51
  176. package/providers/fake/src/providers/checkout.provider.ts +254 -0
  177. package/providers/fake/src/providers/identity.provider.ts +58 -66
  178. package/providers/fake/src/providers/index.ts +13 -9
  179. package/providers/fake/src/providers/inventory.provider.ts +41 -37
  180. package/providers/fake/src/providers/order-search.provider.ts +78 -0
  181. package/providers/fake/src/providers/order.provider.ts +106 -0
  182. package/providers/fake/src/providers/price.provider.ts +94 -42
  183. package/providers/fake/src/providers/product-search.provider.ts +206 -0
  184. package/providers/fake/src/providers/product.provider.ts +57 -42
  185. package/providers/fake/src/providers/profile.provider.ts +147 -0
  186. package/providers/fake/src/providers/store.provider.ts +31 -22
  187. package/providers/fake/src/schema/capabilities.schema.ts +5 -1
  188. package/providers/fake/src/test/cart.provider.spec.ts +62 -83
  189. package/providers/fake/src/test/category.provider.spec.ts +147 -89
  190. package/providers/fake/src/test/checkout.provider.spec.ts +222 -0
  191. package/providers/fake/src/test/order-search.provider.spec.ts +50 -0
  192. package/providers/fake/src/test/order.provider.spec.ts +44 -0
  193. package/providers/fake/src/test/price.provider.spec.ts +52 -47
  194. package/providers/fake/src/test/product.provider.spec.ts +18 -10
  195. package/providers/fake/src/test/profile.provider.spec.ts +167 -0
  196. package/providers/fake/src/test/test-utils.ts +1 -1
  197. package/providers/fake/tsconfig.json +2 -1
  198. package/providers/fake/tsconfig.lib.json +1 -1
  199. package/providers/fake/tsconfig.spec.json +2 -14
  200. package/providers/fake/vitest.config.ts +14 -0
  201. package/providers/medusa/README.md +30 -0
  202. package/providers/medusa/TESTING.md +98 -0
  203. package/{trpc → providers/medusa}/eslint.config.mjs +1 -1
  204. package/providers/medusa/package.json +22 -0
  205. package/providers/medusa/project.json +34 -0
  206. package/providers/medusa/src/core/client.ts +370 -0
  207. package/providers/medusa/src/core/initialize.ts +78 -0
  208. package/providers/medusa/src/index.ts +13 -0
  209. package/providers/medusa/src/providers/cart.provider.ts +575 -0
  210. package/providers/medusa/src/providers/category.provider.ts +247 -0
  211. package/providers/medusa/src/providers/checkout.provider.ts +636 -0
  212. package/providers/medusa/src/providers/identity.provider.ts +137 -0
  213. package/providers/medusa/src/providers/inventory.provider.ts +173 -0
  214. package/providers/medusa/src/providers/order-search.provider.ts +201 -0
  215. package/providers/medusa/src/providers/order.provider.ts +226 -0
  216. package/providers/medusa/src/providers/price.provider.ts +140 -0
  217. package/providers/medusa/src/providers/product-search.provider.ts +243 -0
  218. package/providers/medusa/src/providers/product.provider.ts +261 -0
  219. package/providers/medusa/src/providers/profile.provider.ts +392 -0
  220. package/providers/medusa/src/schema/capabilities.schema.ts +18 -0
  221. package/providers/medusa/src/schema/configuration.schema.ts +11 -0
  222. package/providers/medusa/src/schema/medusa.schema.ts +31 -0
  223. package/providers/medusa/src/test/cart.provider.spec.ts +240 -0
  224. package/providers/medusa/src/test/category.provider.spec.ts +231 -0
  225. package/providers/medusa/src/test/checkout.spec.ts +349 -0
  226. package/providers/medusa/src/test/identity.provider.spec.ts +122 -0
  227. package/providers/medusa/src/test/inventory.provider.spec.ts +88 -0
  228. package/providers/medusa/src/test/large-cart.provider.spec.ts +103 -0
  229. package/providers/medusa/src/test/price.provider.spec.ts +104 -0
  230. package/providers/medusa/src/test/product.provider.spec.ts +146 -0
  231. package/providers/medusa/src/test/search.provider.spec.ts +203 -0
  232. package/providers/medusa/src/test/test-utils.ts +13 -0
  233. package/providers/medusa/src/utils/medusa-helpers.ts +89 -0
  234. package/providers/medusa/tsconfig.json +21 -0
  235. package/providers/medusa/tsconfig.lib.json +9 -0
  236. package/providers/medusa/tsconfig.spec.json +4 -0
  237. package/providers/medusa/vitest.config.ts +15 -0
  238. package/providers/meilisearch/README.md +48 -0
  239. package/{otel → providers/meilisearch}/eslint.config.mjs +1 -2
  240. package/providers/meilisearch/package.json +13 -0
  241. package/providers/meilisearch/project.json +34 -0
  242. package/providers/meilisearch/src/core/initialize.ts +16 -0
  243. package/providers/meilisearch/src/index.ts +5 -0
  244. package/providers/meilisearch/src/providers/index.ts +1 -0
  245. package/providers/meilisearch/src/providers/product-search.provider.ts +251 -0
  246. package/providers/meilisearch/src/schema/capabilities.schema.ts +9 -0
  247. package/providers/meilisearch/src/schema/configuration.schema.ts +10 -0
  248. package/providers/meilisearch/src/schema/index.ts +3 -0
  249. package/providers/meilisearch/src/schema/search.schema.ts +14 -0
  250. package/{otel → providers/meilisearch}/tsconfig.json +3 -2
  251. package/{trpc → providers/meilisearch}/tsconfig.lib.json +2 -2
  252. package/providers/meilisearch/tsconfig.spec.json +4 -0
  253. package/providers/meilisearch/vitest.config.ts +14 -0
  254. package/providers/posthog/package.json +5 -4
  255. package/providers/posthog/project.json +2 -2
  256. package/providers/posthog/src/core/initialize.ts +2 -2
  257. package/providers/posthog/src/index.ts +3 -3
  258. package/providers/posthog/tsconfig.json +2 -1
  259. package/tsconfig.base.json +7 -3
  260. package/vitest.config.ts +10 -0
  261. package/core/src/providers/search.provider.ts +0 -18
  262. package/core/src/schemas/models/search.model.ts +0 -37
  263. package/core/src/schemas/queries/search.query.ts +0 -9
  264. package/examples/next/.swcrc +0 -30
  265. package/examples/next/eslint.config.mjs +0 -21
  266. package/examples/next/index.d.ts +0 -6
  267. package/examples/next/next-env.d.ts +0 -5
  268. package/examples/next/next.config.js +0 -20
  269. package/examples/next/project.json +0 -9
  270. package/examples/next/public/.gitkeep +0 -0
  271. package/examples/next/public/favicon.ico +0 -0
  272. package/examples/next/src/app/global.css +0 -0
  273. package/examples/next/src/app/layout.tsx +0 -18
  274. package/examples/next/src/app/page.module.scss +0 -2
  275. package/examples/next/src/app/page.tsx +0 -48
  276. package/examples/next/src/instrumentation.ts +0 -9
  277. package/examples/next/tsconfig.json +0 -44
  278. package/examples/node/jest.config.ts +0 -10
  279. package/jest.config.ts +0 -6
  280. package/jest.preset.js +0 -3
  281. package/otel/README.md +0 -227
  282. package/otel/package.json +0 -11
  283. package/otel/pnpm-lock.yaml +0 -805
  284. package/otel/project.json +0 -33
  285. package/otel/src/index.ts +0 -22
  286. package/otel/src/metrics.ts +0 -76
  287. package/otel/src/provider-instrumentation.ts +0 -108
  288. package/otel/src/test/otel.spec.ts +0 -8
  289. package/otel/src/trace-decorator.ts +0 -226
  290. package/otel/src/tracer.ts +0 -83
  291. package/otel/src/trpc-middleware.ts +0 -128
  292. package/otel/tsconfig.lib.json +0 -23
  293. package/otel/tsconfig.spec.json +0 -28
  294. package/otel/vite.config.ts +0 -24
  295. package/providers/algolia/jest.config.ts +0 -10
  296. package/providers/algolia/src/providers/product.provider.ts +0 -66
  297. package/providers/algolia/src/providers/search.provider.ts +0 -106
  298. package/providers/algolia/src/test/search.provider.spec.ts +0 -91
  299. package/providers/commercetools/jest.config.ts +0 -10
  300. package/providers/commercetools/src/providers/search.provider.ts +0 -98
  301. package/providers/commercetools/src/test/cart.provider.spec.ts +0 -199
  302. package/providers/commercetools/src/test/category.provider.spec.ts +0 -168
  303. package/providers/commercetools/src/test/checkout.provider.spec.ts +0 -312
  304. package/providers/commercetools/src/test/identity.provider.spec.ts +0 -88
  305. package/providers/commercetools/src/test/inventory.provider.spec.ts +0 -41
  306. package/providers/commercetools/src/test/price.provider.spec.ts +0 -81
  307. package/providers/commercetools/src/test/product.provider.spec.ts +0 -80
  308. package/providers/commercetools/src/test/profile.provider.spec.ts +0 -49
  309. package/providers/commercetools/src/test/search.provider.spec.ts +0 -61
  310. package/providers/commercetools/src/test/store.provider.spec.ts +0 -37
  311. package/providers/fake/jest.config.ts +0 -10
  312. package/providers/fake/src/providers/search.provider.ts +0 -135
  313. package/trpc/README.md +0 -7
  314. package/trpc/__mocks__/superjson.js +0 -25
  315. package/trpc/jest.config.ts +0 -14
  316. package/trpc/package.json +0 -14
  317. package/trpc/project.json +0 -31
  318. package/trpc/src/client.ts +0 -175
  319. package/trpc/src/index.ts +0 -44
  320. package/trpc/src/integration.spec.ts +0 -223
  321. package/trpc/src/server.ts +0 -125
  322. package/trpc/src/transparent-client.spec.ts +0 -161
  323. package/trpc/src/types.ts +0 -144
  324. package/trpc/tsconfig.json +0 -16
  325. package/trpc/tsconfig.spec.json +0 -15
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "provider-meilisearch",
3
+ "$schema": "../../node_modules/nx/schemas/project-schema.json",
4
+ "sourceRoot": "providers/meilisearch/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/meilisearch",
21
+ "main": "providers/meilisearch/src/index.ts",
22
+ "tsConfig": "providers/meilisearch/tsconfig.lib.json",
23
+ "assets": ["providers/meilisearch/*.md"],
24
+ "format": ["esm"],
25
+ "bundle": false
26
+ }
27
+ },
28
+ "nx-release-publish": {
29
+ "options": {
30
+ "packageRoot": "dist/{projectRoot}"
31
+ }
32
+ }
33
+ }
34
+ }
@@ -0,0 +1,16 @@
1
+ import type { Cache, ClientFromCapabilities, RequestContext } from "@reactionary/core";
2
+ import { MeilisearchSearchProvider } from "../providers/product-search.provider.js";
3
+ import type { MeilisearchCapabilities } from "../schema/capabilities.schema.js";
4
+ import type { MeilisearchConfiguration } from "../schema/configuration.schema.js";
5
+
6
+ export function withMeilisearchCapabilities<T extends MeilisearchCapabilities>(configuration: MeilisearchConfiguration, capabilities: T) {
7
+ return (cache: Cache, context: RequestContext): ClientFromCapabilities<T> => {
8
+ const client: any = {};
9
+
10
+ if (capabilities.productSearch) {
11
+ client.productSearch = new MeilisearchSearchProvider(configuration, cache, context);
12
+ }
13
+
14
+ return client;
15
+ };
16
+ }
@@ -0,0 +1,5 @@
1
+ export * from './core/initialize.js';
2
+ export * from './providers/product-search.provider.js';
3
+
4
+ export * from './schema/configuration.schema.js';
5
+ export * from './schema/capabilities.schema.js';
@@ -0,0 +1 @@
1
+ export * from './product-search.provider.js';
@@ -0,0 +1,251 @@
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 { MeiliSearch, type SearchParams, type SearchResponse } from 'meilisearch';
27
+ import type { MeilisearchConfiguration } from '../schema/configuration.schema.js';
28
+ import type { MeilisearchProductSearchResult } from '../schema/search.schema.js';
29
+
30
+ interface MeilisearchNativeVariant {
31
+ sku: string;
32
+ image: string;
33
+ }
34
+
35
+ interface MeilisearchNativeRecord {
36
+ objectID: string;
37
+ slug?: string;
38
+ name?: string;
39
+ variants: Array<MeilisearchNativeVariant>;
40
+ }
41
+
42
+
43
+ export class MeilisearchSearchProvider extends ProductSearchProvider {
44
+ protected config: MeilisearchConfiguration;
45
+
46
+ constructor(config: MeilisearchConfiguration, cache: Cache, context: RequestContext) {
47
+ super(cache, context);
48
+ this.config = config;
49
+ }
50
+
51
+ @Reactionary({
52
+ inputSchema: ProductSearchQueryByTermSchema,
53
+ outputSchema: ProductSearchResultSchema,
54
+ cache: true,
55
+ cacheTimeToLiveInSeconds: 300,
56
+ currencyDependentCaching: false,
57
+ localeDependentCaching: true
58
+ })
59
+ public override async queryByTerm(
60
+ payload: ProductSearchQueryByTerm
61
+ ): Promise<Result<ProductSearchResult>> {
62
+ const client = new MeiliSearch({
63
+ host: this.config.apiUrl,
64
+ apiKey: this.config.apiKey,
65
+ });
66
+
67
+ const index = client.index(this.config.indexName);
68
+
69
+ const facetsThatAreNotCategory = payload.search.facets.filter(x => x.facet.key !== 'categories');
70
+ const categoryFacet = payload.search.facets.find(x => x.facet.key === 'categories') || payload.search.categoryFilter;
71
+
72
+ const finalFilters: string[] = [...payload.search.filters || []];
73
+
74
+ const finalFacetFilters: string[] = [
75
+ ...facetsThatAreNotCategory.map(
76
+ (x) => `${x.facet.key}="${x.key}"`
77
+ ),
78
+ ];
79
+
80
+ if (categoryFacet) {
81
+ finalFilters.push(`categories = "${categoryFacet.key}"`);
82
+ }
83
+
84
+ // Combine all filters
85
+ let filterString: string | undefined;
86
+ if (finalFilters.length > 0 || finalFacetFilters.length > 0) {
87
+ const allFilters = [...finalFilters, ...finalFacetFilters];
88
+ filterString = allFilters.join(' AND ');
89
+ }
90
+
91
+ const searchOptions: SearchParams = {
92
+ offset: (payload.search.paginationOptions.pageNumber - 1) * payload.search.paginationOptions.pageSize,
93
+ limit: payload.search.paginationOptions.pageSize,
94
+ facets: ['*'],
95
+ filter: filterString,
96
+ };
97
+
98
+ if (this.config.useAIEmbedding) {
99
+ searchOptions.hybrid = {
100
+ embedder: this.config.useAIEmbedding
101
+ };
102
+ }
103
+
104
+ const remote = await index.search<MeilisearchNativeRecord>(payload.search.term, searchOptions);
105
+
106
+ const result = this.parsePaginatedResult(remote, payload) as MeilisearchProductSearchResult;
107
+
108
+ // mark selected facets as active
109
+ for (const selectedFacet of payload.search.facets) {
110
+ const facet = result.facets.find((f) => f.identifier.key === selectedFacet.facet.key);
111
+ if (facet) {
112
+ const value = facet.values.find((v) => v.identifier.key === selectedFacet.key);
113
+ if (value) {
114
+ value.active = true;
115
+ }
116
+ }
117
+ }
118
+
119
+ return success(result);
120
+ }
121
+
122
+ public override async createCategoryNavigationFilter(payload: ProductSearchQueryCreateNavigationFilter): Promise<Result<FacetValueIdentifier>> {
123
+
124
+ const facetIdentifier = FacetIdentifierSchema.parse({
125
+ key: 'categories'
126
+ });
127
+ const facetValueIdentifier = FacetValueIdentifierSchema.parse({
128
+ facet: facetIdentifier,
129
+ key: payload.categoryPath.map(c => c.name).join(' > ')
130
+ });
131
+ return success(facetValueIdentifier);
132
+ }
133
+
134
+
135
+ protected parseSingle(body: MeilisearchNativeRecord) {
136
+ const product = {
137
+ identifier: { key: body.objectID },
138
+ name: body.name || body.objectID,
139
+ slug: body.slug || body.objectID,
140
+ variants: [...(body.variants || [])].map(variant => this.parseVariant(variant, body)),
141
+ } satisfies ProductSearchResultItem;
142
+
143
+ return product;
144
+ }
145
+
146
+ protected override parseVariant(variant: MeilisearchNativeVariant, product: MeilisearchNativeRecord): ProductSearchResultItemVariant {
147
+ const result = ProductSearchResultItemVariantSchema.parse({
148
+ variant: {
149
+ sku: variant.sku
150
+ },
151
+ image: ImageSchema.parse({
152
+ sourceUrl: variant.image,
153
+ altText: product.name || '',
154
+ })
155
+ } satisfies Partial<ProductSearchResultItemVariant>);
156
+
157
+ return result;
158
+ }
159
+
160
+ protected parsePaginatedResult(body: SearchResponse<MeilisearchNativeRecord>, query: ProductSearchQueryByTerm) {
161
+ const items = body.hits.map((hit) => this.parseSingle(hit));
162
+ let facets: ProductSearchResultFacet[] = [];
163
+
164
+ if (body.facetDistribution) {
165
+ for (const id in body.facetDistribution) {
166
+ const f = body.facetDistribution[id];
167
+ const facetId = FacetIdentifierSchema.parse({
168
+ key: id
169
+ });
170
+ const facet = this.parseFacet(facetId, f);
171
+ if (facet.values.length > 0) {
172
+ facets.push(facet);
173
+ }
174
+ }
175
+ }
176
+
177
+ // Handle category hierarchy similar to Algolia
178
+ const selectedCategoryFacet = query.search.facets.find(x => x.facet.key === 'categories') || query.search.categoryFilter;
179
+ let subCategoryFacet;
180
+ if (selectedCategoryFacet) {
181
+ const valueDepth = selectedCategoryFacet.key.split(' > ').length;
182
+ subCategoryFacet = facets.find(f => f.identifier.key === `hierarchy.lvl${valueDepth}`);
183
+ } else {
184
+ subCategoryFacet = facets.find(f => f.identifier.key === 'hierarchy.lvl0');
185
+ }
186
+
187
+ if (subCategoryFacet) {
188
+ // remap to 'categories' facet
189
+ subCategoryFacet.identifier = FacetIdentifierSchema.parse({
190
+ key: 'categories'
191
+ });
192
+ subCategoryFacet.name = 'Categories';
193
+ for (const v of subCategoryFacet.values) {
194
+ const pathParts = v.identifier.key.split(' > ');
195
+ v.identifier.facet = subCategoryFacet.identifier;
196
+ v.name = pathParts[pathParts.length - 1];
197
+ }
198
+ }
199
+
200
+ // remove other hierarchy facets
201
+ facets = facets.filter(f => !f.identifier.key.startsWith('hierarchy.lvl'));
202
+
203
+ const totalPages = Math.ceil((body.estimatedTotalHits || 0) / query.search.paginationOptions.pageSize);
204
+
205
+ const result = {
206
+ identifier: {
207
+ term: query.search.term,
208
+ facets: query.search.facets,
209
+ filters: query.search.filters,
210
+ paginationOptions: query.search.paginationOptions,
211
+ },
212
+ pageNumber: query.search.paginationOptions.pageNumber,
213
+ pageSize: query.search.paginationOptions.pageSize,
214
+ totalCount: body.estimatedTotalHits || 0,
215
+ totalPages: totalPages,
216
+ items: items,
217
+ facets,
218
+ } satisfies ProductSearchResult;
219
+
220
+ return result;
221
+ }
222
+
223
+ protected parseFacet(facetIdentifier: FacetIdentifier, facetValues: Record<string, number>): ProductSearchResultFacet {
224
+ const result: ProductSearchResultFacet = ProductSearchResultFacetSchema.parse({
225
+ identifier: facetIdentifier,
226
+ name: facetIdentifier.key.replace(/_/g, ' '),
227
+ values: []
228
+ });
229
+
230
+ for (const vid in facetValues) {
231
+ const fv = facetValues[vid];
232
+
233
+ const facetValueIdentifier = FacetValueIdentifierSchema.parse({
234
+ facet: facetIdentifier,
235
+ key: vid
236
+ } satisfies Partial<FacetValueIdentifier>);
237
+
238
+ result.values.push(this.parseFacetValue(facetValueIdentifier, vid, fv));
239
+ }
240
+ return result;
241
+ }
242
+
243
+ protected parseFacetValue(facetValueIdentifier: FacetValueIdentifier, label: string, count: number): ProductSearchResultFacetValue {
244
+ return ProductSearchResultFacetValueSchema.parse({
245
+ identifier: facetValueIdentifier,
246
+ name: label,
247
+ count: count,
248
+ active: false,
249
+ } satisfies Partial<ProductSearchResultFacetValue>);
250
+ }
251
+ }
@@ -0,0 +1,9 @@
1
+ import { CapabilitiesSchema } from "@reactionary/core";
2
+ import type { z } from 'zod';
3
+
4
+ export const MeilisearchCapabilitiesSchema = CapabilitiesSchema.pick({
5
+ productSearch: true,
6
+ analytics: true
7
+ }).partial();
8
+
9
+ export type MeilisearchCapabilities = z.infer<typeof MeilisearchCapabilitiesSchema>;
@@ -0,0 +1,10 @@
1
+ import { z } from 'zod';
2
+
3
+ export const MeilisearchConfigurationSchema = z.looseObject({
4
+ apiUrl: z.string(),
5
+ apiKey: z.string(),
6
+ indexName: z.string(),
7
+ useAIEmbedding: z.string().optional()
8
+ });
9
+
10
+ export type MeilisearchConfiguration = z.infer<typeof MeilisearchConfigurationSchema>;
@@ -0,0 +1,3 @@
1
+ export * from './configuration.schema.js';
2
+ export * from './capabilities.schema.js';
3
+ export * from './search.schema.js';
@@ -0,0 +1,14 @@
1
+ import { ProductSearchIdentifierSchema, ProductSearchResultSchema } from '@reactionary/core';
2
+ import { z } from 'zod';
3
+
4
+ export const MeilisearchProductSearchIdentifierSchema = ProductSearchIdentifierSchema.extend({
5
+ key: z.string(),
6
+ index: z.string(),
7
+ });
8
+
9
+ export const MeilisearchProductSearchResultSchema = ProductSearchResultSchema.extend({
10
+ identifier: MeilisearchProductSearchIdentifierSchema.default(() => MeilisearchProductSearchIdentifierSchema.parse({}))
11
+ });
12
+
13
+ export type MeilisearchProductSearchResult = z.infer<typeof MeilisearchProductSearchResultSchema>;
14
+ export type MeilisearchProductSearchIdentifier = z.infer<typeof MeilisearchProductSearchIdentifierSchema>;
@@ -1,7 +1,8 @@
1
1
  {
2
- "extends": "../tsconfig.base.json",
2
+ "extends": "../../tsconfig.base.json",
3
3
  "compilerOptions": {
4
- "module": "commonjs",
4
+ "module": "NodeNext",
5
+ "moduleResolution": "nodenext",
5
6
  "forceConsistentCasingInFileNames": true,
6
7
  "strict": true,
7
8
  "importHelpers": true,
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "extends": "./tsconfig.json",
3
3
  "compilerOptions": {
4
- "outDir": "../dist/out-tsc",
4
+ "outDir": "../../dist/out-tsc",
5
5
  "declaration": true,
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
  }
@@ -0,0 +1,4 @@
1
+ {
2
+ "extends": "./tsconfig.lib.json",
3
+ "exclude": []
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,11 +1,12 @@
1
1
  {
2
2
  "name": "@reactionary/provider-posthog",
3
3
  "version": "0.0.1",
4
- "type": "commonjs",
5
- "main": "./index.cjs",
6
- "types": "./index.d.ts",
4
+ "main": "index.js",
5
+ "types": "src/index.d.ts",
7
6
  "dependencies": {
8
7
  "@reactionary/core": "0.0.1",
9
8
  "zod": "4.1.9"
10
- }
9
+ },
10
+ "type": "module",
11
+ "sideEffects": false
11
12
  }
@@ -20,8 +20,8 @@
20
20
  "main": "providers/posthog/src/index.ts",
21
21
  "tsConfig": "providers/posthog/tsconfig.lib.json",
22
22
  "assets": ["providers/posthog/*.md"],
23
- "format": ["cjs"],
24
- "generatePackageJson": true
23
+ "format": ["esm"],
24
+ "bundle": false
25
25
  }
26
26
  },
27
27
  "nx-release-publish": {
@@ -1,6 +1,6 @@
1
1
  import type { Client, Cache } from "@reactionary/core";
2
- import type { PosthogConfiguration } from "../schema/configuration.schema";
3
- import type { PosthogCapabilities } from "../schema/capabilities.schema";
2
+ import type { PosthogConfiguration } from "../schema/configuration.schema.js";
3
+ import type { PosthogCapabilities } from "../schema/capabilities.schema.js";
4
4
 
5
5
  export function withPosthogCapabilities(_configuration: PosthogConfiguration, _capabilities: PosthogCapabilities) {
6
6
  return (_cache: Cache) => {
@@ -1,4 +1,4 @@
1
- export * from './core/initialize';
1
+ export * from './core/initialize.js';
2
2
 
3
- export * from './schema/capabilities.schema';
4
- export * from './schema/configuration.schema';
3
+ export * from './schema/capabilities.schema.js';
4
+ export * from './schema/configuration.schema.js';
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "extends": "../../tsconfig.base.json",
3
3
  "compilerOptions": {
4
- "module": "commonjs",
4
+ "module": "NodeNext",
5
+ "moduleResolution": "nodenext",
5
6
  "forceConsistentCasingInFileNames": true,
6
7
  "strict": true,
7
8
  "importHelpers": true,
@@ -17,15 +17,19 @@
17
17
  "paths": {
18
18
  "@reactionary/core": ["core/src/index.ts"],
19
19
  "@reactionary/examples-node": ["examples/node/src/index.ts"],
20
+ "@reactionary/provider-medusa": ["providers/medusa/src/index.ts"],
20
21
  "@reactionary/otel": ["otel/src/index.ts"],
21
22
  "@reactionary/provider-algolia": ["providers/algolia/src/index.ts"],
23
+ "@reactionary/provider-meilisearch": [
24
+ "providers/meilisearch/src/index.ts"
25
+ ],
22
26
  "@reactionary/provider-commercetools": [
23
27
  "providers/commercetools/src/index.ts"
24
28
  ],
25
29
  "@reactionary/provider-fake": ["providers/fake/src/index.ts"],
26
- "@reactionary/provider-posthog": ["providers/posthog/src/index.ts"],
27
- "@reactionary/trpc": ["trpc/src/index.ts"]
28
- }
30
+ "@reactionary/provider-posthog": ["providers/posthog/src/index.ts"]
31
+ },
32
+ "verbatimModuleSyntax": true
29
33
  },
30
34
  "exclude": ["node_modules", "tmp"]
31
35
  }
@@ -0,0 +1,10 @@
1
+ import { resolve } from 'path'
2
+ import { defineConfig } from 'vitest/config'
3
+
4
+ export default defineConfig({
5
+ test: {
6
+ projects: ['providers/*', 'examples/*', 'core'],
7
+ reporters: ['default', 'verbose', 'github-actions'],
8
+
9
+ },
10
+ })
@@ -1,18 +0,0 @@
1
- import type { SearchResult } from '../schemas/models/search.model';
2
- import type { SearchQueryByTerm } from '../schemas/queries/search.query';
3
- import type { RequestContext } from '../schemas/session.schema';
4
- import { BaseProvider } from './base.provider';
5
-
6
- export abstract class SearchProvider<
7
- T extends SearchResult = SearchResult
8
- > extends BaseProvider<T> {
9
- public abstract queryByTerm(payload: SearchQueryByTerm, reqCtx: RequestContext): Promise<SearchResult>;
10
-
11
-
12
- protected override getResourceName(): string {
13
- return 'product-search';
14
- }
15
-
16
- }
17
-
18
-
@@ -1,37 +0,0 @@
1
- import { z } from 'zod';
2
- import { ProductIdentifierSchema, FacetValueIdentifierSchema, FacetIdentifierSchema, SearchIdentifierSchema } from './identifiers.model';
3
- import { BaseModelSchema, createPaginatedResponseSchema } from './base.model';
4
- import { create } from 'domain';
5
-
6
- export const SearchResultProductSchema = z.looseObject({
7
- identifier: ProductIdentifierSchema.default(ProductIdentifierSchema.parse({})),
8
- name: z.string().default(''),
9
- image: z.string().url().default('https://placehold.co/400'),
10
- slug: z.string().default('')
11
- });
12
-
13
- export const SearchResultFacetValueSchema = z.looseObject({
14
- identifier: FacetValueIdentifierSchema.default(() => FacetValueIdentifierSchema.parse({})),
15
- name: z.string().default(''),
16
- count: z.number().default(0),
17
- active: z.boolean().default(false)
18
- });
19
-
20
- export const SearchResultFacetSchema = z.looseObject({
21
- identifier: FacetIdentifierSchema.default(() => FacetIdentifierSchema.parse({})),
22
- name: z.string().default(''),
23
- values: z.array(SearchResultFacetValueSchema).default(() => [])
24
- });
25
-
26
- export const SearchResultSchema = BaseModelSchema.extend({
27
- identifier: SearchIdentifierSchema.default(() => SearchIdentifierSchema.parse({})),
28
- products: z.array(SearchResultProductSchema).default(() => []),
29
- pages: z.number().default(0),
30
- facets: z.array(SearchResultFacetSchema).default(() => [])
31
- });
32
-
33
-
34
- export type SearchResultProduct = z.infer<typeof SearchResultProductSchema>;
35
- export type SearchResult = z.infer<typeof SearchResultSchema>;
36
- export type SearchResultFacet = z.infer<typeof SearchResultFacetSchema>;
37
- export type SearchResultFacetValue = z.infer<typeof SearchResultFacetValueSchema>;
@@ -1,9 +0,0 @@
1
- import type { z } from 'zod';
2
- import { BaseQuerySchema } from './base.query';
3
- import { SearchIdentifierSchema } from '../models/identifiers.model';
4
-
5
- export const SearchQueryByTermSchema = BaseQuerySchema.extend({
6
- search: SearchIdentifierSchema.required()
7
- });
8
-
9
- export type SearchQueryByTerm = z.infer<typeof SearchQueryByTermSchema>;
@@ -1,30 +0,0 @@
1
- {
2
- "jsc": {
3
- "target": "es2017",
4
- "parser": {
5
- "syntax": "typescript",
6
- "decorators": true,
7
- "dynamicImport": true
8
- },
9
- "transform": {
10
- "decoratorMetadata": true,
11
- "legacyDecorator": true
12
- },
13
- "keepClassNames": true,
14
- "externalHelpers": true,
15
- "loose": true
16
- },
17
- "module": {
18
- "type": "commonjs"
19
- },
20
- "sourceMaps": true,
21
- "exclude": [
22
- "jest.config.ts",
23
- ".*\\.spec.tsx?$",
24
- ".*\\.test.tsx?$",
25
- "./src/jest-setup.ts$",
26
- "./**/jest-setup.ts$",
27
- ".*.js$",
28
- ".*.d.ts$"
29
- ]
30
- }
@@ -1,21 +0,0 @@
1
- import { FlatCompat } from '@eslint/eslintrc';
2
- import { dirname } from 'path';
3
- import { fileURLToPath } from 'url';
4
- import js from '@eslint/js';
5
- import { fixupConfigRules } from '@eslint/compat';
6
- import nx from '@nx/eslint-plugin';
7
- import baseConfig from '../../eslint.config.mjs';
8
- const compat = new FlatCompat({
9
- baseDirectory: dirname(fileURLToPath(import.meta.url)),
10
- recommendedConfig: js.configs.recommended,
11
- });
12
-
13
- export default [
14
- ...fixupConfigRules(compat.extends('next')),
15
- ...fixupConfigRules(compat.extends('next/core-web-vitals')),
16
- ...baseConfig,
17
- ...nx.configs['flat/react-typescript'],
18
- {
19
- ignores: ['.next/**/*'],
20
- },
21
- ];
@@ -1,6 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
- declare module '*.svg' {
3
- const content: any;
4
- export const ReactComponent: any;
5
- export default content;
6
- }
@@ -1,5 +0,0 @@
1
- /// <reference types="next" />
2
- /// <reference types="next/image-types/global" />
3
-
4
- // NOTE: This file should not be edited
5
- // see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
@@ -1,20 +0,0 @@
1
- //@ts-check
2
-
3
-
4
- const { composePlugins, withNx } = require('@nx/next');
5
-
6
- /**
7
- * @type {import('@nx/next/plugins/with-nx').WithNxOptions}
8
- **/
9
- const nextConfig = {
10
- // Use this to set Nx-specific options
11
- // See: https://nx.dev/recipes/next/next-config-setup
12
- nx: {},
13
- };
14
-
15
- const plugins = [
16
- // Add more Next.js plugins to this list if needed.
17
- withNx,
18
- ];
19
-
20
- module.exports = composePlugins(...plugins)(nextConfig);