@irvinebroque/http-rfc-utils 0.1.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.
- package/LICENSE +21 -0
- package/README.md +222 -0
- package/dist/auth.d.ts +139 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +991 -0
- package/dist/auth.js.map +1 -0
- package/dist/cache-status.d.ts +15 -0
- package/dist/cache-status.d.ts.map +1 -0
- package/dist/cache-status.js +152 -0
- package/dist/cache-status.js.map +1 -0
- package/dist/cache.d.ts +94 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +244 -0
- package/dist/cache.js.map +1 -0
- package/dist/client-hints.d.ts +23 -0
- package/dist/client-hints.d.ts.map +1 -0
- package/dist/client-hints.js +81 -0
- package/dist/client-hints.js.map +1 -0
- package/dist/conditional.d.ts +97 -0
- package/dist/conditional.d.ts.map +1 -0
- package/dist/conditional.js +300 -0
- package/dist/conditional.js.map +1 -0
- package/dist/content-disposition.d.ts +23 -0
- package/dist/content-disposition.d.ts.map +1 -0
- package/dist/content-disposition.js +122 -0
- package/dist/content-disposition.js.map +1 -0
- package/dist/cookie.d.ts +43 -0
- package/dist/cookie.d.ts.map +1 -0
- package/dist/cookie.js +472 -0
- package/dist/cookie.js.map +1 -0
- package/dist/cors.d.ts +53 -0
- package/dist/cors.d.ts.map +1 -0
- package/dist/cors.js +170 -0
- package/dist/cors.js.map +1 -0
- package/dist/datetime.d.ts +53 -0
- package/dist/datetime.d.ts.map +1 -0
- package/dist/datetime.js +205 -0
- package/dist/datetime.js.map +1 -0
- package/dist/digest.d.ts +220 -0
- package/dist/digest.d.ts.map +1 -0
- package/dist/digest.js +355 -0
- package/dist/digest.js.map +1 -0
- package/dist/encoding.d.ts +14 -0
- package/dist/encoding.d.ts.map +1 -0
- package/dist/encoding.js +86 -0
- package/dist/encoding.js.map +1 -0
- package/dist/etag.d.ts +55 -0
- package/dist/etag.d.ts.map +1 -0
- package/dist/etag.js +182 -0
- package/dist/etag.js.map +1 -0
- package/dist/ext-value.d.ts +40 -0
- package/dist/ext-value.d.ts.map +1 -0
- package/dist/ext-value.js +119 -0
- package/dist/ext-value.js.map +1 -0
- package/dist/forwarded.d.ts +14 -0
- package/dist/forwarded.d.ts.map +1 -0
- package/dist/forwarded.js +93 -0
- package/dist/forwarded.js.map +1 -0
- package/dist/header-utils.d.ts +71 -0
- package/dist/header-utils.d.ts.map +1 -0
- package/dist/header-utils.js +143 -0
- package/dist/header-utils.js.map +1 -0
- package/dist/headers.d.ts +71 -0
- package/dist/headers.d.ts.map +1 -0
- package/dist/headers.js +134 -0
- package/dist/headers.js.map +1 -0
- package/dist/hsts.d.ts +15 -0
- package/dist/hsts.d.ts.map +1 -0
- package/dist/hsts.js +106 -0
- package/dist/hsts.js.map +1 -0
- package/dist/http-signatures.d.ts +202 -0
- package/dist/http-signatures.d.ts.map +1 -0
- package/dist/http-signatures.js +720 -0
- package/dist/http-signatures.js.map +1 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +125 -0
- package/dist/index.js.map +1 -0
- package/dist/json-pointer.d.ts +97 -0
- package/dist/json-pointer.d.ts.map +1 -0
- package/dist/json-pointer.js +278 -0
- package/dist/json-pointer.js.map +1 -0
- package/dist/jsonpath.d.ts +98 -0
- package/dist/jsonpath.d.ts.map +1 -0
- package/dist/jsonpath.js +1470 -0
- package/dist/jsonpath.js.map +1 -0
- package/dist/language.d.ts +14 -0
- package/dist/language.d.ts.map +1 -0
- package/dist/language.js +95 -0
- package/dist/language.js.map +1 -0
- package/dist/link.d.ts +102 -0
- package/dist/link.d.ts.map +1 -0
- package/dist/link.js +437 -0
- package/dist/link.js.map +1 -0
- package/dist/linkset.d.ts +111 -0
- package/dist/linkset.d.ts.map +1 -0
- package/dist/linkset.js +501 -0
- package/dist/linkset.js.map +1 -0
- package/dist/negotiate.d.ts +71 -0
- package/dist/negotiate.d.ts.map +1 -0
- package/dist/negotiate.js +357 -0
- package/dist/negotiate.js.map +1 -0
- package/dist/pagination.d.ts +80 -0
- package/dist/pagination.d.ts.map +1 -0
- package/dist/pagination.js +188 -0
- package/dist/pagination.js.map +1 -0
- package/dist/prefer.d.ts +18 -0
- package/dist/prefer.d.ts.map +1 -0
- package/dist/prefer.js +93 -0
- package/dist/prefer.js.map +1 -0
- package/dist/problem.d.ts +54 -0
- package/dist/problem.d.ts.map +1 -0
- package/dist/problem.js +104 -0
- package/dist/problem.js.map +1 -0
- package/dist/proxy-status.d.ts +28 -0
- package/dist/proxy-status.d.ts.map +1 -0
- package/dist/proxy-status.js +220 -0
- package/dist/proxy-status.js.map +1 -0
- package/dist/range.d.ts +28 -0
- package/dist/range.d.ts.map +1 -0
- package/dist/range.js +243 -0
- package/dist/range.js.map +1 -0
- package/dist/response.d.ts +101 -0
- package/dist/response.d.ts.map +1 -0
- package/dist/response.js +200 -0
- package/dist/response.js.map +1 -0
- package/dist/sorting.d.ts +66 -0
- package/dist/sorting.d.ts.map +1 -0
- package/dist/sorting.js +168 -0
- package/dist/sorting.js.map +1 -0
- package/dist/structured-fields.d.ts +30 -0
- package/dist/structured-fields.d.ts.map +1 -0
- package/dist/structured-fields.js +468 -0
- package/dist/structured-fields.js.map +1 -0
- package/dist/types.d.ts +772 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/dist/uri-template.d.ts +48 -0
- package/dist/uri-template.d.ts.map +1 -0
- package/dist/uri-template.js +483 -0
- package/dist/uri-template.js.map +1 -0
- package/dist/uri.d.ts +80 -0
- package/dist/uri.d.ts.map +1 -0
- package/dist/uri.js +423 -0
- package/dist/uri.js.map +1 -0
- package/package.json +66 -0
package/dist/uri.d.ts
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* URI utilities per RFC 3986.
|
|
3
|
+
* RFC 3986 §2, §3.1, §3.2.2, §5.2.4, §6.2.
|
|
4
|
+
* @see https://www.rfc-editor.org/rfc/rfc3986.html
|
|
5
|
+
*/
|
|
6
|
+
import type { UriComponent } from './types.js';
|
|
7
|
+
export declare const UNRESERVED_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~";
|
|
8
|
+
export declare const GEN_DELIMS = ":/?#[]@";
|
|
9
|
+
export declare const SUB_DELIMS = "!$&'()*+,;=";
|
|
10
|
+
/**
|
|
11
|
+
* Check if a character is unreserved per RFC 3986 §2.3.
|
|
12
|
+
*
|
|
13
|
+
* @param char - Single character to check
|
|
14
|
+
* @returns true if unreserved
|
|
15
|
+
*/
|
|
16
|
+
export declare function isUnreserved(char: string): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Check if a character is reserved per RFC 3986 §2.2.
|
|
19
|
+
*
|
|
20
|
+
* @param char - Single character to check
|
|
21
|
+
* @returns true if reserved (gen-delims or sub-delims)
|
|
22
|
+
*/
|
|
23
|
+
export declare function isReserved(char: string): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Percent-encode a string for use in a URI component.
|
|
26
|
+
*
|
|
27
|
+
* - Uses uppercase hex digits per RFC 3986 §2.1 SHOULD.
|
|
28
|
+
* - Does not encode unreserved characters per RFC 3986 §2.3.
|
|
29
|
+
* - Encodes based on component context (path/query/fragment/userinfo).
|
|
30
|
+
* - Detects already-encoded sequences to avoid double-encoding.
|
|
31
|
+
*
|
|
32
|
+
* @param str - String to encode
|
|
33
|
+
* @param component - URI component context (default: 'path')
|
|
34
|
+
* @returns Percent-encoded string
|
|
35
|
+
*/
|
|
36
|
+
export declare function percentEncode(str: string, component?: UriComponent): string;
|
|
37
|
+
/**
|
|
38
|
+
* Decode percent-encoded octets in a string.
|
|
39
|
+
*
|
|
40
|
+
* - Decodes all percent-encoded sequences.
|
|
41
|
+
* - Handles UTF-8 multi-byte sequences.
|
|
42
|
+
* - Returns original string if decoding fails.
|
|
43
|
+
*
|
|
44
|
+
* @param str - Percent-encoded string
|
|
45
|
+
* @returns Decoded string
|
|
46
|
+
*/
|
|
47
|
+
export declare function percentDecode(str: string): string;
|
|
48
|
+
/**
|
|
49
|
+
* Remove dot segments from a URI path per RFC 3986 §5.2.4.
|
|
50
|
+
*
|
|
51
|
+
* Implements the remove_dot_segments algorithm exactly as specified.
|
|
52
|
+
*
|
|
53
|
+
* @param path - Path component (may contain . and .. segments)
|
|
54
|
+
* @returns Path with dot segments removed
|
|
55
|
+
*/
|
|
56
|
+
export declare function removeDotSegments(path: string): string;
|
|
57
|
+
/**
|
|
58
|
+
* Normalize a URI per RFC 3986 §6.2.
|
|
59
|
+
*
|
|
60
|
+
* Applies:
|
|
61
|
+
* - Case normalization (§6.2.2.1): lowercase scheme and host
|
|
62
|
+
* - Percent-encoding normalization (§6.2.2.2): uppercase hex, decode unreserved
|
|
63
|
+
* - Path segment normalization (§6.2.2.3): remove dot segments
|
|
64
|
+
* - Scheme-based normalization (§6.2.3): remove default ports, ensure path
|
|
65
|
+
*
|
|
66
|
+
* @param uri - URI to normalize
|
|
67
|
+
* @returns Normalized URI
|
|
68
|
+
*/
|
|
69
|
+
export declare function normalizeUri(uri: string): string;
|
|
70
|
+
/**
|
|
71
|
+
* Compare two URIs for equivalence per RFC 3986 §6.2.1.
|
|
72
|
+
*
|
|
73
|
+
* Normalizes both URIs and performs simple string comparison.
|
|
74
|
+
*
|
|
75
|
+
* @param a - First URI
|
|
76
|
+
* @param b - Second URI
|
|
77
|
+
* @returns true if URIs are equivalent
|
|
78
|
+
*/
|
|
79
|
+
export declare function compareUris(a: string, b: string): boolean;
|
|
80
|
+
//# sourceMappingURL=uri.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uri.d.ts","sourceRoot":"","sources":["../src/uri.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAI/C,eAAO,MAAM,gBAAgB,uEAAuE,CAAC;AAIrG,eAAO,MAAM,UAAU,YAAY,CAAC;AAGpC,eAAO,MAAM,UAAU,gBAAiB,CAAC;AA6BzC;;;;;GAKG;AAEH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAKlD;AAED;;;;;GAKG;AAEH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAKhD;AAED;;;;;;;;;;;GAWG;AAGH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,GAAE,YAAqB,GAAG,MAAM,CAsDnF;AAED;;;;;;;;;GASG;AAEH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAsCjD;AAED;;;;;;;GAOG;AAEH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAwEtD;AAED;;;;;;;;;;;GAWG;AAEH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAuEhD;AAED;;;;;;;;GAQG;AAEH,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAKzD"}
|
package/dist/uri.js
ADDED
|
@@ -0,0 +1,423 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* URI utilities per RFC 3986.
|
|
3
|
+
* RFC 3986 §2, §3.1, §3.2.2, §5.2.4, §6.2.
|
|
4
|
+
* @see https://www.rfc-editor.org/rfc/rfc3986.html
|
|
5
|
+
*/
|
|
6
|
+
// RFC 3986 §2.3: Unreserved characters.
|
|
7
|
+
// unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
|
|
8
|
+
export const UNRESERVED_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~';
|
|
9
|
+
// RFC 3986 §2.2: Reserved characters.
|
|
10
|
+
// gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
|
|
11
|
+
export const GEN_DELIMS = ':/?#[]@';
|
|
12
|
+
// sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
|
|
13
|
+
export const SUB_DELIMS = '!$&\'()*+,;=';
|
|
14
|
+
// Combined reserved = gen-delims / sub-delims
|
|
15
|
+
const RESERVED_CHARS = GEN_DELIMS + SUB_DELIMS;
|
|
16
|
+
// RFC 3986 §3.3: pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
|
|
17
|
+
const PCHAR_EXTRA = SUB_DELIMS + ':@';
|
|
18
|
+
// Characters allowed in each component without encoding (beyond unreserved)
|
|
19
|
+
const COMPONENT_ALLOWED = {
|
|
20
|
+
// RFC 3986 §3.3: path uses pchar
|
|
21
|
+
path: PCHAR_EXTRA,
|
|
22
|
+
// RFC 3986 §3.4: query = *( pchar / "/" / "?" )
|
|
23
|
+
query: PCHAR_EXTRA + '/?',
|
|
24
|
+
// RFC 3986 §3.5: fragment = *( pchar / "/" / "?" )
|
|
25
|
+
fragment: PCHAR_EXTRA + '/?',
|
|
26
|
+
// RFC 3986 §3.2.1: userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
|
|
27
|
+
userinfo: SUB_DELIMS + ':',
|
|
28
|
+
};
|
|
29
|
+
// Default ports for scheme-based normalization (RFC 3986 §6.2.3)
|
|
30
|
+
const DEFAULT_PORTS = {
|
|
31
|
+
http: '80',
|
|
32
|
+
https: '443',
|
|
33
|
+
ftp: '21',
|
|
34
|
+
ws: '80',
|
|
35
|
+
wss: '443',
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Check if a character is unreserved per RFC 3986 §2.3.
|
|
39
|
+
*
|
|
40
|
+
* @param char - Single character to check
|
|
41
|
+
* @returns true if unreserved
|
|
42
|
+
*/
|
|
43
|
+
// RFC 3986 §2.3: unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
|
|
44
|
+
export function isUnreserved(char) {
|
|
45
|
+
if (char.length !== 1) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
return UNRESERVED_CHARS.includes(char);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Check if a character is reserved per RFC 3986 §2.2.
|
|
52
|
+
*
|
|
53
|
+
* @param char - Single character to check
|
|
54
|
+
* @returns true if reserved (gen-delims or sub-delims)
|
|
55
|
+
*/
|
|
56
|
+
// RFC 3986 §2.2: reserved = gen-delims / sub-delims
|
|
57
|
+
export function isReserved(char) {
|
|
58
|
+
if (char.length !== 1) {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
return RESERVED_CHARS.includes(char);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Percent-encode a string for use in a URI component.
|
|
65
|
+
*
|
|
66
|
+
* - Uses uppercase hex digits per RFC 3986 §2.1 SHOULD.
|
|
67
|
+
* - Does not encode unreserved characters per RFC 3986 §2.3.
|
|
68
|
+
* - Encodes based on component context (path/query/fragment/userinfo).
|
|
69
|
+
* - Detects already-encoded sequences to avoid double-encoding.
|
|
70
|
+
*
|
|
71
|
+
* @param str - String to encode
|
|
72
|
+
* @param component - URI component context (default: 'path')
|
|
73
|
+
* @returns Percent-encoded string
|
|
74
|
+
*/
|
|
75
|
+
// RFC 3986 §2.1: Percent-encoding uses uppercase HEXDIG.
|
|
76
|
+
// RFC 3986 §2.3: Unreserved characters SHOULD NOT be encoded.
|
|
77
|
+
export function percentEncode(str, component = 'path') {
|
|
78
|
+
if (!str) {
|
|
79
|
+
return '';
|
|
80
|
+
}
|
|
81
|
+
const allowedExtra = COMPONENT_ALLOWED[component];
|
|
82
|
+
const result = [];
|
|
83
|
+
// Encode string as UTF-8 bytes
|
|
84
|
+
const encoder = new TextEncoder();
|
|
85
|
+
const bytes = encoder.encode(str);
|
|
86
|
+
let i = 0;
|
|
87
|
+
while (i < bytes.length) {
|
|
88
|
+
const byte = bytes[i];
|
|
89
|
+
// Check if this is an ASCII character we can represent directly
|
|
90
|
+
if (byte < 128) {
|
|
91
|
+
const char = String.fromCharCode(byte);
|
|
92
|
+
// RFC 3986 §2.3: Do not encode unreserved characters
|
|
93
|
+
if (UNRESERVED_CHARS.includes(char)) {
|
|
94
|
+
result.push(char);
|
|
95
|
+
i++;
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
// Check component-specific allowed characters
|
|
99
|
+
if (allowedExtra.includes(char)) {
|
|
100
|
+
result.push(char);
|
|
101
|
+
i++;
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
// Check for already-encoded sequence to avoid double-encoding
|
|
105
|
+
// RFC 3986 §2.4: MUST NOT percent-encode an already percent-encoded string
|
|
106
|
+
if (char === '%' && i + 2 < bytes.length) {
|
|
107
|
+
const hex1 = String.fromCharCode(bytes[i + 1]);
|
|
108
|
+
const hex2 = String.fromCharCode(bytes[i + 2]);
|
|
109
|
+
if (isHexDigit(hex1) && isHexDigit(hex2)) {
|
|
110
|
+
// Already encoded - pass through with uppercase normalization
|
|
111
|
+
result.push('%', hex1.toUpperCase(), hex2.toUpperCase());
|
|
112
|
+
i += 3;
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// Percent-encode the byte with uppercase hex
|
|
118
|
+
result.push('%', byte.toString(16).toUpperCase().padStart(2, '0'));
|
|
119
|
+
i++;
|
|
120
|
+
}
|
|
121
|
+
return result.join('');
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Decode percent-encoded octets in a string.
|
|
125
|
+
*
|
|
126
|
+
* - Decodes all percent-encoded sequences.
|
|
127
|
+
* - Handles UTF-8 multi-byte sequences.
|
|
128
|
+
* - Returns original string if decoding fails.
|
|
129
|
+
*
|
|
130
|
+
* @param str - Percent-encoded string
|
|
131
|
+
* @returns Decoded string
|
|
132
|
+
*/
|
|
133
|
+
// RFC 3986 §2.1: Percent-decoding.
|
|
134
|
+
export function percentDecode(str) {
|
|
135
|
+
if (!str || !str.includes('%')) {
|
|
136
|
+
return str;
|
|
137
|
+
}
|
|
138
|
+
const bytes = [];
|
|
139
|
+
let i = 0;
|
|
140
|
+
while (i < str.length) {
|
|
141
|
+
if (str[i] === '%' && i + 2 < str.length) {
|
|
142
|
+
const hex = str.slice(i + 1, i + 3);
|
|
143
|
+
if (isHexDigit(hex[0]) && isHexDigit(hex[1])) {
|
|
144
|
+
bytes.push(parseInt(hex, 16));
|
|
145
|
+
i += 3;
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
// Non-encoded character - get its UTF-8 bytes
|
|
150
|
+
const charCode = str.charCodeAt(i);
|
|
151
|
+
if (charCode < 128) {
|
|
152
|
+
bytes.push(charCode);
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
// Non-ASCII character that wasn't encoded - encode as UTF-8
|
|
156
|
+
const encoder = new TextEncoder();
|
|
157
|
+
const charBytes = encoder.encode(str[i]);
|
|
158
|
+
bytes.push(...charBytes);
|
|
159
|
+
}
|
|
160
|
+
i++;
|
|
161
|
+
}
|
|
162
|
+
// Decode UTF-8 bytes to string
|
|
163
|
+
try {
|
|
164
|
+
const decoder = new TextDecoder('utf-8', { fatal: true });
|
|
165
|
+
return decoder.decode(new Uint8Array(bytes));
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
// Invalid UTF-8 - return original
|
|
169
|
+
return str;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Remove dot segments from a URI path per RFC 3986 §5.2.4.
|
|
174
|
+
*
|
|
175
|
+
* Implements the remove_dot_segments algorithm exactly as specified.
|
|
176
|
+
*
|
|
177
|
+
* @param path - Path component (may contain . and .. segments)
|
|
178
|
+
* @returns Path with dot segments removed
|
|
179
|
+
*/
|
|
180
|
+
// RFC 3986 §5.2.4: Remove Dot Segments algorithm.
|
|
181
|
+
export function removeDotSegments(path) {
|
|
182
|
+
if (!path) {
|
|
183
|
+
return '';
|
|
184
|
+
}
|
|
185
|
+
// Input buffer
|
|
186
|
+
let input = path;
|
|
187
|
+
// Output buffer
|
|
188
|
+
const output = [];
|
|
189
|
+
while (input.length > 0) {
|
|
190
|
+
// A: If the input buffer begins with a prefix of "../" or "./"
|
|
191
|
+
if (input.startsWith('../')) {
|
|
192
|
+
input = input.slice(3);
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
if (input.startsWith('./')) {
|
|
196
|
+
input = input.slice(2);
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
// B: If the input buffer begins with a prefix of "/./" or "/."
|
|
200
|
+
// where "." is a complete path segment
|
|
201
|
+
if (input.startsWith('/./')) {
|
|
202
|
+
input = '/' + input.slice(3);
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
if (input === '/.') {
|
|
206
|
+
input = '/';
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
// C: If the input buffer begins with a prefix of "/../" or "/.."
|
|
210
|
+
// where ".." is a complete path segment
|
|
211
|
+
if (input.startsWith('/../')) {
|
|
212
|
+
input = '/' + input.slice(4);
|
|
213
|
+
// Remove last segment from output
|
|
214
|
+
removeLastSegment(output);
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
if (input === '/..') {
|
|
218
|
+
input = '/';
|
|
219
|
+
removeLastSegment(output);
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
// D: If the input buffer consists only of "." or ".."
|
|
223
|
+
if (input === '.' || input === '..') {
|
|
224
|
+
input = '';
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
// E: Move the first path segment (including initial "/" if any)
|
|
228
|
+
// to the end of the output buffer
|
|
229
|
+
let segmentEnd;
|
|
230
|
+
if (input.startsWith('/')) {
|
|
231
|
+
segmentEnd = input.indexOf('/', 1);
|
|
232
|
+
if (segmentEnd === -1) {
|
|
233
|
+
segmentEnd = input.length;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
segmentEnd = input.indexOf('/');
|
|
238
|
+
if (segmentEnd === -1) {
|
|
239
|
+
segmentEnd = input.length;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
output.push(input.slice(0, segmentEnd));
|
|
243
|
+
input = input.slice(segmentEnd);
|
|
244
|
+
}
|
|
245
|
+
return output.join('');
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Normalize a URI per RFC 3986 §6.2.
|
|
249
|
+
*
|
|
250
|
+
* Applies:
|
|
251
|
+
* - Case normalization (§6.2.2.1): lowercase scheme and host
|
|
252
|
+
* - Percent-encoding normalization (§6.2.2.2): uppercase hex, decode unreserved
|
|
253
|
+
* - Path segment normalization (§6.2.2.3): remove dot segments
|
|
254
|
+
* - Scheme-based normalization (§6.2.3): remove default ports, ensure path
|
|
255
|
+
*
|
|
256
|
+
* @param uri - URI to normalize
|
|
257
|
+
* @returns Normalized URI
|
|
258
|
+
*/
|
|
259
|
+
// RFC 3986 §6.2: Comparison Ladder normalization.
|
|
260
|
+
export function normalizeUri(uri) {
|
|
261
|
+
if (!uri) {
|
|
262
|
+
return '';
|
|
263
|
+
}
|
|
264
|
+
// Use URL for parsing when possible
|
|
265
|
+
let url;
|
|
266
|
+
try {
|
|
267
|
+
url = new URL(uri);
|
|
268
|
+
}
|
|
269
|
+
catch {
|
|
270
|
+
// Not a valid absolute URI - try basic normalization
|
|
271
|
+
return normalizeUriBasic(uri);
|
|
272
|
+
}
|
|
273
|
+
// RFC 3986 §6.2.2.1: Lowercase scheme
|
|
274
|
+
const scheme = url.protocol.slice(0, -1).toLowerCase();
|
|
275
|
+
// RFC 3986 §6.2.2.1: Lowercase host (reg-name)
|
|
276
|
+
// Note: URL already lowercases the hostname
|
|
277
|
+
const host = url.hostname.toLowerCase();
|
|
278
|
+
// RFC 3986 §6.2.3: Remove default port
|
|
279
|
+
let port = url.port;
|
|
280
|
+
if (port && DEFAULT_PORTS[scheme] === port) {
|
|
281
|
+
port = '';
|
|
282
|
+
}
|
|
283
|
+
// RFC 3986 §6.2.2.2: Percent-encoding normalization for path
|
|
284
|
+
let path = normalizePercentEncoding(url.pathname);
|
|
285
|
+
// RFC 3986 §6.2.2.3: Path segment normalization
|
|
286
|
+
path = removeDotSegments(path);
|
|
287
|
+
// RFC 3986 §6.2.3: Ensure non-empty path when authority present
|
|
288
|
+
if (host && !path) {
|
|
289
|
+
path = '/';
|
|
290
|
+
}
|
|
291
|
+
// RFC 3986 §6.2.2.2: Normalize query percent-encoding
|
|
292
|
+
let query = '';
|
|
293
|
+
if (url.search) {
|
|
294
|
+
query = '?' + normalizePercentEncoding(url.search.slice(1));
|
|
295
|
+
}
|
|
296
|
+
// RFC 3986 §6.2.2.2: Normalize fragment percent-encoding
|
|
297
|
+
let fragment = '';
|
|
298
|
+
if (url.hash) {
|
|
299
|
+
fragment = '#' + normalizePercentEncoding(url.hash.slice(1));
|
|
300
|
+
}
|
|
301
|
+
// Reconstruct URI
|
|
302
|
+
let result = scheme + '://';
|
|
303
|
+
// Add userinfo if present (rare)
|
|
304
|
+
if (url.username) {
|
|
305
|
+
result += normalizePercentEncoding(url.username);
|
|
306
|
+
if (url.password) {
|
|
307
|
+
result += ':' + normalizePercentEncoding(url.password);
|
|
308
|
+
}
|
|
309
|
+
result += '@';
|
|
310
|
+
}
|
|
311
|
+
result += host;
|
|
312
|
+
if (port) {
|
|
313
|
+
result += ':' + port;
|
|
314
|
+
}
|
|
315
|
+
result += path + query + fragment;
|
|
316
|
+
return result;
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Compare two URIs for equivalence per RFC 3986 §6.2.1.
|
|
320
|
+
*
|
|
321
|
+
* Normalizes both URIs and performs simple string comparison.
|
|
322
|
+
*
|
|
323
|
+
* @param a - First URI
|
|
324
|
+
* @param b - Second URI
|
|
325
|
+
* @returns true if URIs are equivalent
|
|
326
|
+
*/
|
|
327
|
+
// RFC 3986 §6.2.1: Simple String Comparison after normalization.
|
|
328
|
+
export function compareUris(a, b) {
|
|
329
|
+
if (a === b) {
|
|
330
|
+
return true;
|
|
331
|
+
}
|
|
332
|
+
return normalizeUri(a) === normalizeUri(b);
|
|
333
|
+
}
|
|
334
|
+
// --- Internal helpers ---
|
|
335
|
+
/**
|
|
336
|
+
* Check if a character is a hex digit.
|
|
337
|
+
*/
|
|
338
|
+
function isHexDigit(char) {
|
|
339
|
+
return /^[0-9A-Fa-f]$/.test(char);
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Remove the last path segment from the output buffer.
|
|
343
|
+
* Used by removeDotSegments for ".." processing.
|
|
344
|
+
*
|
|
345
|
+
* RFC 3986 §5.2.4 step C says to remove "the last segment and its
|
|
346
|
+
* preceding '/' (if any)". Since our output buffer stores segments
|
|
347
|
+
* with their leading slashes (e.g., "/a", "/b"), we just pop the
|
|
348
|
+
* last element.
|
|
349
|
+
*/
|
|
350
|
+
function removeLastSegment(output) {
|
|
351
|
+
if (output.length > 0) {
|
|
352
|
+
output.pop();
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Normalize percent-encoding in a string.
|
|
357
|
+
* - Uppercase hex digits
|
|
358
|
+
* - Decode unreserved characters
|
|
359
|
+
*/
|
|
360
|
+
// RFC 3986 §6.2.2.2: Percent-Encoding Normalization.
|
|
361
|
+
function normalizePercentEncoding(str) {
|
|
362
|
+
if (!str) {
|
|
363
|
+
return '';
|
|
364
|
+
}
|
|
365
|
+
const result = [];
|
|
366
|
+
let i = 0;
|
|
367
|
+
while (i < str.length) {
|
|
368
|
+
if (str[i] === '%' && i + 2 < str.length) {
|
|
369
|
+
const hex1 = str[i + 1];
|
|
370
|
+
const hex2 = str[i + 2];
|
|
371
|
+
if (isHexDigit(hex1) && isHexDigit(hex2)) {
|
|
372
|
+
const byte = parseInt(hex1 + hex2, 16);
|
|
373
|
+
const char = String.fromCharCode(byte);
|
|
374
|
+
// RFC 3986 §6.2.2.2: Decode unreserved characters
|
|
375
|
+
if (UNRESERVED_CHARS.includes(char)) {
|
|
376
|
+
result.push(char);
|
|
377
|
+
}
|
|
378
|
+
else {
|
|
379
|
+
// Keep encoded but with uppercase hex
|
|
380
|
+
result.push('%', hex1.toUpperCase(), hex2.toUpperCase());
|
|
381
|
+
}
|
|
382
|
+
i += 3;
|
|
383
|
+
continue;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
result.push(str[i]);
|
|
387
|
+
i++;
|
|
388
|
+
}
|
|
389
|
+
return result.join('');
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Basic normalization for URIs that can't be parsed by URL.
|
|
393
|
+
* Handles relative references and other edge cases.
|
|
394
|
+
*/
|
|
395
|
+
function normalizeUriBasic(uri) {
|
|
396
|
+
// Just normalize percent-encoding and dot segments
|
|
397
|
+
let result = normalizePercentEncoding(uri);
|
|
398
|
+
// If it looks like it has a path, normalize dot segments
|
|
399
|
+
if (result.includes('/')) {
|
|
400
|
+
// Find where the path starts
|
|
401
|
+
const pathStart = result.indexOf('/');
|
|
402
|
+
const beforePath = result.slice(0, pathStart);
|
|
403
|
+
let path = result.slice(pathStart);
|
|
404
|
+
// Check for query/fragment
|
|
405
|
+
const queryStart = path.indexOf('?');
|
|
406
|
+
const fragStart = path.indexOf('#');
|
|
407
|
+
let query = '';
|
|
408
|
+
let fragment = '';
|
|
409
|
+
if (fragStart !== -1) {
|
|
410
|
+
fragment = path.slice(fragStart);
|
|
411
|
+
path = path.slice(0, fragStart);
|
|
412
|
+
}
|
|
413
|
+
if (queryStart !== -1 && (fragStart === -1 || queryStart < fragStart)) {
|
|
414
|
+
const qEnd = fragStart !== -1 ? fragStart : path.length;
|
|
415
|
+
query = path.slice(queryStart, qEnd);
|
|
416
|
+
path = path.slice(0, queryStart);
|
|
417
|
+
}
|
|
418
|
+
path = removeDotSegments(path);
|
|
419
|
+
result = beforePath + path + query + fragment;
|
|
420
|
+
}
|
|
421
|
+
return result;
|
|
422
|
+
}
|
|
423
|
+
//# sourceMappingURL=uri.js.map
|
package/dist/uri.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uri.js","sourceRoot":"","sources":["../src/uri.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@irvinebroque/http-rfc-utils",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "RFC-compliant HTTP utilities for APIs (9110, 8288, 7231, 9457, 9111)",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"import": "./dist/index.js"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"main": "./dist/index.js",
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"sideEffects": false,
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"publishConfig": {
|
|
19
|
+
"access": "public",
|
|
20
|
+
"provenance": true
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"http",
|
|
24
|
+
"rfc",
|
|
25
|
+
"etag",
|
|
26
|
+
"cors",
|
|
27
|
+
"cache-control",
|
|
28
|
+
"content-negotiation",
|
|
29
|
+
"link-header",
|
|
30
|
+
"problem-details",
|
|
31
|
+
"conditional-requests",
|
|
32
|
+
"rfc9110",
|
|
33
|
+
"rfc8288",
|
|
34
|
+
"rfc9457"
|
|
35
|
+
],
|
|
36
|
+
"author": "Brendan Irvine-Broque",
|
|
37
|
+
"license": "MIT",
|
|
38
|
+
"repository": {
|
|
39
|
+
"type": "git",
|
|
40
|
+
"url": "git+https://github.com/irvinebroque/http-rfc-utils.git"
|
|
41
|
+
},
|
|
42
|
+
"homepage": "https://github.com/irvinebroque/http-rfc-utils#readme",
|
|
43
|
+
"bugs": {
|
|
44
|
+
"url": "https://github.com/irvinebroque/http-rfc-utils/issues"
|
|
45
|
+
},
|
|
46
|
+
"engines": {
|
|
47
|
+
"node": ">=22.0.0"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@changesets/changelog-github": "^0.5.2",
|
|
51
|
+
"@changesets/cli": "^2.29.8",
|
|
52
|
+
"@types/node": "^22.10.2",
|
|
53
|
+
"tsx": "^4.21.0",
|
|
54
|
+
"typescript": "^5.7.0"
|
|
55
|
+
},
|
|
56
|
+
"scripts": {
|
|
57
|
+
"build": "tsc",
|
|
58
|
+
"clean": "rm -rf dist",
|
|
59
|
+
"test": "tsx --test test/*.test.ts",
|
|
60
|
+
"test:watch": "tsx --test --watch test/*.test.ts",
|
|
61
|
+
"typecheck": "tsc --noEmit",
|
|
62
|
+
"changeset": "changeset",
|
|
63
|
+
"version": "changeset version",
|
|
64
|
+
"release": "changeset publish"
|
|
65
|
+
}
|
|
66
|
+
}
|