# All files / utils fuzzyFilter.ts

0% Statements 0/52
0% Branches 0/1
0% Functions 0/1
0% Lines 0/52

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

     const identity = <T>(item: T): string => {
      if (typeof item === "string") {
        return item;
      }

      if (process.env.NODE_ENV !== "production") {
        throw new Error(
          "A `TextExtractor` must be provided to `fuzzyFilter` for lists that do not contain strings"
        );
      }

      return "";
    };

    export function fuzzyFilter<T extends string>(
      options: FilterOptions<T>
    ): readonly T[];
    export function fuzzyFilter<T>(
      option: FilterOptions<T> & { extractor: TextExtractor<T> }
    ): readonly T[];
    export function fuzzyFilter<T>(options: FilterOptions<T>): readonly T[] {
      const { list, query, extractor = identity, whitespace = "keep" } = options;
      if (!list.length) {
        return list;
      }

      let q = query.toLowerCase();
      if (whitespace === "ignore") {
        q = q.replace(/\s/g, "");
      } else if (whitespace === "trim") {
        q = q.trim();
      }

      if (!q) {
        return list;
      }

      const regexp = new RegExp(
        `${query}`
          .split("")
          .join("\\w*")
          .replace(/(\(|\||\)|\\(?!w\*)|\[|\|-|\.|\^|\+|\$|\?|^(?!w)\*)/g, "\\$1")
          // Couldn't get the matching of two '*' working, so replace them here..
          .replace(/\*\*/g, "*\\*"),
        "i"
      );
      return list.filter((item) => {
        const value = extractor(item);

        return value.length > 0 && regexp.test(value);
      });
    }