Skip to content

refactor: unify the request pipeline in VaultClient#118

Merged
kurok merged 1 commit into
masterfrom
refactor/110-unify-request-pipeline
Jul 2, 2026
Merged

refactor: unify the request pipeline in VaultClient#118
kurok merged 1 commit into
masterfrom
refactor/110-unify-request-pipeline

Conversation

@kurok

@kurok kurok commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #110. The resolve-mount → rewrite-path → make-request pipeline was implemented three times in src/VaultClient.js (__resolveAndRequest, update(), __v2Only()), with request() carrying a partial fourth copy. Any cross-cutting change (retries, per-request headers, a new engine version) had to be applied identically in each copy. This PR extends __resolveAndRequest(op, method, path, data, extraHeaders, options) into the single entry point and makes the other three delegate to it. Pure refactor — zero behavior change.

Changes

  • src/VaultClient.js
    • __resolveAndRequest gains an options parameter: { raw } (skip resolution/rewriting — literal passthrough), { v2Only } (KV v2 version assertion before any HTTP request), { wrapData } (force the { data } envelope on every engine version — merge-patch semantics)
    • update() is now a delegation passing the application/merge-patch+json header and { wrapData: true } (its envelope has always applied on v1 too — preserved)
    • __v2Only() delegates with { v2Only: true }, keeping the exact UnsupportedOperationError message and its assert-before-request ordering
    • request() routes through { raw: true }
    • grep -c "resolver.resolve(" src/VaultClient.js drops to 1 (was 3)
    • The ~8× catch/log/rethrow in the public methods is intentionally untouched — that extraction is the follow-up called out in Refactor: unify the 4x copy-pasted request pipeline in VaultClient #110
  • test/VaultClient.pipeline.test.mjs (new) — 21 characterization tests written before the refactor and verified green against the old code, pinning v1/v2 × namespace × extra-headers behavior: byte-for-byte v1 path passthrough (incl. trailing slash), update()'s always-on envelope on v1, raw request() never consulting the resolver, exact v2-only error message, no X-Vault-Namespace leakage into per-request headers
  • CHANGELOG.md — bullet under a new # Unreleased heading (no version bump)

Note: sibling PRs (#116 and the in-flight PRs for #109/#111) also add # Unreleased bullets, so a trivial CHANGELOG rebase conflict is possible.

Verification

  • npm run lint — clean
  • npm run test:unit — 276 passing (255 pre-existing tests unmodified + 21 new)
  • npm run coverage — 98.5% statements / 95.57% branches / 100% functions / 98.5% lines (thresholds 97/93/100/97)
  • npm run test:e2e against a real Vault 1.17.6 dev server (KV v1) — 6 passing, 1 pending
  • npm run test:e2e:kv2 against a real Vault dev server (KV v2) — 10 passing

Type of change

  • Bug fix
  • New feature
  • Refactor
  • Documentation
  • CI / tooling

Checklist

  • Tests added or updated
  • npm run lint && npm test passes locally
  • User-facing changes recorded under # Unreleased in CHANGELOG.md
  • All commits have a Signed-off-by: trailer (git commit -s)

@kurok kurok requested review from m2broth and wRLSS as code owners July 2, 2026 11:27
Extend __resolveAndRequest(op, method, path, data, extraHeaders, options)
into the single entry point for the auth-token -> headers -> resolve-mount
-> rewrite-path -> make-request pipeline:

- update() delegates with the merge-patch Content-Type header and
  { wrapData: true }, keeping its always-on { data } envelope on every
  engine version
- __v2Only() delegates with { v2Only: true }, keeping the KV v2 version
  assertion ahead of any HTTP request
- request() routes through { raw: true }, which skips mount resolution
  and path rewriting for literal passthrough

resolver.resolve() now has exactly one call site in VaultClient (down
from three). Pure refactor with zero behavior change: the pre-existing
unit suite passes unmodified, and new characterization tests pin the
pipeline behavior across v1/v2 mounts x namespace x extra headers,
including the byte-for-byte v1 path passthrough and the exact
UnsupportedOperationError message.

The ~8x copy-pasted catch/log/rethrow in the public methods is left
untouched on purpose; extracting it is a follow-up (see #110).

Closes #110

Signed-off-by: Yuriy R <22548029+kurok@users.noreply.github.com>
@kurok kurok force-pushed the refactor/110-unify-request-pipeline branch from 072fc66 to e0c2ec3 Compare July 2, 2026 11:31
@kurok kurok merged commit 9fc0453 into master Jul 2, 2026
18 checks passed
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.

Refactor: unify the 4x copy-pasted request pipeline in VaultClient

2 participants