@factorypure/client-helpers 1.1.9 → 1.1.11

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 (2) hide show
  1. package/dist/index.js +62 -21
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -740,7 +740,7 @@ class SearchExclusionRule {
740
740
  priority = 60;
741
741
  enabled = true;
742
742
  canBeOverridden = true;
743
- overridableBy = ['sku_match', 'calculated_sku_match'];
743
+ overridableBy = ['sku_match', 'calculated_sku_match', 'alt_sku_match'];
744
744
  evaluate(context) {
745
745
  // This is handled in batch processing due to FlexSearch requirement
746
746
  return null;
@@ -757,7 +757,7 @@ class SkipSkuRule {
757
757
  priority = 50;
758
758
  enabled = true;
759
759
  canBeOverridden = true;
760
- overridableBy = ['sku_match', 'calculated_sku_match'];
760
+ overridableBy = ['sku_match', 'calculated_sku_match', 'alt_sku_match'];
761
761
  evaluate(context) {
762
762
  const nots = [];
763
763
  const formatted = context.vendorScrapeOptions.default_skip_skus
@@ -765,11 +765,21 @@ class SkipSkuRule {
765
765
  .map((s) => `${s}`);
766
766
  nots.push(...formatted);
767
767
  nots.push(...context.vendorScrapeOptions.vendor_skip_skus.filter((s) => s.toLowerCase() !== context.variant.sku.toLowerCase()));
768
+ // Get SKU alternates for comparison
769
+ const skuAlternates = context.variantScrapeOptions.sku_alternates || [];
770
+ const skuAlternatesLower = skuAlternates.map((alt) => alt.toLowerCase());
768
771
  const hasExclusion = nots.some((sku) => {
769
772
  const escapedSku = sku.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
770
773
  const skuRegex = new RegExp(`(?: |\/|\&|\=|"|'|\`)${escapedSku}(?: |\/|\&|\=|"|'|\`)`, 'gi');
771
774
  const skuMatches = context.result.title?.match(skuRegex);
772
- return skuMatches && skuMatches.length > 0;
775
+ // If this skip SKU is found in the title
776
+ if (skuMatches && skuMatches.length > 0) {
777
+ // Check if this skip SKU is actually one of the variant's alternates
778
+ const isAlternate = skuAlternatesLower.includes(sku.toLowerCase());
779
+ // Only count as exclusion if it's NOT an alternate
780
+ return !isAlternate;
781
+ }
782
+ return false;
773
783
  });
774
784
  if (hasExclusion) {
775
785
  return {
@@ -794,7 +804,7 @@ class VendorExclusionRule {
794
804
  priority = 50;
795
805
  enabled = true;
796
806
  canBeOverridden = true;
797
- overridableBy = ['sku_match', 'calculated_sku_match'];
807
+ overridableBy = ['sku_match', 'calculated_sku_match', 'alt_sku_match'];
798
808
  evaluate(context) {
799
809
  const nots = [];
800
810
  const formatted = context.vendorScrapeOptions.default_skip_vendors
@@ -964,22 +974,36 @@ class CalculatedSkuMismatchRule {
964
974
  priority = 30;
965
975
  enabled = true;
966
976
  canBeOverridden = true;
967
- overridableBy = ['sku_match', 'calculated_sku_match'];
977
+ overridableBy = ['sku_match', 'calculated_sku_match', 'alt_sku_match'];
968
978
  evaluate(context) {
969
979
  const result = context.result;
970
- if (result.calculated_sku && result.calculated_sku?.toLowerCase() !== context.variant.sku.toLowerCase()) {
971
- return {
972
- ruleId: this.id,
973
- severity: this.severity,
974
- message: HIDE_REASONS.CALCULATED_SKU_MISMATCH,
975
- metadata: {
976
- calculatedSku: result.calculated_sku,
977
- variantSku: context.variant.sku,
978
- },
979
- timestamp: new Date().toISOString(),
980
- };
980
+ if (!result.calculated_sku) {
981
+ return null;
981
982
  }
982
- return null;
983
+ const calculatedSkuLower = result.calculated_sku.toLowerCase();
984
+ const variantSkuLower = context.variant.sku.toLowerCase();
985
+ // Check if calculated SKU matches variant SKU
986
+ if (calculatedSkuLower === variantSkuLower) {
987
+ return null;
988
+ }
989
+ // Check if calculated SKU matches any SKU alternates
990
+ const skuAlternates = context.variantScrapeOptions.sku_alternates || [];
991
+ const matchesAlternate = skuAlternates.some((alt) => alt.toLowerCase() === calculatedSkuLower);
992
+ if (matchesAlternate) {
993
+ return null;
994
+ }
995
+ // If no match found, trigger the rule
996
+ return {
997
+ ruleId: this.id,
998
+ severity: this.severity,
999
+ message: HIDE_REASONS.CALCULATED_SKU_MISMATCH,
1000
+ metadata: {
1001
+ calculatedSku: result.calculated_sku,
1002
+ variantSku: context.variant.sku,
1003
+ skuAlternates: skuAlternates,
1004
+ },
1005
+ timestamp: new Date().toISOString(),
1006
+ };
983
1007
  }
984
1008
  }
985
1009
  /**
@@ -993,7 +1017,7 @@ class CriticalSpecMismatchRule {
993
1017
  priority = 35;
994
1018
  enabled = true;
995
1019
  canBeOverridden = true;
996
- overridableBy = ['sku_match', 'calculated_sku_match'];
1020
+ overridableBy = ['sku_match', 'calculated_sku_match', 'alt_sku_match'];
997
1021
  evaluate(context) {
998
1022
  if (!context.result.regexUnitResults || !context.variant.regexUnitResults) {
999
1023
  return null;
@@ -1022,7 +1046,7 @@ class RefurbishedUsedRule {
1022
1046
  priority = 25;
1023
1047
  enabled = true;
1024
1048
  canBeOverridden = true;
1025
- overridableBy = ['sku_match', 'calculated_sku_match'];
1049
+ overridableBy = [];
1026
1050
  evaluate(context) {
1027
1051
  const refurbishedKeywords = getRefurbishedKeywords(context.variant);
1028
1052
  const normalizedTitle = context.result.title?.toLowerCase().replace(/[^a-z0-9-]/g, ' ') ?? '';
@@ -1085,7 +1109,12 @@ class CalculatedSkuMatchOverrideRule {
1085
1109
  overridableBy = [];
1086
1110
  evaluate(context) {
1087
1111
  const result = context.result;
1088
- if (context.variant.sku.toLowerCase() === result.calculated_sku?.toLowerCase()) {
1112
+ if (!result.calculated_sku)
1113
+ return null;
1114
+ const calculatedSkuLower = result.calculated_sku.toLowerCase();
1115
+ const variantSkuLower = context.variant.sku.toLowerCase();
1116
+ // Check main SKU
1117
+ if (calculatedSkuLower === variantSkuLower) {
1089
1118
  return {
1090
1119
  ruleId: this.id,
1091
1120
  severity: this.severity,
@@ -1094,6 +1123,18 @@ class CalculatedSkuMatchOverrideRule {
1094
1123
  timestamp: new Date().toISOString(),
1095
1124
  };
1096
1125
  }
1126
+ // Check SKU alternates
1127
+ const skuAlternates = context.variantScrapeOptions.sku_alternates || [];
1128
+ const matchesAlternate = skuAlternates.some((alt) => alt.toLowerCase() === calculatedSkuLower);
1129
+ if (matchesAlternate) {
1130
+ return {
1131
+ ruleId: this.id,
1132
+ severity: this.severity,
1133
+ message: HIDE_OVERRIDE_REASONS.CALCULATED_SKU_MATCH,
1134
+ metadata: { isOverride: true, calculatedSku: result.calculated_sku, matchedAlternate: true },
1135
+ timestamp: new Date().toISOString(),
1136
+ };
1137
+ }
1097
1138
  return null;
1098
1139
  }
1099
1140
  }
@@ -1305,7 +1346,7 @@ export const filterScrapeResultsV2 = ({ scrapeResults, variant, variantScrapeOpt
1305
1346
  function handleDuplicatesV2(results) {
1306
1347
  const filteredUniqueResultsMap = {};
1307
1348
  results.forEach((item) => {
1308
- const key = `${item.source}-${item.title}-${item.extracted_price}`;
1349
+ const key = `${item.source}-${item.title}-${item.extracted_total ?? item.extracted_price}`;
1309
1350
  if (!filteredUniqueResultsMap[key]) {
1310
1351
  filteredUniqueResultsMap[key] = item;
1311
1352
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@factorypure/client-helpers",
3
- "version": "1.1.9",
3
+ "version": "1.1.11",
4
4
  "description": "",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",