Rule
no-github-request-interpolated-route (eslint-factory/src/rules/no-github-request-interpolated-route.ts).
Summary
The single diagnostic message always prescribes the value-into-known-path remedy:
Use the typed placeholder form instead — e.g. github.request("GET /repos/{owner}/{repo}", { owner, repo }) — to preserve typed dispatch and prevent malformed paths.
That advice fits the `.../${owner}/${repo}/...` case (e.g. route_slash_command.cjs:180), where the fix is to swap interpolated values for {owner}/{repo} placeholders. But it does not fit the other grounded shape in the corpus: a generic helper that interpolates an entire, opaque route path received as a parameter.
Grounding (live corpus)
Three production sites interpolate a whole dynamic route rather than individual path segments:
actions/setup/js/add_reaction.cjs:193 — github.request(`POST ${endpoint}`, ...) (endpoint is a function parameter)
actions/setup/js/add_reaction_and_edit_comment.cjs:266 — github.request(`POST ${endpoint}`, ...)
actions/setup/js/add_workflow_run_comment.cjs:444 — github.request("POST " + endpoint, ...) (concatenation form)
For these, there is no {placeholder} rewrite: the route is opaque at the call site, so the emitted remedy ("GET /repos/{owner}/{repo}", { owner, repo }) is not actionable and can mislead a maintainer into thinking a mechanical fix exists. The real remediation is structural — thread a typed route down from the callers, or accept the route as dynamic — which is a different message than "use placeholders".
Proposed refinement
Distinguish the whole-route-dynamic shape — a TemplateLiteral / + concatenation whose only non-literal content is a single interpolated expression preceded by a leading HTTP-method-plus-space literal (`POST ${x}` / "POST " + x) — and either:
- Emit a tailored message for that shape (e.g. "the entire route is dynamic; pass a typed route string from the caller instead of interpolating an opaque path"), or
- Keep flagging it (the strictness is defensible) but drop the inapplicable
{owner}/{repo} example from that variant's message, or
- At minimum, document in the README that opaque
`${METHOD} ${routeVar}` helpers are intentionally flagged and require threading a typed route, so the three sites above are not mistaken for a mechanical placeholder fix.
(No autofix is proposed — the rewrite is not mechanical.)
Acceptance criteria
- The rule differentiates value-into-path interpolation from whole-route interpolation (
`${METHOD} ${routeVar}` / "METHOD " + routeVar) and their messages/guidance differ, OR the README explicitly documents the opaque-route case with the three grounded sites.
- Unit tests assert the correct
messageId/data for both shapes; existing tests stay green.
- The value-into-path true positives at
route_slash_command.cjs:180/192/204/216 continue to be flagged with the placeholder remedy.
Generated by 🤖 ESLint Refiner · 411.7 AIC · ⌖ 13 AIC · ⊞ 4.6K · ◷
Rule
no-github-request-interpolated-route(eslint-factory/src/rules/no-github-request-interpolated-route.ts).Summary
The single diagnostic message always prescribes the value-into-known-path remedy:
That advice fits the
`.../${owner}/${repo}/...`case (e.g.route_slash_command.cjs:180), where the fix is to swap interpolated values for{owner}/{repo}placeholders. But it does not fit the other grounded shape in the corpus: a generic helper that interpolates an entire, opaque route path received as a parameter.Grounding (live corpus)
Three production sites interpolate a whole dynamic route rather than individual path segments:
actions/setup/js/add_reaction.cjs:193—github.request(`POST ${endpoint}`, ...)(endpointis a function parameter)actions/setup/js/add_reaction_and_edit_comment.cjs:266—github.request(`POST ${endpoint}`, ...)actions/setup/js/add_workflow_run_comment.cjs:444—github.request("POST " + endpoint, ...)(concatenation form)For these, there is no
{placeholder}rewrite: the route is opaque at the call site, so the emitted remedy ("GET /repos/{owner}/{repo}", { owner, repo }) is not actionable and can mislead a maintainer into thinking a mechanical fix exists. The real remediation is structural — thread a typed route down from the callers, or accept the route as dynamic — which is a different message than "use placeholders".Proposed refinement
Distinguish the whole-route-dynamic shape — a
TemplateLiteral/+concatenation whose only non-literal content is a single interpolated expression preceded by a leading HTTP-method-plus-space literal (`POST ${x}`/"POST " + x) — and either:{owner}/{repo}example from that variant's message, or`${METHOD} ${routeVar}`helpers are intentionally flagged and require threading a typed route, so the three sites above are not mistaken for a mechanical placeholder fix.(No autofix is proposed — the rewrite is not mechanical.)
Acceptance criteria
`${METHOD} ${routeVar}`/"METHOD " + routeVar) and their messages/guidance differ, OR the README explicitly documents the opaque-route case with the three grounded sites.messageId/datafor both shapes; existing tests stay green.route_slash_command.cjs:180/192/204/216continue to be flagged with the placeholder remedy.