fix(js): resolve literal URL from Request constructor in fetch calls (#6364)

* fix(js): resolve literal URL from Request constructor in fetch calls

* fix(js): gate Request URL extraction on fetch and require new operator
This commit is contained in:
Ahmed
2026-10-23 02:38:17 +05:00
committed by GitHub
parent ee0ec027db
commit 3984d12a30
2 changed files with 153 additions and 8 deletions
@@ -263,3 +263,114 @@ it("keeps exact literal targets exact", () => {
},
]);
});
it("resolves inline Request constructor targets with literal URLs", () => {
expect(
endpoints(`
fetch(new Request("/api/chat", { method: "POST" }));
window.fetch(new Request("/api/window"));
`),
).toEqual([
{
kind: "network",
value: "/api/chat",
mechanism: "call:fetch",
resolution: undefined,
},
{
kind: "network",
value: "/api/window",
mechanism: "call:window.fetch",
resolution: undefined,
},
]);
});
it("keeps Request calls without new partial", () => {
expect(endpoints('fetch(Request("/api/stream"));')).toEqual([
{
kind: "network",
value: 'Request("/api/stream")',
mechanism: "call:fetch",
resolution: "partial",
},
]);
});
it("resolves unchanged Request objects and aliases", () => {
expect(
endpoints(`
const req = new Request("/api/chat", { method: "POST" });
const alias = req;
fetch(alias);
`),
).toEqual([
{
kind: "network",
value: "/api/chat",
mechanism: "call:fetch",
resolution: undefined,
},
]);
});
it("keeps Request objects partial when called with toString", () => {
expect(
endpoints(`
const req = new Request("/api/chat");
fetch(req.toString());
`),
).toEqual([
{
kind: "network",
value: "req.toString()",
mechanism: "call:fetch",
resolution: "partial",
},
]);
});
it("keeps Request targets partial on non-fetch network APIs", () => {
expect(
endpoints(`
const socketReq = new Request("wss://host/socket");
new WebSocket(new Request("wss://host/direct"));
new WebSocket(socketReq);
navigator.sendBeacon(new Request("https://api.example.test/beacon"));
`),
).toEqual([
{
kind: "network",
value: 'new Request("wss://host/direct")',
mechanism: "call:WebSocket",
resolution: "partial",
},
{
kind: "network",
value: "socketReq",
mechanism: "call:WebSocket",
resolution: "partial",
},
{
kind: "network",
value: 'new Request("https://api.example.test/beacon")',
mechanism: "call:navigator.sendBeacon",
resolution: "partial",
},
]);
});
it("keeps Request objects partial when Request is locally shadowed", () => {
expect(
endpoints(`
function test(Request) {
fetch(new Request("/api/shadowed"));
}
`),
).toContainEqual({
kind: "network",
value: 'new Request("/api/shadowed")',
mechanism: "call:fetch",
resolution: "partial",
});
});