Path: blob/main/src/publish/rsconnect/api/index.ts
6460 views
/*1* index.ts2*3* Copyright (C) 2020-2022 Posit Software, PBC4*5*/67import { wrapFetch } from "another_cookiejar/mod.ts";8const fetch = wrapFetch();910import { ensureProtocolAndTrailingSlash } from "../../../core/url.ts";11import { ApiError } from "../../types.ts";12import { Bundle, Content, Task, TaskStatus, User } from "./types.ts";1314export class RSConnectClient {15public constructor(16private readonly server_: string,17private readonly key_?: string,18) {19this.server_ = ensureProtocolAndTrailingSlash(this.server_);20}2122public getUser(): Promise<User> {23return this.get<User>("user");24}2526public createContent(name: string, title: string): Promise<Content> {27return this.post<Content>("content", JSON.stringify({ name, title }));28}2930public getContent(guid: string): Promise<Content> {31return this.get<Content>(`content/${guid}`);32}3334public uploadBundle(guid: string, fileBody: Blob): Promise<Bundle> {35return this.post<Bundle>(`content/${guid}/bundles`, fileBody);36}3738public deployBundle(bundle: Bundle): Promise<Task> {39return this.post<Task>(40`content/${bundle.content_guid}/deploy`,41JSON.stringify({ bundle_id: bundle.id }),42);43}4445public getTaskStatus(task: Task): Promise<TaskStatus> {46return this.get<TaskStatus>(47`tasks/${task.task_id}?${new URLSearchParams({ wait: "1" })}`,48);49}5051private get = <T>(path: string): Promise<T> => this.fetch<T>("GET", path);52private post = <T>(path: string, body?: BodyInit | null): Promise<T> =>53this.fetch<T>("POST", path, body);54private fetch = async <T>(55method: string,56path: string,57body?: BodyInit | null,58): Promise<T> => {59return this.handleResponse<T>(60await fetch(this.apiUrl(path), {61method,62// credentials: "include",63headers: {64Accept: "application/json",65...authorizationHeader(this.key_),66},67body,68}),69);70};7172private apiUrl = (path: string) => `${this.server_}__api__/v1/${path}`;7374private handleResponse<T>(response: Response) {75if (response.ok) {76return response.json() as unknown as T;77} else if (response.status !== 200) {78throw new ApiError(response.status, response.statusText);79} else {80throw new Error(`${response.status} - ${response.statusText}`);81}82}8384private cookies_ = new Map<string, string>();85}8687const authorizationHeader = (88key?: string,89): HeadersInit => (!key ? {} : { Authorization: `Key ${key}` });909192