feat: Add strict parsing mode as the default - #4
Merged
Conversation
Add a strict option to parseUrlSearchParams, defaulting to true. In strict mode, only the expected output of @seamapi/url-search-params-serializer is parsed, making the parser a true inverse of the serializer: arrays use only the repeated format, array values may contain commas and are never split, the bracket format throws UnparseableSearchParamError, only the strings true and false parse as booleans, and whitespace is never trimmed or treated as empty. Pass strict: false for generous parsing, which preserves the previous behavior: comma and bracket array formats, generous boolean values, and whitespace trimming, at the cost of array values not containing commas. BREAKING CHANGE: Generous parsing is no longer the default; pass strict: false to parseUrlSearchParams to keep the previous behavior. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015jWzL9LC7Q6bTGaXDoKq4z
In strict mode there is no bracket array format: since the serializer never outputs foo[]= for an array named foo, a param named foo[] is unrelated to foo and is parsed as a param literally named "foo[]". The same applies to record keys ending in [], which are literal keys in strict mode. Previously strict mode threw UnparseableSearchParamError for the bracket format. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015jWzL9LC7Q6bTGaXDoKq4z
razor-x
marked this pull request as ready for review
August 5, 2026 22:08
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.
Summary
Follow-up to #3 (Zod v3/v4 support, released as
0.2.0). Adds astrictoption toparseUrlSearchParams, defaulting totrue. Strict mode parses only the expected output of @seamapi/url-search-params-serializer, making the parser a perfect inverse of the serializer. Generous parsing (the previous behavior) moves behindstrict: false, isolating its extra input formats and their limitations.Needed by seamapi/nextlove#182, which uses
strict: falseto keep accepting all array formats.Strict mode (
strict: true, the default)Perfectly aligned with the serializer — only its output format is parsed:
foo=a&foo=b(plusfoo=for the empty array).foo=a,b&foo=cparses as['a,b', 'c']. The serializer can emit such values, so strict mode round-trips them; the "no commas in array values" limitation now only applies to generous mode.foo[]=afor an array namedfoo, a param namedfoo[]is unrelated tofoo: it parses as a param literally namedfoo[](which the serializer produces for a key of that name, so it round-trips). The same applies to record keys ending in[]— literal keys in strict mode.true/false.null/ the empty array.New bijection tests cover the previously non-invertible cases: array values containing commas, and params literally named with a bracket suffix.
Generous mode (
strict: false)Preserves the previous behavior: comma (
foo=a,b) and bracket (foo[]=a) array formats, generous booleans (yes,1,NO, …), and whitespace trimming/null handling — at the cost of array values not containing commas.Unchanged in both modes: unparseable values pass through as strings for the schema to reject, empty
z.string()isnull, unknown params are ignored, and the ambiguity errors for repeated non-array params, mixed empty array values, and conflicting nested params.Usage
Testing
166 tests pass: the existing suite (updated to pass
strict: falsewhere it exercises generous parsing), a newtest/strict-parsing.test.ts(including literalfoo[]params), and the Zod v4 suite updated for both modes. The README now documents Strict Parsing, Generous Parsing, and the rules shared by both.Breaking change
Generous parsing is no longer the default: pass
strict: falseto keep the previous behavior.Semantic-release: publishes as
0.3.0(0.x minor bump for the breakingfeat!).Generated by Claude Code