feat: add a form-urlencoded decoder with bracketed nesting - #24
Merged
Conversation
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #23, which adds the
decodehook this fills in.application/x-www-form-urlencodedis a wire format, and not one service's dialect. Stripe, Railsand PHP applications all speak it, all three write nesting the same way, and none of them could be
simulated without a decoder for it. It belongs beside JSON for the same reason JSON is here.
{ "line_items": [{ "price_data": { "unit_amount": "250" }, "quantity": "1" }], "expand": ["customer"] }Decisions
Every leaf stays a string. A form body carries no types, and guessing at them would make
quantity=1andpostcode=01234disagree about what a digit is. The resource's own creationbehaviour converts what it needs, where the target shape is known.
Digits order the entries and do not position them.
a[0],a[5]anda[9]give three elementsand never a sparse array of ten. A real encoder counts from zero, where the two readings agree, and
this needs no cap on how large an index a hostile body may claim.
Four inputs throw a
SyntaxErrorrather than being guessed at.name=a&name=ba=1&a[b]=2awould hold a value and more keys at oncea[][b]=1a[b,[a]That follows the existing rule that decode failures stay loud. A real encoder emits well-formed
keys, so these are hostile or mistaken input, and a simulation quietly corrupted by them would be
worse than one that stops.
The
content-typeheader is ignored. What a body claims to be and what it holds are two facts,and choosing the decoder by hand has already settled the first.
Notes
A
__proto__key lands as an own data property and reaches no prototype, whichObject.fromEntriesgives for free. There is a test pinning it.
The parser is a page of code and should stay one. Sparse arrays, dotted keys and
qscompatibilityflags are each a decision a reader would have to hold in their head, and none is needed to simulate
an API.