@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 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.ZodAny>;
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.ZodAny>;
92
- extracted_old_price: z.ZodNullable<z.ZodAny>;
93
- rating: z.ZodNullable<z.ZodAny>;
94
- reviews: z.ZodNullable<z.ZodAny>;
95
- snippet: z.ZodNullable<z.ZodAny>;
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.nullable(z.any()),
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.nullable(z.any()),
44
- extracted_old_price: z.nullable(z.any()),
45
- rating: z.nullable(z.any()),
46
- reviews: z.nullable(z.any()),
47
- snippet: z.nullable(z.any()),
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 = variantScrapeOptions.brand_name_alternates;
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) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@factorypure/client-helpers",
3
- "version": "1.0.27",
3
+ "version": "1.1.0",
4
4
  "description": "",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",