diff options
author | 2021-09-26 10:27:40 +0530 | |
---|---|---|
committer | 2021-09-26 11:57:40 +0700 | |
commit | fdd2e33dbc61675685eaa914f869c955a305764c (patch) | |
tree | 4602bddc1bd523e8bb8cc41d61a9e9e45964eef8 /source/features/restore-file.tsx | |
parent | 37fa4677f1ecf26d7176c8d9d43f8a4db6d5d902 (diff) | |
download | refined-github-fdd2e33dbc61675685eaa914f869c955a305764c.tar.gz refined-github-fdd2e33dbc61675685eaa914f869c955a305764c.tar.zst refined-github-fdd2e33dbc61675685eaa914f869c955a305764c.zip |
Use safer saving mechanism in `restore-file` (#4803)
Co-authored-by: Federico Brigante <me@fregante.com>
Diffstat (limited to 'source/features/restore-file.tsx')
-rw-r--r-- | source/features/restore-file.tsx | 58 |
1 files changed, 37 insertions, 21 deletions
diff --git a/source/features/restore-file.tsx b/source/features/restore-file.tsx index 04a84595..95df3862 100644 --- a/source/features/restore-file.tsx +++ b/source/features/restore-file.tsx @@ -1,13 +1,11 @@ import React from 'dom-chef'; import select from 'select-dom'; import onetime from 'onetime'; -import pushForm from 'push-form'; import delegate from 'delegate-it'; import * as pageDetect from 'github-url-detection'; import features from '.'; import * as api from '../github-helpers/api'; -import fetchDom from '../helpers/fetch-dom'; import showToast from '../github-helpers/toast'; import {getConversationNumber} from '../github-helpers'; @@ -25,6 +23,17 @@ const getBaseReference = onetime(async (): Promise<string> => { `); return repository.pullRequest.baseRefOid; }); +const getHeadReference = async (): Promise<string> => { + // Get the sha of the latest commit to the PR, required to create a new commit + const {repository} = await api.v4(` + repository() { # Cache buster ${Math.random()} + pullRequest(number: ${getConversationNumber()!}) { + headRefOid + } + } + `); + return repository.pullRequest.headRefOid; +}; async function getFile(filePath: string): Promise<{isTruncated: boolean; text: string} | undefined> { const {repository} = await api.v4(` @@ -53,27 +62,34 @@ async function restoreFile(progress: (message: string) => void, menuItem: Elemen throw new Error('Restore failed: File too big'); } - let {pathname} = menuItem.previousElementSibling as HTMLAnchorElement; - // Check if file was deleted by PR - if (menuItem.closest('[data-file-deleted="true"]')) { - progress('Undeleting…'); - const [nameWithOwner, headBranch] = select('.head-ref')!.title.split(':'); - pathname = `/${nameWithOwner}/new/${headBranch}?filename=${filePath}`; - } else { - progress('Committing…'); - } + const [nameWithOwner, prBranch] = select('.head-ref')!.title.split(':'); + progress(menuItem.closest('[data-file-deleted="true"]') ? 'Undeleting…' : 'Committing…'); const content = file.text; - // This is either an `edit` or `create` form - const form = (await fetchDom(pathname, 'form.js-blob-form'))!; - form.elements.value.value = content; // Restore content (`value` is the name of the file content field) - form.elements.message.value = (form.elements.message as HTMLInputElement).placeholder - .replace(/^Create|^Update/, 'Restore'); - - const response = await pushForm(form); - if (!response.ok) { - throw new Error(response.statusText); - } + await api.v4(`mutation { + createCommitOnBranch(input: { + branch: { + repositoryNameWithOwner: "${nameWithOwner}", + branchName: "${prBranch}" + }, + expectedHeadOid: "${await getHeadReference()}", + fileChanges: { + additions: [ + { + path: "${filePath}", + contents: "${btoa(content)}" + } + ] + }, + message: { + headline: "Restore ${filePath}" + } + }) { + commit { + oid + } + } + }`); } const filesRestored = new WeakSet<HTMLButtonElement>(); |