matchesStringOrRegExp.cjs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. // NOTICE: This file is generated by Rollup. To modify it,
  2. // please instead edit the ESM counterpart and rebuild with Rollup (npm run build).
  3. 'use strict';
  4. /**
  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.
  8. *
  9. * Any strings starting and ending with `/` are interpreted
  10. * as regular expressions.
  11. *
  12. * @typedef {{match: string, pattern: (string | RegExp), substring: string} | false} MatchResult
  13. *
  14. * @param {string | Array<string>} input
  15. * @param {string | RegExp | Array<string | RegExp>} comparison
  16. * @returns {MatchResult}
  17. */
  18. function matchesStringOrRegExp(input, comparison) {
  19. if (!Array.isArray(input)) {
  20. return testAgainstStringOrRegExpOrArray(input, comparison);
  21. }
  22. for (const inputItem of input) {
  23. const testResult = testAgainstStringOrRegExpOrArray(inputItem, comparison);
  24. if (testResult) {
  25. return testResult;
  26. }
  27. }
  28. return false;
  29. }
  30. /**
  31. * @param {string} value
  32. * @param {string | RegExp | Array<string | RegExp>} comparison
  33. * @returns {MatchResult}
  34. */
  35. function testAgainstStringOrRegExpOrArray(value, comparison) {
  36. if (!Array.isArray(comparison)) {
  37. return testAgainstStringOrRegExp(value, comparison);
  38. }
  39. for (const comparisonItem of comparison) {
  40. const testResult = testAgainstStringOrRegExp(value, comparisonItem);
  41. if (testResult) {
  42. return testResult;
  43. }
  44. }
  45. return false;
  46. }
  47. /**
  48. * @param {string} value
  49. * @param {RegExp} pattern
  50. * @returns {MatchResult}
  51. */
  52. function matchValue(value, pattern) {
  53. const match = value.match(pattern);
  54. return match ? { match: value, pattern, substring: match[0] ?? '' } : false;
  55. }
  56. /**
  57. * @param {string} value
  58. * @param {string | RegExp} comparison
  59. * @returns {MatchResult}
  60. */
  61. function testAgainstStringOrRegExp(value, comparison) {
  62. // If it's a RegExp, test directly
  63. if (comparison instanceof RegExp) {
  64. return matchValue(value, comparison);
  65. }
  66. // Check if it's RegExp in a string
  67. const regexFlag = 'i';
  68. const comparisonIsRegex =
  69. comparison.startsWith('/') &&
  70. (comparison.endsWith('/') || comparison.endsWith(`/${regexFlag}`));
  71. // If so, create a new RegExp from it
  72. if (comparisonIsRegex) {
  73. const pattern = comparison.endsWith(regexFlag)
  74. ? new RegExp(comparison.slice(1, -2), regexFlag)
  75. : new RegExp(comparison.slice(1, -1));
  76. const result = matchValue(value, pattern);
  77. if (result) {
  78. result.pattern = comparison;
  79. }
  80. return result;
  81. }
  82. // Otherwise, it's a string. Do a strict comparison
  83. return value === comparison ? { match: value, pattern: comparison, substring: value } : false;
  84. }
  85. module.exports = matchesStringOrRegExp;