0
# Normalization and Encoding
1
2
Normalize URIs according to RFC standards, handle different encoding schemes, and ensure URI validity with configurable encoding options.
3
4
## Capabilities
5
6
### URI Normalization
7
8
Methods to normalize URIs according to RFC 3986 standards for consistent representation.
9
10
```javascript { .api }
11
/**
12
* Normalize all URI components
13
* @returns URI instance for chaining
14
*/
15
normalize(): URI;
16
17
/**
18
* Normalize protocol to lowercase
19
* @param build - Whether to rebuild URI immediately
20
* @returns URI instance for chaining
21
*/
22
normalizeProtocol(build?: boolean): URI;
23
24
/**
25
* Normalize hostname (punycode conversion, IPv6 brackets, lowercase)
26
* @param build - Whether to rebuild URI immediately
27
* @returns URI instance for chaining
28
*/
29
normalizeHostname(build?: boolean): URI;
30
31
/**
32
* Remove default ports (80 for http, 443 for https, etc.)
33
* @param build - Whether to rebuild URI immediately
34
* @returns URI instance for chaining
35
*/
36
normalizePort(build?: boolean): URI;
37
38
/**
39
* Normalize path segments (resolve . and .. segments)
40
* @param build - Whether to rebuild URI immediately
41
* @returns URI instance for chaining
42
*/
43
normalizePath(build?: boolean): URI;
44
normalizePathname(build?: boolean): URI; // Alias
45
46
/**
47
* Normalize query string
48
* @param build - Whether to rebuild URI immediately
49
* @returns URI instance for chaining
50
*/
51
normalizeQuery(build?: boolean): URI;
52
normalizeSearch(build?: boolean): URI; // Alias
53
54
/**
55
* Normalize fragment
56
* @param build - Whether to rebuild URI immediately
57
* @returns URI instance for chaining
58
*/
59
normalizeFragment(build?: boolean): URI;
60
normalizeHash(build?: boolean): URI; // Alias
61
```
62
63
**Usage Examples:**
64
65
```javascript
66
// Comprehensive normalization
67
const uri = new URI('HTTP://EXAMPLE.COM:80/Path/../Docs/./File.html?B=2&A=1#Fragment');
68
69
uri.normalize();
70
console.log(uri.toString());
71
// 'http://example.com/Docs/File.html?B=2&A=1#Fragment'
72
73
// Individual normalization steps
74
const stepByStep = new URI('HTTPS://API.EXAMPLE.COM:443/v1/../v2/./users?sort=name');
75
76
stepByStep.normalizeProtocol(); // HTTPS -> https
77
console.log(stepByStep.protocol()); // 'https'
78
79
stepByStep.normalizeHostname(); // API.EXAMPLE.COM -> api.example.com
80
console.log(stepByStep.hostname()); // 'api.example.com'
81
82
stepByStep.normalizePort(); // Remove default port 443
83
console.log(stepByStep.port()); // ''
84
85
stepByStep.normalizePath(); // Resolve ../v2/./users
86
console.log(stepByStep.pathname()); // '/v2/users'
87
88
// Complex path normalization
89
const complexPath = new URI('http://example.com/a/b/c/../../d/./e/../f/../g');
90
complexPath.normalizePath();
91
console.log(complexPath.pathname()); // '/a/d/g'
92
93
// IDN and punycode normalization
94
const idnUri = new URI('http://xn--e1afmkfd.xn--p1ai/path');
95
idnUri.normalizeHostname();
96
console.log(idnUri.hostname()); // Normalized punycode
97
```
98
99
### Encoding Configuration
100
101
Methods to switch between different encoding modes and character sets.
102
103
```javascript { .api }
104
/**
105
* Switch to ISO8859-1 encoding mode
106
* @returns URI instance for chaining
107
*/
108
iso8859(): URI;
109
110
/**
111
* Switch to Unicode encoding mode
112
* @returns URI instance for chaining
113
*/
114
unicode(): URI;
115
116
/**
117
* Create human-readable version with Unicode characters
118
* @returns URI instance for chaining
119
*/
120
readable(): URI;
121
```
122
123
**Usage Examples:**
124
125
```javascript
126
const uri = new URI('http://example.com/caf%C3%A9/r%C3%A9sum%C3%A9.html');
127
128
// Default encoding
129
console.log(uri.pathname()); // '/caf%C3%A9/r%C3%A9sum%C3%A9.html'
130
131
// Switch to readable Unicode
132
uri.readable();
133
console.log(uri.pathname()); // '/café/résumé.html'
134
135
// Switch back to encoded
136
uri.unicode();
137
console.log(uri.pathname()); // '/caf%C3%A9/r%C3%A9sum%C3%A9.html'
138
139
// ISO8859 encoding
140
const isoUri = new URI('http://example.com/café');
141
isoUri.iso8859();
142
// Encoding behavior changes for subsequent operations
143
144
// Chaining with encoding
145
const chainedUri = new URI('http://example.com/path')
146
.unicode()
147
.pathname('/café/résumé.html')
148
.readable();
149
console.log(chainedUri.pathname()); // '/café/résumé.html'
150
```
151
152
### Static Encoding Methods
153
154
Static methods for encoding and decoding URI components with configurable options.
155
156
```javascript { .api }
157
/**
158
* Current encoding function (configurable)
159
* @param string - String to encode
160
* @returns Encoded string
161
*/
162
URI.encode(string: string): string;
163
164
/**
165
* Current decoding function (configurable)
166
* @param string - String to decode
167
* @returns Decoded string
168
*/
169
URI.decode(string: string): string;
170
171
/**
172
* Switch to ISO8859-1 encoding globally
173
* @returns Previous encoding functions
174
*/
175
URI.iso8859(): { encode: function, decode: function };
176
177
/**
178
* Switch to Unicode encoding globally
179
* @returns Previous encoding functions
180
*/
181
URI.unicode(): { encode: function, decode: function };
182
183
/**
184
* Encode reserved characters
185
* @param string - String to encode
186
* @returns String with reserved characters encoded
187
*/
188
URI.encodeReserved(string: string): string;
189
```
190
191
**Usage Examples:**
192
193
```javascript
194
// Default encoding/decoding
195
console.log(URI.encode('hello world')); // 'hello%20world'
196
console.log(URI.decode('hello%20world')); // 'hello world'
197
198
// Encode reserved characters
199
console.log(URI.encodeReserved('hello:world/path?query=value'));
200
// 'hello%3Aworld%2Fpath%3Fquery%3Dvalue'
201
202
// Switch encoding mode globally
203
const originalFunctions = URI.unicode();
204
console.log(URI.encode('café')); // Encodes with Unicode support
205
206
// Restore previous encoding
207
URI.encode = originalFunctions.encode;
208
URI.decode = originalFunctions.decode;
209
210
// Custom encoding example
211
const customEncode = URI.encode;
212
URI.encode = function(string) {
213
// Custom encoding logic
214
return customEncode(string).replace(/%20/g, '+');
215
};
216
217
console.log(URI.encode('hello world')); // 'hello+world'
218
```
219
220
### URN Path Encoding
221
222
Special encoding methods for URN (Uniform Resource Name) paths.
223
224
```javascript { .api }
225
/**
226
* Encode URN path segment
227
* @param segment - URN path segment to encode
228
* @returns Encoded URN path segment
229
*/
230
URI.encodeUrnPathSegment(segment: string): string;
231
232
/**
233
* Decode URN path segment
234
* @param segment - Encoded URN path segment to decode
235
* @returns Decoded URN path segment
236
*/
237
URI.decodeUrnPathSegment(segment: string): string;
238
239
/**
240
* Decode URN path
241
* @param path - Encoded URN path
242
* @returns Decoded URN path
243
*/
244
URI.decodeUrnPath(path: string): string;
245
246
/**
247
* Re-encode URN path
248
* @param path - URN path to re-encode
249
* @returns Re-encoded URN path
250
*/
251
URI.recodeUrnPath(path: string): string;
252
```
253
254
**Usage Examples:**
255
256
```javascript
257
// URN path encoding
258
const urnSegment = 'example:hello world:special';
259
const encodedUrn = URI.encodeUrnPathSegment(urnSegment);
260
console.log(encodedUrn); // Encoded according to URN rules
261
262
const decodedUrn = URI.decodeUrnPathSegment(encodedUrn);
263
console.log(decodedUrn); // 'example:hello world:special'
264
265
// Full URN path handling
266
const urnPath = 'urn:example:hello world:café:résumé';
267
const encodedUrnPath = URI.recodeUrnPath(urnPath);
268
console.log(encodedUrnPath); // Properly encoded URN path
269
270
// Use with URN URIs
271
const urnUri = new URI('urn:isbn:0451450523');
272
console.log(urnUri.is('urn')); // true
273
274
// URN-specific operations
275
const complexUrn = new URI('urn:example:path with spaces:café');
276
const urnParts = complexUrn.pathname().split(':');
277
const decodedParts = urnParts.map(URI.decodeUrnPathSegment);
278
console.log(decodedParts); // ['', 'example', 'path with spaces', 'café']
279
```
280
281
### Validation and Error Handling
282
283
Methods to validate URI components and handle encoding errors.
284
285
```javascript { .api }
286
/**
287
* Ensure hostname is valid for the given protocol
288
* @param hostname - Hostname to validate
289
* @param protocol - Protocol context for validation
290
* @throws TypeError for invalid hostnames when preventInvalidHostname is true
291
*/
292
URI.ensureValidHostname(hostname: string, protocol: string): void;
293
294
/**
295
* Ensure port is valid
296
* @param port - Port to validate
297
* @throws TypeError for invalid ports
298
*/
299
URI.ensureValidPort(port: string | number): void;
300
```
301
302
**Usage Examples:**
303
304
```javascript
305
// Hostname validation
306
try {
307
URI.ensureValidHostname('valid.example.com', 'http');
308
console.log('Hostname is valid');
309
} catch (error) {
310
console.log('Invalid hostname:', error.message);
311
}
312
313
// Port validation
314
try {
315
URI.ensureValidPort(8080);
316
console.log('Port is valid');
317
} catch (error) {
318
console.log('Invalid port:', error.message);
319
}
320
321
// Invalid port example
322
try {
323
URI.ensureValidPort('invalid');
324
} catch (error) {
325
console.log('Error:', error.message); // "Invalid port"
326
}
327
328
// Configure validation behavior
329
const uri = new URI('http://example.com/');
330
uri.preventInvalidHostname(true);
331
332
try {
333
uri.hostname('invalid..hostname');
334
} catch (error) {
335
console.log('Validation prevented invalid hostname');
336
}
337
```