@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
@@ -1,223 +0,0 @@
1
- import { ClientBuilder, NoOpCache } from '@reactionary/core';
2
- import { withFakeCapabilities } from '@reactionary/provider-fake';
3
- import { createTRPCServerRouter, createTRPCContext } from './server';
4
- import { createTRPCClient } from './client';
5
- import type { TransparentClient } from './types';
6
- import { createTRPCProxyClient, httpBatchLink } from '@trpc/client';
7
- import { createHTTPHandler } from '@trpc/server/adapters/standalone';
8
- import * as http from 'http';
9
- import { createInitialRequestContext } from '@reactionary/core';
10
-
11
- /**
12
- * Integration test that actually starts an HTTP server and makes real network calls
13
- * This is the real test that verifies the TRPC transparent transport works end-to-end
14
- */
15
-
16
- // Polyfill fetch for Node.js
17
- global.fetch = global.fetch || require('node-fetch');
18
-
19
- // Create the server-side client
20
- const serverClient = new ClientBuilder()
21
- .withCapability(
22
- withFakeCapabilities(
23
- {
24
- jitter: {
25
- mean: 0,
26
- deviation: 0,
27
- },
28
- seeds: {
29
- category: 1,
30
- product: 1,
31
- search: 1
32
- }
33
- },
34
- { search: true, product: true, identity: false }
35
- )
36
- )
37
- .withCache(new NoOpCache())
38
- .build();
39
-
40
- // Create TRPC router from the client (do this at module level for type inference)
41
- const router = createTRPCServerRouter(serverClient);
42
- type AppRouter = typeof router;
43
-
44
- xdescribe('TRPC Integration Test - Real HTTP Server', () => {
45
- let server: http.Server;
46
- let serverPort: number;
47
- let trpcProxyClient: ReturnType<typeof createTRPCProxyClient<AppRouter>>;
48
- let transparentClient: TransparentClient<typeof serverClient>;
49
-
50
- beforeAll(async () => {
51
-
52
- // Create TRPC HTTP handler
53
- const handler = createHTTPHandler({
54
- router,
55
- createContext: createTRPCContext,
56
- });
57
-
58
- // Start HTTP server with TRPC handler
59
- server = http.createServer(handler);
60
-
61
- // Find available port
62
- serverPort = 3001;
63
- await new Promise<void>((resolve, reject) => {
64
- const tryPort = (port: number) => {
65
- server.listen(port, (err?: Error) => {
66
- if (err) {
67
- if (port < 3010) {
68
- tryPort(port + 1);
69
- } else {
70
- reject(err);
71
- }
72
- } else {
73
- serverPort = port;
74
- resolve();
75
- }
76
- });
77
- };
78
- tryPort(serverPort);
79
- });
80
-
81
- // Create real TRPC proxy client (no transformer for testing)
82
- trpcProxyClient = createTRPCProxyClient<AppRouter>({
83
- links: [
84
- httpBatchLink({
85
- url: `http://localhost:${serverPort}`,
86
- }),
87
- ],
88
- });
89
-
90
- // Create transparent client using the real implementation - now properly typed!
91
- transparentClient = createTRPCClient<typeof serverClient>(trpcProxyClient);
92
- });
93
-
94
- afterAll(async () => {
95
- if (server) {
96
- await new Promise<void>((resolve) => {
97
- server.close(() => resolve());
98
- });
99
- }
100
- });
101
-
102
- const reqCtx = createInitialRequestContext();
103
-
104
- describe('Product Provider via HTTP', () => {
105
- it('should fetch product by slug through real HTTP calls', async () => {
106
- const slug = 'integration-test-product';
107
-
108
- // Get result from transparent client (through HTTP/TRPC)
109
- const trpcResult = await transparentClient.product.getBySlug(
110
- { slug },
111
- reqCtx
112
- );
113
-
114
- // Get result from server client (direct call)
115
- const directResult = await serverClient.product.getBySlug(
116
- { slug },
117
- reqCtx
118
- );
119
-
120
- // Results should have the same structure
121
- expect(trpcResult).toBeDefined();
122
- expect(trpcResult.slug).toBe(slug);
123
- expect(trpcResult.name).toBeDefined();
124
- expect(trpcResult.description).toBeDefined();
125
- expect(trpcResult.image).toBeDefined();
126
-
127
- // Both should have the same slug (faker uses seed for consistency)
128
- expect(trpcResult.slug).toBe(directResult.slug);
129
- });
130
-
131
- it('should fetch product by id through real HTTP calls', async () => {
132
- const productId = 'integration-test-id';
133
-
134
- const trpcResult = await transparentClient.product.getById(
135
- { id: productId },
136
- reqCtx
137
- );
138
-
139
- const directResult = await serverClient.product.getById(
140
- { id: productId },
141
- reqCtx
142
- );
143
-
144
- expect(trpcResult).toBeDefined();
145
- expect(trpcResult.identifier.key).toBe(productId);
146
- expect(trpcResult.name).toBeDefined();
147
- expect(trpcResult.description).toBeDefined();
148
-
149
- // Should match direct call
150
- expect(trpcResult.identifier?.key).toBe(directResult.identifier?.key);
151
- });
152
- });
153
-
154
- describe('Search Provider via HTTP', () => {
155
- it('should perform search through real HTTP calls', async () => {
156
- const searchTerm = 'integration test search';
157
-
158
- const trpcResult = await transparentClient.search.queryByTerm(
159
- {
160
- search: {
161
- term: searchTerm,
162
- page: 0,
163
- pageSize: 10,
164
- facets: []
165
- }
166
- },
167
- reqCtx
168
- );
169
-
170
- const directResult = await serverClient.search.queryByTerm(
171
- {
172
- search: {
173
- term: searchTerm,
174
- page: 0,
175
- pageSize: 10,
176
- facets: []
177
- }
178
- },
179
- reqCtx
180
- );
181
-
182
- expect(trpcResult).toBeDefined();
183
- expect(trpcResult.products).toBeDefined();
184
- expect(Array.isArray(trpcResult.products)).toBe(true);
185
- expect(trpcResult.facets).toBeDefined();
186
-
187
- // Should match direct call structure
188
- expect(trpcResult.products.length).toBe(directResult.products.length);
189
- });
190
- });
191
-
192
- describe('Network Error Handling', () => {
193
- it('should handle HTTP errors gracefully', async () => {
194
- // This should work normally first
195
- const result = await transparentClient.product.getById(
196
- { id: 'test-error-handling' },
197
- reqCtx
198
- );
199
- expect(result).toBeDefined();
200
- });
201
- });
202
-
203
- describe('API Equivalence', () => {
204
- it('should produce identical results for TRPC vs direct calls', async () => {
205
- const testId = 'equivalence-test';
206
-
207
- // Make same call through both paths
208
- const [trpcResult, directResult] = await Promise.all([
209
- transparentClient.product.getById(
210
- { id: testId },
211
- reqCtx
212
- ),
213
- serverClient.product.getById({ id: testId }, reqCtx)
214
- ]);
215
-
216
- // Results should be structurally equivalent
217
- expect(trpcResult.identifier.key).toBe(directResult.identifier.key);
218
- expect(trpcResult.name).toBe(directResult.name);
219
- expect(trpcResult.slug).toBe(directResult.slug);
220
- expect(trpcResult.description).toBe(directResult.description);
221
- });
222
- });
223
- });
@@ -1,125 +0,0 @@
1
- import { initTRPC } from '@trpc/server';
2
- import type { Client, RequestContext, Session } from '@reactionary/core';
3
- import superjson from 'superjson';
4
- import { z } from 'zod';
5
- import { createTRPCTracing } from '@reactionary/otel';
6
- import type {
7
- MethodInfo
8
- } from './types';
9
- import {
10
- introspectClient
11
- } from './types';
12
-
13
- // Initialize TRPC with context containing session (no transformer for testing)
14
- const t = initTRPC.context<{ reqCtx?: RequestContext }>().create();
15
-
16
- export const router = t.router;
17
- export const mergeRouters = t.mergeRouters;
18
-
19
- // Apply tracing middleware
20
- const baseProcedure = t.procedure.use(createTRPCTracing());
21
-
22
- /**
23
- * Create a TRPC router from a built client instance
24
- * This function introspects the client and automatically creates TRPC procedures
25
- * for all provider methods while maintaining type safety
26
- *
27
- * @example
28
- * ```typescript
29
- * const client = buildClient([
30
- * withFakeCapabilities(config, { product: true, search: true })
31
- * ]);
32
- *
33
- * const router = createTRPCServerRouter(client);
34
- * ```
35
- */
36
- export function createTRPCServerRouter<T extends Partial<Client>>(client: T) {
37
- const methods = introspectClient(client);
38
-
39
- // Group methods by provider
40
- const providerMethods = methods.reduce((acc, method) => {
41
- if (!acc[method.providerName]) {
42
- acc[method.providerName] = [];
43
- }
44
- acc[method.providerName].push(method);
45
- return acc;
46
- }, {} as Record<string, MethodInfo[]>);
47
-
48
- // Build router structure
49
- const routes: Record<string, any> = {};
50
-
51
- for (const [providerName, providerMethodsList] of Object.entries(providerMethods)) {
52
- const providerRoutes: Record<string, any> = {};
53
-
54
- for (const methodInfo of providerMethodsList) {
55
- const procedure = createProcedureForMethod(methodInfo);
56
- providerRoutes[methodInfo.name] = procedure;
57
- }
58
-
59
- routes[providerName] = t.router(providerRoutes);
60
- }
61
-
62
- return t.router(routes);
63
- }
64
-
65
- /**
66
- * Create a TRPC procedure for a specific provider method
67
- */
68
- function createProcedureForMethod(methodInfo: MethodInfo) {
69
- // Create input schema - we use a flexible schema since we want to preserve
70
- // the original method signatures without requiring schema definitions
71
- const inputSchema = z.object({
72
- payload: z.any(), // The actual payload from the provider method
73
- reqCtx: z.any().optional(), // Session is optional in input since it might come from context
74
- });
75
-
76
- const procedureWithInput = baseProcedure.input(inputSchema);
77
-
78
- if (methodInfo.isQuery) {
79
- return procedureWithInput.query(async ({ input, ctx }) => {
80
- const reqCtx = input.reqCtx || ctx.reqCtx;
81
-
82
- // Call the original provider method
83
- if (reqCtx) {
84
- return await methodInfo.method(input.payload, reqCtx);
85
- } else {
86
- // Some methods might not require session
87
- return await methodInfo.method(input.payload);
88
- }
89
- });
90
- } else if (methodInfo.isMutation) {
91
- return procedureWithInput.mutation(async ({ input, ctx }) => {
92
- const reqCtx = input.reqCtx || ctx.reqCtx;
93
-
94
- // Call the original provider method
95
- if (reqCtx) {
96
- return await methodInfo.method(input.payload, reqCtx);
97
- } else {
98
- // Some methods might not require session
99
- return await methodInfo.method(input.payload);
100
- }
101
- });
102
- } else {
103
- throw new Error(`Method ${methodInfo.name} is neither query nor mutation`);
104
- }
105
- }
106
-
107
- /**
108
- * Type helper to extract the router type from a client
109
- * This enables full type safety on the client side
110
- */
111
- export type TRPCRouterFromClient<T extends Partial<Client>> = ReturnType<typeof createTRPCServerRouter<T>>;
112
-
113
- /**
114
- * Context creator for TRPC server
115
- * Override this to provide session from your authentication system
116
- */
117
- export function createTRPCContext(_opts: { req?: any; res?: any }) {
118
- // Default implementation - you should override this based on your auth system
119
- return {
120
- reqCtx: undefined as RequestContext | undefined,
121
- };
122
- }
123
-
124
- // Create publicProcedure here to avoid circular imports
125
- export const publicProcedure = baseProcedure;
@@ -1,161 +0,0 @@
1
- import { ClientBuilder, createInitialRequestContext, NoOpCache } from '@reactionary/core';
2
- import { withFakeCapabilities } from '@reactionary/provider-fake';
3
- import { createTRPCServerRouter, introspectClient } from './index';
4
-
5
- /**
6
- * Test suite for TRPC transparent client functionality
7
- * This tests the core introspection and router generation without HTTP setup
8
- */
9
-
10
- // Jest test framework is now available
11
-
12
- // Create the server-side client using the same pattern as examples/node
13
- const serverClient = new ClientBuilder()
14
- .withCapability(
15
- withFakeCapabilities(
16
- {
17
- jitter: {
18
- mean: 0,
19
- deviation: 0,
20
- },
21
- seeds: {
22
- category: 1,
23
- product: 1,
24
- search: 1
25
- }
26
- },
27
- { search: true, product: true, identity: false }
28
- )
29
- )
30
- .withCache(new NoOpCache())
31
- .build();
32
-
33
- // Create TRPC router from the client
34
- const router = createTRPCServerRouter(serverClient);
35
-
36
- xdescribe('TRPC Transparent Client Core Functionality', () => {
37
-
38
- const reqCtx = createInitialRequestContext();
39
-
40
- describe('Client Introspection', () => {
41
- it('should correctly introspect client methods', () => {
42
- const methods = introspectClient(serverClient);
43
-
44
- expect(methods.length).toBeGreaterThan(0);
45
-
46
- // Should find product methods
47
- const productMethods = methods.filter(m => m.providerName === 'product');
48
- expect(productMethods.length).toBeGreaterThan(0);
49
-
50
- const getBySlugMethod = productMethods.find(m => m.name === 'getBySlug');
51
- expect(getBySlugMethod).toBeDefined();
52
- expect(getBySlugMethod!.isQuery).toBe(true);
53
- expect(getBySlugMethod!.isMutation).toBe(false);
54
-
55
- // Should find search methods
56
- const searchMethods = methods.filter(m => m.providerName === 'search');
57
- expect(searchMethods.length).toBeGreaterThan(0);
58
-
59
- const queryByTermMethod = searchMethods.find(m => m.name === 'queryByTerm');
60
- expect(queryByTermMethod).toBeDefined();
61
- expect(queryByTermMethod!.isQuery).toBe(true);
62
-
63
- // Note: Only testing enabled providers (product and search)
64
- });
65
- });
66
-
67
- describe('Router Generation', () => {
68
- it('should create TRPC router from client', () => {
69
- expect(router).toBeDefined();
70
-
71
- // Router should be an object (TRPC router)
72
- expect(typeof router).toBe('object');
73
- expect(router).toBeDefined();
74
- });
75
-
76
- it('should handle provider methods correctly', () => {
77
- const methods = introspectClient(serverClient);
78
- const providerNames = [...new Set(methods.map(m => m.providerName))];
79
-
80
- // Should have enabled providers
81
- expect(providerNames).toContain('product');
82
- expect(providerNames).toContain('search');
83
- });
84
- });
85
-
86
- describe('Method Classification', () => {
87
- it('should correctly classify query methods', () => {
88
- const methods = introspectClient(serverClient);
89
-
90
- const queryMethods = methods.filter(m => m.isQuery);
91
- const queryMethodNames = queryMethods.map(m => m.name);
92
-
93
- // Should include get* methods from enabled providers
94
- expect(queryMethodNames).toContain('getById');
95
- expect(queryMethodNames).toContain('getBySlug');
96
-
97
- // Should include query* methods
98
- expect(queryMethodNames).toContain('queryByTerm');
99
- });
100
-
101
- it('should correctly classify mutation methods', () => {
102
- const methods = introspectClient(serverClient);
103
-
104
- const mutationMethods = methods.filter(m => m.isMutation);
105
- const mutationMethodNames = mutationMethods.map(m => m.name);
106
-
107
- // With current setup, only search and product are enabled
108
- // No mutations expected from these providers
109
- });
110
- });
111
-
112
- describe('Direct Client Functionality', () => {
113
- it('should have working product provider', async () => {
114
- const result = await serverClient.product.getBySlug(
115
- { slug: 'test-product' },
116
- reqCtx
117
- );
118
-
119
- expect(result).toBeDefined();
120
- expect(result.slug).toBe('test-product');
121
- expect(result.name).toBeDefined();
122
- expect(result.description).toBeDefined();
123
- });
124
-
125
- it('should have working search provider', async () => {
126
- const result = await serverClient.search.queryByTerm(
127
- {
128
- search: {
129
- term: 'test search',
130
- page: 0,
131
- pageSize: 10,
132
- facets: []
133
- }
134
- },
135
- reqCtx
136
- );
137
-
138
- expect(result).toBeDefined();
139
- expect(result.products).toBeDefined();
140
- expect(result.facets).toBeDefined();
141
- });
142
-
143
- // Only testing enabled providers (product and search)
144
- });
145
-
146
- describe('Type System Validation', () => {
147
- it('should maintain provider interface structure', () => {
148
- // Verify the client has expected enabled provider structure
149
- expect(serverClient.product).toBeDefined();
150
- expect(serverClient.search).toBeDefined();
151
-
152
- // Verify methods exist
153
- expect(typeof serverClient.product.getById).toBe('function');
154
- expect(typeof serverClient.product.getBySlug).toBe('function');
155
- expect(typeof serverClient.search.queryByTerm).toBe('function');
156
- });
157
- });
158
- });
159
-
160
- // Export for potential use in other tests
161
- export { serverClient, router };
package/trpc/src/types.ts DELETED
@@ -1,144 +0,0 @@
1
- import type {
2
- Client,
3
- RequestContext,
4
- Session} from '@reactionary/core';
5
- import {
6
- BaseProvider
7
- } from '@reactionary/core';
8
-
9
- /**
10
- * Extract method names from a provider that match TRPC patterns
11
- */
12
- export type ProviderMethods<T> = T extends BaseProvider
13
- ? {
14
- [K in keyof T]: T[K] extends (...args: any[]) => any
15
- ? K extends `get${string}` | `query${string}` | 'add' | 'remove' | 'changeQuantity' | 'login' | 'logout' | 'getSelf'
16
- ? K
17
- : never
18
- : never
19
- }[keyof T]
20
- : never;
21
-
22
- /**
23
- * Extract method signature from a provider method
24
- */
25
- export type ProviderMethodSignature<T, K extends keyof T> =
26
- T[K] extends (...args: infer Args) => infer Return
27
- ? (...args: Args) => Return
28
- : never;
29
-
30
- /**
31
- * Map all methods of all providers in a client
32
- */
33
- export type ClientMethodMap<T extends Partial<Client>> = {
34
- [K in keyof T]: T[K] extends BaseProvider
35
- ? {
36
- [M in ProviderMethods<T[K]>]: ProviderMethodSignature<T[K], M>
37
- }
38
- : never;
39
- };
40
-
41
-
42
- /**
43
- * Create transparent client that only includes methods matching TRPC patterns
44
- */
45
- export type TransparentClient<T extends Partial<Client>> = {
46
- [K in keyof T]: T[K] extends BaseProvider
47
- ? {
48
- [M in ProviderMethods<T[K]>]: ProviderMethodSignature<T[K], M>
49
- }
50
- : never;
51
- };
52
-
53
- /**
54
- * Extract method information for TRPC procedure creation
55
- */
56
- export interface MethodInfo {
57
- name: string;
58
- providerName: string;
59
- isQuery: boolean;
60
- isMutation: boolean;
61
- method: (...args: any[]) => any;
62
- }
63
-
64
-
65
- /**
66
- * Utility to determine if a method is a query or mutation based on naming convention
67
- */
68
- export function isQueryMethod(methodName: string): boolean {
69
- return methodName.startsWith('get') ||
70
- methodName.startsWith('query') ||
71
- methodName === 'getSelf';
72
- }
73
-
74
- export function isMutationMethod(methodName: string): boolean {
75
- return !isQueryMethod(methodName) && (
76
- methodName === 'add' ||
77
- methodName === 'remove' ||
78
- methodName === 'changeQuantity' ||
79
- methodName === 'login' ||
80
- methodName === 'logout'
81
- );
82
- }
83
-
84
- /**
85
- * Introspect a client instance to extract all provider methods matching naming patterns
86
- */
87
- export function introspectClient<T extends Partial<Client>>(client: T): MethodInfo[] {
88
- const methods: MethodInfo[] = [];
89
-
90
- for (const [providerName, provider] of Object.entries(client)) {
91
- if (provider instanceof BaseProvider) {
92
- // Get all methods that match our naming patterns
93
- for (const key of Object.getOwnPropertyNames(Object.getPrototypeOf(provider))) {
94
- const method = (provider as any)[key];
95
- if (typeof method === 'function' && key !== 'constructor') {
96
- if (isQueryMethod(key) || isMutationMethod(key)) {
97
- methods.push({
98
- name: key,
99
- providerName,
100
- isQuery: isQueryMethod(key),
101
- isMutation: isMutationMethod(key),
102
- method: method.bind(provider)
103
- });
104
- }
105
- }
106
- }
107
- }
108
- }
109
-
110
- return methods;
111
- }
112
-
113
- /**
114
- * Type for TRPC procedure input - includes payload and session
115
- */
116
- export interface TRPCMethodInput<TPayload = any> {
117
- payload: TPayload;
118
- session?: Session;
119
- }
120
-
121
- /**
122
- * Helper to extract payload type from a provider method
123
- */
124
- export type ExtractPayloadType<T> = T extends (payload: infer P, reqCtx: RequestContext) => any
125
- ? P
126
- : T extends (payload: infer P) => any
127
- ? P
128
- : never;
129
-
130
- /**
131
- * Helper to extract return type from a provider method
132
- */
133
- export type ExtractReturnType<T> = T extends (...args: any[]) => infer R
134
- ? R
135
- : never;
136
-
137
- /**
138
- * Create a TRPC-compatible method signature from a provider method
139
- */
140
- export type TRPCMethodSignature<T> = T extends (payload: infer P, reqCtx: RequestContext) => infer R
141
- ? (input: TRPCMethodInput<P>) => R
142
- : T extends (payload: infer P) => infer R
143
- ? (input: TRPCMethodInput<P>) => R
144
- : never;
@@ -1,16 +0,0 @@
1
- {
2
- "extends": "../tsconfig.base.json",
3
- "compilerOptions": {
4
- "module": "commonjs"
5
- },
6
- "files": [],
7
- "include": [],
8
- "references": [
9
- {
10
- "path": "./tsconfig.lib.json"
11
- },
12
- {
13
- "path": "./tsconfig.spec.json"
14
- }
15
- ]
16
- }
@@ -1,15 +0,0 @@
1
- {
2
- "extends": "./tsconfig.json",
3
- "compilerOptions": {
4
- "outDir": "../dist/out-tsc",
5
- "module": "commonjs",
6
- "moduleResolution": "node10",
7
- "types": ["jest", "node"]
8
- },
9
- "include": [
10
- "jest.config.ts",
11
- "src/**/*.test.ts",
12
- "src/**/*.spec.ts",
13
- "src/**/*.d.ts"
14
- ]
15
- }