all files / src/ index.js

98.41% Statements 62/63
97.22% Branches 35/36
100% Functions 5/5
98.41% Lines 62/63
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113      108× 99×           18× 17×         18×     18× 18× 12× 10×     18× 18×   18× 18× 10× 10×       18× 18×     18×   18× 15× 15×         18×   18× 18× 12× 12×       18×   18× 18× 18× 18× 18× 15× 15×   15×         18×   17×     18× 36× 36×   18× 18× 18×   18× 15× 15×   18×   18×           18×    
'use strict';
var buildUrl = require('build-url');
 
function emptySubstrFind(str, from, find) {
 
  if(!str.slice(from)) {
    return -1;
  }else return str.slice(from).indexOf(find);
 
}
 
// module.exports = function({urlString, config}) {
module.exports = function(urlString) {
 
  if(!urlString) {
    urlString = "";
  } else Iif (urlString.constructor != String) {
    // cannot write test for this case, help appreciated
    return urlString;
  }
 
  let url = {};
  // handle google.com?q=data => google.com/?q=data
  // browser does this by default
  let onlyquestion = emptySubstrFind(urlString, 0, '?');
  if(onlyquestion !== -1) {
    if(onlyquestion !== 0 && urlString[onlyquestion-1] !== '/') {
      urlString = urlString.substr(0, onlyquestion) + '/' + urlString.slice(onlyquestion);
    }
  }
  url.href = urlString;
  let index = 0;
 
  let proto = emptySubstrFind(urlString, 0, '://');
  if(proto !== -1) {
    url.protocol = urlString.substr(0, proto);
    index = proto + 3;
  } else {
    url.protocol = "";
  }
 
  let firstcolon = emptySubstrFind(urlString, index, ':');
  let firstdot = emptySubstrFind(urlString, index, '.');
  // need google.com, youtu.be, etc
  // checks for internet address, localhost
  let hostindex = emptySubstrFind(urlString, index, '/');
  // if(hostindex !== -1 && (firstdot !== -1 || firstcolon !== -1)) {
  if(hostindex !== -1) {
    url.host = urlString.substr(index, hostindex);
    index += hostindex + 1;
  } else {
    // till the very end
    url.host = urlString.slice(index);
    index = urlString.length;
  }
  // remove unnecessary trailing /
  url.baseurl = (urlString[index-1] === '/')? urlString.substr(0, index-1): urlString.substr(0, index);
 
  let question = emptySubstrFind(urlString, index, '?');
  if(question !== -1) {
    url.path = urlString.substr(index, question);
    index += question + 1;
  } else {
    url.path = urlString.slice(index);
    index = urlString.length;
  }
  // remove unnecessary trailing /
  url.path = (url.path.substr(-1) === '/') ? url.path.slice(0, -1) : url.path;
 
  let hash = urlString.slice(index)? urlString.slice(index).lastIndexOf('#'): -1;
  url.query = (hash === -1) ? urlString.slice(index) : urlString.substr(index, hash);
  let queryBreak = url.query ? url.query.split('&'): [];
  url.queryParams = {};
  queryBreak.forEach(function(attribute) {
    let split = attribute.split('=');
    try {
      // refered to as q={}
      url.queryParams[split[0]] = JSON.parse(decodeURIComponent(split[1].replace('/','')));
    } catch(e) {
      url.queryParams[split[0]] = split[1];  
    }
  });
 
  if(hash !== -1) {
    url.hash = urlString.substr(index + hash + 1);
  } else {
    url.hash = null;
  }
 
  url.getBaseurl = function() {
    this.baseurl = (this.protocol !== '') ? this.protocol + '://' + this.host : this.host;
    return this.baseurl;
  };
  url.toString = function() {
    this.baseurl = this.getBaseurl();
    let params = {};
    // in case some parameter has array, refered as q=[{}]
    for(let key in this.queryParams) {
      let value = this.queryParams[key];
      params[key] = (typeof value !== 'string')? JSON.stringify(value) : value;
    }
    if(JSON.stringify(params) === '{}') {
      params = null;
    }
    return buildUrl(this.baseurl, {
      path: this.path,
      hash: this.hash,
      queryParams: params
    });
  };
  return url;
};