; fetch('/api/foo')
(call_expression
  function: (identifier) @_fetch
  arguments: (arguments
    .
    (string (string_fragment) @fetch.url.literal))
  (#eq? @_fetch "fetch"))

; fetch(`/api/foo/${id}`)
(call_expression
  function: (identifier) @_fetch2
  arguments: (arguments
    .
    (template_string) @fetch.url.template)
  (#eq? @_fetch2 "fetch"))

; client.get('/api/foo') — direct call (no await, no type args)
(call_expression
  function: (member_expression
    object: (identifier) @fetch.client
    property: (property_identifier) @fetch.method)
  arguments: (arguments
    .
    (string (string_fragment) @fetch.client.url.literal))
  (#match? @fetch.method "^(get|post|put|patch|delete|head|options)$"))

; client.get(`/api/foo/${id}`) — template, direct call
(call_expression
  function: (member_expression
    object: (identifier) @fetch.client2
    property: (property_identifier) @fetch.method.template)
  arguments: (arguments
    .
    (template_string) @fetch.client.url.template)
  (#match? @fetch.method.template "^(get|post|put|patch|delete|head|options)$"))

; await client.post('/api/foo') — await wraps the member_expression
(call_expression
  function: (await_expression
    (member_expression
      object: (identifier) @fetch.await.client
      property: (property_identifier) @fetch.await.method))
  arguments: (arguments
    .
    (string (string_fragment) @fetch.await.url.literal))
  (#match? @fetch.await.method "^(get|post|put|patch|delete|head|options)$"))

; await client.post(`/api/foo/${id}`) — await + template
(call_expression
  function: (await_expression
    (member_expression
      object: (identifier) @fetch.await.client2
      property: (property_identifier) @fetch.await.method.template))
  arguments: (arguments
    .
    (template_string) @fetch.await.url.template)
  (#match? @fetch.await.method.template "^(get|post|put|patch|delete|head|options)$"))
