identifier-js 0.0.1 → 0.0.3
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.d.ts +73 -0
- package/index.js +273 -0
- package/package.json +43 -35
- package/readme.md +86 -0
- package/tests/parse.test.js +472 -0
- package/tests/performance.js +46 -0
- package/tests/resolve.rfc.test.js +62 -0
- package/tests/resolve.test.js +25 -0
- package/tests/to-absolute.test.js +12 -0
- package/tests/to-relative.test.js +50 -0
- package/tests/validation.test.js +278 -0
- package/tests/vitest-setup.js +18 -0
- /package/{rfc3986-rfc3987-abnf.yml → docs/rfc3986-rfc3987-abnf.yml} +0 -0
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
import { describe, expect, test } from 'vitest';
|
|
2
|
+
import id from '../index.js';
|
|
3
|
+
|
|
4
|
+
describe('isUUID', () => {
|
|
5
|
+
test('valid UUID with lowercase hex digits', () => {
|
|
6
|
+
expect(id.isUUID('123e4567-e89b-42d3-9456-426614174000')).to.equal(true);
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
test('valid UUID with uppercase hex digits', () => {
|
|
10
|
+
expect(id.isUUID('123E4567-E89B-42D3-A456-426614174000')).to.equal(true);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
test('valid UUID with mixed case hex digits', () => {
|
|
14
|
+
expect(id.isUUID('123e4567-E89B-42d3-a456-426614174000')).to.equal(true);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test('invalid UUID missing hyphens', () => {
|
|
18
|
+
expect(() => id.isUUID('123e4567e89b12d3a456426614174000')).to.throw(Error, 'Invalid UUID: 123e4567e89b12d3a456426614174000');
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test('invalid UUID with extra hyphens', () => {
|
|
22
|
+
expect(() => id.isUUID('123e4567-e89b-12d3-a456-426-614174000')).to.throw(Error, 'Invalid UUID: 123e4567-e89b-12d3-a456-426-614174000');
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
test('invalid UUID with incorrect group lengths', () => {
|
|
26
|
+
expect(() => id.isUUID('123e4567-e89b-12d3-a456426614174000')).to.throw(Error, 'Invalid UUID: 123e4567-e89b-12d3-a456426614174000');
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test('invalid UUID with non-hexadecimal characters', () => {
|
|
30
|
+
expect(() => id.isUUID('123e4567-e89b-12d3-g456-426614174000')).to.throw(Error, 'Invalid UUID: 123e4567-e89b-12d3-g456-426614174000');
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test('invalid UUID string that is too short', () => {
|
|
34
|
+
expect(() => id.isUUID('123e4567-e89b-12d3-a456-42661417400')).to.throw(Error, 'Invalid UUID: 123e4567-e89b-12d3-a456-42661417400');
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test('invalid UUID string that is too long', () => {
|
|
38
|
+
expect(() => id.isUUID('123e4567-e89b-12d3-a456-4266141740000')).to.throw(Error, 'Invalid UUID: 123e4567-e89b-12d3-a456-4266141740000');
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test('valid UUID with all zeroes except version control chars', () => {
|
|
42
|
+
expect(id.isUUID('00000000-0000-4000-8000-000000000000')).to.equal(true);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test('invalid UUID with missing section', () => {
|
|
46
|
+
expect(() => id.isUUID('2eb8aa08-aa98-11ea-73b441d16380')).to.throw(Error, 'Invalid UUID: 2eb8aa08-aa98-11ea-73b441d16380');
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test('invalid UUID with too many dashes', () => {
|
|
50
|
+
expect(() => id.isUUID('2eb8-aa08-aa98-11ea-b4aa73b44-1d16380')).to.throw(Error, 'Invalid UUID: 2eb8-aa08-aa98-11ea-b4aa73b44-1d16380');
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
test('invalid UUID with dashes in the wrong spot', () => {
|
|
54
|
+
expect(() => id.isUUID('2eb8aa08aa9811eab4aa73b441d16380----')).to.throw(Error, 'Invalid UUID: 2eb8aa08aa9811eab4aa73b441d16380----');
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test('valid UUID v5', () => {
|
|
58
|
+
expect(id.isUUID('99c17cbb-656f-564a-940f-1a4568f03487')).to.equal(true);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test('valid UUID hypothetical v6', () => {
|
|
62
|
+
expect(id.isUUID('99c17cbb-656f-664a-940f-1a4568f03487')).to.equal(true);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
test('valid UUID hypothetical v15', () => {
|
|
66
|
+
expect(id.isUUID('99c17cbb-656f-f64a-940f-1a4568f03487')).to.equal(true);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
describe('isUUIDv4', () => {
|
|
71
|
+
test('valid UUID v4 with lowercase hex digits', () => {
|
|
72
|
+
expect(id.isUUIDv4('123e4567-e89b-42d3-9456-426614174000')).to.equal(true);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
test('valid UUID v4 with uppercase hex digits', () => {
|
|
76
|
+
expect(id.isUUIDv4('123E4567-E89B-42D3-A456-426614174000')).to.equal(true);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
test('valid UUID v4 with mixed case hex digits', () => {
|
|
80
|
+
expect(id.isUUIDv4('123e4567-E89B-42d3-a456-426614174000')).to.equal(true);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
test('invalid UUID v4 missing hyphens', () => {
|
|
84
|
+
expect(() => id.isUUIDv4('123e4567e89b12d3a456426614174000')).to.throw(Error, 'Invalid UUID-v4: 123e4567e89b12d3a456426614174000');
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
test('invalid UUID v4 with extra hyphens', () => {
|
|
88
|
+
expect(() => id.isUUIDv4('123e4567-e89b-12d3-a456-426-614174000')).to.throw(Error, 'Invalid UUID-v4: 123e4567-e89b-12d3-a456-426-614174000');
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
test('invalid UUID v4 with incorrect group lengths', () => {
|
|
92
|
+
expect(() => id.isUUIDv4('123e4567-e89b-12d3-a456426614174000')).to.throw(Error, 'Invalid UUID-v4: 123e4567-e89b-12d3-a456426614174000');
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
test('invalid UUID v4 with non-hexadecimal characters', () => {
|
|
96
|
+
expect(() => id.isUUIDv4('123e4567-e89b-12d3-g456-426614174000')).to.throw(Error, 'Invalid UUID-v4: 123e4567-e89b-12d3-g456-426614174000');
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
test('invalid UUID v4 string that is too short', () => {
|
|
100
|
+
expect(() => id.isUUIDv4('123e4567-e89b-12d3-a456-42661417400')).to.throw(Error, 'Invalid UUID-v4: 123e4567-e89b-12d3-a456-42661417400');
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
test('invalid UUID v4 string that is too long', () => {
|
|
104
|
+
expect(() => id.isUUIDv4('123e4567-e89b-12d3-a456-4266141740000')).to.throw(Error, 'Invalid UUID-v4: 123e4567-e89b-12d3-a456-4266141740000');
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
test('valid UUID v4 with all zeroes except version control chars', () => {
|
|
108
|
+
expect(id.isUUIDv4('00000000-0000-4000-8000-000000000000')).to.equal(true);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
test('invalid UUID v4 with missing section', () => {
|
|
112
|
+
expect(() => id.isUUIDv4('2eb8aa08-aa98-11ea-73b441d16380')).to.throw(Error, 'Invalid UUID-v4: 2eb8aa08-aa98-11ea-73b441d16380');
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
test('invalid UUID v4 with too many dashes', () => {
|
|
116
|
+
expect(() => id.isUUIDv4('2eb8-aa08-aa98-11ea-b4aa73b44-1d16380')).to.throw(Error, 'Invalid UUID-v4: 2eb8-aa08-aa98-11ea-b4aa73b44-1d16380');
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
test('invalid UUID v4 with dashes in the wrong spot', () => {
|
|
120
|
+
expect(() => id.isUUIDv4('2eb8aa08aa9811eab4aa73b441d16380----')).to.throw(Error, 'Invalid UUID-v4: 2eb8aa08aa9811eab4aa73b441d16380----');
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
describe('isUri', () => {
|
|
125
|
+
test('Full', () => {
|
|
126
|
+
expect(id.isUri('https://jason@example.com:80/foo?bar#baz')).to.equal(true);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
test('Scheme is required', () => {
|
|
130
|
+
expect(() => id.isUri('//example.com/foo?bar#baz')).to.throw(Error, 'Invalid URI: //example.com/foo?bar#baz');
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
test('No authority', () => {
|
|
134
|
+
expect(id.isUri('uri:/foo?bar#baz')).to.equal(true);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
test('No authority starting with double slash', () => {
|
|
138
|
+
expect(() => id.isUri('uri://12:34:56/foo?bar#baz')).to.throw(Error, 'Invalid URI: uri://12:34:56/foo?bar#baz');
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
test('Rootless path', () => {
|
|
142
|
+
expect(id.isUri('uri:foo?bar#baz')).to.equal(true);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
test('Unicode is not allowed', () => {
|
|
146
|
+
expect(() => id.isUri('http://examplé.org/rosé#')).to.throw(Error, 'Invalid URI: http://examplé.org/rosé#');
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
describe('isUriReference', () => {
|
|
151
|
+
test('Full', () => {
|
|
152
|
+
expect(id.isUriReference('https://jason@example.com:80/foo?bar#baz')).to.equal(true);
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
test('No scheme with authority', () => {
|
|
156
|
+
expect(id.isUriReference('//example.com/foo?bar#baz')).to.equal(true);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
test('No double slash', () => {
|
|
160
|
+
expect(id.isUriReference('example.com/foo?bar#baz')).to.equal(true);
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
test('No authority', () => {
|
|
164
|
+
expect(id.isUriReference('/foo?bar#baz')).to.equal(true);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
test('No path', () => {
|
|
168
|
+
expect(id.isUriReference('?bar#baz')).to.equal(true);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
test('No query', () => {
|
|
172
|
+
expect(id.isUriReference('#baz')).to.equal(true);
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
test('Empty', () => {
|
|
176
|
+
expect(id.isUriReference('')).to.equal(true);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
test('Unicode is not allowed', () => {
|
|
180
|
+
expect(() => id.isUriReference('/rosé#')).to.throw(Error, 'Invalid URI-reference: /rosé#');
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
describe('isAbsoluteUri', () => {
|
|
185
|
+
test('Full', () => {
|
|
186
|
+
expect(id.isAbsoluteUri('https://jason@example.com:80/foo?bar')).to.equal(true);
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
test('Scheme is required', () => {
|
|
190
|
+
expect(() => id.isAbsoluteUri('//example.com/foo?bar')).to.throw(Error, 'Invalid absolute-URI: //example.com/foo?bar');
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
test('Fragment is not allowed', () => {
|
|
194
|
+
expect(() => id.isAbsoluteUri('https://example.com/foo?bar#baz')).to.throw(Error, 'Invalid absolute-URI: https://example.com/foo?bar#baz');
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
test('Unicode is not allowed', () => {
|
|
198
|
+
expect(() => id.isAbsoluteUri('http://examplé.org/rosé')).to.throw(Error, 'Invalid absolute-URI: http://examplé.org/rosé');
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
describe('isIri', () => {
|
|
203
|
+
test('Full', () => {
|
|
204
|
+
expect(id.isIri('http://jásón@examplé.org:80/rosé?fóo#bár')).to.equal(true);
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
test('Scheme is required', () => {
|
|
208
|
+
expect(() => id.isIri('//examplé.com/rosé?fóo#bár')).to.throw(Error, 'Invalid IRI: //examplé.com/rosé?fóo#bár');
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
test('No authority', () => {
|
|
212
|
+
expect(id.isIri('uri:/rosé?fóo#bár')).to.equal(true);
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
test('No authority starting with double slash', () => {
|
|
216
|
+
expect(() => id.isIri('uri://12:23:45/rosé?fóo#bár')).to.throw(Error, 'Invalid IRI: uri://12:23:45/rosé?fóo#bár');
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
test('Rootless path', () => {
|
|
220
|
+
expect(id.isIri('uri:rosé?fóo#bár')).to.equal(true);
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
test('Unicode is not allowed in scheme', () => {
|
|
224
|
+
expect(() => id.isIri('examplé://examplé.org/rosé')).to.throw(Error, 'Invalid IRI: examplé://examplé.org/rosé');
|
|
225
|
+
});
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
describe('isIriReference', () => {
|
|
229
|
+
test('Full', () => {
|
|
230
|
+
expect(id.isIriReference('http://jásón@examplé.org:80/rosé?fóo#bár')).to.equal(true);
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
test('No scheme with authority', () => {
|
|
234
|
+
expect(id.isIriReference('//examplé.org/rosé?fóo#bár')).to.equal(true);
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
test('No double slash', () => {
|
|
238
|
+
expect(id.isIriReference('examplé.org/rosé?fóo#bár')).to.equal(true);
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
test('No authority', () => {
|
|
242
|
+
expect(id.isIriReference('/rosé?fóo#bár')).to.equal(true);
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
test('Rootless path', () => {
|
|
246
|
+
expect(id.isIriReference('rosé?fóo#bár')).to.equal(true);
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
test('No path', () => {
|
|
250
|
+
expect(id.isIriReference('?fóo#bár')).to.equal(true);
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
test('No query', () => {
|
|
254
|
+
expect(id.isIriReference('#bár')).to.equal(true);
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
test('Empty', () => {
|
|
258
|
+
expect(id.isIriReference('')).to.equal(true);
|
|
259
|
+
});
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
describe('isAbsoluteIri', () => {
|
|
263
|
+
test('Full', () => {
|
|
264
|
+
expect(id.isAbsoluteIri('http://jásón@examplé.org:80/rosé?fóo')).to.equal(true);
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
test('Scheme is required', () => {
|
|
268
|
+
expect(() => id.isAbsoluteIri('//examplé.org/rosé?fóo')).to.throw(Error, 'Invalid absolute-IRI: //examplé.org/rosé?fóo');
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
test('Fragment is not allowed', () => {
|
|
272
|
+
expect(() => id.isAbsoluteIri('http://examplé.org/rosé?fóo#bár')).to.throw(Error, 'Invalid absolute-IRI: http://examplé.org/rosé?fóo#bár');
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
test('Unicode is not allowed in scheme', () => {
|
|
276
|
+
expect(() => id.isAbsoluteIri('examplé://examplé.org/rosé')).to.throw(Error, 'Invalid absolute-IRI: examplé://examplé.org/rosé');
|
|
277
|
+
});
|
|
278
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const { execSync } = require('child_process');
|
|
3
|
+
|
|
4
|
+
const packageJsonPath = './package.json';
|
|
5
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
6
|
+
|
|
7
|
+
// Install vitest if not already installed
|
|
8
|
+
if (!packageJson.devDependencies?.vitest) {
|
|
9
|
+
console.log('Installing vitest...');
|
|
10
|
+
execSync('npm install --save-dev vitest', { stdio: 'inherit' });
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Ensure the test script is set to vitest
|
|
14
|
+
if (packageJson.scripts?.test !== 'vitest') {
|
|
15
|
+
console.log('Updating test script to vitest...');
|
|
16
|
+
packageJson.scripts.test = 'vitest --watch=false';
|
|
17
|
+
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
18
|
+
}
|
|
File without changes
|