d86be01c3f204ec1fdc583fb5248ac2bd13ad7e8f5e7e76bb7c215d59a169037faf0a51c5899d25766f330a51bc8c70773a8020c00b662cb22b18053875a52 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466
  1. # ufo
  2. [![npm version][npm-version-src]][npm-version-href]
  3. [![npm downloads][npm-downloads-src]][npm-downloads-href]
  4. [![bundle][bundle-src]][bundle-href]
  5. [![Codecov][codecov-src]][codecov-href]
  6. URL utils for humans.
  7. ## Install
  8. Install using npm or your favourite package manager:
  9. Install package:
  10. ```sh
  11. # npm
  12. npm install ufo
  13. # yarn
  14. yarn add ufo
  15. # pnpm
  16. pnpm install ufo
  17. # bun
  18. bun install ufo
  19. ```
  20. Import utils:
  21. ```js
  22. // ESM
  23. import { normalizeURL, joinURL } from "ufo";
  24. // CommonJS
  25. const { normalizeURL, joinURL } = require("ufo");
  26. // Deno
  27. import { parseURL } from "https://unpkg.com/ufo/dist/index.mjs";
  28. ```
  29. <!-- automd:jsdocs src=./src defaultGroup=utils -->
  30. ## Encoding Utils
  31. ### `decode(text)`
  32. Decodes text using `decodeURIComponent`. Returns the original text if it fails.
  33. ### `decodePath(text)`
  34. Decodes path section of URL (consistent with encodePath for slash encoding).
  35. ### `decodeQueryKey(text)`
  36. Decodes query key (consistent with `encodeQueryKey` for plus encoding).
  37. ### `decodeQueryValue(text)`
  38. Decodes query value (consistent with `encodeQueryValue` for plus encoding).
  39. ### `encode(text)`
  40. Encodes characters that need to be encoded in the path, search and hash sections of the URL.
  41. ### `encodeHash(text)`
  42. Encodes characters that need to be encoded in the hash section of the URL.
  43. ### `encodeHost(name)`
  44. Encodes hostname with punycode encoding.
  45. ### `encodeParam(text)`
  46. Encodes characters that need to be encoded in the path section of the URL as a param. This function encodes everything `encodePath` does plus the slash (`/`) character.
  47. ### `encodePath(text)`
  48. Encodes characters that need to be encoded in the path section of the URL.
  49. ### `encodeQueryKey(text)`
  50. Encodes characters that need to be encoded for query values in the query section of the URL and also encodes the `=` character.
  51. ### `encodeQueryValue(input)`
  52. Encodes characters that need to be encoded for query values in the query section of the URL.
  53. ## Parsing Utils
  54. ### `parseAuth(input)`
  55. Takes a string of the form `username:password` and returns an object with the username and password decoded.
  56. ### `parseFilename(input, opts?: { strict? })`
  57. Parses a URL and returns last segment in path as filename.
  58. If `{ strict: true }` is passed as the second argument, it will only return the last segment only if ending with an extension.
  59. **Example:**
  60. ```js
  61. // Result: filename.ext
  62. parseFilename("http://example.com/path/to/filename.ext");
  63. // Result: undefined
  64. parseFilename("/path/to/.hidden-file", { strict: true });
  65. ```
  66. ### `parseHost(input)`
  67. Takes a string, and returns an object with two properties: `hostname` and `port`.
  68. ### `parsePath(input)`
  69. Splits the input string into three parts, and returns an object with those three parts.
  70. ### `parseURL(input, defaultProto?)`
  71. Takes a URL string and returns an object with the URL's `protocol`, `auth`, `host`, `pathname`, `search`, and `hash`.
  72. **Example:**
  73. ```js
  74. parseURL("http://foo.com/foo?test=123#token");
  75. // { protocol: 'http:', auth: '', host: 'foo.com', pathname: '/foo', search: '?test=123', hash: '#token' }
  76. parseURL("foo.com/foo?test=123#token");
  77. // { pathname: 'foo.com/foo', search: '?test=123', hash: '#token' }
  78. parseURL("foo.com/foo?test=123#token", "https://");
  79. // { protocol: 'https:', auth: '', host: 'foo.com', pathname: '/foo', search: '?test=123', hash: '#token' }
  80. ```
  81. ### `stringifyParsedURL(parsed)`
  82. Takes a `ParsedURL` object and returns the stringified URL.
  83. **Example:**
  84. ```js
  85. const obj = parseURL("http://foo.com/foo?test=123#token");
  86. obj.host = "bar.com";
  87. stringifyParsedURL(obj); // "http://bar.com/foo?test=123#token"
  88. ```
  89. ## Query Utils
  90. ### `encodeQueryItem(key, value)`
  91. Encodes a pair of key and value into a url query string value.
  92. If the value is an array, it will be encoded as multiple key-value pairs with the same key.
  93. ### `parseQuery(parametersString)`
  94. Parses and decodes a query string into an object.
  95. The input can be a query string with or without the leading `?`.
  96. ### `stringifyQuery(query)`
  97. Stringfies and encodes a query object into a query string.
  98. ## Utils
  99. ### `$URL()`
  100. ### `cleanDoubleSlashes(input)`
  101. Removes double slashes from the URL.
  102. **Example:**
  103. ```js
  104. cleanDoubleSlashes("//foo//bar//"); // "/foo/bar/"
  105. cleanDoubleSlashes("http://example.com/analyze//http://localhost:3000//");
  106. // Returns "http://example.com/analyze/http://localhost:3000/"
  107. ```
  108. ### `filterQuery(input, predicate)`
  109. Removes the query section of the URL.
  110. **Example:**
  111. ```js
  112. filterQuery("/foo?bar=1&baz=2", (key) => key !== "bar"); // "/foo?baz=2"
  113. ```
  114. ### `getQuery(input)`
  115. Parses and decodes the query object of an input URL into an object.
  116. **Example:**
  117. ```js
  118. getQuery("http://foo.com/foo?test=123&unicode=%E5%A5%BD");
  119. // { test: "123", unicode: "好" }
  120. ```
  121. ### `hasLeadingSlash(input)`
  122. Checks if the input has a leading slash (e.g. `/foo`).
  123. ### `hasProtocol(inputString, opts)`
  124. ### `hasTrailingSlash(input, respectQueryAndFragment?)`
  125. Checks if the input has a trailing slash.
  126. ### `isEmptyURL(url)`
  127. Checks if the input URL is empty or `/`.
  128. ### `isEqual(a, b, options)`
  129. Checks if two paths are equal regardless of encoding, trailing slash, and leading slash differences.
  130. You can make slash check strict by setting `{ trailingSlash: true, leadingSlash: true }` as options.
  131. You can make encoding check strict by setting `{ encoding: true }` as options.
  132. **Example:**
  133. ```js
  134. isEqual("/foo", "foo"); // true
  135. isEqual("foo/", "foo"); // true
  136. isEqual("/foo bar", "/foo%20bar"); // true
  137. // Strict compare
  138. isEqual("/foo", "foo", { leadingSlash: true }); // false
  139. isEqual("foo/", "foo", { trailingSlash: true }); // false
  140. isEqual("/foo bar", "/foo%20bar", { encoding: true }); // false
  141. ```
  142. ### `isNonEmptyURL(url)`
  143. Checks if the input URL is neither empty nor `/`.
  144. ### `isRelative(inputString)`
  145. Check if a path starts with `./` or `../`.
  146. **Example:**
  147. ```js
  148. isRelative("./foo"); // true
  149. ```
  150. ### `isSamePath(p1, p2)`
  151. Check if two paths are equal or not. Trailing slash and encoding are normalized before comparison.
  152. **Example:**
  153. ```js
  154. isSamePath("/foo", "/foo/"); // true
  155. ```
  156. ### `isScriptProtocol(protocol?)`
  157. Checks if the input protocol is any of the dangerous `blob:`, `data:`, `javascript`: or `vbscript:` protocols.
  158. ### `joinRelativeURL()`
  159. Joins multiple URL segments into a single URL and also handles relative paths with `./` and `../`.
  160. **Example:**
  161. ```js
  162. joinRelativeURL("/a", "../b", "./c"); // "/b/c"
  163. ```
  164. ### `joinURL(base)`
  165. Joins multiple URL segments into a single URL.
  166. **Example:**
  167. ```js
  168. joinURL("a", "/b", "/c"); // "a/b/c"
  169. ```
  170. ### `normalizeURL(input)`
  171. Normalizes the input URL:
  172. - Ensures the URL is properly encoded - Ensures pathname starts with a slash - Preserves protocol/host if provided
  173. **Example:**
  174. ```js
  175. normalizeURL("test?query=123 123#hash, test");
  176. // Returns "test?query=123%20123#hash,%20test"
  177. normalizeURL("http://localhost:3000");
  178. // Returns "http://localhost:3000"
  179. ```
  180. ### `resolveURL(base)`
  181. Resolves multiple URL segments into a single URL.
  182. **Example:**
  183. ```js
  184. resolveURL("http://foo.com/foo?test=123#token", "bar", "baz");
  185. // Returns "http://foo.com/foo/bar/baz?test=123#token"
  186. ```
  187. ### `withBase(input, base)`
  188. Ensures the URL or pathname starts with base.
  189. If input already starts with base, it will not be added again.
  190. ### `withFragment(input, hash)`
  191. Adds or replaces the fragment section of the URL.
  192. **Example:**
  193. ```js
  194. withFragment("/foo", "bar"); // "/foo#bar"
  195. withFragment("/foo#bar", "baz"); // "/foo#baz"
  196. withFragment("/foo#bar", ""); // "/foo"
  197. ```
  198. ### `withHttp(input)`
  199. Adds or replaces the URL protocol to `http://`.
  200. **Example:**
  201. ```js
  202. withHttp("https://example.com"); // http://example.com
  203. ```
  204. ### `withHttps(input)`
  205. Adds or replaces the URL protocol to `https://`.
  206. **Example:**
  207. ```js
  208. withHttps("http://example.com"); // https://example.com
  209. ```
  210. ### `withLeadingSlash(input)`
  211. Ensures the URL or pathname has a leading slash.
  212. ### `withoutBase(input, base)`
  213. Removes the base from the URL or pathname.
  214. If input does not start with base, it will not be removed.
  215. ### `withoutFragment(input)`
  216. Removes the fragment section from the URL.
  217. **Example:**
  218. ```js
  219. withoutFragment("http://example.com/foo?q=123#bar")
  220. // Returns "http://example.com/foo?q=123"
  221. ```
  222. ### `withoutHost(input)`
  223. Removes the host from the URL while preserving everything else.
  224. **Example:**
  225. ```js
  226. withoutHost("http://example.com/foo?q=123#bar")
  227. // Returns "/foo?q=123#bar"
  228. ```
  229. ### `withoutLeadingSlash(input)`
  230. Removes leading slash from the URL or pathname.
  231. ### `withoutProtocol(input)`
  232. Removes the protocol from the input.
  233. **Example:**
  234. ```js
  235. withoutProtocol("http://example.com"); // "example.com"
  236. ```
  237. ### `withoutTrailingSlash(input, respectQueryAndFragment?)`
  238. Removes the trailing slash from the URL or pathname.
  239. If second argument is `true`, it will only remove the trailing slash if it's not part of the query or fragment with cost of more expensive operations.
  240. **Example:**
  241. ```js
  242. withoutTrailingSlash("/foo/"); // "/foo"
  243. withoutTrailingSlash("/path/?query=true", true); // "/path?query=true"
  244. ```
  245. ### `withProtocol(input, protocol)`
  246. Adds or replaces protocol of the input URL.
  247. **Example:**
  248. ```js
  249. withProtocol("http://example.com", "ftp://"); // "ftp://example.com"
  250. ```
  251. ### `withQuery(input, query)`
  252. Add/Replace the query section of the URL.
  253. **Example:**
  254. ```js
  255. withQuery("/foo?page=a", { token: "secret" }); // "/foo?page=a&token=secret"
  256. ```
  257. ### `withTrailingSlash(input, respectQueryAndFragment?)`
  258. Ensures the URL ends with a trailing slash.
  259. If second argument is `true`, it will only add the trailing slash if it's not part of the query or fragment with cost of more expensive operation.
  260. **Example:**
  261. ```js
  262. withTrailingSlash("/foo"); // "/foo/"
  263. withTrailingSlash("/path?query=true", true); // "/path/?query=true"
  264. ```
  265. <!-- /automd -->
  266. ## License
  267. [MIT](./LICENSE)
  268. Special thanks to Eduardo San Martin Morote ([posva](https://github.com/posva)) for [encoding utilities](https://github.com/vuejs/vue-router-next/blob/v4.0.1/src/encoding.ts)
  269. <!-- Badges -->
  270. [npm-version-src]: https://img.shields.io/npm/v/ufo?style=flat&colorA=18181B&colorB=F0DB4F
  271. [npm-version-href]: https://npmjs.com/package/ufo
  272. [npm-downloads-src]: https://img.shields.io/npm/dm/ufo?style=flat&colorA=18181B&colorB=F0DB4F
  273. [npm-downloads-href]: https://npmjs.com/package/ufo
  274. [codecov-src]: https://img.shields.io/codecov/c/gh/unjs/ufo/main?style=flat&colorA=18181B&colorB=F0DB4F
  275. [codecov-href]: https://codecov.io/gh/unjs/ufo
  276. [bundle-src]: https://img.shields.io/bundlephobia/minzip/ufo?style=flat&colorA=18181B&colorB=F0DB4F
  277. [bundle-href]: https://bundlephobia.com/result?p=ufo