@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,15 +1,21 @@
1
- import type { Category, FacetIdentifier, FacetValueIdentifier, Result } from '../index.js';
2
- import type { ProductSearchResult, ProductSearchResultFacet, ProductSearchResultFacetValue, ProductSearchResultItemVariant } from '../schemas/models/product-search.model.js';
3
- import type { ProductSearchQueryByTerm, ProductSearchQueryCreateNavigationFilter } from '../schemas/queries/product-search.query.js';
1
+ import type { Category, FacetValueIdentifier, Result } from '../index.js';
2
+ import type { ProductSearchResult } from '../schemas/models/product-search.model.js';
3
+ import type {
4
+ ProductSearchQueryByTerm,
5
+ ProductSearchQueryCreateNavigationFilter,
6
+ } from '../schemas/queries/product-search.query.js';
4
7
  import { BaseProvider } from './base.provider.js';
5
8
 
6
- export abstract class ProductSearchProvider extends BaseProvider {
9
+ export abstract class ProductSearchProvider<
10
+ TProductSearchResult extends ProductSearchResult = ProductSearchResult,
11
+ > extends BaseProvider {
7
12
  protected override getResourceName(): string {
8
13
  return 'product-search';
9
14
  }
10
15
 
11
- public abstract queryByTerm(payload: ProductSearchQueryByTerm): Promise<Result<ProductSearchResult>>;
12
-
16
+ public abstract queryByTerm(
17
+ payload: ProductSearchQueryByTerm,
18
+ ): Promise<Result<TProductSearchResult>>;
13
19
 
14
20
  /**
15
21
  * Since each platform has it own way of representing categories and their hierarchy, we leave it to the platform to tell us how to get from a
@@ -29,7 +35,9 @@ public abstract queryByTerm(payload: ProductSearchQueryByTerm): Promise<Result<P
29
35
  *
30
36
  * @param categoryPath
31
37
  */
32
- public abstract createCategoryNavigationFilter(payload: ProductSearchQueryCreateNavigationFilter): Promise<Result<FacetValueIdentifier>>;
38
+ public abstract createCategoryNavigationFilter(
39
+ payload: ProductSearchQueryCreateNavigationFilter,
40
+ ): Promise<Result<FacetValueIdentifier>>;
33
41
 
34
42
  /**
35
43
  * Parses a facet value from the search response.
@@ -37,25 +45,4 @@ public abstract queryByTerm(payload: ProductSearchQueryByTerm): Promise<Result<P
37
45
  * @param label The label for the facet value.
38
46
  * @param count The count for the facet value.
39
47
  */
40
- protected abstract parseFacetValue(facetValueIdentifier: FacetValueIdentifier, label: string, count: number) : ProductSearchResultFacetValue;
41
-
42
- /**
43
- * Parses a facet from the search response.
44
- * @param facetIdentifier The identifier for the facet.
45
- * @param facetValue The value for the facet.
46
- *
47
- * Usecase: Override this to customize the parsing of facets.
48
- */
49
- protected abstract parseFacet(facetIdentifier: FacetIdentifier, facetValue: unknown) : ProductSearchResultFacet;
50
-
51
- /**
52
- * Parses a product variant from the search response.
53
- * @param variant The variant data from the search response.
54
- * @param product The product data from the search response.
55
- *
56
- * Usecase: Override this to customize the parsing of product variants.
57
- */
58
- protected abstract parseVariant(variant: unknown, product: unknown): ProductSearchResultItemVariant;
59
48
  }
60
-
61
-
@@ -4,7 +4,7 @@ import type { ProductQueryById, ProductQueryBySKU, ProductQueryBySlug } from '..
4
4
  import type { Result } from '../schemas/result.js';
5
5
  import type { NotFoundError } from '../schemas/index.js';
6
6
 
7
- export abstract class ProductProvider extends BaseProvider {
7
+ export abstract class ProductProvider<TProduct extends Product = Product> extends BaseProvider {
8
8
 
9
9
 
10
10
  /**
@@ -17,7 +17,7 @@ export abstract class ProductProvider extends BaseProvider {
17
17
  * Marketing will TYPICALLY recommend products, and in some cases maybe HeroVariants of a product.
18
18
  * In that case, you would need to resolve the product to its hero variant first, and then get the SKU from there.
19
19
  */
20
- public abstract getById(payload: ProductQueryById): Promise<Result<Product>>;
20
+ public abstract getById(payload: ProductQueryById): Promise<Result<TProduct>>;
21
21
 
22
22
 
23
23
  /**
@@ -27,7 +27,7 @@ export abstract class ProductProvider extends BaseProvider {
27
27
  *
28
28
  * Usecase: You are rendering a product detail page, and you need to fetch the product by its slug.
29
29
  */
30
- public abstract getBySlug(payload: ProductQueryBySlug): Promise<Result<Product, NotFoundError>>;
30
+ public abstract getBySlug(payload: ProductQueryBySlug): Promise<Result<TProduct, NotFoundError>>;
31
31
 
32
32
 
33
33
  /**
@@ -39,9 +39,9 @@ export abstract class ProductProvider extends BaseProvider {
39
39
  * and you need to fetch the product details for that SKU. You will get the a Product back, with the variant matching the SKU set as heroSku.
40
40
  * It might also be used on a quick-order page, or product recommendations from external system.
41
41
  */
42
- public abstract getBySKU(payload: ProductQueryBySKU): Promise<Result<Product>>;
42
+ public abstract getBySKU(payload: ProductQueryBySKU): Promise<Result<TProduct>>;
43
43
 
44
- protected createEmptyProduct(id: string): Product {
44
+ protected createEmptyProduct(id: string): TProduct {
45
45
  // FIXME: We can probably get rid of this once we switch to errors as values, as we shouldn't even
46
46
  // be materializing an empty product...
47
47
  const product = {
@@ -73,7 +73,7 @@ export abstract class ProductProvider extends BaseProvider {
73
73
  variants: [],
74
74
  } satisfies Product;
75
75
 
76
- return product;
76
+ return product as unknown as TProduct;
77
77
  }
78
78
 
79
79
  /**
@@ -5,7 +5,7 @@ import type { ProfileQuerySelf as ProfileQueryById } from '../schemas/queries/in
5
5
  import type { Result } from '../schemas/result.js';
6
6
  import { BaseProvider } from './base.provider.js';
7
7
 
8
- export abstract class ProfileProvider extends BaseProvider {
8
+ export abstract class ProfileProvider<TProfile extends Profile = Profile> extends BaseProvider {
9
9
 
10
10
  /**
11
11
  * Returns the profile of the currently authenticated (registered) user.
@@ -13,7 +13,7 @@ export abstract class ProfileProvider extends BaseProvider {
13
13
  * Usecase: Fetch the profile of the logged-in user for display in header, or account settings.
14
14
  * @param payload
15
15
  */
16
- public abstract getById(payload: ProfileQueryById): Promise<Result<Profile, NotFoundError>>;
16
+ public abstract getById(payload: ProfileQueryById): Promise<Result<TProfile, NotFoundError>>;
17
17
 
18
18
  /**
19
19
  * Updates the base profile information of the currently authenticated (registered) user.
@@ -26,7 +26,7 @@ export abstract class ProfileProvider extends BaseProvider {
26
26
  * Usecase: Update the user's name, email, or phone number.
27
27
  * @param payload
28
28
  */
29
- public abstract update(payload: ProfileMutationUpdate): Promise<Result<Profile, NotFoundError>>;
29
+ public abstract update(payload: ProfileMutationUpdate): Promise<Result<TProfile, NotFoundError>>;
30
30
 
31
31
  /**
32
32
  * Creates a new shipping address for the currently authenticated (registered) user.
@@ -36,7 +36,7 @@ export abstract class ProfileProvider extends BaseProvider {
36
36
  * done at checkout should be considered local to that session, unless the addressbook is empty.
37
37
  * @param payload
38
38
  */
39
- public abstract addShippingAddress(payload: ProfileMutationAddShippingAddress): Promise<Result<Profile, NotFoundError>>;
39
+ public abstract addShippingAddress(payload: ProfileMutationAddShippingAddress): Promise<Result<TProfile, NotFoundError>>;
40
40
 
41
41
  /**
42
42
  * Updates an existing shipping address for the currently authenticated (registered) user.
@@ -45,7 +45,7 @@ export abstract class ProfileProvider extends BaseProvider {
45
45
  * done at checkout should be considered local to that session/order, unless the addressbook is empty.
46
46
  * @param payload
47
47
  */
48
- public abstract updateShippingAddress(payload: ProfileMutationUpdateShippingAddress): Promise<Result<Profile, NotFoundError>>;
48
+ public abstract updateShippingAddress(payload: ProfileMutationUpdateShippingAddress): Promise<Result<TProfile, NotFoundError>>;
49
49
 
50
50
  /**
51
51
  * Removes an existing shipping address for the currently authenticated (registered) user.
@@ -55,7 +55,7 @@ export abstract class ProfileProvider extends BaseProvider {
55
55
  * Usecase: User deletes a shipping address from their profile.
56
56
  * @param payload
57
57
  */
58
- public abstract removeShippingAddress(payload: ProfileMutationRemoveShippingAddress): Promise<Result<Profile, NotFoundError>>;
58
+ public abstract removeShippingAddress(payload: ProfileMutationRemoveShippingAddress): Promise<Result<TProfile, NotFoundError>>;
59
59
 
60
60
  /**
61
61
  * Configures an existing shipping address as the default shipping address for the currently authenticated (registered) user.
@@ -63,7 +63,7 @@ export abstract class ProfileProvider extends BaseProvider {
63
63
  * Usecase: User selects a default shipping address in their profile.
64
64
  * @param payload
65
65
  */
66
- public abstract makeShippingAddressDefault(payload: ProfileMutationMakeShippingAddressDefault): Promise<Result<Profile, NotFoundError>>;
66
+ public abstract makeShippingAddressDefault(payload: ProfileMutationMakeShippingAddressDefault): Promise<Result<TProfile, NotFoundError>>;
67
67
 
68
68
  /**
69
69
  * Sets the current/active billing address for the currently authenticated (registered) user.
@@ -74,7 +74,7 @@ export abstract class ProfileProvider extends BaseProvider {
74
74
  * entity being billed, and as such it makes sense to have a single authoritative billing address.
75
75
  * @param payload
76
76
  */
77
- public abstract setBillingAddress(payload: ProfileMutationSetBillingAddress): Promise<Result<Profile, NotFoundError>>;
77
+ public abstract setBillingAddress(payload: ProfileMutationSetBillingAddress): Promise<Result<TProfile, NotFoundError>>;
78
78
 
79
79
  protected override getResourceName(): string {
80
80
  return 'profile';
@@ -3,8 +3,8 @@ import type { StoreQueryByProximity } from '../schemas/queries/index.js';
3
3
  import type { Result } from '../schemas/result.js';
4
4
  import { BaseProvider } from './base.provider.js';
5
5
 
6
- export abstract class StoreProvider extends BaseProvider {
7
- public abstract queryByProximity(payload: StoreQueryByProximity): Promise<Result<Array<Store>>>;
6
+ export abstract class StoreProvider<TStore extends Store = Store> extends BaseProvider {
7
+ public abstract queryByProximity(payload: StoreQueryByProximity): Promise<Result<Array<TStore>>>;
8
8
 
9
9
  protected override getResourceName(): string {
10
10
  return 'store';
@@ -8,6 +8,7 @@ import { NoOpCache } from "../cache/noop-cache.js";
8
8
  import { createInitialRequestContext } from "../initialization.js";
9
9
  import { ClientBuilder } from "../client/client-builder.js";
10
10
  import type { Client } from "../client/client.js";
11
+ import { ProductProvider } from "../providers/product.provider.js";
11
12
 
12
13
  export class MockAnalyticsProvider extends AnalyticsProvider {
13
14
  public events: Array<AnalyticsMutation> = [];
@@ -57,4 +58,84 @@ describe('Client Builder', () => {
57
58
  expect(secondaryAnalyticsProvider.events.length).toBe(1);
58
59
  expect(secondaryAnalyticsProvider.events[0].event).toBe('product-details-view');
59
60
  });
61
+
62
+ it('supports capability factories with args object signature', () => {
63
+ const cache = new NoOpCache();
64
+ const context = createInitialRequestContext();
65
+ const builder = new ClientBuilder(context);
66
+ const analyticsProvider = new MockAnalyticsProvider(cache, context);
67
+
68
+ const client = builder
69
+ .withCache(cache)
70
+ .withCapability(({ cache: sharedCache, context: sharedContext }) => {
71
+ expect(sharedCache).toBe(cache);
72
+ expect(sharedContext).toBe(context);
73
+ return { analytics: analyticsProvider };
74
+ })
75
+ .build();
76
+
77
+ expect(client.analytics).toBeDefined();
78
+ });
79
+
80
+ it('supports throw collision strategy', () => {
81
+ const cache = new NoOpCache();
82
+ const context = createInitialRequestContext();
83
+ const builder = new ClientBuilder(context);
84
+
85
+ class TestProductProvider extends ProductProvider {
86
+ public override async getById(): Promise<any> {
87
+ throw new Error('not implemented');
88
+ }
89
+ public override async getBySlug(): Promise<any> {
90
+ throw new Error('not implemented');
91
+ }
92
+ public override async getBySKU(): Promise<any> {
93
+ throw new Error('not implemented');
94
+ }
95
+ }
96
+
97
+ expect(() =>
98
+ builder
99
+ .withCache(cache)
100
+ .withCollisionStrategy('throw')
101
+ .withCapability(() => ({ product: new TestProductProvider(cache, context) }))
102
+ .withCapability(() => ({ product: new TestProductProvider(cache, context) }))
103
+ .build(),
104
+ ).toThrow(/Capability collision detected for "product"/);
105
+ });
106
+
107
+ it('supports first-wins collision strategy', () => {
108
+ const cache = new NoOpCache();
109
+ const context = createInitialRequestContext();
110
+ const builder = new ClientBuilder(context);
111
+
112
+ class TestProductProvider extends ProductProvider {
113
+ public name: string;
114
+ constructor(cache: Cache, context: RequestContext, name: string) {
115
+ super(cache, context);
116
+ this.name = name;
117
+ }
118
+ public override async getById(): Promise<any> {
119
+ throw new Error('not implemented');
120
+ }
121
+ public override async getBySlug(): Promise<any> {
122
+ throw new Error('not implemented');
123
+ }
124
+ public override async getBySKU(): Promise<any> {
125
+ throw new Error('not implemented');
126
+ }
127
+ }
128
+
129
+ const first = new TestProductProvider(cache, context, 'first');
130
+ const second = new TestProductProvider(cache, context, 'second');
131
+
132
+ const client = builder
133
+ .withCache(cache)
134
+ .withCollisionStrategy('first-wins')
135
+ .withCapability(() => ({ product: first }))
136
+ .withCapability(() => ({ product: second }))
137
+ .build();
138
+
139
+ expect((client.product as TestProductProvider).name).toBe('first');
140
+ });
60
141
  });
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "@reactionary/examples-node",
3
- "version": "0.3.18",
3
+ "version": "0.6.2",
4
4
  "main": "index.js",
5
5
  "types": "src/index.d.ts",
6
6
  "dependencies": {
7
- "@reactionary/core": "0.3.18",
8
- "@reactionary/provider-commercetools": "0.3.18",
9
- "@reactionary/provider-algolia": "0.3.18",
10
- "@reactionary/provider-medusa": "0.3.18",
11
- "@reactionary/provider-meilisearch": "0.3.18",
12
- "@reactionary/provider-fake": "0.3.18"
7
+ "@reactionary/core": "0.6.2",
8
+ "@reactionary/provider-commercetools": "0.6.2",
9
+ "@reactionary/provider-algolia": "0.6.2",
10
+ "@reactionary/provider-medusa": "0.6.2",
11
+ "@reactionary/provider-meilisearch": "0.6.2",
12
+ "@reactionary/provider-fake": "0.6.2"
13
13
  },
14
14
  "type": "module"
15
15
  }
@@ -7,6 +7,7 @@ import {
7
7
  ProductSchema
8
8
  } from '@reactionary/core';
9
9
  import {
10
+ FakeProductFactory,
10
11
  FakeProductProvider,
11
12
  withFakeCapabilities,
12
13
  } from '@reactionary/provider-fake';
@@ -23,9 +24,9 @@ describe('basic node provider extension (models)', () => {
23
24
  type ExtendedProduct = z.infer<typeof ExtendedProductModel>;
24
25
 
25
26
  class ExtendedProductProvider extends FakeProductProvider {
26
- protected override parseSingle(body: string): ExtendedProduct {
27
+ protected override composeSingle(body: string): ExtendedProduct {
27
28
  const result = {
28
- ...super.parseSingle(body),
29
+ ...super.composeSingle(body),
29
30
  gtin: 'gtin-1234'
30
31
  } satisfies ExtendedProduct;
31
32
 
@@ -44,7 +45,8 @@ describe('basic node provider extension (models)', () => {
44
45
  search: 1
45
46
  } },
46
47
  cache,
47
- context
48
+ context,
49
+ new FakeProductFactory(ExtendedProductModel)
48
50
  ),
49
51
  };
50
52
 
@@ -66,7 +68,11 @@ describe('basic node provider extension (models)', () => {
66
68
  search: 1
67
69
  }
68
70
  },
69
- { productSearch: true, product: false, identity: false }
71
+ {
72
+ productSearch: { enabled: true },
73
+ product: { enabled: false },
74
+ identity: { enabled: false },
75
+ }
70
76
  )
71
77
  )
72
78
  .withCapability(withExtendedCapabilities())
@@ -9,6 +9,7 @@ import {
9
9
  ProductSchema
10
10
  } from '@reactionary/core';
11
11
  import {
12
+ FakeProductFactory,
12
13
  FakeProductProvider,
13
14
  withFakeCapabilities,
14
15
  } from '@reactionary/provider-fake';
@@ -60,7 +61,8 @@ describe('basic node provider extension (models)', () => {
60
61
  search: 1
61
62
  }},
62
63
  cache,
63
- context
64
+ context,
65
+ new FakeProductFactory(ProductSchema)
64
66
  ),
65
67
  };
66
68
 
@@ -83,7 +85,11 @@ describe('basic node provider extension (models)', () => {
83
85
  search: 1
84
86
  }
85
87
  },
86
- { productSearch: true, product: false, identity: false }
88
+ {
89
+ productSearch: { enabled: true },
90
+ product: { enabled: false },
91
+ identity: { enabled: false },
92
+ }
87
93
  )
88
94
  )
89
95
  .withCapability(withExtendedCapabilities())
@@ -29,7 +29,11 @@ describe('basic node setup', () => {
29
29
  search: 1,
30
30
  },
31
31
  },
32
- { productSearch: true, product: true, identity: false }
32
+ {
33
+ productSearch: { enabled: true },
34
+ product: { enabled: true },
35
+ identity: { enabled: false },
36
+ }
33
37
  )
34
38
  )
35
39
  .withCache(new NoOpCache())
@@ -21,7 +21,7 @@ describe('client creation', () => {
21
21
  search: 1,
22
22
  },
23
23
  },
24
- { product: true }
24
+ { product: { enabled: true } }
25
25
  )
26
26
  )
27
27
  .withCapability(
@@ -34,14 +34,14 @@ describe('client creation', () => {
34
34
  projectKey: '',
35
35
  scopes: [],
36
36
  facetFieldsForSearch: []
37
- }, { cart: true })
37
+ }, { cart: { enabled: true } })
38
38
  )
39
39
  .withCapability(
40
40
  withAlgoliaCapabilities({
41
41
  apiKey: '',
42
42
  appId: '',
43
43
  indexName: ''
44
- }, { productSearch: true })
44
+ }, { productSearch: { enabled: true } })
45
45
  )
46
46
  .withCache(new NoOpCache())
47
47
  .build();
@@ -99,20 +99,20 @@ export function createClient(provider: PrimaryProvider) {
99
99
  if (provider === PrimaryProvider.MEDUSA) {
100
100
  builder = builder.withCapability(
101
101
  withMedusaCapabilities( getMedusaTestConfiguration(), {
102
- cart: true,
103
- product: true,
104
- category: true,
105
- checkout: true,
106
- identity: true,
107
- inventory: true,
108
- order: true,
109
- price: true,
110
- productSearch: true,
111
- productRecommendations: true,
112
- productAssociations: true,
113
- orderSearch: true,
114
- store: true,
115
- profile: true,
102
+ cart: { enabled: true },
103
+ product: { enabled: true },
104
+ category: { enabled: true },
105
+ checkout: { enabled: true },
106
+ identity: { enabled: true },
107
+ inventory: { enabled: true },
108
+ order: { enabled: true },
109
+ price: { enabled: true },
110
+ productSearch: { enabled: true },
111
+ productRecommendations: { enabled: true },
112
+ productAssociations: { enabled: true },
113
+ orderSearch: { enabled: true },
114
+ store: { enabled: true },
115
+ profile: { enabled: true },
116
116
  })
117
117
  );
118
118
  }
@@ -120,11 +120,11 @@ export function createClient(provider: PrimaryProvider) {
120
120
  if (provider === PrimaryProvider.FAKE) {
121
121
  builder = builder.withCapability(
122
122
  withFakeCapabilities( getFakeConfiguration() , {
123
- price: true,
124
- inventory: true,
125
- product: true,
126
- productReviews: true,
127
- productAssociations: true,
123
+ price: { enabled: true },
124
+ inventory: { enabled: true },
125
+ product: { enabled: true },
126
+ productReviews: { enabled: true },
127
+ productAssociations: { enabled: true },
128
128
  }
129
129
  ))
130
130
  }
@@ -132,21 +132,21 @@ export function createClient(provider: PrimaryProvider) {
132
132
  if (provider === PrimaryProvider.COMMERCETOOLS) {
133
133
  builder = builder.withCapability(
134
134
  withCommercetoolsCapabilities(getCommercetoolsTestConfiguration(), {
135
- cart: true,
136
- product: true,
137
- category: true,
138
- checkout: true,
139
- identity: true,
140
- inventory: true,
141
- order: true,
142
- price: true,
143
- productSearch: true,
144
- productAssociations: true,
145
- productReviews: true,
146
- productList: true,
147
- orderSearch: true,
148
- store: true,
149
- profile: true,
135
+ cart: { enabled: true },
136
+ product: { enabled: true },
137
+ category: { enabled: true },
138
+ checkout: { enabled: true },
139
+ identity: { enabled: true },
140
+ inventory: { enabled: true },
141
+ order: { enabled: true },
142
+ price: { enabled: true },
143
+ productSearch: { enabled: true },
144
+ productAssociations: { enabled: true },
145
+ productReviews: { enabled: true },
146
+ productList: { enabled: true },
147
+ orderSearch: { enabled: true },
148
+ store: { enabled: true },
149
+ profile: { enabled: true },
150
150
  })
151
151
  );
152
152
  }
@@ -155,8 +155,8 @@ export function createClient(provider: PrimaryProvider) {
155
155
  if (provider === PrimaryProvider.ALGOLIA) {
156
156
  builder = builder.withCapability(
157
157
  withAlgoliaCapabilities(getAlgoliaTestConfiguration(), {
158
- productSearch: true,
159
- productRecommendations: true,
158
+ productSearch: { enabled: true },
159
+ productRecommendations: { enabled: true },
160
160
  })
161
161
  );
162
162
  }
@@ -164,15 +164,15 @@ export function createClient(provider: PrimaryProvider) {
164
164
  if (provider === PrimaryProvider.MEILISEARCH) {
165
165
  builder = builder.withCapability(
166
166
  withMeilisearchCapabilities(getMeilisearchTestConfiguration(), {
167
- productSearch: true,
168
- orderSearch: true,
169
- productRecommendations: true,
167
+ productSearch: { enabled: true },
168
+ orderSearch: { enabled: true },
169
+ productRecommendations: { enabled: true },
170
170
  }),
171
171
  );
172
172
  builder = builder.withCapability(
173
173
  withMedusaCapabilities(getMedusaTestConfiguration(), {
174
- cart: true,
175
- identity: true,
174
+ cart: { enabled: true },
175
+ identity: { enabled: true },
176
176
  })
177
177
  );
178
178
  }
@@ -5,5 +5,6 @@
5
5
  "declaration": true,
6
6
  "types": ["node"]
7
7
  },
8
- "include": ["src/**/*.ts"]
8
+ "include": ["src/**/*.ts"],
9
+ "exclude": ["src/**/*.spec.ts", "src/utils.ts"]
9
10
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reactionary/source",
3
- "version": "0.3.18",
3
+ "version": "0.6.2",
4
4
  "license": "MIT",
5
5
  "private": false,
6
6
  "dependencies": {