All files / src/helpers/search index.ts

100% Statements 53/53
98.39% Branches 61/62
100% Functions 7/7
100% Lines 50/50

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 1035x                 5x 20x     10x   2x 2x       1x 1x   2x 2x     1x 1x   1x 1x   2x     2x   1x 1x     10x     5x 18x   18x   18x 4x 4x     18x 2x 1x     18x 1x     18x 11x 11x 10x       18x     5x 5x   5x 3x     2x 2x 1x     1x     5x 4x 3x     1x       5x 5x 5x    
import {
  CategoryWhereSearch,
  ProductWhereSearch,
  OrderWhereSearch,
  Filter,
  AttributeType
} from './../../types/Api';
import { Config } from './../../types/setup';
 
const mapFilterToPredicate = (settings: Config, filter: Filter) => {
  const { locale, currency } = settings;
 
  let valuePredicate: string;
  switch (filter.type) {
    case AttributeType.STRING:
      valuePredicate = `value = "${filter.value}"`;
      break;
    case AttributeType.DATE:
    case AttributeType.DATETIME:
    case AttributeType.TIME:
      valuePredicate = Array.isArray(filter.value) ? `value >= "${filter.value[0]}" and value <= "${filter.value[1]}"` : `value = "${filter.value}"`;
      break;
    case AttributeType.NUMBER:
      valuePredicate = Array.isArray(filter.value) ? `value >= ${filter.value[0]} and value <= ${filter.value[1]}` : `value = ${filter.value}`;
      break;
    case AttributeType.ENUM:
    case AttributeType.LOCALIZED_ENUM:
      valuePredicate = `value(key = "${filter.value}")`;
      break;
    case AttributeType.LOCALIZED_STRING:
      valuePredicate = `value(${locale.toLowerCase()} = "${filter.value}")`;
      break;
    case AttributeType.MONEY:
      valuePredicate = Array.isArray(filter.value)
        ? `value(centAmount >= ${(filter.value[0] as number) * 100} and centAmount <= ${(filter.value[1] as number) * 100} and currencyCode = "${currency}")`
        : `value(centAmount = ${filter.value} and currencyCode = "${currency}")`;
      break;
    case AttributeType.BOOLEAN:
      valuePredicate = `value = ${filter.value}`;
      break;
  }
 
  return `masterData(current(masterVariant(attributes(name = "${filter.name}" and ${valuePredicate}))))`;
};
 
const buildProductWhere = (settings: Config, search: ProductWhereSearch) => {
  const { acceptLanguage } = settings;
 
  const predicates: string[] = [];
 
  if (search?.catId) {
    const catIds = (Array.isArray(search.catId) ? search.catId : [search.catId]).join('","');
    predicates.push(`masterData(current(categories(id in ("${catIds}"))))`);
  }
 
  if (search?.slug) {
    const predicate = acceptLanguage.map(locale => `${locale}="${search.slug}"`).join(' or ');
    predicates.push(`masterData(current(slug(${predicate})))`);
  }
 
  if (search?.id) {
    predicates.push(`id="${search.id}"`);
  }
 
  if (search?.filters) {
    const filterPredicates = search.filters.map((f) => mapFilterToPredicate(settings, f)).join(' or ');
    if (filterPredicates) {
      predicates.push(filterPredicates);
    }
  }
 
  return predicates.join(' and ');
};
 
const buildCategoryWhere = (settings: Config, search: CategoryWhereSearch) => {
  const { acceptLanguage } = settings;
 
  if (search?.catId) {
    return `id="${search.catId}"`;
  }
 
  if (search?.slug) {
    const predicate = acceptLanguage.map(locale => `${locale}="${search.slug}"`).join(' or ');
    return `slug(${predicate})`;
  }
 
  return undefined;
};
 
const buildOrderWhere = (search: OrderWhereSearch): string => {
  if (search?.id) {
    return `id="${search.id}"`;
  }
 
  return null;
};
 
export {
  buildProductWhere,
  buildCategoryWhere,
  buildOrderWhere
};