@factorypure/client-helpers 1.0.25 → 1.0.27
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 +7 -2
- package/dist/index.js +44 -131
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -172,6 +172,10 @@ export declare const scrapeResultsSchema: z.ZodObject<{
|
|
|
172
172
|
calculated_sku_count: z.ZodOptional<z.ZodNull>;
|
|
173
173
|
raw_sku_results: z.ZodOptional<z.ZodNull>;
|
|
174
174
|
details_and_offers: z.ZodOptional<z.ZodNull>;
|
|
175
|
+
total: z.ZodOptional<z.ZodNull>;
|
|
176
|
+
extracted_total: z.ZodOptional<z.ZodNull>;
|
|
177
|
+
shipping: z.ZodOptional<z.ZodNull>;
|
|
178
|
+
extracted_shipping: z.ZodOptional<z.ZodNull>;
|
|
175
179
|
parsed_results: z.ZodOptional<z.ZodNull>;
|
|
176
180
|
lowest_price: z.ZodOptional<z.ZodNull>;
|
|
177
181
|
highest_price: z.ZodOptional<z.ZodNull>;
|
|
@@ -188,6 +192,7 @@ export declare const immersiveScrapeResultsSchema: z.ZodObject<{
|
|
|
188
192
|
position: z.ZodNumber;
|
|
189
193
|
title: z.ZodString;
|
|
190
194
|
found_product_id: z.ZodString;
|
|
195
|
+
type: z.ZodString;
|
|
191
196
|
product_link: z.ZodString;
|
|
192
197
|
immersive_product_page_token: z.ZodString;
|
|
193
198
|
source: z.ZodString;
|
|
@@ -198,14 +203,14 @@ export declare const immersiveScrapeResultsSchema: z.ZodObject<{
|
|
|
198
203
|
extracted_old_price: z.ZodNullable<z.ZodAny>;
|
|
199
204
|
total: z.ZodNullable<z.ZodAny>;
|
|
200
205
|
extracted_total: z.ZodNullable<z.ZodAny>;
|
|
206
|
+
shipping: z.ZodNullable<z.ZodAny>;
|
|
207
|
+
extracted_shipping: z.ZodNullable<z.ZodAny>;
|
|
201
208
|
rating: z.ZodNullable<z.ZodAny>;
|
|
202
209
|
reviews: z.ZodNullable<z.ZodAny>;
|
|
203
210
|
details_and_offers: z.ZodNullable<z.ZodArray<z.ZodString>>;
|
|
204
211
|
tag: z.ZodNullable<z.ZodAny>;
|
|
205
212
|
discount: z.ZodNullable<z.ZodAny>;
|
|
206
213
|
extensions: z.ZodNullable<z.ZodAny>;
|
|
207
|
-
delivery: z.ZodNullable<z.ZodAny>;
|
|
208
|
-
delivery_extracted: z.ZodNullable<z.ZodAny>;
|
|
209
214
|
created_at: z.ZodString;
|
|
210
215
|
store_id: z.ZodNumber;
|
|
211
216
|
serpapi_thumbnail: z.ZodString;
|
package/dist/index.js
CHANGED
|
@@ -64,6 +64,10 @@ export const scrapeResultsSchema = z.object({
|
|
|
64
64
|
calculated_sku_count: z.null().optional(),
|
|
65
65
|
raw_sku_results: z.null().optional(),
|
|
66
66
|
details_and_offers: z.null().optional(),
|
|
67
|
+
total: z.null().optional(),
|
|
68
|
+
extracted_total: z.null().optional(),
|
|
69
|
+
shipping: z.null().optional(),
|
|
70
|
+
extracted_shipping: z.null().optional(),
|
|
67
71
|
parsed_results: z.null().optional(),
|
|
68
72
|
lowest_price: z.null().optional(),
|
|
69
73
|
highest_price: z.null().optional(),
|
|
@@ -80,6 +84,7 @@ export const immersiveScrapeResultsSchema = z.object({
|
|
|
80
84
|
position: z.number(),
|
|
81
85
|
title: z.string(),
|
|
82
86
|
found_product_id: z.string(),
|
|
87
|
+
type: z.string(),
|
|
83
88
|
product_link: z.string(),
|
|
84
89
|
immersive_product_page_token: z.string(),
|
|
85
90
|
source: z.string(),
|
|
@@ -90,14 +95,14 @@ export const immersiveScrapeResultsSchema = z.object({
|
|
|
90
95
|
extracted_old_price: z.nullable(z.any()),
|
|
91
96
|
total: z.nullable(z.any()),
|
|
92
97
|
extracted_total: z.nullable(z.any()),
|
|
98
|
+
shipping: z.nullable(z.any()),
|
|
99
|
+
extracted_shipping: z.nullable(z.any()),
|
|
93
100
|
rating: z.nullable(z.any()),
|
|
94
101
|
reviews: z.nullable(z.any()),
|
|
95
102
|
details_and_offers: z.array(z.string()).nullable(),
|
|
96
103
|
tag: z.nullable(z.any()),
|
|
97
104
|
discount: z.nullable(z.any()),
|
|
98
105
|
extensions: z.nullable(z.any()),
|
|
99
|
-
delivery: z.nullable(z.any()),
|
|
100
|
-
delivery_extracted: z.nullable(z.any()),
|
|
101
106
|
created_at: z.string(),
|
|
102
107
|
store_id: z.number(),
|
|
103
108
|
serpapi_thumbnail: z.string(),
|
|
@@ -198,78 +203,30 @@ export const filterScrapeResults = ({ scrapeResults, variant, filters, globalScr
|
|
|
198
203
|
return filteredResults;
|
|
199
204
|
};
|
|
200
205
|
const handleVendorExclusions = (dataToSearch, filters, variant) => {
|
|
201
|
-
|
|
202
|
-
return dataToSearch;
|
|
203
|
-
}
|
|
204
|
-
const { title, sku } = variant;
|
|
205
|
-
function customEncoder(content) {
|
|
206
|
-
const tokens = [];
|
|
207
|
-
const str = content.toLowerCase();
|
|
208
|
-
// Remove symbols from the string (keep only letters, numbers, commas, and spaces)
|
|
209
|
-
const cleanedStr = str.replace(/[\/-]/g, ' ');
|
|
210
|
-
const cleanedStr2 = cleanedStr.replace(/[^a-z0-9,\/\s]/gi, '');
|
|
211
|
-
const words = cleanedStr2.split(/\s+/);
|
|
212
|
-
for (let word of words) {
|
|
213
|
-
tokens.push(word);
|
|
214
|
-
}
|
|
215
|
-
return tokens;
|
|
216
|
-
}
|
|
217
|
-
const index = new Index({
|
|
218
|
-
// @ts-ignore
|
|
219
|
-
charset: EnglishPreset,
|
|
220
|
-
// encoder: encoder,
|
|
221
|
-
encode: customEncoder,
|
|
222
|
-
tokenize: 'strict',
|
|
223
|
-
});
|
|
224
|
-
dataToSearch.forEach((item, id) => {
|
|
225
|
-
index.add(id, item.title);
|
|
226
|
-
});
|
|
227
|
-
const searchTerms = filters.match_values;
|
|
228
|
-
let final = null;
|
|
229
|
-
searchTerms.forEach((term) => {
|
|
230
|
-
if (final === null) {
|
|
231
|
-
final = index.search(term, {
|
|
232
|
-
resolve: false,
|
|
233
|
-
suggest: true,
|
|
234
|
-
});
|
|
235
|
-
}
|
|
236
|
-
else {
|
|
237
|
-
final = final.or({
|
|
238
|
-
index: index,
|
|
239
|
-
query: term,
|
|
240
|
-
resolve: false,
|
|
241
|
-
suggest: true,
|
|
242
|
-
});
|
|
243
|
-
}
|
|
244
|
-
});
|
|
245
|
-
final = final.and({
|
|
246
|
-
index: index,
|
|
247
|
-
query: sku,
|
|
248
|
-
resolve: false,
|
|
249
|
-
suggest: true,
|
|
250
|
-
});
|
|
206
|
+
// Build exclusion list
|
|
251
207
|
const nots = [];
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
208
|
+
const formatted = filters.skip_vendors
|
|
209
|
+
.filter((s) => s.toLowerCase() !== variant.vendor.toLowerCase())
|
|
210
|
+
.map((s) => `${s}`);
|
|
211
|
+
nots.push(...formatted);
|
|
212
|
+
// Find matching indices based on search criteria
|
|
213
|
+
const matchingIndices = [];
|
|
214
|
+
dataToSearch.forEach((item, index) => {
|
|
215
|
+
// NOT logic: Check if none of the exclusion terms match
|
|
216
|
+
const hasExclusion = nots.some((sku) => {
|
|
217
|
+
const escaped = sku.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
|
|
218
|
+
const matchRegex = new RegExp(`(?: |\/|\&|\=|"|'|\`)${escaped}(?: |\/|\&|\=|"|'|\`)`, 'gi');
|
|
219
|
+
const matches = item.title.match(matchRegex);
|
|
220
|
+
return matches && matches.length > 0;
|
|
263
221
|
});
|
|
222
|
+
if (!hasExclusion) {
|
|
223
|
+
matchingIndices.push(index);
|
|
224
|
+
}
|
|
264
225
|
});
|
|
265
|
-
|
|
266
|
-
const resultsArray = [];
|
|
267
|
-
result.forEach((i) => {
|
|
268
|
-
resultsArray.push(dataToSearch[i]);
|
|
269
|
-
});
|
|
226
|
+
// Mark items that don't match with hide reason
|
|
270
227
|
for (let index = 0; index < dataToSearch.length; index++) {
|
|
271
228
|
const element = dataToSearch[index];
|
|
272
|
-
if (!
|
|
229
|
+
if (!matchingIndices.includes(index)) {
|
|
273
230
|
if (!element.hide_reasons) {
|
|
274
231
|
element.hide_reasons = [];
|
|
275
232
|
}
|
|
@@ -279,74 +236,30 @@ const handleVendorExclusions = (dataToSearch, filters, variant) => {
|
|
|
279
236
|
return dataToSearch;
|
|
280
237
|
};
|
|
281
238
|
const handleSkipSkuSearch = (dataToSearch, filters, variant) => {
|
|
282
|
-
|
|
283
|
-
function customEncoder(content) {
|
|
284
|
-
const tokens = [];
|
|
285
|
-
const str = content.toLowerCase();
|
|
286
|
-
// Remove symbols from the string (keep only letters, numbers, commas, and spaces)
|
|
287
|
-
const cleanedStr = str.replace(/[\/-]/g, ' ');
|
|
288
|
-
const cleanedStr2 = cleanedStr.replace(/[^a-z0-9,\/\s]/gi, '');
|
|
289
|
-
const words = cleanedStr2.split(/\s+/);
|
|
290
|
-
for (let word of words) {
|
|
291
|
-
tokens.push(word);
|
|
292
|
-
}
|
|
293
|
-
return tokens;
|
|
294
|
-
}
|
|
295
|
-
const index = new Index({
|
|
296
|
-
// @ts-ignore
|
|
297
|
-
charset: EnglishPreset,
|
|
298
|
-
// encoder: encoder,
|
|
299
|
-
encode: customEncoder,
|
|
300
|
-
tokenize: 'strict',
|
|
301
|
-
});
|
|
302
|
-
dataToSearch.forEach((item, id) => {
|
|
303
|
-
index.add(id, item.title);
|
|
304
|
-
});
|
|
305
|
-
const searchTerms = filters.match_values;
|
|
306
|
-
let final = null;
|
|
307
|
-
searchTerms.forEach((term) => {
|
|
308
|
-
if (final === null) {
|
|
309
|
-
final = index.search(term, {
|
|
310
|
-
resolve: false,
|
|
311
|
-
suggest: true,
|
|
312
|
-
});
|
|
313
|
-
}
|
|
314
|
-
else {
|
|
315
|
-
final = final.or({
|
|
316
|
-
index: index,
|
|
317
|
-
query: term,
|
|
318
|
-
resolve: false,
|
|
319
|
-
suggest: true,
|
|
320
|
-
});
|
|
321
|
-
}
|
|
322
|
-
});
|
|
323
|
-
final = final.and({
|
|
324
|
-
index: index,
|
|
325
|
-
query: sku,
|
|
326
|
-
resolve: false,
|
|
327
|
-
suggest: true,
|
|
328
|
-
});
|
|
239
|
+
// Build exclusion list
|
|
329
240
|
const nots = [];
|
|
330
|
-
const formatted = filters.skip_skus
|
|
331
|
-
.filter((sku) => sku.toLowerCase() !== variant.sku.toLowerCase())
|
|
332
|
-
.map((sku) => ` ${sku} `);
|
|
241
|
+
const formatted = filters.skip_skus.filter((s) => s.toLowerCase() !== variant.sku.toLowerCase()).map((s) => `${s}`);
|
|
333
242
|
nots.push(...formatted);
|
|
334
|
-
nots.push(...filters.vendor_search_exclusions.filter((
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
243
|
+
nots.push(...filters.vendor_search_exclusions.filter((s) => s.toLowerCase() !== variant.sku.toLowerCase()));
|
|
244
|
+
// Find matching indices based on search criteria
|
|
245
|
+
const matchingIndices = [];
|
|
246
|
+
dataToSearch.forEach((item, index) => {
|
|
247
|
+
// NOT logic: Check if none of the exclusion terms match
|
|
248
|
+
const hasExclusion = nots.some((sku) => {
|
|
249
|
+
const escapedSku = sku.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
|
|
250
|
+
// this regex will pick up values from url eg. /product/sku12345/ without picking up partial matches and double counting eg. 15000 being counted twice in 15000 and xp15000
|
|
251
|
+
const skuRegex = new RegExp(`(?: |\/|\&|\=|"|'|\`)${escapedSku}(?: |\/|\&|\=|"|'|\`)`, 'gi');
|
|
252
|
+
const skuMatches = item.title.match(skuRegex);
|
|
253
|
+
return skuMatches && skuMatches.length > 0;
|
|
340
254
|
});
|
|
255
|
+
if (!hasExclusion) {
|
|
256
|
+
matchingIndices.push(index);
|
|
257
|
+
}
|
|
341
258
|
});
|
|
342
|
-
|
|
343
|
-
const resultsArray = [];
|
|
344
|
-
result.forEach((i) => {
|
|
345
|
-
resultsArray.push(dataToSearch[i]);
|
|
346
|
-
});
|
|
259
|
+
// Mark items that don't match with hide reason
|
|
347
260
|
for (let index = 0; index < dataToSearch.length; index++) {
|
|
348
261
|
const element = dataToSearch[index];
|
|
349
|
-
if (!
|
|
262
|
+
if (!matchingIndices.includes(index)) {
|
|
350
263
|
if (!element.hide_reasons) {
|
|
351
264
|
element.hide_reasons = [];
|
|
352
265
|
}
|