Name: js-handler/node_modules/restify/node_modules/qs/index.js 
1:
/**
2:
 * Object#toString() ref for stringify().
3:
 */
4:
 
5:
var toString = Object.prototype.toString;
6:
 
7:
/**
8:
 * Object#hasOwnProperty ref
9:
 */
10:
 
11:
var hasOwnProperty = Object.prototype.hasOwnProperty;
12:
 
13:
/**
14:
 * Array#indexOf shim.
15:
 */
16:
 
17:
var indexOf = typeof Array.prototype.indexOf === 'function'
18:
  ? function(arr, el) { return arr.indexOf(el); }
19:
  : function(arr, el) {
20:
      for (var i = 0; i < arr.length; i++) {
21:
        if (arr[i] === el) return i;
22:
      }
23:
      return -1;
24:
    };
25:
 
26:
/**
27:
 * Array.isArray shim.
28:
 */
29:
 
30:
var isArray = Array.isArray || function(arr) {
31:
  return toString.call(arr) == '[object Array]';
32:
};
33:
 
34:
/**
35:
 * Object.keys shim.
36:
 */
37:
 
38:
var objectKeys = Object.keys || function(obj) {
39:
  var ret = [];
40:
  for (var key in obj) ret.push(key);
41:
  return ret;
42:
};
43:
 
44:
/**
45:
 * Array#forEach shim.
46:
 */
47:
 
48:
var forEach = typeof Array.prototype.forEach === 'function'
49:
  ? function(arr, fn) { return arr.forEach(fn); }
50:
  : function(arr, fn) {
51:
      for (var i = 0; i < arr.length; i++) fn(arr[i]);
52:
    };
53:
 
54:
/**
55:
 * Array#reduce shim.
56:
 */
57:
 
58:
var reduce = function(arr, fn, initial) {
59:
  if (typeof arr.reduce === 'function') return arr.reduce(fn, initial);
60:
  var res = initial;
61:
  for (var i = 0; i < arr.length; i++) res = fn(res, arr[i]);
62:
  return res;
63:
};
64:
 
65:
/**
66:
 * Create a nullary object if possible
67:
 */
68:
 
69:
function createObject() {
70:
  return Object.create
71:
    ? Object.create(null)
72:
    : {};
73:
}
74:
 
75:
/**
76:
 * Cache non-integer test regexp.
77:
 */
78:
 
79:
var isint = /^[0-9]+$/;
80:
 
81:
function promote(parent, key) {
82:
  if (parent[key].length == 0) return parent[key] = createObject();
83:
  var t = createObject();
84:
  for (var i in parent[key]) t[i] = parent[key][i];
85:
  parent[key] = t;
86:
  return t;
87:
}
88:
 
89:
function parse(parts, parent, key, val) {
90:
  var part = parts.shift();
91:
  // end
92:
  if (!part) {
93:
    if (isArray(parent[key])) {
94:
      parent[key].push(val);
95:
    } else if ('object' == typeof parent[key]) {
96:
      parent[key] = val;
97:
    } else if ('undefined' == typeof parent[key]) {
98:
      parent[key] = val;
99:
    } else {
100:
      parent[key] = [parent[key], val];
101:
    }
102:
    // array
103:
  } else {
104:
    var obj = parent[key] = parent[key] || [];
105:
    if (']' == part) {
106:
      if (isArray(obj)) {
107:
        if ('' != val) obj.push(val);
108:
      } else if ('object' == typeof obj) {
109:
        obj[objectKeys(obj).length] = val;
110:
      } else {
111:
        obj = parent[key] = [parent[key], val];
112:
      }
113:
      // prop
114:
    } else if (~indexOf(part, ']')) {
115:
      part = part.substr(0, part.length - 1);
116:
      if (!isint.test(part) && isArray(obj)) obj = promote(parent, key);
117:
      parse(parts, obj, part, val);
118:
      // key
119:
    } else {
120:
      if (!isint.test(part) && isArray(obj)) obj = promote(parent, key);
121:
      parse(parts, obj, part, val);
122:
    }
123:
  }
124:
}
125:
 
126:
/**
127:
 * Merge parent key/val pair.
128:
 */
129:
 
130:
function merge(parent, key, val){
131:
  if (~indexOf(key, ']')) {
132:
    var parts = key.split('[')
133:
      , len = parts.length
134:
      , last = len - 1;
135:
    parse(parts, parent, 'base', val);
136:
    // optimize
137:
  } else {
138:
    if (!isint.test(key) && isArray(parent.base)) {
139:
      var t = createObject();
140:
      for (var k in parent.base) t[k] = parent.base[k];
141:
      parent.base = t;
142:
    }
143:
    set(parent.base, key, val);
144:
  }
145:
 
146:
  return parent;
147:
}
148:
 
149:
/**
150:
 * Compact sparse arrays.
151:
 */
152:
 
153:
function compact(obj) {
154:
  if ('object' != typeof obj) return obj;
155:
 
156:
  if (isArray(obj)) {
157:
    var ret = [];
158:
    for (var i in obj) ret.push(obj[i]);
159:
    return ret;
160:
  }
161:
 
162:
  for (var key in obj) {
163:
    obj[key] = compact(obj[key]);
164:
  }
165:
 
166:
  return obj;
167:
}
168:
 
169:
/**
170:
 * Restore Object.prototype.
171:
 * see pull-request #58
172:
 */
173:
 
174:
function restoreProto(obj) {
175:
  if (!Object.create) return obj;
176:
  if (isArray(obj)) return obj;
177:
  if (obj && 'object' != typeof obj) return obj;
178:
 
179:
  for (var key in obj) {
180:
    if (hasOwnProperty.call(obj, key)) {
181:
      obj[key] = restoreProto(obj[key]);
182:
    }
183:
  }
184:
 
185:
  obj.__proto__ = Object.prototype;
186:
  return obj;
187:
}
188:
 
189:
/**
190:
 * Parse the given obj.
191:
 */
192:
 
193:
function parseObject(obj){
194:
  var ret = { base: {} };
195:
 
196:
  forEach(objectKeys(obj), function(name){
197:
    merge(ret, name, obj[name]);
198:
  });
199:
 
200:
  return compact(ret.base);
201:
}
202:
 
203:
/**
204:
 * Parse the given str.
205:
 */
206:
 
207:
function parseString(str){
208:
  var ret = reduce(String(str).split('&'), function(ret, pair){
209:
    var eql = indexOf(pair, '=')
210:
      , brace = lastBraceInKey(pair)
211:
      , key = pair.substr(0, brace || eql)
212:
      , val = pair.substr(brace || eql, pair.length)
213:
      , val = val.substr(indexOf(val, '=') + 1, val.length);
214:
 
215:
    // ?foo
216:
    if ('' == key) key = pair, val = '';
217:
    if ('' == key) return ret;
218:
 
219:
    return merge(ret, decode(key), decode(val));
220:
  }, { base: createObject() }).base;
221:
 
222:
  return restoreProto(compact(ret));
223:
}
224:
 
225:
/**
226:
 * Parse the given query `str` or `obj`, returning an object.
227:
 *
228:
 * @param {String} str | {Object} obj
229:
 * @return {Object}
230:
 * @api public
231:
 */
232:
 
233:
exports.parse = function(str){
234:
  if (null == str || '' == str) return {};
235:
  return 'object' == typeof str
236:
    ? parseObject(str)
237:
    : parseString(str);
238:
};
239:
 
240:
/**
241:
 * Turn the given `obj` into a query string
242:
 *
243:
 * @param {Object} obj
244:
 * @return {String}
245:
 * @api public
246:
 */
247:
 
248:
var stringify = exports.stringify = function(obj, prefix) {
249:
  if (isArray(obj)) {
250:
    return stringifyArray(obj, prefix);
251:
  } else if ('[object Object]' == toString.call(obj)) {
252:
    return stringifyObject(obj, prefix);
253:
  } else if ('string' == typeof obj) {
254:
    return stringifyString(obj, prefix);
255:
  } else {
256:
    return prefix + '=' + encodeURIComponent(String(obj));
257:
  }
258:
};
259:
 
260:
/**
261:
 * Stringify the given `str`.
262:
 *
263:
 * @param {String} str
264:
 * @param {String} prefix
265:
 * @return {String}
266:
 * @api private
267:
 */
268:
 
269:
function stringifyString(str, prefix) {
270:
  if (!prefix) throw new TypeError('stringify expects an object');
271:
  return prefix + '=' + encodeURIComponent(str);
272:
}
273:
 
274:
/**
275:
 * Stringify the given `arr`.
276:
 *
277:
 * @param {Array} arr
278:
 * @param {String} prefix
279:
 * @return {String}
280:
 * @api private
281:
 */
282:
 
283:
function stringifyArray(arr, prefix) {
284:
  var ret = [];
285:
  if (!prefix) throw new TypeError('stringify expects an object');
286:
  for (var i = 0; i < arr.length; i++) {
287:
    ret.push(stringify(arr[i], prefix + '[' + i + ']'));
288:
  }
289:
  return ret.join('&');
290:
}
291:
 
292:
/**
293:
 * Stringify the given `obj`.
294:
 *
295:
 * @param {Object} obj
296:
 * @param {String} prefix
297:
 * @return {String}
298:
 * @api private
299:
 */
300:
 
301:
function stringifyObject(obj, prefix) {
302:
  var ret = []
303:
    , keys = objectKeys(obj)
304:
    , key;
305:
 
306:
  for (var i = 0, len = keys.length; i < len; ++i) {
307:
    key = keys[i];
308:
    if ('' == key) continue;
309:
    if (null == obj[key]) {
310:
      ret.push(encodeURIComponent(key) + '=');
311:
    } else {
312:
      ret.push(stringify(obj[key], prefix
313:
        ? prefix + '[' + encodeURIComponent(key) + ']'
314:
        : encodeURIComponent(key)));
315:
    }
316:
  }
317:
 
318:
  return ret.join('&');
319:
}
320:
 
321:
/**
322:
 * Set `obj`'s `key` to `val` respecting
323:
 * the weird and wonderful syntax of a qs,
324:
 * where "foo=bar&foo=baz" becomes an array.
325:
 *
326:
 * @param {Object} obj
327:
 * @param {String} key
328:
 * @param {String} val
329:
 * @api private
330:
 */
331:
 
332:
function set(obj, key, val) {
333:
  var v = obj[key];
334:
  if (undefined === v) {
335:
    obj[key] = val;
336:
  } else if (isArray(v)) {
337:
    v.push(val);
338:
  } else {
339:
    obj[key] = [v, val];
340:
  }
341:
}
342:
 
343:
/**
344:
 * Locate last brace in `str` within the key.
345:
 *
346:
 * @param {String} str
347:
 * @return {Number}
348:
 * @api private
349:
 */
350:
 
351:
function lastBraceInKey(str) {
352:
  var len = str.length
353:
    , brace
354:
    , c;
355:
  for (var i = 0; i < len; ++i) {
356:
    c = str[i];
357:
    if (']' == c) brace = false;
358:
    if ('[' == c) brace = true;
359:
    if ('=' == c && !brace) return i;
360:
  }
361:
}
362:
 
363:
/**
364:
 * Decode `str`.
365:
 *
366:
 * @param {String} str
367:
 * @return {String}
368:
 * @api private
369:
 */
370:
 
371:
function decode(str) {
372:
  try {
373:
    return decodeURIComponent(str.replace(/\+/g, ' '));
374:
  } catch (err) {
375:
    return str;
376:
  }
377:
}