UNPKG

@clickup/rest-client

Version:

A syntax sugar tool around Node fetch() API, tailored to work with TypeScript and response validators

54 lines 2.17 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /** * Sends a series of Content-Range requests to an URL. * - The stream size is unknown in advance even theoretically. So we read it * with chunkSize+1 bytes chunks (+1 is to know for sure, is there something * else left in the stream or not) and then send data with chunkSize bytes * chunks. * - The last chunk is a terminating one (and we know, which one is the last), * so we reflect it in "Content-Range: x-y/S" format setting S to the total * number of bytes in the stream. */ class RestRangeUploader { constructor(_client, _chunkSize, _method, _path, _mimeType) { this._client = _client; this._chunkSize = _chunkSize; this._method = _method; this._path = _path; this._mimeType = _mimeType; this._pos = 0; } async upload(stream) { let buf = Buffer.allocUnsafe(0); let res = null; for await (const readData of stream) { buf = Buffer.concat([buf, readData]); while (buf.length >= this._chunkSize + 1) { res = await this._flush(buf.slice(0, this._chunkSize), false); buf = Buffer.from(buf.slice(this._chunkSize)); } // After this `while` loop finishes, there is always something left in buf // (due to the +1 trick). It guarantees that we have a chance to call // flush(..., true) for the very last chunk. } if (buf.length > 0) { res = await this._flush(buf, true); } return res; } async _flush(buf, isLast) { if (buf.length === 0) { return null; } const totalSize = isLast ? this._pos + buf.length : "*"; const res = await this._client .writeRaw(this._path, buf, this._mimeType, this._method, "*/*") .setHeader("Content-Range", `bytes ${this._pos}-${this._pos + buf.length - 1}/${totalSize}`) .text(); this._pos += buf.length; return res; } } exports.default = RestRangeUploader; //# sourceMappingURL=RestRangeUploader.js.map