source: frontend/node_modules/qs/lib/utils.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 12 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 10.0 KB
Line 
1'use strict';
2
3var formats = require('./formats');
4var getSideChannel = require('side-channel');
5
6var has = Object.prototype.hasOwnProperty;
7var isArray = Array.isArray;
8
9// Track objects created from arrayLimit overflow using side-channel
10// Stores the current max numeric index for O(1) lookup
11var overflowChannel = getSideChannel();
12
13var markOverflow = function markOverflow(obj, maxIndex) {
14 overflowChannel.set(obj, maxIndex);
15 return obj;
16};
17
18var isOverflow = function isOverflow(obj) {
19 return overflowChannel.has(obj);
20};
21
22var getMaxIndex = function getMaxIndex(obj) {
23 return overflowChannel.get(obj);
24};
25
26var setMaxIndex = function setMaxIndex(obj, maxIndex) {
27 overflowChannel.set(obj, maxIndex);
28};
29
30var hexTable = (function () {
31 var array = [];
32 for (var i = 0; i < 256; ++i) {
33 array[array.length] = '%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase();
34 }
35
36 return array;
37}());
38
39var compactQueue = function compactQueue(queue) {
40 while (queue.length > 1) {
41 var item = queue.pop();
42 var obj = item.obj[item.prop];
43
44 if (isArray(obj)) {
45 var compacted = [];
46
47 for (var j = 0; j < obj.length; ++j) {
48 if (typeof obj[j] !== 'undefined') {
49 compacted[compacted.length] = obj[j];
50 }
51 }
52
53 item.obj[item.prop] = compacted;
54 }
55 }
56};
57
58var arrayToObject = function arrayToObject(source, options) {
59 var obj = options && options.plainObjects ? { __proto__: null } : {};
60 for (var i = 0; i < source.length; ++i) {
61 if (typeof source[i] !== 'undefined') {
62 obj[i] = source[i];
63 }
64 }
65
66 return obj;
67};
68
69var merge = function merge(target, source, options) {
70 /* eslint no-param-reassign: 0 */
71 if (!source) {
72 return target;
73 }
74
75 if (typeof source !== 'object' && typeof source !== 'function') {
76 if (isArray(target)) {
77 var nextIndex = target.length;
78 if (options && typeof options.arrayLimit === 'number' && nextIndex > options.arrayLimit) {
79 return markOverflow(arrayToObject(target.concat(source), options), nextIndex);
80 }
81 target[nextIndex] = source;
82 } else if (target && typeof target === 'object') {
83 if (isOverflow(target)) {
84 // Add at next numeric index for overflow objects
85 var newIndex = getMaxIndex(target) + 1;
86 target[newIndex] = source;
87 setMaxIndex(target, newIndex);
88 } else if (options && options.strictMerge) {
89 return [target, source];
90 } else if (
91 (options && (options.plainObjects || options.allowPrototypes))
92 || !has.call(Object.prototype, source)
93 ) {
94 target[source] = true;
95 }
96 } else {
97 return [target, source];
98 }
99
100 return target;
101 }
102
103 if (!target || typeof target !== 'object') {
104 if (isOverflow(source)) {
105 // Create new object with target at 0, source values shifted by 1
106 var sourceKeys = Object.keys(source);
107 var result = options && options.plainObjects
108 ? { __proto__: null, 0: target }
109 : { 0: target };
110 for (var m = 0; m < sourceKeys.length; m++) {
111 var oldKey = parseInt(sourceKeys[m], 10);
112 result[oldKey + 1] = source[sourceKeys[m]];
113 }
114 return markOverflow(result, getMaxIndex(source) + 1);
115 }
116 var combined = [target].concat(source);
117 if (options && typeof options.arrayLimit === 'number' && combined.length > options.arrayLimit) {
118 return markOverflow(arrayToObject(combined, options), combined.length - 1);
119 }
120 return combined;
121 }
122
123 var mergeTarget = target;
124 if (isArray(target) && !isArray(source)) {
125 mergeTarget = arrayToObject(target, options);
126 }
127
128 if (isArray(target) && isArray(source)) {
129 source.forEach(function (item, i) {
130 if (has.call(target, i)) {
131 var targetItem = target[i];
132 if (targetItem && typeof targetItem === 'object' && item && typeof item === 'object') {
133 target[i] = merge(targetItem, item, options);
134 } else {
135 target[target.length] = item;
136 }
137 } else {
138 target[i] = item;
139 }
140 });
141 return target;
142 }
143
144 return Object.keys(source).reduce(function (acc, key) {
145 var value = source[key];
146
147 if (has.call(acc, key)) {
148 acc[key] = merge(acc[key], value, options);
149 } else {
150 acc[key] = value;
151 }
152
153 if (isOverflow(source) && !isOverflow(acc)) {
154 markOverflow(acc, getMaxIndex(source));
155 }
156 if (isOverflow(acc)) {
157 var keyNum = parseInt(key, 10);
158 if (String(keyNum) === key && keyNum >= 0 && keyNum > getMaxIndex(acc)) {
159 setMaxIndex(acc, keyNum);
160 }
161 }
162
163 return acc;
164 }, mergeTarget);
165};
166
167var assign = function assignSingleSource(target, source) {
168 return Object.keys(source).reduce(function (acc, key) {
169 acc[key] = source[key];
170 return acc;
171 }, target);
172};
173
174var decode = function (str, defaultDecoder, charset) {
175 var strWithoutPlus = str.replace(/\+/g, ' ');
176 if (charset === 'iso-8859-1') {
177 // unescape never throws, no try...catch needed:
178 return strWithoutPlus.replace(/%[0-9a-f]{2}/gi, unescape);
179 }
180 // utf-8
181 try {
182 return decodeURIComponent(strWithoutPlus);
183 } catch (e) {
184 return strWithoutPlus;
185 }
186};
187
188var limit = 1024;
189
190/* eslint operator-linebreak: [2, "before"] */
191
192var encode = function encode(str, defaultEncoder, charset, kind, format) {
193 // This code was originally written by Brian White (mscdex) for the io.js core querystring library.
194 // It has been adapted here for stricter adherence to RFC 3986
195 if (str.length === 0) {
196 return str;
197 }
198
199 var string = str;
200 if (typeof str === 'symbol') {
201 string = Symbol.prototype.toString.call(str);
202 } else if (typeof str !== 'string') {
203 string = String(str);
204 }
205
206 if (charset === 'iso-8859-1') {
207 return escape(string).replace(/%u[0-9a-f]{4}/gi, function ($0) {
208 return '%26%23' + parseInt($0.slice(2), 16) + '%3B';
209 });
210 }
211
212 var out = '';
213 for (var j = 0; j < string.length; j += limit) {
214 var segment = string.length >= limit ? string.slice(j, j + limit) : string;
215 var arr = [];
216
217 for (var i = 0; i < segment.length; ++i) {
218 var c = segment.charCodeAt(i);
219 if (
220 c === 0x2D // -
221 || c === 0x2E // .
222 || c === 0x5F // _
223 || c === 0x7E // ~
224 || (c >= 0x30 && c <= 0x39) // 0-9
225 || (c >= 0x41 && c <= 0x5A) // a-z
226 || (c >= 0x61 && c <= 0x7A) // A-Z
227 || (format === formats.RFC1738 && (c === 0x28 || c === 0x29)) // ( )
228 ) {
229 arr[arr.length] = segment.charAt(i);
230 continue;
231 }
232
233 if (c < 0x80) {
234 arr[arr.length] = hexTable[c];
235 continue;
236 }
237
238 if (c < 0x800) {
239 arr[arr.length] = hexTable[0xC0 | (c >> 6)]
240 + hexTable[0x80 | (c & 0x3F)];
241 continue;
242 }
243
244 if (c < 0xD800 || c >= 0xE000) {
245 arr[arr.length] = hexTable[0xE0 | (c >> 12)]
246 + hexTable[0x80 | ((c >> 6) & 0x3F)]
247 + hexTable[0x80 | (c & 0x3F)];
248 continue;
249 }
250
251 i += 1;
252 c = 0x10000 + (((c & 0x3FF) << 10) | (segment.charCodeAt(i) & 0x3FF));
253
254 arr[arr.length] = hexTable[0xF0 | (c >> 18)]
255 + hexTable[0x80 | ((c >> 12) & 0x3F)]
256 + hexTable[0x80 | ((c >> 6) & 0x3F)]
257 + hexTable[0x80 | (c & 0x3F)];
258 }
259
260 out += arr.join('');
261 }
262
263 return out;
264};
265
266var compact = function compact(value) {
267 var queue = [{ obj: { o: value }, prop: 'o' }];
268 var refs = [];
269
270 for (var i = 0; i < queue.length; ++i) {
271 var item = queue[i];
272 var obj = item.obj[item.prop];
273
274 var keys = Object.keys(obj);
275 for (var j = 0; j < keys.length; ++j) {
276 var key = keys[j];
277 var val = obj[key];
278 if (typeof val === 'object' && val !== null && refs.indexOf(val) === -1) {
279 queue[queue.length] = { obj: obj, prop: key };
280 refs[refs.length] = val;
281 }
282 }
283 }
284
285 compactQueue(queue);
286
287 return value;
288};
289
290var isRegExp = function isRegExp(obj) {
291 return Object.prototype.toString.call(obj) === '[object RegExp]';
292};
293
294var isBuffer = function isBuffer(obj) {
295 if (!obj || typeof obj !== 'object') {
296 return false;
297 }
298
299 return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj));
300};
301
302var combine = function combine(a, b, arrayLimit, plainObjects) {
303 // If 'a' is already an overflow object, add to it
304 if (isOverflow(a)) {
305 var newIndex = getMaxIndex(a) + 1;
306 a[newIndex] = b;
307 setMaxIndex(a, newIndex);
308 return a;
309 }
310
311 var result = [].concat(a, b);
312 if (result.length > arrayLimit) {
313 return markOverflow(arrayToObject(result, { plainObjects: plainObjects }), result.length - 1);
314 }
315 return result;
316};
317
318var maybeMap = function maybeMap(val, fn) {
319 if (isArray(val)) {
320 var mapped = [];
321 for (var i = 0; i < val.length; i += 1) {
322 mapped[mapped.length] = fn(val[i]);
323 }
324 return mapped;
325 }
326 return fn(val);
327};
328
329module.exports = {
330 arrayToObject: arrayToObject,
331 assign: assign,
332 combine: combine,
333 compact: compact,
334 decode: decode,
335 encode: encode,
336 isBuffer: isBuffer,
337 isOverflow: isOverflow,
338 isRegExp: isRegExp,
339 markOverflow: markOverflow,
340 maybeMap: maybeMap,
341 merge: merge
342};
Note: See TracBrowser for help on using the repository browser.