123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- "use strict";
- // Dependencies
- var protocols = require("protocols"),
- isSsh = require("is-ssh"),
- qs = require("query-string");
- /**
- * parsePath
- * Parses the input url.
- *
- * @name parsePath
- * @function
- * @param {String} url The input url.
- * @return {Object} An object containing the following fields:
- *
- * - `protocols` (Array): An array with the url protocols (usually it has one element).
- * - `protocol` (String): The first protocol, `"ssh"` (if the url is a ssh url) or `"file"`.
- * - `port` (null|Number): The domain port.
- * - `resource` (String): The url domain (including subdomains).
- * - `user` (String): The authentication user (usually for ssh urls).
- * - `pathname` (String): The url pathname.
- * - `hash` (String): The url hash.
- * - `search` (String): The url querystring value.
- * - `href` (String): The input url.
- * - `query` (Object): The url querystring, parsed as object.
- */
- function parsePath(url) {
- url = (url || "").trim();
- var output = {
- protocols: protocols(url),
- protocol: null,
- port: null,
- resource: "",
- user: "",
- pathname: "",
- hash: "",
- search: "",
- href: url,
- query: Object.create(null)
- },
- protocolIndex = url.indexOf("://"),
- resourceIndex = -1,
- splits = null,
- parts = null;
- if (url.startsWith(".")) {
- if (url.startsWith("./")) {
- url = url.substring(2);
- }
- output.pathname = url;
- output.protocol = "file";
- }
- var firstChar = url.charAt(1);
- if (!output.protocol) {
- output.protocol = output.protocols[0];
- if (!output.protocol) {
- if (isSsh(url)) {
- output.protocol = "ssh";
- } else if (firstChar === "/" || firstChar === "~") {
- url = url.substring(2);
- output.protocol = "file";
- } else {
- output.protocol = "file";
- }
- }
- }
- if (protocolIndex !== -1) {
- url = url.substring(protocolIndex + 3);
- }
- parts = url.split(/\/|\\/);
- if (output.protocol !== "file") {
- output.resource = parts.shift();
- } else {
- output.resource = "";
- }
- // user@domain
- splits = output.resource.split("@");
- if (splits.length === 2) {
- output.user = splits[0];
- output.resource = splits[1];
- }
- // domain.com:port
- splits = output.resource.split(":");
- if (splits.length === 2) {
- output.resource = splits[0];
- if (splits[1]) {
- output.port = Number(splits[1]);
- if (isNaN(output.port)) {
- output.port = null;
- parts.unshift(splits[1]);
- }
- } else {
- output.port = null;
- }
- }
- // Remove empty elements
- parts = parts.filter(Boolean);
- // Stringify the pathname
- if (output.protocol === "file") {
- output.pathname = output.href;
- } else {
- output.pathname = output.pathname || (output.protocol !== "file" || output.href[0] === "/" ? "/" : "") + parts.join("/");
- }
- // #some-hash
- splits = output.pathname.split("#");
- if (splits.length === 2) {
- output.pathname = splits[0];
- output.hash = splits[1];
- }
- // ?foo=bar
- splits = output.pathname.split("?");
- if (splits.length === 2) {
- output.pathname = splits[0];
- output.search = splits[1];
- }
- output.query = qs.parse(output.search);
- output.href = output.href.replace(/\/$/, "");
- output.pathname = output.pathname.replace(/\/$/, "");
- return output;
- }
- module.exports = parsePath;
|