@factorypure/client-helpers 1.0.18 → 1.0.19
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.d.ts +18 -0
- package/dist/index.js +177 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ export type ScrapeFiltersType = {
|
|
|
15
15
|
vendor_search_exclusions: string[];
|
|
16
16
|
search_exclusions: string[];
|
|
17
17
|
result_ignore_keys: ResultIgnoreType[];
|
|
18
|
+
brand_name_alternates: string[];
|
|
18
19
|
};
|
|
19
20
|
export type FilterOptionsType = {
|
|
20
21
|
exclude_linked_variants_enabled?: boolean;
|
|
@@ -72,3 +73,20 @@ export declare const calculateIgnoreStatus: (result: ScrapeResultsType, variant:
|
|
|
72
73
|
sku?: string;
|
|
73
74
|
}, result_ignore_keys: string[] | null) => boolean;
|
|
74
75
|
export declare function calculateVisibility(hide_reasons: string[], hide_override_reasons: string[]): boolean;
|
|
76
|
+
export declare const calculateHideReasons: (result: ScrapeResultsType, variant: {
|
|
77
|
+
id: number;
|
|
78
|
+
title: string;
|
|
79
|
+
sku: string;
|
|
80
|
+
price: number;
|
|
81
|
+
vendor: string;
|
|
82
|
+
regexUnitResults?: any;
|
|
83
|
+
}, variantScrapeOptions: ScrapeFiltersType) => string[];
|
|
84
|
+
export declare const calculateHideOverrideReasons: (result: ScrapeResultsType, variant: {
|
|
85
|
+
id: number;
|
|
86
|
+
title: string;
|
|
87
|
+
sku: string;
|
|
88
|
+
price: number;
|
|
89
|
+
vendor: string;
|
|
90
|
+
found_product_ids?: string[];
|
|
91
|
+
}) => string[];
|
|
92
|
+
export declare function findUnitVariations(data: any): any;
|
package/dist/index.js
CHANGED
|
@@ -671,3 +671,180 @@ function getUndercutThreshold(price, undercutThresholdRanges) {
|
|
|
671
671
|
const range = undercutThresholdRanges.find((r) => price >= r.min && price <= r.max);
|
|
672
672
|
return range ? range.threshold : 0.75; // fallback default
|
|
673
673
|
}
|
|
674
|
+
export const calculateHideReasons = (result, variant, variantScrapeOptions) => {
|
|
675
|
+
const hide_reasons = [];
|
|
676
|
+
if (variantScrapeOptions.result_ignore_keys && variantScrapeOptions.result_ignore_keys.length > 0) {
|
|
677
|
+
variantScrapeOptions.result_ignore_keys.forEach((key) => {
|
|
678
|
+
const resultKeyValues = [variant.id];
|
|
679
|
+
const keyValues = [];
|
|
680
|
+
const keyParts = JSON.parse(key.key_parts);
|
|
681
|
+
keyParts.forEach((part) => {
|
|
682
|
+
keyValues.push(key[part]);
|
|
683
|
+
if (part !== 'variant_id') {
|
|
684
|
+
resultKeyValues.push(result[part === 'price' ? 'extracted_price' : part]);
|
|
685
|
+
}
|
|
686
|
+
});
|
|
687
|
+
const parsedIgnoreKey = keyValues.join('-');
|
|
688
|
+
const resultIgnoreKey = resultKeyValues.join('-');
|
|
689
|
+
if (parsedIgnoreKey === resultIgnoreKey) {
|
|
690
|
+
key.reason === 'Ignored'
|
|
691
|
+
? hide_reasons.push('Manually ignored')
|
|
692
|
+
: hide_reasons.push('Manually excluded');
|
|
693
|
+
}
|
|
694
|
+
});
|
|
695
|
+
}
|
|
696
|
+
if (result.brand) {
|
|
697
|
+
const vendor = variant.vendor ? variant.vendor.toLowerCase() : null;
|
|
698
|
+
const brandNameAlternates = variantScrapeOptions.brand_name_alternates;
|
|
699
|
+
const targetBrands = [vendor, ...(brandNameAlternates || [])].filter((b) => b).map((b) => b?.toLowerCase());
|
|
700
|
+
const calcBrandMatched = result.brand && result.brand !== '' ? targetBrands.includes(result.brand.toLowerCase()) : null;
|
|
701
|
+
if (calcBrandMatched === false) {
|
|
702
|
+
hide_reasons.push('Calculated Brand Mismatch');
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
if (result.details_and_offers && result.details_and_offers.includes('Out of stock online')) {
|
|
706
|
+
hide_reasons.push('Out of stock online');
|
|
707
|
+
}
|
|
708
|
+
if (result.calculated_sku && result.calculated_sku?.toLowerCase() !== variant.sku.toLowerCase()) {
|
|
709
|
+
hide_reasons.push('Calculated SKU Mismatch');
|
|
710
|
+
}
|
|
711
|
+
if (result.regexUnitResults && variant.regexUnitResults) {
|
|
712
|
+
const [regexIgnore, regexIgnoreReasons] = getRegexUnitResultsIgnore(result.regexUnitResults, variant.regexUnitResults, result, variant);
|
|
713
|
+
if (regexIgnore) {
|
|
714
|
+
hide_reasons.push(...regexIgnoreReasons);
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
const refurbishedKeywords = [
|
|
718
|
+
'refurbished',
|
|
719
|
+
'renewed',
|
|
720
|
+
'reconditioned',
|
|
721
|
+
'refurb',
|
|
722
|
+
'remanufactured',
|
|
723
|
+
'scratch',
|
|
724
|
+
'dent',
|
|
725
|
+
'used',
|
|
726
|
+
`${variant.sku}-R`,
|
|
727
|
+
`${variant.sku}-R`.toLowerCase(),
|
|
728
|
+
`${variant.sku}-R`.toUpperCase(),
|
|
729
|
+
`${variant.sku?.toLowerCase()}-R`,
|
|
730
|
+
`${variant.sku?.toUpperCase()}-R`,
|
|
731
|
+
];
|
|
732
|
+
const normalizedTitle = result.title.toLowerCase().replace(/[^a-z0-9-]/g, ' ');
|
|
733
|
+
const isRefurbished = refurbishedKeywords.some((keyword) => normalizedTitle.split(/\s+/).includes(keyword)) ||
|
|
734
|
+
(result.details_and_offers && result.details_and_offers.includes('Pre-owned'));
|
|
735
|
+
if (isRefurbished) {
|
|
736
|
+
hide_reasons.push('Refurbished/Used');
|
|
737
|
+
}
|
|
738
|
+
return hide_reasons;
|
|
739
|
+
};
|
|
740
|
+
export const calculateHideOverrideReasons = (result, variant) => {
|
|
741
|
+
const hide_override_reasons = [];
|
|
742
|
+
const skuRegex = new RegExp(`\\b${variant.sku}\\b`, 'gi');
|
|
743
|
+
if (skuRegex.test(result.title)) {
|
|
744
|
+
hide_override_reasons.push('SKU Match');
|
|
745
|
+
}
|
|
746
|
+
if (variant.sku.toLowerCase() === result.calculated_sku?.toLowerCase()) {
|
|
747
|
+
hide_override_reasons.push('Calculated SKU Match');
|
|
748
|
+
}
|
|
749
|
+
if (variant.found_product_ids && variant.found_product_ids.includes(result.found_product_id)) {
|
|
750
|
+
hide_override_reasons.push('Product Id Linked');
|
|
751
|
+
}
|
|
752
|
+
return hide_override_reasons;
|
|
753
|
+
};
|
|
754
|
+
function getRegexUnitResultsIgnore(resultRegexResults, variantRegexResults, result, variant) {
|
|
755
|
+
const failedUnits = [];
|
|
756
|
+
for (const unit in variantRegexResults) {
|
|
757
|
+
const variations = variantRegexResults[unit];
|
|
758
|
+
if (variations.length === 0)
|
|
759
|
+
continue;
|
|
760
|
+
const mostCommonVariation = variations[0];
|
|
761
|
+
const targetVariations = resultRegexResults[unit] || [];
|
|
762
|
+
if (targetVariations.length === 0)
|
|
763
|
+
continue;
|
|
764
|
+
const matchingVariation = resultRegexResults[unit].find((v) => v.normalized === mostCommonVariation.normalized);
|
|
765
|
+
if (!matchingVariation) {
|
|
766
|
+
// A unit exists in both the target and variant, but no matching variations were found
|
|
767
|
+
failedUnits.push(unit);
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
const criticalUnits = ['ton', 'cc', 'hp'];
|
|
771
|
+
const ignoreReasons = [];
|
|
772
|
+
for (const criticalUnit of criticalUnits) {
|
|
773
|
+
if (failedUnits.includes(criticalUnit)) {
|
|
774
|
+
ignoreReasons.push(`Critical Spec Mismatch`);
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
if (ignoreReasons.length === 0) {
|
|
778
|
+
return [false, []];
|
|
779
|
+
}
|
|
780
|
+
else {
|
|
781
|
+
return [true, ignoreReasons];
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
export function findUnitVariations(data) {
|
|
785
|
+
const units = ['inch', 'cm', 'hp', 'cc', 'ton', 'lbs', 'volts', 'amp', 'ah', 'watt', 'mph', 'mile'];
|
|
786
|
+
const results = {
|
|
787
|
+
inch: [],
|
|
788
|
+
cm: [],
|
|
789
|
+
hp: [],
|
|
790
|
+
cc: [],
|
|
791
|
+
ton: [],
|
|
792
|
+
lbs: [],
|
|
793
|
+
volts: [],
|
|
794
|
+
amp: [],
|
|
795
|
+
watt: [],
|
|
796
|
+
mph: [],
|
|
797
|
+
mile: [],
|
|
798
|
+
ah: [],
|
|
799
|
+
};
|
|
800
|
+
units.forEach((unit) => {
|
|
801
|
+
const escapedUnit = unit.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
|
|
802
|
+
let variationsRegex;
|
|
803
|
+
if (unit === '"' || unit.toLowerCase() === 'inch') {
|
|
804
|
+
// Match numbers (integer or decimal) followed by ", ”, in, inch, inches, -in, - inch, etc.
|
|
805
|
+
variationsRegex = /\b\d+(\.\d+)?-?\s*(?:(\\"|\\u201d)|("|”)|in(ch(es)?)?|-\s*in(ch(es)?)?)/gi;
|
|
806
|
+
}
|
|
807
|
+
else if (unit.toLowerCase() === 'cm') {
|
|
808
|
+
variationsRegex = /\b\d+(\.\d+)?-?\s*(cm|centimeter(s)?)/gi;
|
|
809
|
+
}
|
|
810
|
+
else if (unit.toLowerCase() === 'volts') {
|
|
811
|
+
variationsRegex = /\b\d+(\.\d+)?-?\s*(v|volts|volt)/gi;
|
|
812
|
+
}
|
|
813
|
+
else if (unit.toLowerCase() === 'lbs') {
|
|
814
|
+
variationsRegex = /\b\d+(\.\d+)?-?\s*(lb|lbs|pounds|pound)/gi;
|
|
815
|
+
}
|
|
816
|
+
else if (unit.toLowerCase() === 'hp') {
|
|
817
|
+
variationsRegex = /\b\d+(\.\d+)?-?\s*(hp|horsepower|horse power)/gi;
|
|
818
|
+
}
|
|
819
|
+
else if (unit.toLowerCase() === 'mph') {
|
|
820
|
+
variationsRegex = /\b\d+(\.\d+)?-?\s*(mph|miles per hour|mile per hour)/gi;
|
|
821
|
+
}
|
|
822
|
+
else if (unit.toLowerCase() === 'amp') {
|
|
823
|
+
variationsRegex = /\b\d+(\.\d+)?-?\s*(?<!A?W?G\s*)(A\b|amp\b|amps\b|amperes\b|ampere\b)/gi;
|
|
824
|
+
}
|
|
825
|
+
else if (unit.toLowerCase() === 'ah') {
|
|
826
|
+
variationsRegex = /\b\d+(\.\d+)?-?\s*(ah|ampere hours|amp hour|amp hours)/gi;
|
|
827
|
+
}
|
|
828
|
+
else if (unit.toLowerCase() === 'cc') {
|
|
829
|
+
variationsRegex = /\b\d+(\.\d+)?-?\s*(cc|cubic centimeters|cubic centimeter)/gi;
|
|
830
|
+
}
|
|
831
|
+
else if (unit.toLowerCase() === 'ton') {
|
|
832
|
+
variationsRegex = /\b\d+(\.\d+)?\s*-?\s*(ton|tons)/gi;
|
|
833
|
+
}
|
|
834
|
+
else {
|
|
835
|
+
// Generic: number + unit, with optional dash or space
|
|
836
|
+
variationsRegex = new RegExp(`\\b\\d+(\\.\\d+)?\\s*(-?\\s*${escapedUnit})`, 'gi');
|
|
837
|
+
}
|
|
838
|
+
const matches = [];
|
|
839
|
+
const sampleText = JSON.stringify(data);
|
|
840
|
+
let match;
|
|
841
|
+
while ((match = variationsRegex.exec(sampleText)) !== null) {
|
|
842
|
+
matches.push({ value: match[0], source: match[0], normalized: match[0].replace(/[^\d.]/g, '') });
|
|
843
|
+
}
|
|
844
|
+
results[unit] = matches;
|
|
845
|
+
if (results[unit].length === 0) {
|
|
846
|
+
delete results[unit];
|
|
847
|
+
}
|
|
848
|
+
});
|
|
849
|
+
return results;
|
|
850
|
+
}
|