normalize-url 8.0.2 → 8.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/index.d.ts +39 -0
- package/index.js +23 -0
- package/package.json +1 -1
- package/readme.md +35 -0
package/index.d.ts
CHANGED
|
@@ -278,6 +278,45 @@ export type Options = {
|
|
|
278
278
|
```
|
|
279
279
|
*/
|
|
280
280
|
readonly sortQueryParameters?: boolean;
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
Removes the entire URL path, leaving only the domain.
|
|
284
|
+
|
|
285
|
+
@default false
|
|
286
|
+
|
|
287
|
+
@example
|
|
288
|
+
```
|
|
289
|
+
normalizeUrl('https://example.com/path/to/page', {
|
|
290
|
+
removePath: true
|
|
291
|
+
});
|
|
292
|
+
//=> 'https://example.com'
|
|
293
|
+
```
|
|
294
|
+
*/
|
|
295
|
+
readonly removePath?: boolean;
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
Custom function to transform the URL path components.
|
|
299
|
+
|
|
300
|
+
The function receives an array of non-empty path components and should return a modified array.
|
|
301
|
+
|
|
302
|
+
@default false
|
|
303
|
+
|
|
304
|
+
@example
|
|
305
|
+
```
|
|
306
|
+
// Keep only the first path component
|
|
307
|
+
normalizeUrl('https://example.com/api/v1/users', {
|
|
308
|
+
transformPath: (pathComponents) => pathComponents.slice(0, 1)
|
|
309
|
+
});
|
|
310
|
+
//=> 'https://example.com/api'
|
|
311
|
+
|
|
312
|
+
// Remove specific components
|
|
313
|
+
normalizeUrl('https://example.com/admin/users', {
|
|
314
|
+
transformPath: (pathComponents) => pathComponents.filter(c => c !== 'admin')
|
|
315
|
+
});
|
|
316
|
+
//=> 'https://example.com/users'
|
|
317
|
+
```
|
|
318
|
+
*/
|
|
319
|
+
readonly transformPath?: (pathComponents: string[]) => string[];
|
|
281
320
|
};
|
|
282
321
|
|
|
283
322
|
/**
|
package/index.js
CHANGED
|
@@ -89,6 +89,8 @@ export default function normalizeUrl(urlString, options) {
|
|
|
89
89
|
removeDirectoryIndex: false,
|
|
90
90
|
removeExplicitPort: false,
|
|
91
91
|
sortQueryParameters: true,
|
|
92
|
+
removePath: false,
|
|
93
|
+
transformPath: false,
|
|
92
94
|
...options,
|
|
93
95
|
};
|
|
94
96
|
|
|
@@ -200,6 +202,18 @@ export default function normalizeUrl(urlString, options) {
|
|
|
200
202
|
}
|
|
201
203
|
}
|
|
202
204
|
|
|
205
|
+
// Remove path
|
|
206
|
+
if (options.removePath) {
|
|
207
|
+
urlObject.pathname = '/';
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Transform path components
|
|
211
|
+
if (options.transformPath && typeof options.transformPath === 'function') {
|
|
212
|
+
const pathComponents = urlObject.pathname.split('/').filter(Boolean);
|
|
213
|
+
const newComponents = options.transformPath(pathComponents);
|
|
214
|
+
urlObject.pathname = newComponents?.length > 0 ? `/${newComponents.join('/')}` : '/';
|
|
215
|
+
}
|
|
216
|
+
|
|
203
217
|
if (urlObject.hostname) {
|
|
204
218
|
// Remove trailing dot
|
|
205
219
|
urlObject.hostname = urlObject.hostname.replace(/\.$/, '');
|
|
@@ -240,12 +254,21 @@ export default function normalizeUrl(urlString, options) {
|
|
|
240
254
|
|
|
241
255
|
// Sort query parameters
|
|
242
256
|
if (options.sortQueryParameters) {
|
|
257
|
+
const originalSearch = urlObject.search;
|
|
243
258
|
urlObject.searchParams.sort();
|
|
244
259
|
|
|
245
260
|
// Calling `.sort()` encodes the search parameters, so we need to decode them again.
|
|
246
261
|
try {
|
|
247
262
|
urlObject.search = decodeURIComponent(urlObject.search);
|
|
248
263
|
} catch {}
|
|
264
|
+
|
|
265
|
+
// Fix parameters that originally had no equals sign but got one added by URLSearchParams
|
|
266
|
+
const partsWithoutEquals = originalSearch.slice(1).split('&').filter(p => p && !p.includes('='));
|
|
267
|
+
for (const part of partsWithoutEquals) {
|
|
268
|
+
const decoded = decodeURIComponent(part);
|
|
269
|
+
// Only replace at word boundaries to avoid partial matches
|
|
270
|
+
urlObject.search = urlObject.search.replace(`?${decoded}=`, `?${decoded}`).replace(`&${decoded}=`, `&${decoded}`);
|
|
271
|
+
}
|
|
249
272
|
}
|
|
250
273
|
|
|
251
274
|
if (options.removeTrailingSlash) {
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -307,6 +307,41 @@ normalizeUrl('www.sindresorhus.com?b=two&a=one&c=three', {
|
|
|
307
307
|
//=> 'http://sindresorhus.com/?b=two&a=one&c=three'
|
|
308
308
|
```
|
|
309
309
|
|
|
310
|
+
##### removePath
|
|
311
|
+
|
|
312
|
+
Type: `boolean`\
|
|
313
|
+
Default: `false`
|
|
314
|
+
|
|
315
|
+
Removes the entire URL path, leaving only the domain.
|
|
316
|
+
|
|
317
|
+
```js
|
|
318
|
+
normalizeUrl('https://example.com/path/to/page', {
|
|
319
|
+
removePath: true
|
|
320
|
+
});
|
|
321
|
+
//=> 'https://example.com'
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
##### transformPath
|
|
325
|
+
|
|
326
|
+
Type: `Function`\
|
|
327
|
+
Default: `false`
|
|
328
|
+
|
|
329
|
+
Custom function to transform the URL path components. The function receives an array of non-empty path components and should return a modified array.
|
|
330
|
+
|
|
331
|
+
```js
|
|
332
|
+
// Keep only the first path component
|
|
333
|
+
normalizeUrl('https://example.com/api/v1/users', {
|
|
334
|
+
transformPath: (pathComponents) => pathComponents.slice(0, 1)
|
|
335
|
+
});
|
|
336
|
+
//=> 'https://example.com/api'
|
|
337
|
+
|
|
338
|
+
// Remove specific components
|
|
339
|
+
normalizeUrl('https://example.com/admin/users', {
|
|
340
|
+
transformPath: (pathComponents) => pathComponents.filter(c => c !== 'admin')
|
|
341
|
+
});
|
|
342
|
+
//=> 'https://example.com/users'
|
|
343
|
+
```
|
|
344
|
+
|
|
310
345
|
## Related
|
|
311
346
|
|
|
312
347
|
- [compare-urls](https://github.com/sindresorhus/compare-urls) - Compare URLs by first normalizing them
|