@hsds/utils-strings
Advanced tools
Comparing version 5.2.1 to 7.0.0
@@ -5,4 +5,26 @@ # Changelog | ||
### [5.2.1](https://github.com/helpscout/hsds/compare/utils-strings-5.2.0...utils-strings-5.2.1) (2022-08-25) | ||
# [7.0.0](https://github.com/helpscout/hsds/compare/v6.0.0...v7.0.0) (2023-01-12) | ||
# [6.0.0](https://github.com/helpscout/hsds/compare/v5.0.0...v6.0.0) (2023-01-12) | ||
# [5.0.0](https://github.com/helpscout/hsds/compare/v4.0.0...v5.0.0) (2023-01-12) | ||
### Bug Fixes | ||
* **workspace:** remove esm module from projects ([829cc37](https://github.com/helpscout/hsds/commit/829cc3795f54a8bcfbc0c45b5bc36bd17463bf54)) | ||
### Features | ||
* **workspace:** improves versioning packages ([b836826](https://github.com/helpscout/hsds/commit/b836826d549aeb7295498f1091c783136079f134)) | ||
### [5.2.1](https://github.com/helpscout/hsds/compare/utils-strings-5.2.0...utils-strings-5.2.1) (2022-08-29) | ||
## [5.2.0](https://github.com/helpscout/hsds/compare/utils-strings-5.1.0...utils-strings-5.2.0) (2022-08-18) | ||
@@ -9,0 +31,0 @@ |
{ | ||
"name": "@hsds/utils-strings", | ||
"version": "5.2.1", | ||
"main": "./index.cjs.js", | ||
"module": "./index.esm.js", | ||
"typings": "./index.d.ts" | ||
"version": "7.0.0", | ||
"main": "./index.cjs", | ||
"type": "commonjs", | ||
"types": "./index.d.ts" | ||
} |
@@ -9,3 +9,2 @@ "use strict"; | ||
exports.normalizeUrl = exports.newlineToHTML = exports.escapeHTML = void 0; | ||
const normalizeUrl = string => { | ||
@@ -15,14 +14,9 @@ if (string == null) { | ||
} | ||
let url = string; | ||
if (url.search(/^http[s]?:\/\//) === -1) { | ||
url = `http://${url}`; | ||
} | ||
return url; | ||
}; | ||
exports.normalizeUrl = normalizeUrl; | ||
const newlineToHTML = string => { | ||
@@ -32,9 +26,9 @@ if (!string) { | ||
} | ||
return string.trim().replace(/\r?\n/g, '<br>'); | ||
}; // Taken from the React escapeTextForBrowser internal utility | ||
}; | ||
// Taken from the React escapeTextForBrowser internal utility | ||
exports.newlineToHTML = newlineToHTML; | ||
const escapeHtmlRegExp = /["'&<>]/; | ||
/** | ||
@@ -46,3 +40,2 @@ * Escape HTML special characters in the string for output in the browser. | ||
*/ | ||
const escapeHTML = string => { | ||
@@ -52,9 +45,6 @@ if (!string) { | ||
} | ||
const match = escapeHtmlRegExp.exec(string); | ||
if (!match) { | ||
return string; | ||
} | ||
let escape; | ||
@@ -64,3 +54,2 @@ let html = ''; | ||
let lastIndex = 0; | ||
for (index = match.index; index < string.length; index++) { | ||
@@ -72,3 +61,2 @@ switch (string.charCodeAt(index)) { | ||
break; | ||
case 38: | ||
@@ -78,3 +66,2 @@ // & | ||
break; | ||
case 39: | ||
@@ -84,3 +71,2 @@ // ' | ||
break; | ||
case 60: | ||
@@ -90,3 +76,2 @@ // < | ||
break; | ||
case 62: | ||
@@ -96,17 +81,14 @@ // > | ||
break; | ||
default: | ||
continue; | ||
} | ||
if (lastIndex !== index) { | ||
html += string.substring(lastIndex, index); | ||
} | ||
lastIndex = index + 1; | ||
html += escape; | ||
} | ||
return lastIndex !== index ? html + string.substring(lastIndex, index) : html; | ||
}; | ||
/** | ||
@@ -117,6 +99,5 @@ * The string form of a regular expression that would match all of the | ||
*/ | ||
exports.escapeHTML = escapeHTML; | ||
const alphaNumericAndMarksChars = 'a-z0-9\\-+&@#/%=~_'; | ||
/** | ||
@@ -128,24 +109,24 @@ * Partial regex pattern to match the TLD of a domain. | ||
*/ | ||
const tldPattern = '[a-z]{2,24}'; | ||
const tldPattern = '[a-z]{2,24}'; | ||
/** | ||
* Partial regex pattern to match the domain part of a URL without the subdomain. | ||
*/ | ||
const domainPattern = '[a-z0-9-]+\\.' + tldPattern; | ||
const domainPattern = '[a-z0-9-]+\\.' + tldPattern; | ||
/** | ||
* Partial regex pattern to match the path of a URL. | ||
*/ | ||
const pathPattern = '(?:[/?#](?:[' + alphaNumericAndMarksChars + "\\(\\)|'$*\\[\\]?!:,.;]*[" + alphaNumericAndMarksChars + "|'$*\\[\\]])?)?)"; | ||
const pathPattern = '(?:[/?#](?:[' + alphaNumericAndMarksChars + "\\(\\)|'$*\\[\\]?!:,.;]*[" + alphaNumericAndMarksChars + "|'$*\\[\\]])?)?)"; | ||
/** | ||
* Regex pattern to match a complete URL. | ||
*/ | ||
const urlPattern = '(?:(?:(?:https?:\\/\\/(?:[a-z0-9-]+\\.)*)|(?:[a-z0-9-]+\\.)+)?' + domainPattern + pathPattern; | ||
const urlPattern = '(?:(?:(?:https?:\\/\\/(?:[a-z0-9-]+\\.)*)|(?:[a-z0-9-]+\\.)+)?' + domainPattern + pathPattern; | ||
/** | ||
* Regex pattern to match an email address. | ||
*/ | ||
const emailPattern = "(?:\\b[a-z0-9._'%+-]+@[a-z0-9.-]+\\." + tldPattern + ')'; | ||
const emailPattern = "(?:\\b[a-z0-9._'%+-]+@[a-z0-9.-]+\\." + tldPattern + ')'; | ||
/** | ||
@@ -156,3 +137,2 @@ * @param {string} string | ||
*/ | ||
const convertLinksToHTML = string => { | ||
@@ -162,3 +142,2 @@ if (!string) { | ||
} | ||
return string.split(new RegExp(`(${urlPattern}|${emailPattern})`, 'gi')).reduce((accumulator, value, index) => { | ||
@@ -169,7 +148,6 @@ if (index % 2) { | ||
return accumulator + `<a href="mailto:${escapeHTML(value)}">${escapeHTML(value)}</a>`; | ||
} // Matched a URL | ||
} | ||
// Matched a URL | ||
let url = value; | ||
if (url.match(new RegExp(`^${domainPattern}$`, 'i'))) { | ||
@@ -180,14 +158,15 @@ // Only matched a domain name (without subdomain) | ||
return accumulator + url; | ||
} // Add http as the default scheme if needed | ||
} | ||
// Add http as the default scheme if needed | ||
url = normalizeUrl(url); | ||
url = normalizeUrl(url); // Adding target blank and rel noopener for external links | ||
// Adding target blank and rel noopener for external links | ||
// See: https://developers.google.com/web/tools/lighthouse/audits/noopener | ||
return accumulator + `<a href="${escapeHTML(url)}" target="_blank" rel="noopener">${escapeHTML(value)}</a>`; | ||
} | ||
return accumulator + escapeHTML(value); | ||
}, ''); | ||
}; | ||
/** | ||
@@ -199,13 +178,10 @@ * Camelcases a specified string. | ||
*/ | ||
exports.convertLinksToHTML = convertLinksToHTML; | ||
function camelCase(string) { | ||
return string.replace(/-/g, ' ').replace(/(?:^\w|[A-Z]|\b\w|\s+)/g, (match, index) => { | ||
if (+match === 0) return ''; // or if (/\s+/.test(match)) for white spaces | ||
return index === 0 ? match.toLowerCase() : match.toUpperCase(); | ||
}); | ||
} | ||
/** | ||
@@ -219,5 +195,5 @@ * @license | ||
const STRING_DASHERIZE_REGEXP = /[ _.]/g; | ||
const STRING_DECAMELIZE_REGEXP = /([a-z\d])([A-Z])/g; | ||
/** | ||
@@ -237,6 +213,6 @@ * Converts a camelized string into all lower case separated by underscores. | ||
*/ | ||
function decamelize(str) { | ||
return str.replace(STRING_DECAMELIZE_REGEXP, '$1_$2').toLowerCase(); | ||
} | ||
/** | ||
@@ -257,6 +233,4 @@ Replaces underscores, spaces, periods, or camelCase with dashes. | ||
*/ | ||
function dasherize(str) { | ||
return decamelize(str || '').replace(STRING_DASHERIZE_REGEXP, '-'); | ||
} |
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
15454
398
0