3 var Utils = require('./utils');
5 var arrayPrefixGenerators = {
6 brackets: function brackets(prefix) {
9 indices: function indices(prefix, key) {
10 return prefix + '[' + key + ']';
12 repeat: function repeat(prefix) {
19 strictNullHandling: false,
25 var stringify = function stringify(object, prefix, generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots) {
27 if (typeof filter === 'function') {
28 obj = filter(prefix, obj);
29 } else if (obj instanceof Date) {
30 obj = obj.toISOString();
31 } else if (obj === null) {
32 if (strictNullHandling) {
33 return encoder ? encoder(prefix) : prefix;
39 if (typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean' || Utils.isBuffer(obj)) {
41 return [encoder(prefix) + '=' + encoder(obj)];
43 return [prefix + '=' + String(obj)];
48 if (typeof obj === 'undefined') {
53 if (Array.isArray(filter)) {
56 var keys = Object.keys(obj);
57 objKeys = sort ? keys.sort(sort) : keys;
60 for (var i = 0; i < objKeys.length; ++i) {
63 if (skipNulls && obj[key] === null) {
67 if (Array.isArray(obj)) {
68 values = values.concat(stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots));
70 values = values.concat(stringify(obj[key], prefix + (allowDots ? '.' + key : '[' + key + ']'), generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots));
77 module.exports = function (object, opts) {
79 var options = opts || {};
80 var delimiter = typeof options.delimiter === 'undefined' ? defaults.delimiter : options.delimiter;
81 var strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : defaults.strictNullHandling;
82 var skipNulls = typeof options.skipNulls === 'boolean' ? options.skipNulls : defaults.skipNulls;
83 var encode = typeof options.encode === 'boolean' ? options.encode : defaults.encode;
84 var encoder = encode ? (typeof options.encoder === 'function' ? options.encoder : defaults.encoder) : null;
85 var sort = typeof options.sort === 'function' ? options.sort : null;
86 var allowDots = typeof options.allowDots === 'undefined' ? false : options.allowDots;
90 if (options.encoder !== null && options.encoder !== undefined && typeof options.encoder !== 'function') {
91 throw new TypeError('Encoder has to be a function.');
94 if (typeof options.filter === 'function') {
95 filter = options.filter;
96 obj = filter('', obj);
97 } else if (Array.isArray(options.filter)) {
98 objKeys = filter = options.filter;
103 if (typeof obj !== 'object' || obj === null) {
108 if (options.arrayFormat in arrayPrefixGenerators) {
109 arrayFormat = options.arrayFormat;
110 } else if ('indices' in options) {
111 arrayFormat = options.indices ? 'indices' : 'repeat';
113 arrayFormat = 'indices';
116 var generateArrayPrefix = arrayPrefixGenerators[arrayFormat];
119 objKeys = Object.keys(obj);
126 for (var i = 0; i < objKeys.length; ++i) {
127 var key = objKeys[i];
129 if (skipNulls && obj[key] === null) {
133 keys = keys.concat(stringify(obj[key], key, generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots));
136 return keys.join(delimiter);