string.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. import { isVueViewModel, isString, isRegExp } from './is.js';
  2. /**
  3. * Truncates given string to the maximum characters count
  4. *
  5. * @param str An object that contains serializable values
  6. * @param max Maximum number of characters in truncated string (0 = unlimited)
  7. * @returns string Encoded
  8. */
  9. function truncate(str, max = 0) {
  10. if (typeof str !== 'string' || max === 0) {
  11. return str;
  12. }
  13. return str.length <= max ? str : `${str.slice(0, max)}...`;
  14. }
  15. /**
  16. * This is basically just `trim_line` from
  17. * https://github.com/getsentry/sentry/blob/master/src/sentry/lang/javascript/processor.py#L67
  18. *
  19. * @param str An object that contains serializable values
  20. * @param max Maximum number of characters in truncated string
  21. * @returns string Encoded
  22. */
  23. function snipLine(line, colno) {
  24. let newLine = line;
  25. const lineLength = newLine.length;
  26. if (lineLength <= 150) {
  27. return newLine;
  28. }
  29. if (colno > lineLength) {
  30. // eslint-disable-next-line no-param-reassign
  31. colno = lineLength;
  32. }
  33. let start = Math.max(colno - 60, 0);
  34. if (start < 5) {
  35. start = 0;
  36. }
  37. let end = Math.min(start + 140, lineLength);
  38. if (end > lineLength - 5) {
  39. end = lineLength;
  40. }
  41. if (end === lineLength) {
  42. start = Math.max(end - 140, 0);
  43. }
  44. newLine = newLine.slice(start, end);
  45. if (start > 0) {
  46. newLine = `'{snip} ${newLine}`;
  47. }
  48. if (end < lineLength) {
  49. newLine += ' {snip}';
  50. }
  51. return newLine;
  52. }
  53. /**
  54. * Join values in array
  55. * @param input array of values to be joined together
  56. * @param delimiter string to be placed in-between values
  57. * @returns Joined values
  58. */
  59. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  60. function safeJoin(input, delimiter) {
  61. if (!Array.isArray(input)) {
  62. return '';
  63. }
  64. const output = [];
  65. // eslint-disable-next-line @typescript-eslint/prefer-for-of
  66. for (let i = 0; i < input.length; i++) {
  67. const value = input[i];
  68. try {
  69. // This is a hack to fix a Vue3-specific bug that causes an infinite loop of
  70. // console warnings. This happens when a Vue template is rendered with
  71. // an undeclared variable, which we try to stringify, ultimately causing
  72. // Vue to issue another warning which repeats indefinitely.
  73. // see: https://github.com/getsentry/sentry-javascript/pull/8981
  74. if (isVueViewModel(value)) {
  75. output.push('[VueViewModel]');
  76. } else {
  77. output.push(String(value));
  78. }
  79. } catch (e) {
  80. output.push('[value cannot be serialized]');
  81. }
  82. }
  83. return output.join(delimiter);
  84. }
  85. /**
  86. * Checks if the given value matches a regex or string
  87. *
  88. * @param value The string to test
  89. * @param pattern Either a regex or a string against which `value` will be matched
  90. * @param requireExactStringMatch If true, `value` must match `pattern` exactly. If false, `value` will match
  91. * `pattern` if it contains `pattern`. Only applies to string-type patterns.
  92. */
  93. function isMatchingPattern(
  94. value,
  95. pattern,
  96. requireExactStringMatch = false,
  97. ) {
  98. if (!isString(value)) {
  99. return false;
  100. }
  101. if (isRegExp(pattern)) {
  102. return pattern.test(value);
  103. }
  104. if (isString(pattern)) {
  105. return requireExactStringMatch ? value === pattern : value.includes(pattern);
  106. }
  107. return false;
  108. }
  109. /**
  110. * Test the given string against an array of strings and regexes. By default, string matching is done on a
  111. * substring-inclusion basis rather than a strict equality basis
  112. *
  113. * @param testString The string to test
  114. * @param patterns The patterns against which to test the string
  115. * @param requireExactStringMatch If true, `testString` must match one of the given string patterns exactly in order to
  116. * count. If false, `testString` will match a string pattern if it contains that pattern.
  117. * @returns
  118. */
  119. function stringMatchesSomePattern(
  120. testString,
  121. patterns = [],
  122. requireExactStringMatch = false,
  123. ) {
  124. return patterns.some(pattern => isMatchingPattern(testString, pattern, requireExactStringMatch));
  125. }
  126. export { isMatchingPattern, safeJoin, snipLine, stringMatchesSomePattern, truncate };
  127. //# sourceMappingURL=string.js.map