diff --git a/index.d.ts b/index.d.ts index cdb7b34..cf25d4a 100644 --- a/index.d.ts +++ b/index.d.ts @@ -15,8 +15,20 @@ isAbsoluteUrl('//sindresorhus.com'); isAbsoluteUrl('foo/bar'); //=> false + +isAbsoluteUrl('file://sindresorhus.com', {httpOnly: false}); +//=> true ``` */ -declare function isAbsoluteUrl(url: string): boolean; +interface Options { + /** + Check if it's an absolute HTTP URL + + @default true + */ + readonly httpOnly?: boolean; +} + +declare function isAbsoluteUrl(url: string, httpOnly?: Options): boolean; export = isAbsoluteUrl; diff --git a/index.js b/index.js index 25dca66..027b3b1 100644 --- a/index.js +++ b/index.js @@ -1,10 +1,14 @@ 'use strict'; -module.exports = url => { +module.exports = (url, options = {httpOnly: true}) => { if (typeof url !== 'string') { throw new TypeError(`Expected a \`string\`, got \`${typeof url}\``); } + if (options.httpOnly) { + return /^((http[s]?)?:\/\/([-a-z0-9()@:%_.~#?&//=]*))/gi.test(url); + } + // Don't match Windows paths `c:\` if (/^[a-zA-Z]:\\/.test(url)) { return false; diff --git a/index.test-d.ts b/index.test-d.ts index 6ad483a..74146e4 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -1,4 +1,4 @@ import {expectType} from 'tsd'; import isAbsoluteUrl = require('.'); -expectType(isAbsoluteUrl('https://sindresorhus.com/foo/bar')); +expectType(isAbsoluteUrl('https://sindresorhus.com/foo/bar', {httpOnly: true})); diff --git a/readme.md b/readme.md index 17b3525..f1fd05d 100644 --- a/readme.md +++ b/readme.md @@ -25,6 +25,26 @@ isAbsoluteUrl('foo/bar'); //=> false ``` +### Options + +#### httpOnly + +Type: `boolean`\ +Default: `true` + +Only accept absolute HTTP URLs. + +```js +isAbsoluteUrl('https://si', {httpOnly: true}); +//=> true + +isAbsoluteUrl('mailto:someone@example.com', {httpOnly: false}); +//=> true + +isAbsoluteUrl('data:text/plain;base64,SGV', {httpOnly: false}); +//=> true +``` + ## Related diff --git a/test.js b/test.js index f68537b..f321ee3 100644 --- a/test.js +++ b/test.js @@ -5,9 +5,9 @@ test('main', t => { t.true(isAbsoluteUrl('http://sindresorhus.com')); t.true(isAbsoluteUrl('https://sindresorhus.com')); t.true(isAbsoluteUrl('httpS://sindresorhus.com')); - t.true(isAbsoluteUrl('file://sindresorhus.com')); - t.true(isAbsoluteUrl('mailto:someone@example.com')); - t.true(isAbsoluteUrl('data:text/plain;base64,SGVsbG8sIFdvcmxkIQ%3D%3D')); + t.false(isAbsoluteUrl('file://sindresorhus.com')); + t.false(isAbsoluteUrl('mailto:someone@example.com')); + t.false(isAbsoluteUrl('data:text/plain;base64,SGVsbG8sIFdvcmxkIQ%3D%3D')); t.false(isAbsoluteUrl('//sindresorhus.com')); t.false(isAbsoluteUrl('/foo/bar')); t.false(isAbsoluteUrl('foo/bar')); @@ -17,3 +17,60 @@ test('main', t => { t.false(isAbsoluteUrl('C:\\Dev\\test-broken')); t.false(isAbsoluteUrl('ht,tp://sindresorhus.com')); }); + +test('options => {httpOnly: true}. Assert true', t => { + t.true(isAbsoluteUrl('http://sindresorhus.com', {httpOnly: true})); + t.true(isAbsoluteUrl('https://sindresorhus.com', {httpOnly: true})); + t.true(isAbsoluteUrl('httpS://sindresorhus.com', {httpOnly: true})); + t.true(isAbsoluteUrl('https://www.sindresorhus.com', {httpOnly: true})); + t.true(isAbsoluteUrl('https://www.sindres.orhus.com/path', {httpOnly: true})); + t.true(isAbsoluteUrl('httpS://www.sindresorhus.com', {httpOnly: true})); + t.true(isAbsoluteUrl('https://sindresorhus', {httpOnly: true})); + t.true(isAbsoluteUrl('httpS://localhost:8000', {httpOnly: true})); + t.true(isAbsoluteUrl('http://localhost', {httpOnly: true})); + t.true(isAbsoluteUrl('http://sin dresorhus.com', {httpOnly: true})); +}); + +test('options => {httpOnly: true}. Assert false', t => { + t.false(isAbsoluteUrl('yhttp://sindresorhus.com', {httpOnly: true})); + t.false(isAbsoluteUrl('file://sindresorhus.com', {httpOnly: true})); + t.false(isAbsoluteUrl('mailto:someone@example.com', {httpOnly: true})); + t.false(isAbsoluteUrl('data:text/plain;base64,SGVsbG8sIFdvcmxkIQ%3D%3D', {httpOnly: true})); + t.false(isAbsoluteUrl('ht,tp://sindresorhus.com', {httpOnly: true})); + t.false(isAbsoluteUrl('//sindresorhus.com', {httpOnly: true})); + t.false(isAbsoluteUrl('/foo/bar', {httpOnly: true})); + t.false(isAbsoluteUrl('foo/bar', {httpOnly: true})); + t.false(isAbsoluteUrl('foo', {httpOnly: true})); + t.false(isAbsoluteUrl('c:\\', {httpOnly: true})); + t.false(isAbsoluteUrl('c:\\Dev\\test-broken', {httpOnly: true})); + t.false(isAbsoluteUrl('C:\\Dev\\test-broken', {httpOnly: true})); + t.false(isAbsoluteUrl('h t,tp://sindresorhus.com', {httpOnly: true})); + t.false(isAbsoluteUrl('javascript:throw%20document.cookie', {httpOnly: true})); +}); + +test('options => {httpOnly: false}. Assert true', t => { + t.true(isAbsoluteUrl('http://sindresorhus.com', {httpOnly: false})); + t.true(isAbsoluteUrl('https://sindresorhus.com', {httpOnly: false})); + t.true(isAbsoluteUrl('httpS://sindresorhus.com', {httpOnly: false})); + t.true(isAbsoluteUrl('file://sindresorhus.com', {httpOnly: false})); + t.true(isAbsoluteUrl('mailto:someone@example.com', {httpOnly: false})); + t.true(isAbsoluteUrl('data:text/plain;base64,SGVsbG8sIFdvcmxkIQ%3D%3D', {httpOnly: false})); + t.true(isAbsoluteUrl('https://www.sindresorhus.com', {httpOnly: false})); + t.true(isAbsoluteUrl('https://www.sindres.orhus.com/path', {httpOnly: false})); + t.true(isAbsoluteUrl('httpS://www.sindresorhus.com', {httpOnly: false})); + t.true(isAbsoluteUrl('javascript:throw%20document.cookie', {httpOnly: false})); + t.true(isAbsoluteUrl('https://sindresorhus', {httpOnly: false})); + t.true(isAbsoluteUrl('http://sindr esorhus.com', {httpOnly: false})); +}); + +test('options => {httpOnly: false}. Assert false', t => { + t.false(isAbsoluteUrl('ht,tp://sindresorhus.com', {httpOnly: false})); + t.false(isAbsoluteUrl('//sindresorhus.com', {httpOnly: false})); + t.false(isAbsoluteUrl('/foo/bar', {httpOnly: false})); + t.false(isAbsoluteUrl('foo/bar', {httpOnly: false})); + t.false(isAbsoluteUrl('foo', {httpOnly: false})); + t.false(isAbsoluteUrl('c:\\', {httpOnly: false})); + t.false(isAbsoluteUrl('c:\\Dev\\test-broken', {httpOnly: false})); + t.false(isAbsoluteUrl('C:\\Dev\\test-broken', {httpOnly: false})); + t.false(isAbsoluteUrl('ht,tp://sindresorhus.com', {httpOnly: false})); +});