1 | 1 | 'use strict'; |
2 | | |
3 | | |
4 | 1 | var querystring = require('querystring'); |
5 | | |
6 | | |
7 | | function encoder(key, value) { |
8 | | |
9 | | if (typeof value === 'number') { |
10 | 3 | return ['\\', value].join(''); |
11 | | } |
12 | | |
13 | | if (value === true) { |
14 | 3 | return '\\true'; |
15 | | } |
16 | | if (value === false) { |
17 | 4 | return '\\false'; |
18 | | } |
19 | | if (value === null) { |
20 | 4 | return '\\null'; |
21 | | } |
22 | | if (value === undefined) { |
23 | 4 | return '\\undefined'; |
24 | | } |
25 | | |
26 | 52 | return value; |
27 | | } |
28 | | |
29 | | function decoder(value) { |
30 | 92 | var parsed; |
31 | | |
32 | | if (value === '\\true') { |
33 | 3 | return true; |
34 | | } |
35 | | |
36 | | if (value === '\\false') { |
37 | 4 | return false; |
38 | | } |
39 | | |
40 | | if (value === '\\null') { |
41 | 4 | return null; |
42 | | } |
43 | | |
44 | | if (value === '\\undefined') { |
45 | 4 | return undefined; |
46 | | } |
47 | | |
48 | | if (value.substr(0, 1) === '\\') { |
49 | 4 | parsed = parseFloat(value.substr(1)); |
50 | | if (String(parsed) === value.substr(1)) { |
51 | 4 | return parsed; |
52 | | } |
53 | | } |
54 | | |
55 | 73 | return value; |
56 | | } |
57 | | |
58 | | function passThrough(value) { |
59 | 86 | return value; |
60 | | } |
61 | | |
62 | | |
63 | | function decode(query) { |
64 | 19 | var obj = querystring.decode(query, '&', '=', {decodeURIComponent: decoder}); |
65 | | |
66 | 19 | Object.keys(obj).forEach(function (key) { |
67 | | if (typeof(obj[key]) === 'string' && obj[key].match(/\:/)) { |
68 | 13 | obj[key] = querystring.decode(obj[key], ',', ':', {decodeURIComponent: decoder}); |
69 | | } |
70 | | }); |
71 | | |
72 | 19 | return obj; |
73 | | } |
74 | | |
75 | | |
76 | | function encode(obj) { |
77 | | |
78 | 19 | obj = JSON.parse(JSON.stringify(obj, encoder)); |
79 | | |
80 | 19 | Object.keys(obj).forEach(function (key) { |
81 | | if (obj[key] !== null && typeof obj[key] === 'object') { |
82 | | |
83 | 14 | Object.keys(obj[key]).forEach(function (key2) { |
84 | | if (obj[key][key2] !== null && typeof obj[key][key2] === 'object') { |
85 | 2 | throw new Error('Maximum allowed object depth is 2'); |
86 | | } |
87 | | }); |
88 | | |
89 | 12 | obj[key] = querystring.stringify(obj[key], ',', ':', {encodeURIComponent: passThrough}); |
90 | | } |
91 | | }); |
92 | | |
93 | 17 | return querystring.stringify(obj, '&', '=', {encodeURIComponent: passThrough}); |
94 | | |
95 | | } |
96 | | |
97 | 1 | exports.decode = decode; |
98 | 1 | exports.encode = encode; |
99 | | |