5 * Compares a string to a second value that, if it fits a certain convention,
6 * is converted to a regular expression before the comparison.
7 * If it doesn't fit the convention, then two strings are compared.
9 * Any strings starting and ending with `/` are interpreted
10 * as regular expressions.
12 module.exports = function matchesStringOrRegExp(
13 input /*: string | Array<string>*/,
14 comparison /*: string | Array<string>*/
15 ) /*: false | { match: string, pattern: string}*/ {
16 if (!Array.isArray(input)) {
17 return testAgainstStringOrArray(input, comparison);
20 for (const inputItem of input) {
21 const testResult = testAgainstStringOrArray(inputItem, comparison);
30 function testAgainstStringOrArray(value, comparison) {
31 if (!Array.isArray(comparison)) {
32 return testAgainstString(value, comparison);
35 for (const comparisonItem of comparison) {
36 const testResult = testAgainstString(value, comparisonItem);
44 function testAgainstString(value, comparison) {
45 const firstComparisonChar = comparison[0];
46 const lastComparisonChar = comparison[comparison.length - 1];
47 const secondToLastComparisonChar = comparison[comparison.length - 2];
49 const comparisonIsRegex =
50 firstComparisonChar === "/" &&
51 (lastComparisonChar === "/" ||
52 (secondToLastComparisonChar === "/" && lastComparisonChar === "i"));
54 const hasCaseInsensitiveFlag =
55 comparisonIsRegex && lastComparisonChar === "i";
57 if (comparisonIsRegex) {
58 const valueMatches = hasCaseInsensitiveFlag
59 ? new RegExp(comparison.slice(1, -2), "i").test(value)
60 : new RegExp(comparison.slice(1, -1)).test(value);
61 return valueMatches ? { match: value, pattern: comparison } : false;
64 return value === comparison ? { match: value, pattern: comparison } : false;