diff --git a/src/platforms/GitHub/DOMHelper.ts b/src/platforms/GitHub/DOMHelper.ts index 4d2d60c..b71a51f 100644 --- a/src/platforms/GitHub/DOMHelper.ts +++ b/src/platforms/GitHub/DOMHelper.ts @@ -2,7 +2,7 @@ import { raiseError } from 'analytics' import { Clippy, ClippyClassName } from 'components/Clippy' import React from 'react' import * as s from 'superstruct' -import { $ } from 'utils/$' +import { $, make$ } from 'utils/$' import { formatClass, parseIntFromElement } from 'utils/DOMHelper' import { renderReact } from 'utils/general' import { embeddedDataStruct } from './embeddedDataStructures' @@ -39,6 +39,7 @@ const selectors = { app: 'script[type="application/json"][data-target="react-app.embeddedData"]', reposOverview: '[partial-name="repos-overview"] script[type="application/json"][data-target="react-partial.embeddedData"]', + pullRequest: 'script[type="application/json"][data-target="react-app.embeddedData"]', }, }, } @@ -79,7 +80,12 @@ function resolveEmbeddedReposOverviewData() { return getMetaFromPayload(data.props.initialPayload) } -export function resolveEmbeddedData(): { +export function resolveEmbeddedPullRequestData(doc: Document) { + const data = getDOMJSON(selectors.globalNavigation.embeddedData.pullRequest, make$(doc)) + if (s.is(data, embeddedDataStruct.pullRequest)) return data +} + +export function resolveMetaFromEmbeddedData(): { defaultBranch: string metaData: MetaData } | void { @@ -87,7 +93,7 @@ export function resolveEmbeddedData(): { } export function resolveMeta(): Partial { - const dataFromJSON = resolveEmbeddedData() + const dataFromJSON = resolveMetaFromEmbeddedData() if (dataFromJSON) return dataFromJSON.metaData const metaData = { diff --git a/src/platforms/GitHub/embeddedDataStructures.ts b/src/platforms/GitHub/embeddedDataStructures.ts index 676b93e..2425b7a 100644 --- a/src/platforms/GitHub/embeddedDataStructures.ts +++ b/src/platforms/GitHub/embeddedDataStructures.ts @@ -65,10 +65,36 @@ const reposOverview = s.object({ appPayload: s.unknown(), }), }) + const app = s.object({ payload: repoPayload, }) +const diffSummary = s.object({ + changeType: s.string(), + highestAnnotationLevel: s.nullable(s.string()), + isCodeowner: s.nullable(s.boolean()), + isManifestFile: s.boolean(), + isSymlink: s.boolean(), + isVendored: s.boolean(), + linesAdded: s.number(), + linesChanged: s.number(), + linesDeleted: s.number(), + markedAsViewed: s.boolean(), + path: s.string(), + pathDigest: s.string(), +}) + +export type DiffSummary = s.Infer + +const pullRequest = s.object({ + payload: s.object({ + pullRequestsFilesRoute: s.object({ + diffSummaries: s.array(diffSummary), + }), + }), +}) + export const embeddedDataStruct = { repo, user, @@ -78,4 +104,5 @@ export const embeddedDataStruct = { repoPayload, reposOverview, app, + pullRequest, } diff --git a/src/platforms/GitHub/getPullRequestTreeData.ts b/src/platforms/GitHub/getPullRequestTreeData.ts index be4a1fb..1eadf5f 100644 --- a/src/platforms/GitHub/getPullRequestTreeData.ts +++ b/src/platforms/GitHub/getPullRequestTreeData.ts @@ -1,7 +1,13 @@ import { map } from 'utils/map' import { sanitizedLocation } from 'utils/URLHelper' import * as API from './API' -import { getPRDiffTotalStat, getPullRequestFilesCount, isInPullFilesPage } from './DOMHelper' +import { + getPRDiffTotalStat, + getPullRequestFilesCount, + isInPullFilesPage, + resolveEmbeddedPullRequestData, +} from './DOMHelper' +import { DiffSummary } from './embeddedDataStructures' import { processTree } from './index' import { getCommentsMap } from './utils' @@ -108,34 +114,10 @@ function resolveFileHashMap(docs: Document[]) { } function resolveDiffSummaryMap(docs: Document[]) { - type DiffSummary = { - changeType: 'MODIFIED' - highestAnnotationLevel: null - isCodeowner: null - isManifestFile: boolean - isSymlink: boolean - isVendored: boolean - linesAdded: number - linesChanged: number - linesDeleted: number - markedAsViewed: boolean - path: string - pathDigest: string - } - - type PartialReactAppEmbeddedData = { - payload: { - pullRequestsFilesRoute: { - diffSummaries: [DiffSummary] - } - } - } - return docs - .map(doc => doc.querySelector('script[data-target="react-app.embeddedData"]')?.textContent) - .map(element => { + .map(resolveEmbeddedPullRequestData) + .map(json => { try { - const json = element ? (JSON.parse(element) as PartialReactAppEmbeddedData) : null return json?.payload.pullRequestsFilesRoute.diffSummaries } catch (error) { return null diff --git a/src/platforms/GitHub/index.ts b/src/platforms/GitHub/index.ts index 66c0f26..42463e8 100644 --- a/src/platforms/GitHub/index.ts +++ b/src/platforms/GitHub/index.ts @@ -139,7 +139,7 @@ export const GitHub: Platform = { return metaData }, async getDefaultBranchName({ userName, repoName }, accessToken) { - const dataFromJSON = DOMHelper.resolveEmbeddedData() + const dataFromJSON = DOMHelper.resolveMetaFromEmbeddedData() if (dataFromJSON?.defaultBranch) return dataFromJSON.defaultBranch return (await API.getRepoMeta(userName, repoName, accessToken)).default_branch