/node_modules/express/node_modules/connect/node_modules/qs/test/browser/qs.js

https://bitbucket.org/keithelliott/gittielabs · JavaScript · 351 lines · 187 code · 47 blank · 117 comment · 82 complexity · d38a6e1591e3106a118d946f1cf477a1 MD5 · raw file

  1. /**
  2. * Require the given path.
  3. *
  4. * @param {String} path
  5. * @return {Object} exports
  6. * @api public
  7. */
  8. function require(p, parent){
  9. var path = require.resolve(p)
  10. , mod = require.modules[path];
  11. if (!mod) throw new Error('failed to require "' + p + '" in ' + parent);
  12. if (!mod.exports) {
  13. mod.exports = {};
  14. mod.client = true;
  15. mod.call(mod.exports, mod, mod.exports, require.relative(path));
  16. }
  17. return mod.exports;
  18. }
  19. /**
  20. * Registered modules.
  21. */
  22. require.modules = {};
  23. /**
  24. * Resolve `path`.
  25. *
  26. * @param {String} path
  27. * @return {Object} module
  28. * @api public
  29. */
  30. require.resolve = function(path){
  31. var orig = path
  32. , reg = path + '.js'
  33. , index = path + '/index.js';
  34. return require.modules[reg] && reg
  35. || require.modules[index] && index
  36. || orig;
  37. };
  38. /**
  39. * Register module at `path` with callback `fn`.
  40. *
  41. * @param {String} path
  42. * @param {Function} fn
  43. * @api public
  44. */
  45. require.register = function(path, fn){
  46. require.modules[path] = fn;
  47. };
  48. /**
  49. * Defines and executes anonymous module immediately, while preserving relative
  50. * paths.
  51. *
  52. * @param {String} path
  53. * @param {Function} require ref
  54. * @api public
  55. */
  56. require.exec = function (path, fn) {
  57. fn.call(window, require.relative(path));
  58. };
  59. /**
  60. * Return a require function relative to the `parent` path.
  61. *
  62. * @param {String} parent
  63. * @return {Function}
  64. * @api private
  65. */
  66. require.relative = function(parent) {
  67. return function(p){
  68. if ('.' != p[0]) return require(p);
  69. var path = parent.split('/')
  70. , segs = p.split('/');
  71. path.pop();
  72. for (var i = 0; i < segs.length; i++) {
  73. var seg = segs[i];
  74. if ('..' == seg) path.pop();
  75. else if ('.' != seg) path.push(seg);
  76. }
  77. return require(path.join('/'), parent);
  78. };
  79. };
  80. // component qs: querystring
  81. require.register("querystring", function(module, exports, require){
  82. ;(function(){
  83. /**
  84. * Object#toString() ref for stringify().
  85. */
  86. var toString = Object.prototype.toString;
  87. /**
  88. * Cache non-integer test regexp.
  89. */
  90. var isint = /^[0-9]+$/;
  91. function promote(parent, key) {
  92. if (parent[key].length == 0) return parent[key] = {};
  93. var t = {};
  94. for (var i in parent[key]) t[i] = parent[key][i];
  95. parent[key] = t;
  96. return t;
  97. }
  98. function parse(parts, parent, key, val) {
  99. var part = parts.shift();
  100. // end
  101. if (!part) {
  102. if (Array.isArray(parent[key])) {
  103. parent[key].push(val);
  104. } else if ('object' == typeof parent[key]) {
  105. parent[key] = val;
  106. } else if ('undefined' == typeof parent[key]) {
  107. parent[key] = val;
  108. } else {
  109. parent[key] = [parent[key], val];
  110. }
  111. // array
  112. } else {
  113. var obj = parent[key] = parent[key] || [];
  114. if (']' == part) {
  115. if (Array.isArray(obj)) {
  116. if ('' != val) obj.push(val);
  117. } else if ('object' == typeof obj) {
  118. obj[Object.keys(obj).length] = val;
  119. } else {
  120. obj = parent[key] = [parent[key], val];
  121. }
  122. // prop
  123. } else if (~part.indexOf(']')) {
  124. part = part.substr(0, part.length - 1);
  125. if (!isint.test(part) && Array.isArray(obj)) obj = promote(parent, key);
  126. parse(parts, obj, part, val);
  127. // key
  128. } else {
  129. if (!isint.test(part) && Array.isArray(obj)) obj = promote(parent, key);
  130. parse(parts, obj, part, val);
  131. }
  132. }
  133. }
  134. /**
  135. * Merge parent key/val pair.
  136. */
  137. function merge(parent, key, val){
  138. if (~key.indexOf(']')) {
  139. var parts = key.split('[')
  140. , len = parts.length
  141. , last = len - 1;
  142. parse(parts, parent, 'base', val);
  143. // optimize
  144. } else {
  145. if (!isint.test(key) && Array.isArray(parent.base)) {
  146. var t = {};
  147. for (var k in parent.base) t[k] = parent.base[k];
  148. parent.base = t;
  149. }
  150. set(parent.base, key, val);
  151. }
  152. return parent;
  153. }
  154. /**
  155. * Parse the given obj.
  156. */
  157. function parseObject(obj){
  158. var ret = { base: {} };
  159. Object.keys(obj).forEach(function(name){
  160. merge(ret, name, obj[name]);
  161. });
  162. return ret.base;
  163. }
  164. /**
  165. * Parse the given str.
  166. */
  167. function parseString(str){
  168. return String(str)
  169. .split('&')
  170. .reduce(function(ret, pair){
  171. try{
  172. pair = decodeURIComponent(pair.replace(/\+/g, ' '));
  173. } catch(e) {
  174. // ignore
  175. }
  176. var eql = pair.indexOf('=')
  177. , brace = lastBraceInKey(pair)
  178. , key = pair.substr(0, brace || eql)
  179. , val = pair.substr(brace || eql, pair.length)
  180. , val = val.substr(val.indexOf('=') + 1, val.length);
  181. // ?foo
  182. if ('' == key) key = pair, val = '';
  183. return merge(ret, key, val);
  184. }, { base: {} }).base;
  185. }
  186. /**
  187. * Parse the given query `str` or `obj`, returning an object.
  188. *
  189. * @param {String} str | {Object} obj
  190. * @return {Object}
  191. * @api public
  192. */
  193. exports.parse = function(str){
  194. if (null == str || '' == str) return {};
  195. return 'object' == typeof str
  196. ? parseObject(str)
  197. : parseString(str);
  198. };
  199. /**
  200. * Turn the given `obj` into a query string
  201. *
  202. * @param {Object} obj
  203. * @return {String}
  204. * @api public
  205. */
  206. var stringify = exports.stringify = function(obj, prefix) {
  207. if (Array.isArray(obj)) {
  208. return stringifyArray(obj, prefix);
  209. } else if ('[object Object]' == toString.call(obj)) {
  210. return stringifyObject(obj, prefix);
  211. } else if ('string' == typeof obj) {
  212. return stringifyString(obj, prefix);
  213. } else {
  214. return prefix + '=' + obj;
  215. }
  216. };
  217. /**
  218. * Stringify the given `str`.
  219. *
  220. * @param {String} str
  221. * @param {String} prefix
  222. * @return {String}
  223. * @api private
  224. */
  225. function stringifyString(str, prefix) {
  226. if (!prefix) throw new TypeError('stringify expects an object');
  227. return prefix + '=' + encodeURIComponent(str);
  228. }
  229. /**
  230. * Stringify the given `arr`.
  231. *
  232. * @param {Array} arr
  233. * @param {String} prefix
  234. * @return {String}
  235. * @api private
  236. */
  237. function stringifyArray(arr, prefix) {
  238. var ret = [];
  239. if (!prefix) throw new TypeError('stringify expects an object');
  240. for (var i = 0; i < arr.length; i++) {
  241. ret.push(stringify(arr[i], prefix + '['+i+']'));
  242. }
  243. return ret.join('&');
  244. }
  245. /**
  246. * Stringify the given `obj`.
  247. *
  248. * @param {Object} obj
  249. * @param {String} prefix
  250. * @return {String}
  251. * @api private
  252. */
  253. function stringifyObject(obj, prefix) {
  254. var ret = []
  255. , keys = Object.keys(obj)
  256. , key;
  257. for (var i = 0, len = keys.length; i < len; ++i) {
  258. key = keys[i];
  259. ret.push(stringify(obj[key], prefix
  260. ? prefix + '[' + encodeURIComponent(key) + ']'
  261. : encodeURIComponent(key)));
  262. }
  263. return ret.join('&');
  264. }
  265. /**
  266. * Set `obj`'s `key` to `val` respecting
  267. * the weird and wonderful syntax of a qs,
  268. * where "foo=bar&foo=baz" becomes an array.
  269. *
  270. * @param {Object} obj
  271. * @param {String} key
  272. * @param {String} val
  273. * @api private
  274. */
  275. function set(obj, key, val) {
  276. var v = obj[key];
  277. if (undefined === v) {
  278. obj[key] = val;
  279. } else if (Array.isArray(v)) {
  280. v.push(val);
  281. } else {
  282. obj[key] = [v, val];
  283. }
  284. }
  285. /**
  286. * Locate last brace in `str` within the key.
  287. *
  288. * @param {String} str
  289. * @return {Number}
  290. * @api private
  291. */
  292. function lastBraceInKey(str) {
  293. var len = str.length
  294. , brace
  295. , c;
  296. for (var i = 0; i < len; ++i) {
  297. c = str[i];
  298. if (']' == c) brace = false;
  299. if ('[' == c) brace = true;
  300. if ('=' == c && !brace) return i;
  301. }
  302. }
  303. })();
  304. });