| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Convert Feathers queries between dot notation (`{ 'user.name': 'x' }`) and
nested objects (`{ user: { name: 'x' } }`). Queries arrive in both shapes
depending on where they come from, but adapters only reliably understand the
dot form, so every call site had to normalize this by hand.
Both are query-aware rather than a generic flatten/unflatten:
- operators (`$ne`, `$in`, ...) never become path segments
- `$or`/`$and`/`$nor`/`$not` branches are converted per branch
- `$sort` keys stay in dot notation in both directions — the only form adapters
understand
- `$select`, `$limit`, `$skip` and custom operators pass through untouched
Because "value vs. path" is not always decidable, both take a per-key predicate
(`descend`/`split`) plus declarative `include`/`exclude` shortcuts.
Colliding paths never lose data: deep-equal values collapse, objects with
disjoint keys merge, and a genuine contradiction is wrapped in `$and` — matching
addToQuery. A key whose path is blocked by a non-object value simply stays in
dot notation, which is already a valid condition.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`test.include` was never set, so vitest fell back to its project-wide default
(`**/*.{test,spec}.*`), which only skips `node_modules` and `dist`. The globs
that are set cover something else: `includeSource` is for in-source tests and
`coverage.include` only bounds the coverage scope.
As a result, stray checkouts — e.g. a git worktree under `.claude/` — had their
tests and type tests picked up and run. ESLint had the same problem from the
other side: `eslint .` walked into them, and since they are outside
`tsconfig.eslint.json` every file came back as a parser error.
Scope the discovery instead of blacklisting one directory, so future worktrees
and temporary clones are covered too.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Deploying feathers-utils with
|
| Latest commit: | 24390c6 |
| Status: | ✅ Deploy successful! |
| Preview URL: | https://443852f5.feathers-utils.pages.dev |
| Branch Preview URL: | https://feat-dotify-nestify-query.feathers-utils.pages.dev |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
Queries arrive in both dot notation ({ 'user.name': 'x' }) and nested form ({ user: { name: 'x' } }) depending on where they come from — client, form builder, stored filter, hand-written server code. Adapters only reliably understand the dot form, so every call site had to normalize it by hand. These two utils do the conversion in both directions.
Query-aware, not a generic flatten
A naive flatten/unflatten is wrong here:
dotifyQuery is the reliable direction. nestifyQuery is documented as best effort: on MongoDB { user: { name: 'x' } } means document equality while { 'user.name': 'x' } means a subfield match.
Pluggable, because "value vs. path" is not always decidable
By default a value is a path only if it is a non-empty plain object with at least one non-$ key (Date, RegExp, ObjectId, class instances, arrays, {} are values). A field may legitimately hold an object matched by equality, so both take a per-key predicate plus declarative shortcuts:
The predicate wins over include/exclude, which match the full dotted path; returning undefined falls through to the default heuristic. The predicate is only called where there is an actual decision to make.
Collisions never lose data
Following addToQuery, which already documents wrapping conflicting conditions in $and:
Two details worth a look in review:
Second commit: test/lint discovery
Independent of the feature, and reviewable on its own. test.include was never set, so vitest fell back to its project-wide default and picked up tests from stray checkouts (a git worktree under .claude/); ESLint walked into the same directories and reported every file as a parser error, since they are outside tsconfig.eslint.json. The fix scopes discovery to src/test rather than blacklisting one directory. Happy to split this out if you would rather keep the PR to the feature.
Verification
npm test passes (exit 0): 1213 tests, 0 lint errors, clean typecheck, coverage 96.64% statements / 92.52% branches — 100% statements/branches/functions on all four new source files. Both .md docs pages are discovered with working see: cross-links, and the tsdown build is clean.
🤖 Generated with Claude Code