UNPKG

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