+function sendResumableChunks (options: {
+ url: string
+ token: string
+ pathUploadId: string
+ videoFilePath: string
+ size: number
+ specialStatus?: HttpStatusCode
+ contentLength?: number
+ contentRangeBuilder?: (start: number, chunk: any) => string
+}) {
+ const { url, token, pathUploadId, videoFilePath, size, specialStatus, contentLength, contentRangeBuilder } = options
+
+ const expectedStatus = specialStatus || HttpStatusCode.OK_200
+
+ const path = '/api/v1/videos/upload-resumable'
+ let start = 0
+
+ const readable = createReadStream(videoFilePath, { highWaterMark: 8 * 1024 })
+ return new Promise<GotResponse>((resolve, reject) => {
+ readable.on('data', async function onData (chunk) {
+ readable.pause()
+
+ const headers = {
+ 'Authorization': 'Bearer ' + token,
+ 'Content-Type': 'application/octet-stream',
+ 'Content-Range': contentRangeBuilder
+ ? contentRangeBuilder(start, chunk)
+ : `bytes ${start}-${start + chunk.length - 1}/${size}`,
+ 'Content-Length': contentLength ? contentLength + '' : chunk.length + ''
+ }
+
+ const res = await got({
+ url,
+ method: 'put',
+ headers,
+ path: path + '?' + pathUploadId,
+ body: chunk,
+ responseType: 'json',
+ throwHttpErrors: false
+ })
+
+ start += chunk.length
+
+ if (res.statusCode === expectedStatus) {
+ return resolve(res)
+ }
+
+ if (res.statusCode !== HttpStatusCode.PERMANENT_REDIRECT_308) {
+ readable.off('data', onData)
+ return reject(new Error('Incorrect transient behaviour sending intermediary chunks'))
+ }
+
+ readable.resume()
+ })
+ })
+}
+
+function updateVideo (
+ url: string,
+ accessToken: string,
+ id: number | string,
+ attributes: VideoAttributes,
+ statusCodeExpected = HttpStatusCode.NO_CONTENT_204
+) {