Skip to content

Commit

Permalink
Adding Url class. Parsed object is now an instanceof Url
Browse files Browse the repository at this point in the history
  • Loading branch information
janicklas-ralph committed Apr 3, 2020
1 parent 19aacc0 commit c644df5
Show file tree
Hide file tree
Showing 7 changed files with 3,720 additions and 2,488 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ npm i native-url
```js
const url = require('native-url');

url.parse('https://example.com').host // example.com
url.parse('/?a=b', true).query // { a: 'b' }
url.parse('https://example.com').host; // example.com
url.parse('/?a=b', true).query; // { a: 'b' }
```

### Usage with Webpack

When you use the `url` module, webpack bundles [`node-url`](https://github.com/defunctzombie/node-url) for the browser. You can alias webpack to use `native-url` instead, saving around 7.5kB:
When you use the `url` module, webpack bundles [`node-url`](https://githu b.com/defunctzombie/node-url) for the browser. You can alias webpack to use `native-url` instead, saving around 7.5kB:

```js
// webpack.config.js
Expand All @@ -36,7 +36,7 @@ module.exports = {
url: 'native-url'
}
}
}
};
```

The result is **functionally equivalent** in Node 7+ and all modern browsers.
Expand Down
9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,13 @@
"resolveObject"
],
"devDependencies": {
"husky": "^3.0.5",
"jest": "^24.9.0",
"husky": "^4.2.3",
"jest": "^25.2.6",
"karmatic": "^1.4.0",
"lint-staged": "^9.2.5",
"lint-staged": "^10.1.1",
"microbundle": "^0.11.0",
"prettier": "^1.18.2",
"prettier": "^2.0.2",
"release-it": "^13.5.1",
"webpack": "^4.41.2"
},
"lint-staged": {
Expand Down
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@
export { default as parse } from './parse';
export { default as format } from './format';
export { resolve, resolveObject } from './resolve';
export { default as Url } from './url';
42 changes: 22 additions & 20 deletions src/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ let {
parseTestsWithQueryString,
formatTests,
relativeTests,
relativeTests2
relativeTests2,
} = require('../third_party/test_cases');
let url = require('../dist');

Expand All @@ -18,7 +18,7 @@ parseTests = {
query: 'test=space%20',
pathname: '/hello',
path: '/hello?test=space%20',
href: 'https://google.com/hello?test=space%20'
href: 'https://google.com/hello?test=space%20',
},
'?percent=%25': {
protocol: null,
Expand All @@ -32,7 +32,7 @@ parseTests = {
query: 'percent=%25',
pathname: null,
path: '?percent=%25',
href: '?percent=%25'
href: '?percent=%25',
},
[`?lf=before${encodeURI('\n')}after`]: {
protocol: null,
Expand All @@ -46,7 +46,7 @@ parseTests = {
query: 'lf=before%0Aafter',
pathname: null,
path: '?lf=before%0Aafter',
href: '?lf=before%0Aafter'
href: '?lf=before%0Aafter',
},
'https://www.w.org': {
protocol: 'https:',
Expand All @@ -60,7 +60,7 @@ parseTests = {
query: null,
pathname: '/',
path: '/',
href: 'https://www.w.org/'
href: 'https://www.w.org/',
},
'https://www.wikipedia.org/': {
protocol: 'https:',
Expand All @@ -74,25 +74,27 @@ parseTests = {
query: null,
pathname: '/',
path: '/',
href: 'https://www.wikipedia.org/'
}
href: 'https://www.wikipedia.org/',
},
};

describe('Basic parse and format:', () => {
Object.keys(parseTests).forEach(function(u) {
Object.keys(parseTests).forEach(function (u) {
it(`parse(${u}):`, () => {
const actual = url.parse(u);
const spaced = url.parse(' \t ' + u + '\n\t');
const expected = parseTests[u];

Object.keys(actual).forEach(i => {
Object.keys(actual).forEach((i) => {
if (expected[i] === undefined && actual[i] === null) {
expected[i] = null;
}
});

expect(actual).toEqual(expected);
expect(spaced).toEqual(expected);
// The parsed object is an instanceof Url
// Jasmine's toEqual fails when comparing an instance with and object
expect({ ...actual }).toEqual(expected);
expect({ ...spaced }).toEqual(expected);
});

it(`format(${u}):`, () => {
Expand All @@ -105,24 +107,24 @@ describe('Basic parse and format:', () => {
});

describe('With querystring:', () => {
Object.keys(parseTestsWithQueryString).forEach(function(u) {
Object.keys(parseTestsWithQueryString).forEach(function (u) {
it(`parse(${u}):`, () => {
const actual = url.parse(u, true);
const expected = parseTestsWithQueryString[u];

Object.keys(actual).forEach(i => {
Object.keys(actual).forEach((i) => {
if (expected[i] === undefined && actual[i] === null) {
expected[i] = null;
}
});

expect(actual).toEqual(expected);
expect({ ...actual }).toEqual(expected);
});
});
});

describe('Test format():', () => {
Object.keys(formatTests).forEach(function(u) {
Object.keys(formatTests).forEach(function (u) {
const expected = formatTests[u].href;
it(`format(${u}):`, () => {
const actual = url.format(u);
Expand All @@ -140,7 +142,7 @@ describe('Test format():', () => {
});

describe('Test resolve():', () => {
relativeTests.forEach(function(relativeTest) {
relativeTests.forEach(function (relativeTest) {
it(`resolve(${relativeTest[0]}, ${relativeTest[1]}):`, () => {
const actual = url.resolve(relativeTest[0], relativeTest[1]);
const expected = relativeTest[2];
Expand All @@ -151,7 +153,7 @@ describe('Test resolve():', () => {
});

// https://github.com/joyent/node/issues/568
[undefined, null, true, false, 0.0, 0, [], {}].forEach(function(val) {
[undefined, null, true, false, 0.0, 0, [], {}].forEach(function (val) {
describe('Test [undefined, null, true, false, 0.0, 0, [], {}] values:', () => {
it(`parse(${val})`, () => {
expect(() => {
Expand All @@ -162,7 +164,7 @@ describe('Test resolve():', () => {
});

describe('Test wonky resolves:', () => {
relativeTests2.forEach(function(relativeTest) {
relativeTests2.forEach(function (relativeTest) {
it(`resolve(${relativeTest[1]}, ${relativeTest[0]}):`, () => {
const actual = url.resolve(relativeTest[1], relativeTest[0]);
const expected = relativeTest[2];
Expand All @@ -173,7 +175,7 @@ describe('Test wonky resolves:', () => {
});

describe('Test resolveObject:', () => {
relativeTests.forEach(function(relativeTest) {
relativeTests.forEach(function (relativeTest) {
it(`resolveObject(${relativeTest[0]}, ${relativeTest[1]}):`, () => {
let actual = url.resolveObject(relativeTest[0], relativeTest[1]);
let expected = url.parse(relativeTest[2]);
Expand Down Expand Up @@ -206,7 +208,7 @@ if (
}

describe('Test wonky resolveObject:', () => {
relativeTests2.forEach(function(relativeTest) {
relativeTests2.forEach(function (relativeTest) {
it(`resolveObject(${relativeTest[1]}, ${relativeTest[0]}):`, () => {
let actual = url.resolveObject(
url.parse(relativeTest[1]),
Expand Down
10 changes: 7 additions & 3 deletions src/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import qs from 'querystring';
import format from './format';
import Url from './url';
import { BASE_URL, HOST } from './constants';

const slashedProtocols = /^https?|ftp|gopher|file/;
Expand All @@ -32,7 +33,10 @@ function safeDecode(url) {
}
}

export default function(urlStr, parseQs = false, slashesDenoteHost = false) {
export default function (urlStr, parseQs = false, slashesDenoteHost = false) {
if (urlStr && typeof urlStr === 'object' && urlStr instanceof Url) {
return urlStr;
}
urlStr = urlStr.trim();

const slashesMatch = urlStr.match(urlRegex);
Expand Down Expand Up @@ -88,7 +92,7 @@ export default function(urlStr, parseQs = false, slashesDenoteHost = false) {
}

let url;
let res = {};
let res = new Url();
let err = '';
let preSlash = '';

Expand Down Expand Up @@ -182,7 +186,7 @@ export default function(urlStr, parseQs = false, slashesDenoteHost = false) {
res.href = preSlash ? `${res.pathname}${res.search}${res.hash}` : format(res);

const excludedKeys = /^(file)/.test(res.href) ? ['host', 'hostname'] : [];
Object.keys(res).forEach(k => {
Object.keys(res).forEach((k) => {
if (!~excludedKeys.indexOf(k)) res[k] = res[k] || null;
});

Expand Down
28 changes: 28 additions & 0 deletions src/url.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright 2019 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import parse from './parse';
import format from './format';
import { resolve, resolveObject } from './resolve';

class Url {
static parse = parse;
static format = format;
static resolve = resolve;
static resolveObject = resolve;
}

export default Url;
Loading

0 comments on commit c644df5

Please sign in to comment.