feat: 1.1.0 compat shim — qs-backed deparam, original param#4
Merged
Conversation
added 2 commits
May 20, 2026 10:45
Phase 2 of the modernization plan. The library now delegates parsing to
qs (currently 6.15.2) while keeping the original jQuery-traditional
stringify implementation untouched. All 58 conformance cases stay green;
the only API change vs 1.0.0 is the optional maxDepth parameter
introduced in 1.0.0 (already documented).
Architecture:
- lib/param.js: unchanged from the 2014 implementation. Pure ES5, zero
deps, no attack surface. Comments stripped (no functional change).
- lib/deparam.js: rewritten as a qs.parse wrapper with three local
protections layered on top:
- safeDecoder: ISO-8859 fallback via unescape() when decodeURIComponent
rejects malformed UTF-8. Load-bearing for legacy Latin-1 query
strings flowing through to Elasticsearch with accent preservation.
- preFilter: per-parameter rejection of __proto__/constructor/prototype
key segments and of paths exceeding maxDepth. qs only rejects two
of the three dangerous keys natively, and qs handles depth via
whole-input truncate/throw; we reject per-pair.
- coerceWalk: post-parse type coercion (true/false/null/undefined
strings, numerics) matching the 1.0.0 contract.
Dependencies:
- qs ^6.15.2 added as a runtime dependency (was previously zero).
- Probe devDeps (neoqs, picoquery, picoquery-v1) removed; the
replacement-probe was a one-off experiment whose conclusion is
recorded in PR history.
CI:
- New job: Conformance against qs@latest. Installs qs@latest unsaved
and reruns the full conformance spec. Early-warning for any future qs
release that would break the shim.
- Floor matrix now installs qs into the Docker container before running
smoke-floor (qs is a runtime dep so it must be present on Node 0.10
through 16).
Verified:
- Node 4 floor smoke green via Docker amd64 (qs@6.15.2 installs and
runs cleanly down there).
- npm audit --omit=dev: 0 vulnerabilities.
- npm pack --dry-run: 7 files, same allowlist as 1.0.0.
833af5d to
f242a8a
Compare
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
Compat shim release.
deparamnow delegates parsing to qs with three local protections layered on top (Latin-1 fallback decoder, per-pair prototype/depth rejection, type coercion).paramstays untouched as the original 2014 jQuery-traditional implementation.The library API is unchanged. All 58 conformance cases stay green; the only difference visible to callers is the optional
maxDepthparameter introduced in 1.0.0.Why this shape
After probing qs / neoqs / picoquery for replacement fit (see PR conversation history), qs covers the parse side cleanly with 5 supporting lines (the ISO-8859 fallback decoder). The stringify side has no security upside from qs —
paramis a pure encoder with no attack surface — so it stays on the original code. Asymmetric value, asymmetric architecture.The Latin-1 fallback is load-bearing for downstream Elasticsearch 1.7 usage (legacy producers emit Latin-1 percent-encoded querystrings; accents must reach ES intact).
Dependency change
qs ^6.15.2added as a runtime dependency (was previously zero deps)neoqs,picoquery,picoquery-v1) removedCI changes
test-qs-latestjob: installsqs@latestunsaved and reruns the conformance spec — early-warning if a future qs release would break the shimfloorjob now installsqsinto each Docker container before runningsmoke-floor.js(qs is a runtime dep, must be available on Node 0.10–16)Test plan
test-qs-latestjob green against qs@latestnpm audit --omit=devreports 0 vulnerabilitiesNotes
npm deprecate node-qs-serialization@1.0.0will point users to 1.1.0 (1.0.0 carries the hand-rolled deparam without the ongoing qs patch stream).param.jscomments stripped per the "no reasons in files" preference; behavior unchanged.