stringify.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // Load modules
  2. var Utils = require('./utils');
  3. // Declare internals
  4. var internals = {
  5. delimiter: '&',
  6. arrayPrefixGenerators: {
  7. brackets: function (prefix, key) {
  8. return prefix + '[]';
  9. },
  10. indices: function (prefix, key) {
  11. return prefix + '[' + key + ']';
  12. },
  13. repeat: function (prefix, key) {
  14. return prefix;
  15. }
  16. },
  17. strictNullHandling: false,
  18. skipNulls: false,
  19. encode: true
  20. };
  21. internals.stringify = function (obj, prefix, generateArrayPrefix, strictNullHandling, skipNulls, encode, filter) {
  22. if (typeof filter === 'function') {
  23. obj = filter(prefix, obj);
  24. }
  25. else if (Utils.isBuffer(obj)) {
  26. obj = obj.toString();
  27. }
  28. else if (obj instanceof Date) {
  29. obj = obj.toISOString();
  30. }
  31. else if (obj === null) {
  32. if (strictNullHandling) {
  33. return encode ? Utils.encode(prefix) : prefix;
  34. }
  35. obj = '';
  36. }
  37. if (typeof obj === 'string' ||
  38. typeof obj === 'number' ||
  39. typeof obj === 'boolean') {
  40. if (encode) {
  41. return [Utils.encode(prefix) + '=' + Utils.encode(obj)];
  42. }
  43. return [prefix + '=' + obj];
  44. }
  45. var values = [];
  46. if (typeof obj === 'undefined') {
  47. return values;
  48. }
  49. var objKeys = Array.isArray(filter) ? filter : Object.keys(obj);
  50. for (var i = 0, il = objKeys.length; i < il; ++i) {
  51. var key = objKeys[i];
  52. if (skipNulls &&
  53. obj[key] === null) {
  54. continue;
  55. }
  56. if (Array.isArray(obj)) {
  57. values = values.concat(internals.stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix, strictNullHandling, skipNulls, encode, filter));
  58. }
  59. else {
  60. values = values.concat(internals.stringify(obj[key], prefix + '[' + key + ']', generateArrayPrefix, strictNullHandling, skipNulls, encode, filter));
  61. }
  62. }
  63. return values;
  64. };
  65. module.exports = function (obj, options) {
  66. options = options || {};
  67. var delimiter = typeof options.delimiter === 'undefined' ? internals.delimiter : options.delimiter;
  68. var strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : internals.strictNullHandling;
  69. var skipNulls = typeof options.skipNulls === 'boolean' ? options.skipNulls : internals.skipNulls;
  70. var encode = typeof options.encode === 'boolean' ? options.encode : internals.encode;
  71. var objKeys;
  72. var filter;
  73. if (typeof options.filter === 'function') {
  74. filter = options.filter;
  75. obj = filter('', obj);
  76. }
  77. else if (Array.isArray(options.filter)) {
  78. objKeys = filter = options.filter;
  79. }
  80. var keys = [];
  81. if (typeof obj !== 'object' ||
  82. obj === null) {
  83. return '';
  84. }
  85. var arrayFormat;
  86. if (options.arrayFormat in internals.arrayPrefixGenerators) {
  87. arrayFormat = options.arrayFormat;
  88. }
  89. else if ('indices' in options) {
  90. arrayFormat = options.indices ? 'indices' : 'repeat';
  91. }
  92. else {
  93. arrayFormat = 'indices';
  94. }
  95. var generateArrayPrefix = internals.arrayPrefixGenerators[arrayFormat];
  96. if (!objKeys) {
  97. objKeys = Object.keys(obj);
  98. }
  99. for (var i = 0, il = objKeys.length; i < il; ++i) {
  100. var key = objKeys[i];
  101. if (skipNulls &&
  102. obj[key] === null) {
  103. continue;
  104. }
  105. keys = keys.concat(internals.stringify(obj[key], key, generateArrayPrefix, strictNullHandling, skipNulls, encode, filter));
  106. }
  107. return keys.join(delimiter);
  108. };