medusa-product-helper 0.0.16 → 0.0.19

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 (26) hide show
  1. package/.medusa/server/src/admin/index.js +59 -117
  2. package/.medusa/server/src/admin/index.mjs +59 -117
  3. package/.medusa/server/src/api/store/product-helper/products/route.js +137 -7
  4. package/.medusa/server/src/api/store/product-helper/products/validators.js +11 -1
  5. package/.medusa/server/src/providers/filter-providers/availability-provider.js +53 -67
  6. package/.medusa/server/src/providers/filter-providers/base-filter-provider.js +1 -19
  7. package/.medusa/server/src/providers/filter-providers/base-product-provider.js +37 -100
  8. package/.medusa/server/src/providers/filter-providers/category-provider.js +15 -34
  9. package/.medusa/server/src/providers/filter-providers/collection-provider.js +15 -32
  10. package/.medusa/server/src/providers/filter-providers/index.js +13 -49
  11. package/.medusa/server/src/providers/filter-providers/metadata-provider.js +43 -58
  12. package/.medusa/server/src/providers/filter-providers/price-range-provider.js +66 -79
  13. package/.medusa/server/src/providers/filter-providers/promotion-provider.js +106 -169
  14. package/.medusa/server/src/providers/filter-providers/promotion-window-provider.js +53 -93
  15. package/.medusa/server/src/providers/filter-providers/rating-provider.js +47 -70
  16. package/.medusa/server/src/services/dynamic-filter-service.js +822 -736
  17. package/.medusa/server/src/services/filter-provider-loader.js +91 -139
  18. package/.medusa/server/src/services/filter-provider-registry.js +8 -107
  19. package/.medusa/server/src/services/product-filter-service.js +183 -172
  20. package/.medusa/server/src/shared/product-metadata/utils.js +66 -116
  21. package/.medusa/server/src/utils/query-builders/product-filters.js +89 -111
  22. package/.medusa/server/src/utils/query-parser.js +24 -76
  23. package/.medusa/server/src/workflows/add-to-wishlist.js +12 -26
  24. package/.medusa/server/src/workflows/get-wishlist.js +53 -51
  25. package/.medusa/server/src/workflows/remove-from-wishlist.js +3 -8
  26. package/package.json +1 -1
@@ -2,86 +2,63 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RatingFilterProvider = void 0;
4
4
  const base_filter_provider_1 = require("./base-filter-provider");
5
- /**
6
- * Filter provider for filtering products by rating.
7
- *
8
- * Handles rating filtering with min/max values. Only applies
9
- * if rating is enabled in plugin options. Requires reviews
10
- * if configured.
11
- *
12
- * @example
13
- * ```ts
14
- * { rating: { min: 4, max: 5, require_reviews: true } }
15
- * ```
16
- */
17
5
  class RatingFilterProvider extends base_filter_provider_1.BaseFilterProvider {
18
6
  apply(filters, value, context) {
19
- // Check if rating is enabled
20
- if (!context?.options?.rating?.enabled) {
7
+ if (!this.isRatingEnabled(context))
21
8
  return filters;
22
- }
23
- if (!value || typeof value !== "object" || Array.isArray(value)) {
9
+ if (!this.isValidInput(value))
24
10
  return filters;
25
- }
26
- const rating = value;
27
- // Get defaults from options
28
- const min = rating.min !== undefined
29
- ? rating.min
30
- : context.options.rating.min ?? 0;
31
- const max = rating.max !== undefined
32
- ? rating.max
33
- : context.options.rating.max ?? 5;
34
- const requireReviews = rating.require_reviews !== undefined
35
- ? rating.require_reviews
36
- : context.options.rating.require_reviews ?? false;
37
- // Build rating filter
38
- // Note: Medusa's RemoteQuery doesn't support comparison operators ($gt, $lt, etc.)
39
- // We can only filter by exact values or use post-query filtering for ranges
40
- // For rating range filtering, we need to:
41
- // 1. Filter products that have reviews (if requireReviews is true)
42
- // 2. Calculate average_rating post-query and filter by range
43
- const ratingFilters = {};
44
- if (requireReviews) {
45
- // Filter products that have at least one review
46
- // Since we can't use $gt, we'll filter for products with count > 0
47
- // This is a limitation - exact filtering requires post-query processing
48
- // For now, we'll skip this filter and handle it post-query
49
- console.warn(`[RatingFilterProvider] Rating range filtering (min: ${min}, max: ${max}) ` +
50
- `requires post-query filtering. Medusa's query system doesn't support comparison operators.`);
51
- }
52
- // Note: Rating range filtering (min/max) requires:
53
- // 1. Fetching products with total_rating_count and total_rating_sum
54
- // 2. Calculating average_rating = total_rating_sum / total_rating_count
55
- // 3. Filtering results post-query by the calculated average
56
- // Return filters unchanged - rating filtering will be handled post-query
57
- // This is a known limitation of Medusa's query system
58
- return filters;
11
+ const input = value;
12
+ const { min, max, requireReviews } = this.getRatingCriteria(input, context);
13
+ // Rating range filtering requires post-query processing
14
+ // because Medusa's RemoteQuery doesn't support comparison operators
15
+ this.logRatingWarning(min, max, requireReviews);
16
+ return filters; // Filtering will be handled post-query
59
17
  }
60
18
  validate(value) {
61
- if (value === undefined || value === null) {
19
+ if (value == null)
62
20
  return;
63
- }
64
- if (typeof value !== "object" || Array.isArray(value)) {
21
+ if (!this.isValidInput(value)) {
65
22
  throw new Error("rating must be an object with min and/or max");
66
23
  }
67
- const rating = value;
68
- if (rating.min !== undefined) {
69
- if (typeof rating.min !== "number" || rating.min < 0 || rating.min > 5) {
70
- throw new Error("rating.min must be a number between 0 and 5");
71
- }
24
+ const input = value;
25
+ this.validateRange(input.min, "min", 0, 5);
26
+ this.validateRange(input.max, "max", 0, 5);
27
+ if (input.min !== undefined && input.max !== undefined && input.min > input.max) {
28
+ throw new Error("rating.min must be ≤ rating.max");
72
29
  }
73
- if (rating.max !== undefined) {
74
- if (typeof rating.max !== "number" || rating.max < 0 || rating.max > 5) {
75
- throw new Error("rating.max must be a number between 0 and 5");
76
- }
77
- }
78
- if (rating.min !== undefined && rating.max !== undefined && rating.min > rating.max) {
79
- throw new Error("rating.min must be less than or equal to rating.max");
30
+ this.validateBoolean(input.require_reviews, "require_reviews");
31
+ }
32
+ isRatingEnabled(context) {
33
+ return context?.options?.rating?.enabled === true;
34
+ }
35
+ isValidInput(value) {
36
+ return value != null && typeof value === "object" && !Array.isArray(value);
37
+ }
38
+ getRatingCriteria(input, context) {
39
+ const ratingOptions = context.options.rating;
40
+ return {
41
+ min: input.min ?? ratingOptions.min ?? 0,
42
+ max: input.max ?? ratingOptions.max ?? 5,
43
+ requireReviews: input.require_reviews ?? ratingOptions.require_reviews ?? false
44
+ };
45
+ }
46
+ logRatingWarning(min, max, requireReviews) {
47
+ console.warn(`[RatingFilterProvider] Rating range filtering (min: ${min}, max: ${max}) ` +
48
+ `requires post-query filtering. Medusa's query system doesn't support comparison operators.`);
49
+ }
50
+ validateRange(value, field, minRange, maxRange) {
51
+ if (value === undefined)
52
+ return;
53
+ if (typeof value !== "number" || value < minRange || value > maxRange) {
54
+ throw new Error(`rating.${field} must be a number between ${minRange} and ${maxRange}`);
80
55
  }
81
- if (rating.require_reviews !== undefined) {
82
- if (typeof rating.require_reviews !== "boolean") {
83
- throw new Error("rating.require_reviews must be a boolean");
84
- }
56
+ }
57
+ validateBoolean(value, field) {
58
+ if (value === undefined)
59
+ return;
60
+ if (typeof value !== "boolean") {
61
+ throw new Error(`rating.${field} must be a boolean`);
85
62
  }
86
63
  }
87
64
  }
@@ -89,4 +66,4 @@ exports.RatingFilterProvider = RatingFilterProvider;
89
66
  RatingFilterProvider.identifier = "rating";
90
67
  RatingFilterProvider.displayName = "Rating Filter";
91
68
  RatingFilterProvider.description = "Filters products by rating (min/max)";
92
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmF0aW5nLXByb3ZpZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL3Byb3ZpZGVycy9maWx0ZXItcHJvdmlkZXJzL3JhdGluZy1wcm92aWRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxpRUFBK0U7QUFFL0U7Ozs7Ozs7Ozs7O0dBV0c7QUFDSCxNQUFhLG9CQUFxQixTQUFRLHlDQUFrQjtJQUsxRCxLQUFLLENBQ0gsT0FBZ0MsRUFDaEMsS0FBYyxFQUNkLE9BQXVCO1FBRXZCLDZCQUE2QjtRQUM3QixJQUFJLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLENBQUM7WUFDdkMsT0FBTyxPQUFPLENBQUE7UUFDaEIsQ0FBQztRQUVELElBQUksQ0FBQyxLQUFLLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUNoRSxPQUFPLE9BQU8sQ0FBQTtRQUNoQixDQUFDO1FBRUQsTUFBTSxNQUFNLEdBQUcsS0FJZCxDQUFBO1FBRUQsNEJBQTRCO1FBQzVCLE1BQU0sR0FBRyxHQUNQLE1BQU0sQ0FBQyxHQUFHLEtBQUssU0FBUztZQUN0QixDQUFDLENBQUMsTUFBTSxDQUFDLEdBQUc7WUFDWixDQUFDLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQTtRQUVyQyxNQUFNLEdBQUcsR0FDUCxNQUFNLENBQUMsR0FBRyxLQUFLLFNBQVM7WUFDdEIsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHO1lBQ1osQ0FBQyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUE7UUFFckMsTUFBTSxjQUFjLEdBQ2xCLE1BQU0sQ0FBQyxlQUFlLEtBQUssU0FBUztZQUNsQyxDQUFDLENBQUMsTUFBTSxDQUFDLGVBQWU7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
69
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmF0aW5nLXByb3ZpZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL3Byb3ZpZGVycy9maWx0ZXItcHJvdmlkZXJzL3JhdGluZy1wcm92aWRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxpRUFBK0U7QUFRL0UsTUFBYSxvQkFBcUIsU0FBUSx5Q0FBa0I7SUFLMUQsS0FBSyxDQUFDLE9BQWdDLEVBQUUsS0FBYyxFQUFFLE9BQXVCO1FBQzdFLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQztZQUFFLE9BQU8sT0FBTyxDQUFBO1FBQ2xELElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQztZQUFFLE9BQU8sT0FBTyxDQUFBO1FBRTdDLE1BQU0sS0FBSyxHQUFHLEtBQW9CLENBQUE7UUFDbEMsTUFBTSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsY0FBYyxFQUFFLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEtBQUssRUFBRSxPQUFRLENBQUMsQ0FBQTtRQUU1RSx3REFBd0Q7UUFDeEQsb0VBQW9FO1FBQ3BFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLGNBQWMsQ0FBQyxDQUFBO1FBRS9DLE9BQU8sT0FBTyxDQUFBLENBQUMsdUNBQXVDO0lBQ3hELENBQUM7SUFFRCxRQUFRLENBQUMsS0FBYztRQUNyQixJQUFJLEtBQUssSUFBSSxJQUFJO1lBQUUsT0FBTTtRQUV6QixJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQzlCLE1BQU0sSUFBSSxLQUFLLENBQUMsOENBQThDLENBQUMsQ0FBQTtRQUNqRSxDQUFDO1FBRUQsTUFBTSxLQUFLLEdBQUcsS0FBb0IsQ0FBQTtRQUVsQyxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLENBQUMs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