identifier-js 0.0.3 → 0.0.5
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.
- package/index.js +18 -13
- package/package.json +1 -1
- package/tests/resolve.test.js +11 -13
- package/tests/to-absolute.test.js +1 -1
package/index.js
CHANGED
|
@@ -2,25 +2,26 @@
|
|
|
2
2
|
// a valid URI is always a valid IRI
|
|
3
3
|
const { recursiveCompile } = require('url-templates');
|
|
4
4
|
const patterns = new Map();
|
|
5
|
-
// RFC3986/RFC3987 common rules
|
|
5
|
+
// RFC3986/RFC3987 common rules + https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2:~:text=DNS%29%2E-,A,of%20%5BRFC1123%5D%2E
|
|
6
6
|
const commonRules = {
|
|
7
7
|
scheme: '[a-zA-Z][a-zA-Z0-9+.-]*',
|
|
8
|
-
port: '[
|
|
8
|
+
port: '(?:0|[1-9]\\d{0,3}|[1-5]\\d{4}|6[0-4]\\d{3}|65[0-4]\\d{2}|655[0-2]\\d|6553[0-5])',
|
|
9
9
|
IP_literal: '\\[(?:{IPv6address}|{IPvFuture})\\]',
|
|
10
10
|
IPv6address: '(?:(?:{h16}:){6}{ls32}|::(?:{h16}:){5}{ls32}|(?:(?:{h16})?)::(?:{h16}:){4}{ls32}|(?:(?:{h16}:)?{h16})?::(?:{h16}:){3}{ls32}|(?:(?:{h16}:){0,2}{h16})?::(?:{h16}:){2}{ls32}|(?:(?:{h16}:){0,3}{h16})?::(?:{h16}:){1}{ls32}|(?:(?:{h16}:){0,4}{h16})?::{ls32}|(?:(?:{h16}:){0,5}{h16})?::{h16}|(?:(?:{h16}:){0,6}{h16})?::)',
|
|
11
11
|
ls32: '(?:{h16}:{h16}|{IPv4address})',
|
|
12
|
-
h16: '{
|
|
12
|
+
h16: '{hex_digit}{1,4}',
|
|
13
13
|
IPv4address: '(?:{dec_octet}\\.){3}{dec_octet}',
|
|
14
|
-
dec_octet: '(
|
|
15
|
-
IPvFuture: 'v{
|
|
14
|
+
dec_octet: '(?:\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])',
|
|
15
|
+
IPvFuture: 'v{hex_digit}+\\.(?:{unreserved}|{sub_delims}|:)+',
|
|
16
16
|
unreserved: '[a-zA-Z0-9_.~-]',
|
|
17
17
|
reserved: '(?:{gen_delims}|{sub_delims})',
|
|
18
|
-
pct_encoded: '%{
|
|
18
|
+
pct_encoded: '%{hex_digit}{2}',
|
|
19
19
|
gen_delims: '[:/?#[\\]@]',
|
|
20
20
|
sub_delims: "[!&'()*+,;=$]",
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
hex_digit: '[0-9A-Fa-f]',
|
|
22
|
+
alpha_digit: '[a-zA-Z0-9]',
|
|
23
|
+
UUID: '{hex_digit}{8}-{hex_digit}{4}-{hex_digit}{4}-{hex_digit}{4}-{hex_digit}{12}',
|
|
24
|
+
UUID_v4: '{hex_digit}{8}-{hex_digit}{4}-4{hex_digit}{3}-[89abAB]{hex_digit}{3}-{hex_digit}{12}',
|
|
24
25
|
};
|
|
25
26
|
// RFC3986 rules
|
|
26
27
|
const uriRules = {
|
|
@@ -31,9 +32,10 @@ const uriRules = {
|
|
|
31
32
|
hier_part: '(?:\/\/{authority}{path_abempty}|{path_absolute}|{path_rootless}|{path_empty})',
|
|
32
33
|
relative_part: '(?:\/\/{authority}{path_abempty}|{path_absolute}|{path_noscheme}|{path_empty})',
|
|
33
34
|
authority: '(?:{userinfo}@)?{host}(?::{port})?',
|
|
34
|
-
host: '(?:{IP_literal}|{IPv4address}|{reg_name})',
|
|
35
35
|
userinfo: '(?:{unreserved}|{pct_encoded}|{sub_delims}|:)*',
|
|
36
|
-
|
|
36
|
+
host: '(?:{IP_literal}|{IPv4address}|{reg_name})',
|
|
37
|
+
a_label: '(?:{alpha_digit})(?:(?:{alpha_digit}|-){0,61}(?:{alpha_digit}))?',
|
|
38
|
+
reg_name: "(?:(?=.{1,255}(?:[:/?#]|$))(?:(?:{a_label})(?:\\.{a_label}))*)",
|
|
37
39
|
path: '(?:{path_abempty}|{path_absolute}|{path_noscheme}|{path_rootless}|{path_empty})',
|
|
38
40
|
path_abempty: '(?:\/{segment})*',
|
|
39
41
|
path_absolute: '\/(?:{segment_nz}(?:\/{segment})*)?',
|
|
@@ -58,7 +60,9 @@ const iriRules = {
|
|
|
58
60
|
iauthority: '(?:{iuserinfo}@)?{ihost}(?::{port})?',
|
|
59
61
|
iuserinfo: '(?:{iunreserved}|{pct_encoded}|{sub_delims}|:)*',
|
|
60
62
|
ihost: '(?:{IP_literal}|{IPv4address}|{ireg_name})',
|
|
61
|
-
|
|
63
|
+
separator: '[\\x2E\\uFF0E\\u3002\\uFF61]',
|
|
64
|
+
u_label: '(?:{uchar})(?:(?:{uchar}|-){0,61}(?:{uchar}))?',
|
|
65
|
+
ireg_name: '(?:(?=.{1,255}(?:[:/?#]|$))(?:{u_label})(?:{separator}(?:{u_label}))*)',
|
|
62
66
|
ipath: '(?:{ipath_abempty}|{ipath_absolute}|{ipath_noscheme}|{ipath_rootless}|{ipath_empty})',
|
|
63
67
|
ipath_empty: '',
|
|
64
68
|
ipath_rootless: '{isegment_nz}(?:\/{isegment})*',
|
|
@@ -71,8 +75,9 @@ const iriRules = {
|
|
|
71
75
|
iquery: '(?:{ipchar}|{iprivate}|\/|\\?)*',
|
|
72
76
|
ifragment: '(?:{ipchar}|\/|\\?)*',
|
|
73
77
|
ipchar: '(?:{iunreserved}|{pct_encoded}|{sub_delims}|:|@)',
|
|
74
|
-
iunreserved: '(?:
|
|
78
|
+
iunreserved: '(?:{unreserved}|{ucschar})',
|
|
75
79
|
iprivate: '[\\uE000-\\uF8FF\\u{F0000}-\\u{FFFFD}\\u{100000}-\\u{10FFFD}]',
|
|
80
|
+
uchar: '[\\u200C\\u200D\\u00B7\\u0375\\u30FB\\u05F3\\u05F4\\p{L}\\p{N}\\p{Mn}\\p{Mc}]',
|
|
76
81
|
ucschar: '[\\xA0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF\\u{10000}-\\u{1FFFD}\\u{20000}-\\u{2FFFD}\\u{30000}-\\u{3FFFD}\\u{40000}-\\u{4FFFD}\\u{50000}-\\u{5FFFD}\\u{60000}-\\u{6FFFD}\\u{70000}-\\u{7FFFD}\\u{80000}-\\u{8FFFD}\\u{90000}-\\u{9FFFD}\\u{A0000}-\\u{AFFFD}\\u{B0000}-\\u{BFFFD}\\u{C0000}-\\u{CFFFD}\\u{D0000}-\\u{DFFFD}\\u{E1000}-\\u{EFFFD}]',
|
|
77
82
|
};
|
|
78
83
|
// pattern RFC group names
|
package/package.json
CHANGED
package/tests/resolve.test.js
CHANGED
|
@@ -2,23 +2,21 @@ import { describe, expect, test } from 'vitest';
|
|
|
2
2
|
import id from '../index.js';
|
|
3
3
|
|
|
4
4
|
const resolveTests = [
|
|
5
|
-
// ['', 'urn:some:ip:prop', 'urn:some:ip:prop'], // invalid base (resolveReference throw)
|
|
6
|
-
// ['#', 'urn:some:ip:prop', 'urn:some:ip:prop'], // invalid base (resolveReference throw)
|
|
7
5
|
['urn:some:ip:prop', 'urn:some:ip:prop', 'urn:some:ip:prop'],
|
|
8
|
-
['urn:some:
|
|
9
|
-
['hTTp://example.com/b/c/d/e', '
|
|
10
|
-
['http://eXaMpLe.com/b/c/d/e', '
|
|
11
|
-
['http://example.com/b%2Ec/d/e', '
|
|
12
|
-
['http://example.com/b%2Fc/d/e', '
|
|
13
|
-
['http://example.com/b%2fc/d/e', '
|
|
14
|
-
['http://example.com/b?c%2Fd%3Fe', '
|
|
15
|
-
['http://example.com/b', '
|
|
6
|
+
['urn:some:ip:prop', 'urn:some:other:prop', 'urn:some:ip:prop'],
|
|
7
|
+
['', 'hTTp://example.com/b/c/d/e', 'http://example.com/b/c/d/e'], // scheme to lowercase
|
|
8
|
+
['', 'http://eXaMpLe.com/b/c/d/e', 'http://example.com/b/c/d/e'], // authority to lowercase
|
|
9
|
+
['', 'http://example.com/b%2Ec/d/e', 'http://example.com/b.c/d/e'], // Unnecessary encoding segment
|
|
10
|
+
['', 'http://example.com/b%2Fc/d/e', 'http://example.com/b%2Fc/d/e'], // Necessary encoding segment
|
|
11
|
+
['', 'http://example.com/b%2fc/d/e', 'http://example.com/b%2Fc/d/e'], // Case normalization of encoding segment
|
|
12
|
+
['', 'http://example.com/b?c%2Fd%3Fe', 'http://example.com/b?c/d?e'], // Unnecessary encoding query
|
|
13
|
+
['#c%2Fd%3Fe', 'http://example.com/b', 'http://example.com/b#c/d?e'], // Unnecessary encoding fragment
|
|
16
14
|
];
|
|
17
15
|
|
|
18
16
|
describe('resolveReference', () => {
|
|
19
|
-
resolveTests.forEach(([
|
|
20
|
-
test(`resolveReference('${
|
|
21
|
-
const subject = id.resolveReference(
|
|
17
|
+
resolveTests.forEach(([reference, base, expected]) => {
|
|
18
|
+
test(`resolveReference('${reference}', '${base}') === '${expected}'`, () => {
|
|
19
|
+
const subject = id.resolveReference(reference, base);
|
|
22
20
|
expect(subject).to.equal(expected);
|
|
23
21
|
});
|
|
24
22
|
});
|
|
@@ -3,7 +3,7 @@ import id from '../index.js';
|
|
|
3
3
|
|
|
4
4
|
describe('toAbsoluteReference', () => {
|
|
5
5
|
test('Base with a fragment', () => {
|
|
6
|
-
expect(id.toAbsoluteReference('http://exampl
|
|
6
|
+
expect(id.toAbsoluteReference('http://examplé.org/rosé#dasd')).to.equal('http://examplé.org/rosé');
|
|
7
7
|
});
|
|
8
8
|
|
|
9
9
|
test('Scheme is required', () => {
|