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
@@ -6,45 +6,35 @@ const react = require("react");
6
6
  const reactQuery = require("@tanstack/react-query");
7
7
  const METADATA_FIELD_TYPES = ["number", "text", "file", "bool"];
8
8
  const VALID_FIELD_TYPES = new Set(METADATA_FIELD_TYPES);
9
+ const BOOLEAN_TRUES = /* @__PURE__ */ new Set(["true", "1", "yes", "y", "on"]);
10
+ const BOOLEAN_FALSES = /* @__PURE__ */ new Set(["false", "0", "no", "n", "off"]);
9
11
  function normalizeMetadataDescriptors(input) {
10
- if (!Array.isArray(input)) {
11
- return [];
12
- }
12
+ if (!Array.isArray(input)) return [];
13
13
  const seenKeys = /* @__PURE__ */ new Set();
14
- const normalized = [];
15
- for (const item of input) {
16
- if (!item || typeof item !== "object") {
17
- continue;
18
- }
19
- const key = getNormalizedKey(item.key);
20
- if (!key || seenKeys.has(key)) {
21
- continue;
22
- }
23
- const type = getNormalizedType(item.type);
24
- if (!type) {
25
- continue;
26
- }
27
- const label = getNormalizedLabel(item.label);
28
- const filterable = typeof item.filterable === "boolean" ? item.filterable : Boolean(item.filterable);
29
- normalized.push({
14
+ return input.filter(
15
+ (item) => item && typeof item === "object"
16
+ ).map((item) => {
17
+ const key = normalizeKey(item.key);
18
+ const type = normalizeType(item.type);
19
+ const label = normalizeLabel(item.label);
20
+ const filterable = !!item.filterable;
21
+ return { key, type, label, filterable };
22
+ }).filter(({ key, type }) => key && type && !seenKeys.has(key)).map(({ key, type, label, filterable }) => {
23
+ seenKeys.add(key);
24
+ return {
30
25
  key,
31
26
  type,
32
- ...label ? { label } : {},
33
- ...filterable ? { filterable: true } : {}
34
- });
35
- seenKeys.add(key);
36
- }
37
- return normalized;
27
+ ...label && { label },
28
+ ...filterable && { filterable: true }
29
+ };
30
+ });
38
31
  }
39
32
  function buildInitialFormState(descriptors, metadata) {
40
- return descriptors.reduce(
41
- (acc, descriptor) => {
42
- const currentValue = metadata && typeof metadata === "object" ? metadata[descriptor.key] : void 0;
43
- acc[descriptor.key] = normalizeFormValue(descriptor, currentValue);
44
- return acc;
45
- },
46
- {}
47
- );
33
+ const base = metadata && typeof metadata === "object" ? metadata : {};
34
+ return descriptors.reduce((acc, descriptor) => {
35
+ acc[descriptor.key] = normalizeFormValue(descriptor, base[descriptor.key]);
36
+ return acc;
37
+ }, {});
48
38
  }
49
39
  function buildMetadataPayload({
50
40
  descriptors,
@@ -53,13 +43,12 @@ function buildMetadataPayload({
53
43
  }) {
54
44
  const base = originalMetadata && typeof originalMetadata === "object" ? { ...originalMetadata } : {};
55
45
  descriptors.forEach((descriptor) => {
56
- const rawValue = values[descriptor.key];
57
- const coerced = coerceMetadataValue(descriptor, rawValue);
58
- if (typeof coerced === "undefined") {
46
+ const coerced = coerceMetadataValue(descriptor, values[descriptor.key]);
47
+ if (coerced === void 0) {
59
48
  delete base[descriptor.key];
60
- return;
49
+ } else {
50
+ base[descriptor.key] = coerced;
61
51
  }
62
- base[descriptor.key] = coerced;
63
52
  });
64
53
  return base;
65
54
  }
@@ -70,38 +59,27 @@ function hasMetadataChanges({
70
59
  }) {
71
60
  const next = buildMetadataPayload({ descriptors, values, originalMetadata });
72
61
  const prev = originalMetadata && typeof originalMetadata === "object" ? originalMetadata : {};
73
- return descriptors.some((descriptor) => {
74
- const prevValue = prev[descriptor.key];
75
- const nextValue = next[descriptor.key];
76
- return !isDeepEqual(prevValue, nextValue);
77
- });
62
+ return descriptors.some(({ key }) => !isDeepEqual(prev[key], next[key]));
78
63
  }
79
64
  function validateValueForDescriptor(descriptor, value) {
80
65
  if (descriptor.type === "number") {
81
- if (value === "" || value === null || typeof value === "undefined") {
82
- return void 0;
83
- }
84
- const numericValue = typeof value === "number" ? value : Number(String(value).trim());
85
- if (Number.isNaN(numericValue)) {
86
- return "Enter a valid number";
87
- }
66
+ if (value == null || value === "") return void 0;
67
+ const num = typeof value === "number" ? value : Number(String(value).trim());
68
+ return isNaN(num) ? "Enter a valid number" : void 0;
88
69
  }
89
70
  if (descriptor.type === "file") {
90
- if (!value) {
91
- return void 0;
92
- }
71
+ if (!value) return void 0;
93
72
  try {
94
73
  new URL(String(value).trim());
95
- } catch (err) {
74
+ return void 0;
75
+ } catch {
96
76
  return "Enter a valid URL";
97
77
  }
98
78
  }
99
79
  return void 0;
100
80
  }
101
81
  function normalizeFormValue(descriptor, currentValue) {
102
- if (descriptor.type === "bool") {
103
- return Boolean(currentValue);
104
- }
82
+ if (descriptor.type === "bool") return Boolean(currentValue);
105
83
  if ((descriptor.type === "number" || descriptor.type === "text") && typeof currentValue === "number") {
106
84
  return currentValue.toString();
107
85
  }
@@ -111,78 +89,42 @@ function normalizeFormValue(descriptor, currentValue) {
111
89
  return "";
112
90
  }
113
91
  function coerceMetadataValue(descriptor, value) {
114
- if (value === "" || value === null || typeof value === "undefined") {
115
- return void 0;
116
- }
92
+ if (value == null || value === "") return void 0;
117
93
  if (descriptor.type === "bool") {
118
- if (typeof value === "boolean") {
119
- return value;
120
- }
121
- if (typeof value === "number") {
122
- return value !== 0;
123
- }
124
- if (typeof value === "string") {
125
- const normalized = value.trim().toLowerCase();
126
- if (!normalized) {
127
- return void 0;
128
- }
129
- if (["true", "1", "yes", "y", "on"].includes(normalized)) {
130
- return true;
131
- }
132
- if (["false", "0", "no", "n", "off"].includes(normalized)) {
133
- return false;
134
- }
135
- }
94
+ if (typeof value === "boolean") return value;
95
+ if (typeof value === "number") return value !== 0;
96
+ const normalized = String(value).trim().toLowerCase();
97
+ if (!normalized) return void 0;
98
+ if (BOOLEAN_TRUES.has(normalized)) return true;
99
+ if (BOOLEAN_FALSES.has(normalized)) return false;
136
100
  return Boolean(value);
137
101
  }
138
102
  if (descriptor.type === "number") {
139
- if (typeof value === "number") {
140
- return value;
141
- }
142
- const parsed = Number(String(value).trim());
143
- return Number.isNaN(parsed) ? void 0 : parsed;
103
+ const num = typeof value === "number" ? value : Number(String(value).trim());
104
+ return isNaN(num) ? void 0 : num;
144
105
  }
145
106
  return String(value).trim();
146
107
  }
147
- function getNormalizedKey(value) {
148
- if (typeof value !== "string") {
149
- return null;
150
- }
151
- const trimmed = value.trim();
152
- return trimmed.length ? trimmed : null;
108
+ function normalizeKey(value) {
109
+ return typeof value === "string" ? value.trim() || void 0 : void 0;
153
110
  }
154
- function getNormalizedType(value) {
155
- if (typeof value !== "string") {
156
- return null;
157
- }
111
+ function normalizeType(value) {
112
+ if (typeof value !== "string") return void 0;
158
113
  const type = value.trim().toLowerCase();
159
- return VALID_FIELD_TYPES.has(type) ? type : null;
114
+ return VALID_FIELD_TYPES.has(type) ? type : void 0;
160
115
  }
161
- function getNormalizedLabel(value) {
162
- if (typeof value !== "string") {
163
- return void 0;
164
- }
165
- const trimmed = value.trim();
166
- return trimmed.length ? trimmed : void 0;
116
+ function normalizeLabel(value) {
117
+ return typeof value === "string" ? value.trim() || void 0 : void 0;
167
118
  }
168
119
  function isDeepEqual(a, b) {
169
- if (a === b) {
170
- return true;
171
- }
172
- if (typeof a === "object" && typeof b === "object" && a !== null && b !== null) {
173
- const aKeys = Object.keys(a);
174
- const bKeys = Object.keys(b);
175
- if (aKeys.length !== bKeys.length) {
176
- return false;
177
- }
178
- return aKeys.every(
179
- (key) => isDeepEqual(
180
- a[key],
181
- b[key]
182
- )
183
- );
184
- }
185
- return false;
120
+ if (a === b) return true;
121
+ if (!a || !b || typeof a !== "object" || typeof b !== "object") return false;
122
+ const aKeys = Object.keys(a);
123
+ const bKeys = Object.keys(b);
124
+ if (aKeys.length !== bKeys.length) return false;
125
+ return aKeys.every(
126
+ (key) => isDeepEqual(a[key], b[key])
127
+ );
186
128
  }
187
129
  const CONFIG_ENDPOINT = "/admin/product-metadata-config";
188
130
  const QUERY_KEY = ["medusa-product-helper", "metadata-config"];
@@ -5,45 +5,35 @@ import { useState, useEffect, useMemo, useRef } from "react";
5
5
  import { useQuery, useQueryClient } from "@tanstack/react-query";
6
6
  const METADATA_FIELD_TYPES = ["number", "text", "file", "bool"];
7
7
  const VALID_FIELD_TYPES = new Set(METADATA_FIELD_TYPES);
8
+ const BOOLEAN_TRUES = /* @__PURE__ */ new Set(["true", "1", "yes", "y", "on"]);
9
+ const BOOLEAN_FALSES = /* @__PURE__ */ new Set(["false", "0", "no", "n", "off"]);
8
10
  function normalizeMetadataDescriptors(input) {
9
- if (!Array.isArray(input)) {
10
- return [];
11
- }
11
+ if (!Array.isArray(input)) return [];
12
12
  const seenKeys = /* @__PURE__ */ new Set();
13
- const normalized = [];
14
- for (const item of input) {
15
- if (!item || typeof item !== "object") {
16
- continue;
17
- }
18
- const key = getNormalizedKey(item.key);
19
- if (!key || seenKeys.has(key)) {
20
- continue;
21
- }
22
- const type = getNormalizedType(item.type);
23
- if (!type) {
24
- continue;
25
- }
26
- const label = getNormalizedLabel(item.label);
27
- const filterable = typeof item.filterable === "boolean" ? item.filterable : Boolean(item.filterable);
28
- normalized.push({
13
+ return input.filter(
14
+ (item) => item && typeof item === "object"
15
+ ).map((item) => {
16
+ const key = normalizeKey(item.key);
17
+ const type = normalizeType(item.type);
18
+ const label = normalizeLabel(item.label);
19
+ const filterable = !!item.filterable;
20
+ return { key, type, label, filterable };
21
+ }).filter(({ key, type }) => key && type && !seenKeys.has(key)).map(({ key, type, label, filterable }) => {
22
+ seenKeys.add(key);
23
+ return {
29
24
  key,
30
25
  type,
31
- ...label ? { label } : {},
32
- ...filterable ? { filterable: true } : {}
33
- });
34
- seenKeys.add(key);
35
- }
36
- return normalized;
26
+ ...label && { label },
27
+ ...filterable && { filterable: true }
28
+ };
29
+ });
37
30
  }
38
31
  function buildInitialFormState(descriptors, metadata) {
39
- return descriptors.reduce(
40
- (acc, descriptor) => {
41
- const currentValue = metadata && typeof metadata === "object" ? metadata[descriptor.key] : void 0;
42
- acc[descriptor.key] = normalizeFormValue(descriptor, currentValue);
43
- return acc;
44
- },
45
- {}
46
- );
32
+ const base = metadata && typeof metadata === "object" ? metadata : {};
33
+ return descriptors.reduce((acc, descriptor) => {
34
+ acc[descriptor.key] = normalizeFormValue(descriptor, base[descriptor.key]);
35
+ return acc;
36
+ }, {});
47
37
  }
48
38
  function buildMetadataPayload({
49
39
  descriptors,
@@ -52,13 +42,12 @@ function buildMetadataPayload({
52
42
  }) {
53
43
  const base = originalMetadata && typeof originalMetadata === "object" ? { ...originalMetadata } : {};
54
44
  descriptors.forEach((descriptor) => {
55
- const rawValue = values[descriptor.key];
56
- const coerced = coerceMetadataValue(descriptor, rawValue);
57
- if (typeof coerced === "undefined") {
45
+ const coerced = coerceMetadataValue(descriptor, values[descriptor.key]);
46
+ if (coerced === void 0) {
58
47
  delete base[descriptor.key];
59
- return;
48
+ } else {
49
+ base[descriptor.key] = coerced;
60
50
  }
61
- base[descriptor.key] = coerced;
62
51
  });
63
52
  return base;
64
53
  }
@@ -69,38 +58,27 @@ function hasMetadataChanges({
69
58
  }) {
70
59
  const next = buildMetadataPayload({ descriptors, values, originalMetadata });
71
60
  const prev = originalMetadata && typeof originalMetadata === "object" ? originalMetadata : {};
72
- return descriptors.some((descriptor) => {
73
- const prevValue = prev[descriptor.key];
74
- const nextValue = next[descriptor.key];
75
- return !isDeepEqual(prevValue, nextValue);
76
- });
61
+ return descriptors.some(({ key }) => !isDeepEqual(prev[key], next[key]));
77
62
  }
78
63
  function validateValueForDescriptor(descriptor, value) {
79
64
  if (descriptor.type === "number") {
80
- if (value === "" || value === null || typeof value === "undefined") {
81
- return void 0;
82
- }
83
- const numericValue = typeof value === "number" ? value : Number(String(value).trim());
84
- if (Number.isNaN(numericValue)) {
85
- return "Enter a valid number";
86
- }
65
+ if (value == null || value === "") return void 0;
66
+ const num = typeof value === "number" ? value : Number(String(value).trim());
67
+ return isNaN(num) ? "Enter a valid number" : void 0;
87
68
  }
88
69
  if (descriptor.type === "file") {
89
- if (!value) {
90
- return void 0;
91
- }
70
+ if (!value) return void 0;
92
71
  try {
93
72
  new URL(String(value).trim());
94
- } catch (err) {
73
+ return void 0;
74
+ } catch {
95
75
  return "Enter a valid URL";
96
76
  }
97
77
  }
98
78
  return void 0;
99
79
  }
100
80
  function normalizeFormValue(descriptor, currentValue) {
101
- if (descriptor.type === "bool") {
102
- return Boolean(currentValue);
103
- }
81
+ if (descriptor.type === "bool") return Boolean(currentValue);
104
82
  if ((descriptor.type === "number" || descriptor.type === "text") && typeof currentValue === "number") {
105
83
  return currentValue.toString();
106
84
  }
@@ -110,78 +88,42 @@ function normalizeFormValue(descriptor, currentValue) {
110
88
  return "";
111
89
  }
112
90
  function coerceMetadataValue(descriptor, value) {
113
- if (value === "" || value === null || typeof value === "undefined") {
114
- return void 0;
115
- }
91
+ if (value == null || value === "") return void 0;
116
92
  if (descriptor.type === "bool") {
117
- if (typeof value === "boolean") {
118
- return value;
119
- }
120
- if (typeof value === "number") {
121
- return value !== 0;
122
- }
123
- if (typeof value === "string") {
124
- const normalized = value.trim().toLowerCase();
125
- if (!normalized) {
126
- return void 0;
127
- }
128
- if (["true", "1", "yes", "y", "on"].includes(normalized)) {
129
- return true;
130
- }
131
- if (["false", "0", "no", "n", "off"].includes(normalized)) {
132
- return false;
133
- }
134
- }
93
+ if (typeof value === "boolean") return value;
94
+ if (typeof value === "number") return value !== 0;
95
+ const normalized = String(value).trim().toLowerCase();
96
+ if (!normalized) return void 0;
97
+ if (BOOLEAN_TRUES.has(normalized)) return true;
98
+ if (BOOLEAN_FALSES.has(normalized)) return false;
135
99
  return Boolean(value);
136
100
  }
137
101
  if (descriptor.type === "number") {
138
- if (typeof value === "number") {
139
- return value;
140
- }
141
- const parsed = Number(String(value).trim());
142
- return Number.isNaN(parsed) ? void 0 : parsed;
102
+ const num = typeof value === "number" ? value : Number(String(value).trim());
103
+ return isNaN(num) ? void 0 : num;
143
104
  }
144
105
  return String(value).trim();
145
106
  }
146
- function getNormalizedKey(value) {
147
- if (typeof value !== "string") {
148
- return null;
149
- }
150
- const trimmed = value.trim();
151
- return trimmed.length ? trimmed : null;
107
+ function normalizeKey(value) {
108
+ return typeof value === "string" ? value.trim() || void 0 : void 0;
152
109
  }
153
- function getNormalizedType(value) {
154
- if (typeof value !== "string") {
155
- return null;
156
- }
110
+ function normalizeType(value) {
111
+ if (typeof value !== "string") return void 0;
157
112
  const type = value.trim().toLowerCase();
158
- return VALID_FIELD_TYPES.has(type) ? type : null;
113
+ return VALID_FIELD_TYPES.has(type) ? type : void 0;
159
114
  }
160
- function getNormalizedLabel(value) {
161
- if (typeof value !== "string") {
162
- return void 0;
163
- }
164
- const trimmed = value.trim();
165
- return trimmed.length ? trimmed : void 0;
115
+ function normalizeLabel(value) {
116
+ return typeof value === "string" ? value.trim() || void 0 : void 0;
166
117
  }
167
118
  function isDeepEqual(a, b) {
168
- if (a === b) {
169
- return true;
170
- }
171
- if (typeof a === "object" && typeof b === "object" && a !== null && b !== null) {
172
- const aKeys = Object.keys(a);
173
- const bKeys = Object.keys(b);
174
- if (aKeys.length !== bKeys.length) {
175
- return false;
176
- }
177
- return aKeys.every(
178
- (key) => isDeepEqual(
179
- a[key],
180
- b[key]
181
- )
182
- );
183
- }
184
- return false;
119
+ if (a === b) return true;
120
+ if (!a || !b || typeof a !== "object" || typeof b !== "object") return false;
121
+ const aKeys = Object.keys(a);
122
+ const bKeys = Object.keys(b);
123
+ if (aKeys.length !== bKeys.length) return false;
124
+ return aKeys.every(
125
+ (key) => isDeepEqual(a[key], b[key])
126
+ );
185
127
  }
186
128
  const CONFIG_ENDPOINT = "/admin/product-metadata-config";
187
129
  const QUERY_KEY = ["medusa-product-helper", "metadata-config"];
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GET = void 0;
4
+ const utils_1 = require("@medusajs/framework/utils");
5
+ const product_helper_options_1 = require("../../../../config/product-helper-options");
6
+ const product_filter_service_1 = require("../../../../services/product-filter-service");
7
+ const query_parser_1 = require("../../../../utils/query-parser");
8
+ const validators_1 = require("./validators");
9
+ /**
10
+ * GET /store/product-helper/products
11
+ *
12
+ * List products with advanced filtering capabilities.
13
+ *
14
+ * Matches Medusa's official /store/products API format while adding
15
+ * support for custom filter providers and advanced filtering.
16
+ *
17
+ * @example
18
+ * ```bash
19
+ * # Basic filter
20
+ * GET /store/product-helper/products?category_id=cat_123
21
+ *
22
+ * # Multiple filters
23
+ * GET /store/product-helper/products?category_id=cat_123&price_min=10&price_max=100
24
+ *
25
+ * # Custom filter (if provider registered)
26
+ * GET /store/product-helper/products?margin[min]=20&margin[max]=40
27
+ * ```
28
+ */
29
+ const GET = async (req, res) => {
30
+ try {
31
+ // Normalize query parameters to handle both bracketed and nested formats
32
+ // e.g., price_range[min]=10 -> { price_range: { min: "10" } }
33
+ const rawQuery = req.query || {};
34
+ const normalizedQuery = (0, query_parser_1.normalizeQueryParams)(rawQuery);
35
+ // Validate query parameters using zod schema
36
+ // This ensures type safety and catches invalid inputs early
37
+ const validatedQuery = validators_1.StoreProductHelperFilterQuerySchema.parse(normalizedQuery);
38
+ // Resolve plugin options
39
+ const configModule = req.scope.resolve(utils_1.ContainerRegistrationKeys.CONFIG_MODULE);
40
+ const options = (0, product_helper_options_1.resolveProductHelperOptions)(configModule);
41
+ // Apply filters using ProductFilterService
42
+ // This service will merge custom filters with req.filterableFields
43
+ const filterService = new product_filter_service_1.ProductFilterService(req.scope);
44
+ const { products, count, metadata } = await filterService.applyFilterPlanWithMedusaContext({
45
+ queryConfig: req.queryConfig,
46
+ filterableFields: req.filterableFields || {},
47
+ pricingContext: req.pricingContext,
48
+ query: validatedQuery,
49
+ }, options);
50
+ // Calculate min_price and max_price if price_range=true
51
+ let minPrice = null;
52
+ let maxPrice = null;
53
+ if (validatedQuery.price_range === true) {
54
+ for (const product of products) {
55
+ if (!product.variants || !Array.isArray(product.variants)) {
56
+ continue;
57
+ }
58
+ for (const variant of product.variants) {
59
+ if (!variant.prices || !Array.isArray(variant.prices) || variant.prices.length === 0) {
60
+ continue;
61
+ }
62
+ const price = variant.prices[0]?.amount;
63
+ if (price !== undefined && typeof price === "number") {
64
+ if (minPrice === null || price < minPrice) {
65
+ minPrice = price;
66
+ }
67
+ if (maxPrice === null || price > maxPrice) {
68
+ maxPrice = price;
69
+ }
70
+ }
71
+ }
72
+ }
73
+ }
74
+ // Build response object
75
+ const response = {
76
+ products: products,
77
+ count: metadata?.count || count || products.length,
78
+ offset: metadata?.skip || 0,
79
+ // Ensure limit is never 0 - use metadata take, validated query limit, or default to 20
80
+ limit: (metadata?.take && metadata.take > 0)
81
+ ? metadata.take
82
+ : (validatedQuery.limit && validatedQuery.limit > 0)
83
+ ? validatedQuery.limit
84
+ : (products.length > 0 ? products.length : 20),
85
+ };
86
+ // Add price range fields if price_range=true
87
+ if (validatedQuery.price_range === true) {
88
+ response.min_price = minPrice;
89
+ response.max_price = maxPrice;
90
+ }
91
+ // Return response matching Medusa's format
92
+ res.json(response);
93
+ }
94
+ catch (error) {
95
+ // Handle validation errors
96
+ if (error && typeof error === "object" && "issues" in error) {
97
+ // Zod validation error
98
+ res.status(400).json({
99
+ message: "Invalid query parameters",
100
+ errors: error.issues,
101
+ });
102
+ return;
103
+ }
104
+ // Handle other errors
105
+ const errorMessage = error instanceof Error ? error.message : "Internal server error";
106
+ res.status(500).json({
107
+ message: errorMessage,
108
+ });
109
+ }
110
+ };
111
+ exports.GET = GET;
112
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL3N0b3JlL3Byb2R1Y3QtaGVscGVyL3Byb2R1Y3RzL3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUVBLHFEQUFxRTtBQUNyRSxzRkFBdUY7QUFDdkYsd0ZBQWtGO0FBQ2xGLGlFQUFxRTtBQUNyRSw2Q0FFcUI7QUFnQnJCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBbUJHO0FBQ0ksTUFBTSxHQUFHLEdBQUcsS0FBSyxFQUN0QixHQUF1QixFQUN2QixHQUF1RCxFQUN2RCxFQUFFO0lBQ0YsSUFBSSxDQUFDO1FBQ0gseUVBQXlFO1FBQ3pFLDhEQUE4RDtRQUM5RCxNQUFNLFFBQVEsR0FBRyxHQUFHLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQTtRQUNoQyxNQUFNLGVBQWUsR0FBRyxJQUFBLG1DQUFvQixFQUMxQyxRQUFtQyxDQUNwQyxDQUFBO1FBRUQsNkNBQTZDO1FBQzdDLDREQUE0RDtRQUM1RCxNQUFNLGNBQWMsR0FBRyxnREFBbUMsQ0FBQyxLQUFLLENBQzlELGVBQWUsQ0FDaEIsQ0FBQTtRQUVELHlCQUF5QjtRQUN6QixNQUFNLFlBQVksR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxpQ0FBeUIsQ0FBQyxhQUFhLENBQUMsQ0FBQTtRQUMvRSxNQUFNLE9BQU8sR0FBRyxJQUFBLG9EQUEyQixFQUFDLFlBQVksQ0FBQyxDQUFBO1FBRXpELDJDQUEyQztRQUMzQyxtRUFBbUU7UUFDbkUsTUFBTSxhQUFhLEdBQUcsSUFBSSw2Q0FBb0IsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUE7UUFDekQsTUFBTSxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLEdBQUcsTUFBTSxhQUFhLENBQUMsZ0NBQWdDLENBQ3hGO1lBQ0UsV0FBVyxFQUFFLEdBQUcsQ0FBQyxXQUFXO1lBQzVCLGdCQUFnQixFQUFF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
@@ -145,7 +145,9 @@ exports.StoreProductHelperFilterQuerySchema = zod_1.z
145
145
  rating_min: optionalNumberish,
146
146
  rating_max: optionalNumberish,
147
147
  rating_required: booleanish.default(false),
148
+ price_range: booleanish.default(false),
148
149
  })
150
+ .passthrough() // Allow unknown properties for custom filter providers
149
151
  .refine((value) => typeof value.price_min === "undefined" ||
150
152
  typeof value.price_max === "undefined" ||
151
153
  value.price_min <= value.price_max, {
@@ -168,4 +170,4 @@ exports.StoreBestSellingQuerySchema = zod_1.z.object({
168
170
  variant_id: stringArray,
169
171
  product_id: stringArray,
170
172
  });
171
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdG9ycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcGkvc3RvcmUvcHJvZHVjdC1oZWxwZXIvcHJvZHVjdHMvdmFsaWRhdG9ycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw2QkFBdUI7QUFFdkIsTUFBTSxjQUFjLEdBQUcsT0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxPQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFBO0FBQ3hELE1BQU0saUJBQWlCLEdBQUcsT0FBQztLQUN4QixLQUFLLENBQUMsQ0FBQyxPQUFDLENBQUMsU0FBUyxFQUFFLEVBQUUsT0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLGNBQWMsQ0FBQyxDQUFDO0tBQ2hELFNBQVMsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFO0lBQ25CLElBQUksS0FBSyxLQUFLLFNBQVMsSUFBSSxLQUFLLEtBQUssSUFBSSxJQUFJLEtBQUssS0FBSyxFQUFFLEVBQUUsQ0FBQztRQUMxRCxPQUFPLFNBQVMsQ0FBQTtJQUNsQixDQUFDO0lBRUQsTUFBTSxPQUFPLEdBQ1gsT0FBTyxLQUFLLEtBQUssUUFBUTtRQUN2QixDQUFDLENBQUMsS0FBSztRQUNQLENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQTtJQUVwRCxJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztRQUMxQixNQUFNLElBQUksS0FBSyxDQUFDLHVCQUF1QixDQUFDLENBQUE7SUFDMUMsQ0FBQztJQUVELE9BQU8sT0FBTyxDQUFBO0FBQ2hCLENBQUMsQ0FBQyxDQUFBO0FBRUosTUFBTSxXQUFXLEdBQUcsT0FBQztLQUNsQixLQUFLLENBQUMsQ0FBQyxP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
173
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdG9ycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcGkvc3RvcmUvcHJvZHVjdC1oZWxwZXIvcHJvZHVjdHMvdmFsaWRhdG9ycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw2QkFBdUI7QUFFdkIsTUFBTSxjQUFjLEdBQUcsT0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxPQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFBO0FBQ3hELE1BQU0saUJBQWlCLEdBQUcsT0FBQztLQUN4QixLQUFLLENBQUMsQ0FBQyxPQUFDLENBQUMsU0FBUyxFQUFFLEVBQUUsT0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLGNBQWMsQ0FBQyxDQUFDO0tBQ2hELFNBQVMsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFO0lBQ25CLElBQUksS0FBSyxLQUFLLFNBQVMsSUFBSSxLQUFLLEtBQUssSUFBSSxJQUFJLEtBQUssS0FBSyxFQUFFLEVBQUUsQ0FBQztRQUMxRCxPQUFPLFNBQVMsQ0FBQTtJQUNsQixDQUFDO0lBRUQsTUFBTSxPQUFPLEdBQ1gsT0FBTyxLQUFLLEtBQUssUUFBUTtRQUN2QixDQUFDLENBQUMsS0FBSztRQUNQLENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQTtJQUVwRCxJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztRQUMxQixNQUFNLElBQUksS0FBSyxDQUFDLHVCQUF1QixDQUFDLENBQUE7SUFDMUMsQ0FBQztJQUVELE9BQU8sT0FBTyxDQUFBO0FBQ2hCLENBQUMsQ0FBQyxDQUFBO0FBRUosTUFBTSxXQUFXLEdBQUcsT0FBQztLQUNsQixLQUFLLENBQUMsQ0FBQyxP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