UNPKG

6.77 kBJavaScriptView Raw
1'use strict';
2
3var formats = require('./formats');
4
5var has = Object.prototype.hasOwnProperty;
6var isArray = Array.isArray;
7
8var hexTable = (function () {
9 var array = [];
10 for (var i = 0; i < 256; ++i) {
11 array.push('%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase());
12 }
13
14 return array;
15}());
16
17var compactQueue = function compactQueue(queue) {
18 while (queue.length > 1) {
19 var item = queue.pop();
20 var obj = item.obj[item.prop];
21
22 if (isArray(obj)) {
23 var compacted = [];
24
25 for (var j = 0; j < obj.length; ++j) {
26 if (typeof obj[j] !== 'undefined') {
27 compacted.push(obj[j]);
28 }
29 }
30
31 item.obj[item.prop] = compacted;
32 }
33 }
34};
35
36var arrayToObject = function arrayToObject(source, options) {
37 var obj = options && options.plainObjects ? Object.create(null) : {};
38 for (var i = 0; i < source.length; ++i) {
39 if (typeof source[i] !== 'undefined') {
40 obj[i] = source[i];
41 }
42 }
43
44 return obj;
45};
46
47var merge = function merge(target, source, options) {
48 /* eslint no-param-reassign: 0 */
49 if (!source) {
50 return target;
51 }
52
53 if (typeof source !== 'object') {
54 if (isArray(target)) {
55 target.push(source);
56 } else if (target && typeof target === 'object') {
57 if ((options && (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 (!target || typeof target !== 'object') {
68 return [target].concat(source);
69 }
70
71 var mergeTarget = target;
72 if (isArray(target) && !isArray(source)) {
73 mergeTarget = arrayToObject(target, options);
74 }
75
76 if (isArray(target) && isArray(source)) {
77 source.forEach(function (item, i) {
78 if (has.call(target, i)) {
79 var targetItem = target[i];
80 if (targetItem && typeof targetItem === 'object' && item && typeof item === 'object') {
81 target[i] = merge(targetItem, item, options);
82 } else {
83 target.push(item);
84 }
85 } else {
86 target[i] = item;
87 }
88 });
89 return target;
90 }
91
92 return Object.keys(source).reduce(function (acc, key) {
93 var value = source[key];
94
95 if (has.call(acc, key)) {
96 acc[key] = merge(acc[key], value, options);
97 } else {
98 acc[key] = value;
99 }
100 return acc;
101 }, mergeTarget);
102};
103
104var assign = function assignSingleSource(target, source) {
105 return Object.keys(source).reduce(function (acc, key) {
106 acc[key] = source[key];
107 return acc;
108 }, target);
109};
110
111var decode = function (str, decoder, charset) {
112 var strWithoutPlus = str.replace(/\+/g, ' ');
113 if (charset === 'iso-8859-1') {
114 // unescape never throws, no try...catch needed:
115 return strWithoutPlus.replace(/%[0-9a-f]{2}/gi, unescape);
116 }
117 // utf-8
118 try {
119 return decodeURIComponent(strWithoutPlus);
120 } catch (e) {
121 return strWithoutPlus;
122 }
123};
124
125var encode = function encode(str, defaultEncoder, charset, kind, format) {
126 // This code was originally written by Brian White (mscdex) for the io.js core querystring library.
127 // It has been adapted here for stricter adherence to RFC 3986
128 if (str.length === 0) {
129 return str;
130 }
131
132 var string = str;
133 if (typeof str === 'symbol') {
134 string = Symbol.prototype.toString.call(str);
135 } else if (typeof str !== 'string') {
136 string = String(str);
137 }
138
139 if (charset === 'iso-8859-1') {
140 return escape(string).replace(/%u[0-9a-f]{4}/gi, function ($0) {
141 return '%26%23' + parseInt($0.slice(2), 16) + '%3B';
142 });
143 }
144
145 var out = '';
146 for (var i = 0; i < string.length; ++i) {
147 var c = string.charCodeAt(i);
148
149 if (
150 c === 0x2D // -
151 || c === 0x2E // .
152 || c === 0x5F // _
153 || c === 0x7E // ~
154 || (c >= 0x30 && c <= 0x39) // 0-9
155 || (c >= 0x41 && c <= 0x5A) // a-z
156 || (c >= 0x61 && c <= 0x7A) // A-Z
157 || (format === formats.RFC1738 && (c === 0x28 || c === 0x29)) // ( )
158 ) {
159 out += string.charAt(i);
160 continue;
161 }
162
163 if (c < 0x80) {
164 out = out + hexTable[c];
165 continue;
166 }
167
168 if (c < 0x800) {
169 out = out + (hexTable[0xC0 | (c >> 6)] + hexTable[0x80 | (c & 0x3F)]);
170 continue;
171 }
172
173 if (c < 0xD800 || c >= 0xE000) {
174 out = out + (hexTable[0xE0 | (c >> 12)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)]);
175 continue;
176 }
177
178 i += 1;
179 c = 0x10000 + (((c & 0x3FF) << 10) | (string.charCodeAt(i) & 0x3FF));
180 out += hexTable[0xF0 | (c >> 18)]
181 + hexTable[0x80 | ((c >> 12) & 0x3F)]
182 + hexTable[0x80 | ((c >> 6) & 0x3F)]
183 + hexTable[0x80 | (c & 0x3F)];
184 }
185
186 return out;
187};
188
189var compact = function compact(value) {
190 var queue = [{ obj: { o: value }, prop: 'o' }];
191 var refs = [];
192
193 for (var i = 0; i < queue.length; ++i) {
194 var item = queue[i];
195 var obj = item.obj[item.prop];
196
197 var keys = Object.keys(obj);
198 for (var j = 0; j < keys.length; ++j) {
199 var key = keys[j];
200 var val = obj[key];
201 if (typeof val === 'object' && val !== null && refs.indexOf(val) === -1) {
202 queue.push({ obj: obj, prop: key });
203 refs.push(val);
204 }
205 }
206 }
207
208 compactQueue(queue);
209
210 return value;
211};
212
213var isRegExp = function isRegExp(obj) {
214 return Object.prototype.toString.call(obj) === '[object RegExp]';
215};
216
217var isBuffer = function isBuffer(obj) {
218 if (!obj || typeof obj !== 'object') {
219 return false;
220 }
221
222 return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj));
223};
224
225var combine = function combine(a, b) {
226 return [].concat(a, b);
227};
228
229var maybeMap = function maybeMap(val, fn) {
230 if (isArray(val)) {
231 var mapped = [];
232 for (var i = 0; i < val.length; i += 1) {
233 mapped.push(fn(val[i]));
234 }
235 return mapped;
236 }
237 return fn(val);
238};
239
240module.exports = {
241 arrayToObject: arrayToObject,
242 assign: assign,
243 combine: combine,
244 compact: compact,
245 decode: decode,
246 encode: encode,
247 isBuffer: isBuffer,
248 isRegExp: isRegExp,
249 maybeMap: maybeMap,
250 merge: merge
251};