twitst4tz

twitter statistics web application
Log | Files | Refs | README | LICENSE

stringify.js (6288B)


      1 'use strict';
      2 
      3 var utils = require('./utils');
      4 var formats = require('./formats');
      5 
      6 var arrayPrefixGenerators = {
      7     brackets: function brackets(prefix) { // eslint-disable-line func-name-matching
      8         return prefix + '[]';
      9     },
     10     indices: function indices(prefix, key) { // eslint-disable-line func-name-matching
     11         return prefix + '[' + key + ']';
     12     },
     13     repeat: function repeat(prefix) { // eslint-disable-line func-name-matching
     14         return prefix;
     15     }
     16 };
     17 
     18 var toISO = Date.prototype.toISOString;
     19 
     20 var defaults = {
     21     delimiter: '&',
     22     encode: true,
     23     encoder: utils.encode,
     24     encodeValuesOnly: false,
     25     serializeDate: function serializeDate(date) { // eslint-disable-line func-name-matching
     26         return toISO.call(date);
     27     },
     28     skipNulls: false,
     29     strictNullHandling: false
     30 };
     31 
     32 var stringify = function stringify( // eslint-disable-line func-name-matching
     33     object,
     34     prefix,
     35     generateArrayPrefix,
     36     strictNullHandling,
     37     skipNulls,
     38     encoder,
     39     filter,
     40     sort,
     41     allowDots,
     42     serializeDate,
     43     formatter,
     44     encodeValuesOnly
     45 ) {
     46     var obj = object;
     47     if (typeof filter === 'function') {
     48         obj = filter(prefix, obj);
     49     } else if (obj instanceof Date) {
     50         obj = serializeDate(obj);
     51     } else if (obj === null) {
     52         if (strictNullHandling) {
     53             return encoder && !encodeValuesOnly ? encoder(prefix, defaults.encoder) : prefix;
     54         }
     55 
     56         obj = '';
     57     }
     58 
     59     if (typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean' || utils.isBuffer(obj)) {
     60         if (encoder) {
     61             var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder);
     62             return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder))];
     63         }
     64         return [formatter(prefix) + '=' + formatter(String(obj))];
     65     }
     66 
     67     var values = [];
     68 
     69     if (typeof obj === 'undefined') {
     70         return values;
     71     }
     72 
     73     var objKeys;
     74     if (Array.isArray(filter)) {
     75         objKeys = filter;
     76     } else {
     77         var keys = Object.keys(obj);
     78         objKeys = sort ? keys.sort(sort) : keys;
     79     }
     80 
     81     for (var i = 0; i < objKeys.length; ++i) {
     82         var key = objKeys[i];
     83 
     84         if (skipNulls && obj[key] === null) {
     85             continue;
     86         }
     87 
     88         if (Array.isArray(obj)) {
     89             values = values.concat(stringify(
     90                 obj[key],
     91                 generateArrayPrefix(prefix, key),
     92                 generateArrayPrefix,
     93                 strictNullHandling,
     94                 skipNulls,
     95                 encoder,
     96                 filter,
     97                 sort,
     98                 allowDots,
     99                 serializeDate,
    100                 formatter,
    101                 encodeValuesOnly
    102             ));
    103         } else {
    104             values = values.concat(stringify(
    105                 obj[key],
    106                 prefix + (allowDots ? '.' + key : '[' + key + ']'),
    107                 generateArrayPrefix,
    108                 strictNullHandling,
    109                 skipNulls,
    110                 encoder,
    111                 filter,
    112                 sort,
    113                 allowDots,
    114                 serializeDate,
    115                 formatter,
    116                 encodeValuesOnly
    117             ));
    118         }
    119     }
    120 
    121     return values;
    122 };
    123 
    124 module.exports = function (object, opts) {
    125     var obj = object;
    126     var options = opts ? utils.assign({}, opts) : {};
    127 
    128     if (options.encoder !== null && options.encoder !== undefined && typeof options.encoder !== 'function') {
    129         throw new TypeError('Encoder has to be a function.');
    130     }
    131 
    132     var delimiter = typeof options.delimiter === 'undefined' ? defaults.delimiter : options.delimiter;
    133     var strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : defaults.strictNullHandling;
    134     var skipNulls = typeof options.skipNulls === 'boolean' ? options.skipNulls : defaults.skipNulls;
    135     var encode = typeof options.encode === 'boolean' ? options.encode : defaults.encode;
    136     var encoder = typeof options.encoder === 'function' ? options.encoder : defaults.encoder;
    137     var sort = typeof options.sort === 'function' ? options.sort : null;
    138     var allowDots = typeof options.allowDots === 'undefined' ? false : options.allowDots;
    139     var serializeDate = typeof options.serializeDate === 'function' ? options.serializeDate : defaults.serializeDate;
    140     var encodeValuesOnly = typeof options.encodeValuesOnly === 'boolean' ? options.encodeValuesOnly : defaults.encodeValuesOnly;
    141     if (typeof options.format === 'undefined') {
    142         options.format = formats['default'];
    143     } else if (!Object.prototype.hasOwnProperty.call(formats.formatters, options.format)) {
    144         throw new TypeError('Unknown format option provided.');
    145     }
    146     var formatter = formats.formatters[options.format];
    147     var objKeys;
    148     var filter;
    149 
    150     if (typeof options.filter === 'function') {
    151         filter = options.filter;
    152         obj = filter('', obj);
    153     } else if (Array.isArray(options.filter)) {
    154         filter = options.filter;
    155         objKeys = filter;
    156     }
    157 
    158     var keys = [];
    159 
    160     if (typeof obj !== 'object' || obj === null) {
    161         return '';
    162     }
    163 
    164     var arrayFormat;
    165     if (options.arrayFormat in arrayPrefixGenerators) {
    166         arrayFormat = options.arrayFormat;
    167     } else if ('indices' in options) {
    168         arrayFormat = options.indices ? 'indices' : 'repeat';
    169     } else {
    170         arrayFormat = 'indices';
    171     }
    172 
    173     var generateArrayPrefix = arrayPrefixGenerators[arrayFormat];
    174 
    175     if (!objKeys) {
    176         objKeys = Object.keys(obj);
    177     }
    178 
    179     if (sort) {
    180         objKeys.sort(sort);
    181     }
    182 
    183     for (var i = 0; i < objKeys.length; ++i) {
    184         var key = objKeys[i];
    185 
    186         if (skipNulls && obj[key] === null) {
    187             continue;
    188         }
    189 
    190         keys = keys.concat(stringify(
    191             obj[key],
    192             key,
    193             generateArrayPrefix,
    194             strictNullHandling,
    195             skipNulls,
    196             encode ? encoder : null,
    197             filter,
    198             sort,
    199             allowDots,
    200             serializeDate,
    201             formatter,
    202             encodeValuesOnly
    203         ));
    204     }
    205 
    206     var joined = keys.join(delimiter);
    207     var prefix = options.addQueryPrefix === true ? '?' : '';
    208 
    209     return joined.length > 0 ? prefix + joined : '';
    210 };