@reactionary/source 0.3.18 → 0.6.2

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 (191) hide show
  1. package/README.md +28 -14
  2. package/core/src/client/client-builder.ts +54 -6
  3. package/core/src/factories/cart.factory.ts +40 -0
  4. package/core/src/factories/category.factory.ts +40 -0
  5. package/core/src/factories/checkout.factory.ts +59 -0
  6. package/core/src/factories/identity.factory.ts +26 -0
  7. package/core/src/factories/index.ts +15 -0
  8. package/core/src/factories/inventory.factory.ts +26 -0
  9. package/core/src/factories/order-search.factory.ts +33 -0
  10. package/core/src/factories/order.factory.ts +21 -0
  11. package/core/src/factories/price.factory.ts +29 -0
  12. package/core/src/factories/product-associations.factory.ts +30 -0
  13. package/core/src/factories/product-list.factory.ts +82 -0
  14. package/core/src/factories/product-reviews.factory.ts +58 -0
  15. package/core/src/factories/product-search.factory.ts +31 -0
  16. package/core/src/factories/product.factory.ts +21 -0
  17. package/core/src/factories/profile.factory.ts +23 -0
  18. package/core/src/factories/store.factory.ts +21 -0
  19. package/core/src/index.ts +3 -1
  20. package/core/src/providers/cart.provider.ts +12 -10
  21. package/core/src/providers/category.provider.ts +9 -7
  22. package/core/src/providers/checkout.provider.ts +14 -10
  23. package/core/src/providers/identity.provider.ts +7 -7
  24. package/core/src/providers/inventory.provider.ts +4 -4
  25. package/core/src/providers/order-search.provider.ts +4 -2
  26. package/core/src/providers/order.provider.ts +4 -4
  27. package/core/src/providers/price.provider.ts +5 -5
  28. package/core/src/providers/product-associations.provider.ts +6 -4
  29. package/core/src/providers/product-list.provider.ts +13 -8
  30. package/core/src/providers/product-reviews.provider.ts +8 -4
  31. package/core/src/providers/product-search.provider.ts +15 -28
  32. package/core/src/providers/product.provider.ts +6 -6
  33. package/core/src/providers/profile.provider.ts +8 -8
  34. package/core/src/providers/store.provider.ts +2 -2
  35. package/core/src/test/client-builder.spec.ts +81 -0
  36. package/examples/node/package.json +7 -7
  37. package/examples/node/src/basic/basic-node-provider-model-extension.spec.ts +10 -4
  38. package/examples/node/src/basic/basic-node-provider-query-extension.spec.ts +8 -2
  39. package/examples/node/src/basic/basic-node-setup.spec.ts +5 -1
  40. package/examples/node/src/basic/client-creation.spec.ts +3 -3
  41. package/examples/node/src/utils.ts +41 -41
  42. package/examples/node/tsconfig.lib.json +2 -1
  43. package/package.json +1 -1
  44. package/providers/algolia/src/core/initialize.ts +76 -21
  45. package/providers/algolia/src/core/initialize.types.ts +107 -0
  46. package/providers/algolia/src/factories/index.ts +1 -0
  47. package/providers/algolia/src/factories/product-search/product-search.factory.ts +182 -0
  48. package/providers/algolia/src/index.ts +2 -2
  49. package/providers/algolia/src/providers/analytics.provider.ts +4 -4
  50. package/providers/algolia/src/providers/product-search.provider.ts +67 -184
  51. package/providers/algolia/src/schema/capabilities.schema.ts +81 -7
  52. package/providers/algolia/src/test/analytics.spec.ts +9 -1
  53. package/providers/algolia/src/test/client-builder-product-search-extension.example.ts +85 -0
  54. package/providers/commercetools/src/core/capability-descriptors.ts +324 -0
  55. package/providers/commercetools/src/core/initialize.ts +35 -151
  56. package/providers/commercetools/src/core/initialize.types.ts +174 -0
  57. package/providers/commercetools/src/factories/cart/cart.factory.ts +142 -0
  58. package/providers/commercetools/src/factories/category/category.factory.ts +77 -0
  59. package/providers/commercetools/src/factories/checkout/checkout-initializer-overrides.example.ts +94 -0
  60. package/providers/commercetools/src/factories/checkout/checkout.factory.ts +338 -0
  61. package/providers/commercetools/src/factories/identity/identity.factory.ts +26 -0
  62. package/providers/commercetools/src/factories/inventory/inventory.factory.ts +49 -0
  63. package/providers/commercetools/src/factories/order/order.factory.ts +149 -0
  64. package/providers/commercetools/src/factories/order-search/order-search.factory.ts +108 -0
  65. package/providers/commercetools/src/factories/price/price.factory.ts +76 -0
  66. package/providers/commercetools/src/factories/product/product-factory-baseline.example.ts +14 -0
  67. package/providers/commercetools/src/factories/product/product-factory-schema-and-parse-extension.example.ts +35 -0
  68. package/providers/commercetools/src/factories/product/product-factory-schema-extension.example.ts +23 -0
  69. package/providers/commercetools/src/factories/product/product-initializer-factory-extension.example.ts +41 -0
  70. package/providers/commercetools/src/factories/product/product-provider-custom-method-only.example.ts +47 -0
  71. package/providers/commercetools/src/factories/product/product-provider-schema-signature-extension.example.ts +61 -0
  72. package/providers/commercetools/src/factories/product/product.factory.ts +220 -0
  73. package/providers/commercetools/src/factories/product/utils.example.ts +9 -0
  74. package/providers/commercetools/src/factories/product-associations/product-associations.factory.ts +103 -0
  75. package/providers/commercetools/src/factories/product-list/product-list.factory.ts +122 -0
  76. package/providers/commercetools/src/factories/product-reviews/product-reviews.factory.ts +81 -0
  77. package/providers/commercetools/src/factories/product-search/product-search.factory.ts +182 -0
  78. package/providers/commercetools/src/factories/profile/profile.factory.ts +94 -0
  79. package/providers/commercetools/src/factories/store/store.factory.ts +49 -0
  80. package/providers/commercetools/src/index.ts +15 -0
  81. package/providers/commercetools/src/providers/cart.provider.ts +67 -193
  82. package/providers/commercetools/src/providers/category.provider.ts +24 -64
  83. package/providers/commercetools/src/providers/checkout.provider.ts +50 -322
  84. package/providers/commercetools/src/providers/identity.provider.ts +35 -15
  85. package/providers/commercetools/src/providers/inventory.provider.ts +13 -31
  86. package/providers/commercetools/src/providers/order-search.provider.ts +16 -110
  87. package/providers/commercetools/src/providers/order.provider.ts +13 -144
  88. package/providers/commercetools/src/providers/price.provider.ts +37 -51
  89. package/providers/commercetools/src/providers/product-associations.provider.ts +39 -104
  90. package/providers/commercetools/src/providers/product-list.provider.ts +38 -23
  91. package/providers/commercetools/src/providers/product-reviews.provider.ts +34 -14
  92. package/providers/commercetools/src/providers/product-search.provider.ts +17 -170
  93. package/providers/commercetools/src/providers/product.provider.ts +20 -199
  94. package/providers/commercetools/src/providers/profile.provider.ts +27 -73
  95. package/providers/commercetools/src/providers/store.provider.ts +13 -31
  96. package/providers/commercetools/src/schema/capabilities.schema.ts +258 -20
  97. package/providers/commercetools/src/test/caching.spec.ts +18 -2
  98. package/providers/commercetools/src/test/client-builder-merge-extensions.example.ts +125 -0
  99. package/providers/fake/src/core/initialize.ts +213 -44
  100. package/providers/fake/src/core/initialize.types.ts +164 -0
  101. package/providers/fake/src/factories/cart/cart.factory.ts +34 -0
  102. package/providers/fake/src/factories/category/category.factory.ts +40 -0
  103. package/providers/fake/src/factories/checkout/checkout.factory.ts +53 -0
  104. package/providers/fake/src/factories/identity/identity.factory.ts +25 -0
  105. package/providers/fake/src/factories/index.ts +14 -0
  106. package/providers/fake/src/factories/inventory/inventory.factory.ts +25 -0
  107. package/providers/fake/src/factories/order/order.factory.ts +22 -0
  108. package/providers/fake/src/factories/order-search/order-search.factory.ts +27 -0
  109. package/providers/fake/src/factories/price/price.factory.ts +26 -0
  110. package/providers/fake/src/factories/product/product.factory.ts +22 -0
  111. package/providers/fake/src/factories/product-associations/product-associations.factory.ts +25 -0
  112. package/providers/fake/src/factories/product-reviews/product-reviews.factory.ts +53 -0
  113. package/providers/fake/src/factories/product-search/product-search.factory.ts +27 -0
  114. package/providers/fake/src/factories/profile/profile.factory.ts +22 -0
  115. package/providers/fake/src/factories/store/store.factory.ts +22 -0
  116. package/providers/fake/src/index.ts +2 -0
  117. package/providers/fake/src/providers/cart.provider.ts +23 -14
  118. package/providers/fake/src/providers/category.provider.ts +120 -105
  119. package/providers/fake/src/providers/checkout.provider.ts +39 -20
  120. package/providers/fake/src/providers/identity.provider.ts +40 -34
  121. package/providers/fake/src/providers/inventory.provider.ts +26 -24
  122. package/providers/fake/src/providers/order-search.provider.ts +38 -30
  123. package/providers/fake/src/providers/order.provider.ts +21 -37
  124. package/providers/fake/src/providers/price.provider.ts +42 -34
  125. package/providers/fake/src/providers/product-associations.provider.ts +23 -10
  126. package/providers/fake/src/providers/product-reviews.provider.ts +71 -69
  127. package/providers/fake/src/providers/product-search.provider.ts +43 -70
  128. package/providers/fake/src/providers/product.provider.ts +34 -32
  129. package/providers/fake/src/providers/profile.provider.ts +62 -55
  130. package/providers/fake/src/providers/store.provider.ts +38 -22
  131. package/providers/fake/src/schema/capabilities.schema.ts +175 -18
  132. package/providers/fake/src/test/cart.provider.spec.ts +20 -3
  133. package/providers/fake/src/test/category.provider.spec.ts +4 -1
  134. package/providers/fake/src/test/checkout.provider.spec.ts +12 -2
  135. package/providers/fake/src/test/client-builder-product-extension.example.ts +75 -0
  136. package/providers/fake/src/test/order-search.provider.spec.ts +4 -7
  137. package/providers/fake/src/test/order.provider.spec.ts +4 -6
  138. package/providers/fake/src/test/price.provider.spec.ts +3 -1
  139. package/providers/fake/src/test/product.provider.spec.ts +8 -2
  140. package/providers/fake/src/test/profile.provider.spec.ts +4 -2
  141. package/providers/google-analytics/src/core/initialize.ts +37 -12
  142. package/providers/google-analytics/src/core/initialize.types.ts +47 -0
  143. package/providers/google-analytics/src/index.ts +1 -0
  144. package/providers/google-analytics/src/schema/capabilities.schema.ts +31 -5
  145. package/providers/medusa/src/core/initialize.ts +324 -81
  146. package/providers/medusa/src/core/initialize.types.ts +184 -0
  147. package/providers/medusa/src/factories/cart/cart.factory.ts +34 -0
  148. package/providers/medusa/src/factories/category/category.factory.ts +37 -0
  149. package/providers/medusa/src/factories/checkout/checkout.factory.ts +50 -0
  150. package/providers/medusa/src/factories/identity/identity.factory.ts +22 -0
  151. package/providers/medusa/src/factories/index.ts +12 -0
  152. package/providers/medusa/src/factories/inventory/inventory.factory.ts +25 -0
  153. package/providers/medusa/src/factories/order/order.factory.ts +22 -0
  154. package/providers/medusa/src/factories/order-search/order-search.factory.ts +27 -0
  155. package/providers/medusa/src/factories/price/price.factory.ts +26 -0
  156. package/providers/medusa/src/factories/product/product.factory.ts +22 -0
  157. package/providers/medusa/src/factories/product-associations/product-associations.factory.ts +25 -0
  158. package/providers/medusa/src/factories/product-search/product-search.factory.ts +27 -0
  159. package/providers/medusa/src/factories/profile/profile.factory.ts +22 -0
  160. package/providers/medusa/src/index.ts +2 -0
  161. package/providers/medusa/src/providers/cart.provider.ts +33 -20
  162. package/providers/medusa/src/providers/category.provider.ts +30 -12
  163. package/providers/medusa/src/providers/checkout.provider.ts +42 -17
  164. package/providers/medusa/src/providers/identity.provider.ts +1 -1
  165. package/providers/medusa/src/providers/inventory.provider.ts +21 -7
  166. package/providers/medusa/src/providers/order-search.provider.ts +16 -5
  167. package/providers/medusa/src/providers/order.provider.ts +17 -5
  168. package/providers/medusa/src/providers/price.provider.ts +26 -7
  169. package/providers/medusa/src/providers/product-associations.provider.ts +19 -8
  170. package/providers/medusa/src/providers/product-search.provider.ts +19 -31
  171. package/providers/medusa/src/providers/product.provider.ts +47 -11
  172. package/providers/medusa/src/providers/profile.provider.ts +35 -11
  173. package/providers/medusa/src/schema/capabilities.schema.ts +229 -18
  174. package/providers/medusa/src/test/cart.provider.spec.ts +18 -2
  175. package/providers/medusa/src/test/category.provider.spec.ts +4 -1
  176. package/providers/medusa/src/test/checkout.spec.ts +9 -9
  177. package/providers/medusa/src/test/inventory.provider.spec.ts +3 -1
  178. package/providers/medusa/src/test/large-cart.provider.spec.ts +8 -2
  179. package/providers/medusa/src/test/price.provider.spec.ts +8 -1
  180. package/providers/medusa/src/test/product.provider.spec.ts +3 -1
  181. package/providers/medusa/src/test/search.provider.spec.ts +16 -3
  182. package/providers/meilisearch/src/core/initialize.ts +88 -21
  183. package/providers/meilisearch/src/core/initialize.types.ts +119 -0
  184. package/providers/meilisearch/src/factories/index.ts +2 -0
  185. package/providers/meilisearch/src/factories/order-search/order-search.factory.ts +27 -0
  186. package/providers/meilisearch/src/factories/product-search/product-search.factory.ts +27 -0
  187. package/providers/meilisearch/src/index.ts +2 -0
  188. package/providers/meilisearch/src/providers/index.ts +1 -0
  189. package/providers/meilisearch/src/providers/order-search.provider.ts +21 -6
  190. package/providers/meilisearch/src/providers/product-search.provider.ts +24 -8
  191. package/providers/meilisearch/src/schema/capabilities.schema.ts +95 -8
@@ -1,32 +1,37 @@
1
1
  import type {
2
- Inventory,
2
+ InventoryFactory,
3
+ InventoryFactoryOutput,
4
+ InventoryFactoryWithOutput,
3
5
  RequestContext,
4
6
  Cache,
5
7
  InventoryQueryBySKU,
6
- InventoryIdentifier,
7
- InventoryStatus,
8
8
  Result,
9
9
  NotFoundError,
10
10
  } from '@reactionary/core';
11
11
  import { InventoryProvider, InventoryQueryBySKUSchema, InventorySchema, Reactionary, success, error } from '@reactionary/core';
12
12
  import type { CommercetoolsConfiguration } from '../schema/configuration.schema.js';
13
- import type { InventoryEntry } from '@commercetools/platform-sdk';
14
13
  import type { CommercetoolsAPI } from '../core/client.js';
14
+ import type { CommercetoolsInventoryFactory } from '../factories/inventory/inventory.factory.js';
15
15
 
16
- export class CommercetoolsInventoryProvider extends InventoryProvider {
16
+ export class CommercetoolsInventoryProvider<
17
+ TFactory extends InventoryFactory = CommercetoolsInventoryFactory,
18
+ > extends InventoryProvider<InventoryFactoryOutput<TFactory>> {
17
19
  protected config: CommercetoolsConfiguration;
18
20
  protected commercetools: CommercetoolsAPI;
21
+ protected factory: InventoryFactoryWithOutput<TFactory>;
19
22
 
20
23
  constructor(
21
24
  config: CommercetoolsConfiguration,
22
25
  cache: Cache,
23
26
  context: RequestContext,
24
- commercetools: CommercetoolsAPI
27
+ commercetools: CommercetoolsAPI,
28
+ factory: InventoryFactoryWithOutput<TFactory>,
25
29
  ) {
26
30
  super(cache, context);
27
31
 
28
32
  this.config = config;
29
33
  this.commercetools = commercetools;
34
+ this.factory = factory;
30
35
  }
31
36
 
32
37
  protected async getClient() {
@@ -42,7 +47,7 @@ export class CommercetoolsInventoryProvider extends InventoryProvider {
42
47
  inputSchema: InventoryQueryBySKUSchema,
43
48
  outputSchema: InventorySchema,
44
49
  })
45
- public override async getBySKU(payload: InventoryQueryBySKU): Promise<Result<Inventory, NotFoundError>> {
50
+ public override async getBySKU(payload: InventoryQueryBySKU): Promise<Result<InventoryFactoryOutput<TFactory>, NotFoundError>> {
46
51
  const client = await this.getClient();
47
52
 
48
53
  try {
@@ -65,7 +70,7 @@ export class CommercetoolsInventoryProvider extends InventoryProvider {
65
70
 
66
71
  const result = remote.body.results[0];
67
72
 
68
- const model = this.parseSingle(result);
73
+ const model = this.factory.parseInventory(this.context, result);
69
74
 
70
75
 
71
76
  return success(model);
@@ -78,27 +83,4 @@ export class CommercetoolsInventoryProvider extends InventoryProvider {
78
83
  }
79
84
  }
80
85
 
81
- protected parseSingle(body: InventoryEntry): Inventory {
82
- const identifier = {
83
- variant: { sku: body.sku || '' },
84
- fulfillmentCenter: {
85
- key: body.supplyChannel?.obj?.key || '',
86
- },
87
- } satisfies InventoryIdentifier;
88
-
89
- const quantity = body.availableQuantity || 0;
90
- let status: InventoryStatus = 'outOfStock';
91
-
92
- if (quantity > 0) {
93
- status = 'inStock';
94
- }
95
-
96
- const result = {
97
- identifier,
98
- quantity,
99
- status,
100
- } satisfies Inventory;
101
-
102
- return result;
103
- }
104
86
  }
@@ -1,45 +1,46 @@
1
1
  import type {
2
2
  RequestContext,
3
3
  Cache,
4
+ OrderSearchFactory,
5
+ OrderSearchFactoryOutput,
6
+ OrderSearchFactoryWithOutput,
4
7
  OrderSearchQueryByTerm,
5
- OrderSearchResult,
6
8
  Result,
7
- OrderSearchIdentifier,
8
- MonetaryAmount,
9
- Currency,
10
- IdentityIdentifier,
11
- Address,
12
- OrderStatus,
13
9
  } from '@reactionary/core';
14
10
  import {
15
11
  OrderSearchProvider,
16
12
  OrderSearchQueryByTermSchema,
17
13
  OrderSearchResultSchema,
18
- type OrderSearchResultItem,
19
14
  Reactionary,
20
15
  success,
21
16
  } from '@reactionary/core';
22
17
  import type { CommercetoolsConfiguration } from '../schema/configuration.schema.js';
23
18
  import type { CommercetoolsAPI } from '../core/client.js';
24
19
  import createDebug from 'debug';
25
- import type { Order as CTOrder, OrderPagedSearchResponse , Address as CTAddress, OrderPagedQueryResponse} from '@commercetools/platform-sdk';
20
+ import type { OrderPagedQueryResponse } from '@commercetools/platform-sdk';
21
+ import type { CommercetoolsOrderSearchFactory } from '../factories/order-search/order-search.factory.js';
26
22
 
27
23
  const debug = createDebug('reactionary:commercetools:order-search');
28
24
 
29
- export class CommercetoolsOrderSearchProvider extends OrderSearchProvider {
25
+ export class CommercetoolsOrderSearchProvider<
26
+ TFactory extends OrderSearchFactory = CommercetoolsOrderSearchFactory,
27
+ > extends OrderSearchProvider<OrderSearchFactoryOutput<TFactory>> {
30
28
  protected config: CommercetoolsConfiguration;
31
29
  protected commercetools: CommercetoolsAPI;
30
+ protected factory: OrderSearchFactoryWithOutput<TFactory>;
32
31
 
33
32
  constructor(
34
33
  config: CommercetoolsConfiguration,
35
34
  cache: Cache,
36
35
  context: RequestContext,
37
- commercetools: CommercetoolsAPI
36
+ commercetools: CommercetoolsAPI,
37
+ factory: OrderSearchFactoryWithOutput<TFactory>,
38
38
  ) {
39
39
  super(cache, context);
40
40
 
41
41
  this.config = config;
42
42
  this.commercetools = commercetools;
43
+ this.factory = factory;
43
44
  }
44
45
 
45
46
  protected async getClient() {
@@ -54,7 +55,7 @@ export class CommercetoolsOrderSearchProvider extends OrderSearchProvider {
54
55
  inputSchema: OrderSearchQueryByTermSchema,
55
56
  outputSchema: OrderSearchResultSchema,
56
57
  })
57
- public async queryByTerm(payload: OrderSearchQueryByTerm): Promise<Result<OrderSearchResult>> {
58
+ public async queryByTerm(payload: OrderSearchQueryByTerm): Promise<Result<OrderSearchFactoryOutput<TFactory>>> {
58
59
  debug('queryByTerm', payload);
59
60
 
60
61
  const client = await this.getClient();
@@ -116,10 +117,11 @@ export class CommercetoolsOrderSearchProvider extends OrderSearchProvider {
116
117
  }).execute();
117
118
 
118
119
  const responseBody = response.body;
119
- const result = this.parsePaginatedResult(
120
+ const result = this.factory.parseOrderSearchResult(
121
+ this.context,
120
122
  responseBody,
121
123
  payload
122
- ) as OrderSearchResult;
124
+ );
123
125
 
124
126
  if (debug.enabled) {
125
127
  debug(
@@ -130,100 +132,4 @@ export class CommercetoolsOrderSearchProvider extends OrderSearchProvider {
130
132
  return success(result);
131
133
  }
132
134
 
133
- protected parseAddress(remote: CTAddress) {
134
- return {
135
- countryCode: remote.country || '',
136
- firstName: remote.firstName || '',
137
- lastName: remote.lastName || '',
138
- streetAddress: remote.streetName || '',
139
- streetNumber: remote.streetNumber || '',
140
- postalCode: remote.postalCode || '',
141
- city: remote.city || '',
142
- identifier: {
143
- nickName: '',
144
- },
145
- region: '',
146
- } satisfies Address;
147
- }
148
-
149
-
150
- protected parseSingle(body: CTOrder) {
151
- const identifier = { key: body.id };
152
- const userId: IdentityIdentifier = {
153
- userId: body.customerId || body.anonymousId || '',
154
- };
155
- const customerName = `${body.billingAddress?.firstName} ${body.billingAddress?.lastName}`;
156
- const shippingAddress = this.parseAddress(body.shippingAddress!);
157
- const orderDate = body.createdAt;
158
- let orderStatus: OrderStatus = 'AwaitingPayment';
159
- if (body.paymentState === 'Pending' && body.orderState === 'Open') {
160
- orderStatus = 'AwaitingPayment';
161
- } else if (
162
- body.paymentState === 'Paid' &&
163
- body.orderState === 'Confirmed'
164
- ) {
165
- orderStatus = 'ReleasedToFulfillment';
166
- }
167
- if (body.shipmentState === 'Ready' && body.orderState === 'Confirmed') {
168
- orderStatus = 'ReleasedToFulfillment';
169
- }
170
- if (
171
- (body.shipmentState === 'Shipped' ||
172
- body.shipmentState === 'Delivered') &&
173
- body.orderState === 'Completed'
174
- ) {
175
- orderStatus = 'Shipped';
176
- }
177
- let inventoryStatus: OrderSearchResultItem['inventoryStatus'];
178
-
179
- if (orderStatus === 'Shipped') {
180
- inventoryStatus = 'Allocated'
181
- } else {
182
- inventoryStatus = 'NotAllocated'
183
- }
184
-
185
- const totalAmount: MonetaryAmount = {
186
- currency: body.totalPrice ? body.totalPrice.currencyCode as Currency : this.context.languageContext.currencyCode,
187
- value: body.totalPrice ? body.totalPrice.centAmount / 100 : 0
188
- };
189
-
190
- const order = {
191
- identifier,
192
- userId,
193
- customerName,
194
- shippingAddress,
195
- orderDate,
196
- orderStatus,
197
- inventoryStatus,
198
- totalAmount
199
- } satisfies OrderSearchResultItem;
200
-
201
- return order;
202
- }
203
-
204
- protected parsePaginatedResult(
205
- body: OrderPagedQueryResponse,
206
- query: OrderSearchQueryByTerm
207
- ) {
208
- const identifier = {
209
- ...query.search,
210
- } satisfies OrderSearchIdentifier;
211
-
212
- const orders: OrderSearchResultItem[] = body.results.map((o) => {
213
- return this.parseSingle(o);
214
- })
215
-
216
- const result = {
217
- identifier,
218
- pageNumber: (Math.ceil(body.offset / body.limit) || 0) + 1,
219
- pageSize: body.limit,
220
- totalCount: body.total || 0,
221
- totalPages: Math.ceil((body.total || 0) / body.limit || 0) + 1,
222
- items: orders,
223
- } satisfies OrderSearchResult;
224
-
225
- return result;
226
- }
227
-
228
-
229
135
  }
@@ -1,39 +1,37 @@
1
1
  import type {
2
2
  RequestContext,
3
3
  Cache,
4
- Order,
4
+ OrderFactory,
5
+ OrderFactoryOutput,
6
+ OrderFactoryWithOutput,
5
7
  OrderQueryById,
6
- Currency,
7
- OrderIdentifier,
8
- CostBreakDown,
9
- OrderStatus,
10
- OrderItem,
11
- ProductVariantIdentifier,
12
- ItemCostBreakdown,
13
8
  Result,
14
9
  NotFoundError,
15
10
  } from '@reactionary/core';
16
11
  import { OrderProvider, OrderQueryByIdSchema, OrderSchema, Reactionary, success, error } from '@reactionary/core';
17
- import type * as z from 'zod';
18
12
  import type { CommercetoolsConfiguration } from '../schema/configuration.schema.js';
19
- import type { Order as CTOrder } from '@commercetools/platform-sdk';
20
- import { type CommercetoolsOrderIdentifier } from '../schema/commercetools.schema.js';
21
13
  import type { CommercetoolsAPI } from '../core/client.js';
14
+ import type { CommercetoolsOrderFactory } from '../factories/order/order.factory.js';
22
15
 
23
- export class CommercetoolsOrderProvider extends OrderProvider {
16
+ export class CommercetoolsOrderProvider<
17
+ TFactory extends OrderFactory = CommercetoolsOrderFactory,
18
+ > extends OrderProvider<OrderFactoryOutput<TFactory>> {
24
19
  protected config: CommercetoolsConfiguration;
25
20
  protected commercetools: CommercetoolsAPI;
21
+ protected factory: OrderFactoryWithOutput<TFactory>;
26
22
 
27
23
  constructor(
28
24
  config: CommercetoolsConfiguration,
29
25
  cache: Cache,
30
26
  context: RequestContext,
31
- commercetools: CommercetoolsAPI
27
+ commercetools: CommercetoolsAPI,
28
+ factory: OrderFactoryWithOutput<TFactory>,
32
29
  ) {
33
30
  super(cache, context);
34
31
 
35
32
  this.config = config;
36
33
  this.commercetools = commercetools;
34
+ this.factory = factory;
37
35
  }
38
36
 
39
37
  protected async getClient() {
@@ -48,7 +46,7 @@ export class CommercetoolsOrderProvider extends OrderProvider {
48
46
  inputSchema: OrderQueryByIdSchema,
49
47
  outputSchema: OrderSchema,
50
48
  })
51
- public override async getById(payload: OrderQueryById): Promise<Result<Order, NotFoundError>> {
49
+ public override async getById(payload: OrderQueryById): Promise<Result<OrderFactoryOutput<TFactory>, NotFoundError>> {
52
50
  const client = await this.getClient();
53
51
 
54
52
  try {
@@ -57,7 +55,7 @@ export class CommercetoolsOrderProvider extends OrderProvider {
57
55
  .get()
58
56
  .execute();
59
57
 
60
- return success(this.parseSingle(remote.body));
58
+ return success(this.factory.parseOrder(this.context, remote.body));
61
59
  } catch (e) {
62
60
  return error<NotFoundError>({
63
61
  type: 'NotFound',
@@ -66,133 +64,4 @@ export class CommercetoolsOrderProvider extends OrderProvider {
66
64
  }
67
65
  }
68
66
 
69
- protected parseSingle(_body: unknown): Order {
70
- const remote = _body as CTOrder;
71
-
72
- const identifier = {
73
- key: remote.id,
74
- version: remote.version || 0,
75
- } satisfies CommercetoolsOrderIdentifier;
76
-
77
- const name = remote.custom?.fields['name'] || '';
78
- const description = remote.custom?.fields['description'] || '';
79
-
80
- const grandTotal = remote.totalPrice.centAmount || 0;
81
- const shippingTotal = remote.shippingInfo?.price.centAmount || 0;
82
- const productTotal = grandTotal - shippingTotal;
83
- const taxTotal = remote.taxedPrice?.totalTax?.centAmount || 0;
84
- const discountTotal =
85
- remote.discountOnTotalPrice?.discountedAmount.centAmount || 0;
86
- const surchargeTotal = 0;
87
- const currency = remote.totalPrice.currencyCode as Currency;
88
-
89
- const price = {
90
- totalTax: {
91
- value: taxTotal / 100,
92
- currency,
93
- },
94
- totalDiscount: {
95
- value: discountTotal / 100,
96
- currency,
97
- },
98
- totalSurcharge: {
99
- value: surchargeTotal / 100,
100
- currency,
101
- },
102
- totalShipping: {
103
- value: shippingTotal / 100,
104
- currency: remote.shippingInfo?.price.currencyCode as Currency,
105
- },
106
- totalProductPrice: {
107
- value: productTotal / 100,
108
- currency,
109
- },
110
- grandTotal: {
111
- value: grandTotal / 100,
112
- currency,
113
- },
114
- } satisfies CostBreakDown;
115
-
116
- let orderStatus: OrderStatus = 'AwaitingPayment';
117
- if (remote.paymentState === 'Pending' && remote.orderState === 'Open') {
118
- orderStatus = 'AwaitingPayment';
119
- } else if (
120
- remote.paymentState === 'Paid' &&
121
- remote.orderState === 'Confirmed'
122
- ) {
123
- orderStatus = 'ReleasedToFulfillment';
124
- }
125
- if (remote.shipmentState === 'Ready' && remote.orderState === 'Confirmed') {
126
- orderStatus = 'ReleasedToFulfillment';
127
- }
128
- if (
129
- (remote.shipmentState === 'Shipped' ||
130
- remote.shipmentState === 'Delivered') &&
131
- remote.orderState === 'Completed'
132
- ) {
133
- orderStatus = 'Shipped';
134
- }
135
-
136
- const items = new Array<OrderItem>();
137
- for (const remoteItem of remote.lineItems) {
138
- const identifier = {
139
- key: remoteItem.id
140
- } satisfies OrderIdentifier;
141
-
142
- const variant = {
143
- sku: remoteItem.variant.sku || ''
144
- } satisfies ProductVariantIdentifier;
145
- const quantity = remoteItem.quantity;
146
-
147
- const unitPrice = remoteItem.price.value.centAmount;
148
- const totalPrice = remoteItem.totalPrice.centAmount || 0;
149
- const totalDiscount = remoteItem.price.discounted?.value.centAmount || 0;
150
- const unitDiscount = totalDiscount / remoteItem.quantity;
151
-
152
- const price = {
153
- unitPrice: {
154
- value: unitPrice / 100,
155
- currency,
156
- },
157
- unitDiscount: {
158
- value: unitDiscount / 100,
159
- currency,
160
- },
161
- totalPrice: {
162
- value: (totalPrice || 0) / 100,
163
- currency,
164
- },
165
- totalDiscount: {
166
- value: totalDiscount / 100,
167
- currency,
168
- },
169
- } satisfies ItemCostBreakdown;
170
-
171
- const item = {
172
- identifier,
173
- inventoryStatus: 'NotAllocated',
174
- price,
175
- quantity,
176
- variant
177
- } satisfies OrderItem;
178
-
179
- items.push(item);
180
- }
181
-
182
- const result = {
183
- identifier,
184
- name,
185
- description,
186
- price,
187
- items,
188
- inventoryStatus: 'NotAllocated',
189
- paymentInstructions: [],
190
- userId: {
191
- userId: ''
192
- },
193
- orderStatus
194
- } satisfies Order;
195
-
196
- return result;
197
- }
198
67
  }
@@ -2,42 +2,46 @@ import {
2
2
  CustomerPriceQuerySchema,
3
3
  ListPriceQuerySchema,
4
4
  PriceProvider,
5
+ type PriceFactory,
6
+ type PriceFactoryOutput,
7
+ type PriceFactoryWithOutput,
5
8
  PriceSchema,
6
9
  Reactionary,
7
10
  success,
8
11
  } from '@reactionary/core';
9
12
  import type {
10
13
  RequestContext,
11
- Price,
12
14
  Cache,
13
- Currency,
14
15
  CustomerPriceQuery,
15
16
  ListPriceQuery,
16
- PriceIdentifier,
17
- MonetaryAmount,
18
17
  Result,
19
18
  } from '@reactionary/core';
20
19
  import type { CommercetoolsConfiguration } from '../schema/configuration.schema.js';
21
20
  import type {
22
- Price as CTPrice,
23
21
  ProductVariant as CTProductVariant,
24
22
  } from '@commercetools/platform-sdk';
25
23
  import type { CommercetoolsAPI } from '../core/client.js';
24
+ import type { CommercetoolsPriceFactory } from '../factories/price/price.factory.js';
26
25
 
27
- export class CommercetoolsPriceProvider extends PriceProvider {
26
+ export class CommercetoolsPriceProvider<
27
+ TFactory extends PriceFactory = CommercetoolsPriceFactory,
28
+ > extends PriceProvider<PriceFactoryOutput<TFactory>> {
28
29
  protected config: CommercetoolsConfiguration;
29
30
  protected commercetools: CommercetoolsAPI;
31
+ protected factory: PriceFactoryWithOutput<TFactory>;
30
32
 
31
33
  constructor(
32
34
  config: CommercetoolsConfiguration,
33
35
  cache: Cache,
34
36
  context: RequestContext,
35
- commercetools: CommercetoolsAPI
37
+ commercetools: CommercetoolsAPI,
38
+ factory: PriceFactoryWithOutput<TFactory>,
36
39
  ) {
37
40
  super(cache, context);
38
41
 
39
42
  this.config = config;
40
43
  this.commercetools = commercetools;
44
+ this.factory = factory;
41
45
  }
42
46
 
43
47
  @Reactionary({
@@ -46,7 +50,7 @@ export class CommercetoolsPriceProvider extends PriceProvider {
46
50
  })
47
51
  public override async getCustomerPrice(
48
52
  payload: CustomerPriceQuery
49
- ): Promise<Result<Price>> {
53
+ ): Promise<Result<PriceFactoryOutput<TFactory>>> {
50
54
  const client = await this.getClient();
51
55
  let priceChannelId;
52
56
  if (this.config.customerPriceChannelKey) {
@@ -76,14 +80,14 @@ export class CommercetoolsPriceProvider extends PriceProvider {
76
80
  (x) => x.sku === payload.variant.sku
77
81
  );
78
82
 
79
- return success(this.parseSingle(sku, { includeDiscounts: true }));
83
+ return success(this.factory.parsePrice(this.context, sku, { includeDiscounts: true }));
80
84
  }
81
85
 
82
86
  @Reactionary({
83
87
  inputSchema: ListPriceQuerySchema,
84
88
  outputSchema: PriceSchema,
85
89
  })
86
- public override async getListPrice(payload: ListPriceQuery): Promise<Result<Price>> {
90
+ public override async getListPrice(payload: ListPriceQuery): Promise<Result<PriceFactoryOutput<TFactory>>> {
87
91
  const client = await this.getClient();
88
92
  let priceChannelId;
89
93
  if (this.config.listPriceChannelKey) {
@@ -112,7 +116,7 @@ export class CommercetoolsPriceProvider extends PriceProvider {
112
116
  (x) => x.sku === payload.variant.sku
113
117
  );
114
118
 
115
- return success(this.parseSingle(sku));
119
+ return success(this.factory.parsePrice(this.context, sku));
116
120
  }
117
121
 
118
122
  protected async getClient() {
@@ -120,48 +124,30 @@ export class CommercetoolsPriceProvider extends PriceProvider {
120
124
  return client.withProjectKey({ projectKey: this.config.projectKey });
121
125
  }
122
126
 
123
- protected parseSingle(
124
- _body: unknown,
125
- options = { includeDiscounts: false }
126
- ): Price {
127
- const body = _body as CTProductVariant;
128
- const price = body.price as CTPrice | undefined;
127
+ protected async getChannels() {
128
+ const adminClient = await this.commercetools.getAdminClient();
129
129
 
130
- if (!price) {
131
- return this.createEmptyPriceResult(body.sku!);
132
- }
133
-
134
- let unitPrice = {
135
- value: price.value.centAmount / 100,
136
- currency: price.value.currencyCode as Currency,
137
- } satisfies MonetaryAmount;
138
-
139
- let isOnSale = false;
140
- if (options.includeDiscounts) {
141
- const discountedPrice = price.discounted?.value || price.value;
142
- if (price.discounted) {
143
- isOnSale = true;
144
- }
145
- unitPrice = {
146
- value: discountedPrice.centAmount / 100,
147
- currency: price.value.currencyCode as Currency,
148
- } satisfies MonetaryAmount;
149
- }
150
-
151
- const identifier = {
152
- variant: {
153
- sku: body.sku!,
154
- },
155
- } satisfies PriceIdentifier;
130
+ const offerPriceChannelPromise = adminClient
131
+ .withProjectKey({ projectKey: this.config.projectKey })
132
+ .channels()
133
+ .withKey({ key: 'Offer Price' })
134
+ .get()
135
+ .execute();
136
+ const listPriceChannelPromise = adminClient
137
+ .withProjectKey({ projectKey: this.config.projectKey })
138
+ .channels()
139
+ .withKey({ key: 'List Price' })
140
+ .get()
141
+ .execute();
156
142
 
157
- const result = {
158
- identifier,
159
- tieredPrices: [],
160
- unitPrice,
161
- onSale: isOnSale,
162
- } satisfies Price;
143
+ const [offerChannel, listChannel] = await Promise.all([
144
+ offerPriceChannelPromise,
145
+ listPriceChannelPromise,
146
+ ]);
163
147
 
164
- return result;
148
+ return {
149
+ offer: offerChannel.body.id,
150
+ list: listChannel.body.id,
151
+ };
165
152
  }
166
-
167
153
  }