Edits history of script submission #23237 for ' Update Project Item Status (github)'

  • bunnative
    One script reply has been approved by the moderators
    Ap­pro­ved
    //native
    
    async function graphql(auth: RT.Github, query: string, variables: object) {
      const response = await fetch("https://api.github.com/graphql", {
        method: "POST",
        headers: {
          Authorization: `Bearer ${auth.token}`,
          "Content-Type": "application/json",
          Accept: "application/json",
        },
        body: JSON.stringify({ query, variables }),
      })
      if (!response.ok) {
        throw new Error(`${response.status} ${await response.text()}`)
      }
      const { data, errors } = (await response.json()) as {
        data: any
        errors?: unknown[]
      }
      if (errors?.length) throw new Error(JSON.stringify(errors))
      return data
    }
    
    export type DynSelect_project_number = string
    
    // Dropdown of the owner's projects; fill owner first.
    export async function project_number(auth: RT.Github, owner: string) {
      if (!auth?.token || !owner) return []
      const data = await graphql(
        auth,
        `
          query ($owner: String!) {
            repositoryOwner(login: $owner) {
              ... on ProjectV2Owner {
                projectsV2(first: 100) {
                  nodes {
                    number
                    title
                  }
                }
              }
            }
          }
        `,
        { owner }
      )
      return (data.repositoryOwner?.projectsV2?.nodes ?? []).map((p: any) => ({
        value: String(p.number),
        label: `#${p.number} ${p.title}`,
      }))
    }
    
    export type DynSelect_item_id = string
    
    // Dropdown of the project's items.
    export async function item_id(
      auth: RT.Github,
      owner: string,
      project_number: string
    ) {
      if (!auth?.token || !owner || !project_number) return []
      const data = await graphql(
        auth,
        `
          query ($owner: String!, $number: Int!) {
            repositoryOwner(login: $owner) {
              ... on ProjectV2Owner {
                projectV2(number: $number) {
                  items(first: 100) {
                    nodes {
                      id
                      content {
                        ... on Issue {
                          number
                          title
                        }
                        ... on PullRequest {
                          number
                          title
                        }
                        ... on DraftIssue {
                          title
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        `,
        { owner, number: Number(project_number) }
      )
      return (data.repositoryOwner?.projectV2?.items.nodes ?? []).map((i: any) => ({
        value: i.id,
        label: i.content?.number
          ? `#${i.content.number} ${i.content.title}`
          : (i.content?.title ?? i.id),
      }))
    }
    
    export type DynSelect_status = string
    
    // Dropdown of the project's Status options.
    export async function status(
      auth: RT.Github,
      owner: string,
      project_number: string
    ) {
      if (!auth?.token || !owner || !project_number) return []
      const data = await graphql(
        auth,
        `
          query ($owner: String!, $number: Int!) {
            repositoryOwner(login: $owner) {
              ... on ProjectV2Owner {
                projectV2(number: $number) {
                  field(name: "Status") {
                    ... on ProjectV2SingleSelectField {
                      options {
                        id
                        name
                      }
                    }
                  }
                }
              }
            }
          }
        `,
        { owner, number: Number(project_number) }
      )
      return (data.repositoryOwner?.projectV2?.field?.options ?? []).map(
        (o: any) => ({
          value: o.id,
          label: o.name,
        })
      )
    }
    
    /**
     * Update Project Item Status
     * Set the Status of a project item (issue, pull request or draft issue). status is the Status option id. Classic tokens and OAuth connections need the project scope.
     */
    export async function main(
      auth: RT.Github,
      owner: string,
      project_number: DynSelect_project_number,
      item_id: DynSelect_item_id,
      status: DynSelect_status
    ) {
      const data = await graphql(
        auth,
        `
          query ($owner: String!, $number: Int!) {
            repositoryOwner(login: $owner) {
              ... on ProjectV2Owner {
                projectV2(number: $number) {
                  id
                  field(name: "Status") {
                    ... on ProjectV2SingleSelectField {
                      id
                    }
                  }
                }
              }
            }
          }
        `,
        { owner, number: Number(project_number) }
      )
      const project = data.repositoryOwner?.projectV2
      if (!project?.field)
        throw new Error(`Project ${project_number} has no Status field`)
    
      const result = await graphql(
        auth,
        `
          mutation (
            $projectId: ID!
            $itemId: ID!
            $fieldId: ID!
            $optionId: String!
          ) {
            updateProjectV2ItemFieldValue(
              input: {
                projectId: $projectId
                itemId: $itemId
                fieldId: $fieldId
                value: { singleSelectOptionId: $optionId }
              }
            ) {
              projectV2Item {
                id
              }
            }
          }
        `,
        {
          projectId: project.id,
          itemId: item_id,
          fieldId: project.field.id,
          optionId: status,
        }
      )
      return result.updateProjectV2ItemFieldValue.projectV2Item
    }
    

    Submitted by hugo989 2 hours ago