@reactionary/magento 0.0.1 → 0.10.18

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 (62) hide show
  1. package/LICENSE +21 -0
  2. package/capabilities/cart.capability.js +22 -22
  3. package/capabilities/category.capability.js +10 -9
  4. package/capabilities/checkout.capability.js +308 -0
  5. package/capabilities/identity.capability.js +31 -16
  6. package/capabilities/inventory.capability.js +2 -2
  7. package/capabilities/order-search.capability.js +150 -0
  8. package/capabilities/order.capability.js +51 -0
  9. package/capabilities/price.capability.js +2 -2
  10. package/capabilities/product-associations.capability.js +118 -0
  11. package/capabilities/product-recommendations.capability.js +148 -0
  12. package/capabilities/product-reviews.capability.js +182 -0
  13. package/capabilities/product-search.capability.js +2 -2
  14. package/capabilities/product.capability.js +6 -5
  15. package/capabilities/profile.capability.js +283 -0
  16. package/core/client.js +324 -24
  17. package/core/initialize.js +150 -2
  18. package/core/product-reviews.graphql.js +72 -0
  19. package/factories/category/category.factory.js +1 -1
  20. package/factories/checkout/checkout.factory.js +203 -0
  21. package/factories/index.js +6 -0
  22. package/factories/order/order.factory.js +115 -0
  23. package/factories/order-search/order-search.factory.js +79 -0
  24. package/factories/product/product.factory.js +23 -18
  25. package/factories/product-associations/product-associations.factory.js +25 -0
  26. package/factories/product-reviews/product-reviews.factory.js +65 -0
  27. package/factories/product-search/product-search.factory.js +3 -4
  28. package/factories/profile/profile.factory.js +61 -0
  29. package/index.js +9 -0
  30. package/package.json +11 -6
  31. package/schema/capabilities.schema.js +16 -2
  32. package/schema/configuration.schema.js +5 -1
  33. package/src/capabilities/cart.capability.d.ts +5 -0
  34. package/src/capabilities/checkout.capability.d.ts +30 -0
  35. package/src/capabilities/order-search.capability.d.ts +16 -0
  36. package/src/capabilities/order.capability.d.ts +12 -0
  37. package/src/capabilities/product-associations.capability.d.ts +23 -0
  38. package/src/capabilities/product-recommendations.capability.d.ts +24 -0
  39. package/src/capabilities/product-reviews.capability.d.ts +35 -0
  40. package/src/capabilities/profile.capability.d.ts +24 -0
  41. package/src/core/client.d.ts +77 -2
  42. package/src/core/initialize.types.d.ts +40 -7
  43. package/src/core/product-reviews.graphql.d.ts +10 -0
  44. package/src/factories/category/category.factory.d.ts +2 -2
  45. package/src/factories/checkout/checkout.factory.d.ts +32 -0
  46. package/src/factories/index.d.ts +6 -0
  47. package/src/factories/order/order.factory.d.ts +77 -0
  48. package/src/factories/order-search/order-search.factory.d.ts +43 -0
  49. package/src/factories/product/product.factory.d.ts +2 -1
  50. package/src/factories/product-associations/product-associations.factory.d.ts +15 -0
  51. package/src/factories/product-reviews/product-reviews.factory.d.ts +40 -0
  52. package/src/factories/profile/profile.factory.d.ts +43 -0
  53. package/src/index.d.ts +9 -0
  54. package/src/schema/capabilities.schema.d.ts +50 -2
  55. package/src/schema/configuration.schema.d.ts +7 -0
  56. package/src/schema/magento.types.d.ts +219 -0
  57. package/src/utils/magento-product-lookup.d.ts +15 -0
  58. package/src/utils/magento-product.d.ts +36 -0
  59. package/src/utils/magento-review.d.ts +20 -0
  60. package/utils/magento-product-lookup.js +76 -0
  61. package/utils/magento-product.js +110 -0
  62. package/utils/magento-review.js +34 -0
@@ -0,0 +1,61 @@
1
+ class MagentoProfileFactory {
2
+ profileSchema;
3
+ constructor(profileSchema) {
4
+ this.profileSchema = profileSchema;
5
+ }
6
+ parseProfile(context, data) {
7
+ const customer = data;
8
+ const phone = customer.custom_attributes?.find((a) => a.attribute_code === "phone")?.value ?? "";
9
+ const addresses = customer.addresses ?? [];
10
+ const billingId = customer.default_billing;
11
+ const shippingId = customer.default_shipping;
12
+ let billingAddress;
13
+ let shippingAddress;
14
+ const alternateShippingAddresses = [];
15
+ for (const address of addresses) {
16
+ const parsed = this.parseAddress(context, address);
17
+ const id = address.id !== void 0 ? String(address.id) : void 0;
18
+ if (id && billingId && id === billingId) {
19
+ billingAddress = parsed;
20
+ } else if (id && shippingId && id === shippingId) {
21
+ shippingAddress = parsed;
22
+ } else {
23
+ alternateShippingAddresses.push(parsed);
24
+ }
25
+ }
26
+ const result = {
27
+ identifier: {
28
+ userId: String(customer.id)
29
+ },
30
+ email: customer.email,
31
+ emailVerified: true,
32
+ phone,
33
+ phoneVerified: false,
34
+ billingAddress,
35
+ shippingAddress,
36
+ alternateShippingAddresses,
37
+ createdAt: new Date(customer.created_at || Date.now()).toISOString(),
38
+ updatedAt: new Date(customer.updated_at || Date.now()).toISOString()
39
+ };
40
+ return this.profileSchema.parse(result);
41
+ }
42
+ parseAddress(_context, address) {
43
+ const street = address.street ?? [];
44
+ return {
45
+ identifier: {
46
+ nickName: address.company || ""
47
+ },
48
+ firstName: address.firstname || "",
49
+ lastName: address.lastname || "",
50
+ streetAddress: street[0] || "",
51
+ streetNumber: street[1] || "",
52
+ city: address.city || "",
53
+ region: address.region?.region || "",
54
+ postalCode: address.postcode || "",
55
+ countryCode: address.country_id || ""
56
+ };
57
+ }
58
+ }
59
+ export {
60
+ MagentoProfileFactory
61
+ };
package/index.js CHANGED
@@ -5,6 +5,8 @@ export * from "./core/initialize.js";
5
5
  export * from "./core/initialize.types.js";
6
6
  export * from "./core/client.js";
7
7
  export * from "./factories/index.js";
8
+ export * from "./utils/magento-product.js";
9
+ export * from "./utils/magento-review.js";
8
10
  export * from "./capabilities/product.capability.js";
9
11
  export * from "./capabilities/product-search.capability.js";
10
12
  export * from "./capabilities/category.capability.js";
@@ -12,3 +14,10 @@ export * from "./capabilities/inventory.capability.js";
12
14
  export * from "./capabilities/price.capability.js";
13
15
  export * from "./capabilities/identity.capability.js";
14
16
  export * from "./capabilities/cart.capability.js";
17
+ export * from "./capabilities/profile.capability.js";
18
+ export * from "./capabilities/order-search.capability.js";
19
+ export * from "./capabilities/order.capability.js";
20
+ export * from "./capabilities/checkout.capability.js";
21
+ export * from "./capabilities/product-associations.capability.js";
22
+ export * from "./capabilities/product-recommendations.capability.js";
23
+ export * from "./capabilities/product-reviews.capability.js";
package/package.json CHANGED
@@ -1,15 +1,20 @@
1
1
  {
2
2
  "name": "@reactionary/magento",
3
- "version": "0.0.1",
4
- "private": false,
3
+ "version": "0.10.18",
5
4
  "type": "module",
6
5
  "main": "./index.js",
7
6
  "types": "./src/index.d.ts",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/Solteq/reactionary.git"
10
+ },
8
11
  "dependencies": {
9
- "@reactionary/core": "0.0.1",
12
+ "@reactionary/core": "0.10.18",
10
13
  "zod": "4.1.9",
11
14
  "debug": "^4.4.3"
12
15
  },
13
- "sideEffets": false
14
-
15
- }
16
+ "devDependencies": {
17
+ "vitest": "^4.0.9"
18
+ },
19
+ "sideEffects": false
20
+ }
@@ -16,7 +16,14 @@ const MagentoCapabilitiesSchema = CapabilitiesSchema.pick({
16
16
  inventory: true,
17
17
  price: true,
18
18
  identity: true,
19
- cart: true
19
+ cart: true,
20
+ profile: true,
21
+ orderSearch: true,
22
+ order: true,
23
+ checkout: true,
24
+ productAssociations: true,
25
+ productRecommendations: true,
26
+ productReviews: true
20
27
  }).extend({
21
28
  product: OverridableCapabilitySchema.optional(),
22
29
  productSearch: OverridableCapabilitySchema.optional(),
@@ -24,7 +31,14 @@ const MagentoCapabilitiesSchema = CapabilitiesSchema.pick({
24
31
  category: OverridableCapabilitySchema.optional(),
25
32
  price: OverridableCapabilitySchema.optional(),
26
33
  inventory: OverridableCapabilitySchema.optional(),
27
- identity: DirectCapabilitySchema.optional()
34
+ identity: DirectCapabilitySchema.optional(),
35
+ profile: OverridableCapabilitySchema.optional(),
36
+ orderSearch: OverridableCapabilitySchema.optional(),
37
+ order: OverridableCapabilitySchema.optional(),
38
+ checkout: OverridableCapabilitySchema.optional(),
39
+ productAssociations: OverridableCapabilitySchema.optional(),
40
+ productRecommendations: DirectCapabilitySchema.optional(),
41
+ productReviews: OverridableCapabilitySchema.optional()
28
42
  }).partial();
29
43
  export {
30
44
  MagentoCapabilitiesSchema
@@ -3,10 +3,14 @@ const MagentoConfigurationSchema = z.looseObject({
3
3
  adminApiKey: z.string().meta({ description: "The API key for Magento admin operations. Needed for the few tasks that require admin access." }),
4
4
  baseUrl: z.string().meta({ description: "The base URL for the Magento installation." }),
5
5
  mediaUrl: z.string().optional().meta({ description: "The base URL for media files. If not provided, it will be derived from the baseUrl." }),
6
+ mediaSource: z.enum(["EXTERNAL", "DEFAULT"]).default("DEFAULT").meta({ description: "Where product imagery is taken from. DEFAULT uses the Magento media gallery. EXTERNAL uses the `original_dam_reference` attribute, which holds the PIM-sorted list of DAM image URLs." }),
6
7
  defaultCurrency: z.string().default(""),
7
8
  rootCategoryId: z.string().default("2").meta({ description: 'The ID of the root category in Magento. Typically "2" for the default Magento setup.' }),
8
9
  allCurrencies: z.array(z.string()),
9
- storeCode: z.string().default("")
10
+ graphqlUrl: z.string().optional().meta({ description: "The GraphQL endpoint. Defaults to `{baseUrl}/graphql`. Reviews and ratings have no REST equivalent in Magento, so the product reviews capability goes through GraphQL." }),
11
+ reviewRatingCode: z.string().optional().meta({ description: 'The name of the Magento review rating (as listed by `productReviewRatingsMetadata`) that carries the overall star rating. Defaults to "Rating"; the first available rating is used as a fallback.' }),
12
+ storeCode: z.string().default(""),
13
+ authStoreCode: z.string().default("default").meta({ description: "The store/website scope used for customer authentication and account operations (token, customers/me). Customers typically live on the default website, which may differ from the catalog storeCode." })
10
14
  });
11
15
  export {
12
16
  MagentoConfigurationSchema
@@ -8,6 +8,11 @@ export declare class MagentoCartCapability<TFactory extends CartFactory = Magent
8
8
  protected factory: CartFactoryWithOutput<TFactory>;
9
9
  constructor(config: MagentoConfiguration, cache: Cache, context: RequestContext, magentoApi: MagentoClient, factory: CartFactoryWithOutput<TFactory>);
10
10
  getById(payload: CartQueryById): Promise<Result<CartFactoryCartOutput<TFactory>, NotFoundError>>;
11
+ /**
12
+ * Fetches the cart (with merged totals) and parses it into the model. Shared
13
+ * by all mutations that return the resulting cart.
14
+ */
15
+ protected respondWithCart(key: string): Promise<Result<CartFactoryCartOutput<TFactory>>>;
11
16
  add(payload: CartMutationItemAdd): Promise<Result<CartFactoryCartOutput<TFactory>>>;
12
17
  remove(payload: CartMutationItemRemove): Promise<Result<CartFactoryCartOutput<TFactory>>>;
13
18
  changeQuantity(payload: CartMutationItemQuantityChange): Promise<Result<CartFactoryCartOutput<TFactory>>>;
@@ -0,0 +1,30 @@
1
+ import { CheckoutCapability, type Address, type Cache, type CheckoutFactory, type CheckoutFactoryCheckoutOutput, type CheckoutFactoryPaymentMethodOutput, type CheckoutFactoryShippingMethodOutput, type CheckoutFactoryWithOutput, type CheckoutIdentifier, type CheckoutMutationAddPaymentInstruction, type CheckoutMutationFinalizeCheckout, type CheckoutMutationInitiateCheckout, type CheckoutMutationRemovePaymentInstruction, type CheckoutMutationSetShippingAddress, type CheckoutMutationSetShippingInstruction, type CheckoutQueryById, type CheckoutQueryForAvailablePaymentMethods, type CheckoutQueryForAvailableShippingMethods, type NotFoundError, type RequestContext, type Result } from '@reactionary/core';
2
+ import type { MagentoClient } from '../core/client.js';
3
+ import { type MagentoCheckoutFactory } from '../factories/checkout/checkout.factory.js';
4
+ import type { MagentoConfiguration } from '../schema/configuration.schema.js';
5
+ import type { MagentoCart, MagentoCartTotals, MagentoCheckoutAddress, MagentoCheckoutState } from '../schema/magento.types.js';
6
+ export declare class CheckoutNotReadyForFinalizationError extends Error {
7
+ checkoutIdentifier: CheckoutIdentifier;
8
+ constructor(checkoutIdentifier: CheckoutIdentifier);
9
+ }
10
+ export declare class MagentoCheckoutCapability<TFactory extends CheckoutFactory = MagentoCheckoutFactory> extends CheckoutCapability<CheckoutFactoryCheckoutOutput<TFactory>, CheckoutFactoryShippingMethodOutput<TFactory>, CheckoutFactoryPaymentMethodOutput<TFactory>> {
11
+ magentoApi: MagentoClient;
12
+ protected config: MagentoConfiguration;
13
+ protected factory: CheckoutFactoryWithOutput<TFactory>;
14
+ constructor(config: MagentoConfiguration, cache: Cache, context: RequestContext, magentoApi: MagentoClient, factory: CheckoutFactoryWithOutput<TFactory>);
15
+ protected toMagentoAddress(address: Omit<Address, 'identifier'>, email?: string): MagentoCheckoutAddress;
16
+ protected loadCartAndTotals(cartKey: string): Promise<{
17
+ cart: MagentoCart;
18
+ totals?: MagentoCartTotals;
19
+ }>;
20
+ protected buildCheckout(cartKey: string, state: MagentoCheckoutState): Promise<CheckoutFactoryCheckoutOutput<TFactory>>;
21
+ initiateCheckoutForCart(payload: CheckoutMutationInitiateCheckout): Promise<Result<CheckoutFactoryCheckoutOutput<TFactory>>>;
22
+ getById(payload: CheckoutQueryById): Promise<Result<CheckoutFactoryCheckoutOutput<TFactory>, NotFoundError>>;
23
+ setShippingAddress(payload: CheckoutMutationSetShippingAddress): Promise<Result<CheckoutFactoryCheckoutOutput<TFactory>>>;
24
+ getAvailableShippingMethods(payload: CheckoutQueryForAvailableShippingMethods): Promise<Result<CheckoutFactoryShippingMethodOutput<TFactory>[]>>;
25
+ getAvailablePaymentMethods(payload: CheckoutQueryForAvailablePaymentMethods): Promise<Result<CheckoutFactoryPaymentMethodOutput<TFactory>[]>>;
26
+ addPaymentInstruction(payload: CheckoutMutationAddPaymentInstruction): Promise<Result<CheckoutFactoryCheckoutOutput<TFactory>>>;
27
+ removePaymentInstruction(payload: CheckoutMutationRemovePaymentInstruction): Promise<Result<CheckoutFactoryCheckoutOutput<TFactory>>>;
28
+ setShippingInstruction(payload: CheckoutMutationSetShippingInstruction): Promise<Result<CheckoutFactoryCheckoutOutput<TFactory>>>;
29
+ finalizeCheckout(payload: CheckoutMutationFinalizeCheckout): Promise<Result<CheckoutFactoryCheckoutOutput<TFactory>>>;
30
+ }
@@ -0,0 +1,16 @@
1
+ import type { Cache, OrderSearchFactory, OrderSearchFactoryOutput, OrderSearchFactoryWithOutput, OrderSearchQueryByTerm, RequestContext, Result } from '@reactionary/core';
2
+ import { OrderSearchCapability } from '@reactionary/core';
3
+ import type { MagentoClient } from '../core/client.js';
4
+ import type { MagentoOrderSearchFactory } from '../factories/order-search/order-search.factory.js';
5
+ import type { MagentoConfiguration } from '../schema/configuration.schema.js';
6
+ export declare class MagentoOrderSearchCapability<TFactory extends OrderSearchFactory = MagentoOrderSearchFactory> extends OrderSearchCapability<OrderSearchFactoryOutput<TFactory>> {
7
+ magentoApi: MagentoClient;
8
+ protected config: MagentoConfiguration;
9
+ protected factory: OrderSearchFactoryWithOutput<TFactory>;
10
+ constructor(config: MagentoConfiguration, cache: Cache, context: RequestContext, magentoApi: MagentoClient, factory: OrderSearchFactoryWithOutput<TFactory>);
11
+ protected emptyResult(payload: OrderSearchQueryByTerm): ReturnType<TFactory["parseOrderSearchResult"]>;
12
+ protected resolveCustomerId(): Promise<string | null>;
13
+ protected buildSearchParams(payload: OrderSearchQueryByTerm, customerId: string): URLSearchParams;
14
+ queryByTerm(payload: OrderSearchQueryByTerm): Promise<Result<OrderSearchFactoryOutput<TFactory>>>;
15
+ protected filterByPartNumber(response: any, partNumbers: string[]): any;
16
+ }
@@ -0,0 +1,12 @@
1
+ import type { Cache, NotFoundError, OrderFactory, OrderFactoryOutput, OrderFactoryWithOutput, OrderQueryById, RequestContext, Result } from '@reactionary/core';
2
+ import { OrderCapability } from '@reactionary/core';
3
+ import type { MagentoClient } from '../core/client.js';
4
+ import type { MagentoOrderFactory } from '../factories/order/order.factory.js';
5
+ import type { MagentoConfiguration } from '../schema/configuration.schema.js';
6
+ export declare class MagentoOrderCapability<TFactory extends OrderFactory = MagentoOrderFactory> extends OrderCapability<OrderFactoryOutput<TFactory>> {
7
+ magentoApi: MagentoClient;
8
+ protected config: MagentoConfiguration;
9
+ protected factory: OrderFactoryWithOutput<TFactory>;
10
+ constructor(config: MagentoConfiguration, cache: Cache, context: RequestContext, magentoApi: MagentoClient, factory: OrderFactoryWithOutput<TFactory>);
11
+ getById(payload: OrderQueryById): Promise<Result<OrderFactoryOutput<TFactory>, NotFoundError>>;
12
+ }
@@ -0,0 +1,23 @@
1
+ import { ProductAssociationsCapability, type Cache, type ProductAssociationsFactory, type ProductAssociationsFactoryOutput, type ProductAssociationsFactoryWithOutput, type ProductAssociationsGetAccessoriesQuery, type ProductAssociationsGetReplacementsQuery, type ProductAssociationsGetSparepartsQuery, type ProductIdentifier, type RequestContext, type Result } from '@reactionary/core';
2
+ import type { MagentoClient } from '../core/client.js';
3
+ import type { MagentoProductAssociationsFactory } from '../factories/product-associations/product-associations.factory.js';
4
+ import type { MagentoConfiguration } from '../schema/configuration.schema.js';
5
+ import type { MagentoProduct, MagentoProductLinkType } from '../schema/magento.types.js';
6
+ /**
7
+ * Maps the reactionary association types onto Magento's native product links.
8
+ * Each mapping is an extension point so projects can re-wire them.
9
+ */
10
+ export declare class MagentoProductAssociationsCapability<TFactory extends ProductAssociationsFactory = MagentoProductAssociationsFactory> extends ProductAssociationsCapability<ProductAssociationsFactoryOutput<TFactory>> {
11
+ magentoApi: MagentoClient;
12
+ protected config: MagentoConfiguration;
13
+ protected factory: ProductAssociationsFactoryWithOutput<TFactory>;
14
+ constructor(config: MagentoConfiguration, cache: Cache, context: RequestContext, magentoApi: MagentoClient, factory: ProductAssociationsFactoryWithOutput<TFactory>);
15
+ protected getAccessoriesLinkType(): MagentoProductLinkType;
16
+ protected getSparepartsLinkType(): MagentoProductLinkType;
17
+ protected getReplacementsLinkType(): MagentoProductLinkType;
18
+ protected fetchAssociatedProductsFor(forProduct: ProductIdentifier, linkType: MagentoProductLinkType, maxNumberOfAssociations: number): Promise<MagentoProduct[]>;
19
+ protected toAssociations(forProduct: ProductIdentifier, associationType: string, products: MagentoProduct[]): ProductAssociationsFactoryOutput<TFactory>[];
20
+ getAccessories(query: ProductAssociationsGetAccessoriesQuery): Promise<Result<ProductAssociationsFactoryOutput<TFactory>[]>>;
21
+ getSpareparts(query: ProductAssociationsGetSparepartsQuery): Promise<Result<ProductAssociationsFactoryOutput<TFactory>[]>>;
22
+ getReplacements(query: ProductAssociationsGetReplacementsQuery): Promise<Result<ProductAssociationsFactoryOutput<TFactory>[]>>;
23
+ }
@@ -0,0 +1,24 @@
1
+ import { ProductRecommendationsCapability, type Cache, type ProductIdentifier, type ProductRecommendation, type ProductRecommendationAlgorithmFrequentlyBoughtTogetherQuery, type ProductRecommendationAlgorithmRelatedProductsQuery, type ProductRecommendationAlgorithmSimilarProductsQuery, type ProductRecommendationAlgorithmTrendingInCategoryQuery, type ProductRecommendationsByCollectionQuery, type RequestContext, type Result } from '@reactionary/core';
2
+ import type { MagentoClient } from '../core/client.js';
3
+ import type { MagentoConfiguration } from '../schema/configuration.schema.js';
4
+ import type { MagentoProduct, MagentoProductLinkType } from '../schema/magento.types.js';
5
+ /**
6
+ * Magento has no recommendation engine, so recommendations are derived from the
7
+ * catalogue itself: native product links for the product based algorithms, and
8
+ * the category tree for collections and category trends.
9
+ */
10
+ export declare class MagentoProductRecommendationsCapability extends ProductRecommendationsCapability {
11
+ magentoApi: MagentoClient;
12
+ protected config: MagentoConfiguration;
13
+ constructor(config: MagentoConfiguration, cache: Cache, context: RequestContext, magentoApi: MagentoClient);
14
+ protected getRelatedLinkType(): MagentoProductLinkType;
15
+ protected getSimilarLinkType(): MagentoProductLinkType;
16
+ protected getFrequentlyBoughtTogetherLinkType(): MagentoProductLinkType;
17
+ protected toRecommendations(algorithm: string, keyPrefix: string, products: MagentoProduct[]): ProductRecommendation[];
18
+ protected fetchLinkedProducts(sourceProduct: ProductIdentifier, linkType: MagentoProductLinkType, numberOfRecommendations: number): Promise<MagentoProduct[]>;
19
+ getCollection(query: ProductRecommendationsByCollectionQuery): Promise<Result<ProductRecommendation[]>>;
20
+ protected getRelatedProductsRecommendations(query: ProductRecommendationAlgorithmRelatedProductsQuery): Promise<ProductRecommendation[]>;
21
+ protected getSimilarProductsRecommendations(query: ProductRecommendationAlgorithmSimilarProductsQuery): Promise<ProductRecommendation[]>;
22
+ protected getFrequentlyBoughtTogetherRecommendations(query: ProductRecommendationAlgorithmFrequentlyBoughtTogetherQuery): Promise<ProductRecommendation[]>;
23
+ protected getTrendingInCategoryRecommendations(query: ProductRecommendationAlgorithmTrendingInCategoryQuery): Promise<ProductRecommendation[]>;
24
+ }
@@ -0,0 +1,35 @@
1
+ import { ProductReviewsCapability, type Cache, type ProductReviewMutationSubmit, type ProductReviewsFactory, type ProductReviewsFactoryRatingOutput, type ProductReviewsFactoryReviewOutput, type ProductReviewsFactoryReviewPaginatedOutput, type ProductReviewsFactoryWithOutput, type ProductReviewsGetRatingSummaryQuery, type ProductReviewsListQuery, type RequestContext, type Result } from '@reactionary/core';
2
+ import type { MagentoClient } from '../core/client.js';
3
+ import type { MagentoProductReviewsFactory } from '../factories/product-reviews/product-reviews.factory.js';
4
+ import type { MagentoConfiguration } from '../schema/configuration.schema.js';
5
+ import type { MagentoCreateProductReviewRating, MagentoReviewableProduct } from '../schema/magento.types.js';
6
+ /**
7
+ * Magento's REST API carries no reviews or ratings at all, so this capability
8
+ * talks to the GraphQL endpoint (`products.rating_summary`, `products.reviews`
9
+ * and the `createProductReview` mutation) through {@link MagentoClient}.
10
+ *
11
+ * Two consequences of that schema are worth knowing about:
12
+ * - there is no per-star distribution, so `ratingDistribution` is undefined;
13
+ * - reviews have no identifier, so keys are derived (see `buildProductReviewKey`).
14
+ */
15
+ export declare class MagentoProductReviewsCapability<TFactory extends ProductReviewsFactory = MagentoProductReviewsFactory> extends ProductReviewsCapability<ProductReviewsFactoryRatingOutput<TFactory>, ProductReviewsFactoryReviewPaginatedOutput<TFactory>, ProductReviewsFactoryReviewOutput<TFactory>> {
16
+ magentoApi: MagentoClient;
17
+ protected config: MagentoConfiguration;
18
+ protected factory: ProductReviewsFactoryWithOutput<TFactory>;
19
+ constructor(config: MagentoConfiguration, cache: Cache, context: RequestContext, magentoApi: MagentoClient, factory: ProductReviewsFactoryWithOutput<TFactory>);
20
+ /**
21
+ * The name of the Magento rating that carries the overall star score. Stores
22
+ * can define several named ratings; override to pick a different one.
23
+ */
24
+ protected getReviewRatingCode(): string;
25
+ protected fetchRatingSummary(sku: string): Promise<MagentoReviewableProduct | null>;
26
+ protected fetchReviews(sku: string, pageSize: number, pageNumber: number): Promise<MagentoReviewableProduct | null>;
27
+ /**
28
+ * Magento will not accept a star count directly — the rating has to be sent
29
+ * as an opaque `value_id` looked up through `productReviewRatingsMetadata`.
30
+ */
31
+ protected resolveRatingInput(rating: number): Promise<MagentoCreateProductReviewRating[] | null>;
32
+ getRatingSummary(query: ProductReviewsGetRatingSummaryQuery): Promise<Result<ProductReviewsFactoryRatingOutput<TFactory>>>;
33
+ findReviews(query: ProductReviewsListQuery): Promise<Result<ProductReviewsFactoryReviewPaginatedOutput<TFactory>>>;
34
+ submitReview(mutation: ProductReviewMutationSubmit): Promise<Result<ProductReviewsFactoryReviewOutput<TFactory>>>;
35
+ }
@@ -0,0 +1,24 @@
1
+ import { type Address, type Cache, type NotFoundError, ProfileCapability, type ProfileFactory, type ProfileFactoryOutput, type ProfileFactoryWithOutput, type ProfileMutationAddShippingAddress, type ProfileMutationMakeShippingAddressDefault, type ProfileMutationRemoveShippingAddress, type ProfileMutationSetBillingAddress, type ProfileMutationUpdate, type ProfileMutationUpdateShippingAddress, type ProfileQuerySelf as ProfileQueryById, type RequestContext, type Result } from '@reactionary/core';
2
+ import type { MagentoClient } from '../core/client.js';
3
+ import type { MagentoAddress, MagentoCustomer, MagentoProfileFactory } from '../factories/profile/profile.factory.js';
4
+ import type { MagentoConfiguration } from '../schema/configuration.schema.js';
5
+ export declare class MagentoProfileCapability<TFactory extends ProfileFactory = MagentoProfileFactory> extends ProfileCapability<ProfileFactoryOutput<TFactory>> {
6
+ magentoApi: MagentoClient;
7
+ protected config: MagentoConfiguration;
8
+ protected factory: ProfileFactoryWithOutput<TFactory>;
9
+ constructor(config: MagentoConfiguration, cache: Cache, context: RequestContext, magentoApi: MagentoClient, factory: ProfileFactoryWithOutput<TFactory>);
10
+ protected fetchCustomer(): Promise<MagentoCustomer | null>;
11
+ protected buildMagentoAddress(address: Address, flags?: {
12
+ default_billing?: boolean;
13
+ default_shipping?: boolean;
14
+ }, existing?: MagentoAddress): MagentoAddress;
15
+ protected findByNickName(customer: MagentoCustomer, nickName: string): MagentoAddress | undefined;
16
+ getById(payload: ProfileQueryById): Promise<Result<ProfileFactoryOutput<TFactory>, NotFoundError>>;
17
+ update(payload: ProfileMutationUpdate): Promise<Result<ProfileFactoryOutput<TFactory>, NotFoundError>>;
18
+ addShippingAddress(payload: ProfileMutationAddShippingAddress): Promise<Result<ProfileFactoryOutput<TFactory>, NotFoundError>>;
19
+ updateShippingAddress(payload: ProfileMutationUpdateShippingAddress): Promise<Result<ProfileFactoryOutput<TFactory>, NotFoundError>>;
20
+ removeShippingAddress(payload: ProfileMutationRemoveShippingAddress): Promise<Result<ProfileFactoryOutput<TFactory>, NotFoundError>>;
21
+ makeShippingAddressDefault(payload: ProfileMutationMakeShippingAddressDefault): Promise<Result<ProfileFactoryOutput<TFactory>, NotFoundError>>;
22
+ setBillingAddress(payload: ProfileMutationSetBillingAddress): Promise<Result<ProfileFactoryOutput<TFactory>, NotFoundError>>;
23
+ protected preserveAddresses(customer: MagentoCustomer): MagentoAddress[];
24
+ }
@@ -1,6 +1,13 @@
1
1
  import type { MagentoConfiguration } from '../schema/configuration.schema.js';
2
2
  import type { RequestContext } from '@reactionary/core';
3
+ import type { MagentoCheckoutAddress, MagentoCheckoutState, MagentoCreateProductReviewInput, MagentoCreateProductReviewResult, MagentoPaymentMethod, MagentoPlaceOrderPayload, MagentoProductLink, MagentoProductReview, MagentoProductReviewRatingMetadata, MagentoProductReviewRatingsMetadataQueryResult, MagentoProductReviewsQueryResult, MagentoProductSearchResult, MagentoReviewableProduct, MagentoShippingInformationPayload, MagentoShippingInformationResult, MagentoShippingMethod } from '../schema/magento.types.js';
3
4
  export declare const SESSION_KEY = "MAGENTO_PROVIDER";
5
+ /**
6
+ * Magento enforces a password complexity policy (min. number of character
7
+ * classes). Deterministically pad the password so it always satisfies the
8
+ * policy; the same transform is applied on both register and login.
9
+ */
10
+ export declare function ensureMagentoPasswordPolicy(password: string): string;
4
11
  export interface MagentoCustomStorage {
5
12
  getItem(key: string): Promise<string | null>;
6
13
  setItem(key: string, value: string): Promise<void>;
@@ -22,12 +29,30 @@ declare class MagentoRest {
22
29
  protected apiUrl: string;
23
30
  constructor(baseUrl: string, storeCode: string, getAuthHeader: () => Promise<Record<string, string>>);
24
31
  private normalizeUrl;
25
- request<T>(method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE', path: string, body?: unknown): Promise<T>;
32
+ request<T>(method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE', path: string, body?: unknown, options?: {
33
+ allowNotFound?: boolean;
34
+ }): Promise<T>;
35
+ }
36
+ /**
37
+ * Reviews and ratings are absent from the Magento REST API, so they are read
38
+ * and written over GraphQL. The store scope travels in the `Store` header
39
+ * rather than in the path, which is the one structural difference from REST.
40
+ */
41
+ export declare class MagentoGraphQL {
42
+ private endpoint;
43
+ private storeCode;
44
+ private getAuthHeader;
45
+ constructor(endpoint: string, storeCode: string, getAuthHeader: () => Promise<Record<string, string>>);
46
+ request<T>(document: string, variables?: Record<string, unknown>): Promise<T>;
26
47
  }
27
48
  export declare class Magento {
28
49
  private rest;
29
50
  private tokenStore;
30
- constructor(rest: MagentoRest, tokenStore: RequestContextTokenStore);
51
+ private graphql?;
52
+ private authRest;
53
+ private adminRest;
54
+ constructor(rest: MagentoRest, tokenStore: RequestContextTokenStore, authRest?: MagentoRest, adminRest?: MagentoRest, graphql?: MagentoGraphQL | undefined);
55
+ private get gql();
31
56
  auth: {
32
57
  login: (email: string, password: string) => Promise<string>;
33
58
  logout: () => Promise<void>;
@@ -36,10 +61,18 @@ export declare class Magento {
36
61
  customer: {
37
62
  register: (customer: any, password?: string) => Promise<any>;
38
63
  me: () => Promise<any>;
64
+ update: (customer: any) => Promise<any>;
39
65
  };
40
66
  product: {
41
67
  getBySKU: (sku: string) => Promise<any>;
42
68
  search: (params: URLSearchParams) => Promise<any>;
69
+ getLinks: (sku: string, linkType: string) => Promise<MagentoProductLink[]>;
70
+ };
71
+ productReviews: {
72
+ getSummary: (sku: string) => Promise<MagentoProductReviewsQueryResult>;
73
+ list: (sku: string, pageSize: number, currentPage: number) => Promise<MagentoProductReviewsQueryResult>;
74
+ getRatingsMetadata: () => Promise<MagentoProductReviewRatingsMetadataQueryResult>;
75
+ create: (input: MagentoCreateProductReviewInput) => Promise<MagentoCreateProductReviewResult>;
43
76
  };
44
77
  category: {
45
78
  getById: (categoryId: string) => Promise<any>;
@@ -50,6 +83,17 @@ export declare class Magento {
50
83
  getStockStatus: (sku: string) => Promise<any>;
51
84
  getSourceItems: (params: URLSearchParams) => Promise<any>;
52
85
  };
86
+ order: {
87
+ list: (params: URLSearchParams) => Promise<any>;
88
+ get: (id: string) => Promise<any>;
89
+ };
90
+ checkout: {
91
+ estimateShippingMethods: (cartId: string | null, address: MagentoCheckoutAddress, customerToken?: string | null) => Promise<MagentoShippingMethod[]>;
92
+ getPaymentMethods: (cartId: string | null, customerToken?: string | null) => Promise<MagentoPaymentMethod[]>;
93
+ setShippingInformation: (cartId: string | null, payload: MagentoShippingInformationPayload, customerToken?: string | null) => Promise<MagentoShippingInformationResult>;
94
+ setBillingAddress: (cartId: string | null, address: MagentoCheckoutAddress, customerToken?: string | null) => Promise<number>;
95
+ placeOrder: (cartId: string | null, payload: MagentoPlaceOrderPayload, customerToken?: string | null) => Promise<number>;
96
+ };
53
97
  cart: {
54
98
  create: (customerToken?: string | null) => Promise<string>;
55
99
  get: (cartId?: string | null, customerToken?: string | null) => Promise<any>;
@@ -62,6 +106,11 @@ export declare class Magento {
62
106
  };
63
107
  };
64
108
  }
109
+ /**
110
+ * Magento serves GraphQL from a fixed `/graphql` path next to the REST tree,
111
+ * unless the installation was reverse-proxied elsewhere.
112
+ */
113
+ export declare function resolveGraphQLEndpoint(config: MagentoConfiguration): string;
65
114
  export declare class MagentoAdminClient {
66
115
  protected rest: MagentoRest;
67
116
  protected client: Magento;
@@ -72,15 +121,34 @@ export declare class MagentoClient {
72
121
  protected config: MagentoConfiguration;
73
122
  protected tokenStore: RequestContextTokenStore;
74
123
  protected rest: MagentoRest;
124
+ protected authRest: MagentoRest;
125
+ protected adminRest: MagentoRest;
126
+ protected graphql: MagentoGraphQL;
75
127
  protected client: Promise<Magento> | undefined;
76
128
  constructor(config: MagentoConfiguration, context: RequestContext);
77
129
  getClient(): Promise<Magento>;
78
130
  login(email: string, password: string): Promise<string>;
79
131
  logout(): Promise<void>;
80
132
  getMe(): Promise<any>;
133
+ getCustomerToken(): Promise<string | null>;
134
+ getActiveCartId(): Promise<string | null>;
135
+ setActiveCartId(cartId: string): Promise<void>;
136
+ clearActiveCartId(): Promise<void>;
81
137
  register(customer: any, password?: string): Promise<any>;
138
+ updateMe(customer: any): Promise<any>;
139
+ searchOrders(params: URLSearchParams): Promise<any>;
140
+ /** Returns undefined (not a thrown error) when Magento returns a 404 — no order with this entity_id. */
141
+ getOrderById(id: string): Promise<any>;
82
142
  getProductBySKU(sku: string): Promise<any>;
83
143
  resolveProductForSKU(sku: string): Promise<any>;
144
+ searchProducts(params: URLSearchParams): Promise<MagentoProductSearchResult>;
145
+ getProductLinks(sku: string, linkType: string): Promise<MagentoProductLink[]>;
146
+ /** Returns null when no product matches the SKU in the current store scope. */
147
+ getProductReviewSummary(sku: string): Promise<MagentoReviewableProduct | null>;
148
+ /** Returns null when no product matches the SKU in the current store scope. */
149
+ getProductReviews(sku: string, pageSize: number, currentPage: number): Promise<MagentoReviewableProduct | null>;
150
+ getProductReviewRatingsMetadata(): Promise<MagentoProductReviewRatingMetadata[]>;
151
+ createProductReview(input: MagentoCreateProductReviewInput): Promise<MagentoProductReview | null>;
84
152
  createCart(): Promise<string>;
85
153
  getCart(cartId?: string | null): Promise<any>;
86
154
  getCartTotals(cartId?: string | null): Promise<any>;
@@ -89,5 +157,12 @@ export declare class MagentoClient {
89
157
  removeCartItem(cartId: string | null, itemId: number): Promise<any>;
90
158
  applyCoupon(cartId: string | null, couponCode: string): Promise<any>;
91
159
  removeCoupon(cartId: string | null): Promise<any>;
160
+ estimateShippingMethods(cartId: string | null, address: MagentoCheckoutAddress): Promise<MagentoShippingMethod[]>;
161
+ getPaymentMethods(cartId: string | null): Promise<MagentoPaymentMethod[]>;
162
+ setShippingInformation(cartId: string | null, payload: MagentoShippingInformationPayload): Promise<MagentoShippingInformationResult>;
163
+ setCheckoutBillingAddress(cartId: string | null, address: MagentoCheckoutAddress): Promise<number>;
164
+ placeOrder(cartId: string | null, payload: MagentoPlaceOrderPayload): Promise<number>;
165
+ getCheckoutState(cartKey: string): Promise<MagentoCheckoutState>;
166
+ setCheckoutState(cartKey: string, state: MagentoCheckoutState): Promise<void>;
92
167
  }
93
168
  export {};
@@ -1,4 +1,4 @@
1
- import type { CartFactory, CategoryFactory, ClientFromCapabilities, InventoryFactory, PriceFactory, ProductFactory, ProductSearchFactory } from '@reactionary/core';
1
+ import type { CartFactory, CategoryFactory, ClientFromCapabilities, InventoryFactory, PriceFactory, ProductFactory, ProductSearchFactory, ProfileFactory, OrderSearchFactory, OrderFactory, CheckoutFactory, ProductAssociationsFactory, ProductReviewsFactory } from '@reactionary/core';
2
2
  import type { MagentoCapabilities } from '../schema/capabilities.schema.js';
3
3
  import type { MagentoCartFactory } from '../factories/cart/cart.factory.js';
4
4
  import type { MagentoCategoryFactory } from '../factories/category/category.factory.js';
@@ -6,6 +6,12 @@ import type { MagentoInventoryFactory } from '../factories/inventory/inventory.f
6
6
  import type { MagentoPriceFactory } from '../factories/price/price.factory.js';
7
7
  import type { MagentoProductFactory } from '../factories/product/product.factory.js';
8
8
  import type { MagentoProductSearchFactory } from '../factories/product-search/product-search.factory.js';
9
+ import type { MagentoProfileFactory } from '../factories/profile/profile.factory.js';
10
+ import type { MagentoOrderSearchFactory } from '../factories/order-search/order-search.factory.js';
11
+ import type { MagentoOrderFactory } from '../factories/order/order.factory.js';
12
+ import type { MagentoCheckoutFactory } from '../factories/checkout/checkout.factory.js';
13
+ import type { MagentoProductAssociationsFactory } from '../factories/product-associations/product-associations.factory.js';
14
+ import type { MagentoProductReviewsFactory } from '../factories/product-reviews/product-reviews.factory.js';
9
15
  import type { MagentoCartCapability } from '../capabilities/cart.capability.js';
10
16
  import type { MagentoCategoryCapability } from '../capabilities/category.capability.js';
11
17
  import type { MagentoIdentityCapability } from '../capabilities/identity.capability.js';
@@ -13,14 +19,22 @@ import type { MagentoInventoryCapability } from '../capabilities/inventory.capab
13
19
  import type { MagentoPriceCapability } from '../capabilities/price.capability.js';
14
20
  import type { MagentoProductCapability } from '../capabilities/product.capability.js';
15
21
  import type { MagentoProductSearchCapability } from '../capabilities/product-search.capability.js';
16
- type OverridableCapabilityKey = 'product' | 'productSearch' | 'cart' | 'category' | 'price' | 'inventory';
22
+ import type { MagentoProfileCapability } from '../capabilities/profile.capability.js';
23
+ import type { MagentoOrderSearchCapability } from '../capabilities/order-search.capability.js';
24
+ import type { MagentoOrderCapability } from '../capabilities/order.capability.js';
25
+ import type { MagentoCheckoutCapability } from '../capabilities/checkout.capability.js';
26
+ import type { MagentoProductAssociationsCapability } from '../capabilities/product-associations.capability.js';
27
+ import type { MagentoProductRecommendationsCapability } from '../capabilities/product-recommendations.capability.js';
28
+ import type { MagentoProductReviewsCapability } from '../capabilities/product-reviews.capability.js';
29
+ type OverridableCapabilityKey = 'product' | 'productSearch' | 'cart' | 'category' | 'price' | 'inventory' | 'profile' | 'orderSearch' | 'order' | 'checkout' | 'productAssociations' | 'productReviews';
30
+ type DirectCapabilityKey = 'identity' | 'productRecommendations';
17
31
  type EnabledCapability<TCapability> = TCapability extends {
18
32
  enabled: true;
19
33
  } ? true : false;
20
- type NormalizeConfiguredCapabilities<T extends MagentoCapabilities> = Omit<T, OverridableCapabilityKey | 'identity'> & {
34
+ type NormalizeConfiguredCapabilities<T extends MagentoCapabilities> = Omit<T, OverridableCapabilityKey | DirectCapabilityKey> & {
21
35
  [K in OverridableCapabilityKey]?: EnabledCapability<T[K]>;
22
36
  } & {
23
- identity?: EnabledCapability<T['identity']>;
37
+ [K in DirectCapabilityKey]?: EnabledCapability<T[K]>;
24
38
  };
25
39
  type ExtractCapabilityFactory<TCapability, TContract, TDefaultFactory> = TCapability extends {
26
40
  enabled: true;
@@ -37,6 +51,12 @@ type FactoryContractMap = {
37
51
  category: CategoryFactory;
38
52
  price: PriceFactory;
39
53
  inventory: InventoryFactory;
54
+ profile: ProfileFactory;
55
+ orderSearch: OrderSearchFactory;
56
+ order: OrderFactory;
57
+ checkout: CheckoutFactory;
58
+ productAssociations: ProductAssociationsFactory;
59
+ productReviews: ProductReviewsFactory;
40
60
  };
41
61
  type DefaultFactoryMap = {
42
62
  product: MagentoProductFactory;
@@ -45,6 +65,12 @@ type DefaultFactoryMap = {
45
65
  category: MagentoCategoryFactory;
46
66
  price: MagentoPriceFactory;
47
67
  inventory: MagentoInventoryFactory;
68
+ profile: MagentoProfileFactory;
69
+ orderSearch: MagentoOrderSearchFactory;
70
+ order: MagentoOrderFactory;
71
+ checkout: MagentoCheckoutFactory;
72
+ productAssociations: MagentoProductAssociationsFactory;
73
+ productReviews: MagentoProductReviewsFactory;
48
74
  };
49
75
  type ResolvedFactoryMap<T extends MagentoCapabilities> = {
50
76
  [K in OverridableCapabilityKey]: ExtractCapabilityFactory<T[K], FactoryContractMap[K], DefaultFactoryMap[K]>;
@@ -56,17 +82,24 @@ type DefaultCapabilityMap<T extends MagentoCapabilities> = {
56
82
  category: MagentoCategoryCapability<ResolvedFactoryMap<T>['category']>;
57
83
  price: MagentoPriceCapability<ResolvedFactoryMap<T>['price']>;
58
84
  inventory: MagentoInventoryCapability<ResolvedFactoryMap<T>['inventory']>;
85
+ profile: MagentoProfileCapability<ResolvedFactoryMap<T>['profile']>;
86
+ orderSearch: MagentoOrderSearchCapability<ResolvedFactoryMap<T>['orderSearch']>;
87
+ order: MagentoOrderCapability<ResolvedFactoryMap<T>['order']>;
88
+ checkout: MagentoCheckoutCapability<ResolvedFactoryMap<T>['checkout']>;
89
+ productAssociations: MagentoProductAssociationsCapability<ResolvedFactoryMap<T>['productAssociations']>;
90
+ productReviews: MagentoProductReviewsCapability<ResolvedFactoryMap<T>['productReviews']>;
91
+ productRecommendations: MagentoProductRecommendationsCapability;
59
92
  identity: MagentoIdentityCapability;
60
93
  };
61
94
  type CapabilityImplementationMap<T extends MagentoCapabilities> = {
62
- [K in OverridableCapabilityKey | 'identity']: ExtractCapabilityImplementation<T[K], DefaultCapabilityMap<T>[K]>;
95
+ [K in OverridableCapabilityKey | DirectCapabilityKey]: ExtractCapabilityImplementation<T[K], DefaultCapabilityMap<T>[K]>;
63
96
  };
64
97
  type EnabledCapabilityOverrideMap<T extends MagentoCapabilities> = {
65
- [K in OverridableCapabilityKey | 'identity' as T[K] extends {
98
+ [K in OverridableCapabilityKey | DirectCapabilityKey as T[K] extends {
66
99
  enabled: true;
67
100
  } ? K : never]: CapabilityImplementationMap<T>[K];
68
101
  };
69
- export type MagentoClientFromCapabilities<T extends MagentoCapabilities> = Omit<ClientFromCapabilities<NormalizeConfiguredCapabilities<T>>, OverridableCapabilityKey | 'identity'> & EnabledCapabilityOverrideMap<T>;
102
+ export type MagentoClientFromCapabilities<T extends MagentoCapabilities> = Omit<ClientFromCapabilities<NormalizeConfiguredCapabilities<T>>, OverridableCapabilityKey | DirectCapabilityKey> & EnabledCapabilityOverrideMap<T>;
70
103
  export declare function resolveCapabilityWithFactory<TFactory, TResolvedCapability, TCapabilityArgs>(capability: {
71
104
  factory?: TFactory;
72
105
  capability?: (args: TCapabilityArgs) => TResolvedCapability;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Magento's REST API carries no reviews or ratings, so everything the product
3
+ * reviews capability needs is fetched through the GraphQL endpoint. Reviews are
4
+ * reachable only as a nested field on `products`, which is why every document
5
+ * here starts from a single-SKU product lookup.
6
+ */
7
+ export declare const PRODUCT_RATING_SUMMARY_QUERY = "\n query ReactionaryProductRatingSummary($sku: String!) {\n products(filter: { sku: { eq: $sku } }, pageSize: 1, currentPage: 1) {\n items {\n sku\n rating_summary\n review_count\n }\n }\n }\n";
8
+ export declare const PRODUCT_REVIEWS_QUERY = "\n query ReactionaryProductReviews($sku: String!, $pageSize: Int!, $currentPage: Int!) {\n products(filter: { sku: { eq: $sku } }, pageSize: 1, currentPage: 1) {\n items {\n sku\n rating_summary\n review_count\n reviews(pageSize: $pageSize, currentPage: $currentPage) {\n items {\n\n average_rating\n created_at\n nickname\n summary\n text\n ratings_breakdown {\n name\n value\n }\n\n }\n page_info {\n page_size\n current_page\n total_pages\n }\n }\n }\n }\n }\n";
9
+ export declare const PRODUCT_REVIEW_RATINGS_METADATA_QUERY = "\n query ReactionaryProductReviewRatingsMetadata {\n productReviewRatingsMetadata {\n items {\n id\n name\n values {\n value_id\n value\n }\n }\n }\n }\n";
10
+ export declare const CREATE_PRODUCT_REVIEW_MUTATION = "\n mutation ReactionaryCreateProductReview($input: CreateProductReviewInput!) {\n createProductReview(input: $input) {\n review {\n\n average_rating\n created_at\n nickname\n summary\n text\n ratings_breakdown {\n name\n value\n }\n\n }\n }\n }\n";
@@ -1,4 +1,4 @@
1
- import { type AnyCategoryPaginatedResultSchema, type AnyCategorySchema, type CategoryFactory, type CategoryPaginatedResultSchema, type CategorySchema, type RequestContext } from '@reactionary/core';
1
+ import { type AnyCategoryPaginatedResultSchema, type AnyCategorySchema, type CategoryFactory, type CategoryPaginatedResultSchema, type CategoryQueryForChildCategories, type CategoryQueryForTopCategories, type CategorySchema, type RequestContext } from '@reactionary/core';
2
2
  import type * as z from 'zod';
3
3
  import type { MagentoCategory, MagentoCategorySearchResult } from '../../schema/magento.types.js';
4
4
  export interface MagentoCategoryPaginatedInput extends MagentoCategorySearchResult {
@@ -10,5 +10,5 @@ export declare class MagentoCategoryFactory<TCategorySchema extends AnyCategoryS
10
10
  readonly categoryPaginatedResultSchema: TCategoryPaginatedSchema;
11
11
  constructor(categorySchema: TCategorySchema, categoryPaginatedResultSchema: TCategoryPaginatedSchema);
12
12
  parseCategory(_context: RequestContext, data: MagentoCategory): z.output<TCategorySchema>;
13
- parseCategoryPaginatedResult(context: RequestContext, data: MagentoCategoryPaginatedInput): z.output<TCategoryPaginatedSchema>;
13
+ parseCategoryPaginatedResult(context: RequestContext, data: MagentoCategoryPaginatedInput, _query: CategoryQueryForTopCategories | CategoryQueryForChildCategories): z.output<TCategoryPaginatedSchema>;
14
14
  }