@reactionary/source 0.0.42 → 0.0.51

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 (137) hide show
  1. package/.vscode/settings.json +5 -0
  2. package/core/package.json +3 -1
  3. package/core/src/cache/cache.interface.ts +14 -18
  4. package/core/src/cache/memory-cache.ts +56 -0
  5. package/core/src/cache/noop-cache.ts +5 -23
  6. package/core/src/cache/redis-cache.ts +28 -38
  7. package/core/src/client/client-builder.ts +3 -3
  8. package/core/src/client/client.ts +11 -11
  9. package/core/src/decorators/reactionary.decorator.ts +80 -8
  10. package/core/src/index.ts +2 -1
  11. package/{examples/node/src/test-utils.ts → core/src/initialization.ts} +20 -10
  12. package/core/src/providers/analytics.provider.ts +1 -1
  13. package/core/src/providers/base.provider.ts +61 -25
  14. package/core/src/providers/cart.provider.ts +17 -18
  15. package/core/src/providers/category.provider.ts +9 -9
  16. package/core/src/providers/checkout.provider.ts +156 -0
  17. package/core/src/providers/identity.provider.ts +8 -7
  18. package/core/src/providers/index.ts +4 -1
  19. package/core/src/providers/inventory.provider.ts +4 -4
  20. package/core/src/providers/order.provider.ts +31 -0
  21. package/core/src/providers/price.provider.ts +6 -6
  22. package/core/src/providers/product.provider.ts +6 -6
  23. package/core/src/providers/profile.provider.ts +22 -0
  24. package/core/src/providers/search.provider.ts +4 -4
  25. package/core/src/providers/store.provider.ts +14 -0
  26. package/core/src/schemas/capabilities.schema.ts +4 -2
  27. package/core/src/schemas/models/analytics.model.ts +1 -1
  28. package/core/src/schemas/models/cart.model.ts +1 -20
  29. package/core/src/schemas/models/checkout.model.ts +68 -0
  30. package/core/src/schemas/models/cost.model.ts +21 -0
  31. package/core/src/schemas/models/identifiers.model.ts +84 -35
  32. package/core/src/schemas/models/identity.model.ts +19 -20
  33. package/core/src/schemas/models/index.ts +5 -0
  34. package/core/src/schemas/models/order.model.ts +47 -0
  35. package/core/src/schemas/models/payment.model.ts +3 -10
  36. package/core/src/schemas/models/product.model.ts +6 -3
  37. package/core/src/schemas/models/profile.model.ts +3 -2
  38. package/core/src/schemas/models/shipping-method.model.ts +34 -3
  39. package/core/src/schemas/models/store.model.ts +11 -0
  40. package/core/src/schemas/mutations/cart.mutation.ts +2 -2
  41. package/core/src/schemas/mutations/checkout.mutation.ts +50 -0
  42. package/core/src/schemas/mutations/identity.mutation.ts +6 -0
  43. package/core/src/schemas/mutations/index.ts +2 -1
  44. package/core/src/schemas/mutations/profile.mutation.ts +9 -0
  45. package/core/src/schemas/queries/cart.query.ts +1 -1
  46. package/core/src/schemas/queries/checkout.query.ts +22 -0
  47. package/core/src/schemas/queries/identity.query.ts +1 -1
  48. package/core/src/schemas/queries/index.ts +4 -1
  49. package/core/src/schemas/queries/inventory.query.ts +4 -12
  50. package/core/src/schemas/queries/order.query.ts +9 -0
  51. package/core/src/schemas/queries/price.query.ts +1 -1
  52. package/core/src/schemas/queries/product.query.ts +8 -1
  53. package/core/src/schemas/queries/profile.query.ts +7 -0
  54. package/core/src/schemas/queries/search.query.ts +1 -1
  55. package/core/src/schemas/queries/store.query.ts +11 -0
  56. package/core/src/schemas/session.schema.ts +31 -6
  57. package/eslint.config.mjs +7 -0
  58. package/examples/next/src/app/page.tsx +4 -12
  59. package/examples/node/package.json +1 -3
  60. package/examples/node/src/basic/basic-node-provider-model-extension.spec.ts +9 -8
  61. package/examples/node/src/basic/basic-node-provider-query-extension.spec.ts +4 -3
  62. package/examples/node/src/basic/basic-node-setup.spec.ts +4 -5
  63. package/nx.json +1 -0
  64. package/otel/src/metrics.ts +2 -1
  65. package/otel/src/provider-instrumentation.ts +2 -1
  66. package/otel/src/trace-decorator.ts +8 -8
  67. package/otel/src/tracer.ts +7 -6
  68. package/otel/src/trpc-middleware.ts +3 -2
  69. package/package.json +4 -1
  70. package/providers/algolia/src/core/initialize.ts +4 -3
  71. package/providers/algolia/src/providers/product.provider.ts +21 -13
  72. package/providers/algolia/src/providers/search.provider.ts +9 -9
  73. package/providers/algolia/src/schema/capabilities.schema.ts +1 -1
  74. package/providers/algolia/src/test/search.provider.spec.ts +10 -10
  75. package/providers/algolia/src/test/test-utils.ts +1 -1
  76. package/providers/commercetools/README.md +11 -0
  77. package/providers/commercetools/package.json +1 -0
  78. package/providers/commercetools/src/core/client.ts +174 -87
  79. package/providers/commercetools/src/core/initialize.ts +23 -16
  80. package/providers/commercetools/src/providers/cart.provider.ts +98 -117
  81. package/providers/commercetools/src/providers/category.provider.ts +34 -37
  82. package/providers/commercetools/src/providers/checkout.provider.ts +644 -0
  83. package/providers/commercetools/src/providers/identity.provider.ts +22 -82
  84. package/providers/commercetools/src/providers/index.ts +5 -0
  85. package/providers/commercetools/src/providers/inventory.provider.ts +67 -48
  86. package/providers/commercetools/src/providers/order.provider.ts +165 -0
  87. package/providers/commercetools/src/providers/price.provider.ts +76 -50
  88. package/providers/commercetools/src/providers/product.provider.ts +43 -23
  89. package/providers/commercetools/src/providers/profile.provider.ts +61 -0
  90. package/providers/commercetools/src/providers/search.provider.ts +12 -15
  91. package/providers/commercetools/src/providers/store.provider.ts +78 -0
  92. package/providers/commercetools/src/schema/capabilities.schema.ts +4 -2
  93. package/providers/commercetools/src/schema/commercetools.schema.ts +7 -5
  94. package/providers/commercetools/src/schema/configuration.schema.ts +2 -0
  95. package/providers/commercetools/src/test/cart.provider.spec.ts +38 -17
  96. package/providers/commercetools/src/test/category.provider.spec.ts +18 -17
  97. package/providers/commercetools/src/test/checkout.provider.spec.ts +312 -0
  98. package/providers/commercetools/src/test/identity.provider.spec.ts +88 -0
  99. package/providers/commercetools/src/test/inventory.provider.spec.ts +41 -0
  100. package/providers/commercetools/src/test/price.provider.spec.ts +10 -9
  101. package/providers/commercetools/src/test/product.provider.spec.ts +28 -10
  102. package/providers/commercetools/src/test/profile.provider.spec.ts +49 -0
  103. package/providers/commercetools/src/test/search.provider.spec.ts +8 -7
  104. package/providers/commercetools/src/test/store.provider.spec.ts +37 -0
  105. package/providers/commercetools/src/test/test-utils.ts +13 -38
  106. package/providers/fake/src/core/initialize.ts +96 -38
  107. package/providers/fake/src/providers/analytics.provider.ts +6 -5
  108. package/providers/fake/src/providers/cart.provider.ts +30 -27
  109. package/providers/fake/src/providers/category.provider.ts +16 -12
  110. package/providers/fake/src/providers/identity.provider.ts +22 -14
  111. package/providers/fake/src/providers/index.ts +1 -0
  112. package/providers/fake/src/providers/inventory.provider.ts +13 -13
  113. package/providers/fake/src/providers/price.provider.ts +13 -13
  114. package/providers/fake/src/providers/product.provider.ts +20 -14
  115. package/providers/fake/src/providers/search.provider.ts +7 -5
  116. package/providers/fake/src/providers/store.provider.ts +47 -0
  117. package/providers/fake/src/schema/capabilities.schema.ts +4 -1
  118. package/providers/fake/src/test/cart.provider.spec.ts +18 -18
  119. package/providers/fake/src/test/category.provider.spec.ts +55 -37
  120. package/providers/fake/src/test/price.provider.spec.ts +9 -14
  121. package/providers/fake/src/test/product.provider.spec.ts +27 -0
  122. package/providers/fake/src/test/test-utils.ts +2 -33
  123. package/providers/posthog/src/core/initialize.ts +3 -3
  124. package/providers/posthog/src/schema/capabilities.schema.ts +1 -1
  125. package/trpc/src/client.ts +42 -41
  126. package/trpc/src/index.ts +4 -3
  127. package/trpc/src/integration.spec.ts +11 -11
  128. package/trpc/src/server.ts +27 -25
  129. package/trpc/src/transparent-client.spec.ts +4 -5
  130. package/trpc/src/types.ts +24 -22
  131. package/core/src/cache/cache-evaluation.interface.ts +0 -19
  132. package/core/src/providers/cart-payment.provider.ts +0 -56
  133. package/core/src/schemas/mutations/cart-payment.mutation.ts +0 -21
  134. package/core/src/schemas/queries/cart-payment.query.ts +0 -12
  135. package/providers/commercetools/src/providers/cart-payment.provider.ts +0 -192
  136. package/providers/commercetools/src/test/cart-payment.provider.spec.ts +0 -149
  137. package/trpc/src/test-utils.ts +0 -31
@@ -1,12 +0,0 @@
1
- import z from "zod";
2
- import { CartIdentifierSchema } from "../models/identifiers.model";
3
- import { PaymentStatusSchema } from "../models/payment.model";
4
- import { BaseQuerySchema } from "./base.query";
5
-
6
-
7
- export const CartPaymentQueryByCartSchema = BaseQuerySchema.extend({
8
- cart: CartIdentifierSchema.required(),
9
- status: z.array(PaymentStatusSchema).optional().describe('Optional status to filter payment instructions by'),
10
- });
11
-
12
- export type CartPaymentQueryByCart = z.infer<typeof CartPaymentQueryByCartSchema>;
@@ -1,192 +0,0 @@
1
-
2
- import { CommercetoolsConfiguration } from "../schema/configuration.schema";
3
- import { CommercetoolsClient } from "../core/client";
4
- import { Payment as CTPayment, PaymentStatus } from "@commercetools/platform-sdk";
5
- import { traced } from "@reactionary/otel";
6
- import { CommercetoolsCartIdentifier, CommercetoolsCartIdentifierSchema, CommercetoolsCartPaymentInstructionIdentifierSchema } from "../schema/commercetools.schema";
7
- import { Cache, CartPaymentInstruction, CartPaymentProvider, Currency, PaymentMethodIdentifierSchema, } from "@reactionary/core";
8
- import type { CartPaymentQueryByCart, CartPaymentMutationAddPayment, CartPaymentMutationCancelPayment, Session } from "@reactionary/core";
9
- import z from "zod";
10
-
11
- export class CommercetoolsCartPaymentProvider<
12
- T extends CartPaymentInstruction = CartPaymentInstruction
13
- > extends CartPaymentProvider<T> {
14
- protected config: CommercetoolsConfiguration;
15
-
16
- constructor(config: CommercetoolsConfiguration, schema: z.ZodType<T>, cache: Cache) {
17
- super(schema, cache);
18
-
19
- this.config = config;
20
- }
21
-
22
- protected getClient(session: Session) {
23
- const token = session.identity.keyring.find(x => x.service === 'commercetools')?.token;
24
- const client = new CommercetoolsClient(this.config).getClient(
25
- token
26
- );
27
- return {
28
- payments: client.withProjectKey({ projectKey: this.config.projectKey }).me().payments(),
29
- carts: client.withProjectKey({ projectKey: this.config.projectKey }).me().carts()
30
- };
31
- }
32
-
33
-
34
-
35
- @traced()
36
- public override async getByCartIdentifier(payload: CartPaymentQueryByCart, session: Session): Promise<T[]> {
37
- const client = this.getClient(session);
38
-
39
- const ctId = payload.cart as CommercetoolsCartIdentifier;
40
- const ctVersion = ctId.version || 0;
41
-
42
- const cart = await client.carts.withId({ ID: ctId.key })
43
- .get({
44
- queryArgs: {
45
- expand: 'paymentInfo.payments[*]',
46
- },
47
- })
48
- .execute();
49
-
50
- let payments = (cart.body.paymentInfo?.payments || []).map(x => x.obj!).filter(x => x);
51
- if (payload.status) {
52
- payments = payments.filter(payment => payload.status!.some(status => payment.paymentStatus?.interfaceCode === status));
53
- }
54
-
55
- // Map over the payments and parse each one
56
- const parsedPayments = payments.map(payment => this.parseSingle(payment, session));
57
-
58
- // Commercetools does not link carts to payments, but the other way around, so for this we have to synthesize the link.
59
- const returnPayments = parsedPayments.map(x => {
60
- x.cart = { key: cart.body.id, version: cart.body.version || 0 };
61
- return x;
62
- });
63
- return returnPayments;
64
- }
65
-
66
-
67
-
68
- public override async initiatePaymentForCart(payload: CartPaymentMutationAddPayment, session: Session): Promise<T> {
69
- const client = this.getClient(session);
70
- const cartId = payload.cart as CommercetoolsCartIdentifier;
71
- const response = await client.payments.post({
72
- body: {
73
-
74
- amountPlanned: {
75
- centAmount: Math.round(payload.paymentInstruction.amount.value * 100),
76
- currencyCode: payload.paymentInstruction.amount.currency
77
- },
78
- paymentMethodInfo: {
79
- method: payload.paymentInstruction.paymentMethod.method,
80
- name: {
81
- [session.languageContext.locale]: payload.paymentInstruction.paymentMethod.name
82
- },
83
- paymentInterface: payload.paymentInstruction.paymentMethod.paymentProcessor
84
- },
85
- custom:{
86
- type: {
87
- typeId: 'type',
88
- key: 'reactionaryPaymentCustomFields',
89
- },
90
- fields: {
91
- cartId: cartId.key,
92
- cartVersion: cartId.version + '',
93
- }},
94
-
95
- },
96
- }).execute();
97
-
98
- // Now add the payment to the cart
99
- const ctId = payload.cart as CommercetoolsCartIdentifier
100
- const updatedCart = await client.carts.withId({ ID: ctId.key }).post({
101
- body: {
102
- version: ctId.version,
103
- actions: [
104
- {
105
- 'action': 'addPayment',
106
- 'payment': {
107
- 'typeId': 'payment',
108
- 'id': response.body.id
109
- }
110
- }
111
- ]
112
- }
113
- }).execute();
114
-
115
- const payment = this.parseSingle(response.body, session);
116
-
117
- // we return the newest cart version so caller can update their cart reference, if they want to.
118
- // hopefully this wont cause excessive confusion
119
- payment.cart = CommercetoolsCartIdentifierSchema.parse({
120
- key: updatedCart.body.id,
121
- version: updatedCart.body.version || 0
122
- });
123
- return payment;
124
- }
125
-
126
-
127
- @traced()
128
- public override async cancelPaymentInstruction(payload: CartPaymentMutationCancelPayment, session: Session): Promise<T> {
129
- const client = this.getClient(session);
130
-
131
- // get newest version
132
- const newestVersion = await client.payments.withId({ ID: payload.paymentInstruction.key }).get().execute();
133
-
134
-
135
- // we set the planned amount to 0, which effectively cancels the payment, and also allows the backend to clean it up.
136
- // Note: This does NOT remove the payment from the cart, as that would be a breaking change to the cart, and we want to avoid that during checkout.
137
- // Instead, the payment will remain on the cart, but with status 'canceled', and can be removed later if needed.
138
- // This also allows us to keep a record of the payment instruction for auditing purposes.
139
- // The cart can be re-used, and a new payment instruction can be added to it later.
140
- // The frontend should ignore any payment instructions with status 'canceled' when displaying payment options to the user.
141
- const response = await client.payments.withId({ ID: payload.paymentInstruction.key }).post({
142
- body: {
143
- version: newestVersion.body.version,
144
- actions: [
145
- {
146
- action: 'changeAmountPlanned',
147
- amount: {
148
- centAmount: 0,
149
- currencyCode: newestVersion.body.amountPlanned.currencyCode
150
- }
151
- },
152
- ]
153
- }
154
- }).execute();
155
-
156
- const payment = this.parseSingle(response.body, session);
157
- payment.cart = payload.cart;
158
- return payment;
159
- }
160
-
161
-
162
-
163
- @traced()
164
- protected override parseSingle(_body: unknown, session: Session): T {
165
- const body = _body as CTPayment;
166
-
167
- const base = this.newModel();
168
- base.identifier = CommercetoolsCartPaymentInstructionIdentifierSchema.parse({
169
- key: body.id,
170
- version: body.version || 0
171
- });
172
-
173
- base.amount = {
174
- value: body.amountPlanned.centAmount / 100,
175
- currency: body.amountPlanned.currencyCode as Currency,
176
- };
177
-
178
-
179
- base.paymentMethod = PaymentMethodIdentifierSchema.parse({
180
- key: body.paymentMethodInfo?.method
181
- });
182
-
183
- // FIXME: seems wrong
184
- base.status = body.paymentStatus?.interfaceCode as unknown as any;
185
-
186
- base.cart = { key: '', version: 0 };
187
-
188
- return this.assert(base);
189
- }
190
-
191
-
192
- }
@@ -1,149 +0,0 @@
1
- import 'dotenv/config';
2
- import {
3
- Cart,
4
- CartMutationAddPaymentMethodSchema,
5
- CartPaymentInstructionSchema,
6
- CartSchema,
7
- IdentitySchema,
8
- NoOpCache,
9
- Session,
10
- } from '@reactionary/core';
11
- import {
12
- createAnonymousTestSession,
13
- getCommercetoolsTestConfiguration,
14
- } from './test-utils';
15
- import { CommercetoolsCartProvider } from '../providers/cart.provider';
16
- import { CommercetoolsIdentityProvider } from '../providers/identity.provider';
17
- import { CommercetoolsCartPaymentProvider } from '../providers/cart-payment.provider';
18
- import { CartPaymentMutationAddPayment } from 'core/src/schemas/mutations/cart-payment.mutation';
19
-
20
- const testData = {
21
- skuWithoutTiers: 'SGB-01',
22
- skuWithTiers: 'GMCT-01',
23
- };
24
-
25
- describe('Commercetools Cart Payment Provider', () => {
26
- let provider: CommercetoolsCartPaymentProvider;
27
- let cartProvider: CommercetoolsCartProvider;
28
- let identityProvider: CommercetoolsIdentityProvider;
29
- let session: Session;
30
-
31
- beforeAll(() => {
32
- provider = new CommercetoolsCartPaymentProvider(
33
- getCommercetoolsTestConfiguration(),
34
- CartPaymentInstructionSchema,
35
- new NoOpCache()
36
- );
37
- cartProvider = new CommercetoolsCartProvider(
38
- getCommercetoolsTestConfiguration(),
39
- CartSchema,
40
- new NoOpCache()
41
- );
42
- identityProvider = new CommercetoolsIdentityProvider(
43
- getCommercetoolsTestConfiguration(),
44
- IdentitySchema,
45
- new NoOpCache()
46
- );
47
- });
48
-
49
- beforeEach(() => {
50
- session = createAnonymousTestSession();
51
- });
52
-
53
- describe('anonymous sessions', () => {
54
- let cart: Cart;
55
-
56
- beforeEach(async () => {
57
- cart = await cartProvider.add(
58
- {
59
- cart: { key: '', version: 0 },
60
- sku: {
61
- key: testData.skuWithoutTiers,
62
- },
63
- quantity: 1,
64
- },
65
- session
66
- );
67
- });
68
-
69
- it('a new cart will return 0 payment instructions', async () => {
70
- const payments = await provider.getByCartIdentifier(
71
- { cart: cart.identifier, status: undefined },
72
- session
73
- );
74
- expect(payments.length).toBe(0);
75
- });
76
-
77
- it('can initiate a new payment', async () => {
78
- const payment = await provider.initiatePaymentForCart(
79
- {
80
- cart: cart.identifier,
81
- paymentInstruction: {
82
- paymentMethod: {
83
- method: 'stripe',
84
- name: 'Stripe',
85
- paymentProcessor: 'stripe',
86
- },
87
- amount: {
88
- value: cart.price.grandTotal.value,
89
- currency: cart.price.grandTotal.currency,
90
- },
91
- protocolData: [{ key: 'test-key', value: 'test-value' }],
92
- },
93
- },
94
- session
95
- );
96
-
97
- expect(payment.identifier.key).toBeDefined();
98
-
99
- // verify that we can fetch it again.
100
- const payments = await provider.getByCartIdentifier(
101
- { cart: cart.identifier, status: undefined },
102
- session
103
- );
104
- expect(payments.length).toBe(1);
105
- expect(payments[0].identifier.key).toBe(payment.identifier.key);
106
- });
107
-
108
-
109
- it('can cancel an in-progress payment', async () => {
110
- const payment = await provider.initiatePaymentForCart(
111
- {
112
- cart: cart.identifier,
113
- paymentInstruction: {
114
- paymentMethod: {
115
- method: 'stripe',
116
- name: 'Stripe',
117
- paymentProcessor: 'stripe',
118
- },
119
- amount: {
120
- value: cart.price.grandTotal.value,
121
- currency: cart.price.grandTotal.currency,
122
- },
123
- protocolData: [{ key: 'test-key', value: 'test-value' }],
124
- },
125
- },
126
- session
127
- );
128
- expect(payment.identifier.key).toBeDefined();
129
-
130
- const cancelledPayment = await provider.cancelPaymentInstruction(
131
- {
132
- cart: cart.identifier,
133
- paymentInstruction: payment.identifier
134
- },
135
- session
136
- );
137
- expect(cancelledPayment.status).toBe('canceled');
138
-
139
-
140
- // verify that it is gone
141
- const payments = await provider.getByCartIdentifier(
142
- { cart: cart.identifier, status: undefined },
143
- session
144
- );
145
- expect(payments.length).toBe(0);
146
- expect(payments[0].identifier.key).toBe(payment.identifier.key);
147
- });
148
- });
149
- });
@@ -1,31 +0,0 @@
1
- import { Session } from '@reactionary/core';
2
-
3
- export function createAnonymousTestSession(): Session {
4
- return {
5
- id: 'test-session-id',
6
- identity: {
7
- type: 'Anonymous',
8
- meta: {
9
- cache: { hit: false, key: '' },
10
- placeholder: false,
11
- },
12
- id: { userId: 'anonymous' },
13
- token: undefined,
14
- issued: new Date(),
15
- expiry: new Date(new Date().getTime() + 3600 * 1000),
16
- logonId: "",
17
- createdAt: "",
18
- updatedAt: "",
19
- keyring: [],
20
- currentService: undefined
21
- },
22
- languageContext: {
23
- locale: 'en-US',
24
- currencyCode: 'USD',
25
- countryCode: 'US',
26
- },
27
- storeIdentifier: {
28
- key: 'the-good-store',
29
- },
30
- };
31
- }