diff --git a/index.js b/index.js index e656f74..92b08a9 100644 --- a/index.js +++ b/index.js @@ -3,9 +3,9 @@ const ipRegex = require('ip-regex'); const tlds = require('tlds'); module.exports = opts => { - opts = Object.assign({strict: true}, opts); + opts = Object.assign({strict: true, local: false}, opts); - const protocol = `(?:(?:[a-z]+:)?//)${opts.strict ? '' : '?'}`; + const protocol = '(?:(?:[a-z]+:)?//)'; const auth = '(?:\\S+(?::\\S*)?@)?'; const ip = ipRegex.v4().source; const host = '(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)'; @@ -13,7 +13,7 @@ module.exports = opts => { const tld = `(?:\\.${opts.strict ? '(?:[a-z\\u00a1-\\uffff]{2,})' : `(?:${tlds.sort((a, b) => b.length - a.length).join('|')})`})\\.?`; const port = '(?::\\d{2,5})?'; const path = '(?:[/?#][^\\s"]*)?'; - const regex = `(?:${protocol}|www\\.)${auth}(?:localhost|${ip}|${host}${domain}${tld})${port}${path}`; + const regex = `(?:(?:${protocol}${opts.strict ? '' : '?'}|www\\.)${auth}(?:localhost|${ip}|${host}${domain}${tld})${opts.local ? `|${protocol}${host}` : ''})${port}${path}`; return opts.exact ? new RegExp(`(?:^${regex}$)`, 'i') : new RegExp(regex, 'ig'); }; diff --git a/readme.md b/readme.md index 38a1118..2805d28 100644 --- a/readme.md +++ b/readme.md @@ -29,6 +29,9 @@ urlRegex({exact: true}).test('http://github.com foo bar'); urlRegex({exact: true}).test('http://github.com'); //=> true +urlRegex({exact: true, local: true}).test('http://orgchart/index.php'); +//=> true + urlRegex({strict: false}).test('github.com foo bar'); //=> true @@ -62,6 +65,13 @@ Default: `true` Force URLs to start with a valid protocol or `www`. If set to `false` it'll match the TLD against a list of valid [TLDs](https://github.com/stephenmathieson/node-tlds). +##### local + +Type: `boolean`
+Default: `false` + +Allow also to test URLs with private network hosts. If set to `true` it'll match local URLs like `http://forge/library/home/` (without TLD). + ## Related diff --git a/test.js b/test.js index 525380c..e3d6f5c 100644 --- a/test.js +++ b/test.js @@ -1,5 +1,11 @@ import test from 'ava'; -import m from './'; +import m from '.'; + +const localUrlFixtures = [ + 'http://orgchart/index.php', + 'http://aplicakcepredpisy/index.php?tpl=pk_khika$book_id=1057', + 'http://forge/library/home/' +]; test('match exact URLs', t => { const fixtures = [ @@ -195,3 +201,39 @@ test('match using list of TLDs', t => { t.true(m({exact: true, strict: false}).test(x)); } }); + +test('match local URLs', t => { + for (const x of localUrlFixtures) { + t.true(m({exact: true, local: true}).test(x)); + } +}); + +test('should not match local domains but localhost', t => { + t.true(m({exact: true}).test('http://localhost/')); + + for (const x of localUrlFixtures) { + t.false(m({exact: true}).test(x)); + } +}); + +test('should not match words or text as local URLs', t => { + const fixtures = [ + 'text', + 'text with more words, but still without URLs', + 'text without url and/or slash' + ]; + + for (const x of fixtures) { + t.false(m({strict: false, exact: false, local: true}).test(x)); + } +}); + +test('match local URLs in text', t => { + const fixtures = [ + 'text with local(http://orgchart/index.php) urls' + ]; + + for (const x of fixtures) { + t.true(m({strict: false, exact: false, local: true}).test(x)); + } +});