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.
- package/.medusa/server/src/admin/index.js +59 -117
- package/.medusa/server/src/admin/index.mjs +59 -117
- package/.medusa/server/src/api/store/product-helper/products/route.js +112 -0
- package/.medusa/server/src/api/store/product-helper/products/validators.js +3 -1
- package/.medusa/server/src/config/product-helper-options.js +15 -1
- package/.medusa/server/src/index.js +101 -0
- package/.medusa/server/src/providers/filter-providers/availability-provider.js +82 -0
- package/.medusa/server/src/providers/filter-providers/base-filter-provider.js +14 -0
- package/.medusa/server/src/providers/filter-providers/base-product-provider.js +59 -0
- package/.medusa/server/src/providers/filter-providers/category-provider.js +36 -0
- package/.medusa/server/src/providers/filter-providers/collection-provider.js +36 -0
- package/.medusa/server/src/providers/filter-providers/index.js +58 -0
- package/.medusa/server/src/providers/filter-providers/metadata-provider.js +69 -0
- package/.medusa/server/src/providers/filter-providers/price-range-provider.js +95 -0
- package/.medusa/server/src/providers/filter-providers/promotion-provider.js +134 -0
- package/.medusa/server/src/providers/filter-providers/promotion-window-provider.js +85 -0
- package/.medusa/server/src/providers/filter-providers/rating-provider.js +69 -0
- package/.medusa/server/src/services/dynamic-filter-service.js +525 -0
- package/.medusa/server/src/services/filter-provider-loader.js +107 -0
- package/.medusa/server/src/services/filter-provider-registry.js +43 -0
- package/.medusa/server/src/services/product-filter-service.js +183 -0
- package/.medusa/server/src/shared/product-metadata/utils.js +66 -116
- package/.medusa/server/src/utils/query-builders/product-filters.js +89 -111
- package/.medusa/server/src/utils/query-parser.js +51 -0
- package/.medusa/server/src/workflows/add-to-wishlist.js +12 -26
- package/.medusa/server/src/workflows/get-wishlist.js +53 -51
- package/.medusa/server/src/workflows/remove-from-wishlist.js +3 -8
- package/README.md +89 -0
- package/package.json +3 -3
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.loadFilterProviders = loadFilterProviders;
|
|
7
|
+
const base_filter_provider_1 = require("../providers/filter-providers/base-filter-provider");
|
|
8
|
+
const fs_1 = require("fs");
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
async function loadFilterProviders(configs, options = {}) {
|
|
11
|
+
const providers = [];
|
|
12
|
+
const baseDir = options.baseDir || process.cwd();
|
|
13
|
+
for (const config of configs) {
|
|
14
|
+
try {
|
|
15
|
+
const provider = await loadProvider(config, baseDir);
|
|
16
|
+
providers.push(provider);
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
throw new Error(`Failed to load filter provider from ${JSON.stringify(config)}: ${error}`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return providers;
|
|
23
|
+
}
|
|
24
|
+
async function loadProvider(config, baseDir) {
|
|
25
|
+
const { providerPath, providerOptions } = parseConfig(config);
|
|
26
|
+
const ProviderClass = await resolveProviderClass(providerPath, baseDir);
|
|
27
|
+
validateProviderClass(ProviderClass, providerPath);
|
|
28
|
+
return instantiateProvider(ProviderClass, providerOptions);
|
|
29
|
+
}
|
|
30
|
+
function parseConfig(config) {
|
|
31
|
+
if (typeof config === "string") {
|
|
32
|
+
return { providerPath: config };
|
|
33
|
+
}
|
|
34
|
+
return { providerPath: config.path, providerOptions: config.options };
|
|
35
|
+
}
|
|
36
|
+
async function resolveProviderClass(providerPath, baseDir) {
|
|
37
|
+
// Try module import first
|
|
38
|
+
try {
|
|
39
|
+
const module = await import(providerPath);
|
|
40
|
+
return extractProviderClass(module, providerPath);
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
// Fall back to file import
|
|
44
|
+
const absolutePath = path_1.default.isAbsolute(providerPath)
|
|
45
|
+
? providerPath
|
|
46
|
+
: path_1.default.resolve(baseDir, providerPath);
|
|
47
|
+
await validateFileExists(absolutePath);
|
|
48
|
+
const module = await importFile(absolutePath);
|
|
49
|
+
return extractProviderClass(module, providerPath);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
async function validateFileExists(filePath) {
|
|
53
|
+
try {
|
|
54
|
+
await fs_1.promises.access(filePath);
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
throw new Error(`Filter provider file not found: ${filePath}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
async function importFile(filePath) {
|
|
61
|
+
// Try ESM import first
|
|
62
|
+
try {
|
|
63
|
+
return await import(filePath);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
// Fall back to CommonJS require
|
|
67
|
+
return require(filePath);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function extractProviderClass(module, providerPath) {
|
|
71
|
+
// Try default export
|
|
72
|
+
if (typeof module?.default === "function") {
|
|
73
|
+
return module.default;
|
|
74
|
+
}
|
|
75
|
+
// Try to find a BaseFilterProvider subclass
|
|
76
|
+
for (const value of Object.values(module)) {
|
|
77
|
+
if (isProviderClass(value)) {
|
|
78
|
+
return value;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
throw new Error(`No filter provider class found in ${providerPath}`);
|
|
82
|
+
}
|
|
83
|
+
function isProviderClass(value) {
|
|
84
|
+
return (typeof value === "function" &&
|
|
85
|
+
value.prototype &&
|
|
86
|
+
Object.getPrototypeOf(value.prototype)?.constructor === base_filter_provider_1.BaseFilterProvider &&
|
|
87
|
+
typeof value.identifier === "string" &&
|
|
88
|
+
typeof value.displayName === "string");
|
|
89
|
+
}
|
|
90
|
+
function validateProviderClass(ProviderClass, providerPath) {
|
|
91
|
+
if (!isProviderClass(ProviderClass)) {
|
|
92
|
+
throw new Error(`Class in ${providerPath} does not appear to extend BaseFilterProvider. ` +
|
|
93
|
+
`Missing static 'identifier' and/or 'displayName' properties.`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function instantiateProvider(ProviderClass, options) {
|
|
97
|
+
try {
|
|
98
|
+
// @ts-expect-error - ProviderClass is validated to be a concrete subclass
|
|
99
|
+
return options ? new ProviderClass(options) : new ProviderClass();
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
// Constructor doesn't accept options, try without
|
|
103
|
+
// @ts-expect-error - ProviderClass is validated to be a concrete subclass
|
|
104
|
+
return new ProviderClass();
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsdGVyLXByb3ZpZGVyLWxvYWRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9zZXJ2aWNlcy9maWx0ZXItcHJvdmlkZXItbG9hZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBU0Esa0RBaUJDO0FBMUJELDZGQUF1RjtBQUV2RiwyQkFBbUM7QUFDbkMsZ0RBQXVCO0FBTWhCLEtBQUssVUFBVSxtQkFBbUIsQ0FDdkMsT0FBK0IsRUFDL0IsVUFBc0MsRUFBRTtJQUV4QyxNQUFNLFNBQVMsR0FBeUIsRUFBRSxDQUFBO0lBQzFDLE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxPQUFPLElBQUksT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFBO0lBRWhELEtBQUssTUFBTSxNQUFNLElBQUksT0FBTyxFQUFFLENBQUM7UUFDN0IsSUFBSSxDQUFDO1lBQ0gsTUFBTSxRQUFRLEdBQUcsTUFBTSxZQUFZLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFBO1lBQ3BELFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUE7UUFDMUIsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixNQUFNLElBQUksS0FBSyxDQUFDLHVDQUF1QyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEtBQUssRUFBRSxDQUFDLENBQUE7UUFDNUYsQ0FBQztJQUNILENBQUM7SUFFRCxPQUFPLFNBQVMsQ0FBQTtBQUNsQixDQUFDO0FBRUQsS0FBSyxVQUFVLFlBQVksQ0FDekIsTUFBNEIsRUFDNUIsT0FBZTtJQUVmLE1BQU0sRUFBRSxZQUFZLEVBQUUsZUFBZSxFQUFFLEdBQUcsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFBO0lBQzdELE1BQU0sYUFBYSxHQUFHLE1BQU0sb0JBQW9CLENBQUMsWUFBWSxFQUFFLE9BQU8sQ0FBQyxDQUFBO0lBRXZFLHFCQUFxQixDQUFDLGFBQWEsRUFBRSxZQUFZLENBQUMs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
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FilterProviderRegistry = void 0;
|
|
4
|
+
class FilterProviderRegistry {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.providers = new Map();
|
|
7
|
+
}
|
|
8
|
+
register(provider) {
|
|
9
|
+
const constructor = provider.constructor;
|
|
10
|
+
const identifier = constructor.identifier;
|
|
11
|
+
const displayName = constructor.displayName || "Unknown";
|
|
12
|
+
if (!identifier) {
|
|
13
|
+
throw new Error("Filter provider must have a static 'identifier' property");
|
|
14
|
+
}
|
|
15
|
+
if (this.providers.has(identifier)) {
|
|
16
|
+
const existing = this.providers.get(identifier);
|
|
17
|
+
const existingDisplayName = existing.constructor.displayName || "Unknown";
|
|
18
|
+
throw new Error(`Filter provider "${identifier}" (${existingDisplayName}) already registered. ` +
|
|
19
|
+
`Cannot register ${displayName}.`);
|
|
20
|
+
}
|
|
21
|
+
this.providers.set(identifier, provider);
|
|
22
|
+
}
|
|
23
|
+
get(identifier) {
|
|
24
|
+
return this.providers.get(identifier);
|
|
25
|
+
}
|
|
26
|
+
has(identifier) {
|
|
27
|
+
return this.providers.has(identifier);
|
|
28
|
+
}
|
|
29
|
+
getAll() {
|
|
30
|
+
return Array.from(this.providers.values());
|
|
31
|
+
}
|
|
32
|
+
getIdentifiers() {
|
|
33
|
+
return Array.from(this.providers.keys());
|
|
34
|
+
}
|
|
35
|
+
clear() {
|
|
36
|
+
this.providers.clear();
|
|
37
|
+
}
|
|
38
|
+
size() {
|
|
39
|
+
return this.providers.size;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
exports.FilterProviderRegistry = FilterProviderRegistry;
|
|
43
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsdGVyLXByb3ZpZGVyLXJlZ2lzdHJ5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3NlcnZpY2VzL2ZpbHRlci1wcm92aWRlci1yZWdpc3RyeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFFQSxNQUFhLHNCQUFzQjtJQUFuQztRQUNVLGNBQVMsR0FBRyxJQUFJLEdBQUcsRUFBOEIsQ0FBQTtJQStDM0QsQ0FBQztJQTdDQyxRQUFRLENBQUMsUUFBNEI7UUFDbkMsTUFBTSxXQUFXLEdBQUcsUUFBUSxDQUFDLFdBQXdDLENBQUE7UUFDckUsTUFBTSxVQUFVLEdBQUcsV0FBVyxDQUFDLFVBQVUsQ0FBQTtRQUN6QyxNQUFNLFdBQVcsR0FBRyxXQUFXLENBQUMsV0FBVyxJQUFJLFNBQVMsQ0FBQTtRQUV4RCxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDaEIsTUFBTSxJQUFJLEtBQUssQ0FBQywwREFBMEQsQ0FBQyxDQUFBO1FBQzdFLENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7WUFDbkMsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFFLENBQUE7WUFDaEQsTUFBTSxtQkFBbUIsR0FBSSxRQUFRLENBQUMsV0FBeUMsQ0FBQyxXQUFXLElBQUksU0FBUyxDQUFBO1lBRXhHLE1BQU0sSUFBSSxLQUFLLENBQ2Isb0JBQW9CLFVBQVUsTUFBTSxtQkFBbUIsd0JBQXdCO2dCQUMvRSxtQkFBbUIsV0FBVyxHQUFHLENBQ2xDLENBQUE7UUFDSCxDQUFDO1FBRUQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsVUFBVSxFQUFFLFFBQVEsQ0FBQyxDQUFBO0lBQzFDLENBQUM7SUFFRCxHQUFHLENBQUMsVUFBa0I7UUFDcEIsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQTtJQUN2QyxDQUFDO0lBRUQsR0FBRyxDQUFDLFVBQWtCO1FBQ3BCLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUE7SUFDdkMsQ0FBQztJQUVELE1BQU07UUFDSixPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFBO0lBQzVDLENBQUM7SUFFRCxjQUFjO1FBQ1osT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQTtJQUMxQyxDQUFDO0lBRUQsS0FBSztRQUNILElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUE7SUFDeEIsQ0FBQztJQUVELElBQUk7UUFDRixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFBO0lBQzVCLENBQUM7Q0FDRjtBQWhERCx3REFnREMifQ==
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ProductFilterService = void 0;
|
|
4
|
+
const dynamic_filter_service_1 = require("./dynamic-filter-service");
|
|
5
|
+
const index_1 = require("../index");
|
|
6
|
+
class ProductFilterService {
|
|
7
|
+
constructor(container) {
|
|
8
|
+
this.dynamicFilterService = this.resolveService(container);
|
|
9
|
+
}
|
|
10
|
+
resolveService(container) {
|
|
11
|
+
try {
|
|
12
|
+
return container.resolve(index_1.DYNAMIC_FILTER_SERVICE);
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return new dynamic_filter_service_1.DynamicFilterService(container);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
async applyFilterPlanWithMedusaContext(context, options) {
|
|
19
|
+
const filterParams = this.buildFilterParams(context);
|
|
20
|
+
const applyOptions = this.buildApplyOptions(context, options, filterParams);
|
|
21
|
+
return await this.dynamicFilterService.applyFilters(applyOptions);
|
|
22
|
+
}
|
|
23
|
+
buildFilterParams(context) {
|
|
24
|
+
const customFilters = this.extractCustomFilters(context.query);
|
|
25
|
+
return {
|
|
26
|
+
...context.filterableFields,
|
|
27
|
+
...customFilters
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
extractCustomFilters(query) {
|
|
31
|
+
const filters = {};
|
|
32
|
+
if (query?.price_range && this.isObject(query.price_range)) {
|
|
33
|
+
const priceRange = this.parsePriceRange(query.price_range);
|
|
34
|
+
if (priceRange)
|
|
35
|
+
filters.price_range = priceRange;
|
|
36
|
+
}
|
|
37
|
+
if (query?.promotion && this.isObject(query.promotion)) {
|
|
38
|
+
const promotionFilter = this.parsePromotionFilter(query.promotion);
|
|
39
|
+
if (promotionFilter)
|
|
40
|
+
filters.promotion = promotionFilter;
|
|
41
|
+
}
|
|
42
|
+
return filters;
|
|
43
|
+
}
|
|
44
|
+
parsePriceRange(priceRange) {
|
|
45
|
+
if (!this.isObject(priceRange))
|
|
46
|
+
return undefined;
|
|
47
|
+
const range = priceRange;
|
|
48
|
+
const min = this.parseNumber(range.min);
|
|
49
|
+
const max = this.parseNumber(range.max);
|
|
50
|
+
if (min === undefined && max === undefined)
|
|
51
|
+
return undefined;
|
|
52
|
+
return {
|
|
53
|
+
min,
|
|
54
|
+
max,
|
|
55
|
+
currency_code: typeof range.currency_code === "string" ? range.currency_code : undefined
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
parsePromotionFilter(promotion) {
|
|
59
|
+
if (!this.isObject(promotion))
|
|
60
|
+
return undefined;
|
|
61
|
+
const promo = promotion;
|
|
62
|
+
const filter = {};
|
|
63
|
+
const minDiscount = this.parsePercentage(promo.min_discount_percentage);
|
|
64
|
+
if (minDiscount !== undefined)
|
|
65
|
+
filter.min_discount_percentage = minDiscount;
|
|
66
|
+
const maxDiscount = this.parsePercentage(promo.max_discount_percentage);
|
|
67
|
+
if (maxDiscount !== undefined)
|
|
68
|
+
filter.max_discount_percentage = maxDiscount;
|
|
69
|
+
if (typeof promo.promotion_type === "string")
|
|
70
|
+
filter.promotion_type = promo.promotion_type;
|
|
71
|
+
if (typeof promo.status === "string")
|
|
72
|
+
filter.status = promo.status;
|
|
73
|
+
const startsAt = this.parseDate(promo.starts_at);
|
|
74
|
+
if (startsAt)
|
|
75
|
+
filter.starts_at = startsAt;
|
|
76
|
+
const endsAt = this.parseDate(promo.ends_at);
|
|
77
|
+
if (endsAt)
|
|
78
|
+
filter.ends_at = endsAt;
|
|
79
|
+
filter.include_open_ended = this.parseBoolean(promo.include_open_ended) ?? true;
|
|
80
|
+
return Object.keys(filter).length > 0 ? filter : undefined;
|
|
81
|
+
}
|
|
82
|
+
parseNumber(value) {
|
|
83
|
+
if (value === undefined || value === null)
|
|
84
|
+
return undefined;
|
|
85
|
+
const num = typeof value === "string" ? Number(value) : value;
|
|
86
|
+
return typeof num === "number" && !isNaN(num) ? num : undefined;
|
|
87
|
+
}
|
|
88
|
+
parsePercentage(value) {
|
|
89
|
+
const num = this.parseNumber(value);
|
|
90
|
+
return num !== undefined && num >= 0 && num <= 100 ? num : undefined;
|
|
91
|
+
}
|
|
92
|
+
parseDate(value) {
|
|
93
|
+
if (value instanceof Date)
|
|
94
|
+
return value;
|
|
95
|
+
if (typeof value === "string") {
|
|
96
|
+
const date = new Date(value);
|
|
97
|
+
return isNaN(date.getTime()) ? undefined : date;
|
|
98
|
+
}
|
|
99
|
+
return undefined;
|
|
100
|
+
}
|
|
101
|
+
parseBoolean(value) {
|
|
102
|
+
if (typeof value === "boolean")
|
|
103
|
+
return value;
|
|
104
|
+
if (typeof value === "string") {
|
|
105
|
+
return value === "true" || value === "1";
|
|
106
|
+
}
|
|
107
|
+
return undefined;
|
|
108
|
+
}
|
|
109
|
+
isObject(value) {
|
|
110
|
+
return value != null && typeof value === "object" && !Array.isArray(value);
|
|
111
|
+
}
|
|
112
|
+
buildApplyOptions(context, options, filterParams) {
|
|
113
|
+
return {
|
|
114
|
+
filterParams,
|
|
115
|
+
options,
|
|
116
|
+
pagination: context.queryConfig?.pagination ? {
|
|
117
|
+
offset: context.queryConfig.pagination.skip,
|
|
118
|
+
limit: context.queryConfig.pagination.take,
|
|
119
|
+
} : undefined,
|
|
120
|
+
projection: context.queryConfig?.fields?.length ? {
|
|
121
|
+
fields: context.queryConfig.fields
|
|
122
|
+
} : undefined,
|
|
123
|
+
context: context.pricingContext ? {
|
|
124
|
+
pricingContext: context.pricingContext
|
|
125
|
+
} : undefined
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
async applyFilterPlan(plan, options) {
|
|
129
|
+
const filterParams = this.convertPlanToFilterParams(plan);
|
|
130
|
+
const applyOptions = {
|
|
131
|
+
filterParams,
|
|
132
|
+
options,
|
|
133
|
+
pagination: plan.pagination,
|
|
134
|
+
projection: plan.projection,
|
|
135
|
+
};
|
|
136
|
+
const result = await this.dynamicFilterService.applyFilters(applyOptions);
|
|
137
|
+
return { products: result.products, count: result.count };
|
|
138
|
+
}
|
|
139
|
+
convertPlanToFilterParams(plan) {
|
|
140
|
+
const filters = {};
|
|
141
|
+
if (Object.keys(plan.baseFilters).length > 0) {
|
|
142
|
+
filters.base_product = plan.baseFilters;
|
|
143
|
+
}
|
|
144
|
+
const categories = plan.baseFilters.categories?.id;
|
|
145
|
+
if (categories?.length) {
|
|
146
|
+
filters.category_id = categories;
|
|
147
|
+
}
|
|
148
|
+
if (plan.baseFilters.collection_id) {
|
|
149
|
+
filters.collection_id = plan.baseFilters.collection_id;
|
|
150
|
+
}
|
|
151
|
+
if (Object.keys(plan.metadataFilters).length > 0) {
|
|
152
|
+
filters.metadata = plan.metadataFilters;
|
|
153
|
+
}
|
|
154
|
+
if (plan.priceRange) {
|
|
155
|
+
filters.price_range = {
|
|
156
|
+
min: plan.priceRange.min,
|
|
157
|
+
max: plan.priceRange.max,
|
|
158
|
+
currency_code: plan.priceRange.currency_code,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
if (plan.promotionWindow) {
|
|
162
|
+
filters.promotion_window = {
|
|
163
|
+
start: plan.promotionWindow.range?.start,
|
|
164
|
+
end: plan.promotionWindow.range?.end,
|
|
165
|
+
activeOn: plan.promotionWindow.activeOn,
|
|
166
|
+
includeOpen: plan.promotionWindow.includeOpen,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
if (plan.availability) {
|
|
170
|
+
filters.availability = plan.availability;
|
|
171
|
+
}
|
|
172
|
+
if (plan.rating?.enabled) {
|
|
173
|
+
filters.rating = {
|
|
174
|
+
min: plan.rating.min,
|
|
175
|
+
max: plan.rating.max,
|
|
176
|
+
require_reviews: plan.rating.require_reviews,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
return filters;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
exports.ProductFilterService = ProductFilterService;
|
|
183
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvZHVjdC1maWx0ZXItc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9zZXJ2aWNlcy9wcm9kdWN0LWZpbHRlci1zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLHFFQUF5RjtBQUN6RixvQ0FBaUQ7QUFJakQsTUFBYSxvQkFBb0I7SUFHL0IsWUFBWSxTQUEwQjtRQUNwQyxJQUFJLENBQUMsb0JBQW9CLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxTQUFTLENBQUMsQ0FBQTtJQUM1RCxDQUFDO0lBRU8sY0FBYyxDQUFDLFNBQTBCO1FBQy9DLElBQUksQ0FBQztZQUNILE9BQU8sU0FBUyxDQUFDLE9BQU8sQ0FBdUIsOEJBQXNCLENBQUMsQ0FBQTtRQUN4RSxDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1AsT0FBTyxJQUFJLDZDQUFvQixDQUFDLFNBQVMsQ0FBQyxDQUFBO1FBQzVDLENBQUM7SUFDSCxDQUFDO0lBRUQsS0FBSyxDQUFDLGdDQUFnQyxDQUNwQyxPQUtDLEVBQ0QsT0FBNkI7UUFFN0IsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxDQUFBO1FBQ3BELE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLFlBQVksQ0FBQyxDQUFBO1FBRTNFLE9BQU8sTUFBTSxJQUFJLENBQUMsb0JBQW9CLENBQUMsWUFBWSxDQUFDLFlBQVksQ0FBQyxDQUFBO0lBQ25FLENBQUM7SUFFTyxpQkFBaUIsQ0FBQyxPQUd6QjtRQUNDLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUE7UUFDOUQsT0FBTztZQUNMLEdBQUcsT0FBTyxDQUFDLGdCQUFnQjtZQUMzQixHQUFHLGFBQWE7U0FDakIsQ0FBQTtJQUNILENBQUM7SUFFTyxvQkFBb0IsQ0FBQyxL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
|
|
@@ -8,43 +8,31 @@ exports.hasMetadataChanges = hasMetadataChanges;
|
|
|
8
8
|
exports.validateValueForDescriptor = validateValueForDescriptor;
|
|
9
9
|
const types_1 = require("./types");
|
|
10
10
|
const VALID_FIELD_TYPES = new Set(types_1.METADATA_FIELD_TYPES);
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
* - Filters out invalid entries.
|
|
14
|
-
* - Deduplicates by key (first occurrence wins).
|
|
15
|
-
* - Trims key and label whitespace.
|
|
16
|
-
*/
|
|
11
|
+
const BOOLEAN_TRUES = new Set(["true", "1", "yes", "y", "on"]);
|
|
12
|
+
const BOOLEAN_FALSES = new Set(["false", "0", "no", "n", "off"]);
|
|
17
13
|
function normalizeMetadataDescriptors(input) {
|
|
18
|
-
if (!Array.isArray(input))
|
|
14
|
+
if (!Array.isArray(input))
|
|
19
15
|
return [];
|
|
20
|
-
}
|
|
21
16
|
const seenKeys = new Set();
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
continue;
|
|
34
|
-
}
|
|
35
|
-
const label = getNormalizedLabel(item.label);
|
|
36
|
-
const filterable = typeof item.filterable === "boolean"
|
|
37
|
-
? item.filterable
|
|
38
|
-
: Boolean(item.filterable);
|
|
39
|
-
normalized.push({
|
|
40
|
-
key,
|
|
41
|
-
type,
|
|
42
|
-
...(label ? { label } : {}),
|
|
43
|
-
...(filterable ? { filterable: true } : {}),
|
|
44
|
-
});
|
|
17
|
+
return input
|
|
18
|
+
.filter((item) => item && typeof item === "object")
|
|
19
|
+
.map(item => {
|
|
20
|
+
const key = normalizeKey(item.key);
|
|
21
|
+
const type = normalizeType(item.type);
|
|
22
|
+
const label = normalizeLabel(item.label);
|
|
23
|
+
const filterable = !!(item.filterable);
|
|
24
|
+
return { key, type, label, filterable };
|
|
25
|
+
})
|
|
26
|
+
.filter(({ key, type }) => key && type && !seenKeys.has(key))
|
|
27
|
+
.map(({ key, type, label, filterable }) => {
|
|
45
28
|
seenKeys.add(key);
|
|
46
|
-
|
|
47
|
-
|
|
29
|
+
return {
|
|
30
|
+
key: key,
|
|
31
|
+
type: type,
|
|
32
|
+
...(label && { label }),
|
|
33
|
+
...(filterable && { filterable: true })
|
|
34
|
+
};
|
|
35
|
+
});
|
|
48
36
|
}
|
|
49
37
|
function getDescriptorMap(descriptors) {
|
|
50
38
|
return descriptors.reduce((acc, descriptor) => {
|
|
@@ -53,11 +41,9 @@ function getDescriptorMap(descriptors) {
|
|
|
53
41
|
}, {});
|
|
54
42
|
}
|
|
55
43
|
function buildInitialFormState(descriptors, metadata) {
|
|
44
|
+
const base = metadata && typeof metadata === "object" ? metadata : {};
|
|
56
45
|
return descriptors.reduce((acc, descriptor) => {
|
|
57
|
-
|
|
58
|
-
? metadata[descriptor.key]
|
|
59
|
-
: undefined;
|
|
60
|
-
acc[descriptor.key] = normalizeFormValue(descriptor, currentValue);
|
|
46
|
+
acc[descriptor.key] = normalizeFormValue(descriptor, base[descriptor.key]);
|
|
61
47
|
return acc;
|
|
62
48
|
}, {});
|
|
63
49
|
}
|
|
@@ -66,13 +52,13 @@ function buildMetadataPayload({ descriptors, values, originalMetadata, }) {
|
|
|
66
52
|
? { ...originalMetadata }
|
|
67
53
|
: {};
|
|
68
54
|
descriptors.forEach((descriptor) => {
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
if (typeof coerced === "undefined") {
|
|
55
|
+
const coerced = coerceMetadataValue(descriptor, values[descriptor.key]);
|
|
56
|
+
if (coerced === undefined) {
|
|
72
57
|
delete base[descriptor.key];
|
|
73
|
-
return;
|
|
74
58
|
}
|
|
75
|
-
|
|
59
|
+
else {
|
|
60
|
+
base[descriptor.key] = coerced;
|
|
61
|
+
}
|
|
76
62
|
});
|
|
77
63
|
return base;
|
|
78
64
|
}
|
|
@@ -81,42 +67,32 @@ function hasMetadataChanges({ descriptors, values, originalMetadata, }) {
|
|
|
81
67
|
const prev = originalMetadata && typeof originalMetadata === "object"
|
|
82
68
|
? originalMetadata
|
|
83
69
|
: {};
|
|
84
|
-
return descriptors.some((
|
|
85
|
-
const prevValue = prev[descriptor.key];
|
|
86
|
-
const nextValue = next[descriptor.key];
|
|
87
|
-
return !isDeepEqual(prevValue, nextValue);
|
|
88
|
-
});
|
|
70
|
+
return descriptors.some(({ key }) => !isDeepEqual(prev[key], next[key]));
|
|
89
71
|
}
|
|
90
72
|
function validateValueForDescriptor(descriptor, value) {
|
|
91
73
|
if (descriptor.type === "number") {
|
|
92
|
-
if (value
|
|
74
|
+
if (value == null || value === "")
|
|
93
75
|
return undefined;
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
if (Number.isNaN(numericValue)) {
|
|
97
|
-
return "Enter a valid number";
|
|
98
|
-
}
|
|
76
|
+
const num = typeof value === "number" ? value : Number(String(value).trim());
|
|
77
|
+
return isNaN(num) ? "Enter a valid number" : undefined;
|
|
99
78
|
}
|
|
100
79
|
if (descriptor.type === "file") {
|
|
101
|
-
if (!value)
|
|
80
|
+
if (!value)
|
|
102
81
|
return undefined;
|
|
103
|
-
}
|
|
104
82
|
try {
|
|
105
|
-
// eslint-disable-next-line no-new
|
|
106
83
|
new URL(String(value).trim());
|
|
84
|
+
return undefined;
|
|
107
85
|
}
|
|
108
|
-
catch
|
|
86
|
+
catch {
|
|
109
87
|
return "Enter a valid URL";
|
|
110
88
|
}
|
|
111
89
|
}
|
|
112
90
|
return undefined;
|
|
113
91
|
}
|
|
114
92
|
function normalizeFormValue(descriptor, currentValue) {
|
|
115
|
-
if (descriptor.type === "bool")
|
|
93
|
+
if (descriptor.type === "bool")
|
|
116
94
|
return Boolean(currentValue);
|
|
117
|
-
|
|
118
|
-
if ((descriptor.type === "number" || descriptor.type === "text") &&
|
|
119
|
-
typeof currentValue === "number") {
|
|
95
|
+
if ((descriptor.type === "number" || descriptor.type === "text") && typeof currentValue === "number") {
|
|
120
96
|
return currentValue.toString();
|
|
121
97
|
}
|
|
122
98
|
if (typeof currentValue === "string" || typeof currentValue === "number") {
|
|
@@ -125,75 +101,49 @@ function normalizeFormValue(descriptor, currentValue) {
|
|
|
125
101
|
return "";
|
|
126
102
|
}
|
|
127
103
|
function coerceMetadataValue(descriptor, value) {
|
|
128
|
-
if (value
|
|
104
|
+
if (value == null || value === "")
|
|
129
105
|
return undefined;
|
|
130
|
-
}
|
|
131
106
|
if (descriptor.type === "bool") {
|
|
132
|
-
if (typeof value === "boolean")
|
|
107
|
+
if (typeof value === "boolean")
|
|
133
108
|
return value;
|
|
134
|
-
|
|
135
|
-
if (typeof value === "number") {
|
|
109
|
+
if (typeof value === "number")
|
|
136
110
|
return value !== 0;
|
|
137
|
-
|
|
138
|
-
if (
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
return true;
|
|
145
|
-
}
|
|
146
|
-
if (["false", "0", "no", "n", "off"].includes(normalized)) {
|
|
147
|
-
return false;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
111
|
+
const normalized = String(value).trim().toLowerCase();
|
|
112
|
+
if (!normalized)
|
|
113
|
+
return undefined;
|
|
114
|
+
if (BOOLEAN_TRUES.has(normalized))
|
|
115
|
+
return true;
|
|
116
|
+
if (BOOLEAN_FALSES.has(normalized))
|
|
117
|
+
return false;
|
|
150
118
|
return Boolean(value);
|
|
151
119
|
}
|
|
152
120
|
if (descriptor.type === "number") {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
}
|
|
156
|
-
const parsed = Number(String(value).trim());
|
|
157
|
-
return Number.isNaN(parsed) ? undefined : parsed;
|
|
121
|
+
const num = typeof value === "number" ? value : Number(String(value).trim());
|
|
122
|
+
return isNaN(num) ? undefined : num;
|
|
158
123
|
}
|
|
159
124
|
return String(value).trim();
|
|
160
125
|
}
|
|
161
|
-
function
|
|
162
|
-
|
|
163
|
-
return null;
|
|
164
|
-
}
|
|
165
|
-
const trimmed = value.trim();
|
|
166
|
-
return trimmed.length ? trimmed : null;
|
|
126
|
+
function normalizeKey(value) {
|
|
127
|
+
return typeof value === "string" ? value.trim() || undefined : undefined;
|
|
167
128
|
}
|
|
168
|
-
function
|
|
169
|
-
if (typeof value !== "string")
|
|
170
|
-
return
|
|
171
|
-
}
|
|
129
|
+
function normalizeType(value) {
|
|
130
|
+
if (typeof value !== "string")
|
|
131
|
+
return undefined;
|
|
172
132
|
const type = value.trim().toLowerCase();
|
|
173
|
-
return VALID_FIELD_TYPES.has(type) ? type :
|
|
133
|
+
return VALID_FIELD_TYPES.has(type) ? type : undefined;
|
|
174
134
|
}
|
|
175
|
-
function
|
|
176
|
-
|
|
177
|
-
return undefined;
|
|
178
|
-
}
|
|
179
|
-
const trimmed = value.trim();
|
|
180
|
-
return trimmed.length ? trimmed : undefined;
|
|
135
|
+
function normalizeLabel(value) {
|
|
136
|
+
return typeof value === "string" ? value.trim() || undefined : undefined;
|
|
181
137
|
}
|
|
182
138
|
function isDeepEqual(a, b) {
|
|
183
|
-
if (a === b)
|
|
139
|
+
if (a === b)
|
|
184
140
|
return true;
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
if (aKeys.length !== bKeys.length) {
|
|
193
|
-
return false;
|
|
194
|
-
}
|
|
195
|
-
return aKeys.every((key) => isDeepEqual(a[key], b[key]));
|
|
196
|
-
}
|
|
197
|
-
return false;
|
|
141
|
+
if (!a || !b || typeof a !== "object" || typeof b !== "object")
|
|
142
|
+
return false;
|
|
143
|
+
const aKeys = Object.keys(a);
|
|
144
|
+
const bKeys = Object.keys(b);
|
|
145
|
+
if (aKeys.length !== bKeys.length)
|
|
146
|
+
return false;
|
|
147
|
+
return aKeys.every(key => isDeepEqual(a[key], b[key]));
|
|
198
148
|
}
|
|
199
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
149
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvc2hhcmVkL3Byb2R1Y3QtbWV0YWRhdGEvdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFjQSxvRUF5QkM7QUFFRCw0Q0FLQztBQUVELHNEQVVDO0FBRUQsb0RBd0JDO0FBRUQsZ0RBZUM7QUFFRCxnRUF1QkM7QUE5SEQsbUNBS2dCO0FBS2hCLE1BQU0saUJBQWlCLEdBQUcsSUFBSSxHQUFHLENBQW9CLDRCQUFvQixDQUFDLENBQUE7QUFDMUUsTUFBTSxhQUFhLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQTtBQUM5RCxNQUFNLGNBQWMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFBO0FBRWhFLFNBQWdCLDRCQUE0QixDQUFDLEtBQWM7SUFDekQsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDO1FBQUUsT0FBTyxFQUFFLENBQUE7SUFFcEMsTUFBTSxRQUFRLEdBQUcsSUFBSSxHQUFHLEVBQVUsQ0FBQTtJQUNsQyxPQUFPLEtBQUs7U0FDVCxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQW1DLEVBQUUsQ0FDaEQsSUFBSSxJQUFJLE9BQU8sSUFBSSxLQUFLLFFBQVEsQ0FDakM7U0FDQSxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUU7UUFDVixNQUFNLEdBQUcsR0FBRyxZQUFZLENBQUUsSUFBWSxDQUFDLEdBQUcsQ0FBQyxDQUFBO1FBQzNDLE1BQU0sSUFBSSxHQUFHLGFBQWEsQ0FBRSxJQUFZLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDOUMsTUFBTSxLQUFLLEdBQUcsY0FBYyxDQUFFLElBQVksQ0FBQyxLQUFLLENBQUMs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
|