11# @knide/pathnorm
22
3+ [ ![ npm version] ( https://img.shields.io/npm/v/@knide/pathnorm )] ( https://www.npmjs.com/package/@knide/pathnorm )
4+ [ ![ Bundle Size] ( https://img.shields.io/bundlephobia/minzip/@knide/pathnorm )] ( https://bundlephobia.com/package/@knide/pathnorm )
5+ [ ![ License] ( https://img.shields.io/npm/l/@knide/pathnorm )] ( ./LICENSE )
6+
37Normalize and join path or URL segments into a single clean string.
48
59- Zero dependencies
6- - Dual CJS + ESM build
710- Full TypeScript support
811- Tree-shakeable
12+ - ** < 500B** minified + gzipped — use ` @knide/pathnorm/posix ` for an even lighter bundle in browser-only contexts
913
1014## Installation
1115
@@ -36,64 +40,62 @@ Exports `np` and `unixNp`.
3640import { np , unixNp } from ' @knide/pathnorm'
3741```
3842
39- ### ` np(...parts) `
43+ ### ` np(...parts) ` (POSIX + Win32 + UNC + URLs)
4044
4145Joins and normalizes path or URL segments. Detects and handles URLs, POSIX paths, Win32 drive letters, UNC paths, and Win32 namespace paths automatically.
4246
4347``` ts
4448import { np } from ' @knide/pathnorm'
49+
4550// URLs
46- np (" https://abc.def//212 /" , " dw//we " , " 23123 " )
47- // → "https://abc.def/212/dw/we/23123 "
51+ np (" https://example.com//api /" , " v1//users " , " profile " )
52+ // → "https://example.com/api/v1/users/profile "
4853
49- np (" exp://abc.def//212 /" , " dw/we " )
50- // → "exp://abc.def/212/dw/we "
54+ np (" exp://com.myapp//screens /" , " home " )
55+ // → "exp://com.myapp/screens/home "
5156
5257// POSIX
53- np (" abc.def//212/ " , " dwwe " , " 23123 " )
54- // → "abc.def/212/dwwe/23123 "
58+ np (" /var/www//html/ " , " assets//images " , " logo.png " )
59+ // → "/var/www/html/assets/images/logo.png "
5560
56- np (" foo//bar" , " /baz" )
57- // → "/foo/bar/baz"
58-
59- np (" /foo//bar" , " baz" )
60- // → "/foo/bar/baz"
61+ np (" uploads//images" , " /photos" )
62+ // → "/uploads/images/photos"
6163
6264// Win32 drive letter
63- np (" C:\\ foo \\\\ bar " , " baz " )
64- // → "C:\foo\bar\baz "
65+ np (" C:\\ Users \\\\ Alice \\ Documents " , " report.pdf " )
66+ // → "C:\Users\Alice\Documents\report.pdf "
6567
6668// UNC
67- np (" \\\\ server \\ share\\\\ folder " , " file .txt" )
68- // → "//server /share/folder/file .txt"
69+ np (" \\\\ server01 \\ share\\\\ docs " , " letter .txt" )
70+ // → "//server01 /share/docs/letter .txt"
6971
7072// Win32 namespace
71- np (" \\\\ ?\\ C:\\ foo \\\\ bar " , " baz " )
72- // → "//?/C:/foo/bar/baz "
73+ np (" \\\\ ?\\ C:\\ Users \\\\ Alice " , " report.pdf " )
74+ // → "//?/C:/Users/Alice/report.pdf "
7375
74- // Mixed slashes in Win32
75- np (" C:\\ foo//bar \\\\ baz " )
76- // → "C:\foo\bar\baz "
76+ // Mixed slashes
77+ np (" C:\\ projects//my-app \\\\ src " )
78+ // → "C:\projects\my-app\src "
7779```
7880
79- ### ` unixNp(...parts) `
81+ ### ` unixNp(...parts) ` (always forward slashes)
8082
81- Like ` np ` , but always returns a Unix-style path . Useful when working with Win32 paths but the consumer expects forward slashes .
83+ Like ` np ` , but always returns forward slashes . Useful when working with Win32 paths in a Unix-expecting context .
8284
8385``` ts
8486import { unixNp } from ' @knide/pathnorm'
85- unixNp (" C:\\ foo\\\\ bar" , " baz" )
86- // → "C:/foo/bar/baz"
8787
88- unixNp (" \\\\ server\\ share\\\\ folder" , " file.txt" )
89- // → "//server/share/folder/file.txt"
88+ unixNp (" C:\\ Users\\\\ Alice\\ Documents" , " report.pdf" )
89+ // → "C:/Users/Alice/Documents/report.pdf"
90+
91+ unixNp (" \\\\ server01\\ share\\\\ docs" , " letter.txt" )
92+ // → "//server01/share/docs/letter.txt"
9093
91- unixNp (" \\\\ ?\\ C:\\ foo \\\\ bar " , " baz " )
92- // → "//?/C:/foo/bar/baz "
94+ unixNp (" \\\\ ?\\ C:\\ Users \\\\ Alice " , " report.pdf " )
95+ // → "//?/C:/Users/Alice/report.pdf "
9396
94- // POSIX paths pass through unchanged
95- unixNp (" /foo//bar" , " baz" )
96- // → "/foo/bar/baz"
97+ unixNp (" /var/www//html" , " index.html" )
98+ // → "/var/www/html/index.html"
9799```
98100
99101---
@@ -108,26 +110,22 @@ import { np } from '@knide/pathnorm/posix'
108110
109111### ` np(...parts) ` (POSIX + URLs)
110112
111- Joins and normalizes URL or POSIX path segments.
112-
113113``` ts
114114import { np } from ' @knide/pathnorm/posix'
115+
115116// URLs
116- np (" https://abc.def//212 /" , " dw//we " , " 23123 " )
117- // → "https://abc.def/212/dw/we/23123 "
117+ np (" https://example.com//api /" , " v1//users " , " profile " )
118+ // → "https://example.com/api/v1/users/profile "
118119
119- np (" exp://abc.def//212 /" , " dw/we " )
120- // → "exp://abc.def/212/dw/we "
120+ np (" exp://com.myapp//screens /" , " home " )
121+ // → "exp://com.myapp/screens/home "
121122
122123// POSIX
123- np (" abc.def//212/" , " dwwe" , " 23123" )
124- // → "abc.def/212/dwwe/23123"
125-
126- np (" foo//bar" , " /baz" )
127- // → "/foo/bar/baz"
124+ np (" /var/www//html/" , " assets//images" , " logo.png" )
125+ // → "/var/www/html/assets/images/logo.png"
128126
129- np (" /foo//bar " , " baz " )
130- // → "/foo/bar/baz "
127+ np (" uploads//images " , " /photos " )
128+ // → "/uploads/images/photos "
131129
132130// Typical web usage
133131np (window .location .origin , " /api/proxy//betterauth" )
@@ -144,7 +142,7 @@ np(window.location.origin, "/api/proxy//betterauth")
144142- Trailing slashes are not preserved.
145143
146144``` ts
147- // Only first scheme is treated as prefix
148- np (" exp ://" , " sdfasdf " , " abc.def//212/ " , " dw//we " , " 23123 " , " https ://" )
149- // → "exp ://sdfasdf/abc.def/212/dw/we/23123/https:/ "
145+ // Only the first segment's scheme is treated as a URL prefix
146+ np (" https ://example.com// " , " /api/v1 " , " http ://users " )
147+ // → "https ://example.com/api/v1/http:/users "
150148```
0 commit comments