@factorypure/client-helpers 1.1.28 → 1.2.0
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/dist/index.js +73 -40
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -480,7 +480,6 @@ export const ABSOLUTE_BLOCK_RULE_IDS = [
|
|
|
480
480
|
'duplicate',
|
|
481
481
|
'high_price_outlier',
|
|
482
482
|
'low_price_outlier',
|
|
483
|
-
'skip_sku',
|
|
484
483
|
];
|
|
485
484
|
/**
|
|
486
485
|
* Rule IDs that can be overridden when the matching-engine confidence is high enough.
|
|
@@ -496,6 +495,7 @@ export const CONFIDENCE_OVERRIDABLE_RULE_IDS = [
|
|
|
496
495
|
'competitor_exclusion',
|
|
497
496
|
'date_outlier',
|
|
498
497
|
'critical_spec_mismatch',
|
|
498
|
+
'skip_sku',
|
|
499
499
|
];
|
|
500
500
|
/**
|
|
501
501
|
* Evaluates whether a result should be surfaced given its filter state and matching confidence.
|
|
@@ -524,7 +524,6 @@ export function evaluateConfidenceOverride(filterResults, visibilityState, confi
|
|
|
524
524
|
return 'show_with_override';
|
|
525
525
|
return 'hide';
|
|
526
526
|
}
|
|
527
|
-
// const wattages = Array.from({ length: 41 }, (_, i) => (5000 + i * 500).toString())
|
|
528
527
|
// ===============================
|
|
529
528
|
// Filter Rule Registry
|
|
530
529
|
// ===============================
|
|
@@ -908,6 +907,7 @@ class SearchExclusionRule {
|
|
|
908
907
|
return null;
|
|
909
908
|
}
|
|
910
909
|
}
|
|
910
|
+
const skipSkuRegexCache = new Map();
|
|
911
911
|
/**
|
|
912
912
|
* Rule for SKU skip filtering
|
|
913
913
|
*/
|
|
@@ -921,28 +921,32 @@ class SkipSkuRule {
|
|
|
921
921
|
canBeOverridden = true;
|
|
922
922
|
overridableBy = ['sku_match', 'calculated_sku_match', 'alt_sku_match'];
|
|
923
923
|
evaluate(context) {
|
|
924
|
-
const
|
|
925
|
-
const
|
|
926
|
-
|
|
927
|
-
.
|
|
928
|
-
|
|
929
|
-
nots.
|
|
930
|
-
|
|
924
|
+
const variantSkuLower = context.variant.sku.toLowerCase();
|
|
925
|
+
const allSkus = [
|
|
926
|
+
...context.vendorScrapeOptions.default_skip_skus,
|
|
927
|
+
...context.vendorScrapeOptions.vendor_skip_skus,
|
|
928
|
+
];
|
|
929
|
+
const nots = allSkus.filter((s) => s.toLowerCase() !== variantSkuLower);
|
|
930
|
+
if (nots.length === 0)
|
|
931
|
+
return null;
|
|
931
932
|
const skuAlternates = context.variantScrapeOptions.sku_alternates || [];
|
|
932
|
-
const
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
const
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
}
|
|
944
|
-
|
|
945
|
-
}
|
|
933
|
+
const cacheKey = variantSkuLower + '\x00' + nots.join('\x00') + '\x01' + skuAlternates.join('\x00');
|
|
934
|
+
let cached = skipSkuRegexCache.get(cacheKey);
|
|
935
|
+
if (!cached) {
|
|
936
|
+
const alternatesSet = new Set(skuAlternates.map((a) => a.toLowerCase()));
|
|
937
|
+
// Only build regex for SKUs that are not alternates (alternates can never be exclusions)
|
|
938
|
+
const nonAlternateNots = nots.filter((s) => !alternatesSet.has(s.toLowerCase()));
|
|
939
|
+
const regex = nonAlternateNots.length > 0
|
|
940
|
+
? new RegExp(`(?: |\/|\&|\=|"|'|\`)(?:${nonAlternateNots
|
|
941
|
+
.map((s) => s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'))
|
|
942
|
+
.join('|')})(?: |\/|\&|\=|"|'|\`)`, 'i')
|
|
943
|
+
: null;
|
|
944
|
+
cached = { regex: regex, alternatesSet };
|
|
945
|
+
skipSkuRegexCache.set(cacheKey, cached);
|
|
946
|
+
}
|
|
947
|
+
if (!cached.regex)
|
|
948
|
+
return null;
|
|
949
|
+
const hasExclusion = cached.regex.test(context.result.title ?? '');
|
|
946
950
|
if (hasExclusion) {
|
|
947
951
|
return {
|
|
948
952
|
ruleId: this.id,
|
|
@@ -955,6 +959,7 @@ class SkipSkuRule {
|
|
|
955
959
|
return null;
|
|
956
960
|
}
|
|
957
961
|
}
|
|
962
|
+
const vendorExclusionRegexCache = new Map();
|
|
958
963
|
/**
|
|
959
964
|
* Rule for vendor exclusions
|
|
960
965
|
*/
|
|
@@ -967,18 +972,42 @@ class VendorExclusionRule {
|
|
|
967
972
|
enabled = true;
|
|
968
973
|
canBeOverridden = true;
|
|
969
974
|
overridableBy = ['sku_match', 'calculated_sku_match', 'alt_sku_match', 'match_confirmation_override'];
|
|
975
|
+
// evaluate(context: FilterContext): FilterResult | null {
|
|
976
|
+
// const nots: string[] = []
|
|
977
|
+
// const formatted = context.vendorScrapeOptions.default_skip_vendors
|
|
978
|
+
// .filter((s) => s.toLowerCase() !== context.variant.vendor.toLowerCase())
|
|
979
|
+
// .map((s) => `${s}`)
|
|
980
|
+
// nots.push(...formatted)
|
|
981
|
+
// const hasExclusion = nots.some((vendor) => {
|
|
982
|
+
// const escaped = vendor.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')
|
|
983
|
+
// const matchRegex = new RegExp(`(?: |\/|\&|\=|"|'|\`)${escaped}(?: |\/|\&|\=|"|'|\`)`, 'gi')
|
|
984
|
+
// const matches = context.result.title?.match(matchRegex)
|
|
985
|
+
// return matches && matches.length > 0
|
|
986
|
+
// })
|
|
987
|
+
// if (hasExclusion) {
|
|
988
|
+
// return {
|
|
989
|
+
// ruleId: this.id,
|
|
990
|
+
// severity: this.severity,
|
|
991
|
+
// message: HIDE_REASONS.VENDOR_EXCLUSION,
|
|
992
|
+
// metadata: { title: context.result.title },
|
|
993
|
+
// timestamp: new Date().toISOString(),
|
|
994
|
+
// }
|
|
995
|
+
// }
|
|
996
|
+
// return null
|
|
997
|
+
// }
|
|
970
998
|
evaluate(context) {
|
|
971
|
-
const
|
|
972
|
-
const
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
const
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
}
|
|
999
|
+
const variantVendorLower = context.variant.vendor.toLowerCase();
|
|
1000
|
+
const vendors = context.vendorScrapeOptions.default_skip_vendors.filter((s) => s.toLowerCase() !== variantVendorLower);
|
|
1001
|
+
if (vendors.length === 0)
|
|
1002
|
+
return null;
|
|
1003
|
+
const cacheKey = variantVendorLower + '\x00' + vendors.join('\x00');
|
|
1004
|
+
let matchRegex = vendorExclusionRegexCache.get(cacheKey);
|
|
1005
|
+
if (!matchRegex) {
|
|
1006
|
+
const combinedPattern = vendors.map((s) => s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')).join('|');
|
|
1007
|
+
matchRegex = new RegExp(`(?: |\/|\&|\=|"|'|\`)(?:${combinedPattern})(?: |\/|\&|\=|"|'|\`)`, 'i');
|
|
1008
|
+
vendorExclusionRegexCache.set(cacheKey, matchRegex);
|
|
1009
|
+
}
|
|
1010
|
+
const hasExclusion = matchRegex.test(context.result.title ?? '');
|
|
982
1011
|
if (hasExclusion) {
|
|
983
1012
|
return {
|
|
984
1013
|
ruleId: this.id,
|
|
@@ -1255,8 +1284,9 @@ class RefurbishedUsedRule {
|
|
|
1255
1284
|
evaluate(context) {
|
|
1256
1285
|
const refurbishedKeywords = getRefurbishedKeywords(context.variant);
|
|
1257
1286
|
const normalizedTitle = context.result.title?.toLowerCase().replace(/[^a-z0-9-]/g, ' ') ?? '';
|
|
1287
|
+
const titleWords = normalizedTitle.split(/\s+/);
|
|
1258
1288
|
const details = context.result.details_and_offers;
|
|
1259
|
-
const isRefurbished = refurbishedKeywords.some((keyword) =>
|
|
1289
|
+
const isRefurbished = refurbishedKeywords.some((keyword) => titleWords.includes(keyword)) ||
|
|
1260
1290
|
(details && details.includes('Pre-owned'));
|
|
1261
1291
|
if (isRefurbished) {
|
|
1262
1292
|
return {
|
|
@@ -1624,6 +1654,9 @@ export function createCustomFilterRule(config) {
|
|
|
1624
1654
|
* This provides more flexibility and better extensibility than the legacy filterScrapeResults
|
|
1625
1655
|
*/
|
|
1626
1656
|
export const filterScrapeResultsV2 = ({ scrapeResults, variant, variantScrapeOptions, vendorScrapeOptions, globalScrapeOptions, filterConfig, customRules, comparisonMap, matchConfirmationMap, }) => {
|
|
1657
|
+
if (scrapeResults.length === 0 || !scrapeResults) {
|
|
1658
|
+
return [];
|
|
1659
|
+
}
|
|
1627
1660
|
const registry = createDefaultFilterRegistry();
|
|
1628
1661
|
// Register custom rules if provided
|
|
1629
1662
|
if (customRules) {
|
|
@@ -2024,11 +2057,9 @@ export const getRefurbishedKeywords = (variant) => {
|
|
|
2024
2057
|
];
|
|
2025
2058
|
if (variant?.sku) {
|
|
2026
2059
|
const skuBasedKeywords = [
|
|
2060
|
+
`${variant.sku.toLowerCase()}-r`,
|
|
2061
|
+
`${variant.sku.toUpperCase()}-R`,
|
|
2027
2062
|
`${variant.sku}-R`,
|
|
2028
|
-
`${variant.sku}-R`.toLowerCase(),
|
|
2029
|
-
`${variant.sku}-R`.toUpperCase(),
|
|
2030
|
-
`${variant.sku?.toLowerCase()}-R`,
|
|
2031
|
-
`${variant.sku?.toUpperCase()}-R`,
|
|
2032
2063
|
];
|
|
2033
2064
|
refurbishedKeywords.push(...skuBasedKeywords);
|
|
2034
2065
|
}
|
|
@@ -2251,7 +2282,9 @@ export function getShownResults(matchResult, sortedResults, minConfidence, sortD
|
|
|
2251
2282
|
shownResults.push(foundResult);
|
|
2252
2283
|
}
|
|
2253
2284
|
else if (foundResult &&
|
|
2254
|
-
foundResult.filter_results?.
|
|
2285
|
+
foundResult.filter_results?.some((fr) => fr?.metadata?.isOverride === true)
|
|
2286
|
+
// foundResult.filter_results?.map((fr: FilterResult) => fr.ruleId).includes('match_confirmation_override')
|
|
2287
|
+
) {
|
|
2255
2288
|
shownResults.push(foundResult);
|
|
2256
2289
|
}
|
|
2257
2290
|
});
|