@factorypure/client-helpers 1.0.27 → 1.1.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.d.ts +38 -14
- package/dist/index.js +38 -14
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -80,7 +80,7 @@ export declare const scrapeResultsSchema: z.ZodObject<{
|
|
|
80
80
|
title: z.ZodString;
|
|
81
81
|
found_product_id: z.ZodString;
|
|
82
82
|
product_link: z.ZodString;
|
|
83
|
-
inline_link: z.ZodNullable<z.
|
|
83
|
+
inline_link: z.ZodNullable<z.ZodString>;
|
|
84
84
|
immersive_product_page_token: z.ZodString;
|
|
85
85
|
serpapi_immersive_product_api: z.ZodString;
|
|
86
86
|
source: z.ZodString;
|
|
@@ -88,11 +88,11 @@ export declare const scrapeResultsSchema: z.ZodObject<{
|
|
|
88
88
|
multiple_sources: z.ZodNumber;
|
|
89
89
|
price: z.ZodString;
|
|
90
90
|
extracted_price: z.ZodNumber;
|
|
91
|
-
old_price: z.ZodNullable<z.
|
|
92
|
-
extracted_old_price: z.ZodNullable<z.
|
|
93
|
-
rating: z.ZodNullable<z.
|
|
94
|
-
reviews: z.ZodNullable<z.
|
|
95
|
-
snippet: z.ZodNullable<z.
|
|
91
|
+
old_price: z.ZodNullable<z.ZodString>;
|
|
92
|
+
extracted_old_price: z.ZodNullable<z.ZodNumber>;
|
|
93
|
+
rating: z.ZodNullable<z.ZodNumber>;
|
|
94
|
+
reviews: z.ZodNullable<z.ZodNumber>;
|
|
95
|
+
snippet: z.ZodNullable<z.ZodString>;
|
|
96
96
|
thumbnail: z.ZodString;
|
|
97
97
|
serpapi_thumbnail: z.ZodString;
|
|
98
98
|
tag: z.ZodNullable<z.ZodAny>;
|
|
@@ -293,6 +293,8 @@ export declare const immersiveScrapeResultsSchema: z.ZodObject<{
|
|
|
293
293
|
normalized: z.ZodString;
|
|
294
294
|
}, z.core.$strip>>;
|
|
295
295
|
}, z.core.$strip>>;
|
|
296
|
+
inline_link: z.ZodOptional<z.ZodNull>;
|
|
297
|
+
delivery: z.ZodOptional<z.ZodNull>;
|
|
296
298
|
}, z.core.$strip>;
|
|
297
299
|
export type ScrapeResultsType = z.infer<typeof scrapeResultsSchema>;
|
|
298
300
|
export type ImmersiveScrapeResultsType = z.infer<typeof immersiveScrapeResultsSchema>;
|
|
@@ -319,18 +321,14 @@ export type ScrapeFiltersType = {
|
|
|
319
321
|
result_ignore_keys: ResultIgnoreType[] | null;
|
|
320
322
|
brand_name_alternates: string[];
|
|
321
323
|
dayWindow: number | null;
|
|
324
|
+
custom_search_value: string;
|
|
325
|
+
sku_regex: string | null;
|
|
322
326
|
};
|
|
323
327
|
export declare const variantScrapeOptionsSchema: z.ZodObject<{
|
|
324
328
|
search_exclusions: z.ZodArray<z.ZodString>;
|
|
325
|
-
vendor_search_exclusions: z.ZodArray<z.ZodString>;
|
|
326
329
|
custom_search_value: z.ZodString;
|
|
327
330
|
match_values: z.ZodArray<z.ZodString>;
|
|
328
|
-
skip_skus: z.ZodArray<z.ZodString>;
|
|
329
331
|
competitor_exclusions: z.ZodArray<z.ZodString>;
|
|
330
|
-
disable_vendor_skip_skus: z.ZodBoolean;
|
|
331
|
-
disable_wattage_filter: z.ZodBoolean;
|
|
332
|
-
found_product_ids: z.ZodNullable<z.ZodArray<z.ZodNumber>>;
|
|
333
|
-
immersive_product_page_token: z.ZodNullable<z.ZodString>;
|
|
334
332
|
found_id_exclusions: z.ZodNullable<z.ZodArray<z.ZodNumber>>;
|
|
335
333
|
result_ignore_keys: z.ZodNullable<z.ZodArray<z.ZodObject<{
|
|
336
334
|
id: z.ZodNumber;
|
|
@@ -343,9 +341,34 @@ export declare const variantScrapeOptionsSchema: z.ZodObject<{
|
|
|
343
341
|
created_by: z.ZodNumber;
|
|
344
342
|
key_parts: z.ZodString;
|
|
345
343
|
}, z.core.$strip>>>;
|
|
346
|
-
brand_name_alternates: z.ZodNullable<z.ZodArray<z.ZodString>>;
|
|
347
344
|
}, z.core.$strip>;
|
|
348
345
|
export type VariantScrapeOptionsType = z.infer<typeof variantScrapeOptionsSchema>;
|
|
346
|
+
export declare const vendorScrapeOptionsSchema: z.ZodObject<{
|
|
347
|
+
vendor_search_exclusions: z.ZodArray<z.ZodString>;
|
|
348
|
+
skip_skus: z.ZodArray<z.ZodString>;
|
|
349
|
+
result_ignore_keys: z.ZodNullable<z.ZodArray<z.ZodObject<{
|
|
350
|
+
id: z.ZodNumber;
|
|
351
|
+
variant_id: z.ZodNumber;
|
|
352
|
+
title: z.ZodString;
|
|
353
|
+
price: z.ZodString;
|
|
354
|
+
source: z.ZodString;
|
|
355
|
+
reason: z.ZodString;
|
|
356
|
+
duration_days: z.ZodNumber;
|
|
357
|
+
created_by: z.ZodNumber;
|
|
358
|
+
key_parts: z.ZodString;
|
|
359
|
+
}, z.core.$strip>>>;
|
|
360
|
+
brand_name_alternates: z.ZodNullable<z.ZodArray<z.ZodString>>;
|
|
361
|
+
}, z.core.$strip>;
|
|
362
|
+
export type VendorScrapeOptionsType = z.infer<typeof vendorScrapeOptionsSchema>;
|
|
363
|
+
export declare const globalScrapeOptionsSchema: z.ZodObject<{
|
|
364
|
+
undercut_threshold_ranges: z.ZodArray<z.ZodObject<{
|
|
365
|
+
min: z.ZodNumber;
|
|
366
|
+
max: z.ZodNumber;
|
|
367
|
+
threshold: z.ZodNumber;
|
|
368
|
+
}, z.core.$strip>>;
|
|
369
|
+
scam_sources: z.ZodArray<z.ZodString>;
|
|
370
|
+
}, z.core.$strip>;
|
|
371
|
+
export type GlobalScrapeOptionsType = z.infer<typeof globalScrapeOptionsSchema>;
|
|
349
372
|
export declare const HIDE_REASONS: {
|
|
350
373
|
IGNORED: string;
|
|
351
374
|
HIGH_PRICE_OUTLIER: string;
|
|
@@ -362,6 +385,7 @@ export declare const HIDE_REASONS: {
|
|
|
362
385
|
REFURBISHED_USED: string;
|
|
363
386
|
SKIP_SKU: string;
|
|
364
387
|
VENDOR_EXCLUSION: string;
|
|
388
|
+
SCAM_SOURCE_EXCLUSION: string;
|
|
365
389
|
};
|
|
366
390
|
export declare const HIDE_OVERRIDE_REASONS: {
|
|
367
391
|
SKU_MATCH: string;
|
|
@@ -393,7 +417,7 @@ export declare const calculateHideReasons: (result: ScrapeResultsType | Immersiv
|
|
|
393
417
|
price: number;
|
|
394
418
|
vendor: string;
|
|
395
419
|
regexUnitResults?: RegexUnitResultsType;
|
|
396
|
-
}, variantScrapeOptions: VariantScrapeOptionsType) => string[];
|
|
420
|
+
}, variantScrapeOptions: VariantScrapeOptionsType, vendorScrapeOptions: VendorScrapeOptionsType) => string[];
|
|
397
421
|
export declare const calculateHideOverrideReasons: (result: ScrapeResultsType | ImmersiveScrapeResultsType, variant: {
|
|
398
422
|
id: number;
|
|
399
423
|
title: string;
|
package/dist/index.js
CHANGED
|
@@ -32,7 +32,7 @@ export const scrapeResultsSchema = z.object({
|
|
|
32
32
|
title: z.string(),
|
|
33
33
|
found_product_id: z.string(),
|
|
34
34
|
product_link: z.string(),
|
|
35
|
-
inline_link: z.
|
|
35
|
+
inline_link: z.string().nullable(),
|
|
36
36
|
immersive_product_page_token: z.string(),
|
|
37
37
|
serpapi_immersive_product_api: z.string(),
|
|
38
38
|
source: z.string(),
|
|
@@ -40,11 +40,11 @@ export const scrapeResultsSchema = z.object({
|
|
|
40
40
|
multiple_sources: z.number(),
|
|
41
41
|
price: z.string(),
|
|
42
42
|
extracted_price: z.number(),
|
|
43
|
-
old_price: z.
|
|
44
|
-
extracted_old_price: z.
|
|
45
|
-
rating: z.
|
|
46
|
-
reviews: z.
|
|
47
|
-
snippet: z.
|
|
43
|
+
old_price: z.string().nullable(),
|
|
44
|
+
extracted_old_price: z.number().nullable(),
|
|
45
|
+
rating: z.number().nullable(),
|
|
46
|
+
reviews: z.number().nullable(),
|
|
47
|
+
snippet: z.string().nullable(),
|
|
48
48
|
thumbnail: z.string(),
|
|
49
49
|
serpapi_thumbnail: z.string(),
|
|
50
50
|
tag: z.nullable(z.any()),
|
|
@@ -124,6 +124,8 @@ export const immersiveScrapeResultsSchema = z.object({
|
|
|
124
124
|
brand: z.string().nullable(),
|
|
125
125
|
company_id: z.number().nullable(),
|
|
126
126
|
regexUnitResults: z.nullable(regexUnitResultsSchema),
|
|
127
|
+
inline_link: z.null().optional(),
|
|
128
|
+
delivery: z.null().optional(),
|
|
127
129
|
});
|
|
128
130
|
export const ResultIgnoreSchema = z.object({
|
|
129
131
|
id: z.number(),
|
|
@@ -138,19 +140,26 @@ export const ResultIgnoreSchema = z.object({
|
|
|
138
140
|
});
|
|
139
141
|
export const variantScrapeOptionsSchema = z.object({
|
|
140
142
|
search_exclusions: z.array(z.string()),
|
|
141
|
-
vendor_search_exclusions: z.array(z.string()),
|
|
142
143
|
custom_search_value: z.string(),
|
|
143
144
|
match_values: z.array(z.string()),
|
|
144
|
-
skip_skus: z.array(z.string()),
|
|
145
145
|
competitor_exclusions: z.array(z.string()),
|
|
146
|
-
disable_vendor_skip_skus: z.boolean(),
|
|
147
|
-
disable_wattage_filter: z.boolean(),
|
|
148
|
-
found_product_ids: z.array(z.number()).nullable(),
|
|
149
|
-
immersive_product_page_token: z.string().nullable(),
|
|
150
146
|
found_id_exclusions: z.array(z.number()).nullable(),
|
|
151
147
|
result_ignore_keys: z.array(ResultIgnoreSchema).nullable(),
|
|
148
|
+
});
|
|
149
|
+
export const vendorScrapeOptionsSchema = z.object({
|
|
150
|
+
vendor_search_exclusions: z.array(z.string()),
|
|
151
|
+
skip_skus: z.array(z.string()),
|
|
152
|
+
result_ignore_keys: z.array(ResultIgnoreSchema).nullable(),
|
|
152
153
|
brand_name_alternates: z.array(z.string()).nullable(),
|
|
153
154
|
});
|
|
155
|
+
export const globalScrapeOptionsSchema = z.object({
|
|
156
|
+
undercut_threshold_ranges: z.array(z.object({
|
|
157
|
+
min: z.number(),
|
|
158
|
+
max: z.number(),
|
|
159
|
+
threshold: z.number(),
|
|
160
|
+
})),
|
|
161
|
+
scam_sources: z.array(z.string()),
|
|
162
|
+
});
|
|
154
163
|
export const HIDE_REASONS = {
|
|
155
164
|
IGNORED: 'Ignored',
|
|
156
165
|
HIGH_PRICE_OUTLIER: 'Too Expensive',
|
|
@@ -167,6 +176,7 @@ export const HIDE_REASONS = {
|
|
|
167
176
|
REFURBISHED_USED: 'Refurbished/Used',
|
|
168
177
|
SKIP_SKU: 'Skipped SKU',
|
|
169
178
|
VENDOR_EXCLUSION: 'Vendor Exclusion',
|
|
179
|
+
SCAM_SOURCE_EXCLUSION: 'Scam Source Exclusion',
|
|
170
180
|
};
|
|
171
181
|
export const HIDE_OVERRIDE_REASONS = {
|
|
172
182
|
SKU_MATCH: 'SKU Match',
|
|
@@ -187,6 +197,7 @@ const HIDE_ALWAYS_MAP = {
|
|
|
187
197
|
[HIDE_REASONS.REFURBISHED_USED]: false,
|
|
188
198
|
[HIDE_REASONS.SKIP_SKU]: false,
|
|
189
199
|
[HIDE_REASONS.VENDOR_EXCLUSION]: false,
|
|
200
|
+
[HIDE_REASONS.SCAM_SOURCE_EXCLUSION]: true,
|
|
190
201
|
};
|
|
191
202
|
export const TOO_CHEAP_MULTIPLIER = 0.75;
|
|
192
203
|
export const TOO_EXPENSIVE_MULTIPLIER = 1.15;
|
|
@@ -200,6 +211,7 @@ export const filterScrapeResults = ({ scrapeResults, variant, filters, globalScr
|
|
|
200
211
|
filteredResults = handleExclusionsSearch(filteredResults, filters, variant);
|
|
201
212
|
filteredResults = handleSkipSkuSearch(filteredResults, filters, variant);
|
|
202
213
|
filteredResults = handleVendorExclusions(filteredResults, filters, variant);
|
|
214
|
+
filteredResults = filterScamExclusions(filteredResults, globalScrapeOptions?.scam_sources || []);
|
|
203
215
|
return filteredResults;
|
|
204
216
|
};
|
|
205
217
|
const handleVendorExclusions = (dataToSearch, filters, variant) => {
|
|
@@ -387,6 +399,18 @@ const filterCompetitors = (results, competitor_exclusions) => {
|
|
|
387
399
|
});
|
|
388
400
|
return results;
|
|
389
401
|
};
|
|
402
|
+
const filterScamExclusions = (results, scam_sources) => {
|
|
403
|
+
results.forEach((item) => {
|
|
404
|
+
if (!item.hide_reasons) {
|
|
405
|
+
item.hide_reasons = [];
|
|
406
|
+
}
|
|
407
|
+
const lowerSource = item.source.toLowerCase();
|
|
408
|
+
if (scam_sources.some((exclusion) => exclusion && lowerSource === exclusion.toLowerCase())) {
|
|
409
|
+
item.hide_reasons.push(HIDE_REASONS.SCAM_SOURCE_EXCLUSION);
|
|
410
|
+
}
|
|
411
|
+
});
|
|
412
|
+
return results;
|
|
413
|
+
};
|
|
390
414
|
const filterDuplicateResults = (results) => {
|
|
391
415
|
const filteredUniqueResultsMap = {};
|
|
392
416
|
results.forEach((item) => {
|
|
@@ -459,7 +483,7 @@ function getUndercutThreshold(price, undercutThresholdRanges) {
|
|
|
459
483
|
const range = undercutThresholdRanges.find((r) => price >= r.min && price <= r.max);
|
|
460
484
|
return range ? range.threshold : 0.75; // fallback default
|
|
461
485
|
}
|
|
462
|
-
export const calculateHideReasons = (result, variant, variantScrapeOptions) => {
|
|
486
|
+
export const calculateHideReasons = (result, variant, variantScrapeOptions, vendorScrapeOptions) => {
|
|
463
487
|
const hide_reasons = [];
|
|
464
488
|
if (variantScrapeOptions.result_ignore_keys && variantScrapeOptions.result_ignore_keys.length > 0) {
|
|
465
489
|
variantScrapeOptions.result_ignore_keys.forEach((key) => {
|
|
@@ -483,7 +507,7 @@ export const calculateHideReasons = (result, variant, variantScrapeOptions) => {
|
|
|
483
507
|
}
|
|
484
508
|
if (result.brand) {
|
|
485
509
|
const vendor = variant.vendor ? variant.vendor.toLowerCase() : null;
|
|
486
|
-
const brandNameAlternates =
|
|
510
|
+
const brandNameAlternates = vendorScrapeOptions.brand_name_alternates;
|
|
487
511
|
const targetBrands = [vendor, ...(brandNameAlternates || [])].filter((b) => b).map((b) => b?.toLowerCase());
|
|
488
512
|
const calcBrandMatched = result.brand && result.brand !== '' ? targetBrands.includes(result.brand.toLowerCase()) : null;
|
|
489
513
|
if (calcBrandMatched === false) {
|