• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2
3var has = Object.prototype.hasOwnProperty;
4
5var hexTable = (function () {
6    var array = [];
7    for (var i = 0; i < 256; ++i) {
8        array.push('%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase());
9    }
10
11    return array;
12}());
13
14var compactQueue = function compactQueue(queue) {
15    var obj;
16
17    while (queue.length) {
18        var item = queue.pop();
19        obj = item.obj[item.prop];
20
21        if (Array.isArray(obj)) {
22            var compacted = [];
23
24            for (var j = 0; j < obj.length; ++j) {
25                if (typeof obj[j] !== 'undefined') {
26                    compacted.push(obj[j]);
27                }
28            }
29
30            item.obj[item.prop] = compacted;
31        }
32    }
33
34    return obj;
35};
36
37var arrayToObject = function arrayToObject(source, options) {
38    var obj = options && options.plainObjects ? Object.create(null) : {};
39    for (var i = 0; i < source.length; ++i) {
40        if (typeof source[i] !== 'undefined') {
41            obj[i] = source[i];
42        }
43    }
44
45    return obj;
46};
47
48var merge = function merge(target, source, options) {
49    if (!source) {
50        return target;
51    }
52
53    if (typeof source !== 'object') {
54        if (Array.isArray(target)) {
55            target.push(source);
56        } else if (typeof target === 'object') {
57            if (options.plainObjects || options.allowPrototypes || !has.call(Object.prototype, source)) {
58                target[source] = true;
59            }
60        } else {
61            return [target, source];
62        }
63
64        return target;
65    }
66
67    if (typeof target !== 'object') {
68        return [target].concat(source);
69    }
70
71    var mergeTarget = target;
72    if (Array.isArray(target) && !Array.isArray(source)) {
73        mergeTarget = arrayToObject(target, options);
74    }
75
76    if (Array.isArray(target) && Array.isArray(source)) {
77        source.forEach(function (item, i) {
78            if (has.call(target, i)) {
79                if (target[i] && typeof target[i] === 'object') {
80                    target[i] = merge(target[i], item, options);
81                } else {
82                    target.push(item);
83                }
84            } else {
85                target[i] = item;
86            }
87        });
88        return target;
89    }
90
91    return Object.keys(source).reduce(function (acc, key) {
92        var value = source[key];
93
94        if (has.call(acc, key)) {
95            acc[key] = merge(acc[key], value, options);
96        } else {
97            acc[key] = value;
98        }
99        return acc;
100    }, mergeTarget);
101};
102
103var assign = function assignSingleSource(target, source) {
104    return Object.keys(source).reduce(function (acc, key) {
105        acc[key] = source[key];
106        return acc;
107    }, target);
108};
109
110var decode = function (str) {
111    try {
112        return decodeURIComponent(str.replace(/\+/g, ' '));
113    } catch (e) {
114        return str;
115    }
116};
117
118var encode = function encode(str) {
119    // This code was originally written by Brian White (mscdex) for the io.js core querystring library.
120    // It has been adapted here for stricter adherence to RFC 3986
121    if (str.length === 0) {
122        return str;
123    }
124
125    var string = typeof str === 'string' ? str : String(str);
126
127    var out = '';
128    for (var i = 0; i < string.length; ++i) {
129        var c = string.charCodeAt(i);
130
131        if (
132            c === 0x2D // -
133            || c === 0x2E // .
134            || c === 0x5F // _
135            || c === 0x7E // ~
136            || (c >= 0x30 && c <= 0x39) // 0-9
137            || (c >= 0x41 && c <= 0x5A) // a-z
138            || (c >= 0x61 && c <= 0x7A) // A-Z
139        ) {
140            out += string.charAt(i);
141            continue;
142        }
143
144        if (c < 0x80) {
145            out = out + hexTable[c];
146            continue;
147        }
148
149        if (c < 0x800) {
150            out = out + (hexTable[0xC0 | (c >> 6)] + hexTable[0x80 | (c & 0x3F)]);
151            continue;
152        }
153
154        if (c < 0xD800 || c >= 0xE000) {
155            out = out + (hexTable[0xE0 | (c >> 12)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)]);
156            continue;
157        }
158
159        i += 1;
160        c = 0x10000 + (((c & 0x3FF) << 10) | (string.charCodeAt(i) & 0x3FF));
161        out += hexTable[0xF0 | (c >> 18)]
162            + hexTable[0x80 | ((c >> 12) & 0x3F)]
163            + hexTable[0x80 | ((c >> 6) & 0x3F)]
164            + hexTable[0x80 | (c & 0x3F)];
165    }
166
167    return out;
168};
169
170var compact = function compact(value) {
171    var queue = [{ obj: { o: value }, prop: 'o' }];
172    var refs = [];
173
174    for (var i = 0; i < queue.length; ++i) {
175        var item = queue[i];
176        var obj = item.obj[item.prop];
177
178        var keys = Object.keys(obj);
179        for (var j = 0; j < keys.length; ++j) {
180            var key = keys[j];
181            var val = obj[key];
182            if (typeof val === 'object' && val !== null && refs.indexOf(val) === -1) {
183                queue.push({ obj: obj, prop: key });
184                refs.push(val);
185            }
186        }
187    }
188
189    return compactQueue(queue);
190};
191
192var isRegExp = function isRegExp(obj) {
193    return Object.prototype.toString.call(obj) === '[object RegExp]';
194};
195
196var isBuffer = function isBuffer(obj) {
197    if (obj === null || typeof obj === 'undefined') {
198        return false;
199    }
200
201    return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj));
202};
203
204module.exports = {
205    arrayToObject: arrayToObject,
206    assign: assign,
207    compact: compact,
208    decode: decode,
209    encode: encode,
210    isBuffer: isBuffer,
211    isRegExp: isRegExp,
212    merge: merge
213};
214