@factorypure/client-helpers 1.0.26 → 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 CHANGED
@@ -192,6 +192,7 @@ export declare const immersiveScrapeResultsSchema: z.ZodObject<{
192
192
  position: z.ZodNumber;
193
193
  title: z.ZodString;
194
194
  found_product_id: z.ZodString;
195
+ type: z.ZodString;
195
196
  product_link: z.ZodString;
196
197
  immersive_product_page_token: z.ZodString;
197
198
  source: z.ZodString;
package/dist/index.js CHANGED
@@ -84,6 +84,7 @@ export const immersiveScrapeResultsSchema = z.object({
84
84
  position: z.number(),
85
85
  title: z.string(),
86
86
  found_product_id: z.string(),
87
+ type: z.string(),
87
88
  product_link: z.string(),
88
89
  immersive_product_page_token: z.string(),
89
90
  source: z.string(),
@@ -202,78 +203,30 @@ export const filterScrapeResults = ({ scrapeResults, variant, filters, globalScr
202
203
  return filteredResults;
203
204
  };
204
205
  const handleVendorExclusions = (dataToSearch, filters, variant) => {
205
- if (!filters.skip_vendors || filters.skip_vendors.length === 0) {
206
- return dataToSearch;
207
- }
208
- const { title, sku } = variant;
209
- function customEncoder(content) {
210
- const tokens = [];
211
- const str = content.toLowerCase();
212
- // Remove symbols from the string (keep only letters, numbers, commas, and spaces)
213
- const cleanedStr = str.replace(/[\/-]/g, ' ');
214
- const cleanedStr2 = cleanedStr.replace(/[^a-z0-9,\/\s]/gi, '');
215
- const words = cleanedStr2.split(/\s+/);
216
- for (let word of words) {
217
- tokens.push(word);
218
- }
219
- return tokens;
220
- }
221
- const index = new Index({
222
- // @ts-ignore
223
- charset: EnglishPreset,
224
- // encoder: encoder,
225
- encode: customEncoder,
226
- tokenize: 'strict',
227
- });
228
- dataToSearch.forEach((item, id) => {
229
- index.add(id, item.title);
230
- });
231
- const searchTerms = filters.match_values;
232
- let final = null;
233
- searchTerms.forEach((term) => {
234
- if (final === null) {
235
- final = index.search(term, {
236
- resolve: false,
237
- suggest: true,
238
- });
239
- }
240
- else {
241
- final = final.or({
242
- index: index,
243
- query: term,
244
- resolve: false,
245
- suggest: true,
246
- });
247
- }
248
- });
249
- final = final.and({
250
- index: index,
251
- query: sku,
252
- resolve: false,
253
- suggest: true,
254
- });
206
+ // Build exclusion list
255
207
  const nots = [];
256
- if (filters.skip_vendors.length > 0) {
257
- const formatted = filters.skip_vendors
258
- .filter((vendor) => vendor.toLowerCase() !== variant.vendor.toLowerCase())
259
- .map((vendor) => ` ${vendor} `);
260
- nots.push(...formatted);
261
- }
262
- nots.forEach((term) => {
263
- final = final.not({
264
- index: index,
265
- query: term,
266
- resolve: false,
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;
267
221
  });
222
+ if (!hasExclusion) {
223
+ matchingIndices.push(index);
224
+ }
268
225
  });
269
- const result = final.resolve({ limit: 1000 });
270
- const resultsArray = [];
271
- result.forEach((i) => {
272
- resultsArray.push(dataToSearch[i]);
273
- });
226
+ // Mark items that don't match with hide reason
274
227
  for (let index = 0; index < dataToSearch.length; index++) {
275
228
  const element = dataToSearch[index];
276
- if (!result.includes(index)) {
229
+ if (!matchingIndices.includes(index)) {
277
230
  if (!element.hide_reasons) {
278
231
  element.hide_reasons = [];
279
232
  }
@@ -283,74 +236,30 @@ const handleVendorExclusions = (dataToSearch, filters, variant) => {
283
236
  return dataToSearch;
284
237
  };
285
238
  const handleSkipSkuSearch = (dataToSearch, filters, variant) => {
286
- const { title, sku } = variant;
287
- function customEncoder(content) {
288
- const tokens = [];
289
- const str = content.toLowerCase();
290
- // Remove symbols from the string (keep only letters, numbers, commas, and spaces)
291
- const cleanedStr = str.replace(/[\/-]/g, ' ');
292
- const cleanedStr2 = cleanedStr.replace(/[^a-z0-9,\/\s]/gi, '');
293
- const words = cleanedStr2.split(/\s+/);
294
- for (let word of words) {
295
- tokens.push(word);
296
- }
297
- return tokens;
298
- }
299
- const index = new Index({
300
- // @ts-ignore
301
- charset: EnglishPreset,
302
- // encoder: encoder,
303
- encode: customEncoder,
304
- tokenize: 'strict',
305
- });
306
- dataToSearch.forEach((item, id) => {
307
- index.add(id, item.title);
308
- });
309
- const searchTerms = filters.match_values;
310
- let final = null;
311
- searchTerms.forEach((term) => {
312
- if (final === null) {
313
- final = index.search(term, {
314
- resolve: false,
315
- suggest: true,
316
- });
317
- }
318
- else {
319
- final = final.or({
320
- index: index,
321
- query: term,
322
- resolve: false,
323
- suggest: true,
324
- });
325
- }
326
- });
327
- final = final.and({
328
- index: index,
329
- query: sku,
330
- resolve: false,
331
- suggest: true,
332
- });
239
+ // Build exclusion list
333
240
  const nots = [];
334
- const formatted = filters.skip_skus
335
- .filter((sku) => sku.toLowerCase() !== variant.sku.toLowerCase())
336
- .map((sku) => ` ${sku} `);
241
+ const formatted = filters.skip_skus.filter((s) => s.toLowerCase() !== variant.sku.toLowerCase()).map((s) => `${s}`);
337
242
  nots.push(...formatted);
338
- nots.push(...filters.vendor_search_exclusions.filter((sku) => sku.toLowerCase() !== variant.sku.toLowerCase()));
339
- nots.forEach((term) => {
340
- final = final.not({
341
- index: index,
342
- query: term,
343
- resolve: false,
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;
344
254
  });
255
+ if (!hasExclusion) {
256
+ matchingIndices.push(index);
257
+ }
345
258
  });
346
- const result = final.resolve({ limit: 1000 });
347
- const resultsArray = [];
348
- result.forEach((i) => {
349
- resultsArray.push(dataToSearch[i]);
350
- });
259
+ // Mark items that don't match with hide reason
351
260
  for (let index = 0; index < dataToSearch.length; index++) {
352
261
  const element = dataToSearch[index];
353
- if (!result.includes(index)) {
262
+ if (!matchingIndices.includes(index)) {
354
263
  if (!element.hide_reasons) {
355
264
  element.hide_reasons = [];
356
265
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@factorypure/client-helpers",
3
- "version": "1.0.26",
3
+ "version": "1.0.27",
4
4
  "description": "",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",