Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide type argument to encoder/decoder function used by parse/stringify #333

Merged
merged 1 commit into from Sep 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
24 changes: 24 additions & 0 deletions README.md
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
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
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
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
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
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();
});