|
1 | 1 | // The one door this feature uses to reach the API client. Named operations and |
2 | | -// hooks move here as they are extracted; until then it re-exports what the feature |
3 | | -// already calls, so no file in the feature imports `api/` directly. |
4 | | -export { ApiFailure, api, authHeaders, request } from "../../api/client"; |
| 2 | +// hooks live here; no file in the feature calls the transport directly. |
| 3 | +import { request, request as clientRequest } from "../../api/client"; |
| 4 | +import type { |
| 5 | + BrowserProfile, |
| 6 | + FileContent, |
| 7 | + FileEntry, |
| 8 | + LocalServer, |
| 9 | + PickedElement, |
| 10 | + PreviewTab, |
| 11 | + ProjectFileView, |
| 12 | + SearchHit, |
| 13 | + TerminalInfo, |
| 14 | +} from "../../api/types"; |
| 15 | +import type { PreviewCopy } from "../../generated/PreviewCopy"; |
| 16 | + |
| 17 | +const q = encodeURIComponent; |
| 18 | +const thread = (threadId: string) => `/api/threads/${q(threadId)}`; |
| 19 | +const previews = (threadId: string) => `${thread(threadId)}/previews`; |
| 20 | +const preview = (threadId: string, tabId: string) => `${previews(threadId)}/${q(tabId)}`; |
| 21 | + |
| 22 | +export type PreviewSize = { width: number; height: number }; |
| 23 | +export type PreviewView = { zoom?: number; appearance?: string; mobile?: boolean }; |
| 24 | +export type PreviewInput = { kind: string; x?: number; y?: number; delta_y?: number; text?: string }; |
| 25 | + |
| 26 | +export function listPreviewTabs(threadId: string, signal?: AbortSignal) { |
| 27 | + return request<PreviewTab[]>("GET", previews(threadId), undefined, signal); |
| 28 | +} |
| 29 | + |
| 30 | +export function openPreview(threadId: string, body: { url: string; width: number; height: number; private?: boolean; profile?: string }) { |
| 31 | + return request<PreviewTab>("POST", previews(threadId), body); |
| 32 | +} |
| 33 | + |
| 34 | +export function navigatePreview(threadId: string, tabId: string, url: string) { |
| 35 | + return request("POST", `${preview(threadId, tabId)}/navigate`, { url }); |
| 36 | +} |
| 37 | + |
| 38 | +export function changePreviewView(threadId: string, tabId: string, change: PreviewView) { |
| 39 | + return request("POST", `${preview(threadId, tabId)}/view`, change); |
| 40 | +} |
| 41 | + |
| 42 | +export function reloadPreview(threadId: string, tabId: string, hard: boolean) { |
| 43 | + return request("POST", `${preview(threadId, tabId)}/reload`, { hard }); |
| 44 | +} |
| 45 | + |
| 46 | +export function clearPreview(threadId: string, tabId: string, what: { cookies?: boolean; cache?: boolean }) { |
| 47 | + return request("POST", `${preview(threadId, tabId)}/clear`, what); |
| 48 | +} |
| 49 | + |
| 50 | +export function resizePreview(threadId: string, tabId: string, size: PreviewSize) { |
| 51 | + return request("POST", `${preview(threadId, tabId)}/resize`, size); |
| 52 | +} |
| 53 | + |
| 54 | +export function popOutPreview(threadId: string, tabId: string) { |
| 55 | + return request("POST", `${preview(threadId, tabId)}/window`); |
| 56 | +} |
| 57 | + |
| 58 | +export function stepPreviewHistory(threadId: string, tabId: string, back: boolean) { |
| 59 | + return request("POST", `${preview(threadId, tabId)}/history`, { back }); |
| 60 | +} |
| 61 | + |
| 62 | +export function closePreview(threadId: string, tabId: string) { |
| 63 | + return request("DELETE", preview(threadId, tabId)); |
| 64 | +} |
| 65 | + |
| 66 | +export function setPreviewControl(threadId: string, tabId: string, human: boolean) { |
| 67 | + return request("POST", `${preview(threadId, tabId)}/control`, { human }); |
| 68 | +} |
| 69 | + |
| 70 | +export function sendPreviewInput(threadId: string, tabId: string, body: PreviewInput) { |
| 71 | + return request("POST", `${preview(threadId, tabId)}/input`, body); |
| 72 | +} |
| 73 | + |
| 74 | +export function pickPreviewElement(threadId: string, tabId: string, point: { x: number; y: number }) { |
| 75 | + return request<PickedElement>("POST", `${preview(threadId, tabId)}/pick`, point); |
| 76 | +} |
| 77 | + |
| 78 | +export function copyPreview(threadId: string, tabId: string) { |
| 79 | + return request<PreviewCopy>("POST", `${preview(threadId, tabId)}/copy`); |
| 80 | +} |
| 81 | + |
| 82 | +export function previewRecordingEndpoint(threadId: string, tabId: string) { |
| 83 | + return `${preview(threadId, tabId)}/recording`; |
| 84 | +} |
| 85 | + |
| 86 | +/** The transport a recording picks between writes and reads with. */ |
| 87 | +export const previewTransport = clientRequest; |
| 88 | + |
| 89 | +export function choosePreviewFiles(threadId: string, tabId: string, files: string[]) { |
| 90 | + return request("POST", `${preview(threadId, tabId)}/chooser`, { files }); |
| 91 | +} |
| 92 | + |
| 93 | +export function listBrowserProfiles(signal?: AbortSignal) { |
| 94 | + return request<BrowserProfile[]>("GET", "/api/browser-profiles", undefined, signal); |
| 95 | +} |
| 96 | + |
| 97 | +export function listThreadServers(threadId: string, signal?: AbortSignal) { |
| 98 | + return request<LocalServer[]>("GET", `${thread(threadId)}/servers`, undefined, signal); |
| 99 | +} |
| 100 | + |
| 101 | +export function stopThreadServer(threadId: string, pid: number) { |
| 102 | + return request<void>("POST", `${thread(threadId)}/servers/${pid}/stop`); |
| 103 | +} |
| 104 | + |
| 105 | +export function readThreadFile(threadId: string, path: string, signal?: AbortSignal) { |
| 106 | + return request<FileContent>("GET", `${thread(threadId)}/files/content?path=${q(path)}`, undefined, signal); |
| 107 | +} |
| 108 | + |
| 109 | +export function saveThreadFile(threadId: string, body: { path: string; content: string; base_revision: string | null }) { |
| 110 | + return request("PUT", `${thread(threadId)}/files/content`, body); |
| 111 | +} |
| 112 | + |
| 113 | +export function listThreadFiles(threadId: string, path: string, signal?: AbortSignal) { |
| 114 | + return request<FileEntry[]>("GET", `${thread(threadId)}/files?path=${q(path)}`, undefined, signal); |
| 115 | +} |
| 116 | + |
| 117 | +export function searchThreadFiles(threadId: string, query: string, signal?: AbortSignal) { |
| 118 | + return request<SearchHit[]>("GET", `${thread(threadId)}/files/search?q=${q(query)}&content=true`, undefined, signal); |
| 119 | +} |
| 120 | + |
| 121 | +export function openThreadFileInBrowser(threadId: string, path: string) { |
| 122 | + return request("POST", `${thread(threadId)}/previews/file`, { path }); |
| 123 | +} |
| 124 | + |
| 125 | +export function listTerminals(threadId: string, signal?: AbortSignal) { |
| 126 | + return request<TerminalInfo[]>("GET", `${thread(threadId)}/terminals`, undefined, signal); |
| 127 | +} |
| 128 | + |
| 129 | +export function startTerminal(threadId: string, body: unknown) { |
| 130 | + return request<TerminalInfo>("POST", `${thread(threadId)}/terminals`, body); |
| 131 | +} |
| 132 | + |
| 133 | +export function startConsole(threadId: string) { |
| 134 | + return request<TerminalInfo>("POST", `${thread(threadId)}/console`, {}); |
| 135 | +} |
| 136 | + |
| 137 | +export function closeTerminal(threadId: string, terminalId: string) { |
| 138 | + return request("DELETE", `${thread(threadId)}/terminals/${q(terminalId)}`); |
| 139 | +} |
| 140 | + |
| 141 | +export function listThreadScripts(threadId: string, signal?: AbortSignal) { |
| 142 | + return request<ProjectFileView>("GET", `${thread(threadId)}/scripts`, undefined, signal); |
| 143 | +} |
| 144 | + |
| 145 | +export { ApiFailure, api, authHeaders } from "../../api/client"; |
5 | 146 | export { serviceSocketUrl, serviceUrl } from "../../api/origin"; |
6 | 147 | export { pullsApi } from "../../api/pulls"; |
7 | 148 | export { inDesktopApp } from "../../api/shell"; |
|
0 commit comments