繁体   English   中英

如何从 defaultBranchRef 上的 GitHub GraphQL 获取类型目标?.history

[英]How do I get type target?.history from GitHub GraphQL on defaultBranchRef

我正在尝试使用 typesaftey 获取最后一次提交,但无法通过history属性,因为它可以是空的 object、 {} 、null、未定义或我想要的实际 object,提交。

我的 GitHub GraphQL 查询是

query OrgReposAgExtended_v3(
  $organization: String!
  $pageSize: Int
  $after: String
) {
  organization(login: $organization) {
    repositories(
      first: $pageSize
      after: $after
      orderBy: { field: STARGAZERS, direction: DESC }
    ) {
      totalCount
      pageInfo {
        startCursor
        hasNextPage
        endCursor
      }
      edges {
        cursor
        node {
          ...RepoEx
        }
      }
    }
  }
}
fragment Commit on Commit {
  message
  pushedDate
  committedDate
}
fragment RepoEx on Repository {
  repositoryName: name
  id
  url
  lastPushToDefaultBranch: defaultBranchRef {
    name
    target {
      ... on Commit {
        history(first: 1) {
          edges {
            node {
              # this is the object I want
              ...Commit
            }
          }
        }
      }
    }
  }
}

来自 codegen'd SDK 的响应是

{
  organization: {
    repositories: {
      totalCount: 2130,
      pageInfo: {
        startCursor: 'Y3Vyc29yOnYyOpLNBc3OB9Ef4Q==',
        hasNextPage: true,
        endCursor: 'Y3Vyc29yOnYyOpLNBc3OB9Ef4Q=='
      },
      edges: [
        {
          cursor: 'Y3Vyc29yOnYyOpLNBc3OB9Ef4Q==',
          node: {
            repositoryName: 'cognitive-services-speech-sdk',
            id: 'MDEwOlJlcG9zaXRvcnkxMzExNDU2OTc=',
            url: 'https://github.com/Azure-Samples/cognitive-services-speech-sdk',
            lastPushToDefaultBranch: {
              name: 'master',
              target: {
                history: {
                  edges: [
                    {
                      node: {
                        message:
                          'pull 1.25 new samples and updates to public GitHub repository. (#1812)\n\n* pull 1.25 new samples and updates to public GitHub repository.\r\n\r\n* also update the sdk version used by all the samples.\r\n\r\n* add step to install maui-android, so new maui smaples will build in ci.\r\n\r\n* adding the maui-android workflow did not fix the restore fialure.  Exclude the maui project from CiCd build like in carbon.\r\n\r\n* adding the maui-android workflow did not fix the restore fialure.  Exclude the maui project from CiCd build like in carbon.\r\n\r\n* adding the maui-android workflow did not fix the restore fialure.  Exclude the maui project from CiCd build like in carbon.\r\n\r\n* adding the maui-android workflow did not fix the restore fialure.  Exclude the maui project from CiCd build like in carbon.\r\n\r\n* adding the maui-android workflow did not fix the restore fialure.  Exclude the maui project from CiCd build like in carbon.',
                        pushedDate: '2023-01-28T04:29:05Z',
                        committedDate: '2023-01-28T04:29:02Z'
                      }
                    }
                  ]
                }
              }
            }
          }
        }
      ]
    }
  }
}

它从 codegen 中输入为(格式化为阅读)

export type IRepoExFragment = { 
    id: string, 
    url: any, 
    repositoryName: string, 
    lastPushToDefaultBranch?: { 
        name: string, 
        target?: { 
            history: { 
                edges?: Array<{ 
                    node?: { 
                        message: string, 
                        pushedDate?: any | null | undefined, 
                        committedDate: any } | null | undefined 
                } | null | undefined> | null | undefined 
            } 
        } | {} | null | undefined // how to do I by pass this to get the history object?
    } | null | undefined 
};

回购中的源代码 function

export async function reposExtended({
  pat,
  gitHubGraphQLUrl,
  orgName
}: IRepoParameters2): Promise<IRepoExRefactored | null> {
  if (!pat) {
    throw new Error('GitHub Personal Access Token is required')
  }
  if (!gitHubGraphQLUrl) {
    throw new Error('GitHub GraphQL URL is required')
  }
  if (!orgName) {
    throw new Error('orgName is required')
  }

  const page_size: InputMaybe<number> = 1 // Max page size for GitHub
  const variables: IOrgReposAgExtended_V3QueryVariables = {
    organization: orgName,
    pageSize: page_size,
    after: null
  }
  const data = await reposExQueryGraphQlSDK(gitHubGraphQLUrl, pat, variables)
  const repo =
    data.organization?.repositories?.edges &&
    data.organization?.repositories?.edges.length > 0
      ? data.organization?.repositories?.edges[0]?.node
      : null

  if (repo === null) return null
  if (JSON.stringify(repo) === JSON.stringify({})) return null

  let repoReturned = null

  if (repo !== null && repo !== undefined) {
    repoReturned = {
      id: repo.id || '',
      url: repo.url || '',
      lastPushToDefaultBranch: null
    }

    // Get last commit
    const lastCommitTarget = repo.lastPushToDefaultBranch?.target

    if (lastCommitTarget !== null && lastCommitTarget !== undefined) {
      const history = lastCommitTarget.history

      // just to see what history is
      console.log(history)
    }
  }

  return repoReturned
}

构建错误是

src/sdk/v3/repos_extended.ts:70:40 - error TS2339: Property 'history' does not exist on type '{} | { history: { edges?: ({ node?: { message: string; pushedDate?: any; committedDate: any; } | null | undefined; } | null | undefined)[] | null | undefined; }; }'.
  Property 'history' does not exist on type '{}'.

70       const history = lastCommitTarget.history
                                          ~~~~~~~

src/sdk/v3/repos_extended.ts:77:3 - error TS2322: Type '{ id: string; url: any; lastPushToDefaultBranch: null; } | null' is not assignable to type 'IRepoExRefactored | null'.
  Type '{ id: string; url: any; lastPushToDefaultBranch: null; }' is not assignable to type 'IRepoExRefactored'.
    Types of property 'lastPushToDefaultBranch' are incompatible.
      Type 'null' is not assignable to type '{ name: string; message: string | null | undefined; pushedDate?: string | null | undefined; committedDate: string | null | undefined; status?: string | undefined; } | undefined'.

77   return repoReturned

Codegen'd sdk 在 repo 中- 我知道我不应该签入 gen'd SDK - 这仅供参考以帮助理解基础类型。

我的仓库在这里

在@Xirzec 的帮助下,我得到了正确的代码。 您可以清理它以满足您的需要。

简单的解释是:

declare var x: {} | {'a':string, 'b': number } | null | undefined

// combination of null/undefined check and property `in` object
if(x !==null && x !== undefined && "a" in x ){
    // x is not empty or null or undefined
    console.log(x.a)
}

这个具体场景是:

// THIS IS THE FIX TO GET PAST THROUGH HISTORY
const lastCommitTarget = repo.lastPushToDefaultBranch?.target
let commit

if (
  lastCommitTarget !== null &&
  lastCommitTarget !== undefined &&
  'history' in lastCommitTarget
) {
  const history = lastCommitTarget.history

  if (
    history?.edges !== null &&
    history?.edges !== undefined &&
    history?.edges.length > 0
  ) {
    const node = history?.edges[0]?.node

    // THIS IS THE COMMIT
    console.log(node);
  }
}  

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM