-
-
Notifications
You must be signed in to change notification settings - Fork 732
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
Custom stringify arrays and objects #365
base: main
Are you sure you want to change the base?
Conversation
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.
…, `has-symbols`, `tape`
… treated as normal text Co-authored-by: Mohamed Omar <[email protected]> Co-authored-by: Quentin de Longraye <[email protected]>
Fixes ljharb#311. Followup to ljharb#336.
… arrays and objects with custom function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any changes to stringify
would need to be mirrored in parse
, so things can round trip.
I'm not yet convinced that this complexity is worth adding, but I appreciate you've made it appropriately generic.
I'll think about it now
No problems. I can use fork for myself. |
Maybe something like that? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm confused why there's both an array replacer and an object replacer, since for parse, they both do the same thing.
You may set `objectFormat: 'curly'` to enable curly brackets notation: | ||
|
||
```javascript | ||
var withDots = qs.parse('a{b}=c', { objectFormat: 'curly' }); | ||
assert.deepEqual(withDots, { a: { b: 'c' } }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is an extremely confusing and strange notation i've never seen anywhere else; i'm fine adding a function form so someone can do this themselves, but i'd need a lot of convincing that this format deserves first-class support.
qs.stringify({ a: { b: { c: 'd', e: 'f' } } }, { arrayFormat: 'curly' }); | ||
// 'a{b}{c}=d&a{b}{e}=f' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
similarly here
qs.stringify({ a: { b: { c: 'd', e: 'f' } } }, { arrayFormat: 'curly' }); | |
// 'a{b}{c}=d&a{b}{e}=f' |
var key = givenKey; | ||
if (typeof options.arrayFormat === 'function') { | ||
key = options.arrayFormat(key); | ||
} else if (options.arrayFormat in arrayKeyReplacer) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
} else if (options.arrayFormat in arrayKeyReplacer) { | |
} else if (has.call(arrayKeyReplacer, options.arrayFormat)) { |
} | ||
if (typeof options.objectFormat === 'function') { | ||
key = options.objectFormat(key); | ||
} else if (options.objectFormat in objectKeyReplacer) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
} else if (options.objectFormat in objectKeyReplacer) { | |
} else if (has.call(objectKeyReplacer, options.objectFormat)) { |
curly: function curly(key) { | ||
return key.replace(/\{([^{}[]+)\}/g, '[$1]'); | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
curly: function curly(key) { | |
return key.replace(/\{([^{}[]+)\}/g, '[$1]'); | |
}, |
var generateObjectPrefix; | ||
if (opts && typeof opts.objectFormat === 'function') { | ||
generateObjectPrefix = opts.objectFormat; | ||
} else if (opts && opts.objectFormat in objectPrefixGenerators) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
} else if (opts && opts.objectFormat in objectPrefixGenerators) { | |
} else if (opts && has.call(objectPrefixGenerators, opts.objectFormat)) { |
} else if (opts && opts.allowDots) { | ||
generateObjectPrefix = objectPrefixGenerators.dots; | ||
} else { | ||
generateObjectPrefix = objectPrefixGenerators.brackets; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this seems like it should be handled by the option normalization and the default?
st.deepEqual(qs.parse('a[]=b&a[]=c', { arrayFormat: 'comma' }), { a: ['b', 'c'] }); | ||
st.deepEqual(qs.parse('a[0]=b&a[1]=c', { arrayFormat: 'comma' }), { a: ['b', 'c'] }); | ||
st.deepEqual(qs.parse('a=b,c', { arrayFormat: 'comma' }), { a: 'b,c' }); | ||
st.deepEqual(qs.parse('a=b,c', { arrayFormat: 'comma' }), { a: ['b', 'c'] }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this shouldn't change, or else it's a breaking change
@leninlin are you still interested in completing this PR? |
I added the ability to compile the query string using a custom function for arrays and objects.
I need this to work with the Python REST framework (https://github.com/AltSchool/dynamic-rest):
I added a function with curly brackets to the default list, but custom functions for the future will be useful for such situations.