Support commit diffs (#8)
* cra boilerplate * Dummy chrome extension * eslint and working url popup * content script and dummy messaging * replace .obj diffs with dummy test * comment and in-order multiple type support * get pull api data from url * README title and desc * api/elements match with filename check * github token signin signout * manifest v3, service request for CORS * working kittycad api in service worker * First real background message * Clean up, better types * Fix settings * multiservice settings * Tweaks * WIP: download file * Working downloads and kittycad conversion * Inject react, add three dependencies * Working stl canvas * primer for github-like style * Loading before model * diff colors * colorMode auto * Popup clean up * clean up * Working loading * Logos * Add GitHub CI * Working test * yarn test in ci * Little tweak * Update README * component tests * Better test * Clean up * UserCard test * working caddiff test * Note * Rename App to Settings * storage test * Clean up * Clean up content script * further content cleanup * Fix test * Little tweaks to modelview * More tests and testing * Regex fix * LFS file download test * prettier config from kittycad/website * Little tweaks * comment * log level * Tweaks * README update * more prettier * comment * Irrelevant comment * No .vscode and readme update * Remove .vscode * Package.json update after vscode removal * Working commit diff * Start cleaning up * Clean up * Add artifact upload * return when matched * Better test * Clean up * prettier * Clean up html snippet
This commit is contained in:
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
@ -23,3 +23,7 @@ jobs:
|
|||||||
- run: yarn build
|
- run: yarn build
|
||||||
|
|
||||||
- run: yarn test
|
- run: yarn test
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
path: build
|
||||||
|
@ -4,6 +4,7 @@ import {
|
|||||||
KittycadUser,
|
KittycadUser,
|
||||||
Message,
|
Message,
|
||||||
MessageGetFileDiff,
|
MessageGetFileDiff,
|
||||||
|
MessageGetGithubCommitData,
|
||||||
MessageGetGithubPullFilesData,
|
MessageGetGithubPullFilesData,
|
||||||
MessageIds,
|
MessageIds,
|
||||||
MessageResponse,
|
MessageResponse,
|
||||||
@ -86,6 +87,16 @@ chrome.runtime.onMessage.addListener(
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (message.id === MessageIds.GetGithubCommit) {
|
||||||
|
const { owner, repo, sha } =
|
||||||
|
message.data as MessageGetGithubCommitData
|
||||||
|
github.rest.repos
|
||||||
|
.getCommit({ owner, repo, ref: sha })
|
||||||
|
.then(r => sendResponse(r.data))
|
||||||
|
.catch(e => sendResponse(e))
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
if (message.id === MessageIds.GetGithubUser) {
|
if (message.id === MessageIds.GetGithubUser) {
|
||||||
github.rest.users
|
github.rest.users
|
||||||
.getAuthenticated()
|
.getAuthenticated()
|
||||||
|
@ -2,12 +2,11 @@ import React from 'react'
|
|||||||
import { createRoot } from 'react-dom/client'
|
import { createRoot } from 'react-dom/client'
|
||||||
import { CadDiff } from '../components/CadDiff'
|
import { CadDiff } from '../components/CadDiff'
|
||||||
import { Loading } from '../components/Loading'
|
import { Loading } from '../components/Loading'
|
||||||
import { isFilenameSupported } from './diff'
|
import { Commit, DiffEntry, FileDiff, Message, MessageIds, Pull } from './types'
|
||||||
import { DiffEntry, FileDiff, Message, MessageIds, Pull } from './types'
|
|
||||||
import {
|
import {
|
||||||
getGithubUrlParams,
|
getGithubPullUrlParams,
|
||||||
getWebPullElements,
|
mapInjectableDiffElements,
|
||||||
getInjectablePullElements,
|
getGithubCommitUrlParams,
|
||||||
} from './web'
|
} from './web'
|
||||||
|
|
||||||
// https://github.com/OctoLinker/injection
|
// https://github.com/OctoLinker/injection
|
||||||
@ -15,34 +14,20 @@ import {
|
|||||||
// no ts support
|
// no ts support
|
||||||
const gitHubInjection = require('github-injection')
|
const gitHubInjection = require('github-injection')
|
||||||
|
|
||||||
async function injectPullDiff(
|
async function injectDiff(
|
||||||
owner: string,
|
owner: string,
|
||||||
repo: string,
|
repo: string,
|
||||||
pull: number,
|
sha: string,
|
||||||
|
parentSha: string,
|
||||||
|
files: DiffEntry[],
|
||||||
document: Document
|
document: Document
|
||||||
) {
|
) {
|
||||||
const allApiFiles = await chrome.runtime.sendMessage<Message, DiffEntry[]>({
|
const map = mapInjectableDiffElements(document, files)
|
||||||
id: MessageIds.GetGithubPullFiles,
|
for (const { element } of map) {
|
||||||
data: { owner, repo, pull },
|
|
||||||
})
|
|
||||||
const apiFiles = allApiFiles.filter(f => isFilenameSupported(f.filename))
|
|
||||||
console.log(`Found ${apiFiles.length} supported files with the API`)
|
|
||||||
|
|
||||||
const elements = getWebPullElements(document)
|
|
||||||
console.log(`Found ${elements.length} elements in the web page`)
|
|
||||||
|
|
||||||
const injectableElements = getInjectablePullElements(elements, apiFiles)
|
|
||||||
for (const { element } of injectableElements) {
|
|
||||||
createRoot(element).render(React.createElement(Loading))
|
createRoot(element).render(React.createElement(Loading))
|
||||||
}
|
}
|
||||||
|
|
||||||
const pullData = await chrome.runtime.sendMessage<Message, Pull>({
|
for (const { element, file } of map) {
|
||||||
id: MessageIds.GetGithubPull,
|
|
||||||
data: { owner, repo, pull },
|
|
||||||
})
|
|
||||||
const sha = pullData.head.sha
|
|
||||||
const parentSha = pullData.base.sha
|
|
||||||
for (const { element, file } of injectableElements) {
|
|
||||||
const fileDiff = await chrome.runtime.sendMessage<Message, FileDiff>({
|
const fileDiff = await chrome.runtime.sendMessage<Message, FileDiff>({
|
||||||
id: MessageIds.GetFileDiff,
|
id: MessageIds.GetFileDiff,
|
||||||
data: { owner, repo, sha, parentSha, file },
|
data: { owner, repo, sha, parentSha, file },
|
||||||
@ -51,17 +36,54 @@ async function injectPullDiff(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function injectPullDiff(
|
||||||
|
owner: string,
|
||||||
|
repo: string,
|
||||||
|
pull: number,
|
||||||
|
document: Document
|
||||||
|
) {
|
||||||
|
const files = await chrome.runtime.sendMessage<Message, DiffEntry[]>({
|
||||||
|
id: MessageIds.GetGithubPullFiles,
|
||||||
|
data: { owner, repo, pull },
|
||||||
|
})
|
||||||
|
const pullData = await chrome.runtime.sendMessage<Message, Pull>({
|
||||||
|
id: MessageIds.GetGithubPull,
|
||||||
|
data: { owner, repo, pull },
|
||||||
|
})
|
||||||
|
const sha = pullData.head.sha
|
||||||
|
const parentSha = pullData.base.sha
|
||||||
|
await injectDiff(owner, repo, sha, parentSha, files, document)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function injectCommitDiff(
|
||||||
|
owner: string,
|
||||||
|
repo: string,
|
||||||
|
sha: string,
|
||||||
|
document: Document
|
||||||
|
) {
|
||||||
|
const commit = await chrome.runtime.sendMessage<Message, Commit>({
|
||||||
|
id: MessageIds.GetGithubCommit,
|
||||||
|
data: { owner, repo, sha },
|
||||||
|
})
|
||||||
|
if (!commit.files) throw Error('Found no file changes in commit')
|
||||||
|
if (!commit.parents.length) throw Error('Found no commit parent')
|
||||||
|
const parentSha = commit.parents[0].sha
|
||||||
|
injectDiff(owner, repo, sha, parentSha, commit.files, document)
|
||||||
|
}
|
||||||
|
|
||||||
gitHubInjection(async () => {
|
gitHubInjection(async () => {
|
||||||
const params = getGithubUrlParams(window.location.href)
|
const url = window.location.href
|
||||||
if (!params) {
|
const pullParams = getGithubPullUrlParams(url)
|
||||||
console.log("URL doesn't match pull request pattern.")
|
if (pullParams) {
|
||||||
|
const { owner, repo, pull } = pullParams
|
||||||
|
await injectPullDiff(owner, repo, pull, window.document)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const { owner, repo, pull } = params
|
|
||||||
console.log('Found pull request diff URL', owner, repo, pull)
|
const commitParams = getGithubCommitUrlParams(url)
|
||||||
try {
|
if (commitParams) {
|
||||||
await injectPullDiff(owner, repo, pull, window.document)
|
const { owner, repo, sha } = commitParams
|
||||||
} catch (e) {
|
await injectCommitDiff(owner, repo, sha, window.document)
|
||||||
console.error(e)
|
return
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -11,6 +11,7 @@ export type DiffEntry = components['schemas']['diff-entry']
|
|||||||
export type ContentFile = components['schemas']['content-file']
|
export type ContentFile = components['schemas']['content-file']
|
||||||
export type User = components['schemas']['simple-user']
|
export type User = components['schemas']['simple-user']
|
||||||
export type Pull = components['schemas']['pull-request']
|
export type Pull = components['schemas']['pull-request']
|
||||||
|
export type Commit = components['schemas']['commit']
|
||||||
|
|
||||||
// chrome extension
|
// chrome extension
|
||||||
|
|
||||||
@ -27,6 +28,7 @@ export enum MessageIds {
|
|||||||
GetKittycadUser = 'GetKittyCadUser',
|
GetKittycadUser = 'GetKittyCadUser',
|
||||||
GetFileDiff = 'GetFileDiff',
|
GetFileDiff = 'GetFileDiff',
|
||||||
GetGithubPull = 'GetGithubPull',
|
GetGithubPull = 'GetGithubPull',
|
||||||
|
GetGithubCommit = 'GetGithubCommit',
|
||||||
}
|
}
|
||||||
|
|
||||||
export type MessageGetGithubPullFilesData = {
|
export type MessageGetGithubPullFilesData = {
|
||||||
@ -35,6 +37,12 @@ export type MessageGetGithubPullFilesData = {
|
|||||||
pull: number
|
pull: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type MessageGetGithubCommitData = {
|
||||||
|
owner: string
|
||||||
|
repo: string
|
||||||
|
sha: string
|
||||||
|
}
|
||||||
|
|
||||||
export type MessageGetFileDiff = {
|
export type MessageGetFileDiff = {
|
||||||
owner: string
|
owner: string
|
||||||
repo: string
|
repo: string
|
||||||
@ -49,12 +57,17 @@ export type MessageSaveToken = {
|
|||||||
|
|
||||||
export type Message = {
|
export type Message = {
|
||||||
id: MessageIds
|
id: MessageIds
|
||||||
data?: MessageGetGithubPullFilesData | MessageSaveToken | MessageGetFileDiff
|
data?:
|
||||||
|
| MessageGetGithubPullFilesData
|
||||||
|
| MessageGetGithubCommitData
|
||||||
|
| MessageSaveToken
|
||||||
|
| MessageGetFileDiff
|
||||||
}
|
}
|
||||||
|
|
||||||
export type MessageResponse =
|
export type MessageResponse =
|
||||||
| DiffEntry[]
|
| DiffEntry[]
|
||||||
| Pull
|
| Pull
|
||||||
|
| Commit
|
||||||
| User
|
| User
|
||||||
| KittycadUser
|
| KittycadUser
|
||||||
| MessageSaveToken
|
| MessageSaveToken
|
||||||
|
@ -1,22 +1,50 @@
|
|||||||
import { DiffEntry } from './types'
|
import { DiffEntry } from './types'
|
||||||
import {
|
import {
|
||||||
getElementFilename,
|
getElementFilename,
|
||||||
getGithubUrlParams,
|
getGithubCommitUrlParams,
|
||||||
getInjectablePullElements,
|
getGithubPullUrlParams,
|
||||||
getWebPullElements,
|
mapInjectableDiffElements,
|
||||||
|
getSupportedWebDiffElements,
|
||||||
} from './web'
|
} from './web'
|
||||||
|
|
||||||
const githubPullHtmlSnippet = `
|
const githubPullHtmlSnippet = `
|
||||||
<div class="file js-file js-details-container js-targetable-element show-inline-notes Details Details--on open js-tagsearch-file" data-file-type=".obj">
|
<div class="file" data-file-type=".json">
|
||||||
<div class="file-header d-flex flex-md-row flex-column flex-md-items-center file-header--expandable js-file-header js-skip-tagsearch sticky-file-header js-position-sticky js-position-sticky-stacked">
|
<div class="file-header">
|
||||||
<div class="file-info flex-auto min-width-0 mb-md-0 mb-2">
|
<div class="file-info">
|
||||||
<span class="Truncate">
|
<span class="Truncate">
|
||||||
<a title="samples/file_center_of_mass/output.obj" class="Link--primary Truncate-text" href="#diff-5f8df244900f6383db3354c02b8a984a044b272e6bfe4cacc1ec8d4892ad3e21">samples/file_center_of_mass/output.obj</a>
|
<a title="samples/file_center_of_mass/output.json">samples/file_center_of_mass/output.json</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="js-file-content">
|
||||||
|
<div class="data highlight js-blob-wrapper" style="">
|
||||||
|
// was a code diff
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="file" data-file-type=".obj">
|
||||||
|
<div class="file-header">
|
||||||
|
<div class="file-info">
|
||||||
|
<span class="Truncate">
|
||||||
|
<a title="samples/file_center_of_mass/output.obj">samples/file_center_of_mass/output.obj</a>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="js-file-content">
|
||||||
|
<div class="data highlight empty">
|
||||||
|
Git LFS file not shown
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="js-file-content Details-content--hidden position-relative">
|
<div class="file" data-file-type=".obj">
|
||||||
|
<div class="file-header">
|
||||||
|
<div class="file-info">
|
||||||
|
<span class="Truncate">
|
||||||
|
<a title="seesaw.obj">seesaw.obj</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="js-file-content">
|
||||||
<div class="data highlight empty">
|
<div class="data highlight empty">
|
||||||
Git LFS file not shown
|
Git LFS file not shown
|
||||||
</div>
|
</div>
|
||||||
@ -30,6 +58,21 @@ const githubPullHtmlDocument = parser.parseFromString(
|
|||||||
)
|
)
|
||||||
|
|
||||||
const githubPullFilesSample: DiffEntry[] = [
|
const githubPullFilesSample: DiffEntry[] = [
|
||||||
|
{
|
||||||
|
sha: 'c24ca35738a99e6bf834e0ee141db27c62fce499',
|
||||||
|
filename: 'samples/file_center_of_mass/output.json',
|
||||||
|
status: 'modified',
|
||||||
|
additions: 3,
|
||||||
|
deletions: 3,
|
||||||
|
changes: 6,
|
||||||
|
blob_url:
|
||||||
|
'https://github.com/KittyCAD/litterbox/blob/11510a02d8294cac5943b8ebdc416170f5b738b5/samples%2Ffile_center_of_mass%2Foutput.json',
|
||||||
|
raw_url:
|
||||||
|
'https://github.com/KittyCAD/litterbox/raw/11510a02d8294cac5943b8ebdc416170f5b738b5/samples%2Ffile_center_of_mass%2Foutput.json',
|
||||||
|
contents_url:
|
||||||
|
'https://api.github.com/repos/KittyCAD/litterbox/contents/samples%2Ffile_center_of_mass%2Foutput.json?ref=11510a02d8294cac5943b8ebdc416170f5b738b5',
|
||||||
|
patch: '@@ -1,8 +1,8 @@\n {\n "title": "output.json",\n "center_of_mass": [\n- -1.7249649e-08,\n- 2.96097,\n- -0.36378\n+ -0.12732863,\n+ 1.0363415,\n+ -9.5138624e-08\n ]\n }\n\\ No newline at end of file',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
sha: '2f35d962a711bea7a8bf57481b8717f7dedbe1c5',
|
sha: '2f35d962a711bea7a8bf57481b8717f7dedbe1c5',
|
||||||
filename: 'samples/file_center_of_mass/output.obj',
|
filename: 'samples/file_center_of_mass/output.obj',
|
||||||
@ -45,12 +88,27 @@ const githubPullFilesSample: DiffEntry[] = [
|
|||||||
'https://api.github.com/repos/KittyCAD/litterbox/contents/samples%2Ffile_center_of_mass%2Foutput.obj?ref=11510a02d8294cac5943b8ebdc416170f5b738b5',
|
'https://api.github.com/repos/KittyCAD/litterbox/contents/samples%2Ffile_center_of_mass%2Foutput.obj?ref=11510a02d8294cac5943b8ebdc416170f5b738b5',
|
||||||
patch: '@@ -1,3 +1,3 @@\n version https://git-lfs.github.com/spec/v1\n-oid sha256:2a07f53add3eee88b80a0bbe0412cf91df3d3bd9d45934ce849e0440eff90ee1\n-size 62122\n+oid sha256:0c0eb961e7e0589d83693335408b90d3b8adae9f4054c3e396c6eedbc5ed16ec\n+size 62545',
|
patch: '@@ -1,3 +1,3 @@\n version https://git-lfs.github.com/spec/v1\n-oid sha256:2a07f53add3eee88b80a0bbe0412cf91df3d3bd9d45934ce849e0440eff90ee1\n-size 62122\n+oid sha256:0c0eb961e7e0589d83693335408b90d3b8adae9f4054c3e396c6eedbc5ed16ec\n+size 62545',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
sha: '2f35d962a711bea7a8bf57481b8717f7dedbe1c5',
|
||||||
|
filename: 'seesaw.obj',
|
||||||
|
status: 'modified',
|
||||||
|
additions: 2,
|
||||||
|
deletions: 2,
|
||||||
|
changes: 4,
|
||||||
|
blob_url:
|
||||||
|
'https://github.com/KittyCAD/litterbox/blob/11510a02d8294cac5943b8ebdc416170f5b738b5/seesaw.obj',
|
||||||
|
raw_url:
|
||||||
|
'https://github.com/KittyCAD/litterbox/raw/11510a02d8294cac5943b8ebdc416170f5b738b5/seesaw.obj',
|
||||||
|
contents_url:
|
||||||
|
'https://api.github.com/repos/KittyCAD/litterbox/contents/seesaw.obj?ref=11510a02d8294cac5943b8ebdc416170f5b738b5',
|
||||||
|
patch: '@@ -1,3 +1,3 @@\n version https://git-lfs.github.com/spec/v1\n-oid sha256:2a07f53add3eee88b80a0bbe0412cf91df3d3bd9d45934ce849e0440eff90ee1\n-size 62122\n+oid sha256:0c0eb961e7e0589d83693335408b90d3b8adae9f4054c3e396c6eedbc5ed16ec\n+size 62545',
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
describe('Function getGithubUrlParams', () => {
|
describe('Function getGithubPullUrlParams', () => {
|
||||||
it('gets params out of a valid github pull request link', () => {
|
it('gets params out of a valid github pull request link', () => {
|
||||||
const pullUrl = 'https://github.com/KittyCAD/kittycad.ts/pull/67/files'
|
const url = 'https://github.com/KittyCAD/kittycad.ts/pull/67/files'
|
||||||
const params = getGithubUrlParams(pullUrl)
|
const params = getGithubPullUrlParams(url)
|
||||||
expect(params).toBeDefined()
|
expect(params).toBeDefined()
|
||||||
const { owner, repo, pull } = params!
|
const { owner, repo, pull } = params!
|
||||||
expect(owner).toEqual('KittyCAD')
|
expect(owner).toEqual('KittyCAD')
|
||||||
@ -59,31 +117,50 @@ describe('Function getGithubUrlParams', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it("doesn't match other URLs", () => {
|
it("doesn't match other URLs", () => {
|
||||||
expect(getGithubUrlParams('http://google.com')).toBeUndefined()
|
expect(getGithubPullUrlParams('http://google.com')).toBeUndefined()
|
||||||
expect(
|
expect(
|
||||||
getGithubUrlParams('https://github.com/KittyCAD/litterbox')
|
getGithubPullUrlParams('https://github.com/KittyCAD/litterbox')
|
||||||
|
).toBeUndefined()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('Function getGithubCommitUrlParams', () => {
|
||||||
|
it('gets params out of a valid github commit link', () => {
|
||||||
|
const url =
|
||||||
|
'https://github.com/KittyCAD/litterbox/commit/4ddf899550addf41d6bf1b790ce79e46501411b3'
|
||||||
|
const params = getGithubCommitUrlParams(url)
|
||||||
|
expect(params).toBeDefined()
|
||||||
|
const { owner, repo, sha } = params!
|
||||||
|
expect(owner).toEqual('KittyCAD')
|
||||||
|
expect(repo).toEqual('litterbox')
|
||||||
|
expect(sha).toEqual('4ddf899550addf41d6bf1b790ce79e46501411b3')
|
||||||
|
})
|
||||||
|
|
||||||
|
it("doesn't match other URLs", () => {
|
||||||
|
expect(getGithubPullUrlParams('http://google.com')).toBeUndefined()
|
||||||
|
expect(
|
||||||
|
getGithubPullUrlParams('https://github.com/KittyCAD/litterbox')
|
||||||
).toBeUndefined()
|
).toBeUndefined()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('finds web elements for supported files', () => {
|
it('finds web elements for supported files', () => {
|
||||||
const elements = getWebPullElements(githubPullHtmlDocument)
|
const elements = getSupportedWebDiffElements(githubPullHtmlDocument)
|
||||||
expect(elements).toHaveLength(1)
|
expect(elements).toHaveLength(2)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('finds the filename of a supported file element', () => {
|
it('finds the filename of a supported file element', () => {
|
||||||
const elements = getWebPullElements(githubPullHtmlDocument)
|
const elements = getSupportedWebDiffElements(githubPullHtmlDocument)
|
||||||
const filename = getElementFilename(elements[0])
|
const filename = getElementFilename(elements[0])
|
||||||
expect(filename).toEqual('samples/file_center_of_mass/output.obj')
|
expect(filename).toEqual('samples/file_center_of_mass/output.obj')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('finds injectable elements from html and api results', () => {
|
it('finds injectable elements from html and api results', () => {
|
||||||
const elements = getWebPullElements(githubPullHtmlDocument)
|
const injectableElements = mapInjectableDiffElements(
|
||||||
const injectableElements = getInjectablePullElements(
|
githubPullHtmlDocument,
|
||||||
elements,
|
|
||||||
githubPullFilesSample
|
githubPullFilesSample
|
||||||
)
|
)
|
||||||
expect(injectableElements).toHaveLength(1)
|
expect(injectableElements).toHaveLength(2)
|
||||||
const { element, file } = injectableElements[0]
|
const { element, file } = injectableElements[0]
|
||||||
expect(element).toBeDefined()
|
expect(element).toBeDefined()
|
||||||
expect(file).toBeDefined()
|
expect(file).toBeDefined()
|
||||||
|
@ -1,16 +1,15 @@
|
|||||||
import { supportedSrcFormats } from './diff'
|
import { isFilenameSupported, supportedSrcFormats } from './diff'
|
||||||
import { DiffEntry } from './types'
|
import { DiffEntry } from './types'
|
||||||
|
|
||||||
export type GithubUrlParams =
|
export type GithubPullUrlParams = {
|
||||||
| {
|
owner: string
|
||||||
owner: string
|
repo: string
|
||||||
repo: string
|
pull: number
|
||||||
pull: number
|
}
|
||||||
}
|
|
||||||
| undefined
|
|
||||||
|
|
||||||
export function getGithubUrlParams(url: string): GithubUrlParams {
|
export function getGithubPullUrlParams(
|
||||||
// TODO: support commit diff
|
url: string
|
||||||
|
): GithubPullUrlParams | undefined {
|
||||||
const pullRe =
|
const pullRe =
|
||||||
/https:\/\/github\.com\/([a-zA-Z0-9_.-]+)\/([a-zA-Z0-9_.-]+)\/pull\/(\d+)\/files/
|
/https:\/\/github\.com\/([a-zA-Z0-9_.-]+)\/([a-zA-Z0-9_.-]+)\/pull\/(\d+)\/files/
|
||||||
const result = pullRe.exec(url)
|
const result = pullRe.exec(url)
|
||||||
@ -19,10 +18,32 @@ export function getGithubUrlParams(url: string): GithubUrlParams {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const [, owner, repo, pull] = result
|
const [, owner, repo, pull] = result
|
||||||
|
console.log('Found a supported Github Pull Request URL:', owner, repo, pull)
|
||||||
return { owner, repo, pull: parseInt(pull) }
|
return { owner, repo, pull: parseInt(pull) }
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getWebPullElements(document: Document): HTMLElement[] {
|
export type GithubCommitUrlParams = {
|
||||||
|
owner: string
|
||||||
|
repo: string
|
||||||
|
sha: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getGithubCommitUrlParams(
|
||||||
|
url: string
|
||||||
|
): GithubCommitUrlParams | undefined {
|
||||||
|
const pullRe =
|
||||||
|
/https:\/\/github\.com\/([a-zA-Z0-9_.-]+)\/([a-zA-Z0-9_.-]+)\/commit\/(\w+)/
|
||||||
|
const result = pullRe.exec(url)
|
||||||
|
if (!result) {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
const [, owner, repo, sha] = result
|
||||||
|
console.log('Found a supported Github Commit URL:', owner, repo, sha)
|
||||||
|
return { owner, repo, sha }
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getSupportedWebDiffElements(document: Document): HTMLElement[] {
|
||||||
const fileTypeSelectors = Array.from(supportedSrcFormats).map(
|
const fileTypeSelectors = Array.from(supportedSrcFormats).map(
|
||||||
t => `.file[data-file-type=".${t}"]`
|
t => `.file[data-file-type=".${t}"]`
|
||||||
)
|
)
|
||||||
@ -37,19 +58,25 @@ export function getElementFilename(element: HTMLElement) {
|
|||||||
return titleElement.getAttribute('title')
|
return titleElement.getAttribute('title')
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getInjectablePullElements(
|
export function mapInjectableDiffElements(
|
||||||
elements: HTMLElement[],
|
document: Document,
|
||||||
files: DiffEntry[]
|
files: DiffEntry[]
|
||||||
) {
|
) {
|
||||||
if (elements.length !== files.length) {
|
const supportedFiles = files.filter(f => isFilenameSupported(f.filename))
|
||||||
|
console.log(`Found ${supportedFiles.length} supported files with the API`)
|
||||||
|
|
||||||
|
const supportedElements = getSupportedWebDiffElements(document)
|
||||||
|
console.log(`Found ${supportedElements.length} elements in the web page`)
|
||||||
|
|
||||||
|
if (supportedElements.length !== supportedFiles.length) {
|
||||||
throw Error(
|
throw Error(
|
||||||
`elements and files have different length. Got ${elements.length} and ${files.length}`
|
`elements and files have different length. Got ${supportedElements.length} and ${files.length}`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const injectableElements = []
|
const injectableElements: { element: HTMLElement; file: DiffEntry }[] = []
|
||||||
for (const [index, element] of elements.entries()) {
|
for (const [index, element] of supportedElements.entries()) {
|
||||||
const apiFile = files[index]
|
const apiFile = supportedFiles[index]
|
||||||
const filename = getElementFilename(element)
|
const filename = getElementFilename(element)
|
||||||
if (filename !== apiFile.filename) {
|
if (filename !== apiFile.filename) {
|
||||||
throw Error(
|
throw Error(
|
||||||
|
Reference in New Issue
Block a user