Packages

Elixir client for the Linear GraphQL API.

Current section

Files

Jump to
linear_client lib linear mutations.ex
Raw

lib/linear/mutations.ex

defmodule Linear.Mutations do
@moduledoc false
alias Linear.Client
@create_issue_mutation """
mutation LinearCreateIssue($input: IssueCreateInput!) {
issueCreate(input: $input) {
success
issue {
id identifier title url
state { id name }
team { id name key }
}
}
}
"""
@update_issue_mutation """
mutation LinearUpdateIssue($id: String!, $input: IssueUpdateInput!) {
issueUpdate(id: $id, input: $input) {
success
issue {
id identifier title url
state { id name }
}
}
}
"""
@create_comment_mutation """
mutation LinearCreateComment($issueId: String!, $body: String!) {
commentCreate(input: {issueId: $issueId, body: $body}) {
success
comment { id body createdAt }
}
}
"""
@state_lookup_query """
query LinearResolveState($issueId: String!, $stateName: String!) {
issue(id: $issueId) {
team {
states(filter: {name: {eq: $stateName}}, first: 1) {
nodes { id }
}
}
}
}
"""
@spec create_issue(Client.t(), map(), keyword()) :: {:ok, map()} | {:error, term()}
def create_issue(client, attrs, opts \\ []) when is_map(attrs) do
query_opts = Keyword.take(opts, [:request_fn])
case Client.query(client, @create_issue_mutation, Keyword.merge(query_opts, variables: %{"input" => attrs})) do
{:ok, %{"issueCreate" => %{"success" => true, "issue" => issue}}} ->
{:ok, issue}
{:ok, %{"issueCreate" => %{"success" => false}}} ->
{:error, :issue_create_failed}
error ->
error
end
end
@spec update_issue(Client.t(), String.t(), map(), keyword()) :: {:ok, map()} | {:error, term()}
def update_issue(client, issue_id, attrs, opts \\ []) when is_binary(issue_id) and is_map(attrs) do
query_opts = Keyword.take(opts, [:request_fn])
case Client.query(
client,
@update_issue_mutation,
Keyword.merge(query_opts, variables: %{"id" => issue_id, "input" => attrs})
) do
{:ok, %{"issueUpdate" => %{"success" => true, "issue" => issue}}} ->
{:ok, issue}
{:ok, %{"issueUpdate" => %{"success" => false}}} ->
{:error, :issue_update_failed}
error ->
error
end
end
@spec create_comment(Client.t(), String.t(), String.t(), keyword()) :: {:ok, map()} | {:error, term()}
def create_comment(client, issue_id, body, opts \\ []) when is_binary(issue_id) and is_binary(body) do
query_opts = Keyword.take(opts, [:request_fn])
case Client.query(
client,
@create_comment_mutation,
Keyword.merge(query_opts, variables: %{"issueId" => issue_id, "body" => body})
) do
{:ok, %{"commentCreate" => %{"success" => true, "comment" => comment}}} ->
{:ok, comment}
{:ok, %{"commentCreate" => %{"success" => false}}} ->
{:error, :comment_create_failed}
error ->
error
end
end
@spec transition_issue(Client.t(), String.t(), String.t(), keyword()) :: {:ok, map()} | {:error, term()}
def transition_issue(client, issue_id, state_name, opts \\ [])
when is_binary(issue_id) and is_binary(state_name) do
query_opts = Keyword.take(opts, [:request_fn])
with {:ok, state_id} <- resolve_state_id(client, issue_id, state_name, query_opts) do
update_issue(client, issue_id, %{"stateId" => state_id}, opts)
end
end
defp resolve_state_id(client, issue_id, state_name, query_opts) do
case Client.query(
client,
@state_lookup_query,
Keyword.merge(query_opts, variables: %{"issueId" => issue_id, "stateName" => state_name})
) do
{:ok, data} ->
case get_in(data, ["issue", "team", "states", "nodes", Access.at(0), "id"]) do
nil -> {:error, {:state_not_found, state_name}}
id -> {:ok, id}
end
error ->
error
end
end
end