'use strict'; var has = Object.prototype.hasOwnProperty , undef; /** * Decode a URI encoded string. * * @param {String} input The URI encoded string. * @returns {String} The decoded string. * @api private */ function decode(input) { return decodeURIComponent(input.replace(/\+/g, ' ')); } /** * Simple query string parser. * * @param {String} query The query string that needs to be parsed. * @returns {Object} * @api public */ function querystring(query) { var parser = /([^=?&]+)=?([^&]*)/g , result = {} , part; while (part = parser.exec(query)) { var key = decode(part[1]) , value = decode(part[2]); // // Prevent overriding of existing properties. This ensures that build-in // methods like `toString` or __proto__ are not overriden by malicious // querystrings. // if (key in result) continue; result[key] = value; } return result; } /** * Transform a query string to an object. * * @param {Object} obj Object that should be transformed. * @param {String} prefix Optional prefix. * @returns {String} * @api public */ function querystringify(obj, prefix) { prefix = prefix || ''; var pairs = [] , value , key; // // Optionally prefix with a '?' if needed // if ('string' !== typeof prefix) prefix = '?'; for (key in obj) { if (has.call(obj, key)) { value = obj[key]; // // Edge cases where we actually want to encode the value to an empty // string instead of the stringified value. // if (!value && (value === null || value === undef || isNaN(value))) { value = ''; } pairs.push(encodeURIComponent(key) +'='+ encodeURIComponent(value)); } } return pairs.length ? prefix + pairs.join('&') : ''; } // // Expose the module. // exports.stringify = querystringify; exports.parse = querystring;