@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.
Files changed (147) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +222 -0
  3. package/dist/auth.d.ts +139 -0
  4. package/dist/auth.d.ts.map +1 -0
  5. package/dist/auth.js +991 -0
  6. package/dist/auth.js.map +1 -0
  7. package/dist/cache-status.d.ts +15 -0
  8. package/dist/cache-status.d.ts.map +1 -0
  9. package/dist/cache-status.js +152 -0
  10. package/dist/cache-status.js.map +1 -0
  11. package/dist/cache.d.ts +94 -0
  12. package/dist/cache.d.ts.map +1 -0
  13. package/dist/cache.js +244 -0
  14. package/dist/cache.js.map +1 -0
  15. package/dist/client-hints.d.ts +23 -0
  16. package/dist/client-hints.d.ts.map +1 -0
  17. package/dist/client-hints.js +81 -0
  18. package/dist/client-hints.js.map +1 -0
  19. package/dist/conditional.d.ts +97 -0
  20. package/dist/conditional.d.ts.map +1 -0
  21. package/dist/conditional.js +300 -0
  22. package/dist/conditional.js.map +1 -0
  23. package/dist/content-disposition.d.ts +23 -0
  24. package/dist/content-disposition.d.ts.map +1 -0
  25. package/dist/content-disposition.js +122 -0
  26. package/dist/content-disposition.js.map +1 -0
  27. package/dist/cookie.d.ts +43 -0
  28. package/dist/cookie.d.ts.map +1 -0
  29. package/dist/cookie.js +472 -0
  30. package/dist/cookie.js.map +1 -0
  31. package/dist/cors.d.ts +53 -0
  32. package/dist/cors.d.ts.map +1 -0
  33. package/dist/cors.js +170 -0
  34. package/dist/cors.js.map +1 -0
  35. package/dist/datetime.d.ts +53 -0
  36. package/dist/datetime.d.ts.map +1 -0
  37. package/dist/datetime.js +205 -0
  38. package/dist/datetime.js.map +1 -0
  39. package/dist/digest.d.ts +220 -0
  40. package/dist/digest.d.ts.map +1 -0
  41. package/dist/digest.js +355 -0
  42. package/dist/digest.js.map +1 -0
  43. package/dist/encoding.d.ts +14 -0
  44. package/dist/encoding.d.ts.map +1 -0
  45. package/dist/encoding.js +86 -0
  46. package/dist/encoding.js.map +1 -0
  47. package/dist/etag.d.ts +55 -0
  48. package/dist/etag.d.ts.map +1 -0
  49. package/dist/etag.js +182 -0
  50. package/dist/etag.js.map +1 -0
  51. package/dist/ext-value.d.ts +40 -0
  52. package/dist/ext-value.d.ts.map +1 -0
  53. package/dist/ext-value.js +119 -0
  54. package/dist/ext-value.js.map +1 -0
  55. package/dist/forwarded.d.ts +14 -0
  56. package/dist/forwarded.d.ts.map +1 -0
  57. package/dist/forwarded.js +93 -0
  58. package/dist/forwarded.js.map +1 -0
  59. package/dist/header-utils.d.ts +71 -0
  60. package/dist/header-utils.d.ts.map +1 -0
  61. package/dist/header-utils.js +143 -0
  62. package/dist/header-utils.js.map +1 -0
  63. package/dist/headers.d.ts +71 -0
  64. package/dist/headers.d.ts.map +1 -0
  65. package/dist/headers.js +134 -0
  66. package/dist/headers.js.map +1 -0
  67. package/dist/hsts.d.ts +15 -0
  68. package/dist/hsts.d.ts.map +1 -0
  69. package/dist/hsts.js +106 -0
  70. package/dist/hsts.js.map +1 -0
  71. package/dist/http-signatures.d.ts +202 -0
  72. package/dist/http-signatures.d.ts.map +1 -0
  73. package/dist/http-signatures.js +720 -0
  74. package/dist/http-signatures.js.map +1 -0
  75. package/dist/index.d.ts +41 -0
  76. package/dist/index.d.ts.map +1 -0
  77. package/dist/index.js +125 -0
  78. package/dist/index.js.map +1 -0
  79. package/dist/json-pointer.d.ts +97 -0
  80. package/dist/json-pointer.d.ts.map +1 -0
  81. package/dist/json-pointer.js +278 -0
  82. package/dist/json-pointer.js.map +1 -0
  83. package/dist/jsonpath.d.ts +98 -0
  84. package/dist/jsonpath.d.ts.map +1 -0
  85. package/dist/jsonpath.js +1470 -0
  86. package/dist/jsonpath.js.map +1 -0
  87. package/dist/language.d.ts +14 -0
  88. package/dist/language.d.ts.map +1 -0
  89. package/dist/language.js +95 -0
  90. package/dist/language.js.map +1 -0
  91. package/dist/link.d.ts +102 -0
  92. package/dist/link.d.ts.map +1 -0
  93. package/dist/link.js +437 -0
  94. package/dist/link.js.map +1 -0
  95. package/dist/linkset.d.ts +111 -0
  96. package/dist/linkset.d.ts.map +1 -0
  97. package/dist/linkset.js +501 -0
  98. package/dist/linkset.js.map +1 -0
  99. package/dist/negotiate.d.ts +71 -0
  100. package/dist/negotiate.d.ts.map +1 -0
  101. package/dist/negotiate.js +357 -0
  102. package/dist/negotiate.js.map +1 -0
  103. package/dist/pagination.d.ts +80 -0
  104. package/dist/pagination.d.ts.map +1 -0
  105. package/dist/pagination.js +188 -0
  106. package/dist/pagination.js.map +1 -0
  107. package/dist/prefer.d.ts +18 -0
  108. package/dist/prefer.d.ts.map +1 -0
  109. package/dist/prefer.js +93 -0
  110. package/dist/prefer.js.map +1 -0
  111. package/dist/problem.d.ts +54 -0
  112. package/dist/problem.d.ts.map +1 -0
  113. package/dist/problem.js +104 -0
  114. package/dist/problem.js.map +1 -0
  115. package/dist/proxy-status.d.ts +28 -0
  116. package/dist/proxy-status.d.ts.map +1 -0
  117. package/dist/proxy-status.js +220 -0
  118. package/dist/proxy-status.js.map +1 -0
  119. package/dist/range.d.ts +28 -0
  120. package/dist/range.d.ts.map +1 -0
  121. package/dist/range.js +243 -0
  122. package/dist/range.js.map +1 -0
  123. package/dist/response.d.ts +101 -0
  124. package/dist/response.d.ts.map +1 -0
  125. package/dist/response.js +200 -0
  126. package/dist/response.js.map +1 -0
  127. package/dist/sorting.d.ts +66 -0
  128. package/dist/sorting.d.ts.map +1 -0
  129. package/dist/sorting.js +168 -0
  130. package/dist/sorting.js.map +1 -0
  131. package/dist/structured-fields.d.ts +30 -0
  132. package/dist/structured-fields.d.ts.map +1 -0
  133. package/dist/structured-fields.js +468 -0
  134. package/dist/structured-fields.js.map +1 -0
  135. package/dist/types.d.ts +772 -0
  136. package/dist/types.d.ts.map +1 -0
  137. package/dist/types.js +8 -0
  138. package/dist/types.js.map +1 -0
  139. package/dist/uri-template.d.ts +48 -0
  140. package/dist/uri-template.d.ts.map +1 -0
  141. package/dist/uri-template.js +483 -0
  142. package/dist/uri-template.js.map +1 -0
  143. package/dist/uri.d.ts +80 -0
  144. package/dist/uri.d.ts.map +1 -0
  145. package/dist/uri.js +423 -0
  146. package/dist/uri.js.map +1 -0
  147. 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
@@ -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
+ }