Skip to content

Commit 7f216ee

Browse files
Chris Dysonljharb
authored andcommitted
[New] parse/stringify: Pass extra key/value argument to decoder
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.
1 parent 4019179 commit 7f216ee

File tree

6 files changed

+62
-7
lines changed

6 files changed

+62
-7
lines changed

README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,30 @@ var decoded = qs.parse('x=z', { decoder: function (str) {
330330
}})
331331
```
332332

333+
You can encode keys and values using different logic by using the type argument provided to the encoder:
334+
335+
```javascript
336+
var encoded = qs.stringify({ a: { b: 'c' } }, { encoder: function (str, defaultEncoder, charset, type) {
337+
if (type === 'key') {
338+
return // Encoded key
339+
} else if (type === 'value') {
340+
return // Encoded value
341+
}
342+
}})
343+
```
344+
345+
The type argument is also provided to the decoder:
346+
347+
```javascript
348+
var decoded = qs.parse('x=z', { decoder: function (str, defaultEncoder, charset, type) {
349+
if (type === 'key') {
350+
return // Decoded key
351+
} else if (type === 'value') {
352+
return // Decoded value
353+
}
354+
}})
355+
```
356+
333357
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.
334358

335359
When arrays are stringified, by default they are given explicit indices:

lib/parse.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,11 @@ var parseValues = function parseQueryStringValues(str, options) {
7272

7373
var key, val;
7474
if (pos === -1) {
75-
key = options.decoder(part, defaults.decoder, charset);
75+
key = options.decoder(part, defaults.decoder, charset, 'key');
7676
val = options.strictNullHandling ? null : '';
7777
} else {
78-
key = options.decoder(part.slice(0, pos), defaults.decoder, charset);
79-
val = options.decoder(part.slice(pos + 1), defaults.decoder, charset);
78+
key = options.decoder(part.slice(0, pos), defaults.decoder, charset, 'key');
79+
val = options.decoder(part.slice(pos + 1), defaults.decoder, charset, 'value');
8080
}
8181

8282
if (val && options.interpretNumericEntities && charset === 'iso-8859-1') {

lib/stringify.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,16 +80,16 @@ var stringify = function stringify( // eslint-disable-line func-name-matching
8080

8181
if (obj === null) {
8282
if (strictNullHandling) {
83-
return encoder && !encodeValuesOnly ? encoder(prefix, defaults.encoder, charset) : prefix;
83+
return encoder && !encodeValuesOnly ? encoder(prefix, defaults.encoder, charset, 'key') : prefix;
8484
}
8585

8686
obj = '';
8787
}
8888

8989
if (isNonNullishPrimitive(obj) || utils.isBuffer(obj)) {
9090
if (encoder) {
91-
var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder, charset);
92-
return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder, charset))];
91+
var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder, charset, 'key');
92+
return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder, charset, 'value'))];
9393
}
9494
return [formatter(prefix) + '=' + formatter(String(obj))];
9595
}

test/.eslintrc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
"no-buffer-constructor": 0,
1212
"no-extend-native": 0,
1313
"no-magic-numbers": 0,
14+
"no-throw-literal": 0,
1415
"object-curly-newline": 0,
15-
"sort-keys": 0
16+
"sort-keys": 0,
1617
}
1718
}

test/parse.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,5 +686,20 @@ test('parse()', function (t) {
686686
st.end();
687687
});
688688

689+
t.test('allows for decoding keys and values differently', function (st) {
690+
var decoder = function (str, defaultDecoder, charset, type) {
691+
if (type === 'key') {
692+
return defaultDecoder(str, defaultDecoder, charset, type).toLowerCase();
693+
}
694+
if (type === 'value') {
695+
return defaultDecoder(str, defaultDecoder, charset, type).toUpperCase();
696+
}
697+
throw 'this should never happen! type: ' + type;
698+
};
699+
700+
st.deepEqual(qs.parse('KeY=vAlUe', { decoder: decoder }), { key: 'VALUE' });
701+
st.end();
702+
});
703+
689704
t.end();
690705
});

test/stringify.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -719,5 +719,20 @@ test('stringify()', function (t) {
719719
st.end();
720720
});
721721

722+
t.test('allows for encoding keys and values differently', function (st) {
723+
var encoder = function (str, defaultEncoder, charset, type) {
724+
if (type === 'key') {
725+
return defaultEncoder(str, defaultEncoder, charset, type).toLowerCase();
726+
}
727+
if (type === 'value') {
728+
return defaultEncoder(str, defaultEncoder, charset, type).toUpperCase();
729+
}
730+
throw 'this should never happen! type: ' + type;
731+
};
732+
733+
st.deepEqual(qs.stringify({ KeY: 'vAlUe' }, { encoder: encoder }), 'key=VALUE');
734+
st.end();
735+
});
736+
722737
t.end();
723738
});

0 commit comments

Comments
 (0)