3 var utils = require('./utils');
4 var formats = require('./formats');
6 var arrayPrefixGenerators = {
7 brackets: function brackets(prefix) { // eslint-disable-line func-name-matching
10 indices: function indices(prefix, key) { // eslint-disable-line func-name-matching
11 return prefix + '[' + key + ']';
13 repeat: function repeat(prefix) { // eslint-disable-line func-name-matching
18 var toISO = Date.prototype.toISOString;
23 encoder: utils.encode,
24 serializeDate: function serializeDate(date) { // eslint-disable-line func-name-matching
25 return toISO.call(date);
28 strictNullHandling: false
31 var stringify = function stringify( // eslint-disable-line func-name-matching
45 if (typeof filter === 'function') {
46 obj = filter(prefix, obj);
47 } else if (obj instanceof Date) {
48 obj = serializeDate(obj);
49 } else if (obj === null) {
50 if (strictNullHandling) {
51 return encoder ? encoder(prefix) : prefix;
57 if (typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean' || utils.isBuffer(obj)) {
59 return [formatter(encoder(prefix)) + '=' + formatter(encoder(obj))];
61 return [formatter(prefix) + '=' + formatter(String(obj))];
66 if (typeof obj === 'undefined') {
71 if (Array.isArray(filter)) {
74 var keys = Object.keys(obj);
75 objKeys = sort ? keys.sort(sort) : keys;
78 for (var i = 0; i < objKeys.length; ++i) {
81 if (skipNulls && obj[key] === null) {
85 if (Array.isArray(obj)) {
86 values = values.concat(stringify(
88 generateArrayPrefix(prefix, key),
100 values = values.concat(stringify(
102 prefix + (allowDots ? '.' + key : '[' + key + ']'),
119 module.exports = function (object, opts) {
121 var options = opts || {};
123 if (options.encoder !== null && options.encoder !== undefined && typeof options.encoder !== 'function') {
124 throw new TypeError('Encoder has to be a function.');
127 var delimiter = typeof options.delimiter === 'undefined' ? defaults.delimiter : options.delimiter;
128 var strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : defaults.strictNullHandling;
129 var skipNulls = typeof options.skipNulls === 'boolean' ? options.skipNulls : defaults.skipNulls;
130 var encode = typeof options.encode === 'boolean' ? options.encode : defaults.encode;
131 var encoder = encode ? (typeof options.encoder === 'function' ? options.encoder : defaults.encoder) : null;
132 var sort = typeof options.sort === 'function' ? options.sort : null;
133 var allowDots = typeof options.allowDots === 'undefined' ? false : options.allowDots;
134 var serializeDate = typeof options.serializeDate === 'function' ? options.serializeDate : defaults.serializeDate;
135 if (typeof options.format === 'undefined') {
136 options.format = formats.default;
137 } else if (!Object.prototype.hasOwnProperty.call(formats.formatters, options.format)) {
138 throw new TypeError('Unknown format option provided.');
140 var formatter = formats.formatters[options.format];
144 if (typeof options.filter === 'function') {
145 filter = options.filter;
146 obj = filter('', obj);
147 } else if (Array.isArray(options.filter)) {
148 filter = options.filter;
154 if (typeof obj !== 'object' || obj === null) {
159 if (options.arrayFormat in arrayPrefixGenerators) {
160 arrayFormat = options.arrayFormat;
161 } else if ('indices' in options) {
162 arrayFormat = options.indices ? 'indices' : 'repeat';
164 arrayFormat = 'indices';
167 var generateArrayPrefix = arrayPrefixGenerators[arrayFormat];
170 objKeys = Object.keys(obj);
177 for (var i = 0; i < objKeys.length; ++i) {
178 var key = objKeys[i];
180 if (skipNulls && obj[key] === null) {
184 keys = keys.concat(stringify(
199 return keys.join(delimiter);