@reactionary/source 0.0.27

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 (197) hide show
  1. package/.editorconfig +13 -0
  2. package/.github/workflows/pull-request.yml +37 -0
  3. package/.github/workflows/release.yml +49 -0
  4. package/.nvmrc +1 -0
  5. package/.prettierignore +6 -0
  6. package/.prettierrc +3 -0
  7. package/.verdaccio/config.yml +28 -0
  8. package/.vscode/extensions.json +9 -0
  9. package/README.md +39 -0
  10. package/core/README.md +11 -0
  11. package/core/eslint.config.mjs +23 -0
  12. package/core/package.json +8 -0
  13. package/core/project.json +33 -0
  14. package/core/src/cache/caching-strategy.ts +25 -0
  15. package/core/src/cache/redis-cache.ts +41 -0
  16. package/core/src/client/client.ts +39 -0
  17. package/core/src/index.ts +42 -0
  18. package/core/src/providers/analytics.provider.ts +10 -0
  19. package/core/src/providers/base.provider.ts +75 -0
  20. package/core/src/providers/cart.provider.ts +10 -0
  21. package/core/src/providers/identity.provider.ts +10 -0
  22. package/core/src/providers/inventory.provider.ts +11 -0
  23. package/core/src/providers/price.provider.ts +10 -0
  24. package/core/src/providers/product.provider.ts +11 -0
  25. package/core/src/providers/search.provider.ts +12 -0
  26. package/core/src/schemas/capabilities.schema.ts +13 -0
  27. package/core/src/schemas/models/analytics.model.ts +7 -0
  28. package/core/src/schemas/models/base.model.ts +19 -0
  29. package/core/src/schemas/models/cart.model.ts +17 -0
  30. package/core/src/schemas/models/currency.model.ts +187 -0
  31. package/core/src/schemas/models/identifiers.model.ts +45 -0
  32. package/core/src/schemas/models/identity.model.ts +15 -0
  33. package/core/src/schemas/models/inventory.model.ts +8 -0
  34. package/core/src/schemas/models/price.model.ts +17 -0
  35. package/core/src/schemas/models/product.model.ts +28 -0
  36. package/core/src/schemas/models/search.model.ts +35 -0
  37. package/core/src/schemas/mutations/analytics.mutation.ts +22 -0
  38. package/core/src/schemas/mutations/base.mutation.ts +7 -0
  39. package/core/src/schemas/mutations/cart.mutation.ts +30 -0
  40. package/core/src/schemas/mutations/identity.mutation.ts +18 -0
  41. package/core/src/schemas/mutations/inventory.mutation.ts +5 -0
  42. package/core/src/schemas/mutations/price.mutation.ts +5 -0
  43. package/core/src/schemas/mutations/product.mutation.ts +6 -0
  44. package/core/src/schemas/mutations/search.mutation.ts +5 -0
  45. package/core/src/schemas/queries/analytics.query.ts +5 -0
  46. package/core/src/schemas/queries/base.query.ts +7 -0
  47. package/core/src/schemas/queries/cart.query.ts +12 -0
  48. package/core/src/schemas/queries/identity.query.ts +10 -0
  49. package/core/src/schemas/queries/inventory.query.ts +9 -0
  50. package/core/src/schemas/queries/price.query.ts +12 -0
  51. package/core/src/schemas/queries/product.query.ts +18 -0
  52. package/core/src/schemas/queries/search.query.ts +12 -0
  53. package/core/src/schemas/session.schema.ts +9 -0
  54. package/core/tsconfig.json +23 -0
  55. package/core/tsconfig.lib.json +23 -0
  56. package/core/tsconfig.spec.json +28 -0
  57. package/eslint.config.mjs +46 -0
  58. package/examples/angular/e2e/example.spec.ts +9 -0
  59. package/examples/angular/eslint.config.mjs +41 -0
  60. package/examples/angular/playwright.config.ts +38 -0
  61. package/examples/angular/project.json +86 -0
  62. package/examples/angular/public/favicon.ico +0 -0
  63. package/examples/angular/src/app/app.component.html +6 -0
  64. package/examples/angular/src/app/app.component.scss +22 -0
  65. package/examples/angular/src/app/app.component.ts +14 -0
  66. package/examples/angular/src/app/app.config.ts +16 -0
  67. package/examples/angular/src/app/app.routes.ts +25 -0
  68. package/examples/angular/src/app/cart/cart.component.html +4 -0
  69. package/examples/angular/src/app/cart/cart.component.scss +14 -0
  70. package/examples/angular/src/app/cart/cart.component.ts +73 -0
  71. package/examples/angular/src/app/identity/identity.component.html +6 -0
  72. package/examples/angular/src/app/identity/identity.component.scss +18 -0
  73. package/examples/angular/src/app/identity/identity.component.ts +49 -0
  74. package/examples/angular/src/app/product/product.component.html +14 -0
  75. package/examples/angular/src/app/product/product.component.scss +11 -0
  76. package/examples/angular/src/app/product/product.component.ts +42 -0
  77. package/examples/angular/src/app/search/search.component.html +35 -0
  78. package/examples/angular/src/app/search/search.component.scss +129 -0
  79. package/examples/angular/src/app/search/search.component.ts +50 -0
  80. package/examples/angular/src/app/services/product.service.ts +35 -0
  81. package/examples/angular/src/app/services/search.service.ts +48 -0
  82. package/examples/angular/src/app/services/trpc.client.ts +27 -0
  83. package/examples/angular/src/index.html +13 -0
  84. package/examples/angular/src/main.ts +7 -0
  85. package/examples/angular/src/styles.scss +17 -0
  86. package/examples/angular/src/test-setup.ts +6 -0
  87. package/examples/angular/tsconfig.app.json +10 -0
  88. package/examples/angular/tsconfig.editor.json +6 -0
  89. package/examples/angular/tsconfig.json +32 -0
  90. package/examples/node/README.md +11 -0
  91. package/examples/node/eslint.config.mjs +22 -0
  92. package/examples/node/jest.config.ts +10 -0
  93. package/examples/node/package.json +10 -0
  94. package/examples/node/project.json +20 -0
  95. package/examples/node/src/index.ts +2 -0
  96. package/examples/node/src/initialize-algolia.spec.ts +29 -0
  97. package/examples/node/src/initialize-commercetools.spec.ts +31 -0
  98. package/examples/node/src/initialize-extended-providers.spec.ts +38 -0
  99. package/examples/node/src/initialize-mixed-providers.spec.ts +36 -0
  100. package/examples/node/src/providers/custom-algolia-product.provider.ts +18 -0
  101. package/examples/node/src/schemas/custom-product.schema.ts +8 -0
  102. package/examples/node/tsconfig.json +23 -0
  103. package/examples/node/tsconfig.lib.json +10 -0
  104. package/examples/node/tsconfig.spec.json +15 -0
  105. package/examples/trpc-node/eslint.config.mjs +3 -0
  106. package/examples/trpc-node/project.json +61 -0
  107. package/examples/trpc-node/src/assets/.gitkeep +0 -0
  108. package/examples/trpc-node/src/main.ts +55 -0
  109. package/examples/trpc-node/src/router-instance.ts +52 -0
  110. package/examples/trpc-node/tsconfig.app.json +9 -0
  111. package/examples/trpc-node/tsconfig.json +13 -0
  112. package/examples/vue/eslint.config.mjs +24 -0
  113. package/examples/vue/index.html +13 -0
  114. package/examples/vue/project.json +8 -0
  115. package/examples/vue/src/app/App.vue +275 -0
  116. package/examples/vue/src/main.ts +6 -0
  117. package/examples/vue/src/styles.scss +9 -0
  118. package/examples/vue/src/vue-shims.d.ts +5 -0
  119. package/examples/vue/tsconfig.app.json +14 -0
  120. package/examples/vue/tsconfig.json +20 -0
  121. package/examples/vue/vite.config.ts +31 -0
  122. package/jest.config.ts +6 -0
  123. package/jest.preset.js +3 -0
  124. package/migrations.json +11 -0
  125. package/nx.json +130 -0
  126. package/package.json +118 -0
  127. package/project.json +14 -0
  128. package/providers/algolia/README.md +11 -0
  129. package/providers/algolia/eslint.config.mjs +22 -0
  130. package/providers/algolia/jest.config.ts +10 -0
  131. package/providers/algolia/package.json +9 -0
  132. package/providers/algolia/project.json +33 -0
  133. package/providers/algolia/src/core/initialize.ts +20 -0
  134. package/providers/algolia/src/index.ts +7 -0
  135. package/providers/algolia/src/providers/product.provider.ts +25 -0
  136. package/providers/algolia/src/providers/search.provider.ts +125 -0
  137. package/providers/algolia/src/schema/capabilities.schema.ts +10 -0
  138. package/providers/algolia/src/schema/configuration.schema.ts +9 -0
  139. package/providers/algolia/src/schema/search.schema.ts +14 -0
  140. package/providers/algolia/src/test/product.provider.spec.ts +18 -0
  141. package/providers/algolia/src/test/search.provider.spec.ts +82 -0
  142. package/providers/algolia/tsconfig.json +23 -0
  143. package/providers/algolia/tsconfig.lib.json +10 -0
  144. package/providers/algolia/tsconfig.spec.json +15 -0
  145. package/providers/commercetools/README.md +11 -0
  146. package/providers/commercetools/eslint.config.mjs +22 -0
  147. package/providers/commercetools/jest.config.ts +10 -0
  148. package/providers/commercetools/package.json +10 -0
  149. package/providers/commercetools/project.json +33 -0
  150. package/providers/commercetools/src/core/client.ts +152 -0
  151. package/providers/commercetools/src/core/initialize.ts +40 -0
  152. package/providers/commercetools/src/index.ts +12 -0
  153. package/providers/commercetools/src/providers/cart.provider.ts +223 -0
  154. package/providers/commercetools/src/providers/identity.provider.ts +130 -0
  155. package/providers/commercetools/src/providers/inventory.provider.ts +82 -0
  156. package/providers/commercetools/src/providers/price.provider.ts +66 -0
  157. package/providers/commercetools/src/providers/product.provider.ts +90 -0
  158. package/providers/commercetools/src/providers/search.provider.ts +86 -0
  159. package/providers/commercetools/src/schema/capabilities.schema.ts +13 -0
  160. package/providers/commercetools/src/schema/configuration.schema.ts +11 -0
  161. package/providers/commercetools/src/test/product.provider.spec.ts +20 -0
  162. package/providers/commercetools/src/test/search.provider.spec.ts +18 -0
  163. package/providers/commercetools/tsconfig.json +23 -0
  164. package/providers/commercetools/tsconfig.lib.json +10 -0
  165. package/providers/commercetools/tsconfig.spec.json +15 -0
  166. package/providers/fake/README.md +7 -0
  167. package/providers/fake/eslint.config.mjs +22 -0
  168. package/providers/fake/package.json +9 -0
  169. package/providers/fake/project.json +33 -0
  170. package/providers/fake/src/core/initialize.ts +24 -0
  171. package/providers/fake/src/index.ts +8 -0
  172. package/providers/fake/src/providers/identity.provider.ts +91 -0
  173. package/providers/fake/src/providers/product.provider.ts +73 -0
  174. package/providers/fake/src/providers/search.provider.ts +142 -0
  175. package/providers/fake/src/schema/capabilities.schema.ts +10 -0
  176. package/providers/fake/src/schema/configuration.schema.ts +15 -0
  177. package/providers/fake/src/utilities/jitter.ts +14 -0
  178. package/providers/fake/tsconfig.json +20 -0
  179. package/providers/fake/tsconfig.lib.json +9 -0
  180. package/providers/posthog/README.md +7 -0
  181. package/providers/posthog/eslint.config.mjs +22 -0
  182. package/providers/posthog/package.json +11 -0
  183. package/providers/posthog/project.json +33 -0
  184. package/providers/posthog/src/core/initialize.ts +9 -0
  185. package/providers/posthog/src/index.ts +4 -0
  186. package/providers/posthog/src/schema/capabilities.schema.ts +8 -0
  187. package/providers/posthog/src/schema/configuration.schema.ts +8 -0
  188. package/providers/posthog/tsconfig.json +20 -0
  189. package/providers/posthog/tsconfig.lib.json +9 -0
  190. package/trpc/README.md +7 -0
  191. package/trpc/eslint.config.mjs +19 -0
  192. package/trpc/package.json +13 -0
  193. package/trpc/project.json +31 -0
  194. package/trpc/src/index.ts +64 -0
  195. package/trpc/tsconfig.json +13 -0
  196. package/trpc/tsconfig.lib.json +9 -0
  197. package/tsconfig.base.json +30 -0
package/nx.json ADDED
@@ -0,0 +1,130 @@
1
+ {
2
+ "$schema": "./node_modules/nx/schemas/nx-schema.json",
3
+ "namedInputs": {
4
+ "default": ["{projectRoot}/**/*", "sharedGlobals"],
5
+ "production": [
6
+ "default",
7
+ "!{projectRoot}/.eslintrc.json",
8
+ "!{projectRoot}/eslint.config.mjs",
9
+ "!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)",
10
+ "!{projectRoot}/tsconfig.spec.json",
11
+ "!{projectRoot}/src/test-setup.[jt]s",
12
+ "!{projectRoot}/jest.config.[jt]s",
13
+ "!{projectRoot}/test-setup.[jt]s"
14
+ ],
15
+ "sharedGlobals": ["{workspaceRoot}/.github/workflows/ci.yml"]
16
+ },
17
+ "targetDefaults": {
18
+ "@angular-devkit/build-angular:application": {
19
+ "cache": true,
20
+ "dependsOn": ["^build"],
21
+ "inputs": ["production", "^production"]
22
+ },
23
+ "@nx/eslint:lint": {
24
+ "cache": true,
25
+ "inputs": [
26
+ "default",
27
+ "{workspaceRoot}/.eslintrc.json",
28
+ "{workspaceRoot}/.eslintignore",
29
+ "{workspaceRoot}/eslint.config.mjs"
30
+ ]
31
+ },
32
+ "@nx/esbuild:esbuild": {
33
+ "cache": true,
34
+ "dependsOn": ["^build"],
35
+ "inputs": ["production", "^production"]
36
+ },
37
+ "e2e-ci--**/*": {
38
+ "dependsOn": ["^build"]
39
+ },
40
+ "@nx/js:tsc": {
41
+ "cache": true,
42
+ "dependsOn": ["^build"],
43
+ "inputs": ["production", "^production"]
44
+ }
45
+ },
46
+ "generators": {
47
+ "@nx/angular:application": {
48
+ "e2eTestRunner": "none",
49
+ "linter": "eslint",
50
+ "style": "scss",
51
+ "unitTestRunner": "jest"
52
+ },
53
+ "@nx/next": {
54
+ "application": {
55
+ "style": "scss",
56
+ "linter": "eslint"
57
+ }
58
+ },
59
+ "@nx/angular:component": {
60
+ "style": "scss",
61
+ "displayBlock": true,
62
+ "skipTests": true,
63
+ "standalone": true,
64
+ "changeDetection": "OnPush",
65
+ "viewEncapsulation": "ShadowDom"
66
+ }
67
+ },
68
+ "release": {
69
+ "git": {
70
+ "commit": false,
71
+ "stageChanges": false,
72
+ "tag": true
73
+ },
74
+ "version": {
75
+ "preVersionCommand": "pnpm nx run-many -t build"
76
+ },
77
+ "changelog": {
78
+ "workspaceChangelog": {
79
+ "createRelease": "github",
80
+ "file": false
81
+ }
82
+ }
83
+ },
84
+ "plugins": [
85
+ {
86
+ "plugin": "@nx/eslint/plugin",
87
+ "options": {
88
+ "targetName": "lint"
89
+ }
90
+ },
91
+ {
92
+ "plugin": "@nx/jest/plugin",
93
+ "options": {
94
+ "targetName": "test"
95
+ }
96
+ },
97
+ {
98
+ "plugin": "@nx/playwright/plugin",
99
+ "options": {
100
+ "targetName": "e2e"
101
+ }
102
+ },
103
+ {
104
+ "plugin": "@nx/next/plugin",
105
+ "options": {
106
+ "startTargetName": "start",
107
+ "buildTargetName": "build",
108
+ "devTargetName": "dev",
109
+ "serveStaticTargetName": "serve-static",
110
+ "buildDepsTargetName": "build-deps",
111
+ "watchDepsTargetName": "watch-deps"
112
+ }
113
+ },
114
+ {
115
+ "plugin": "@nx/vite/plugin",
116
+ "options": {
117
+ "buildTargetName": "build",
118
+ "testTargetName": "test",
119
+ "serveTargetName": "serve",
120
+ "devTargetName": "dev",
121
+ "previewTargetName": "preview",
122
+ "serveStaticTargetName": "serve-static",
123
+ "typecheckTargetName": "typecheck",
124
+ "buildDepsTargetName": "build-deps",
125
+ "watchDepsTargetName": "watch-deps"
126
+ }
127
+ }
128
+ ],
129
+ "nxCloudId": "683eb2fef42fbc631b8c5f05"
130
+ }
package/package.json ADDED
@@ -0,0 +1,118 @@
1
+ {
2
+ "name": "@reactionary/source",
3
+ "version": "0.0.27",
4
+ "license": "MIT",
5
+ "private": false,
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
+ "@commercetools/platform-sdk": "^8.8.0",
15
+ "@commercetools/ts-client": "^3.2.2",
16
+ "@faker-js/faker": "^9.8.0",
17
+ "@trpc/client": "^11.1.2",
18
+ "@trpc/server": "^11.1.2",
19
+ "@upstash/redis": "^1.34.9",
20
+ "algoliasearch": "^5.23.4",
21
+ "connect-redis": "^8.1.0",
22
+ "cors": "^2.8.5",
23
+ "express": "^5.1.0",
24
+ "express-session": "^1.18.1",
25
+ "ioredis": "^5.6.1",
26
+ "next": "~15.2.4",
27
+ "posthog-node": "^4.18.0",
28
+ "react": "19.0.0",
29
+ "react-dom": "19.0.0",
30
+ "rxjs": "~7.8.0",
31
+ "search-insights": "^2.17.3",
32
+ "superjson": "^2.2.2",
33
+ "vue": "^3.5.13",
34
+ "zod": "4.0.0-beta.20250430T185432",
35
+ "zone.js": "~0.15.0"
36
+ },
37
+ "devDependencies": {
38
+ "@angular-devkit/build-angular": "~19.2.0",
39
+ "@angular-devkit/core": "~19.2.0",
40
+ "@angular-devkit/schematics": "~19.2.0",
41
+ "@angular/cli": "~19.2.0",
42
+ "@angular/compiler-cli": "~19.2.0",
43
+ "@angular/language-service": "~19.2.0",
44
+ "@eslint/compat": "^1.1.1",
45
+ "@eslint/eslintrc": "^2.1.1",
46
+ "@eslint/js": "^9.8.0",
47
+ "@next/eslint-plugin-next": "^15.2.4",
48
+ "@nx/angular": "21.1.2",
49
+ "@nx/devkit": "21.1.2",
50
+ "@nx/esbuild": "21.1.2",
51
+ "@nx/eslint": "21.1.2",
52
+ "@nx/eslint-plugin": "21.1.2",
53
+ "@nx/jest": "21.1.2",
54
+ "@nx/js": "21.1.2",
55
+ "@nx/next": "21.1.2",
56
+ "@nx/node": "21.1.2",
57
+ "@nx/playwright": "21.1.2",
58
+ "@nx/vite": "21.1.2",
59
+ "@nx/vue": "21.1.2",
60
+ "@nx/web": "21.1.2",
61
+ "@nx/workspace": "21.1.2",
62
+ "@playwright/test": "^1.36.0",
63
+ "@schematics/angular": "~19.2.0",
64
+ "@swc-node/register": "~1.9.1",
65
+ "@swc/cli": "~0.6.0",
66
+ "@swc/core": "~1.5.7",
67
+ "@swc/helpers": "~0.5.11",
68
+ "@types/jest": "^29.5.12",
69
+ "@types/node": "18.16.9",
70
+ "@types/react": "19.0.0",
71
+ "@types/react-dom": "19.0.0",
72
+ "@typescript-eslint/utils": "^8.19.0",
73
+ "@vitejs/plugin-vue": "^5.2.3",
74
+ "@vitest/ui": "^3.0.0",
75
+ "@vue/eslint-config-prettier": "7.1.0",
76
+ "@vue/eslint-config-typescript": "^11.0.3",
77
+ "@vue/test-utils": "^2.4.6",
78
+ "angular-eslint": "^19.2.0",
79
+ "esbuild": "^0.19.2",
80
+ "eslint": "^9.8.0",
81
+ "eslint-config-next": "^15.2.4",
82
+ "eslint-config-prettier": "^10.0.0",
83
+ "eslint-plugin-import": "2.31.0",
84
+ "eslint-plugin-jsx-a11y": "6.10.1",
85
+ "eslint-plugin-playwright": "^1.6.2",
86
+ "eslint-plugin-react": "7.35.0",
87
+ "eslint-plugin-react-hooks": "5.0.0",
88
+ "eslint-plugin-vue": "^9.16.1",
89
+ "jest": "^29.7.0",
90
+ "jest-environment-jsdom": "^29.7.0",
91
+ "jest-environment-node": "^29.7.0",
92
+ "jest-preset-angular": "~14.4.0",
93
+ "jiti": "2.4.2",
94
+ "jsdom": "~22.1.0",
95
+ "jsonc-eslint-parser": "^2.1.0",
96
+ "nx": "21.1.2",
97
+ "prettier": "^2.6.2",
98
+ "sass": "1.62.1",
99
+ "ts-jest": "^29.1.0",
100
+ "ts-node": "10.9.1",
101
+ "tslib": "^2.3.0",
102
+ "typescript": "~5.7.2",
103
+ "typescript-eslint": "^8.19.0",
104
+ "verdaccio": "^6.0.5",
105
+ "vite": "^6.0.0",
106
+ "vitest": "^3.0.0",
107
+ "vue-tsc": "^2.2.8"
108
+ },
109
+ "nx": {
110
+ "includedScripts": []
111
+ },
112
+ "publishConfig": {
113
+ "access": "public",
114
+ "provenance": false
115
+ },
116
+ "packageManager": "pnpm@8.15.9+sha512.499434c9d8fdd1a2794ebf4552b3b25c0a633abcee5bb15e7b5de90f32f47b513aca98cd5cfd001c31f0db454bc3804edccd578501e4ca293a6816166bbd9f81",
117
+ "scripts": {}
118
+ }
package/project.json ADDED
@@ -0,0 +1,14 @@
1
+ {
2
+ "name": "@reactionary/source",
3
+ "$schema": "node_modules/nx/schemas/project-schema.json",
4
+ "targets": {
5
+ "local-registry": {
6
+ "executor": "@nx/js:verdaccio",
7
+ "options": {
8
+ "port": 4873,
9
+ "config": ".verdaccio/config.yml",
10
+ "storage": "tmp/local-registry/storage"
11
+ }
12
+ }
13
+ }
14
+ }
@@ -0,0 +1,11 @@
1
+ # provider-algolia
2
+
3
+ This library was generated with [Nx](https://nx.dev).
4
+
5
+ ## Building
6
+
7
+ Run `nx build provider-algolia` to build the library.
8
+
9
+ ## Running unit tests
10
+
11
+ Run `nx test provider-algolia` to execute the unit tests via [Jest](https://jestjs.io).
@@ -0,0 +1,22 @@
1
+ import baseConfig from '../../eslint.config.mjs';
2
+
3
+ export default [
4
+ ...baseConfig,
5
+ {
6
+ files: ['**/*.json'],
7
+ rules: {
8
+ '@nx/dependency-checks': [
9
+ 'error',
10
+ {
11
+ ignoredFiles: [
12
+ '{projectRoot}/eslint.config.{js,cjs,mjs}',
13
+ '{projectRoot}/esbuild.config.{js,ts,mjs,mts}',
14
+ ],
15
+ },
16
+ ],
17
+ },
18
+ languageOptions: {
19
+ parser: await import('jsonc-eslint-parser'),
20
+ },
21
+ },
22
+ ];
@@ -0,0 +1,10 @@
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
+ };
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "@reactionary/provider-algolia",
3
+ "version": "0.0.1",
4
+ "dependencies": {
5
+ "@reactionary/core": "0.0.1",
6
+ "algoliasearch": "^5.23.4",
7
+ "zod": "4.0.0-beta.20250430T185432"
8
+ }
9
+ }
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "provider-algolia",
3
+ "$schema": "../../node_modules/nx/schemas/project-schema.json",
4
+ "sourceRoot": "providers/algolia/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/algolia",
21
+ "main": "providers/algolia/src/index.ts",
22
+ "tsConfig": "providers/algolia/tsconfig.lib.json",
23
+ "assets": ["providers/algolia/*.md"],
24
+ "format": ["esm"]
25
+ }
26
+ },
27
+ "nx-release-publish": {
28
+ "options": {
29
+ "packageRoot": "dist/{projectRoot}"
30
+ }
31
+ }
32
+ }
33
+ }
@@ -0,0 +1,20 @@
1
+ import { Client, ProductMutationSchema, ProductQuerySchema, ProductSchema, SearchMutationSchema, SearchQuerySchema } from "@reactionary/core";
2
+ import { AlgoliaProductProvider } from "../providers/product.provider";
3
+ import { AlgoliaSearchProvider } from "../providers/search.provider";
4
+ import { AlgoliaCapabilities } from "../schema/capabilities.schema";
5
+ import { AlgoliaConfiguration } from "../schema/configuration.schema";
6
+ import { AlgoliaSearchResultSchema } from "../schema/search.schema";
7
+
8
+ export function withAlgoliaCapabilities(configuration: AlgoliaConfiguration, capabilities: AlgoliaCapabilities) {
9
+ const client: Partial<Client> = {};
10
+
11
+ if (capabilities.product) {
12
+ client.product = new AlgoliaProductProvider(configuration, ProductSchema, ProductQuerySchema, ProductMutationSchema);
13
+ }
14
+
15
+ if (capabilities.search) {
16
+ client.search = new AlgoliaSearchProvider(configuration, AlgoliaSearchResultSchema, SearchQuerySchema, SearchMutationSchema);
17
+ }
18
+
19
+ return client;
20
+ }
@@ -0,0 +1,7 @@
1
+ export * from './core/initialize';
2
+
3
+ export * from './providers/product.provider';
4
+ export * from './providers/search.provider';
5
+
6
+ export * from './schema/configuration.schema';
7
+ export * from './schema/capabilities.schema';
@@ -0,0 +1,25 @@
1
+ import { BaseMutation, Product, ProductMutation, ProductProvider, ProductQuery, Session } from '@reactionary/core';
2
+ import { z } from 'zod';
3
+ import { AlgoliaConfiguration } from '../schema/configuration.schema';
4
+
5
+ export class AlgoliaProductProvider<
6
+ T extends Product = Product,
7
+ Q extends ProductQuery = ProductQuery,
8
+ M extends ProductMutation = ProductMutation
9
+ > extends ProductProvider<T, Q, M> {
10
+ protected config: AlgoliaConfiguration;
11
+
12
+ constructor(config: AlgoliaConfiguration, schema: z.ZodType<T>, querySchema: z.ZodType<Q, Q>, mutationSchema: z.ZodType<M, M>) {
13
+ super(schema, querySchema, mutationSchema);
14
+
15
+ this.config = config;
16
+ }
17
+
18
+ protected override async fetch(queries: Q[], session: Session): Promise<T[]> {
19
+ return [];
20
+ }
21
+
22
+ protected override process(mutation: BaseMutation[], session: Session): Promise<T> {
23
+ throw new Error('Method not implemented.');
24
+ }
25
+ }
@@ -0,0 +1,125 @@
1
+ import {
2
+ SearchIdentifier,
3
+ SearchMutation,
4
+ SearchProvider,
5
+ SearchQuery,
6
+ SearchResult,
7
+ SearchResultFacetSchema,
8
+ SearchResultFacetValueSchema,
9
+ Session,
10
+ } from '@reactionary/core';
11
+ import { algoliasearch } from 'algoliasearch';
12
+ import { z } from 'zod';
13
+ import { AlgoliaConfiguration } from '../schema/configuration.schema';
14
+
15
+ export class AlgoliaSearchProvider<
16
+ T extends SearchResult = SearchResult,
17
+ Q extends SearchQuery = SearchQuery,
18
+ M extends SearchMutation = SearchMutation
19
+ > extends SearchProvider<T, Q, M> {
20
+ protected config: AlgoliaConfiguration;
21
+
22
+ constructor(config: AlgoliaConfiguration, schema: z.ZodType<T>, querySchema: z.ZodType<Q, Q>, mutationSchema: z.ZodType<M, M>) {
23
+ super(schema, querySchema, mutationSchema);
24
+
25
+ this.config = config;
26
+ }
27
+
28
+ protected override async fetch(queries: Q[], session: Session): Promise<T[]> {
29
+ const results = [];
30
+
31
+ for (const query of queries) {
32
+ const result = await this.get(query.search);
33
+
34
+ results.push(result);
35
+ }
36
+
37
+ return results;
38
+ }
39
+
40
+ protected override process(mutations: M[], session: Session): Promise<T> {
41
+ throw new Error('Method not implemented.');
42
+ }
43
+
44
+ protected async get(identifier: SearchIdentifier): Promise<T> {
45
+ const client = algoliasearch(this.config.appId, this.config.apiKey);
46
+ const remote = await client.search<unknown>({
47
+ requests: [
48
+ {
49
+ indexName: this.config.indexName,
50
+ query: identifier.term,
51
+ page: identifier.page,
52
+ hitsPerPage: identifier.pageSize,
53
+ facets: ['*'],
54
+ analytics: true,
55
+ clickAnalytics: true,
56
+ facetFilters: identifier.facets.map(
57
+ (x) => `${encodeURIComponent(x.facet.key)}:${x.key}`
58
+ ),
59
+ },
60
+ ],
61
+ });
62
+
63
+ const parsed = this.parse(remote, identifier);
64
+
65
+ return parsed;
66
+ }
67
+
68
+ protected parse(remote: any, query: SearchIdentifier): T {
69
+ const result = this.newModel();
70
+
71
+ const remoteProducts = remote.results[0];
72
+
73
+ for (const id in remoteProducts.facets) {
74
+ const f = remoteProducts.facets[id];
75
+
76
+ const facet = SearchResultFacetSchema.parse({});
77
+ facet.identifier.key = id;
78
+ facet.name = id;
79
+
80
+ for (const vid in f) {
81
+ const fv = f[vid];
82
+
83
+ const facetValue = SearchResultFacetValueSchema.parse({});
84
+ facetValue.count = fv;
85
+ facetValue.name = vid;
86
+ facetValue.identifier.key = vid;
87
+ facetValue.identifier.facet = facet.identifier;
88
+
89
+ if (
90
+ query.facets.find(
91
+ (x) =>
92
+ x.facet.key == facetValue.identifier.facet.key &&
93
+ x.key == facetValue.identifier.key
94
+ )
95
+ ) {
96
+ facetValue.active = true;
97
+ }
98
+
99
+ facet.values.push(facetValue);
100
+ }
101
+
102
+ result.facets.push(facet);
103
+ }
104
+
105
+ for (const p of remoteProducts.hits) {
106
+ result.products.push({
107
+ identifier: {
108
+ key: p.objectID,
109
+ },
110
+ slug: p.slug,
111
+ name: p.name,
112
+ image: p.image,
113
+ });
114
+ }
115
+
116
+ result.identifier = {
117
+ ...query,
118
+ index: remoteProducts.index,
119
+ key: remoteProducts.queryID
120
+ };
121
+ result.pages = remoteProducts.nbPages;
122
+
123
+ return result;
124
+ }
125
+ }
@@ -0,0 +1,10 @@
1
+ import { CapabilitiesSchema } from "@reactionary/core";
2
+ import { z } from 'zod';
3
+
4
+ export const AlgoliaCapabilitiesSchema = CapabilitiesSchema.pick({
5
+ product: true,
6
+ search: true,
7
+ analytics: true
8
+ }).partial();
9
+
10
+ export type AlgoliaCapabilities = z.infer<typeof AlgoliaCapabilitiesSchema>;
@@ -0,0 +1,9 @@
1
+ import { z } from 'zod';
2
+
3
+ export const AlgoliaConfigurationSchema = z.looseInterface({
4
+ appId: z.string(),
5
+ apiKey: z.string(),
6
+ indexName: z.string()
7
+ });
8
+
9
+ export type AlgoliaConfiguration = z.infer<typeof AlgoliaConfigurationSchema>;
@@ -0,0 +1,14 @@
1
+ import { SearchIdentifierSchema, SearchResultSchema } from '@reactionary/core';
2
+ import { z } from 'zod';
3
+
4
+ export const AlgoliaSearchIdentifierSchema = SearchIdentifierSchema.extend({
5
+ key: z.string().default(''),
6
+ index: z.string().default('')
7
+ });
8
+
9
+ export const AlgoliaSearchResultSchema = SearchResultSchema.extend({
10
+ identifier: AlgoliaSearchIdentifierSchema.default(() => AlgoliaSearchIdentifierSchema.parse({}))
11
+ });
12
+
13
+ export type AlgoliaSearchResult = z.infer<typeof AlgoliaSearchResultSchema>;
14
+ export type AlgoliaSearchIdentifier = z.infer<typeof AlgoliaSearchIdentifierSchema>;
@@ -0,0 +1,18 @@
1
+ import { ProductSchema } from '@reactionary/core';
2
+ import { AlgoliaProductProvider } from '../providers/product.provider';
3
+
4
+ describe('Algolia Product Provider', () => {
5
+ it('should be able to get a product by id', async () => {
6
+ const provider = new AlgoliaProductProvider({
7
+ apiKey: process.env['ALGOLIA_API_KEY'] || '',
8
+ appId: process.env['ALGOLIA_APP_ID'] || '',
9
+ indexName: process.env['ALGOLIA_INDEX'] || ''
10
+ }, ProductSchema);
11
+
12
+ const result = await provider.get({ id: '4d28f98d-c446-446e-b59a-d9f718e5b98a'});
13
+
14
+ expect(result.identifier.key).toBe('4d28f98d-c446-446e-b59a-d9f718e5b98a');
15
+ expect(result.name).toBe('Sunnai Glass Bowl');
16
+ expect(result.image).toBe('https://res.cloudinary.com/dfke2ip5c/image/upload/c_thumb,w_200,g_face/v1744117881/6d189e9017e385a6a465b9099227ccae.jpeg');
17
+ });
18
+ });
@@ -0,0 +1,82 @@
1
+ import { SearchResultSchema } from '@reactionary/core';
2
+ import { AlgoliaSearchProvider } from '../providers/search.provider';
3
+
4
+ describe('Algolia Search Provider', () => {
5
+ const provider = new AlgoliaSearchProvider({
6
+ apiKey: process.env['ALGOLIA_API_KEY'] || '',
7
+ appId: process.env['ALGOLIA_APP_ID'] || '',
8
+ indexName: process.env['ALGOLIA_INDEX'] || '',
9
+ }, SearchResultSchema);
10
+
11
+ it('should be able to get a result by term', async () => {
12
+ const result = await provider.get({
13
+ term: 'glass',
14
+ page: 0,
15
+ pageSize: 20,
16
+ facets: [],
17
+ });
18
+
19
+ expect(result.products.length).toBeGreaterThan(0);
20
+ expect(result.facets.length).toBe(2);
21
+ expect(result.facets[0].values.length).toBeGreaterThan(0);
22
+ expect(result.facets[1].values.length).toBeGreaterThan(0);
23
+ });
24
+
25
+ it('should be able to paginate', async () => {
26
+ const firstPage = await provider.get({
27
+ term: 'glass',
28
+ page: 0,
29
+ pageSize: 20,
30
+ facets: [],
31
+ });
32
+ const secondPage = await provider.get({
33
+ term: 'glass',
34
+ page: 1,
35
+ pageSize: 20,
36
+ facets: [],
37
+ });
38
+
39
+ expect(firstPage.identifier.page).toBe(0);
40
+ expect(secondPage.identifier.page).toBe(1);
41
+ expect(firstPage.products[0].identifier.key).not.toEqual(
42
+ secondPage.products[0].identifier.key
43
+ );
44
+ });
45
+
46
+ it('should be able to change page size', async () => {
47
+ const smallPage = await provider.get({
48
+ term: 'glass',
49
+ page: 0,
50
+ pageSize: 2,
51
+ facets: [],
52
+ });
53
+ const largePage = await provider.get({
54
+ term: 'glass',
55
+ page: 0,
56
+ pageSize: 30,
57
+ facets: [],
58
+ });
59
+
60
+ expect(smallPage.products.length).toBe(2);
61
+ expect(smallPage.identifier.pageSize).toBe(2);
62
+ expect(largePage.products.length).toBe(30);
63
+ expect(largePage.identifier.pageSize).toBe(30);
64
+ });
65
+
66
+ it('should be able to apply facets', async () => {
67
+ const initial = await provider.get({
68
+ term: 'glass',
69
+ page: 0,
70
+ pageSize: 2,
71
+ facets: [],
72
+ });
73
+ const filtered = await provider.get({
74
+ term: 'glass',
75
+ page: 0,
76
+ pageSize: 2,
77
+ facets: [initial.facets[0].values[0].identifier],
78
+ });
79
+
80
+ expect(initial.pages).toBeGreaterThan(filtered.pages);
81
+ });
82
+ });