Skip to content

feat(group): make HTTP consumer client identifiers configurable#1942

Open
easonliu8899 wants to merge 1 commit into
abhigyanpatwari:mainfrom
easonliu8899:feat/configurable-http-consumer-clients
Open

feat(group): make HTTP consumer client identifiers configurable#1942
easonliu8899 wants to merge 1 commit into
abhigyanpatwari:mainfrom
easonliu8899:feat/configurable-http-consumer-clients

Conversation

@easonliu8899
Copy link
Copy Markdown

What

Adds a detect.http_client_aliases option to group.yaml so the JS/TS HTTP
consumer extractor recognizes member-style calls (client.get(url),
client.post(url), …) made through a wrapped HTTP client, not just the
built-in axios.

# group.yaml
detect:
  http_client_aliases: [request, http]   # default: []

With the example above, calls like request.get('/api/users') and
http.post('/orders') are extracted as HTTP consumer contracts and can
cross-link to provider endpoints during group sync.

Why

Many front-ends wrap their HTTP client behind a small helper instead of
calling axios/fetch directly — e.g. uni-app / luch-request projects do:

import request from '@/utils/request.js';
export function getUsers() { return request.get('/api/users'); }

The Node HTTP plugin hard-coded the consumer client identifier to axios
((#eq? @obj "axios")), so these wrapped calls produced zero consumer
contracts and therefore zero cross-links, even though the URLs are plain
string literals that are trivially extractable. This affects any codebase
that renames or wraps its HTTP client.

How it works

  • The axios.<verb>(url) tree-sitter query no longer pins @obj to
    "axios"; it captures the object identifier and the plugin filters it
    against a configurable client-identifier set in scanBundle.
  • The set defaults to {"axios"} (built-in), and is widened by the aliases
    threaded from group.yamlHttpRouteExtractor → each Node plugin's
    prepareReposcan. No tree-sitter query is recompiled per config.
  • framework on each detection is now the matched identifier (axios stays
    axios; a wrapped request reports request).

Backward compatibility

  • Default http_client_aliases: [] ⇒ only axios is recognized — identical
    behavior to before
    . The existing axios/fetch/jQuery consumer tests pass
    unchanged.
  • Object-form (axios({ url })) and fetch/jQuery detection are untouched.
  • New detect key defaults to [], so existing groups are unaffected on the
    next sync.

How to verify

cd gitnexus && npm install && npm run build
npx vitest run test/unit/group/http-route-extractor.test.ts   # incl. 2 new tests
npx vitest run test/unit/group/config-parser.test.ts          # incl. 4 new tests
npx tsc --noEmit

New tests:

  • http-route-extractor.test.ts: a wrapped request.get() is not detected
    without aliases (no false positives), and is detected (GET + DELETE) when
    new HttpRouteExtractor(['request']) is configured.
  • config-parser.test.ts: default [], explicit list parsing, and validation
    errors for non-array / non-string entries.

Real-world validation

Validated on a real 2-repo group (a uni-app / luch-request frontend that
wraps its client as request + a Spring backend). With
detect.http_client_aliases: [request], group sync cross-links went from
0 → 135 (exact, confidence 1.0). Spot-checked links are correct round
trips, e.g. POST /wx/login matches the frontend request.post("wx/login")
to the backend @PostMapping("/login") under a /wx class mapping. Without
the alias the same group produces 0 cross-links.

Risk / rollback

  • Low. The change is additive and opt-in; the default code path is unchanged.
  • Scope limited to member-style ident.verb(stringLiteral) consumer calls.
    String-concatenation URLs and uni.request({ url }) object-form calls are
    still out of scope (documented limitation, not a regression).
  • Rollback is a straight revert of this commit — no migration, no stored-data
    format change.

Out of scope (possible follow-ups)

  • Java provider @RequestMapping(value = "...") named-argument extraction
    (separate precision improvement, unrelated to this consumer-side change).
  • Configurable client aliases for the object-form (client({ url })) and for
    non-Node language plugins.
  • api_impact / route_map resolve a single repo's graph Route nodes, which
    for Spring/Java back-ends are not always populated from @RequestMapping /
    @GetMapping handlers — so an exact lookup like api_impact route="/wx/login"
    can return "no routes" even though the route exists as a provider contract and
    cross-links correctly in group sync. Cross-repo consumers remain reachable
    via query repo:"@group" and the group contracts resource; populating graph
    Route nodes from Spring handlers would let api_impact cover Java back-ends.

The Node HTTP plugin hard-coded the consumer client identifier to
`axios` (`(#eq? @obj "axios")`), so member-style calls made through a
wrapped HTTP client — e.g. uni-app / luch-request style
`import request from "@/utils/request"; request.get("/x")` — produced
zero consumer contracts and therefore zero cross-links, even though
the URLs are plain string literals.

Add a `detect.http_client_aliases` option to group.yaml. The
`<client>.<verb>(url)` query now captures the object identifier instead
of pinning it to "axios", and the plugin filters it against a
config-driven client-identifier set (default {"axios"}) threaded from
group.yaml -> HttpRouteExtractor -> each Node plugin's prepareRepo.

Backward compatible: default `[]` recognizes only axios, identical to
prior behavior. Object-form (`axios({url})`), fetch and jQuery
detection are untouched.

Tests: wrapped `request.get` is not detected without aliases and is
detected (GET + DELETE) when opted in; config-parser default/parse/
validation for the new field.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 31, 2026

@claude is attempting to deploy a commit to the NexusCore Team on Vercel.

A member of the Team first needs to authorize it.

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.

2 participants