@factorypure/client-helpers 1.1.28 → 1.1.29
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 +69 -37
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -908,6 +908,7 @@ class SearchExclusionRule {
|
|
|
908
908
|
return null;
|
|
909
909
|
}
|
|
910
910
|
}
|
|
911
|
+
const skipSkuRegexCache = new Map();
|
|
911
912
|
/**
|
|
912
913
|
* Rule for SKU skip filtering
|
|
913
914
|
*/
|
|
@@ -921,28 +922,32 @@ class SkipSkuRule {
|
|
|
921
922
|
canBeOverridden = true;
|
|
922
923
|
overridableBy = ['sku_match', 'calculated_sku_match', 'alt_sku_match'];
|
|
923
924
|
evaluate(context) {
|
|
924
|
-
const
|
|
925
|
-
const
|
|
926
|
-
|
|
927
|
-
.
|
|
928
|
-
|
|
929
|
-
nots.
|
|
930
|
-
|
|
925
|
+
const variantSkuLower = context.variant.sku.toLowerCase();
|
|
926
|
+
const allSkus = [
|
|
927
|
+
...context.vendorScrapeOptions.default_skip_skus,
|
|
928
|
+
...context.vendorScrapeOptions.vendor_skip_skus,
|
|
929
|
+
];
|
|
930
|
+
const nots = allSkus.filter((s) => s.toLowerCase() !== variantSkuLower);
|
|
931
|
+
if (nots.length === 0)
|
|
932
|
+
return null;
|
|
931
933
|
const skuAlternates = context.variantScrapeOptions.sku_alternates || [];
|
|
932
|
-
const
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
const
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
}
|
|
944
|
-
|
|
945
|
-
}
|
|
934
|
+
const cacheKey = variantSkuLower + '\x00' + nots.join('\x00') + '\x01' + skuAlternates.join('\x00');
|
|
935
|
+
let cached = skipSkuRegexCache.get(cacheKey);
|
|
936
|
+
if (!cached) {
|
|
937
|
+
const alternatesSet = new Set(skuAlternates.map((a) => a.toLowerCase()));
|
|
938
|
+
// Only build regex for SKUs that are not alternates (alternates can never be exclusions)
|
|
939
|
+
const nonAlternateNots = nots.filter((s) => !alternatesSet.has(s.toLowerCase()));
|
|
940
|
+
const regex = nonAlternateNots.length > 0
|
|
941
|
+
? new RegExp(`(?: |\/|\&|\=|"|'|\`)(?:${nonAlternateNots
|
|
942
|
+
.map((s) => s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'))
|
|
943
|
+
.join('|')})(?: |\/|\&|\=|"|'|\`)`, 'i')
|
|
944
|
+
: null;
|
|
945
|
+
cached = { regex: regex, alternatesSet };
|
|
946
|
+
skipSkuRegexCache.set(cacheKey, cached);
|
|
947
|
+
}
|
|
948
|
+
if (!cached.regex)
|
|
949
|
+
return null;
|
|
950
|
+
const hasExclusion = cached.regex.test(context.result.title ?? '');
|
|
946
951
|
if (hasExclusion) {
|
|
947
952
|
return {
|
|
948
953
|
ruleId: this.id,
|
|
@@ -955,6 +960,7 @@ class SkipSkuRule {
|
|
|
955
960
|
return null;
|
|
956
961
|
}
|
|
957
962
|
}
|
|
963
|
+
const vendorExclusionRegexCache = new Map();
|
|
958
964
|
/**
|
|
959
965
|
* Rule for vendor exclusions
|
|
960
966
|
*/
|
|
@@ -967,18 +973,42 @@ class VendorExclusionRule {
|
|
|
967
973
|
enabled = true;
|
|
968
974
|
canBeOverridden = true;
|
|
969
975
|
overridableBy = ['sku_match', 'calculated_sku_match', 'alt_sku_match', 'match_confirmation_override'];
|
|
976
|
+
// evaluate(context: FilterContext): FilterResult | null {
|
|
977
|
+
// const nots: string[] = []
|
|
978
|
+
// const formatted = context.vendorScrapeOptions.default_skip_vendors
|
|
979
|
+
// .filter((s) => s.toLowerCase() !== context.variant.vendor.toLowerCase())
|
|
980
|
+
// .map((s) => `${s}`)
|
|
981
|
+
// nots.push(...formatted)
|
|
982
|
+
// const hasExclusion = nots.some((vendor) => {
|
|
983
|
+
// const escaped = vendor.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')
|
|
984
|
+
// const matchRegex = new RegExp(`(?: |\/|\&|\=|"|'|\`)${escaped}(?: |\/|\&|\=|"|'|\`)`, 'gi')
|
|
985
|
+
// const matches = context.result.title?.match(matchRegex)
|
|
986
|
+
// return matches && matches.length > 0
|
|
987
|
+
// })
|
|
988
|
+
// if (hasExclusion) {
|
|
989
|
+
// return {
|
|
990
|
+
// ruleId: this.id,
|
|
991
|
+
// severity: this.severity,
|
|
992
|
+
// message: HIDE_REASONS.VENDOR_EXCLUSION,
|
|
993
|
+
// metadata: { title: context.result.title },
|
|
994
|
+
// timestamp: new Date().toISOString(),
|
|
995
|
+
// }
|
|
996
|
+
// }
|
|
997
|
+
// return null
|
|
998
|
+
// }
|
|
970
999
|
evaluate(context) {
|
|
971
|
-
const
|
|
972
|
-
const
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
const
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
}
|
|
1000
|
+
const variantVendorLower = context.variant.vendor.toLowerCase();
|
|
1001
|
+
const vendors = context.vendorScrapeOptions.default_skip_vendors.filter((s) => s.toLowerCase() !== variantVendorLower);
|
|
1002
|
+
if (vendors.length === 0)
|
|
1003
|
+
return null;
|
|
1004
|
+
const cacheKey = variantVendorLower + '\x00' + vendors.join('\x00');
|
|
1005
|
+
let matchRegex = vendorExclusionRegexCache.get(cacheKey);
|
|
1006
|
+
if (!matchRegex) {
|
|
1007
|
+
const combinedPattern = vendors.map((s) => s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')).join('|');
|
|
1008
|
+
matchRegex = new RegExp(`(?: |\/|\&|\=|"|'|\`)(?:${combinedPattern})(?: |\/|\&|\=|"|'|\`)`, 'i');
|
|
1009
|
+
vendorExclusionRegexCache.set(cacheKey, matchRegex);
|
|
1010
|
+
}
|
|
1011
|
+
const hasExclusion = matchRegex.test(context.result.title ?? '');
|
|
982
1012
|
if (hasExclusion) {
|
|
983
1013
|
return {
|
|
984
1014
|
ruleId: this.id,
|
|
@@ -1255,8 +1285,9 @@ class RefurbishedUsedRule {
|
|
|
1255
1285
|
evaluate(context) {
|
|
1256
1286
|
const refurbishedKeywords = getRefurbishedKeywords(context.variant);
|
|
1257
1287
|
const normalizedTitle = context.result.title?.toLowerCase().replace(/[^a-z0-9-]/g, ' ') ?? '';
|
|
1288
|
+
const titleWords = normalizedTitle.split(/\s+/);
|
|
1258
1289
|
const details = context.result.details_and_offers;
|
|
1259
|
-
const isRefurbished = refurbishedKeywords.some((keyword) =>
|
|
1290
|
+
const isRefurbished = refurbishedKeywords.some((keyword) => titleWords.includes(keyword)) ||
|
|
1260
1291
|
(details && details.includes('Pre-owned'));
|
|
1261
1292
|
if (isRefurbished) {
|
|
1262
1293
|
return {
|
|
@@ -1624,6 +1655,9 @@ export function createCustomFilterRule(config) {
|
|
|
1624
1655
|
* This provides more flexibility and better extensibility than the legacy filterScrapeResults
|
|
1625
1656
|
*/
|
|
1626
1657
|
export const filterScrapeResultsV2 = ({ scrapeResults, variant, variantScrapeOptions, vendorScrapeOptions, globalScrapeOptions, filterConfig, customRules, comparisonMap, matchConfirmationMap, }) => {
|
|
1658
|
+
if (scrapeResults.length === 0 || !scrapeResults) {
|
|
1659
|
+
return [];
|
|
1660
|
+
}
|
|
1627
1661
|
const registry = createDefaultFilterRegistry();
|
|
1628
1662
|
// Register custom rules if provided
|
|
1629
1663
|
if (customRules) {
|
|
@@ -2024,11 +2058,9 @@ export const getRefurbishedKeywords = (variant) => {
|
|
|
2024
2058
|
];
|
|
2025
2059
|
if (variant?.sku) {
|
|
2026
2060
|
const skuBasedKeywords = [
|
|
2061
|
+
`${variant.sku.toLowerCase()}-r`,
|
|
2062
|
+
`${variant.sku.toUpperCase()}-R`,
|
|
2027
2063
|
`${variant.sku}-R`,
|
|
2028
|
-
`${variant.sku}-R`.toLowerCase(),
|
|
2029
|
-
`${variant.sku}-R`.toUpperCase(),
|
|
2030
|
-
`${variant.sku?.toLowerCase()}-R`,
|
|
2031
|
-
`${variant.sku?.toUpperCase()}-R`,
|
|
2032
2064
|
];
|
|
2033
2065
|
refurbishedKeywords.push(...skuBasedKeywords);
|
|
2034
2066
|
}
|