medusa-product-helper 0.0.13 → 0.0.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 (29) 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 +112 -0
  4. package/.medusa/server/src/api/store/product-helper/products/validators.js +3 -1
  5. package/.medusa/server/src/config/product-helper-options.js +15 -1
  6. package/.medusa/server/src/index.js +101 -0
  7. package/.medusa/server/src/providers/filter-providers/availability-provider.js +82 -0
  8. package/.medusa/server/src/providers/filter-providers/base-filter-provider.js +14 -0
  9. package/.medusa/server/src/providers/filter-providers/base-product-provider.js +59 -0
  10. package/.medusa/server/src/providers/filter-providers/category-provider.js +36 -0
  11. package/.medusa/server/src/providers/filter-providers/collection-provider.js +36 -0
  12. package/.medusa/server/src/providers/filter-providers/index.js +58 -0
  13. package/.medusa/server/src/providers/filter-providers/metadata-provider.js +69 -0
  14. package/.medusa/server/src/providers/filter-providers/price-range-provider.js +95 -0
  15. package/.medusa/server/src/providers/filter-providers/promotion-provider.js +134 -0
  16. package/.medusa/server/src/providers/filter-providers/promotion-window-provider.js +85 -0
  17. package/.medusa/server/src/providers/filter-providers/rating-provider.js +69 -0
  18. package/.medusa/server/src/services/dynamic-filter-service.js +525 -0
  19. package/.medusa/server/src/services/filter-provider-loader.js +107 -0
  20. package/.medusa/server/src/services/filter-provider-registry.js +43 -0
  21. package/.medusa/server/src/services/product-filter-service.js +183 -0
  22. package/.medusa/server/src/shared/product-metadata/utils.js +66 -116
  23. package/.medusa/server/src/utils/query-builders/product-filters.js +89 -111
  24. package/.medusa/server/src/utils/query-parser.js +51 -0
  25. package/.medusa/server/src/workflows/add-to-wishlist.js +12 -26
  26. package/.medusa/server/src/workflows/get-wishlist.js +53 -51
  27. package/.medusa/server/src/workflows/remove-from-wishlist.js +3 -8
  28. package/README.md +89 -0
  29. package/package.json +3 -3
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PriceRangeFilterProvider = void 0;
4
+ const base_filter_provider_1 = require("./base-filter-provider");
5
+ class PriceRangeFilterProvider extends base_filter_provider_1.BaseFilterProvider {
6
+ apply(filters, value, context) {
7
+ const priceRange = this.getPriceRange(value, context);
8
+ if (!priceRange || (priceRange.min === undefined && priceRange.max === undefined)) {
9
+ return filters;
10
+ }
11
+ filters.__price_range_filter__ = priceRange;
12
+ return filters;
13
+ }
14
+ validate(value) {
15
+ if (value == null)
16
+ return;
17
+ if (!this.isValidPriceRangeObject(value)) {
18
+ throw new Error("price_range must be an object with min and/or max");
19
+ }
20
+ const range = value;
21
+ if (range.min !== undefined && !this.isValidMin(range.min)) {
22
+ throw new Error("price_range.min must be a non-negative number");
23
+ }
24
+ if (range.max !== undefined && !this.isValidMax(range.max)) {
25
+ throw new Error("price_range.max must be a non-negative number");
26
+ }
27
+ if (range.min !== undefined && range.max !== undefined && range.min > range.max) {
28
+ throw new Error("price_range.min must be less than or equal to price_range.max");
29
+ }
30
+ if (range.currency_code !== undefined && !this.isValidCurrencyCode(range.currency_code)) {
31
+ throw new Error("price_range.currency_code must be a 3-character ISO currency code");
32
+ }
33
+ }
34
+ getPriceRange(value, context) {
35
+ // Try to get explicit price range
36
+ const explicitRange = this.parseExplicitRange(value);
37
+ if (explicitRange)
38
+ return explicitRange;
39
+ // Fall back to default from options
40
+ return this.getDefaultRange(context);
41
+ }
42
+ parseExplicitRange(value) {
43
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
44
+ return undefined;
45
+ }
46
+ const range = value;
47
+ if (range.min === undefined && range.max === undefined) {
48
+ return undefined;
49
+ }
50
+ const min = this.parseNumber(range.min);
51
+ const max = this.parseNumber(range.max);
52
+ if (min === undefined && max === undefined) {
53
+ return undefined;
54
+ }
55
+ return {
56
+ min,
57
+ max,
58
+ currency_code: typeof range.currency_code === "string" ? range.currency_code : undefined
59
+ };
60
+ }
61
+ parseNumber(value) {
62
+ if (value === undefined || value === null)
63
+ return undefined;
64
+ const num = typeof value === "string" ? Number(value) : value;
65
+ return typeof num === "number" && !isNaN(num) && num >= 0 ? num : undefined;
66
+ }
67
+ getDefaultRange(context) {
68
+ const defaultRange = context?.options?.default_price_range;
69
+ if (!defaultRange || (defaultRange.min === null && defaultRange.max === null)) {
70
+ return undefined;
71
+ }
72
+ return {
73
+ min: defaultRange.min ?? undefined,
74
+ max: defaultRange.max ?? undefined,
75
+ currency_code: defaultRange.currency_code
76
+ };
77
+ }
78
+ isValidPriceRangeObject(value) {
79
+ return value != null && typeof value === "object" && !Array.isArray(value);
80
+ }
81
+ isValidMin(min) {
82
+ return typeof min === "number" && min >= 0;
83
+ }
84
+ isValidMax(max) {
85
+ return typeof max === "number" && max >= 0;
86
+ }
87
+ isValidCurrencyCode(code) {
88
+ return typeof code === "string" && code.length === 3;
89
+ }
90
+ }
91
+ exports.PriceRangeFilterProvider = PriceRangeFilterProvider;
92
+ PriceRangeFilterProvider.identifier = "price_range";
93
+ PriceRangeFilterProvider.displayName = "Price Range Filter";
94
+ PriceRangeFilterProvider.description = "Filters products by price range (min/max)";
95
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJpY2UtcmFuZ2UtcHJvdmlkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvcHJvdmlkZXJzL2ZpbHRlci1wcm92aWRlcnMvcHJpY2UtcmFuZ2UtcHJvdmlkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsaUVBQStFO0FBYy9FLE1BQWEsd0JBQXlCLFNBQVEseUNBQWtCO0lBSzlELEtBQUssQ0FBQyxPQUFnQyxFQUFFLEtBQWMsRUFBRSxPQUF1QjtRQUM3RSxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQTtRQUVyRCxJQUFJLENBQUMsVUFBVSxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsS0FBSyxTQUFTLElBQUksVUFBVSxDQUFDLEdBQUcsS0FBSyxTQUFTLENBQUMsRUFBRSxDQUFDO1lBQ2xGLE9BQU8sT0FBTyxDQUFBO1FBQ2hCLENBQUM7UUFFRCxPQUFPLENBQUMsc0JBQXNCLEdBQUcsVUFBVSxDQUFBO1FBQzNDLE9BQU8sT0FBTyxDQUFBO0lBQ2hCLENBQUM7SUFFRCxRQUFRLENBQUMsS0FBYztRQUNyQixJQUFJLEtBQUssSUFBSSxJQUFJO1lBQUUsT0FBTTtRQUV6QixJQUFJLENBQUMsSUFBSSxDQUFDLHVCQUF1QixDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDekMsTUFBTSxJQUFJLEtBQUssQ0FBQyxtREFBbUQsQ0FBQyxDQUFBO1FBQ3RFLENBQUM7UUFFRCxNQUFNLEtBQUssR0FBRyxLQUF3QixDQUFBO1FBRXRDLElBQUksS0FBSyxDQUFDLEdBQUcsS0FBSyxTQUFTLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQzNELE1BQU0sSUFBSSxLQUFLLENBQUMsK0NBQStDLENBQUMsQ0FBQTtRQUNsRSxDQUFDO1FBRUQsSUFBSSxLQUFLLENBQUMsR0FBRyxL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
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PromotionFilterProvider = void 0;
4
+ const base_filter_provider_1 = require("./base-filter-provider");
5
+ const VALID_PROMOTION_TYPES = [
6
+ "amount_off_product", "percentage_off_product", "amount_off_order",
7
+ "percentage_off_order", "buy_x_get_y", "free_shipping"
8
+ ];
9
+ class PromotionFilterProvider extends base_filter_provider_1.BaseFilterProvider {
10
+ apply(filters, value) {
11
+ if (!this.isValidFilterInput(value))
12
+ return filters;
13
+ const filterCriteria = this.buildCriteria(value);
14
+ if (!this.hasValidCriteria(filterCriteria)) {
15
+ return filters;
16
+ }
17
+ filters.__promotion_filter__ = filterCriteria;
18
+ return filters;
19
+ }
20
+ validate(value) {
21
+ if (value == null)
22
+ return;
23
+ if (!this.isValidFilterInput(value)) {
24
+ throw new Error(`promotion filter must be an object, got ${Array.isArray(value) ? "array" : typeof value}`);
25
+ }
26
+ const filter = value;
27
+ const minDiscount = this.validatePercentage(filter.min_discount_percentage, "min_discount_percentage");
28
+ const maxDiscount = this.validatePercentage(filter.max_discount_percentage, "max_discount_percentage");
29
+ if (minDiscount !== undefined && maxDiscount !== undefined && minDiscount > maxDiscount) {
30
+ throw new Error(`promotion.min_discount_percentage must be ≤ max_discount_percentage, got min=${minDiscount}, max=${maxDiscount}`);
31
+ }
32
+ this.validatePromotionType(filter.promotion_type);
33
+ this.validateDate(filter.starts_at, "starts_at");
34
+ this.validateDate(filter.ends_at, "ends_at");
35
+ this.validateString(filter.status, "status");
36
+ this.validateBooleanOrString(filter.include_open_ended, "include_open_ended");
37
+ }
38
+ isValidFilterInput(value) {
39
+ return value != null && typeof value === "object" && !Array.isArray(value);
40
+ }
41
+ buildCriteria(input) {
42
+ const criteria = {
43
+ include_open_ended: input.include_open_ended ?? true
44
+ };
45
+ const minDiscount = this.parsePercentage(input.min_discount_percentage);
46
+ if (minDiscount !== undefined)
47
+ criteria.min_discount_percentage = minDiscount;
48
+ const maxDiscount = this.parsePercentage(input.max_discount_percentage);
49
+ if (maxDiscount !== undefined)
50
+ criteria.max_discount_percentage = maxDiscount;
51
+ if (input.promotion_type)
52
+ criteria.promotion_type = input.promotion_type;
53
+ if (input.status)
54
+ criteria.status = input.status;
55
+ if (input.starts_at) {
56
+ criteria.starts_at = input.starts_at instanceof Date ? input.starts_at : new Date(input.starts_at);
57
+ }
58
+ if (input.ends_at) {
59
+ criteria.ends_at = input.ends_at instanceof Date ? input.ends_at : new Date(input.ends_at);
60
+ }
61
+ return criteria;
62
+ }
63
+ parsePercentage(value) {
64
+ if (value === undefined)
65
+ return undefined;
66
+ const num = typeof value === "string" ? Number(value) : value;
67
+ if (typeof num !== "number" || isNaN(num) || num < 0 || num > 100) {
68
+ return undefined;
69
+ }
70
+ return num;
71
+ }
72
+ hasValidCriteria(criteria) {
73
+ return !!(criteria.min_discount_percentage !== undefined ||
74
+ criteria.max_discount_percentage !== undefined ||
75
+ criteria.promotion_type ||
76
+ criteria.starts_at ||
77
+ criteria.ends_at ||
78
+ criteria.status);
79
+ }
80
+ validatePercentage(value, field) {
81
+ if (value === undefined)
82
+ return undefined;
83
+ const num = typeof value === "string" ? Number(value) : value;
84
+ if (typeof num !== "number" || isNaN(num)) {
85
+ throw new Error(`promotion.${field} must be a number, got ${typeof value}`);
86
+ }
87
+ if (num < 0 || num > 100) {
88
+ throw new Error(`promotion.${field} must be between 0 and 100, got ${num}`);
89
+ }
90
+ return num;
91
+ }
92
+ validatePromotionType(value) {
93
+ if (value === undefined)
94
+ return;
95
+ if (typeof value !== "string") {
96
+ throw new Error(`promotion.promotion_type must be a string, got ${typeof value}`);
97
+ }
98
+ if (!VALID_PROMOTION_TYPES.includes(value)) {
99
+ throw new Error(`promotion.promotion_type must be one of: ${VALID_PROMOTION_TYPES.join(", ")}, got "${value}"`);
100
+ }
101
+ }
102
+ validateDate(value, field) {
103
+ if (value === undefined)
104
+ return;
105
+ if (!(value instanceof Date) && typeof value !== "string") {
106
+ throw new Error(`promotion.${field} must be a Date or ISO string, got ${typeof value}`);
107
+ }
108
+ if (typeof value === "string") {
109
+ const date = new Date(value);
110
+ if (isNaN(date.getTime())) {
111
+ throw new Error(`promotion.${field} must be a valid ISO date string, got "${value}"`);
112
+ }
113
+ }
114
+ }
115
+ validateString(value, field) {
116
+ if (value === undefined)
117
+ return;
118
+ if (typeof value !== "string") {
119
+ throw new Error(`promotion.${field} must be a string, got ${typeof value}`);
120
+ }
121
+ }
122
+ validateBooleanOrString(value, field) {
123
+ if (value === undefined)
124
+ return;
125
+ if (typeof value !== "boolean" && typeof value !== "string") {
126
+ throw new Error(`promotion.${field} must be a boolean or string, got ${typeof value}`);
127
+ }
128
+ }
129
+ }
130
+ exports.PromotionFilterProvider = PromotionFilterProvider;
131
+ PromotionFilterProvider.identifier = "promotion";
132
+ PromotionFilterProvider.displayName = "Promotion Filter";
133
+ PromotionFilterProvider.description = "Filters products by Medusa promotions with discount percentage support";
134
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvbW90aW9uLXByb3ZpZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL3Byb3ZpZGVycy9maWx0ZXItcHJvdmlkZXJzL3Byb21vdGlvbi1wcm92aWRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxpRUFBK0U7QUFzQi9FLE1BQU0scUJBQXFCLEdBQUc7SUFDNUIsb0JBQW9CLEVBQUUsd0JBQXdCLEVBQUUsa0JBQWtCO0lBQ2xFLHNCQUFzQixFQUFFLGFBQWEsRUFBRSxlQUFlO0NBQzlDLENBQUE7QUFFVixNQUFhLHVCQUF3QixTQUFRLHlDQUFrQjtJQUs3RCxLQUFLLENBQUMsT0FBZ0MsRUFBRSxLQUFjO1FBQ3BELElBQUksQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsS0FBSyxDQUFDO1lBQUUsT0FBTyxPQUFPLENBQUE7UUFFbkQsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUE2QixDQUFDLENBQUE7UUFFeEUsSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxjQUFjLENBQUMsRUFBRSxDQUFDO1lBQzNDLE9BQU8sT0FBTyxDQUFBO1FBQ2hCLENBQUM7UUFFRCxPQUFPLENBQUMsb0JBQW9CLEdBQUcsY0FBYyxDQUFBO1FBQzdDLE9BQU8sT0FBTyxDQUFBO0lBQ2hCLENBQUM7SUFFRCxRQUFRLENBQUMsS0FBYztRQUNyQixJQUFJLEtBQUssSUFBSSxJQUFJO1lBQUUsT0FBTTtRQUV6QixJQUFJLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDcEMsTUFBTSxJQUFJLEtBQUssQ0FBQywyQ0FBMkMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxPQUFPLEtBQUssRUFBRSxDQUFDLENBQUE7UUFDN0csQ0FBQztRQUVELE1BQU0sTUFBTSxHQUFHLEtB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
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PromotionWindowFilterProvider = void 0;
4
+ const base_filter_provider_1 = require("./base-filter-provider");
5
+ class PromotionWindowFilterProvider extends base_filter_provider_1.BaseFilterProvider {
6
+ apply(filters, value, context) {
7
+ if (!this.isValidInput(value))
8
+ return filters;
9
+ const input = value;
10
+ const metadataFilters = this.buildMetadataFilters(input, context);
11
+ if (Object.keys(metadataFilters).length === 0) {
12
+ return filters;
13
+ }
14
+ // Note: Medusa's RemoteQuery doesn't support MongoDB-style operators ($gte, $lte, $or)
15
+ // Date range filtering needs post-query processing or a different approach
16
+ console.warn(`[PromotionWindowFilterProvider] Date range filtering in metadata is limited. ` +
17
+ `Only exact date matches are supported. For date ranges, consider post-query filtering.`);
18
+ return {
19
+ ...filters,
20
+ metadata: {
21
+ ...(filters.metadata || {}),
22
+ ...metadataFilters
23
+ }
24
+ };
25
+ }
26
+ validate(value) {
27
+ if (value == null)
28
+ return;
29
+ if (!this.isValidInput(value)) {
30
+ throw new Error("promotion_window must be an object");
31
+ }
32
+ const input = value;
33
+ this.validateDateOrString(input.start, "start");
34
+ this.validateDateOrString(input.end, "end");
35
+ this.validateDateOrString(input.activeOn, "activeOn");
36
+ this.validateBoolean(input.includeOpen, "includeOpen");
37
+ }
38
+ isValidInput(value) {
39
+ return value != null && typeof value === "object" && !Array.isArray(value);
40
+ }
41
+ buildMetadataFilters(input, context) {
42
+ const startKey = context?.options?.promotion_window?.start_metadata_key || "promotion_start";
43
+ const endKey = context?.options?.promotion_window?.end_metadata_key || "promotion_end";
44
+ const includeOpen = input.includeOpen ?? context?.options?.promotion_window?.treat_open_ended_as_active ?? true;
45
+ const metadataFilters = {};
46
+ if (input.start || input.end) {
47
+ if (input.start) {
48
+ metadataFilters[startKey] = this.toDate(input.start).toISOString();
49
+ }
50
+ if (input.end) {
51
+ metadataFilters[endKey] = this.toDate(input.end).toISOString();
52
+ }
53
+ }
54
+ else if (input.activeOn) {
55
+ const activeDate = this.toDate(input.activeOn);
56
+ metadataFilters[startKey] = activeDate.toISOString();
57
+ if (!includeOpen) {
58
+ metadataFilters[endKey] = activeDate.toISOString();
59
+ }
60
+ }
61
+ return metadataFilters;
62
+ }
63
+ toDate(value) {
64
+ return value instanceof Date ? value : new Date(value);
65
+ }
66
+ validateDateOrString(value, field) {
67
+ if (value === undefined)
68
+ return;
69
+ if (!(value instanceof Date) && typeof value !== "string") {
70
+ throw new Error(`promotion_window.${field} must be a Date or ISO string`);
71
+ }
72
+ }
73
+ validateBoolean(value, field) {
74
+ if (value === undefined)
75
+ return;
76
+ if (typeof value !== "boolean") {
77
+ throw new Error(`promotion_window.${field} must be a boolean`);
78
+ }
79
+ }
80
+ }
81
+ exports.PromotionWindowFilterProvider = PromotionWindowFilterProvider;
82
+ PromotionWindowFilterProvider.identifier = "promotion_window";
83
+ PromotionWindowFilterProvider.displayName = "Promotion Window Filter";
84
+ PromotionWindowFilterProvider.description = "Filters products by promotion date windows using metadata";
85
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvbW90aW9uLXdpbmRvdy1wcm92aWRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9wcm92aWRlcnMvZmlsdGVyLXByb3ZpZGVycy9wcm9tb3Rpb24td2luZG93LXByb3ZpZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLGlFQUErRTtBQVMvRSxNQUFhLDZCQUE4QixTQUFRLHlDQUFrQjtJQUtuRSxLQUFLLENBQUMsT0FBZ0MsRUFBRSxLQUFjLEVBQUUsT0FBdUI7UUFDN0UsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDO1lBQUUsT0FBTyxPQUFPLENBQUE7UUFFN0MsTUFBTSxLQUFLLEdBQUcsS0FBNkIsQ0FBQTtRQUMzQyxNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFBO1FBRWpFLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDOUMsT0FBTyxPQUFPLENBQUE7UUFDaEIsQ0FBQztRQUVELHVGQUF1RjtRQUN2RiwyRUFBMkU7UUFDM0UsT0FBTyxDQUFDLElBQUksQ0FDViwrRUFBK0U7WUFDL0Usd0ZBQXdGLENBQ3pGLENBQUE7UUFFRCxPQUFPO1lBQ0wsR0FBRyxPQUFPO1lBQ1YsUUFBUSxFQUFFO2dCQUNSLEdBQUcsQ0FBQyxPQUFPLENBQUMsUUFBbUMsSUFBSSxFQUFFLENBQUM7Z0JBQ3RELEdBQUcsZUFBZTthQUNuQjtTQUNGLENBQUE7SUFDSCxDQUFDO0lBRUQsUUFBUSxDQUFDLEtBQWM7UUFDckIsSUFBSSxLQUFLLElBQUksSUFBSTtZQUFFLE9BQU07UUFFekIsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUM5QixNQUFNLElBQUksS0FBSyxDQUFDLG9DQUFvQyxDQUFDLENB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
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RatingFilterProvider = void 0;
4
+ const base_filter_provider_1 = require("./base-filter-provider");
5
+ class RatingFilterProvider extends base_filter_provider_1.BaseFilterProvider {
6
+ apply(filters, value, context) {
7
+ if (!this.isRatingEnabled(context))
8
+ return filters;
9
+ if (!this.isValidInput(value))
10
+ 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
17
+ }
18
+ validate(value) {
19
+ if (value == null)
20
+ return;
21
+ if (!this.isValidInput(value)) {
22
+ throw new Error("rating must be an object with min and/or max");
23
+ }
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");
29
+ }
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}`);
55
+ }
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`);
62
+ }
63
+ }
64
+ }
65
+ exports.RatingFilterProvider = RatingFilterProvider;
66
+ RatingFilterProvider.identifier = "rating";
67
+ RatingFilterProvider.displayName = "Rating Filter";
68
+ RatingFilterProvider.description = "Filters products by rating (min/max)";
69
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmF0aW5nLXByb3ZpZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL3Byb3ZpZGVycy9maWx0ZXItcHJvdmlkZXJzL3JhdGluZy1wcm92aWRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxpRUFBK0U7QUFRL0UsTUFBYSxvQkFBcUIsU0FBUSx5Q0FBa0I7SUFLMUQsS0FBSyxDQUFDLE9BQWdDLEVBQUUsS0FBYyxFQUFFLE9BQXVCO1FBQzdFLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQztZQUFFLE9BQU8sT0FBTyxDQUFBO1FBQ2xELElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQztZQUFFLE9BQU8sT0FBTyxDQUFBO1FBRTdDLE1BQU0sS0FBSyxHQUFHLEtBQW9CLENBQUE7UUFDbEMsTUFBTSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsY0FBYyxFQUFFLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEtBQUssRUFBRSxPQUFRLENBQUMsQ0FBQTtRQUU1RSx3REFBd0Q7UUFDeEQsb0VBQW9FO1FBQ3BFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLGNBQWMsQ0FBQyxDQUFBO1FBRS9DLE9BQU8sT0FBTyxDQUFBLENBQUMsdUNBQXVDO0lBQ3hELENBQUM7SUFFRCxRQUFRLENBQUMsS0FBYztRQUNyQixJQUFJLEtBQUssSUFBSSxJQUFJO1lBQUUsT0FBTTtRQUV6QixJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQzlCLE1BQU0sSUFBSSxLQUFLLENBQUMsOENBQThDLENBQUMsQ0FBQTtRQUNqRSxDQUFDO1FBRUQsTUFBTSxLQUFLLEdBQUcsS0FBb0IsQ0FBQTtRQUVsQyxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQTtRQUMxQyxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQTtRQUUxQyxJQUFJLEtBQUssQ0FBQyxHQUFHLEtBQUssU0FBUyxJQUFJLEtBQUssQ0FBQyxHQUFHLEtBQUssU0FBUyxJQUFJLEtBQUssQ0FBQyxHQUFHLEdBQUcsS0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDO1lBQ2hGLE1BQU0sSUFBSSxLQUFLLENBQUMsaUNBQWlDLENBQUMsQ0FBQTtRQUNwRCxDQUFDO1FBRUQsSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsZUFBZSxFQUFFLGlCQUFpQixDQUFDLENBQUE7SUFDaEUsQ0FBQztJQUVPLGVBQWUsQ0FBQyxPQUF1QjtRQUM3QyxPQUFPLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE9BQU8sS0FBSyxJQUFJLENBQUE7SUFDbkQsQ0FBQztJQUVPLFlBQVksQ0FBQyxLQUFjO1FBQ2pDLE9BQU8sS0FBSyxJQUFJLElBQUksSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFBO0lBQzVFLENBQUM7SUFFTyxpQkFBaUIsQ0FBQyxLQUFrQixFQUFFLE9BQXNCO1FBQ2xFLE1BQU0sYUFBYSxHQUFHLE9BQU8sQ0FBQyxPQUFRLENBQUMsTUFBTyxDQUFBO1FBRTlDLE9BQU87WUFDTCxHQUFHLEVBQUUsS0FBSyxDQUFDLEdBQUcsSUFBSSxhQUFhLENBQUMsR0FBRyxJQUFJLENBQUM7WUFDeEMsR0FBRyxFQUFFLEtBQUssQ0FBQyxHQUFHLElBQUksYUFBYSxDQUFDLEdBQUcsSUFBSSxDQUFDO1lBQ3hDLGNBQWMsRUFBRSxLQUFLLENBQUMsZUFBZSxJQUFJLGFBQWEsQ0FBQyxlQUFlLElBQUksS0FBSztTQUNoRixDQUFBO0lBQ0gsQ0FBQztJQUVPLGdCQUFnQixDQUFDLEdBQVcsRUFBRSxHQUFXLEVBQUUsY0FBdUI7UUFDeEUsT0FBTyxDQUFDLElBQUksQ0FDVix1REFBdUQsR0FBRyxVQUFVLEdBQUcsSUFBSTtZQUMzRSw0RkFBNEYsQ0FDN0YsQ0FBQTtJQUNILENBQUM7SUFFTyxhQUFhLENBQUMsS0FBYyxFQUFFLEtBQWEsRUFBRSxRQUFnQixFQUFFLFFBQWdCO1FBQ3JGLElBQUksS0FBSyxLQUFLLFNBQVM7WUFBRSxPQUFNO1FBRS9CLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLEtBQUssR0FBRyxRQUFRLElBQUksS0FBSyxHQUFHLFFBQVEsRUFBRSxDQUFDO1lBQ3RFLE1BQU0sSUFBSSxLQUFLLENBQUMsVUFBVSxLQUFLLDZCQUE2QixRQUFRLFFBQVEsUUFBUSxFQUFFLENBQUMsQ0FBQTtRQUN6RixDQUFDO0lBQ0gsQ0FBQztJQUVPLGVBQWUsQ0FBQyxLQUFjLEVBQUUsS0FBYTtRQUNuRCxJQUFJLEtBQUssS0FBSyxTQUFTO1lBQUUsT0FBTTtRQUUvQixJQUFJLE9BQU8sS0FBSyxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQy9CLE1BQU0sSUFBSSxLQUFLLENBQUMsVUFBVSxLQUFLLG9CQUFvQixDQUFDLENBQUE7UUFDdEQsQ0FBQztJQUNILENBQUM7O0FBN0VILG9EQThFQztBQTdFaUIsK0JBQVUsR0FBRyxRQUFRLENBQUE7QUFDckIsZ0NBQVcsR0FBRyxlQUFlLENBQUE7QUFDN0IsZ0NBQVcsR0FBRyxzQ0FBc0MsQ0FBQSJ9