fast-uri 2.0.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -13,3 +13,5 @@ on:
13
13
  jobs:
14
14
  test:
15
15
  uses: fastify/workflows/.github/workflows/plugins-ci.yml@v3
16
+ with:
17
+ license-check: true
@@ -5,6 +5,9 @@ on:
5
5
  branches:
6
6
  - master
7
7
 
8
+ permissions:
9
+ contents: read
10
+
8
11
  jobs:
9
12
  pnpm:
10
13
  runs-on: ${{ matrix.os }}
@@ -12,26 +15,25 @@ jobs:
12
15
  strategy:
13
16
  matrix:
14
17
  # Maintenance and active LTS
15
- node-version: [10, 12, 14, 16]
16
- os: [ubuntu-latest]
18
+ node-version: [14, 16]
19
+ os: [ubuntu-18.04]
17
20
 
18
21
  steps:
19
22
  - uses: actions/checkout@v3
23
+ with:
24
+ persist-credentials: false
20
25
 
21
26
  - name: Use Node.js
22
- uses: actions/setup-node@v3.1.1
23
- id: setup_node
27
+ uses: actions/setup-node@v3
24
28
  with:
25
29
  node-version: ${{ matrix.node-version }}
26
30
 
27
31
  - name: Install with pnpm
28
- id: install_package_manager
29
32
  run: |
30
33
  curl -L https://unpkg.com/@pnpm/self-installer | node
31
34
  pnpm install
32
35
 
33
36
  - name: Run tests
34
- id: test
35
37
  run: |
36
38
  pnpm run test
37
39
 
@@ -41,25 +43,24 @@ jobs:
41
43
  strategy:
42
44
  matrix:
43
45
  # Maintenance and active LTS
44
- node-version: [10, 12, 14, 16]
45
- os: [ubuntu-latest]
46
+ node-version: [14, 16]
47
+ os: [ubuntu-18.04]
46
48
 
47
49
  steps:
48
50
  - uses: actions/checkout@v3
51
+ with:
52
+ persist-credentials: false
49
53
 
50
54
  - name: Use Node.js
51
- id: setup_node
52
- uses: actions/setup-node@v3.1.1
55
+ uses: actions/setup-node@v3
53
56
  with:
54
57
  node-version: ${{ matrix.node-version }}
55
58
 
56
59
  - name: Install with yarn
57
- id: install_package_manager
58
60
  run: |
59
61
  curl -o- -L https://yarnpkg.com/install.sh | bash
60
62
  yarn install --ignore-engines
61
63
 
62
64
  - name: Run tests
63
- id: test
64
65
  run: |
65
66
  yarn run test
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  <div align="center">
4
4
 
5
- [![CI](https://github.com/fastify/fastify/workflows/ci/badge.svg)](https://github.com/fastify/fast-uri/actions/workflows/ci.yml)
5
+ [![CI](https://github.com/fastify/fast-uri/actions/workflows/ci.yml/badge.svg)](https://github.com/fastify/fast-uri/actions/workflows/ci.yml)
6
6
  [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](https://standardjs.com/)
7
7
 
8
8
  </div>
@@ -122,4 +122,4 @@ urijs: resolve x 225,759 ops/sec ±0.37% (95 runs sampled)
122
122
 
123
123
  - [ ] Support MailTo
124
124
  - [ ] Be 100% iso compatible with uri-js
125
- - [ ] Add browser test stack
125
+ - [ ] Add browser test stack
package/index.js CHANGED
@@ -126,6 +126,10 @@ function serialize (cmpts, opts) {
126
126
  if (components.path !== undefined) {
127
127
  if (!options.skipEscape) {
128
128
  components.path = escape(components.path)
129
+
130
+ if (components.scheme !== undefined) {
131
+ components.path = components.path.split('%3A').join(':')
132
+ }
129
133
  } else {
130
134
  components.path = unescape(components.path)
131
135
  }
@@ -175,7 +179,6 @@ function serialize (cmpts, opts) {
175
179
  }
176
180
 
177
181
  const URI_PARSE = /^(?:([^:/?#]+):)?(?:\/\/((?:([^/?#@]*)@)?(\[[^/?#\]]+\]|[^/?#:]*)(?::(\d*))?))?([^?#]*)(?:\?([^#]*))?(?:#((?:.|\n|\r)*))?/i
178
- const NO_MATCH_IS_UNDEFINED = ('').match(/(){0}/)[1] === undefined
179
182
 
180
183
  function parse (uri, opts) {
181
184
  const options = Object.assign({}, opts)
@@ -194,34 +197,18 @@ function parse (uri, opts) {
194
197
  const matches = uri.match(URI_PARSE)
195
198
 
196
199
  if (matches) {
197
- if (NO_MATCH_IS_UNDEFINED) {
198
- // store each component
199
- parsed.scheme = matches[1]
200
- parsed.userinfo = matches[3]
201
- parsed.host = matches[4]
202
- parsed.port = parseInt(matches[5], 10)
203
- parsed.path = matches[6] || ''
204
- parsed.query = matches[7]
205
- parsed.fragment = matches[8]
206
-
207
- // fix port number
208
- if (isNaN(parsed.port)) {
209
- parsed.port = matches[5]
210
- }
211
- } else { // IE FIX for improper RegExp matching
212
- // store each component
213
- parsed.scheme = matches[1] || undefined
214
- parsed.userinfo = (uri.indexOf('@') !== -1 ? matches[3] : undefined)
215
- parsed.host = (uri.indexOf('//') !== -1 ? matches[4] : undefined)
216
- parsed.port = parseInt(matches[5], 10)
217
- parsed.path = matches[6] || ''
218
- parsed.query = (uri.indexOf('?') !== -1 ? matches[7] : undefined)
219
- parsed.fragment = (uri.indexOf('#') !== -1 ? matches[8] : undefined)
220
-
221
- // fix port number
222
- if (isNaN(parsed.port)) {
223
- parsed.port = (uri.match(/\/\/(?:.|\n)*:(?:\/|\?|#|$)/) ? matches[4] : undefined)
224
- }
200
+ // store each component
201
+ parsed.scheme = matches[1]
202
+ parsed.userinfo = matches[3]
203
+ parsed.host = matches[4]
204
+ parsed.port = parseInt(matches[5], 10)
205
+ parsed.path = matches[6] || ''
206
+ parsed.query = matches[7]
207
+ parsed.fragment = matches[8]
208
+
209
+ // fix port number
210
+ if (isNaN(parsed.port)) {
211
+ parsed.port = matches[5]
225
212
  }
226
213
  if (parsed.host) {
227
214
  const ipv4result = normalizeIPv4(parsed.host)
@@ -291,7 +278,7 @@ function parse (uri, opts) {
291
278
  return parsed
292
279
  }
293
280
 
294
- module.exports = {
281
+ const fastUri = {
295
282
  normalize,
296
283
  resolve,
297
284
  resolveComponents,
@@ -299,3 +286,7 @@ module.exports = {
299
286
  serialize,
300
287
  parse
301
288
  }
289
+
290
+ module.exports = fastUri
291
+ module.exports.default = fastUri
292
+ module.exports.fastUri = fastUri
package/lib/utils.js CHANGED
@@ -7,7 +7,7 @@ function normalizeIPv4 (host) {
7
7
  const matches = host.match(/^(\b25[0-5]|\b2[0-4][0-9]|\b[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/) || []
8
8
  const [address] = matches
9
9
  if (address) {
10
- return { host: stripLeadingZeros(address, '.', false), isIPV4: true }
10
+ return { host: stripLeadingZeros(address, '.'), isIPV4: true }
11
11
  } else {
12
12
  return { host, isIPV4: false }
13
13
  }
@@ -92,7 +92,7 @@ function getIPV6 (input) {
92
92
 
93
93
  function normalizeIPv6 (host, opts = {}) {
94
94
  if (findToken(host, ':') < 2) { return { host, isIPV6: false } }
95
- const ipv6 = getIPV6(host, opts.isIPV4)
95
+ const ipv6 = getIPV6(host)
96
96
 
97
97
  if (!ipv6.error) {
98
98
  let newHost = ipv6.address
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "fast-uri",
3
3
  "description": "Dependency free RFC 3986 URI toolbox",
4
- "version": "2.0.0",
4
+ "version": "2.2.0",
5
5
  "main": "index.js",
6
6
  "type": "commonjs",
7
- "types": "index.d.ts",
7
+ "types": "types/index.d.ts",
8
8
  "license": "MIT",
9
9
  "author": "Vincent Le Goff <vince.legoff@gmail.com> (https://github.com/zekth)",
10
10
  "repository": {
@@ -31,8 +31,7 @@
31
31
  "snazzy": "^9.0.0",
32
32
  "standard": "^17.0.0",
33
33
  "tap": "^16.0.0",
34
- "tsd": "^0.20.0",
35
- "typescript": "^4.4.4",
34
+ "tsd": "^0.24.1",
36
35
  "uri-js": "^4.4.1"
37
36
  },
38
37
  "dependencies": {},
@@ -111,6 +111,10 @@ test('compatibility serialize', (t) => {
111
111
  host: 'example.com',
112
112
  resourceName: '/foo?bar',
113
113
  secure: true
114
+ },
115
+ {
116
+ scheme: 'scheme',
117
+ path: 'with:colon'
114
118
  }
115
119
  ]
116
120
  toSerialize.forEach((x) => {
@@ -4,12 +4,21 @@ const tap = require('tap')
4
4
  const test = tap.test
5
5
  const URI = require('../')
6
6
 
7
- test('URI Equals', (t) => {
8
- // test from RFC 3986
9
- t.equal(URI.equal('example://a/b/c/%7Bfoo%7D', 'eXAMPLE://a/./b/../b/%63/%7bfoo%7d'), true)
7
+ const fn = URI.equal
8
+ const runTest = (t, suite) => {
9
+ suite.forEach(s => {
10
+ const operator = s.result ? '==' : '!='
11
+ t.equal(fn(s.pair[0], s.pair[1]), s.result, `${s.pair[0]} ${operator} ${s.pair[1]}`)
12
+ t.equal(fn(s.pair[1], s.pair[0]), s.result, `${s.pair[1]} ${operator} ${s.pair[0]}`)
13
+ })
14
+ }
10
15
 
11
- // test from RFC 3987
12
- t.equal(URI.equal('http://example.org/~user', 'http://example.org/%7euser'), true)
16
+ test('URI Equals', (t) => {
17
+ const suite = [
18
+ { pair: ['example://a/b/c/%7Bfoo%7D', 'eXAMPLE://a/./b/../b/%63/%7bfoo%7d'], result: true }, // test from RFC 3986
19
+ { pair: ['http://example.org/~user', 'http://example.org/%7euser'], result: true } // test from RFC 3987
20
+ ]
21
+ runTest(t, suite)
13
22
  t.end()
14
23
  })
15
24
 
@@ -20,39 +29,55 @@ test('URI Equals', (t) => {
20
29
  // })
21
30
 
22
31
  test('HTTP Equals', (t) => {
23
- // test from RFC 2616
24
- t.equal(URI.equal('http://abc.com:80/~smith/home.html', 'http://abc.com/~smith/home.html'), true)
25
- t.equal(URI.equal({ scheme: 'http', host: 'abc.com', port: 80, path: '/~smith/home.html' }, 'http://abc.com/~smith/home.html'), true)
26
- t.equal(URI.equal('http://ABC.com/%7Esmith/home.html', 'http://abc.com/~smith/home.html'), true)
27
- t.equal(URI.equal('http://ABC.com:/%7esmith/home.html', 'http://abc.com/~smith/home.html'), true)
28
- t.equal(URI.equal('HTTP://ABC.COM', 'http://abc.com/'), true)
29
- // test from RFC 3986
30
- t.equal(URI.equal('http://example.com:/', 'http://example.com:80/'), true)
32
+ const suite = [
33
+ // test from RFC 2616
34
+ { pair: ['http://abc.com:80/~smith/home.html', 'http://abc.com/~smith/home.html'], result: true },
35
+ { pair: [{ scheme: 'http', host: 'abc.com', port: 80, path: '/~smith/home.html' }, 'http://abc.com/~smith/home.html'], result: true },
36
+ { pair: ['http://ABC.com/%7Esmith/home.html', 'http://abc.com/~smith/home.html'], result: true },
37
+ { pair: ['http://ABC.com:/%7esmith/home.html', 'http://abc.com/~smith/home.html'], result: true },
38
+ { pair: ['HTTP://ABC.COM', 'http://abc.com/'], result: true },
39
+ // test from RFC 3986
40
+ { pair: ['http://example.com:/', 'http://example.com:80/'], result: true }
41
+ ]
42
+ runTest(t, suite)
31
43
  t.end()
32
44
  })
33
45
 
34
46
  test('HTTPS Equals', (t) => {
35
- t.equal(URI.equal('https://example.com', 'https://example.com:443/'), true)
36
- t.equal(URI.equal('https://example.com:/', 'https://example.com:443/'), true)
47
+ const suite = [
48
+ { pair: ['https://example.com', 'https://example.com:443/'], result: true },
49
+ { pair: ['https://example.com:/', 'https://example.com:443/'], result: true }
50
+ ]
51
+ runTest(t, suite)
37
52
  t.end()
38
53
  })
39
54
 
40
55
  test('URN Equals', (t) => {
41
- // test from RFC 2141
42
- t.equal(URI.equal('urn:foo:a123,456', 'urn:foo:a123,456'), true)
43
- t.equal(URI.equal('urn:foo:a123,456', 'URN:foo:a123,456'), true)
44
- t.equal(URI.equal('urn:foo:a123,456', 'urn:FOO:a123,456'), true)
56
+ const suite = [
57
+ // test from RFC 2141
58
+ { pair: ['urn:foo:a123,456', 'urn:foo:a123,456'], result: true },
59
+ { pair: ['urn:foo:a123,456', 'URN:foo:a123,456'], result: true },
60
+ { pair: ['urn:foo:a123,456', 'urn:FOO:a123,456'], result: true }
61
+ ]
45
62
 
46
63
  // Disabling for now as the whole equal logic might need
47
64
  // to be refactored
48
65
  // t.equal(URI.equal('urn:foo:a123,456', 'urn:foo:A123,456'), false)
49
66
  // t.equal(URI.equal('urn:foo:a123%2C456', 'URN:FOO:a123%2c456'), true)
67
+
68
+ runTest(t, suite)
50
69
  t.end()
51
70
  })
71
+
52
72
  test('UUID Equals', (t) => {
53
- t.equal(URI.equal('URN:UUID:F81D4FAE-7DEC-11D0-A765-00A0C91E6BF6', 'urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6'), true)
73
+ const suite = [
74
+ { pair: ['URN:UUID:F81D4FAE-7DEC-11D0-A765-00A0C91E6BF6', 'urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6'], result: true }
75
+ ]
76
+
77
+ runTest(t, suite)
54
78
  t.end()
55
79
  })
80
+
56
81
  // test('Mailto Equals', (t) => {
57
82
  // // tests from RFC 6068
58
83
  // t.equal(URI.equal('mailto:addr1@an.example,addr2@an.example', 'mailto:?to=addr1@an.example,addr2@an.example'), true)
@@ -61,11 +86,19 @@ test('UUID Equals', (t) => {
61
86
  // })
62
87
 
63
88
  test('WS Equal', (t) => {
64
- t.equal(URI.equal('WS://ABC.COM:80/chat#one', 'ws://abc.com/chat'), true)
89
+ const suite = [
90
+ { pair: ['WS://ABC.COM:80/chat#one', 'ws://abc.com/chat'], result: true }
91
+ ]
92
+
93
+ runTest(t, suite)
65
94
  t.end()
66
95
  })
67
96
 
68
97
  test('WSS Equal', (t) => {
69
- t.equal(URI.equal('WSS://ABC.COM:443/chat#one', 'wss://abc.com/chat'), true)
98
+ const suite = [
99
+ { pair: ['WSS://ABC.COM:443/chat#one', 'wss://abc.com/chat'], result: true }
100
+ ]
101
+
102
+ runTest(t, suite)
70
103
  t.end()
71
104
  })
@@ -0,0 +1,53 @@
1
+ type FastUri = typeof fastUri
2
+
3
+ declare namespace fastUri {
4
+ export interface URIComponent {
5
+ scheme?: string;
6
+ userinfo?: string;
7
+ host?: string;
8
+ port?: number | string;
9
+ path?: string;
10
+ query?: string;
11
+ fragment?: string;
12
+ reference?: string;
13
+ error?: string;
14
+ }
15
+ export interface Options {
16
+ scheme?: string;
17
+ reference?: string;
18
+ unicodeSupport?: boolean;
19
+ domainHost?: boolean;
20
+ absolutePath?: boolean;
21
+ tolerant?: boolean;
22
+ }
23
+
24
+ /**
25
+ * @deprecated Use Options instead
26
+ */
27
+ export type options = Options
28
+ /**
29
+ * @deprecated Use URIComponent instead
30
+ */
31
+ export type URIComponents = URIComponent
32
+
33
+ export function normalize(uri: string, opts?: Options): string;
34
+ export function normalize(uri: URIComponent, opts?: Options): URIComponent;
35
+ export function normalize(uri: any, opts?: Options): any;
36
+
37
+ export function resolve(baseURI: string, relativeURI: string, options?: Options): string
38
+
39
+ export function resolveComponent(base: URIComponent, relative: URIComponent, options?: Options, skipNormalization?: boolean): URIComponent
40
+
41
+ export function parse(uri: string, opts?: Options): URIComponent;
42
+
43
+ export function serialize(component: URIComponent, opts?: Options): string;
44
+
45
+ export function equal(uriA: string, uriB: string): boolean;
46
+
47
+ export function resolve(base: string, path: string): string;
48
+
49
+ export const fastUri: FastUri
50
+ export { fastUri as default }
51
+ }
52
+
53
+ export = fastUri
@@ -0,0 +1,17 @@
1
+ import uri, { URIComponents, URIComponent, Options, options } from "..";
2
+ import { expectDeprecated, expectType } from "tsd";
3
+
4
+ const parsed = uri.parse("foo");
5
+ expectType<URIComponents>(parsed);
6
+ const parsed2 = uri.parse("foo", {
7
+ domainHost: true,
8
+ scheme: 'https',
9
+ unicodeSupport: false
10
+ })
11
+ expectType<URIComponents>(parsed2);
12
+
13
+ expectType<URIComponent>({} as URIComponents)
14
+ expectDeprecated({} as URIComponents)
15
+
16
+ expectType<Options>({} as options)
17
+ expectDeprecated({} as options)
package/index.d.ts DELETED
@@ -1,27 +0,0 @@
1
- export interface URIComponents {
2
- scheme?: string;
3
- userinfo?: string;
4
- host?: string;
5
- port?: number | string;
6
- path?: string;
7
- query?: string;
8
- fragment?: string;
9
- reference?: string;
10
- error?: string;
11
- }
12
- export interface options {
13
- scheme?: string;
14
- reference?: string;
15
- unicodeSupport?: boolean;
16
- domainHost?: boolean;
17
- absolutePath?: boolean;
18
- tolerant?:boolean;
19
- }
20
-
21
- export function parse(uri: string, opts?: options): URIComponents;
22
-
23
- export function serialize(component: URIComponents, opts?: options): string;
24
-
25
- export function equal(uriA: string, uriB:string): boolean;
26
-
27
- export function resolve(base:string, path:string): string;
package/index.test-d.ts DELETED
@@ -1,11 +0,0 @@
1
- import uri, { URIComponents } from ".";
2
- import { expectType } from "tsd";
3
-
4
- const parsed = uri.parse("foo");
5
- expectType<URIComponents>(parsed);
6
- const parsed2 = uri.parse("foo", {
7
- domainHost: true,
8
- scheme: 'https',
9
- unicodeSupport: false
10
- })
11
- expectType<URIComponents>(parsed2);
package/types/.gitkeep DELETED
File without changes