//native
import * as wmill from "windmill-client"
/**
* New or Updated Issue
* Emits issues created or updated since the last poll (oldest first), tracked by an updatedAt watermark in Windmill state. The first run only sets the watermark. Optionally restrict to one team.
*/
export async function main(auth: RT.Linear, team_id: string | undefined) {
const lastChecked: string | undefined = await wmill.getState()
const filter: { [key: string]: any } = {}
if (team_id) filter.team = { id: { eq: team_id } }
if (lastChecked) filter.updatedAt = { gt: lastChecked }
const issues: { updatedAt: string; [key: string]: any }[] = []
let after: string | undefined
do {
const response = await fetch("https://api.linear.app/graphql", {
method: "POST",
headers: {
Authorization: auth.apiKey,
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify({
query: `query ($filter: IssueFilter, $first: Int, $after: String) { issues(filter: $filter, orderBy: updatedAt, first: $first, after: $after) { nodes { id identifier title description url priority priorityLabel dueDate createdAt updatedAt state { id name type } assignee { id name email } team { id key name } project { id name } labels { nodes { id name } } } pageInfo { hasNextPage endCursor } } }`,
// First run: only the most recently updated issue is needed to seed the watermark.
variables: { filter, first: lastChecked ? 100 : 1, after },
}),
})
if (!response.ok) {
throw new Error(`${response.status} ${await response.text()}`)
}
const { data, errors } = await response.json()
if (errors) {
throw new Error(JSON.stringify(errors))
}
issues.push(...data.issues.nodes)
after =
lastChecked && data.issues.pageInfo.hasNextPage
? data.issues.pageInfo.endCursor
: undefined
} while (after)
// ISO 8601 UTC timestamps sort lexicographically.
issues.sort((a, b) => a.updatedAt.localeCompare(b.updatedAt))
const newest = issues.at(-1)?.updatedAt
if (newest) await wmill.setState(newest)
return lastChecked ? issues : []
}
Submitted by hugo989 1 hour ago