UNPKG

1.95 kBJavaScriptView Raw
1/* @flow */
2
3/**
4 * Compares a string to a second value that, if it fits a certain convention,
5 * is converted to a regular expression before the comparison.
6 * If it doesn't fit the convention, then two strings are compared.
7 *
8 * Any strings starting and ending with `/` are interpreted
9 * as regular expressions.
10 */
11module.exports = function matchesStringOrRegExp(
12 input /*: string | Array<string>*/,
13 comparison /*: string | Array<string>*/
14) /*: false | { match: string, pattern: string}*/ {
15 if (!Array.isArray(input)) {
16 return testAgainstStringOrArray(input, comparison);
17 }
18
19 for (const inputItem of input) {
20 const testResult = testAgainstStringOrArray(inputItem, comparison);
21 if (testResult) {
22 return testResult;
23 }
24 }
25
26 return false;
27};
28
29function testAgainstStringOrArray(value, comparison) {
30 if (!Array.isArray(comparison)) {
31 return testAgainstString(value, comparison);
32 }
33
34 for (const comparisonItem of comparison) {
35 const testResult = testAgainstString(value, comparisonItem);
36 if (testResult) {
37 return testResult;
38 }
39 }
40 return false;
41}
42
43function testAgainstString(value, comparison) {
44 const firstComparisonChar = comparison[0];
45 const lastComparisonChar = comparison[comparison.length - 1];
46 const secondToLastComparisonChar = comparison[comparison.length - 2];
47
48 const comparisonIsRegex =
49 firstComparisonChar === "/" &&
50 (lastComparisonChar === "/" ||
51 (secondToLastComparisonChar === "/" && lastComparisonChar === "i"));
52
53 const hasCaseInsensitiveFlag =
54 comparisonIsRegex && lastComparisonChar === "i";
55
56 if (comparisonIsRegex) {
57 const valueMatches = hasCaseInsensitiveFlag
58 ? new RegExp(comparison.slice(1, -2), "i").test(value)
59 : new RegExp(comparison.slice(1, -1)).test(value);
60 return valueMatches ? { match: value, pattern: comparison } : false;
61 }
62
63 return value === comparison ? { match: value, pattern: comparison } : false;
64}