Skip to content

fix: align filter coercion and YAML flow-map parsing across PHP and JS#69

Merged
felipesauer merged 1 commit into
mainfrom
fix/filter-coercion-and-yaml-flow-parity
Jun 8, 2026
Merged

fix: align filter coercion and YAML flow-map parsing across PHP and JS#69
felipesauer merged 1 commit into
mainfrom
fix/filter-coercion-and-yaml-flow-parity

Conversation

@felipesauer

Copy link
Copy Markdown
Owner

Summary

An audit surfaced four behaviors that either diverged between the PHP and TypeScript packages — breaking the library's cross-language parity guarantee — or were incorrect in both. Each was confirmed by running real code on PHP 8.3 and Node 24. All fixes are mirrored symmetrically and locked by identical parity tests.

  • Filter numeric literals now coerce identically: only plain decimal integers and decimal floats (incl. scientific notation) become numbers; hex (0x1A), binary (0b101), octal (0o17), and underscore-grouped literals stay strings in both runtimes. Integral values such as 1e3 collapse to an integer so they compare equal to integer data under strict equality. (Before: [?v == 1e3] matched 1000 in PHP but 1 in JS.)
  • Relational operators (>, <, >=, <=) compare only when both operands are numbers; any other type yields false. This removes the "abc" > 5 (PHP true / JS false) and "" >= 0 (PHP false / JS true) divergences. ==/!= are unchanged (already strict).
  • YAML flow maps split on the first colon outside quotes and unquote quoted keys, so {"a:b": v} parses to { "a:b": "v" } instead of corrupting the key/value pair.
  • YAML merge keys (<<) are now rejected inside flow maps ({<<: {a: 1}}), closing a gap in the documented "merge keys are blocked" guarantee.
  • Path cache key is normalized by stripping the optional root prefix, so $.a.b, $a.b, and a.b share one cache entry instead of three.
  • Documented that nested flow collections are not expanded by the minimal YAML parser (intentional, mirrored in both runtimes).

Behavioral changes worth noting

Filter predicates with hex/binary/octal literals (JS only) previously coerced to numbers and now stay strings; relational comparisons against numeric-looking string field values now return false in both runtimes (use arithmetic, e.g. @.v * 1 > 5, to compare them numerically).

Validation

  • cd packages/php && composer test — 673 passed, 100% line coverage
  • cd packages/php && composer analyse — PHPStan: no errors
  • cd packages/php && composer test:mutation — Infection MSI 100% / Covered MSI 100%
  • cd packages/js && npm test — 1839 passed
  • cd packages/js && npx tsc --noEmit && npx eslint src/ tests/ — clean
  • cd packages/js && npm run test:mutation — Stryker score 94.28% (≥ 93% break threshold)
  • Both parity suites (ParityTest.php, parity.test.ts) — 59 identical cross-language tests, green

Several behaviors diverged between the PHP and TypeScript packages or were
incorrect in both, breaking the cross-language parity guarantee. All fixes
are mirrored symmetrically and covered by identical parity tests.

- Unify numeric-literal coercion in filter predicates: only plain decimal
  integers and decimal floats (incl. scientific notation) become numbers;
  hex/binary/octal/underscore literals stay strings in both runtimes.
  Integral values such as 1e3 collapse to an integer so they compare equal
  to integer data under strict equality (was 1000 in PHP, 1 in JS).
- Restrict relational operators (>, <, >=, <=) to compare only when both
  operands are numbers; any other type yields false. Removes the
  "abc" > 5 and "" >= 0 divergences. Equality (==, !=) is unchanged.
- Split YAML flow-map keys on the first colon outside quotes and unquote
  quoted keys, so {"a:b": v} parses correctly instead of corrupting the pair.
- Reject merge keys (<<) used inside flow maps, closing a gap in the
  documented "merge keys are blocked" guarantee.
- Normalize the path cache key by stripping the optional root prefix so
  $.a.b, $a.b, and a.b share a single cache entry.
- Document that nested flow collections are not expanded by the minimal
  YAML parser (intentional, mirrored in both runtimes).
@codecov

codecov Bot commented Jun 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@felipesauer felipesauer merged commit 9aebe64 into main Jun 8, 2026
9 checks passed
@felipesauer felipesauer deleted the fix/filter-coercion-and-yaml-flow-parity branch June 8, 2026 20:59
felipesauer pushed a commit that referenced this pull request Jun 8, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.1.12](php-v0.1.11...php-v0.1.12)
(2026-06-08)


### Bug Fixes

* align filter coercion and YAML flow-map parsing across PHP and JS
([#69](#69))
([9aebe64](9aebe64))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
felipesauer pushed a commit to felipesauer/safeaccess-inline-php that referenced this pull request Jun 8, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.1.12](felipesauer/safeaccess-inline@php-v0.1.11...php-v0.1.12)
(2026-06-08)


### Bug Fixes

* align filter coercion and YAML flow-map parsing across PHP and JS
([#69](felipesauer/safeaccess-inline#69))
([9aebe64](felipesauer/safeaccess-inline@9aebe64))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
felipesauer added a commit that referenced this pull request Jun 8, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.1.6](js-v0.1.5...js-v0.1.6)
(2026-06-08)


### Bug Fixes

* align filter coercion and YAML flow-map parsing across PHP and JS
([#69](#69))
([9aebe64](9aebe64))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Felipe Sauer <120697114+felipesauer@users.noreply.github.com>
felipesauer added a commit to felipesauer/safeaccess-inline-js that referenced this pull request Jun 8, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.1.6](felipesauer/safeaccess-inline@js-v0.1.5...js-v0.1.6)
(2026-06-08)


### Bug Fixes

* align filter coercion and YAML flow-map parsing across PHP and JS
([#69](felipesauer/safeaccess-inline#69))
([9aebe64](felipesauer/safeaccess-inline@9aebe64))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Felipe Sauer <120697114+felipesauer@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant