@factorypure/client-helpers 1.0.14 → 1.0.16
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 +20 -1
- package/dist/index.js +379 -65
- package/package.json +25 -25
package/dist/index.d.ts
CHANGED
|
@@ -28,7 +28,25 @@ export type FilterOptionsType = {
|
|
|
28
28
|
search_exclusions_enabled?: boolean;
|
|
29
29
|
exclude_ignored_keys_enabled?: boolean;
|
|
30
30
|
};
|
|
31
|
-
export declare const
|
|
31
|
+
export declare const HIDE_REASONS: {
|
|
32
|
+
IGNORED: string;
|
|
33
|
+
HIGH_PRICE_OUTLIER: string;
|
|
34
|
+
LOW_PRICE_OUTLIER: string;
|
|
35
|
+
DATE_OUTLIER: string;
|
|
36
|
+
COMPETITOR_EXCLUSION: string;
|
|
37
|
+
DUPLICATE: string;
|
|
38
|
+
SEARCH_EXCLUSION: string;
|
|
39
|
+
CALCULATED_SKU_MISMATCH: string;
|
|
40
|
+
CRITICAL_SPEC_MISMATCH: string;
|
|
41
|
+
MANUALLY_IGNORED: string;
|
|
42
|
+
OUT_OF_STOCK_ONLINE: string;
|
|
43
|
+
REFURBISHED_USED: string;
|
|
44
|
+
SKIP_SKU: string;
|
|
45
|
+
VENDOR_EXCLUSION: string;
|
|
46
|
+
};
|
|
47
|
+
export declare const TOO_CHEAP_MULTIPLIER = 0.75;
|
|
48
|
+
export declare const TOO_EXPENSIVE_MULTIPLIER = 1.25;
|
|
49
|
+
export declare const filterScrapeResults: ({ scrapeResults, variant, filters, filterOptions, globalScrapeOptions, }: {
|
|
32
50
|
scrapeResults: ScrapeResultsType[];
|
|
33
51
|
variant: {
|
|
34
52
|
id: number;
|
|
@@ -39,6 +57,7 @@ export declare const filterScrapeResults: ({ scrapeResults, variant, filters, fi
|
|
|
39
57
|
};
|
|
40
58
|
filters: ScrapeFiltersType;
|
|
41
59
|
filterOptions?: FilterOptionsType;
|
|
60
|
+
globalScrapeOptions?: any;
|
|
42
61
|
}) => z.infer<any>[];
|
|
43
62
|
export declare const calculateIgnoreStatus: (result: ScrapeResultsType, variant: {
|
|
44
63
|
id: number;
|
package/dist/index.js
CHANGED
|
@@ -37,8 +37,24 @@ export const scrapeResultsSchema = z.object({
|
|
|
37
37
|
store_id: z.number(),
|
|
38
38
|
match_score: z.number().nullable(),
|
|
39
39
|
});
|
|
40
|
-
const
|
|
41
|
-
|
|
40
|
+
export const HIDE_REASONS = {
|
|
41
|
+
IGNORED: "Ignored",
|
|
42
|
+
HIGH_PRICE_OUTLIER: "Too Expensive",
|
|
43
|
+
LOW_PRICE_OUTLIER: "Too Cheap",
|
|
44
|
+
DATE_OUTLIER: "Outdated Listing",
|
|
45
|
+
COMPETITOR_EXCLUSION: "Source Excluded",
|
|
46
|
+
DUPLICATE: "Duplicate",
|
|
47
|
+
SEARCH_EXCLUSION: "Search Exclusion",
|
|
48
|
+
CALCULATED_SKU_MISMATCH: "Calculated SKU Mismatch",
|
|
49
|
+
CRITICAL_SPEC_MISMATCH: "Critical Spec Mismatch",
|
|
50
|
+
MANUALLY_IGNORED: "Manually ignored",
|
|
51
|
+
OUT_OF_STOCK_ONLINE: "Out of stock online",
|
|
52
|
+
REFURBISHED_USED: "Refurbished/Used",
|
|
53
|
+
SKIP_SKU: "Skipped SKU",
|
|
54
|
+
VENDOR_EXCLUSION: "Vendor Exclusion",
|
|
55
|
+
};
|
|
56
|
+
export const TOO_CHEAP_MULTIPLIER = 0.75;
|
|
57
|
+
export const TOO_EXPENSIVE_MULTIPLIER = 1.25;
|
|
42
58
|
const wattages = Array.from({ length: 41 }, (_, i) => (5000 + i * 500).toString());
|
|
43
59
|
export const filterScrapeResults = ({ scrapeResults, variant, filters, filterOptions = {
|
|
44
60
|
exclude_linked_variants_enabled: true,
|
|
@@ -52,32 +68,35 @@ export const filterScrapeResults = ({ scrapeResults, variant, filters, filterOpt
|
|
|
52
68
|
wattage_exclusions_enabled: true,
|
|
53
69
|
search_exclusions_enabled: true,
|
|
54
70
|
exclude_ignored_keys_enabled: false,
|
|
55
|
-
}, }) => {
|
|
71
|
+
}, globalScrapeOptions, }) => {
|
|
56
72
|
let filteredResults = scrapeResults;
|
|
57
|
-
if (filterOptions.exclude_linked_variants_enabled) {
|
|
58
|
-
|
|
59
|
-
}
|
|
60
|
-
if (filterOptions.found_id_exclusions_enabled) {
|
|
61
|
-
|
|
62
|
-
}
|
|
63
|
-
if (filterOptions.exclude_ignored_keys_enabled) {
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
if (filterOptions.price_filter_enabled) {
|
|
67
|
-
|
|
68
|
-
}
|
|
69
|
-
if (filterOptions.date_filter_enabled) {
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
if (filterOptions.competitor_filter_enabled) {
|
|
73
|
-
|
|
74
|
-
}
|
|
75
|
-
if (filterOptions.duplicates_filter_enabled) {
|
|
76
|
-
|
|
77
|
-
}
|
|
78
|
-
if (filterOptions.search_index_enabled) {
|
|
79
|
-
|
|
80
|
-
|
|
73
|
+
// if (filterOptions.exclude_linked_variants_enabled) {
|
|
74
|
+
// filteredResults = filterLinkedElsewhereResults(filteredResults, variant.id)
|
|
75
|
+
// }
|
|
76
|
+
// if (filterOptions.found_id_exclusions_enabled) {
|
|
77
|
+
// filteredResults = filterFoundProductIdExclusions(filteredResults, filters.found_id_exclusions)
|
|
78
|
+
// }
|
|
79
|
+
// if (filterOptions.exclude_ignored_keys_enabled) {
|
|
80
|
+
// filteredResults = filterIgnoredResults(filteredResults)
|
|
81
|
+
// }
|
|
82
|
+
// if (filterOptions.price_filter_enabled) {
|
|
83
|
+
filteredResults = filterPriceOutliers(filteredResults, variant.price, globalScrapeOptions);
|
|
84
|
+
// }
|
|
85
|
+
// if (filterOptions.date_filter_enabled) {
|
|
86
|
+
filteredResults = filterDateWindow(filteredResults, filters.dayWindow);
|
|
87
|
+
// }
|
|
88
|
+
// if (filterOptions.competitor_filter_enabled) {
|
|
89
|
+
filteredResults = filterCompetitors(filteredResults, filters.competitor_exclusions);
|
|
90
|
+
// }
|
|
91
|
+
// if (filterOptions.duplicates_filter_enabled) {
|
|
92
|
+
filteredResults = filterDuplicateResults(filteredResults);
|
|
93
|
+
// }
|
|
94
|
+
// if (filterOptions.search_index_enabled) {
|
|
95
|
+
filteredResults = handleExclusionsSearch(filteredResults, filters, variant, filterOptions);
|
|
96
|
+
filteredResults = handleSkipSkuSearch(filteredResults, filters, variant, filterOptions);
|
|
97
|
+
filteredResults = handleVendorExclusions(filteredResults, filters, variant, filterOptions);
|
|
98
|
+
// filteredResults = handleIndexSearch(filteredResults, filters, variant, filterOptions)
|
|
99
|
+
// }
|
|
81
100
|
return filteredResults;
|
|
82
101
|
};
|
|
83
102
|
const handleIndexSearch = (dataToSearch, filters, variant, filterOptions) => {
|
|
@@ -104,6 +123,29 @@ const handleIndexSearch = (dataToSearch, filters, variant, filterOptions) => {
|
|
|
104
123
|
index.add(id, item.title);
|
|
105
124
|
});
|
|
106
125
|
const searchTerms = filters.match_values;
|
|
126
|
+
let final = null;
|
|
127
|
+
searchTerms.forEach((term) => {
|
|
128
|
+
if (final === null) {
|
|
129
|
+
final = index.search(term, {
|
|
130
|
+
resolve: false,
|
|
131
|
+
suggest: true,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
final = final.or({
|
|
136
|
+
index: index,
|
|
137
|
+
query: term,
|
|
138
|
+
resolve: false,
|
|
139
|
+
suggest: true,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
final = final.and({
|
|
144
|
+
index: index,
|
|
145
|
+
query: sku,
|
|
146
|
+
resolve: false,
|
|
147
|
+
suggest: true,
|
|
148
|
+
});
|
|
107
149
|
const nots = [];
|
|
108
150
|
if (filters.skip_skus.length && filterOptions.skip_skus_enabled) {
|
|
109
151
|
const formatted = filters.skip_skus
|
|
@@ -142,10 +184,221 @@ const handleIndexSearch = (dataToSearch, filters, variant, filterOptions) => {
|
|
|
142
184
|
if (title.toLowerCase().includes("dual fuel")) {
|
|
143
185
|
// nots.push('tri fuel', 'trifuel', 'tri-fuel')
|
|
144
186
|
}
|
|
187
|
+
nots.forEach((term) => {
|
|
188
|
+
final = final.not({
|
|
189
|
+
index: index,
|
|
190
|
+
query: term,
|
|
191
|
+
resolve: false,
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
const result = final.resolve({ limit: 1000 });
|
|
195
|
+
const resultsArray = [];
|
|
196
|
+
result.forEach((i) => {
|
|
197
|
+
resultsArray.push(dataToSearch[i]);
|
|
198
|
+
});
|
|
199
|
+
for (let index = 0; index < dataToSearch.length; index++) {
|
|
200
|
+
const element = dataToSearch[index];
|
|
201
|
+
if (!result.includes(index)) {
|
|
202
|
+
if (!element.hide_reasons) {
|
|
203
|
+
element.hide_reasons = [];
|
|
204
|
+
}
|
|
205
|
+
element.hide_reasons.push(HIDE_REASONS.SEARCH_EXCLUSION);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return dataToSearch;
|
|
209
|
+
};
|
|
210
|
+
const handleVendorExclusions = (dataToSearch, filters, variant, filterOptions) => {
|
|
211
|
+
if (!filters.skip_vendors || filters.skip_vendors.length === 0) {
|
|
212
|
+
return dataToSearch;
|
|
213
|
+
}
|
|
214
|
+
const { title, sku } = variant;
|
|
215
|
+
function customEncoder(content) {
|
|
216
|
+
const tokens = [];
|
|
217
|
+
const str = content.toLowerCase();
|
|
218
|
+
// Remove symbols from the string (keep only letters, numbers, commas, and spaces)
|
|
219
|
+
const cleanedStr = str.replace(/[\/-]/g, " ");
|
|
220
|
+
const cleanedStr2 = cleanedStr.replace(/[^a-z0-9,\/\s]/gi, "");
|
|
221
|
+
const words = cleanedStr2.split(/\s+/);
|
|
222
|
+
for (let word of words) {
|
|
223
|
+
tokens.push(word);
|
|
224
|
+
}
|
|
225
|
+
return tokens;
|
|
226
|
+
}
|
|
227
|
+
const index = new Index({
|
|
228
|
+
charset: EnglishPreset,
|
|
229
|
+
// encoder: encoder,
|
|
230
|
+
encode: customEncoder,
|
|
231
|
+
tokenize: "strict",
|
|
232
|
+
});
|
|
233
|
+
dataToSearch.forEach((item, id) => {
|
|
234
|
+
index.add(id, item.title);
|
|
235
|
+
});
|
|
236
|
+
const searchTerms = filters.match_values;
|
|
145
237
|
let final = null;
|
|
146
|
-
let urlFinal = null;
|
|
147
238
|
searchTerms.forEach((term) => {
|
|
148
|
-
if (final === null
|
|
239
|
+
if (final === null) {
|
|
240
|
+
final = index.search(term, {
|
|
241
|
+
resolve: false,
|
|
242
|
+
suggest: true,
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
final = final.or({
|
|
247
|
+
index: index,
|
|
248
|
+
query: term,
|
|
249
|
+
resolve: false,
|
|
250
|
+
suggest: true,
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
final = final.and({
|
|
255
|
+
index: index,
|
|
256
|
+
query: sku,
|
|
257
|
+
resolve: false,
|
|
258
|
+
suggest: true,
|
|
259
|
+
});
|
|
260
|
+
const nots = [];
|
|
261
|
+
if (filters.skip_vendors.length && filterOptions.skip_vendors_enabled) {
|
|
262
|
+
const formatted = filters.skip_vendors
|
|
263
|
+
.filter((vendor) => vendor.toLowerCase() !== variant.vendor.toLowerCase())
|
|
264
|
+
.map((vendor) => ` ${vendor} `);
|
|
265
|
+
nots.push(...formatted);
|
|
266
|
+
}
|
|
267
|
+
nots.forEach((term) => {
|
|
268
|
+
final = final.not({
|
|
269
|
+
index: index,
|
|
270
|
+
query: term,
|
|
271
|
+
resolve: false,
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
const result = final.resolve({ limit: 1000 });
|
|
275
|
+
const resultsArray = [];
|
|
276
|
+
result.forEach((i) => {
|
|
277
|
+
resultsArray.push(dataToSearch[i]);
|
|
278
|
+
});
|
|
279
|
+
for (let index = 0; index < dataToSearch.length; index++) {
|
|
280
|
+
const element = dataToSearch[index];
|
|
281
|
+
if (!result.includes(index)) {
|
|
282
|
+
if (!element.hide_reasons) {
|
|
283
|
+
element.hide_reasons = [];
|
|
284
|
+
}
|
|
285
|
+
element.hide_reasons.push(HIDE_REASONS.VENDOR_EXCLUSION);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
return dataToSearch;
|
|
289
|
+
};
|
|
290
|
+
const handleSkipSkuSearch = (dataToSearch, filters, variant, filterOptions) => {
|
|
291
|
+
// if (
|
|
292
|
+
// (!filters.skip_skus || filters.skip_skus.length === 0) &&
|
|
293
|
+
// (!filters.vendor_search_exclusions || filters.vendor_search_exclusions.length === 0)
|
|
294
|
+
// ) {
|
|
295
|
+
// return dataToSearch
|
|
296
|
+
// }
|
|
297
|
+
const { title, sku } = variant;
|
|
298
|
+
function customEncoder(content) {
|
|
299
|
+
const tokens = [];
|
|
300
|
+
const str = content.toLowerCase();
|
|
301
|
+
// Remove symbols from the string (keep only letters, numbers, commas, and spaces)
|
|
302
|
+
const cleanedStr = str.replace(/[\/-]/g, " ");
|
|
303
|
+
const cleanedStr2 = cleanedStr.replace(/[^a-z0-9,\/\s]/gi, "");
|
|
304
|
+
const words = cleanedStr2.split(/\s+/);
|
|
305
|
+
for (let word of words) {
|
|
306
|
+
tokens.push(word);
|
|
307
|
+
}
|
|
308
|
+
return tokens;
|
|
309
|
+
}
|
|
310
|
+
const index = new Index({
|
|
311
|
+
charset: EnglishPreset,
|
|
312
|
+
// encoder: encoder,
|
|
313
|
+
encode: customEncoder,
|
|
314
|
+
tokenize: "strict",
|
|
315
|
+
});
|
|
316
|
+
dataToSearch.forEach((item, id) => {
|
|
317
|
+
index.add(id, item.title);
|
|
318
|
+
});
|
|
319
|
+
const searchTerms = filters.match_values;
|
|
320
|
+
let final = null;
|
|
321
|
+
searchTerms.forEach((term) => {
|
|
322
|
+
if (final === null) {
|
|
323
|
+
final = index.search(term, {
|
|
324
|
+
resolve: false,
|
|
325
|
+
suggest: true,
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
else {
|
|
329
|
+
final = final.or({
|
|
330
|
+
index: index,
|
|
331
|
+
query: term,
|
|
332
|
+
resolve: false,
|
|
333
|
+
suggest: true,
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
final = final.and({
|
|
338
|
+
index: index,
|
|
339
|
+
query: sku,
|
|
340
|
+
resolve: false,
|
|
341
|
+
suggest: true,
|
|
342
|
+
});
|
|
343
|
+
const nots = [];
|
|
344
|
+
const formatted = filters.skip_skus
|
|
345
|
+
.filter((sku) => sku.toLowerCase() !== variant.sku.toLowerCase())
|
|
346
|
+
.map((sku) => ` ${sku} `);
|
|
347
|
+
nots.push(...formatted);
|
|
348
|
+
nots.push(...filters.vendor_search_exclusions.filter((sku) => sku.toLowerCase() !== variant.sku.toLowerCase()));
|
|
349
|
+
nots.forEach((term) => {
|
|
350
|
+
final = final.not({
|
|
351
|
+
index: index,
|
|
352
|
+
query: term,
|
|
353
|
+
resolve: false,
|
|
354
|
+
});
|
|
355
|
+
});
|
|
356
|
+
const result = final.resolve({ limit: 1000 });
|
|
357
|
+
const resultsArray = [];
|
|
358
|
+
result.forEach((i) => {
|
|
359
|
+
resultsArray.push(dataToSearch[i]);
|
|
360
|
+
});
|
|
361
|
+
for (let index = 0; index < dataToSearch.length; index++) {
|
|
362
|
+
const element = dataToSearch[index];
|
|
363
|
+
if (!result.includes(index)) {
|
|
364
|
+
if (!element.hide_reasons) {
|
|
365
|
+
element.hide_reasons = [];
|
|
366
|
+
}
|
|
367
|
+
element.hide_reasons.push(HIDE_REASONS.SKIP_SKU);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
return dataToSearch;
|
|
371
|
+
};
|
|
372
|
+
const handleExclusionsSearch = (dataToSearch, filters, variant, filterOptions) => {
|
|
373
|
+
if (!filters.search_exclusions || filters.search_exclusions.length === 0) {
|
|
374
|
+
return dataToSearch;
|
|
375
|
+
}
|
|
376
|
+
const { title, sku } = variant;
|
|
377
|
+
function customEncoder(content) {
|
|
378
|
+
const tokens = [];
|
|
379
|
+
const str = content.toLowerCase();
|
|
380
|
+
// Remove symbols from the string (keep only letters, numbers, commas, and spaces)
|
|
381
|
+
const cleanedStr = str.replace(/[\/-]/g, " ");
|
|
382
|
+
const cleanedStr2 = cleanedStr.replace(/[^a-z0-9,\/\s]/gi, "");
|
|
383
|
+
const words = cleanedStr2.split(/\s+/);
|
|
384
|
+
for (let word of words) {
|
|
385
|
+
tokens.push(word);
|
|
386
|
+
}
|
|
387
|
+
return tokens;
|
|
388
|
+
}
|
|
389
|
+
const index = new Index({
|
|
390
|
+
charset: EnglishPreset,
|
|
391
|
+
// encoder: encoder,
|
|
392
|
+
encode: customEncoder,
|
|
393
|
+
tokenize: "strict",
|
|
394
|
+
});
|
|
395
|
+
dataToSearch.forEach((item, id) => {
|
|
396
|
+
index.add(id, item.title);
|
|
397
|
+
});
|
|
398
|
+
const searchTerms = filters.match_values;
|
|
399
|
+
let final = null;
|
|
400
|
+
searchTerms.forEach((term) => {
|
|
401
|
+
if (final === null) {
|
|
149
402
|
final = index.search(term, {
|
|
150
403
|
resolve: false,
|
|
151
404
|
suggest: true,
|
|
@@ -160,19 +413,14 @@ const handleIndexSearch = (dataToSearch, filters, variant, filterOptions) => {
|
|
|
160
413
|
});
|
|
161
414
|
}
|
|
162
415
|
});
|
|
163
|
-
// final = final.and({
|
|
164
|
-
// index: index,
|
|
165
|
-
// query: 'Chipper',
|
|
166
|
-
// resolve: false,
|
|
167
|
-
// // suggest: true,
|
|
168
|
-
// })
|
|
169
|
-
// MUST INCLUDE SKU???
|
|
170
416
|
final = final.and({
|
|
171
417
|
index: index,
|
|
172
418
|
query: sku,
|
|
173
419
|
resolve: false,
|
|
174
420
|
suggest: true,
|
|
175
421
|
});
|
|
422
|
+
const nots = [];
|
|
423
|
+
nots.push(...filters.search_exclusions);
|
|
176
424
|
nots.forEach((term) => {
|
|
177
425
|
final = final.not({
|
|
178
426
|
index: index,
|
|
@@ -185,7 +433,16 @@ const handleIndexSearch = (dataToSearch, filters, variant, filterOptions) => {
|
|
|
185
433
|
result.forEach((i) => {
|
|
186
434
|
resultsArray.push(dataToSearch[i]);
|
|
187
435
|
});
|
|
188
|
-
|
|
436
|
+
for (let index = 0; index < dataToSearch.length; index++) {
|
|
437
|
+
const element = dataToSearch[index];
|
|
438
|
+
if (!result.includes(index)) {
|
|
439
|
+
if (!element.hide_reasons) {
|
|
440
|
+
element.hide_reasons = [];
|
|
441
|
+
}
|
|
442
|
+
element.hide_reasons.push(HIDE_REASONS.SEARCH_EXCLUSION);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
return dataToSearch;
|
|
189
446
|
};
|
|
190
447
|
const filterLinkedElsewhereResults = (results, variantId) => {
|
|
191
448
|
const filtered = results.filter((result) => {
|
|
@@ -220,48 +477,89 @@ const filterFoundProductIdExclusions = (results, found_id_exclusions) => {
|
|
|
220
477
|
return filtered;
|
|
221
478
|
};
|
|
222
479
|
const filterIgnoredResults = (results) => {
|
|
223
|
-
|
|
224
|
-
|
|
480
|
+
results.forEach((item) => {
|
|
481
|
+
if (!item.hide_reasons) {
|
|
482
|
+
item.hide_reasons = [];
|
|
483
|
+
}
|
|
484
|
+
if (item.ignore_result) {
|
|
485
|
+
item.hide_reasons.push(HIDE_REASONS.IGNORED);
|
|
486
|
+
}
|
|
225
487
|
});
|
|
226
|
-
|
|
488
|
+
// const filtered = results.filter((item) => {
|
|
489
|
+
// return item.ignore_result ? false : true
|
|
490
|
+
// })
|
|
491
|
+
return results;
|
|
227
492
|
};
|
|
228
|
-
const filterPriceOutliers = (results, variantPrice,
|
|
229
|
-
|
|
230
|
-
|
|
493
|
+
const filterPriceOutliers = (results, variantPrice, globalScrapeOptions) => {
|
|
494
|
+
results.forEach((item) => {
|
|
495
|
+
if (!item.hide_reasons) {
|
|
496
|
+
item.hide_reasons = [];
|
|
497
|
+
}
|
|
498
|
+
const too_cheap_multiplier = getUndercutThreshold(variantPrice, globalScrapeOptions.undercut_threshold_ranges || []);
|
|
231
499
|
const isMoreExpensive = item.extracted_price > variantPrice * TOO_EXPENSIVE_MULTIPLIER;
|
|
232
|
-
const
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
return false;
|
|
500
|
+
const isTooCheap = item.extracted_price < variantPrice * too_cheap_multiplier;
|
|
501
|
+
if (isMoreExpensive) {
|
|
502
|
+
item.hide_reasons.push(HIDE_REASONS.HIGH_PRICE_OUTLIER);
|
|
236
503
|
}
|
|
237
|
-
if (isTooCheap
|
|
238
|
-
|
|
504
|
+
if (isTooCheap) {
|
|
505
|
+
item.hide_reasons.push(HIDE_REASONS.LOW_PRICE_OUTLIER);
|
|
239
506
|
}
|
|
240
|
-
return true;
|
|
241
507
|
});
|
|
508
|
+
const filtered = results;
|
|
509
|
+
// const filtered = results.filter((item) => {
|
|
510
|
+
// const showMoreExpensive = showHighPriceOutliers === true
|
|
511
|
+
// const isMoreExpensive = item.extracted_price > variantPrice * TOO_EXPENSIVE_MULTIPLIER
|
|
512
|
+
// const showTooCheap = showLowPriceOutliers === true
|
|
513
|
+
// const isTooCheap = item.extracted_price < variantPrice * TOO_CHEAP_MULTIPLIER
|
|
514
|
+
// if (isMoreExpensive && !showMoreExpensive) {
|
|
515
|
+
// return false
|
|
516
|
+
// }
|
|
517
|
+
// if (isTooCheap && !showTooCheap) {
|
|
518
|
+
// return false
|
|
519
|
+
// }
|
|
520
|
+
// return true
|
|
521
|
+
// })
|
|
242
522
|
return filtered;
|
|
243
523
|
};
|
|
244
524
|
const filterDateWindow = (results, dayWindow) => {
|
|
245
|
-
|
|
246
|
-
if (!
|
|
247
|
-
|
|
525
|
+
results.forEach((item) => {
|
|
526
|
+
if (!item.hide_reasons) {
|
|
527
|
+
item.hide_reasons = [];
|
|
528
|
+
}
|
|
248
529
|
const itemDate = new Date(item.created_at);
|
|
249
|
-
const variantDate = startOfDay(subDays(new Date(), Number(dayWindow) ||
|
|
250
|
-
|
|
530
|
+
const variantDate = startOfDay(subDays(new Date(), Number(dayWindow) || 3));
|
|
531
|
+
if (itemDate < variantDate) {
|
|
532
|
+
item.hide_reasons.push(HIDE_REASONS.DATE_OUTLIER);
|
|
533
|
+
}
|
|
251
534
|
});
|
|
252
|
-
|
|
535
|
+
// const filtered = results.filter((item) => {
|
|
536
|
+
// if (!dayWindow) return true
|
|
537
|
+
// const itemDate = new Date(item.created_at)
|
|
538
|
+
// const variantDate = startOfDay(subDays(new Date(), Number(dayWindow) || 7))
|
|
539
|
+
// return itemDate >= variantDate
|
|
540
|
+
// })
|
|
541
|
+
return results;
|
|
253
542
|
};
|
|
254
543
|
const filterCompetitors = (results, competitor_exclusions) => {
|
|
255
|
-
|
|
544
|
+
results.forEach((item) => {
|
|
545
|
+
if (!item.hide_reasons) {
|
|
546
|
+
item.hide_reasons = [];
|
|
547
|
+
}
|
|
256
548
|
const lowerSource = item.source.toLowerCase();
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
return false;
|
|
260
|
-
}
|
|
549
|
+
if (competitor_exclusions.some((exclusion) => exclusion && lowerSource === exclusion.toLowerCase())) {
|
|
550
|
+
item.hide_reasons.push(HIDE_REASONS.COMPETITOR_EXCLUSION);
|
|
261
551
|
}
|
|
262
|
-
return true;
|
|
263
552
|
});
|
|
264
|
-
|
|
553
|
+
// const filtered = results.filter((item) => {
|
|
554
|
+
// const lowerSource = item.source.toLowerCase()
|
|
555
|
+
// for (const exclusion of competitor_exclusions) {
|
|
556
|
+
// if (exclusion && lowerSource === exclusion.toLowerCase()) {
|
|
557
|
+
// return false
|
|
558
|
+
// }
|
|
559
|
+
// }
|
|
560
|
+
// return true
|
|
561
|
+
// })
|
|
562
|
+
return results;
|
|
265
563
|
};
|
|
266
564
|
const filterDuplicateResults = (results) => {
|
|
267
565
|
const filteredUniqueResultsMap = {};
|
|
@@ -273,12 +571,24 @@ const filterDuplicateResults = (results) => {
|
|
|
273
571
|
else {
|
|
274
572
|
const existingItem = filteredUniqueResultsMap[key];
|
|
275
573
|
if (new Date(item.created_at) > new Date(existingItem.created_at)) {
|
|
574
|
+
const foundResult = results.find((res) => res.id === existingItem.id);
|
|
575
|
+
if (foundResult) {
|
|
576
|
+
if (!foundResult.hide_reasons) {
|
|
577
|
+
foundResult.hide_reasons = [];
|
|
578
|
+
}
|
|
579
|
+
foundResult.hide_reasons.push(HIDE_REASONS.DUPLICATE);
|
|
580
|
+
}
|
|
276
581
|
filteredUniqueResultsMap[key] = item;
|
|
277
582
|
}
|
|
583
|
+
else {
|
|
584
|
+
if (!item.hide_reasons) {
|
|
585
|
+
item.hide_reasons = [];
|
|
586
|
+
}
|
|
587
|
+
item.hide_reasons.push(HIDE_REASONS.DUPLICATE);
|
|
588
|
+
}
|
|
278
589
|
}
|
|
279
590
|
});
|
|
280
|
-
|
|
281
|
-
return filtered;
|
|
591
|
+
return results;
|
|
282
592
|
};
|
|
283
593
|
export const calculateIgnoreStatus = (result, variant, result_ignore_keys) => {
|
|
284
594
|
let ignore = false;
|
|
@@ -316,3 +626,7 @@ export const calculateIgnoreStatus = (result, variant, result_ignore_keys) => {
|
|
|
316
626
|
}
|
|
317
627
|
return ignore;
|
|
318
628
|
};
|
|
629
|
+
function getUndercutThreshold(price, undercutThresholdRanges) {
|
|
630
|
+
const range = undercutThresholdRanges.find((r) => price >= r.min && price <= r.max);
|
|
631
|
+
return range ? range.threshold : 0.75; // fallback default
|
|
632
|
+
}
|
package/package.json
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
2
|
+
"name": "@factorypure/client-helpers",
|
|
3
|
+
"version": "1.0.16",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"type": "module",
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsc",
|
|
13
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [],
|
|
16
|
+
"author": "",
|
|
17
|
+
"license": "ISC",
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"typescript": "^5.6.2"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@types/date-fns": "^2.5.3",
|
|
23
|
+
"date-fns": "^4.1.0",
|
|
24
|
+
"flexsearch": "^0.8.212",
|
|
25
|
+
"zod": "^4.3.5"
|
|
26
|
+
}
|
|
27
27
|
}
|