UNPKG

@inweb/client

Version:

JavaScript REST API client for the Open Cloud Server

172 lines (155 loc) 5.79 kB
/////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2002-2026, Open Design Alliance (the "Alliance"). // All rights reserved. // // This software and its documentation and related materials are owned by // the Alliance. The software may only be incorporated into application // programs owned by members of the Alliance, subject to a signed // Membership Agreement and Supplemental Software License Agreement with the // Alliance. The structure and organization of this software are the valuable // trade secrets of the Alliance and its suppliers. The software is also // protected by copyright law and international treaty provisions. Application // programs incorporating this software must include the following statement // with their copyright notices: // // This application incorporates Open Design Alliance software pursuant to a // license agreement with Open Design Alliance. // Open Design Alliance Copyright (C) 2002-2026 by Open Design Alliance. // All rights reserved. // // By use of this software, its documentation or related materials, you // acknowledge and accept the above terms. /////////////////////////////////////////////////////////////////////////////// import { IHttpClient } from "./IHttpClient"; import { $fetch } from "./Fetch"; import { $xmlhttp } from "./XMLHttp"; export class HttpClient implements IHttpClient { public serverUrl: string; public headers: HeadersInit = {}; public signInUserId = ""; public signInUserIsAdmin = false; constructor(serverUrl: string) { this.serverUrl = serverUrl; } get(relativePath: string, init: RequestInit = {}): Promise<Response> { return $fetch(`${this.serverUrl}${relativePath}`, { ...init, method: "GET", headers: { ...this.headers, ...init.headers }, }); } post(relativePath: string, body?: BodyInit | object, init: RequestInit = {}): Promise<Response> { return $fetch(`${this.serverUrl}${relativePath}`, { ...init, method: "POST", headers: { ...this.headers, ...init.headers }, body, }); } put(relativePath: string, body?: BodyInit | object, init: RequestInit = {}): Promise<Response> { return $fetch(`${this.serverUrl}${relativePath}`, { ...init, method: "PUT", headers: { ...this.headers, ...init.headers }, body, }); } delete(relativePath: string, init: RequestInit = {}): Promise<Response> { return $fetch(`${this.serverUrl}${relativePath}`, { ...init, method: "DELETE", headers: { ...this.headers, ...init.headers }, }); } uploadFile( relativePath: string, file: File, onProgress?: (progress: number) => void, init: RequestInit = {} ): Promise<XMLHttpRequest> { const data = new FormData(); data.append("file", file); return $xmlhttp(`${this.serverUrl}${relativePath}`, { method: "POST", headers: { ...this.headers, ...init.headers }, body: data, uploadProgress: onProgress, }); } async downloadFile( relativePath: string, onProgress?: (progress: number, chunk: Uint8Array) => void, init: RequestInit = {} ): Promise<Response> { const response = await this.get(relativePath, init); if (!onProgress) return response; const contentLength = response.headers.get("Content-Length"); const total = parseInt(contentLength || "", 10) || 1; const stream = new ReadableStream({ async start(controller) { const reader = response.body.getReader(); let loaded = 0; while (true) { const { done, value } = await reader.read(); if (done) break; controller.enqueue(value); loaded += value.length; onProgress(loaded / total, value); } controller.close(); }, }); return new Response(stream); } async downloadFileRange( relativePath: string, reserved: number | string, ranges: Array<{ begin: number; end: number; requestId: number }>, onProgress?: (progress: number, chunk: Uint8Array, requestId: number) => void, init: RequestInit = {} ): Promise<Response> { const headers = { ...init.headers, Range: "bytes=" + ranges.map((x) => `${x.begin}-${x.end}`).join(","), }; const response = await this.get(relativePath, { ...init, headers }); if (!onProgress) return response; const contentLength = response.headers.get("content-length"); const total = parseInt(contentLength || "", 10) || 1; const stream = new ReadableStream({ async start(controller) { const reader = response.body.getReader(); let loaded = 0; let rangedIndex = 0; let rangePos = 0; while (true) { const { done, value } = await reader.read(); if (done) break; controller.enqueue(value); loaded += value.length; let chunkLeft = value.length; let chunkPos = 0; while (chunkLeft > 0) { const range = ranges[rangedIndex]; const rangeLeft = range.end - range.begin + 1 - rangePos; if (chunkLeft < rangeLeft) { const chunk = value.subarray(chunkPos, chunkPos + chunkLeft); onProgress(loaded / total, chunk, range.requestId); rangePos += chunkLeft; chunkLeft = 0; } else { const chunk = value.subarray(chunkPos, chunkPos + rangeLeft); onProgress(loaded / total, chunk, range.requestId); chunkPos += rangeLeft; chunkLeft -= rangeLeft; rangedIndex++; rangePos = 0; } } } controller.close(); }, }); return new Response(stream); } }