Skip to content

feat(group): add Kotlin Spring WebClient long-form HTTP consumer extraction#1884

Merged
magyargergo merged 6 commits into
abhigyanpatwari:mainfrom
henry201605:feat/kotlin-spring-webclient-long-form
May 29, 2026
Merged

feat(group): add Kotlin Spring WebClient long-form HTTP consumer extraction#1884
magyargergo merged 6 commits into
abhigyanpatwari:mainfrom
henry201605:feat/kotlin-spring-webclient-long-form

Conversation

@henry201605

Copy link
Copy Markdown
Contributor

Summary

Follow-up to #1855. Adds support for the WebClient long-form fluent chain that #1855 explicitly deferred:

webClient.method(HttpMethod.GET).uri("/api/users").retrieve().awaitBody<User>()
webClient.method(HttpMethod.POST).uri("/api/orders")...
webClient.method(HttpMethod.DELETE).uri("/api/items/1")...

The short form (webClient.get().uri("/x")) was already covered in #1855. The long form remains common in Kotlin Spring 4 → 5 migrations and in codebases that prefer the fluent verb-as-enum style.

Approach

A single deeper tree-sitter query (WEB_CLIENT_LONG_PATTERNS) matches the full chain structurally — both .method(HttpMethod.X) and .uri("...") are captured in one pattern, no walk-up helper needed.

(call_expression
  (navigation_expression
    (call_expression
      (navigation_expression
        (simple_identifier) @obj (#eq? @obj "webClient")
        (navigation_suffix
          (simple_identifier) @method_call (#eq? @method_call "method")))
      (call_suffix
        (value_arguments
          . (value_argument
              (navigation_expression
                (simple_identifier) @httpMethodCls (#eq? @httpMethodCls "HttpMethod")
                (navigation_suffix (simple_identifier) @verb))))))
    (navigation_suffix (simple_identifier) @uri (#eq? @uri "uri")))
  (call_suffix
    (value_arguments . (value_argument . (string_literal) @path))))

Verb is captured as the simple_identifier under HttpMethod's navigation_suffix (the literal field name GET/POST/...) and whitelisted to ^(GET|POST|PUT|DELETE|PATCH)$ for symmetry with the short form's WEB_CLIENT_SHORT_TO_HTTP map.

Receiver constraint (#eq? @obj "webClient") mirrors the short form and the Java plugin's heuristic.

Out of scope (intentional)

  • Variable-bound verbs: val verb = HttpMethod.PATCH; webClient.method(verb).... Source-scan can't follow the binding without graph context. Pinned by an anti-overreach test in the consumer suite.
  • HEAD / OPTIONS / TRACE: not in WEB_CLIENT_SHORT_TO_HTTP either — keeps polyglot symmetry with java.ts and the short form.

Tests

4 new cases under consumer extraction — fetch patterns, gated by tree-sitter-kotlin grammar availability.

Positive (3)

  • long form GET
  • long form POST / PUT / DELETE / PATCH (4 verbs in one fixture)
  • no double-emit: a long-form chain emits exactly one consumer, not one from each query

Anti-regression (1)

  • variable-bound verb does NOT match (graph-aware concern)

The previous 'does NOT match Kotlin WebClient long form (deferred to follow-up)' test from #1855 is replaced by these — the deferred state is now resolved.

Reverse validation

Temporarily disabling the long-form emit makes exactly the 3 positive tests fail; the variable-bound-verb anti-regression test continues to pass (it pins behavior independent of the emit being on or off — exactly the right shape).

Local validation

  • http-route-extractor.test.ts — 66 / 66 ✅
  • test/unit/group — 546 / 546 ✅
  • npx prettier --check (changed files) — clean ✅

…action

Follow-up to abhigyanpatwari#1855. Extends `kotlin.ts` with the long-form WebClient
fluent chain that abhigyanpatwari#1855 explicitly deferred:

  webClient.method(HttpMethod.GET).uri("/x").retrieve().awaitBody<T>()

This pattern remains common in Kotlin Spring 4 → 5 migrations and in
codebases that prefer the fluent verb-as-enum style. The short form
(`webClient.get().uri("/x")`) was already supported in abhigyanpatwari#1855.

Approach:
  - Single deeper tree-sitter query (`WEB_CLIENT_LONG_PATTERNS`) that
    matches the full chain structurally — both `.method(HttpMethod.X)`
    and `.uri("...")` in one pattern. Verb is captured as the
    `simple_identifier` of the `HttpMethod.X` field access.
  - Verb is whitelisted to GET/POST/PUT/DELETE/PATCH (consistent with
    the short-form's `WEB_CLIENT_SHORT_TO_HTTP` map).
  - Receiver constraint `(#eq? @obj "webClient")` mirrors the short
    form and Java plugin heuristic.

Out of scope (intentional):
  - Variable-bound verbs: `val verb = HttpMethod.PATCH; webClient.method(verb)...`
    Source-scan can't follow the binding without graph context.
    Pinned by an anti-overreach test.
  - HEAD/OPTIONS/TRACE: not in `WEB_CLIENT_SHORT_TO_HTTP` either —
    keeps polyglot symmetry with java.ts and the short form.

Tests: 4 new cases under `consumer extraction — fetch patterns`,
gated by tree-sitter-kotlin grammar availability.

  positive (3)
   - long form GET
   - long form POST / PUT / DELETE / PATCH (4 verbs in 1 fixture)
   - no double-emit pin (long-form chain produces exactly one
     consumer, not one from each query)
  anti-regression (1)
   - variable-bound verb does NOT match (graph-aware concern)

The previous `'does NOT match Kotlin WebClient long form (deferred
to follow-up)'` test from abhigyanpatwari#1855 is replaced by these — the deferred
state is now resolved.

Reverse-validated: temporarily disabling the long-form emit makes
exactly the 3 positive tests fail; the variable-bound-verb anti-
regression test continues to pass (it pins behavior independent
of the emit being on or off).

Local validation:
  - test/unit/group/http-route-extractor.test.ts: 66/66 ✅
  - test/unit/group: 546/546 ✅
  - npx prettier --check (changed files): clean ✅
@vercel

vercel Bot commented May 29, 2026

Copy link
Copy Markdown

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

A member of the Team first needs to authorize it.

@github-actions

github-actions Bot commented May 29, 2026

Copy link
Copy Markdown
Contributor

CI Report

All checks passed

Pipeline Status

Stage Status Details
✅ Typecheck success tsc --noEmit
✅ Tests success unit tests, 3 platforms
✅ E2E success gitnexus-web changes only

Test Results

Tests Passed Failed Skipped Duration
10064 10060 0 4 635s

✅ All 10060 tests passed

4 test(s) skipped — expand for details
  • PHP pipeline benchmark > scales with file count (workers enabled)
  • Ruby pipeline benchmark > scales with file count (workers enabled)
  • Rust pipeline benchmark > scales with file count (workers enabled)
  • buildTypeEnv > known limitations (documented skip tests) > Ruby block parameter: users.each { |user| } — closure param inference, different feature

Code Coverage

Tests

Metric Coverage Covered Base Delta Status
Statements 79.86% 35415/44342 79.48% 📈 +0.4 🟢 ███████████████░░░░░
Branches 68.43% 22584/32999 68% 📈 +0.4 🟢 █████████████░░░░░░░
Functions 84.88% 3656/4307 84.56% 📈 +0.3 🟢 ████████████████░░░░
Lines 83.42% 31905/38245 82.97% 📈 +0.5 🟢 ████████████████░░░░

📋 View full run · Generated by CI

@github-actions

github-actions Bot commented May 29, 2026

Copy link
Copy Markdown
Contributor

Claude finished @magyargergo's task in 5m 31s —— View job


Production-Readiness Review: PR #1884

feat(group): add Kotlin Spring WebClient long-form HTTP consumer extraction


Tasks

  • Read repo docs (DoD.md, AGENTS.md, GUARDRAILS.md)
  • Inspect changed files (kotlin.ts, http-route-extractor.test.ts)
  • Inspect related files (java.ts, http-route-extractor.ts, tree-sitter-scanner.ts)
  • Run git hygiene checks
  • Run hidden Unicode / bidi scans
  • Check CI run logs for Kotlin test execution
  • Analyze tree-sitter query correctness and AST shape
  • Verify false-positive / double-emit safety
  • Verify contract ID / path normalization
  • Verify dedup and merge logic

Review bar for this PR

Reviewed against DoD.md v2.0.0 (§2.1–§2.9, §5 five-axis gates, §6 not-Done signals). This is a narrow source-scan consumer extraction change. Relevant DoD items: correctness on the real runtime path, test assertions that catch broken wiring, no stale comments, exact assertions over bounds-only assertions, no unrelated churn.


Problem being solved

Kotlin Spring services using the enum-style WebClient fluent API — webClient.method(HttpMethod.GET).uri("/api/users").retrieve().awaitBody<T>() — previously emitted no HTTP consumer contracts. This left group sync with provider-only contracts and missing cross-repo links. The short form (webClient.get().uri("/x")) was covered in #1855. This PR resolves the explicitly deferred long-form gap.


Current PR state

  • Open, not draft. No assigned reviewers, no labels, no milestone.
  • Head ad7082e — merge commit that brings feat/kotlin-spring-webclient-long-form (9c8196d) together with main (7b38b8a, Java HTTP consumer extraction).
  • Diff: 2 files changed, +218/−28.
  • CI (run 26612543229) ran on 9c8196d (pre-merge). See CI gap finding below.

Merge status and mergeability

CI green on 9c8196d. Post-merge HEAD ad7082e ran only auxiliary checks (Dependency Review, PR Autofix, Gitleaks). Mergeability/conflicts/branch-protection not directly verifiable from this environment. No structural conflicts are expected — the merge only adds Java HTTP consumer changes (java.ts, Java test fixtures) which are entirely separate files from this PR's changes.


Repository history considered


Branch hygiene assessment

Clean. Diff is exactly 2 files: kotlin.ts (+94/−11) and http-route-extractor.test.ts (+124/−17). One feature commit. No workflow churn, dependency churn, formatting sweep, or unrelated edits. Fully consistent with the stated scope.


Understanding of the change

kotlin.ts adds WEB_CLIENT_LONG_PATTERNS, a single deeper tree-sitter query that structurally matches the full webClient.method(HttpMethod.X).uri("...") chain in one pass. Verb is captured as the simple_identifier under HttpMethod's navigation_suffix (i.e., the literal GET/POST/... field name). A scan loop at lines 499–521 reads @verb and @path, applies a ^(GET|POST|PUT|DELETE|PATCH)$ whitelist, unquotes the path, and emits role: "consumer", framework: "spring-web-client", confidence: 0.7.

http-route-extractor.test.ts adds 4 new itKotlinConsumer tests (gated on grammar availability): long-form GET, long-form POST/PUT/DELETE/PATCH, no-double-emit, variable-bound verb non-match. The previous deferred-non-match test from #1855 is replaced. Tests run through extractor.extract(null, dir, makeRepo(dir)) — the real HttpRouteExtractor source-scan path, not a helper stub.


Findings

F1 — Stale block comment at test:1670–1675

Risk: Comment left unupdated after the deferred gap is resolved.

Evidence to check: Lines 1670–1675 of http-route-extractor.test.ts:

// ─── Kotlin consumers (RestTemplate / WebClient short / OkHttp) ──
// Same shape as the Java consumer test above, but parsed by the
// tree-sitter-kotlin grammar via `KOTLIN_HTTP_PLUGIN`. Three        ← still says "Three"
// consumer flavors covered here (long-form WebClient
// `webClient.method(HttpMethod.X).uri(...)` is intentionally
// deferred to a follow-up — see kotlin.ts file header).            ← stale, no longer deferred

Confirmed evidence: The comment still says "Three consumer flavors" and "intentionally deferred to a follow-up" after this PR adds the fourth flavor and resolves the deferral. The kotlin.ts file header was correctly updated to list four patterns (lines 23–26), but the test file block comment was not.

Recommended fix: Update the comment to say "Four consumer flavors covered here (RestTemplate, WebClient short, OkHttp, WebClient long form)." Remove the deferred sentence.

Blocks merge: No. DoD §2.3 flags stale comments as a not-Done signal, but this is a misleading comment in a test file, not executable logic. Minor follow-up acceptable. Fix this →


F2 — toBeGreaterThanOrEqual(4) in the multi-verb test

Risk: Bounds-only assertion masks accidental extra consumers. DoD §2.7: "Use toBe / toEqual for exact expectations; avoid toBeGreaterThanOrEqual and other bounds-only assertions that mask regressions."

Evidence to check: http-route-extractor.test.ts line ~1919:

const wcConsumers = consumers.filter((c) => c.meta.framework === 'spring-web-client');
expect(wcConsumers.length).toBeGreaterThanOrEqual(4);

Confirmed evidence: The fixture LongVerbClient.kt contains exactly 4 long-form calls (POST, PUT, DELETE, PATCH). The exact contract ID assertions (toBeDefined()) are already present for each verb. The toBeGreaterThanOrEqual(4) supplements those checks but would pass if 5 or 6 consumers were accidentally emitted from the file.

Mitigating factors: The exact contract ID presence assertions are there. The double-emit test uses toHaveLength(1) for a GET call. The dedupeContracts key is contractId|filePath|symbolName — since all 4 calls have different contract IDs (different verbs and/or different paths), no accidental dedup would hide extras.

Recommended fix: Replace with expect(wcConsumers.length).toBe(4). The fixture is fully known and deterministic. Fix this →

Blocks merge: No. The exact-contract-ID assertions already catch the primary production failure mode. Follow-up acceptable.


F3 — No negative test for HttpMethod.HEAD / OPTIONS / TRACE

Risk: The whitelist ^(GET|POST|PUT|DELETE|PATCH)$ correctly silences these verbs, but there is no test that pins this behavior. A future relaxation of the whitelist regex could silently start emitting contracts for these methods.

Evidence to check: kotlin.ts line 510: if (!/^(GET|POST|PUT|DELETE|PATCH)$/.test(verbText)) continue; — correct. No test asserts zero output for webClient.method(HttpMethod.HEAD).uri("/x").

Confirmed evidence: The whitelist is present and correct. The gap is the absence of a pinning test for the intentionally unsupported verbs. This is consistent with how #1855 handled the same verbs on the short form (no explicit test there either), so it is an accepted pattern in this codebase.

Recommended fix: Add one negative test: fixture with webClient.method(HttpMethod.HEAD).uri("/api/health"), assert zero consumers. Keeps the intentional omission auditable.

Blocks merge: No. The behavior is correct; this is an adequacy gap with precedent from #1855.


F4 — CI validated pre-merge SHA, not current head

Risk: The main test suite ran on 9c8196d. Current head is ad7082e (merge bringing in 7b38b8a — Java HTTP consumer extraction from PR #1872). The post-merge state has not been validated by the full test suite.

Evidence to check: CI run 26612543229 was triggered on 9c8196d. Post-merge, only Dependency Review, PR Autofix, and Gitleaks ran on ad7082e.

Confirmed evidence: The gap is real but extremely low-risk. PR #1872's changes are in java.ts and Java consumer test fixtures — completely separate files. No shared infrastructure was modified. There is no realistic interaction path between Java HTTP consumer extraction and Kotlin long-form consumer extraction.

Recommended fix: Maintainers should confirm the CI re-runs (or is triggered) on the merge commit before merge. If the CI pipeline is configured to auto-run on any push to the PR branch, push a no-op commit to trigger it.

Blocks merge: No in practice, but should be confirmed by maintainers.


PR-specific assessment sections

Kotlin WebClient semantics lane ✅

The query correctly anchors on the .uri(...) call expression rather than the terminal .awaitBody<T>() or .retrieve(). The verb is captured from HttpMethod.X — the literal enum field name in source. The query does not touch later chain hops, so arbitrary fluent continuations (.retrieve().awaitBody<T>(), .retrieve().awaitBodilessEntity(), .exchangeToMono(...)) do not affect match correctness. Verified by the multi-verb fixture which uses both awaitBody and awaitBodilessEntity and produces correct output.

Known limitations (all accepted, documented in kotlin.ts file header):

  • this.webClient receiver: NOT matched (navigation_expression, not simple_identifier). Same limitation as feat(group): add Kotlin Spring HTTP consumer extraction #1855 short form.
  • Non-webClient receiver names (userClient, orderWebClient): NOT matched. Same accepted heuristic.
  • Fully qualified org.springframework.http.HttpMethod.GET: NOT matched (produces nested navigation_expression). Acceptable for source-scan.
  • Named URI arg uri(path = "/x"): NOT matched. Safe — no false positives.
  • URI builder lambda uri { it.path("/x").build() }: NOT matched. Safe.
  • Variable-bound verbs: NOT matched. Pinned by anti-overreach test.

Tree-sitter query correctness lane ✅

The query structure is sound. Whitespace and newlines are not structural in tree-sitter — multi-line chains produce the same AST and will match. The . (value_argument ...) anchor (immediate-child dot) on the value_arguments nodes correctly restricts to the first argument, preventing false positives on multi-arg overloads like uri("/x", mapOf(...)) (the anchor fails when there are multiple arguments of different types). The verb whitelist regex ^(GET|POST|PUT|DELETE|PATCH)$ correctly filters upper-case HttpMethod field names.

The @method_call (#eq? @method_call "method") constraint is disjoint from the short-form verb whitelist ^(get|post|put|delete|patch)$ — this is the structural guarantee behind no-double-emit and is verified by an exact count assertion.

False-positive and duplicate lane ✅

  • No double-emit: Confirmed by expect(fromThisFile).toHaveLength(1) assertion on a single long-form call.
  • No variable-bound verb guessing: Confirmed by expect(fromThisFile).toHaveLength(0) assertion.
  • No short-form contamination: The short-form query requires @verb (#match? @verb "^(get|post|put|delete|patch)$") on the inner navigation_suffix, which would be method on a long-form call — that fails the regex.

GitNexus contract integration lane ✅

Tests run through extractor.extract(null, dir, makeRepo(dir)) — the real HttpRouteExtractor.extractConsumersSourceScan path with normalizeConsumerPath. Numeric path segments (/1, /2, /3) are normalized to {param}. Verified: http::PUT::/api/orders/{param}, http::DELETE::/api/orders/{param}, http::PATCH::/api/orders/{param}. Framework label spring-web-client is checked in GET and multi-verb tests. Confidence 0.7 matches Java and Kotlin short-form consumer precedent. No contract ID format drift.

The dedupeContracts key contractId|filePath|symbolName correctly deduplicates within a file, and mergeGraphAndSourceContracts deduplicates by contract ID across graph and source-scan results. No interaction issue.

Optional grammar / CI lane ✅

CI log line 500: test/unit/group/http-route-extractor.test.ts (66 tests) 366ms — all 66 tests passed, no skips. The 4 skipped tests in the full suite are the PHP/Ruby/Rust benchmark integrations and Ruby type-env limitation — none are Kotlin consumer tests. The new 4 long-form tests ran and passed across all 3 platforms (ubuntu, macos, windows).

Security and hygiene lane ✅

grep -P for bidi/zero-width Unicode controls in both changed files returned no output — files are clean. No secrets, no debug logs, no TODO placeholders, no local paths.

Repository history alignment lane ✅

This PR is a tight, correct follow-up to #1855. The deferred test is replaced (not weakened — the new tests include 3 positive assertions and 1 anti-overreach). The accepted #1855 limitations (receiver heuristic, OkHttp GET default) are preserved unchanged. #1834's named-annotation key constraint in the Kotlin provider query blocks is untouched. #1870/#1225 are not overclaimed.


Back-and-forth avoided by verifying

Concern Verified outcome
Hidden Unicode Clean — grep returned no hits
Kotlin tests ran in CI Confirmed — 66/66 in http-route-extractor.test.ts, 0 skips
Double-emit Pinned by exact toHaveLength(1) assertion
Variable-bound verb Pinned by exact toHaveLength(0) assertion
Short-form query contamination Structurally impossible — "method" fails short-form verb regex
Path normalization Verified correct: numeric IDs → {param}, tested for PUT/DELETE/PATCH
dedupeContracts behavior Key is `contractId
Contract framework label spring-web-client asserted in 2 of 4 new tests
OkHttp / RestTemplate / provider behavior Untouched files; existing tests still present in CI
#1834 named-arg Kotlin safety Provider query blocks unchanged

Open questions

None. All production-risk questions are resolved by code inspection and CI evidence.


Final verdict

production-ready with minor follow-ups

The core logic is correct: the tree-sitter query structurally matches the long-form chain, verb whitelisting is sound, the double-emit guarantee is proven by an exact assertion, variable-bound verbs are safely rejected, contract IDs normalize correctly, and all 66 tests passed across 3 CI platforms. Two minor items do not block production correctness: (1) a stale block comment at test:1670–1675 still says "three consumer flavors / deferred to follow-up" — it should say four and drop the deferral sentence; (2) toBeGreaterThanOrEqual(4) in the multi-verb test should be toBe(4) per DoD §2.7. The pre-merge SHA gap in CI is low-risk given the merge only brings in Java consumer changes with no shared infrastructure overlap. Recommend updating the stale comment and weak assertion in this PR or immediately after; neither affects runtime behavior.

View CI run · View PR

@magyargergo

Copy link
Copy Markdown
Collaborator

@henry201605 could you please look into these findings? 🙏

…atwari#1884

Two minor follow-ups from the production-readiness review:

F1 — Stale block comment at the top of the Kotlin consumer suite
(was: "Three consumer flavors covered here ... long-form deferred
to a follow-up"). Updated to "Four consumer flavors" and removed
the deferred sentence — the deferral is resolved by this PR. The
kotlin.ts file header was already updated; this brings the test
file comment in sync. Per DoD §2.3 (no stale comments).

F2 — Replaced `expect(wcConsumers.length).toBeGreaterThanOrEqual(4)`
with `expect(wcConsumers).toHaveLength(4)` in the multi-verb test.
The fixture is fully deterministic — exactly 4 long-form calls,
no other consumer types — so an exact count assertion is the right
shape per DoD §2.7 ("use toBe / toEqual for exact expectations").
Added a comment explaining what the assertion catches that the
existing per-verb toBeDefined() checks would miss (accidental 5th
consumer from a duplicate query firing or a regressed receiver
constraint).

F3 (HEAD/OPTIONS/TRACE negative test) is intentionally not added
in this PR — same precedent as abhigyanpatwari#1855 where HEAD/OPTIONS/TRACE on
the short form are also implicitly excluded without a pinning
test. Happy to add one in a separate PR if maintainers want
explicit pinning across both forms.

F4 (CI on pre-merge SHA) is the maintainer's call — the merge from
main is theirs to re-trigger CI on. The merge brings only Java
consumer changes (PR abhigyanpatwari#1872) and Go provider changes (PR abhigyanpatwari#1886),
both in entirely separate files from this PR's Kotlin work.

Local validation:
  - test/unit/group/http-route-extractor.test.ts: 73/73 ✅
    (66 from this PR pre-merge + 7 from PR abhigyanpatwari#1872 merged via main)
  - npx prettier --check (changed files): clean ✅
@henry201605

Copy link
Copy Markdown
Contributor Author

@magyargergo Thanks for the review! 🙏 Went through the four findings — quick notes below.

F1 (stale comment, "Three consumer flavors / deferred") — fixed in 69e4e0ac. Updated the block comment at the top of the Kotlin consumer suite to "Four consumer flavors" and removed the deferred sentence. The kotlin.ts file header was already updated in the original commit; this brings the test file comment in sync per DoD §2.3.

F2 (toBeGreaterThanOrEqual(4) → exact count) — fixed in the same commit. Replaced with expect(wcConsumers).toHaveLength(4) (semantically equivalent to the toBe(4) Claude suggested, but the dedicated matcher gives a friendlier failure message — "expected array to have length 4 but got 5" — happy to switch to the literal toBe if you prefer). The fixture is fully deterministic (exactly 4 long-form calls, no other consumer types), so an exact count is the right shape per DoD §2.7. Added a comment explaining what it catches beyond the existing per-verb toBeDefined() checks (e.g. accidental 5th emit from a duplicate query firing or a regressed receiver constraint).

F3 (no negative test for HEAD / OPTIONS / TRACE) — intentionally not added here. As Claude noted, the same verbs are also implicitly excluded on the short-form path from #1855 without an explicit pin, so adding one only on the long form would create asymmetry. Happy to open a separate small PR adding HEAD/OPTIONS/TRACE pins for both short and long forms together if you'd like consistent coverage — just say the word.

F4 (CI ran on pre-merge SHA 9c8196d) — your call on the re-trigger. The two merges from main bring in PR #1872 (Java HTTP consumer) and PR #1886 (Go provider builtins), both in entirely separate files from this PR's Kotlin work. I can push a no-op commit to force CI on the merge head if you'd prefer.

Local validation after the new commit:

Happy to make any further adjustments!

Comment thread gitnexus/src/core/group/extractors/http-patterns/kotlin.ts Outdated
…e scope

Address @magyargergo's review request on PR abhigyanpatwari#1884:

  > Can you please extract the regexp from the for loop? 🙏
    (kotlin.ts:510)

Compiles the verb whitelist `^(GET|POST|PUT|DELETE|PATCH)$` once at
module load instead of every iteration of the long-form scan loop.
Mirrors the placement and JSDoc style of the sibling
`WEB_CLIENT_SHORT_TO_HTTP` constant.

Behavior is unchanged — same verb whitelist, same exclusion of
HEAD/OPTIONS/TRACE for symmetry with the short form. The 4
itKotlinConsumer long-form tests added in this PR continue to
pass, and the variable-bound-verb anti-overreach test continues
to pin the deliberate non-match.

Local validation:
  - test/unit/group/http-route-extractor.test.ts: 77/77 ✅
  - test/unit/group: 557/557 ✅
  - npx prettier --check (changed file): clean ✅
@henry201605

Copy link
Copy Markdown
Contributor Author

@magyargergo Thanks for the catch! 🙏 Done in commit 77d1dcc5 — hoisted the verb whitelist to module scope as WEB_CLIENT_LONG_VERB_RE, placed alongside the sibling WEB_CLIENT_SHORT_TO_HTTP constant so the style stays consistent. Behavior is unchanged and all tests still pass. Let me know if you'd like any further tweaks!

@magyargergo magyargergo merged commit 2f15c1e into abhigyanpatwari:main May 29, 2026
40 of 43 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.

2 participants