Skip to content

Commit

Permalink
[New] parse/stringify: Pass extra key/value argument to decoder
Browse files Browse the repository at this point in the history
A new fourth argument is now provided when invoking the decoder inside parse,
this argument represents whether the first argument (str) is a key or a value.
This can then be used to decode key and values different within the decode function.

A test has been added for this new behavior.
  • Loading branch information
Chris Dyson authored and ljharb committed Sep 12, 2019
1 parent 4019179 commit 7f216ee
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 7 deletions.
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,30 @@ var decoded = qs.parse('x=z', { decoder: function (str) {
}})
```

You can encode keys and values using different logic by using the type argument provided to the encoder:

```javascript
var encoded = qs.stringify({ a: { b: 'c' } }, { encoder: function (str, defaultEncoder, charset, type) {
if (type === 'key') {
return // Encoded key
} else if (type === 'value') {
return // Encoded value
}
}})
```

The type argument is also provided to the decoder:

```javascript
var decoded = qs.parse('x=z', { decoder: function (str, defaultEncoder, charset, type) {
if (type === 'key') {
return // Decoded key
} else if (type === 'value') {
return // Decoded value
}
}})
```

Examples beyond this point will be shown as though the output is not URI encoded for clarity. Please note that the return values in these cases *will* be URI encoded during real usage.

When arrays are stringified, by default they are given explicit indices:
Expand Down
6 changes: 3 additions & 3 deletions lib/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,11 @@ var parseValues = function parseQueryStringValues(str, options) {

var key, val;
if (pos === -1) {
key = options.decoder(part, defaults.decoder, charset);
key = options.decoder(part, defaults.decoder, charset, 'key');
val = options.strictNullHandling ? null : '';
} else {
key = options.decoder(part.slice(0, pos), defaults.decoder, charset);
val = options.decoder(part.slice(pos + 1), defaults.decoder, charset);
key = options.decoder(part.slice(0, pos), defaults.decoder, charset, 'key');
val = options.decoder(part.slice(pos + 1), defaults.decoder, charset, 'value');
}

if (val && options.interpretNumericEntities && charset === 'iso-8859-1') {
Expand Down
6 changes: 3 additions & 3 deletions lib/stringify.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,16 +80,16 @@ var stringify = function stringify( // eslint-disable-line func-name-matching

if (obj === null) {
if (strictNullHandling) {
return encoder && !encodeValuesOnly ? encoder(prefix, defaults.encoder, charset) : prefix;
return encoder && !encodeValuesOnly ? encoder(prefix, defaults.encoder, charset, 'key') : prefix;
}

obj = '';
}

if (isNonNullishPrimitive(obj) || utils.isBuffer(obj)) {
if (encoder) {
var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder, charset);
return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder, charset))];
var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder, charset, 'key');
return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder, charset, 'value'))];
}
return [formatter(prefix) + '=' + formatter(String(obj))];
}
Expand Down
3 changes: 2 additions & 1 deletion test/.eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
"no-buffer-constructor": 0,
"no-extend-native": 0,
"no-magic-numbers": 0,
"no-throw-literal": 0,
"object-curly-newline": 0,
"sort-keys": 0
"sort-keys": 0,
}
}
15 changes: 15 additions & 0 deletions test/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -686,5 +686,20 @@ test('parse()', function (t) {
st.end();
});

t.test('allows for decoding keys and values differently', function (st) {
var decoder = function (str, defaultDecoder, charset, type) {
if (type === 'key') {
return defaultDecoder(str, defaultDecoder, charset, type).toLowerCase();
}
if (type === 'value') {
return defaultDecoder(str, defaultDecoder, charset, type).toUpperCase();
}
throw 'this should never happen! type: ' + type;
};

st.deepEqual(qs.parse('KeY=vAlUe', { decoder: decoder }), { key: 'VALUE' });
st.end();
});

t.end();
});
15 changes: 15 additions & 0 deletions test/stringify.js
Original file line number Diff line number Diff line change
Expand Up @@ -719,5 +719,20 @@ test('stringify()', function (t) {
st.end();
});

t.test('allows for encoding keys and values differently', function (st) {
var encoder = function (str, defaultEncoder, charset, type) {
if (type === 'key') {
return defaultEncoder(str, defaultEncoder, charset, type).toLowerCase();
}
if (type === 'value') {
return defaultEncoder(str, defaultEncoder, charset, type).toUpperCase();
}
throw 'this should never happen! type: ' + type;
};

st.deepEqual(qs.stringify({ KeY: 'vAlUe' }, { encoder: encoder }), 'key=VALUE');
st.end();
});

t.end();
});

0 comments on commit 7f216ee

Please sign in to comment.