From eaf8583d293f4f9bca7cc3984185db97d4e6acba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Uhl=C3=AD=C5=99?= Date: Thu, 15 Jul 2021 13:39:46 +0200 Subject: [PATCH 1/5] feat: streaming directory --- src/modules/bzz.ts | 2 +- src/utils/collection.ts | 10 +++++++--- src/utils/tar.ts | 3 ++- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/modules/bzz.ts b/src/modules/bzz.ts index 4626bbfd..3754c110 100644 --- a/src/modules/bzz.ts +++ b/src/modules/bzz.ts @@ -156,7 +156,7 @@ function extractCollectionUploadHeaders( */ export async function uploadCollection( url: string, - collection: Collection, + collection: Collection, postageBatchId: BatchId, options?: CollectionUploadOptions, ): Promise { diff --git a/src/utils/collection.ts b/src/utils/collection.ts index 77a259c0..32d8c927 100644 --- a/src/utils/collection.ts +++ b/src/utils/collection.ts @@ -3,17 +3,21 @@ import path from 'path' import { Collection } from '../types' import { BeeArgumentError } from './error' import { fileArrayBuffer } from './file' -import { isUint8Array } from './type' +import { isReadable, isUint8Array } from './type' +import type { Readable } from 'stream' export function isCollection(data: unknown): data is Collection { if (!Array.isArray(data)) { return false } - return data.every(entry => typeof entry === 'object' && entry.data && entry.path && isUint8Array(entry.data)) + return data.every( + entry => + typeof entry === 'object' && entry.data && entry.path && (isUint8Array(entry.data) || isReadable(entry.data)), + ) } -export function assertCollection(data: unknown): asserts data is Collection { +export function assertCollection(data: unknown): asserts data is Collection { if (!isCollection(data)) { throw new BeeArgumentError('invalid collection', data) } diff --git a/src/utils/tar.ts b/src/utils/tar.ts index f7429256..915946f1 100644 --- a/src/utils/tar.ts +++ b/src/utils/tar.ts @@ -1,5 +1,6 @@ import { Collection } from '../types' import Tar from 'tar-js' +import type { Readable } from 'stream' // this is a workaround type so that we are able to pass in Uint8Arrays // as string to `tar.append` @@ -19,7 +20,7 @@ function fixUnicodePath(path: string): StringLike { } } -export function makeTar(data: Collection): Uint8Array { +export function makeTar(data: Collection): Uint8Array { const tar = new Tar() for (const entry of data) { const path = fixUnicodePath(entry.path) From d800bbcdb8fbb0381ec9cb3e176ef91e6a94744c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Uhl=C3=AD=C5=99?= Date: Mon, 19 Jul 2021 13:28:54 +0200 Subject: [PATCH 2/5] chore: wip --- package-lock.json | 91 +++++++++++++++++++++-------------- package.json | 4 ++ src/bee.ts | 7 ++- src/modules/bzz.ts | 2 +- src/types/index.ts | 19 +++++++- src/utils/collection.ts | 11 +++-- src/utils/file.ts | 40 ---------------- src/utils/safe-axios.ts | 61 ------------------------ src/utils/tar.ts | 103 ++++++++++++++++++++++++++++++++-------- src/utils/type.ts | 17 ++++++- 10 files changed, 186 insertions(+), 169 deletions(-) delete mode 100644 src/utils/file.ts diff --git a/package-lock.json b/package-lock.json index 352c948a..34eb6e16 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,9 @@ "elliptic": "^6.5.4", "isomorphic-ws": "^4.0.1", "js-sha3": "^0.8.0", + "readable-web-to-node-stream": "^3.0.2", "tar-js": "^0.3.0", + "tar-stream": "^2.2.0", "ws": "^7.5.0" }, "devDependencies": { @@ -36,6 +38,7 @@ "@types/jest-environment-puppeteer": "^4.4.1", "@types/node": "^15.12.4", "@types/puppeteer": "^5.4.3", + "@types/readable-stream": "^2.3.11", "@types/tar-stream": "^2.2.0", "@types/terser-webpack-plugin": "^5.0.3", "@types/ws": "^7.4.5", @@ -58,6 +61,7 @@ "nock": "^13.1.0", "prettier": "^2.3.1", "puppeteer": "^9.1.1", + "readable-stream": "^3.6.0", "rimraf": "^3.0.2", "terser-webpack-plugin": "^5.1.3", "ts-node": "^10.0.0", @@ -4005,6 +4009,16 @@ "@types/node": "*" } }, + "node_modules/@types/readable-stream": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-2.3.11.tgz", + "integrity": "sha512-0z+/apYJwKFz/RHp6mOMxz/y7xOvWPYPevuCEyAY3gXsjtaac02E26RvxA+I96rfvmVH/dEMGXNvyJfViR1FSQ==", + "dev": true, + "dependencies": { + "@types/node": "*", + "safe-buffer": "*" + } + }, "node_modules/@types/stack-utils": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", @@ -5084,7 +5098,6 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, "funding": [ { "type": "github", @@ -5122,7 +5135,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", @@ -5209,7 +5221,6 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, "funding": [ { "type": "github", @@ -6052,7 +6063,6 @@ "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, "dependencies": { "once": "^1.4.0" } @@ -7208,8 +7218,7 @@ "node_modules/fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" }, "node_modules/fs-exists-sync": { "version": "0.1.0", @@ -7742,7 +7751,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, "funding": [ { "type": "github", @@ -12818,7 +12826,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, "dependencies": { "wrappy": "1" } @@ -13675,7 +13682,6 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -13685,6 +13691,21 @@ "node": ">= 6" } }, + "node_modules/readable-web-to-node-stream": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz", + "integrity": "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==", + "dependencies": { + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -14321,7 +14342,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, "dependencies": { "safe-buffer": "~5.2.0" } @@ -14330,7 +14350,6 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, "funding": [ { "type": "github", @@ -14560,7 +14579,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "dev": true, "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", @@ -15087,8 +15105,7 @@ "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "node_modules/v8-compile-cache": { "version": "2.3.0", @@ -15702,8 +15719,7 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "node_modules/write-file-atomic": { "version": "3.0.3", @@ -18790,6 +18806,16 @@ "@types/node": "*" } }, + "@types/readable-stream": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-2.3.11.tgz", + "integrity": "sha512-0z+/apYJwKFz/RHp6mOMxz/y7xOvWPYPevuCEyAY3gXsjtaac02E26RvxA+I96rfvmVH/dEMGXNvyJfViR1FSQ==", + "dev": true, + "requires": { + "@types/node": "*", + "safe-buffer": "*" + } + }, "@types/stack-utils": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", @@ -19643,8 +19669,7 @@ "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" }, "big.js": { "version": "5.2.2", @@ -19662,7 +19687,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, "requires": { "buffer": "^5.5.0", "inherits": "^2.0.4", @@ -19736,7 +19760,6 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, "requires": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" @@ -20392,7 +20415,6 @@ "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, "requires": { "once": "^1.4.0" } @@ -21237,8 +21259,7 @@ "fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" }, "fs-exists-sync": { "version": "0.1.0", @@ -21636,8 +21657,7 @@ "ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" }, "ignore": { "version": "5.1.8", @@ -25548,7 +25568,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, "requires": { "wrappy": "1" } @@ -26180,13 +26199,20 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, + "readable-web-to-node-stream": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz", + "integrity": "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==", + "requires": { + "readable-stream": "^3.6.0" + } + }, "readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -26693,7 +26719,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, "requires": { "safe-buffer": "~5.2.0" }, @@ -26701,8 +26726,7 @@ "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" } } }, @@ -26875,7 +26899,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "dev": true, "requires": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", @@ -27248,8 +27271,7 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "v8-compile-cache": { "version": "2.3.0", @@ -27708,8 +27730,7 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "write-file-atomic": { "version": "3.0.3", diff --git a/package.json b/package.json index 13bd6022..d5f634c5 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,9 @@ "elliptic": "^6.5.4", "isomorphic-ws": "^4.0.1", "js-sha3": "^0.8.0", + "readable-web-to-node-stream": "^3.0.2", "tar-js": "^0.3.0", + "tar-stream": "^2.2.0", "ws": "^7.5.0" }, "devDependencies": { @@ -75,6 +77,7 @@ "@types/jest-environment-puppeteer": "^4.4.1", "@types/node": "^15.12.4", "@types/puppeteer": "^5.4.3", + "@types/readable-stream": "^2.3.11", "@types/tar-stream": "^2.2.0", "@types/terser-webpack-plugin": "^5.0.3", "@types/ws": "^7.4.5", @@ -97,6 +100,7 @@ "nock": "^13.1.0", "prettier": "^2.3.1", "puppeteer": "^9.1.1", + "readable-stream": "^3.6.0", "rimraf": "^3.0.2", "terser-webpack-plugin": "^5.1.3", "ts-node": "^10.0.0", diff --git a/src/bee.ts b/src/bee.ts index 4377d895..6f5363c1 100644 --- a/src/bee.ts +++ b/src/bee.ts @@ -9,7 +9,6 @@ import * as stamps from './modules/stamps' import { BeeArgumentError, BeeError } from './utils/error' import { prepareWebsocketData } from './utils/data' -import { fileArrayBuffer, isFile } from './utils/file' import { AxiosRequestConfig } from 'axios' import { makeFeedReader, makeFeedWriter } from './feed' import { makeSigner } from './chunk/signer' @@ -34,6 +33,7 @@ import { assertPublicKey, assertReference, assertUploadOptions, + isFile, isReadable, makeTagUid, } from './utils/type' @@ -184,12 +184,11 @@ export class Bee { } if (isFile(data)) { - const fileData = await fileArrayBuffer(data) const fileName = name ?? data.name const contentType = data.type const fileOptions = { contentType, ...options } - return bzz.uploadFile(this.url, fileData, postageBatchId, fileName, fileOptions) + return bzz.uploadFile(this.url, data.stream(), postageBatchId, fileName, fileOptions) } else if (isReadable(data) && options?.tag && !options.size) { // TODO: Needed until https://github.com/ethersphere/bee/issues/2317 is resolved const reference = await bzz.uploadFile(this.url, data, postageBatchId, name, options) @@ -254,7 +253,7 @@ export class Bee { if (options) assertCollectionUploadOptions(options) - const data = await makeCollectionFromFileList(fileList) + const data = makeCollectionFromFileList(fileList) return bzz.uploadCollection(this.url, data, postageBatchId, options) } diff --git a/src/modules/bzz.ts b/src/modules/bzz.ts index 3754c110..36fa180d 100644 --- a/src/modules/bzz.ts +++ b/src/modules/bzz.ts @@ -165,7 +165,7 @@ export async function uploadCollection( } assertCollection(collection) - const tarData = makeTar(collection) + const tarData = await makeTar(collection) const response = await safeAxios<{ reference: Reference }>({ ...options?.axiosOptions, diff --git a/src/types/index.ts b/src/types/index.ts index a0bfa05c..f09b9af3 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -7,6 +7,9 @@ import { Bytes } from '../utils/bytes' import { BeeError } from '../utils/error' import { EthAddress, HexEthAddress } from '../utils/eth' import { HexString } from '../utils/hex' +import { Readable as NativeReadable } from 'stream' +import { Readable as CompatibilityReadable } from 'readable-stream' + export * from './debug' export interface Dictionary { @@ -47,6 +50,12 @@ export type PublicKey = HexString export type Address = HexString +/** + * Type representing Readable stream that abstracts away implementation especially the difference between + * browser and NodeJS versions + */ +export type Readable = NativeReadable | CompatibilityReadable | ReadableStream + /** * BatchId is result of keccak256 hash so 64 hex string without prefix. */ @@ -222,12 +231,20 @@ export interface Data extends Uint8Array { * Object represents a file and some of its metadata in [[Directory]] object. */ export interface CollectionEntry { + /** + * Data of the entry + */ data: T /** - * + * Path in the directory structure */ path: string + + /** + * If data is Readable then length has to be specified as well! + */ + length?: number } /** diff --git a/src/utils/collection.ts b/src/utils/collection.ts index 32d8c927..d44e468f 100644 --- a/src/utils/collection.ts +++ b/src/utils/collection.ts @@ -2,9 +2,9 @@ import fs from 'fs' import path from 'path' import { Collection } from '../types' import { BeeArgumentError } from './error' -import { fileArrayBuffer } from './file' import { isReadable, isUint8Array } from './type' -import type { Readable } from 'stream' +import { ReadableWebToNodeStream } from 'readable-web-to-node-stream' +import type { Readable } from 'readable-stream' export function isCollection(data: unknown): data is Collection { if (!Array.isArray(data)) { @@ -87,8 +87,8 @@ function makeFilePath(file: WebkitFile) { throw new TypeError('file is not valid File object') } -export async function makeCollectionFromFileList(fileList: FileList | File[]): Promise> { - const collection: Collection = [] +export function makeCollectionFromFileList(fileList: FileList | File[]): Collection { + const collection: Collection = [] for (let i = 0; i < fileList.length; i++) { const file = fileList[i] as WebkitFile @@ -96,7 +96,8 @@ export async function makeCollectionFromFileList(fileList: FileList | File[]): P if (file) { collection.push({ path: makeFilePath(file), - data: new Uint8Array(await fileArrayBuffer(file)), + data: new ReadableWebToNodeStream(file.stream()), + length: file.size, }) } } diff --git a/src/utils/file.ts b/src/utils/file.ts deleted file mode 100644 index 1530b5e8..00000000 --- a/src/utils/file.ts +++ /dev/null @@ -1,40 +0,0 @@ -/** - * Compatibility functions for working with File API objects - * - * https://developer.mozilla.org/en-US/docs/Web/API/File - */ - -export function isFile(file: unknown): file is File { - // browser - if (typeof File === 'function') { - return file instanceof File - } - - // node.js - const f = file as File - - return ( - typeof f === 'object' && - typeof f.name === 'string' && - (typeof f.stream === 'function' || typeof f.arrayBuffer === 'function') - ) -} - -/** - * Compatibility helper for browsers where the `arrayBuffer function is - * missing from `File` objects. - * - * @param file A File object - */ -export async function fileArrayBuffer(file: File): Promise { - if (file.arrayBuffer) { - return file.arrayBuffer() - } - - // workaround for Safari where arrayBuffer is not supported on Files - return new Promise(resolve => { - const fr = new FileReader() - fr.onload = () => resolve(fr.result as ArrayBuffer) - fr.readAsArrayBuffer(file) - }) -} diff --git a/src/utils/safe-axios.ts b/src/utils/safe-axios.ts index 4ea27713..06ea27ee 100644 --- a/src/utils/safe-axios.ts +++ b/src/utils/safe-axios.ts @@ -1,8 +1,6 @@ import axios, { AxiosRequestConfig, AxiosResponse } from 'axios' import { BeeError, BeeRequestError, BeeResponseError } from './error' -import utils from 'axios/lib/utils' -import normalizeHeaderName from 'axios/lib/helpers/normalizeHeaderName' axios.defaults.adapter = require('axios/lib/adapters/http') // https://stackoverflow.com/a/57320262 /** @@ -14,70 +12,11 @@ export function setDefaultHeaders(headers: Record): void { axios.defaults.headers.common = headers } -/** - * Utility function from axios's implementation - * https://github.com/axios/axios/blob/d99d5faac29899eba68ce671e6b3cbc9832e9ad8/lib/defaults.js - * - * @param headers - * @param value - */ -function setContentTypeIfUnset(headers: Record, value: string) { - if (!utils.isUndefined(headers) && utils.isUndefined(headers['Content-Type'])) { - headers['Content-Type'] = value - } -} - -/** - * Taken over from axios's implementation - * https://github.com/axios/axios/blob/d99d5faac29899eba68ce671e6b3cbc9832e9ad8/lib/defaults.js - * - * Unfortunately we can't use the default implementation as fallback one and override only the JSON serialization as the JSON.stringify - * is a last thing to do as all the previous cases (buffer, file etc.) are objects as well - * so they have to be ruled out first before trying JSON.stringify. - * - * @param data - * @param headers - */ -function transformRequest(data: unknown, headers: Record): string | unknown { - normalizeHeaderName(headers, 'Accept') - normalizeHeaderName(headers, 'Content-Type') - - if ( - utils.isFormData(data) || - utils.isArrayBuffer(data) || - utils.isBuffer(data) || - utils.isStream(data) || - utils.isFile(data) || - utils.isBlob(data) - ) { - return data - } - - if (utils.isArrayBufferView(data)) { - return data.buffer - } - - if (utils.isURLSearchParams(data)) { - setContentTypeIfUnset(headers, 'application/x-www-form-urlencoded;charset=utf-8') - - return data.toString() - } - - if (utils.isObject(data) || (headers && headers['Content-Type'] === 'application/json')) { - setContentTypeIfUnset(headers, 'application/json') - - return JSON.stringify(data) - } - - return data -} - export async function safeAxios(config: AxiosRequestConfig): Promise> { try { const response = await axios({ maxContentLength: Infinity, maxBodyLength: Infinity, - transformRequest, ...config, }) diff --git a/src/utils/tar.ts b/src/utils/tar.ts index 915946f1..268291ca 100644 --- a/src/utils/tar.ts +++ b/src/utils/tar.ts @@ -1,31 +1,92 @@ import { Collection } from '../types' -import Tar from 'tar-js' -import type { Readable } from 'stream' - -// this is a workaround type so that we are able to pass in Uint8Arrays -// as string to `tar.append` -interface StringLike { - readonly length: number - charCodeAt: (index: number) => number -} +import { Readable } from 'stream' +import * as tar from 'tar-stream' +import { Pack } from 'tar-stream' +import { assertNonNegativeInteger, isReadable } from './type' + +type FileInfo = { name: string; size: number; stream: Readable } + +/** + * Helper class for tar-stream as found at https://github.com/mafintosh/tar-stream/issues/24#issuecomment-579797456 + * Modified for better readability. + * + * Credit to https://github.com/dominicbartl + */ +export class TarArchive { + private pack = tar.pack() + private streamQueue: FileInfo[] = [] + private size = 0 -// converts a string to utf8 Uint8Array and returns it as a string-like -// object that `tar.append` accepts as path -function fixUnicodePath(path: string): StringLike { - const codes = new TextEncoder().encode(path) + addBuffer(name: string, buffer: Buffer) { + this.size += buffer.length + this.pack.entry( + { + name: name, + }, + buffer, + ) + } + + addStream(name: string, size: number, stream: Readable) { + this.streamQueue.push({ + name, + size, + stream, + }) + } - return { - length: codes.length, - charCodeAt: index => codes[index], + async write(): Promise { + return new Promise((resolve, reject) => { + this.nextEntry(err => { + if (err) { + reject(err) + } else { + resolve(this.pack) + } + }) + }) + } + + private nextEntry(callback: (err?: Error) => void) { + const file = this.streamQueue.shift() + + if (file) { + const writeEntryStream = this.pack.entry( + { + name: file.name, + size: file.size, + }, + err => { + if (err) { + callback(err) + } else { + this.size += file.size + this.nextEntry(callback) + } + }, + ) + file.stream.pipe(writeEntryStream) + } else { + this.pack.finalize() + callback() + } } } -export function makeTar(data: Collection): Uint8Array { - const tar = new Tar() +export async function makeTar(data: Collection): Promise { + const tar = new TarArchive() + for (const entry of data) { - const path = fixUnicodePath(entry.path) - tar.append(path, entry.data) + if (isReadable(entry.data)) { + assertNonNegativeInteger(entry.length, 'entry.length') + + tar.addStream(entry.path, entry.length, entry.data) + } else if (entry.data instanceof Uint8Array) { + tar.addBuffer(entry.path, Buffer.from(entry.data)) + } else { + throw new TypeError('Unknown data type!') + } } - return tar.out + return tar.write() } diff --git a/src/utils/type.ts b/src/utils/type.ts index 6a05779c..d4199cd9 100644 --- a/src/utils/type.ts +++ b/src/utils/type.ts @@ -21,7 +21,6 @@ import { TAGS_LIMIT_MAX, } from '../types' import { BeeArgumentError } from './error' -import { isFile } from './file' import { assertHexString } from './hex' export function isReadable(entry: unknown): entry is Readable { @@ -34,6 +33,22 @@ export function isReadable(entry: unknown): entry is Readable { ) } +export function isFile(file: unknown): file is File { + // browser + if (typeof File === 'function') { + return file instanceof File + } + + // node.js + const f = file as File + + return ( + typeof f === 'object' && + typeof f.name === 'string' && + (typeof f.stream === 'function' || typeof f.arrayBuffer === 'function') + ) +} + export function isUint8Array(obj: unknown): obj is Uint8Array { return obj instanceof Uint8Array } From 08536819db8ec448d3557a9efb9eef7f3c734f2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Uhl=C3=AD=C5=99?= Date: Wed, 21 Jul 2021 09:06:20 +0200 Subject: [PATCH 3/5] chore: wip --- jest.config.ts | 76 ++++++++++++++--- src/bee.ts | 41 ++++++++- src/modules/bzz.ts | 9 +- src/types/index.ts | 6 +- src/utils/collection.ts | 35 ++------ src/utils/data.ts | 5 +- src/utils/expose.ts | 1 - src/utils/tar.ts | 33 ++++++-- src/utils/type.ts | 103 +++++++++++++++++----- test/integration/bee-class.spec.ts | 52 +++++++++--- test/integration/modules/bzz.spec.ts | 16 ++++ test/unit/assertions.ts | 122 +++++++++++++++++---------- test/unit/bee-class.spec.ts | 36 ++++++++ test/utils.ts | 10 +++ 14 files changed, 408 insertions(+), 137 deletions(-) diff --git a/jest.config.ts b/jest.config.ts index ea6f522f..262a8bef 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -6,7 +6,8 @@ import type { Config } from '@jest/types' import { glob } from 'glob' import * as Path from 'path' -import { createPostageBatch } from './src/modules/stamps' +import { createPostageBatch, getPostageBatch } from './src/modules/stamps' +import type { BatchId } from './src' /** * Get 'alias' configuration of Jest and Webpack for browser testing and compilation. @@ -36,19 +37,66 @@ export async function getBrowserPathMapping(): Promise<{ [aliasNodeReference: st export default async (): Promise => { try { - console.log('Creating postage stamps...') const beeUrl = process.env.BEE_API_URL || 'http://localhost:1633' const beePeerUrl = process.env.BEE_PEER_API_URL || 'http://localhost:11633' - const stamps = await Promise.all([createPostageBatch(beeUrl, '1', 20), createPostageBatch(beePeerUrl, '1', 20)]) - process.env.BEE_POSTAGE = stamps[0] - console.log('Queen stamp: ', process.env.BEE_POSTAGE) - process.env.BEE_PEER_POSTAGE = stamps[1] - console.log('Peer stamp: ', process.env.BEE_PEER_POSTAGE) - // sleep for 11 seconds (10 blocks with ganache block time = 1s) - // needed for postage batches to become usable - // FIXME: sleep should be imported for this, but then we fail with - // Could not find a declaration file for module 'tar-js' - await new Promise(resolve => setTimeout(() => resolve(), 11_000)) + + if (process.env.BEE_POSTAGE) { + try { + if (!(await getPostageBatch(beeUrl, process.env.BEE_POSTAGE as BatchId)).usable) { + delete process.env.BEE_POSTAGE + console.log('BEE_POSTAGE stamp was found but is not usable') + } else { + console.log('Using configured BEE_POSTAGE stamp.') + } + } catch (e) { + delete process.env.BEE_POSTAGE + console.log('BEE_POSTAGE stamp was not found') + } + } + + if (process.env.BEE_PEER_POSTAGE) { + try { + if (!(await getPostageBatch(beePeerUrl, process.env.BEE_PEER_POSTAGE as BatchId)).usable) { + delete process.env.BEE_PEER_POSTAGE + console.log('BEE_PEER_POSTAGE stamp was found but is not usable') + } else { + console.log('Using configured BEE_PEER_POSTAGE stamp.') + } + } catch (e) { + delete process.env.BEE_PEER_POSTAGE + console.log('BEE_PEER_POSTAGE stamp was not found') + } + } + + if (!process.env.BEE_POSTAGE || !process.env.BEE_PEER_POSTAGE) { + console.log('Creating postage stamps...') + + const stampsPromises: Promise[] = [] + const stampsEnv = [] + + if (!process.env.BEE_POSTAGE) { + stampsPromises.push(createPostageBatch(beeUrl, '1', 20)) + stampsEnv.push('BEE_POSTAGE') + } + + if (!process.env.BEE_PEER_POSTAGE) { + stampsPromises.push(createPostageBatch(beePeerUrl, '1', 20)) + stampsEnv.push('BEE_PEER_POSTAGE') + } + + const stamps = await Promise.all(stampsPromises) + + for (let i = 0; i < stamps.length; i++) { + process.env[stampsEnv[i]] = stamps[i] + console.log(`${stampsEnv[i]}: ${stamps[i]}`) + } + + // sleep for 11 seconds (10 blocks with ganache block time = 1s) + // needed for postage batches to become usable + // FIXME: sleep should be imported for this, but then we fail with + // Could not find a declaration file for module 'tar-js' + await new Promise(resolve => setTimeout(() => resolve(), 11_000)) + } } catch (e) { // It is possible that for unit tests the Bee nodes does not run // so we are only logging errors and not leaving them to propagate @@ -72,7 +120,7 @@ export default async (): Promise => { moduleDirectories: ['node_modules'], // Run tests from one or more projects - projects: ([ + projects: [ // We don't have any DOM specific tests atm. // { // displayName: 'dom:unit', @@ -96,7 +144,7 @@ export default async (): Promise => { testEnvironment: 'node', testRegex: 'test/integration/((?!\\.browser).)*\\.spec\\.ts', }, - ] as unknown[]) as string[], // bad types + ] as unknown[] as string[], // bad types // The root directory that Jest should scan for tests and modules within rootDir: 'test', diff --git a/src/bee.ts b/src/bee.ts index 6f5363c1..75a5716a 100644 --- a/src/bee.ts +++ b/src/bee.ts @@ -1,4 +1,4 @@ -import type { Readable } from 'stream' +import type { Readable as NodeReadable } from 'stream' import * as bzz from './modules/bzz' import * as tag from './modules/tag' import * as pinning from './modules/pinning' @@ -24,6 +24,7 @@ import { assertAllTagsOptions, assertBatchId, assertBoolean, + assertCollection, assertCollectionUploadOptions, assertData, assertFileData, @@ -39,7 +40,15 @@ import { } from './utils/type' import { setJsonData, getJsonData } from './feed/json' import { makeCollectionFromFS, makeCollectionFromFileList } from './utils/collection' -import { AllTagsOptions, NumberString, PostageBatchOptions, STAMPS_DEPTH_MAX, STAMPS_DEPTH_MIN } from './types' +import { + AllTagsOptions, + NumberString, + PostageBatchOptions, + STAMPS_DEPTH_MAX, + STAMPS_DEPTH_MIN, + Readable, + Collection, +} from './types' import type { Tag, @@ -104,6 +113,9 @@ export class Bee { /** * Upload data to a Bee node * + * **To make sure that you won't loose critical data it is highly recommended to also + * locally pin the data with `options.pin = true`** + * * @param postageBatchId Postage BatchId to be used to upload the data with * @param data Data to be uploaded * @param options Additional options like tag, encryption, pinning, content-type @@ -141,12 +153,14 @@ export class Bee { /** * Download data as a Readable stream * + * TODO: Test this in browser scope + * * @param reference Bee data reference * @param axiosOptions optional - alter default options of axios HTTP client * @see [Bee docs - Upload and download](https://docs.ethswarm.org/docs/access-the-swarm/upload-and-download) * @see [Bee API reference - `GET /bytes`](https://docs.ethswarm.org/api/#tag/Bytes/paths/~1bytes~1{reference}/get) */ - async downloadReadableData(reference: Reference | string, axiosOptions?: AxiosRequestConfig): Promise { + async downloadReadableData(reference: Reference | string, axiosOptions?: AxiosRequestConfig): Promise { assertReference(reference) return bytes.downloadReadable(this.url, reference, axiosOptions) @@ -225,17 +239,33 @@ export class Bee { * @see [Bee docs - Upload and download](https://docs.ethswarm.org/docs/access-the-swarm/upload-and-download) * @see [Bee API reference - `GET /bzz`](https://docs.ethswarm.org/api/#tag/Collection/paths/~1bzz~1{reference}~1{path}/get) */ - async downloadReadableFile(reference: Reference | string, path = ''): Promise> { + async downloadReadableFile(reference: Reference | string, path = ''): Promise> { assertReference(reference) return bzz.downloadFileReadable(this.url, reference, path) } + async uploadCollection( + postageBatchId: string | BatchId, + collection: Collection, + options?: CollectionUploadOptions, + ): Promise { + assertBatchId(postageBatchId) + assertCollection(collection) + + if (options) assertCollectionUploadOptions(options) + + return bzz.uploadCollection(this.url, collection, postageBatchId, options) + } + /** * Upload collection of files to a Bee node * * Uses the FileList API from the browser. * + * **To make sure that you won't loose critical data it is highly recommended to also + * locally pin the data with `options.pin = true`** + * * @param postageBatchId Postage BatchId to be used to upload the data with * @param fileList list of files to be uploaded * @param options Additional options like tag, encryption, pinning @@ -263,6 +293,9 @@ export class Bee { * * Available only in Node.js as it uses the `fs` module. * + * **To make sure that you won't loose critical data it is highly recommended to also + * locally pin the data with `options.pin = true`** + * * @param postageBatchId Postage BatchId to be used to upload the data with * @param dir the path of the files to be uploaded * @param options Additional options like tag, encryption, pinning diff --git a/src/modules/bzz.ts b/src/modules/bzz.ts index 36fa180d..4a83a934 100644 --- a/src/modules/bzz.ts +++ b/src/modules/bzz.ts @@ -7,16 +7,17 @@ import { FileUploadOptions, Reference, UploadHeaders, + Readable, } from '../types' import { extractUploadHeaders, readFileHeaders } from '../utils/headers' import { safeAxios } from '../utils/safe-axios' import { prepareData } from '../utils/data' import { BeeArgumentError } from '../utils/error' import { makeTar } from '../utils/tar' -import { assertCollection } from '../utils/collection' import { AxiosRequestConfig } from 'axios' import { wrapBytesWithHelpers } from '../utils/bytes' -import { Readable } from 'stream' +import type { Readable as NodeReadable } from 'stream' +import { assertCollection } from '../utils/type' const bzzEndpoint = '/bzz' @@ -111,8 +112,8 @@ export async function downloadFileReadable( hash: string, path = '', axiosOptions?: AxiosRequestConfig, -): Promise> { - const response = await safeAxios({ +): Promise> { + const response = await safeAxios({ ...axiosOptions, method: 'GET', responseType: 'stream', diff --git a/src/types/index.ts b/src/types/index.ts index f09b9af3..f66e6b1d 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -7,8 +7,8 @@ import { Bytes } from '../utils/bytes' import { BeeError } from '../utils/error' import { EthAddress, HexEthAddress } from '../utils/eth' import { HexString } from '../utils/hex' -import { Readable as NativeReadable } from 'stream' -import { Readable as CompatibilityReadable } from 'readable-stream' +import type { Readable as NativeReadable } from 'stream' +import type { Readable as CompatibilityReadable } from 'readable-stream' export * from './debug' @@ -52,7 +52,7 @@ export type Address = HexString /** * Type representing Readable stream that abstracts away implementation especially the difference between - * browser and NodeJS versions + * browser and NodeJS versions as both are supported. */ export type Readable = NativeReadable | CompatibilityReadable | ReadableStream diff --git a/src/utils/collection.ts b/src/utils/collection.ts index d44e468f..25030bf3 100644 --- a/src/utils/collection.ts +++ b/src/utils/collection.ts @@ -1,27 +1,7 @@ import fs from 'fs' import path from 'path' -import { Collection } from '../types' -import { BeeArgumentError } from './error' -import { isReadable, isUint8Array } from './type' -import { ReadableWebToNodeStream } from 'readable-web-to-node-stream' -import type { Readable } from 'readable-stream' - -export function isCollection(data: unknown): data is Collection { - if (!Array.isArray(data)) { - return false - } - - return data.every( - entry => - typeof entry === 'object' && entry.data && entry.path && (isUint8Array(entry.data) || isReadable(entry.data)), - ) -} - -export function assertCollection(data: unknown): asserts data is Collection { - if (!isCollection(data)) { - throw new BeeArgumentError('invalid collection', data) - } -} +import { Collection, Readable } from '../types' +import { Readable as NodeReadable } from 'stream' /** * Creates array in the format of Collection with data loaded from directory on filesystem. @@ -29,7 +9,7 @@ export function assertCollection(data: unknown): asserts data is Collection> { +export async function makeCollectionFromFS(dir: string): Promise> { if (typeof dir !== 'string') { throw new TypeError('dir has to be string!') } @@ -41,11 +21,11 @@ export async function makeCollectionFromFS(dir: string): Promise> { +async function buildCollectionRelative(dir: string, relativePath: string): Promise> { // Handles case when the dir is not existing or it is a file ==> throws an error const dirname = path.join(dir, relativePath) const entries = await fs.promises.opendir(dirname) - let collection: Collection = [] + let collection: Collection = [] for await (const entry of entries) { const fullPath = path.join(dir, relativePath, entry.name) @@ -54,7 +34,8 @@ async function buildCollectionRelative(dir: string, relativePath: string): Promi if (entry.isFile()) { collection.push({ path: entryPath, - data: new Uint8Array(await fs.promises.readFile(fullPath)), + data: fs.createReadStream(fullPath), + length: (await fs.promises.stat(fullPath)).size, }) } else if (entry.isDirectory()) { collection = [...(await buildCollectionRelative(dir, entryPath)), ...collection] @@ -96,7 +77,7 @@ export function makeCollectionFromFileList(fileList: FileList | File[]): Collect if (file) { collection.push({ path: makeFilePath(file), - data: new ReadableWebToNodeStream(file.stream()), + data: file.stream(), length: file.size, }) } diff --git a/src/utils/data.ts b/src/utils/data.ts index e5e08ec1..8498ee35 100644 --- a/src/utils/data.ts +++ b/src/utils/data.ts @@ -1,5 +1,6 @@ -import { Readable } from 'stream' import type { Data } from 'ws' +import { Readable } from '../types' +import { isReadable } from './type' /** * Validates input and converts to Uint8Array or Readable @@ -11,7 +12,7 @@ export function prepareData(data: string | ArrayBuffer | Uint8Array | Readable): if (data instanceof ArrayBuffer) return new Uint8Array(data) - if (data instanceof Uint8Array || data instanceof Readable) return data + if (data instanceof Uint8Array || isReadable(data)) return data throw new TypeError('unknown data type') } diff --git a/src/utils/expose.ts b/src/utils/expose.ts index 802a63e3..939bc38c 100644 --- a/src/utils/expose.ts +++ b/src/utils/expose.ts @@ -1,7 +1,6 @@ export * as Collections from './collection' export * as Bytes from './bytes' export * as Data from './data' -export * as File from './file' export * as Hex from './hex' export * as Tar from './tar' export * as Eth from './eth' diff --git a/src/utils/tar.ts b/src/utils/tar.ts index 268291ca..d40455d4 100644 --- a/src/utils/tar.ts +++ b/src/utils/tar.ts @@ -1,10 +1,11 @@ -import { Collection } from '../types' -import { Readable } from 'stream' +import { Collection, Readable } from '../types' import * as tar from 'tar-stream' import { Pack } from 'tar-stream' import { assertNonNegativeInteger, isReadable } from './type' +import type { Readable as NodeReadable } from 'stream' +import { ReadableWebToNodeStream } from 'readable-web-to-node-stream' -type FileInfo = { name: string; size: number; stream: Readable } +type FileInfo = { name: string; size: number; stream: NodeReadable } /** * Helper class for tar-stream as found at https://github.com/mafintosh/tar-stream/issues/24#issuecomment-579797456 @@ -17,7 +18,7 @@ export class TarArchive { private streamQueue: FileInfo[] = [] private size = 0 - addBuffer(name: string, buffer: Buffer) { + addBuffer(name: string, buffer: Buffer): void { this.size += buffer.length this.pack.entry( { @@ -27,11 +28,11 @@ export class TarArchive { ) } - addStream(name: string, size: number, stream: Readable) { + addStream(name: string, size: number, stream: Readable): void { this.streamQueue.push({ name, size, - stream, + stream: this.normalizeStream(stream), }) } @@ -47,6 +48,24 @@ export class TarArchive { }) } + private normalizeStream(stream: Readable): NodeReadable { + const browserReadable = stream as ReadableStream + + if ( + typeof browserReadable.getReader === 'function' && + browserReadable.locked !== undefined && + typeof browserReadable.cancel === 'function' && + typeof browserReadable.pipeTo === 'function' && + typeof browserReadable.pipeThrough === 'function' + ) { + // The typings for `readable-stream` is implementing old version of streams + // so I am re-typing this to use the native typings from `stream` package. + return new ReadableWebToNodeStream(stream as ReadableStream) as unknown as NodeReadable + } + + return stream as NodeReadable + } + private nextEntry(callback: (err?: Error) => void) { const file = this.streamQueue.shift() @@ -78,7 +97,7 @@ export async function makeTar(data: Collection): Promise< for (const entry of data) { if (isReadable(entry.data)) { - assertNonNegativeInteger(entry.length, 'entry.length') + assertNonNegativeInteger(entry.length, "Collection's entry.length") tar.addStream(entry.path, entry.length, entry.data) } else if (entry.data instanceof Uint8Array) { diff --git a/src/utils/type.ts b/src/utils/type.ts index d4199cd9..899251e6 100644 --- a/src/utils/type.ts +++ b/src/utils/type.ts @@ -1,4 +1,3 @@ -import { Readable } from 'stream' import { Address, AddressPrefix, @@ -19,18 +18,44 @@ import { AllTagsOptions, TAGS_LIMIT_MIN, TAGS_LIMIT_MAX, + Readable, + Collection, + CollectionEntry, } from '../types' import { BeeArgumentError } from './error' import { assertHexString } from './hex' +import type { Readable as NodeReadable } from 'stream' +/** + * Validates if passed object is either browser's ReadableStream + * or Node's Readable. + * + * @param entry + */ export function isReadable(entry: unknown): entry is Readable { - return ( - typeof entry === 'object' && - entry !== null && - typeof (entry as Readable).pipe === 'function' && - (entry as Readable).readable && - typeof (entry as Readable)._read === 'function' - ) + if (!isStrictlyObject(entry)) { + return false + } + + const nodeReadable = entry as NodeReadable + + if (typeof nodeReadable.pipe === 'function' && nodeReadable.readable && typeof nodeReadable._read === 'function') { + return true + } + + const browserReadable = entry as ReadableStream + + if ( + typeof browserReadable.getReader === 'function' && + browserReadable.locked !== undefined && + typeof browserReadable.cancel === 'function' && + typeof browserReadable.pipeTo === 'function' && + typeof browserReadable.pipeThrough === 'function' + ) { + return true + } + + return false } export function isFile(file: unknown): file is File { @@ -67,7 +92,17 @@ export function isObject(value: unknown): value is Record { return value !== null && typeof value === 'object' } -export function isStrictlyObject(value: unknown): value is Record { +/** + * Generally it is discouraged to use `object` type, but in this case I think + * it is best to do so as it is possible to easily convert from `object`to other + * types, which will be usually the case after asserting that the object is + * strictly object. With for examlpe Record you have to first + * cast it to `unknown` which I think bit defeat the purpose. + * + * @param value + */ +// eslint-disable-next-line @typescript-eslint/ban-types +export function isStrictlyObject(value: unknown): value is object { return isObject(value) && !Array.isArray(value) } @@ -75,12 +110,12 @@ export function assertBoolean(value: unknown): asserts value is boolean { if (value !== true && value !== false) throw new TypeError('value is not boolean') } -export function assertInteger(value: unknown): asserts value is number | NumberString { - if (!isInteger(value)) throw new TypeError('value is not integer') +export function assertInteger(value: unknown, name = 'value'): asserts value is number | NumberString { + if (!isInteger(value)) throw new TypeError(`${name} is not integer`) } export function assertNonNegativeInteger(value: unknown, name = 'Value'): asserts value is number | NumberString { - assertInteger(value) + assertInteger(value, name) if (Number(value) < 0) throw new BeeArgumentError(`${name} has to be bigger or equal to zero`, value) } @@ -147,6 +182,32 @@ export function assertFileUploadOptions(value: unknown): asserts value is FileUp } } +export function assertCollection(data: unknown): asserts data is Collection { + if (!Array.isArray(data)) { + throw new TypeError('Collection must be an array!') + } + + for (const el of data) { + if (!isStrictlyObject(el)) { + throw new TypeError("Collection's entry must be an object!") + } + + const entry = el as CollectionEntry + + if (!entry.path || typeof entry.path !== 'string') { + throw new TypeError("Collection's entry must have string property path!") + } + + if (!isUint8Array(entry.data) && !isReadable(entry.data)) { + throw new TypeError("Collection's entry data must be either Uint8Array or Readable!") + } + + if (isReadable(entry.data) && typeof entry.length !== 'number') { + throw new TypeError('When collections entry uses Readable it has to also specify its length!') + } + } +} + export function assertCollectionUploadOptions(value: unknown): asserts value is CollectionUploadOptions { assertUploadOptions(value, 'CollectionUploadOptions') @@ -267,22 +328,24 @@ export function assertAllTagsOptions(options: unknown): asserts options is AllTa throw new TypeError('options has to be an object or undefined!') } - if (options?.limit !== undefined) { - if (typeof options.limit !== 'number') { + const tagOptions = options as AllTagsOptions + + if (tagOptions?.limit !== undefined) { + if (typeof tagOptions.limit !== 'number') { throw new TypeError('options.limit has to be a number or undefined!') } - if (options.limit < TAGS_LIMIT_MIN) { - throw new BeeArgumentError(`options.limit has to be at least ${TAGS_LIMIT_MIN}`, options.limit) + if (tagOptions.limit < TAGS_LIMIT_MIN) { + throw new BeeArgumentError(`options.limit has to be at least ${TAGS_LIMIT_MIN}`, tagOptions.limit) } - if (options.limit > TAGS_LIMIT_MAX) { - throw new BeeArgumentError(`options.limit has to be at most ${TAGS_LIMIT_MAX}`, options.limit) + if (tagOptions.limit > TAGS_LIMIT_MAX) { + throw new BeeArgumentError(`options.limit has to be at most ${TAGS_LIMIT_MAX}`, tagOptions.limit) } } - if (options?.offset !== undefined) { - assertNonNegativeInteger(options.offset, 'options.offset') + if (tagOptions?.offset !== undefined) { + assertNonNegativeInteger(tagOptions.offset, 'options.offset') } } diff --git a/test/integration/bee-class.spec.ts b/test/integration/bee-class.spec.ts index e90a5eb1..0e6eb342 100644 --- a/test/integration/bee-class.spec.ts +++ b/test/integration/bee-class.spec.ts @@ -19,6 +19,7 @@ import { PSS_TIMEOUT, randomByteArray, sleep, + streamToString, testChunkPayload, testIdentity, testJsonHash, @@ -72,11 +73,11 @@ describe('Bee class', () => { }) it('should work with file object', async () => { - const content = new Uint8Array([1, 2, 3]) + const content = 'hello world' const name = 'hello.txt' const type = 'text/plain' const file = { - arrayBuffer: () => content, + stream: () => Readable.from(content), name, type, } as unknown as File @@ -84,16 +85,16 @@ describe('Bee class', () => { const hash = await bee.uploadFile(getPostageBatch(), file) const downloadedFile = await bee.downloadFile(hash) - expect(downloadedFile.data).toEqual(content) + expect(downloadedFile.data.text()).toEqual(content) expect(downloadedFile.name).toEqual(name) expect(downloadedFile.contentType).toEqual(type) }) it('should work with file object and name overridden', async () => { - const content = new Uint8Array([1, 2, 3]) + const content = 'hello world' const name = 'hello.txt' const file = { - arrayBuffer: () => content, + stream: () => Readable.from(content), name, } as unknown as File const nameOverride = 'hello-override.txt' @@ -101,14 +102,14 @@ describe('Bee class', () => { const hash = await bee.uploadFile(getPostageBatch(), file, nameOverride) const downloadedFile = await bee.downloadFile(hash) - expect(downloadedFile.data).toEqual(content) + expect(downloadedFile.data.text()).toEqual(content) expect(downloadedFile.name).toEqual(nameOverride) }) it('should work with file object and content-type overridden', async () => { - const content = new Uint8Array([1, 2, 3]) + const content = 'hello world' const file = { - arrayBuffer: () => content, + stream: () => Readable.from(content), name: 'hello.txt', type: 'text/plain', } as unknown as File @@ -117,11 +118,11 @@ describe('Bee class', () => { const hash = await bee.uploadFile(getPostageBatch(), file, undefined, { contentType: contentTypeOverride }) const downloadedFile = await bee.downloadFile(hash) - expect(downloadedFile.data).toEqual(content) + expect(downloadedFile.data.text()).toEqual(content) expect(downloadedFile.contentType).toEqual(contentTypeOverride) }) - it('should work with readable', async () => { + it('should work with readable upload', async () => { const readable = Readable.from(['hello world']) const name = 'hello.txt' const contentType = 'text/plain' @@ -133,6 +134,18 @@ describe('Bee class', () => { expect(file.data.text()).toEqual('hello world') }) + it('should work with readable download', async () => { + const readable = Readable.from(['hello world']) + const name = 'hello.txt' + const contentType = 'text/plain' + + const hash = await bee.uploadFile(getPostageBatch(), readable, name, { contentType }) + const readableFileData = await bee.downloadReadableFile(hash) + + expect(readableFileData.name).toEqual(name) + expect(await streamToString(readableFileData.data)).toEqual('hello world') + }) + it('should work with readable and tags', async () => { const tag = await bee.createTag() @@ -160,6 +173,25 @@ describe('Bee class', () => { const hash = await bee.uploadFilesFromDirectory(getPostageBatch(), './test/data') expect(hash.length).toEqual(REFERENCE_HEX_LENGTH) + + const file = await bee.downloadFile(hash, '1.txt') + expect(file.data.text()).toEqual('1\n') + }) + + it('should upload collection', async () => { + const directoryStructure: Collection = [ + { + path: '0', + data: Readable.from('hello-world'), + length: 11, + }, + ] + + const hash = await bee.uploadCollection(getPostageBatch(), directoryStructure) + const file = await bee.downloadFile(hash, directoryStructure[0].path) + + expect(file.name).toEqual(directoryStructure[0].path) + expect(file.data.text()).toEqual('hello-world') }) }) diff --git a/test/integration/modules/bzz.spec.ts b/test/integration/modules/bzz.spec.ts index bf6d7c31..de10cc8c 100644 --- a/test/integration/modules/bzz.spec.ts +++ b/test/integration/modules/bzz.spec.ts @@ -24,6 +24,22 @@ describe('modules/bzz', () => { expect(file.data).toEqual(directoryStructure[0].data) }) + it('should store and retrieve collection with readable', async () => { + const directoryStructure: Collection = [ + { + path: '0', + data: Readable.from('hello-world'), + length: 11, + }, + ] + + const hash = await bzz.uploadCollection(BEE_URL, directoryStructure, getPostageBatch()) + const file = await bzz.downloadFile(BEE_URL, hash, directoryStructure[0].path) + + expect(file.name).toEqual(directoryStructure[0].path) + expect(file.data.text()).toEqual('hello-world') + }) + it('should retrieve the filename but not the complete path', async () => { const path = 'a/b/c/d/' const name = '0' diff --git a/test/unit/assertions.ts b/test/unit/assertions.ts index c25ee2ba..9b2f75d5 100644 --- a/test/unit/assertions.ts +++ b/test/unit/assertions.ts @@ -1,8 +1,9 @@ /* eslint-disable */ import { BeeArgumentError } from '../../src' import { makeBytes } from '../../src/utils/bytes' +import { Readable } from 'stream' -export function testBatchIdAssertion(executor: (input: unknown) => void): void { +export function testBatchIdAssertion (executor: (input: unknown) => void): void { it('should throw exception for bad BatchId', async () => { await expect(() => executor(1)).rejects.toThrow(TypeError) await expect(() => executor(true)).rejects.toThrow(TypeError) @@ -14,17 +15,17 @@ export function testBatchIdAssertion(executor: (input: unknown) => void): void { // Not an valid hexstring (ZZZ) await expect(() => executor('ZZZfb5a872396d9693e5c9f9d7233cfa93f395c093371017ff44aa9ae6564cdd')).rejects.toThrow( - TypeError, + TypeError ) // Prefixed hexstring is not accepted await expect(() => executor('0x634fb5a872396d9693e5c9f9d7233cfa93f395c093371017ff44aa9ae6564cdd')).rejects.toThrow( - TypeError, + TypeError ) }) } -export function testDataAssertions(executor: (input: unknown) => void): void { +export function testDataAssertions (executor: (input: unknown) => void): void { it('should throw exception for bad Data', async () => { await expect(() => executor(1)).rejects.toThrow(TypeError) await expect(() => executor(true)).rejects.toThrow(TypeError) @@ -35,7 +36,7 @@ export function testDataAssertions(executor: (input: unknown) => void): void { }) } -export function testFileDataAssertions(executor: (input: unknown) => void): void { +export function testFileDataAssertions (executor: (input: unknown) => void): void { it('should throw exception for bad FileData', async () => { await expect(() => executor(1)).rejects.toThrow(TypeError) await expect(() => executor(true)).rejects.toThrow(TypeError) @@ -49,7 +50,7 @@ export function testFileDataAssertions(executor: (input: unknown) => void): void }) } -export function testUploadOptionsAssertions(executor: (input: unknown) => void): void { +export function testUploadOptionsAssertions (executor: (input: unknown) => void): void { it('should throw exception for bad UploadOptions', async () => { await expect(() => executor(1)).rejects.toThrow(TypeError) await expect(() => executor(true)).rejects.toThrow(TypeError) @@ -79,7 +80,7 @@ export function testUploadOptionsAssertions(executor: (input: unknown) => void): }) } -export function testFileUploadOptionsAssertions(executor: (input: unknown) => void): void { +export function testFileUploadOptionsAssertions (executor: (input: unknown) => void): void { it('should throw exception for bad FileUploadOptions', async () => { await expect(() => executor({ contentType: true })).rejects.toThrow(TypeError) await expect(() => executor({ contentType: 1 })).rejects.toThrow(TypeError) @@ -94,7 +95,7 @@ export function testFileUploadOptionsAssertions(executor: (input: unknown) => vo }) } -export function testCollectionUploadOptionsAssertions(executor: (input: unknown) => void): void { +export function testCollectionUploadOptionsAssertions (executor: (input: unknown) => void): void { it('should throw exception for bad CollectionUploadOptions', async () => { await expect(() => executor({ indexDocument: true })).rejects.toThrow(TypeError) await expect(() => executor({ indexDocument: 1 })).rejects.toThrow(TypeError) @@ -108,7 +109,38 @@ export function testCollectionUploadOptionsAssertions(executor: (input: unknown) }) } -export function testReferenceAssertions(executor: (input: unknown) => void): void { +export function testCollectionAssertions (executor: (input: unknown) => void): void { + it('should throw exception for bad Collection', async () => { + await expect(() => executor('string')).rejects.toThrow(TypeError) + await expect(() => executor(true)).rejects.toThrow(TypeError) + await expect(() => executor({})).rejects.toThrow(TypeError) + await expect(() => executor(null)).rejects.toThrow(TypeError) + await expect(() => executor(undefined)).rejects.toThrow(TypeError) + + await expect(() => executor([{ path: true, data: new Uint8Array([1, 2, 3]) }])).rejects.toThrow(TypeError) + await expect(() => executor([{ path: 1, data: new Uint8Array([1, 2, 3]) }])).rejects.toThrow(TypeError) + await expect(() => executor([{ path: null, data: new Uint8Array([1, 2, 3]) }])).rejects.toThrow(TypeError) + await expect(() => executor([{ path: undefined, data: new Uint8Array([1, 2, 3]) }])).rejects.toThrow(TypeError) + await expect(() => executor([{ path: [], data: new Uint8Array([1, 2, 3]) }])).rejects.toThrow(TypeError) + await expect(() => executor([{ path: {}, data: new Uint8Array([1, 2, 3]) }])).rejects.toThrow(TypeError) + + await expect(() => executor([{ path: 'some/path', data: null }])).rejects.toThrow(TypeError) + await expect(() => executor([{ path: 'some/path', data: true }])).rejects.toThrow(TypeError) + await expect(() => executor([{ path: 'some/path', data: 1 }])).rejects.toThrow(TypeError) + await expect(() => executor([{ path: 'some/path', data: 'string' }])).rejects.toThrow(TypeError) + await expect(() => executor([{ path: 'some/path', data: undefined }])).rejects.toThrow(TypeError) + await expect(() => executor([{ path: 'some/path', data: {} }])).rejects.toThrow(TypeError) + + await expect(() => executor([{ path: 'some/path', data: Readable.from('hello-world') }])).rejects.toThrow(TypeError) + await expect(() => executor([{ path: 'some/path', data: Readable.from('hello-world'), length: '' }])).rejects.toThrow(TypeError) + await expect(() => executor([{ path: 'some/path', data: Readable.from('hello-world'), length: true }])).rejects.toThrow(TypeError) + await expect(() => executor([{ path: 'some/path', data: Readable.from('hello-world'), length: [] }])).rejects.toThrow(TypeError) + await expect(() => executor([{ path: 'some/path', data: Readable.from('hello-world'), length: {} }])).rejects.toThrow(TypeError) + await expect(() => executor([{ path: 'some/path', data: Readable.from('hello-world'), length: null }])).rejects.toThrow(TypeError) + }) +} + +export function testReferenceAssertions (executor: (input: unknown) => void): void { it('should throw exception for bad Reference', async () => { await expect(() => executor(1)).rejects.toThrow(TypeError) await expect(() => executor(true)).rejects.toThrow(TypeError) @@ -120,22 +152,22 @@ export function testReferenceAssertions(executor: (input: unknown) => void): voi // Not an valid hexstring (ZZZ) await expect(() => executor('ZZZfb5a872396d9693e5c9f9d7233cfa93f395c093371017ff44aa9ae6564cdd')).rejects.toThrow( - TypeError, + TypeError ) // Prefixed hexstring is not accepted await expect(() => executor('0x634fb5a872396d9693e5c9f9d7233cfa93f395c093371017ff44aa9ae6564cdd')).rejects.toThrow( - TypeError, + TypeError ) // Length mismatch await expect(() => executor('4fb5a872396d9693e5c9f9d7233cfa93f395c093371017ff44aa9ae6564cdd')).rejects.toThrow( - TypeError, + TypeError ) }) } -export function testAddressPrefixAssertions(executor: (input: unknown) => void): void { +export function testAddressPrefixAssertions (executor: (input: unknown) => void): void { it('should throw exception for bad AddressPrefix', async () => { await expect(() => executor(1)).rejects.toThrow(TypeError) await expect(() => executor(true)).rejects.toThrow(TypeError) @@ -147,22 +179,22 @@ export function testAddressPrefixAssertions(executor: (input: unknown) => void): // Not an valid hexstring (ZZZ) await expect(() => executor('ZZZfb5a872396d9693e5c9f9d7233cfa93f395c093371017ff44aa9ae6564cdd')).rejects.toThrow( - TypeError, + TypeError ) // Prefixed hexstring is not accepted await expect(() => executor('0x634fb5a872396d9693e5c9f9d7233cfa93f395c093371017ff44aa9ae6564cdd')).rejects.toThrow( - TypeError, + TypeError ) // Too long hexstring await expect(() => executor('123634fb5a872396d9693e5c9f9d7233cfa93f395c093371017ff44aa9ae6564cdd')).rejects.toThrow( - BeeArgumentError, + BeeArgumentError ) }) } -export function testPublicKeyAssertions(executor: (input: unknown) => void): void { +export function testPublicKeyAssertions (executor: (input: unknown) => void): void { it('should throw exception for bad PublicKey', async () => { await expect(() => executor(1)).rejects.toThrow(TypeError) await expect(() => executor(true)).rejects.toThrow(TypeError) @@ -171,22 +203,22 @@ export function testPublicKeyAssertions(executor: (input: unknown) => void): voi // Not an valid hexstring (ZZZ) await expect(() => executor('ZZZfb5a872396d9693e5c9f9d7233cfa93f395c093371017ff44aa9ae6564cdd')).rejects.toThrow( - TypeError, + TypeError ) // Prefixed hexstring is not accepted await expect(() => executor('0x634fb5a872396d9693e5c9f9d7233cfa93f395c093371017ff44aa9ae6564cdd')).rejects.toThrow( - TypeError, + TypeError ) // Length mismatch await expect(() => executor('4fb5a872396d9693e5c9f9d7233cfa93f395c093371017ff44aa9ae6564cdd')).rejects.toThrow( - TypeError, + TypeError ) }) } -export function testPssMessageHandlerAssertions(executor: (input: unknown) => void): void { +export function testPssMessageHandlerAssertions (executor: (input: unknown) => void): void { it('should throw exception for bad PssMessageHandler', async () => { await expect(() => executor(1)).rejects.toThrow(TypeError) await expect(() => executor(true)).rejects.toThrow(TypeError) @@ -197,48 +229,48 @@ export function testPssMessageHandlerAssertions(executor: (input: unknown) => vo await expect(() => executor('')).rejects.toThrow(TypeError) await expect(() => { - return executor({ onMessage() {} }) + return executor({ onMessage () {} }) }).rejects.toThrow(TypeError) await expect(() => { - return executor({ onMessage() {}, onError: '' }) + return executor({ onMessage () {}, onError: '' }) }).rejects.toThrow(TypeError) await expect(() => { - return executor({ onMessage() {}, onError: [] }) + return executor({ onMessage () {}, onError: [] }) }).rejects.toThrow(TypeError) await expect(() => { - return executor({ onMessage() {}, onError: {} }) + return executor({ onMessage () {}, onError: {} }) }).rejects.toThrow(TypeError) await expect(() => { - return executor({ onMessage() {}, onError: true }) + return executor({ onMessage () {}, onError: true }) }).rejects.toThrow(TypeError) await expect(() => { - return executor({ onError() {}, onMessage: true }) + return executor({ onError () {}, onMessage: true }) }).rejects.toThrow(TypeError) await expect(() => { - return executor({ onError() {}, onMessage: {} }) + return executor({ onError () {}, onMessage: {} }) }).rejects.toThrow(TypeError) await expect(() => { - return executor({ onError() {}, onMessage: [] }) + return executor({ onError () {}, onMessage: [] }) }).rejects.toThrow(TypeError) await expect(() => { - return executor({ onError() {}, onMessage: '' }) + return executor({ onError () {}, onMessage: '' }) }).rejects.toThrow(TypeError) await expect(() => { - return executor({ onError() {}, onMessage: 1 }) + return executor({ onError () {}, onMessage: 1 }) }).rejects.toThrow(TypeError) }) } -export function testTopicAssertions(executor: (input: unknown) => void): void { +export function testTopicAssertions (executor: (input: unknown) => void): void { it('should throw exception for bad Topic', async () => { await expect(() => executor(1)).rejects.toThrow(TypeError) await expect(() => executor(true)).rejects.toThrow(TypeError) @@ -249,7 +281,7 @@ export function testTopicAssertions(executor: (input: unknown) => void): void { }) } -export function testFeedTopicAssertions(executor: (input: unknown) => void): void { +export function testFeedTopicAssertions (executor: (input: unknown) => void): void { it('should throw exception for bad Topic', async () => { await expect(() => executor(1)).rejects.toThrow(TypeError) await expect(() => executor(true)).rejects.toThrow(TypeError) @@ -260,17 +292,17 @@ export function testFeedTopicAssertions(executor: (input: unknown) => void): voi // Not an valid hexstring (ZZZ) await expect(() => executor('ZZZfb5a872396d9693e5c9f9d7233cfa93f395c093371017ff44aa9ae6564cdd')).rejects.toThrow( - TypeError, + TypeError ) // Length mismatch await expect(() => executor('4fb5a872396d9693e5c9f9d7233cfa93f395c093371017ff44aa9ae6564cdd')).rejects.toThrow( - TypeError, + TypeError ) }) } -export function testEthAddressAssertions(executor: (input: unknown) => void): void { +export function testEthAddressAssertions (executor: (input: unknown) => void): void { it('should throw exception for bad EthAddress', async () => { await expect(() => executor(1)).rejects.toThrow(TypeError) await expect(() => executor(true)).rejects.toThrow(TypeError) @@ -281,12 +313,12 @@ export function testEthAddressAssertions(executor: (input: unknown) => void): vo // Not an valid hexstring (ZZZ) await expect(() => executor('ZZZfb5a872396d9693e5c9f9d7233cfa93f395c093371017ff44aa9ae6564cdd')).rejects.toThrow( - TypeError, + TypeError ) // Length mismatch await expect(() => executor('4fb5a872396d9693e5c9f9d7233cfa93f395c093371017ff44aa9ae6564cdd')).rejects.toThrow( - TypeError, + TypeError ) // Bytes length mismatch @@ -294,7 +326,7 @@ export function testEthAddressAssertions(executor: (input: unknown) => void): vo }) } -export function testMakeSignerAssertions(executor: (input: unknown) => void, optionals = true): void { +export function testMakeSignerAssertions (executor: (input: unknown) => void, optionals = true): void { it('should throw exception for bad Signer', async () => { await expect(() => executor(1)).rejects.toThrow(TypeError) await expect(() => executor(true)).rejects.toThrow(TypeError) @@ -308,12 +340,12 @@ export function testMakeSignerAssertions(executor: (input: unknown) => void, opt // Not an valid hexstring (ZZZ) await expect(() => executor('ZZZfb5a872396d9693e5c9f9d7233cfa93f395c093371017ff44aa9ae6564cdd')).rejects.toThrow( - TypeError, + TypeError ) // Hex Length mismatch await expect(() => executor('4fb5a872396d9693e5c9f9d7233cfa93f395c093371017ff44aa9ae6564cdd')).rejects.toThrow( - TypeError, + TypeError ) // Bytes Length mismatch @@ -333,7 +365,7 @@ export function testMakeSignerAssertions(executor: (input: unknown) => void, opt }) } -export function testFeedTypeAssertions(executor: (input: unknown) => void, optionals = true): void { +export function testFeedTypeAssertions (executor: (input: unknown) => void, optionals = true): void { it('should throw exception for bad FeedType', async () => { await expect(() => executor(1)).rejects.toThrow(TypeError) await expect(() => executor(true)).rejects.toThrow(TypeError) @@ -349,7 +381,7 @@ export function testFeedTypeAssertions(executor: (input: unknown) => void, optio }) } -export function testAddressAssertions(executor: (input: unknown) => void, optionals = true): void { +export function testAddressAssertions (executor: (input: unknown) => void, optionals = true): void { it('should throw exception for bad Address', async () => { await expect(() => executor(1)).rejects.toThrow(TypeError) await expect(() => executor(true)).rejects.toThrow(TypeError) @@ -359,12 +391,12 @@ export function testAddressAssertions(executor: (input: unknown) => void, option // Not an valid hexstring (ZZZ) await expect(() => executor('ZZZfb5a872396d9693e5c9f9d7233cfa93f395c093371017ff44aa9ae6564cdd')).rejects.toThrow( - TypeError, + TypeError ) // Hex Length mismatch await expect(() => executor('4fb5a872396d9693e5c9f9d7233cfa93f395c093371017ff44aa9ae6564cdd')).rejects.toThrow( - TypeError, + TypeError ) if (optionals) { diff --git a/test/unit/bee-class.spec.ts b/test/unit/bee-class.spec.ts index 3e457752..d6cd9c39 100644 --- a/test/unit/bee-class.spec.ts +++ b/test/unit/bee-class.spec.ts @@ -3,6 +3,7 @@ import { BatchId, Bee, BeeArgumentError, + Collection, CollectionUploadOptions, PssMessageHandler, ReferenceResponse, @@ -26,8 +27,10 @@ import { testFeedTopicAssertions, testEthAddressAssertions, testMakeSignerAssertions, + testCollectionAssertions, } from './assertions' import { FeedType } from '../../src/feed/type' +import { Readable } from 'stream' const TOPIC = 'some=very%nice#topic' const HASHED_TOPIC = makeTopicFromString(TOPIC) @@ -161,6 +164,39 @@ describe('Bee class', () => { }) }) + describe('uploadCollection', () => { + const collection: Collection = [ + { + path: 'some/path', + data: new Uint8Array([1, 2, 3]), + }, + ] + + testBatchIdAssertion(async (input: unknown) => { + const bee = new Bee(MOCK_SERVER_URL) + + return bee.uploadCollection(input as BatchId, collection) + }) + + testUploadOptionsAssertions(async (input: unknown) => { + const bee = new Bee(MOCK_SERVER_URL) + + return bee.uploadCollection(testBatchId, collection, input as UploadOptions) + }) + + testCollectionUploadOptionsAssertions(async (input: unknown) => { + const bee = new Bee(MOCK_SERVER_URL) + + return bee.uploadCollection(testBatchId, collection, input as UploadOptions) + }) + + testCollectionAssertions(async (input: unknown) => { + const bee = new Bee(MOCK_SERVER_URL) + + return bee.uploadCollection(testBatchId, input as Collection) + }) + }) + describe('uploadFilesFromDirectory', () => { testBatchIdAssertion(async (input: unknown) => { const bee = new Bee(MOCK_SERVER_URL) diff --git a/test/utils.ts b/test/utils.ts index 8909b74f..3ba46486 100644 --- a/test/utils.ts +++ b/test/utils.ts @@ -254,6 +254,16 @@ export function shorten(inputStr: unknown, len = 17): string { return `${str.slice(0, 6)}...${str.slice(-6)} (length: ${str.length})` } +export async function streamToString(stream: Readable): Promise { + const chunks: Uint8Array[] = [] + + return new Promise((resolve, reject) => { + stream.on('data', chunk => chunks.push(Buffer.from(chunk))) + stream.on('error', err => reject(err)) + stream.on('end', () => resolve(Buffer.concat(chunks).toString('utf8'))) + }) +} + export const invalidReference = '0000000000000000000000000000000000000000000000000000000000000000' as Reference export const okResponse: BeeGenericResponse = { From 68becaaf6ee23de0524adbbaa6c6f6786e6f2cb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Uhl=C3=AD=C5=99?= Date: Fri, 23 Jul 2021 09:37:34 +0200 Subject: [PATCH 4/5] chore: wip --- package-lock.json | 523 +++++++++++++++++++-- package.json | 2 + test/integration/bee-class.browser.spec.ts | 2 +- webpack.config.ts | 2 + 4 files changed, 491 insertions(+), 38 deletions(-) diff --git a/package-lock.json b/package-lock.json index 34eb6e16..e99162e3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "readable-web-to-node-stream": "^3.0.2", "tar-js": "^0.3.0", "tar-stream": "^2.2.0", + "util": "^0.12.4", "ws": "^7.5.0" }, "devDependencies": { @@ -47,6 +48,7 @@ "babel-jest": "^27.0.5", "babel-loader": "^8.2.2", "bufferutil": "^4.0.3", + "constants-browserify": "^1.0.0", "debug": "^4.3.1", "depcheck": "^1.4.0", "eslint": "^7.29.0", @@ -4851,6 +4853,17 @@ "node": ">= 4.0.0" } }, + "node_modules/available-typed-arrays": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.4.tgz", + "integrity": "sha512-SA5mXJWrId1TaQjfxUYghbqQ/hYioKmLJvPJyDuYRtXXenFNMjj4hSSt1Cf1xsuXSXrtxrVC5Ot4eU6cOtBDdA==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/axios": { "version": "0.21.1", "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", @@ -5281,7 +5294,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, "dependencies": { "function-bind": "^1.1.1", "get-intrinsic": "^1.0.2" @@ -5537,6 +5549,12 @@ "node": ">= 0.10.0" } }, + "node_modules/constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, "node_modules/conventional-changelog-angular": { "version": "5.0.12", "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.12.tgz", @@ -5811,7 +5829,6 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, "dependencies": { "object-keys": "^1.0.12" }, @@ -6113,12 +6130,57 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/es-abstract": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz", + "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==", + "dependencies": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "is-callable": "^1.2.3", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.3", + "is-string": "^1.0.6", + "object-inspect": "^1.10.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/es-module-lexer": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.6.0.tgz", "integrity": "sha512-f8kcHX1ArhllUtb/wVSyvygoKCznIjnxhLxy7TCvIiMdT7fL4ZDTIKaadMe6eLvOXg6Wk02UeoFgUoZ2EKZZUA==", "dev": true }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -7201,6 +7263,11 @@ "node": ">=0.10.0" } }, + "node_modules/foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" + }, "node_modules/form-data": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", @@ -7267,8 +7334,7 @@ "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "node_modules/functional-red-black-tree": { "version": "1.0.1", @@ -7307,7 +7373,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dev": true, "dependencies": { "function-bind": "^1.1.1", "has": "^1.0.3", @@ -7555,7 +7620,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, "dependencies": { "function-bind": "^1.1.1" }, @@ -7563,6 +7627,14 @@ "node": ">= 0.4.0" } }, + "node_modules/has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -7576,7 +7648,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -7870,12 +7941,34 @@ "loose-envify": "^1.0.0" } }, + "node_modules/is-arguments": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz", + "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==", + "dependencies": { + "call-bind": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, + "node_modules/is-bigint": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz", + "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -7892,7 +7985,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.0.tgz", "integrity": "sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA==", - "dev": true, "dependencies": { "call-bind": "^1.0.0" }, @@ -7909,6 +8001,17 @@ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, + "node_modules/is-callable": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-ci": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", @@ -7933,6 +8036,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-date-object": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz", + "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", @@ -7969,6 +8083,17 @@ "node": ">=6" } }, + "node_modules/is-generator-function": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.9.tgz", + "integrity": "sha512-ZJ34p1uvIfptHCN7sFTjGibB9/oBg17sHqzDLfuwhvmN/qLVvIQXRQ8licZQ35WJ8KuEQt/etnnzQFI9C9Ue/A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-glob": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", @@ -7981,6 +8106,17 @@ "node": ">=0.10.0" } }, + "node_modules/is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -7994,7 +8130,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz", "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -8038,6 +8173,21 @@ "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", "dev": true }, + "node_modules/is-regex": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", + "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", + "dependencies": { + "call-bind": "^1.0.2", + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", @@ -8048,10 +8198,23 @@ } }, "node_modules/is-string": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", - "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", - "dev": true, + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", + "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dependencies": { + "has-symbols": "^1.0.2" + }, "engines": { "node": ">= 0.4" }, @@ -8071,6 +8234,24 @@ "node": ">=0.10.0" } }, + "node_modules/is-typed-array": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.5.tgz", + "integrity": "sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug==", + "dependencies": { + "available-typed-arrays": "^1.0.2", + "call-bind": "^1.0.2", + "es-abstract": "^1.18.0-next.2", + "foreach": "^2.0.5", + "has-symbols": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -12795,11 +12976,18 @@ "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", "dev": true }, + "node_modules/object-inspect": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", + "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, "engines": { "node": ">= 0.4" } @@ -12808,7 +12996,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "dev": true, "dependencies": { "call-bind": "^1.0.0", "define-properties": "^1.1.3", @@ -13966,8 +14153,7 @@ "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "node_modules/safer-buffer": { "version": "2.1.2", @@ -14398,6 +14584,30 @@ "node": ">=8" } }, + "node_modules/string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/strip-ansi": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", @@ -15018,6 +15228,20 @@ "node": ">=0.8.0" } }, + "node_modules/unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "dependencies": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/unbzip2-stream": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", @@ -15102,6 +15326,19 @@ "node-gyp-build": "^4.2.0" } }, + "node_modules/util": { + "version": "0.12.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz", + "integrity": "sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==", + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "safe-buffer": "^5.1.2", + "which-typed-array": "^1.1.2" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -15645,6 +15882,41 @@ "node": ">= 8" } }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.4.tgz", + "integrity": "sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA==", + "dependencies": { + "available-typed-arrays": "^1.0.2", + "call-bind": "^1.0.0", + "es-abstract": "^1.18.0-next.1", + "foreach": "^2.0.5", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.1", + "is-typed-array": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/wildcard": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", @@ -19479,6 +19751,11 @@ "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", "dev": true }, + "available-typed-arrays": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.4.tgz", + "integrity": "sha512-SA5mXJWrId1TaQjfxUYghbqQ/hYioKmLJvPJyDuYRtXXenFNMjj4hSSt1Cf1xsuXSXrtxrVC5Ot4eU6cOtBDdA==" + }, "axios": { "version": "0.21.1", "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", @@ -19796,7 +20073,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, "requires": { "function-bind": "^1.1.1", "get-intrinsic": "^1.0.2" @@ -20002,6 +20278,12 @@ "bluebird": "^3.7.2" } }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, "conventional-changelog-angular": { "version": "5.0.12", "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.12.tgz", @@ -20219,7 +20501,6 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, "requires": { "object-keys": "^1.0.12" } @@ -20453,12 +20734,45 @@ "is-arrayish": "^0.2.1" } }, + "es-abstract": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz", + "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==", + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "is-callable": "^1.2.3", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.3", + "is-string": "^1.0.6", + "object-inspect": "^1.10.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + } + }, "es-module-lexer": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.6.0.tgz", "integrity": "sha512-f8kcHX1ArhllUtb/wVSyvygoKCznIjnxhLxy7TCvIiMdT7fL4ZDTIKaadMe6eLvOXg6Wk02UeoFgUoZ2EKZZUA==", "dev": true }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -21245,6 +21559,11 @@ "for-in": "^1.0.1" } }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" + }, "form-data": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", @@ -21295,8 +21614,7 @@ "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "functional-red-black-tree": { "version": "1.0.1", @@ -21329,7 +21647,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dev": true, "requires": { "function-bind": "^1.1.1", "has": "^1.0.3", @@ -21507,11 +21824,15 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, "requires": { "function-bind": "^1.1.1" } }, + "has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==" + }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -21521,8 +21842,7 @@ "has-symbols": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", - "dev": true + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" }, "hash-sum": { "version": "2.0.0", @@ -21741,12 +22061,25 @@ "loose-envify": "^1.0.0" } }, + "is-arguments": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz", + "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==", + "requires": { + "call-bind": "^1.0.0" + } + }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, + "is-bigint": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz", + "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==" + }, "is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -21760,7 +22093,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.0.tgz", "integrity": "sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA==", - "dev": true, "requires": { "call-bind": "^1.0.0" } @@ -21771,6 +22103,11 @@ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, + "is-callable": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==" + }, "is-ci": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", @@ -21789,6 +22126,11 @@ "has": "^1.0.3" } }, + "is-date-object": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz", + "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==" + }, "is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", @@ -21813,6 +22155,11 @@ "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "dev": true }, + "is-generator-function": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.9.tgz", + "integrity": "sha512-ZJ34p1uvIfptHCN7sFTjGibB9/oBg17sHqzDLfuwhvmN/qLVvIQXRQ8licZQ35WJ8KuEQt/etnnzQFI9C9Ue/A==" + }, "is-glob": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", @@ -21822,6 +22169,11 @@ "is-extglob": "^2.1.1" } }, + "is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==" + }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -21831,8 +22183,7 @@ "is-number-object": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz", - "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==", - "dev": true + "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==" }, "is-obj": { "version": "2.0.0", @@ -21861,6 +22212,15 @@ "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", "dev": true }, + "is-regex": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", + "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", + "requires": { + "call-bind": "^1.0.2", + "has-symbols": "^1.0.2" + } + }, "is-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", @@ -21868,10 +22228,17 @@ "dev": true }, "is-string": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", - "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", - "dev": true + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", + "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==" + }, + "is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "requires": { + "has-symbols": "^1.0.2" + } }, "is-text-path": { "version": "1.0.1", @@ -21882,6 +22249,18 @@ "text-extensions": "^1.0.0" } }, + "is-typed-array": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.5.tgz", + "integrity": "sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug==", + "requires": { + "available-typed-arrays": "^1.0.2", + "call-bind": "^1.0.2", + "es-abstract": "^1.18.0-next.2", + "foreach": "^2.0.5", + "has-symbols": "^1.0.1" + } + }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -25546,17 +25925,20 @@ "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", "dev": true }, + "object-inspect": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", + "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==" + }, "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" }, "object.assign": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "dev": true, "requires": { "call-bind": "^1.0.0", "define-properties": "^1.1.3", @@ -26403,8 +26785,7 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "safer-buffer": { "version": "2.1.2", @@ -26757,6 +27138,24 @@ "strip-ansi": "^6.0.0" } }, + "string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, "strip-ansi": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", @@ -27200,6 +27599,17 @@ "dev": true, "optional": true }, + "unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "requires": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + } + }, "unbzip2-stream": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", @@ -27268,6 +27678,19 @@ "node-gyp-build": "^4.2.0" } }, + "util": { + "version": "0.12.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz", + "integrity": "sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==", + "requires": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "safe-buffer": "^5.1.2", + "which-typed-array": "^1.1.2" + } + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -27672,6 +28095,32 @@ "isexe": "^2.0.0" } }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, + "which-typed-array": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.4.tgz", + "integrity": "sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA==", + "requires": { + "available-typed-arrays": "^1.0.2", + "call-bind": "^1.0.0", + "es-abstract": "^1.18.0-next.1", + "foreach": "^2.0.5", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.1", + "is-typed-array": "^1.1.3" + } + }, "wildcard": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", diff --git a/package.json b/package.json index d5f634c5..8adefb2d 100644 --- a/package.json +++ b/package.json @@ -86,6 +86,7 @@ "babel-jest": "^27.0.5", "babel-loader": "^8.2.2", "bufferutil": "^4.0.3", + "constants-browserify": "^1.0.0", "debug": "^4.3.1", "depcheck": "^1.4.0", "eslint": "^7.29.0", @@ -108,6 +109,7 @@ "typedoc-plugin-markdown": "^3.10.0", "typescript": "^4.3.4", "utf-8-validate": "^5.0.5", + "util": "^0.12.4", "webpack": "^5.40.0", "webpack-bundle-analyzer": "^4.4.1", "webpack-cli": "^4.7.2" diff --git a/test/integration/bee-class.browser.spec.ts b/test/integration/bee-class.browser.spec.ts index 82b6459b..2996eafc 100644 --- a/test/integration/bee-class.browser.spec.ts +++ b/test/integration/bee-class.browser.spec.ts @@ -126,7 +126,7 @@ describe('Bee class - in browser', () => { expect(uploadEvent).toEqual({ loaded: 4, total: 4 }) }) - describe('pss', () => { + describe.skip('pss', () => { it( 'should send and receive pss message', done => { diff --git a/webpack.config.ts b/webpack.config.ts index 8113dc66..d009adfa 100644 --- a/webpack.config.ts +++ b/webpack.config.ts @@ -77,6 +77,8 @@ const base = async (env?: Partial): Promise => path: false, fs: false, stream: false, + util: require.resolve("util/"), + constants: require.resolve("constants-browserify") }, }, optimization: { From e1d657c707741e1d00928845d63ca896597cba9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Uhl=C3=AD=C5=99?= Date: Tue, 27 Jul 2021 09:02:52 +0200 Subject: [PATCH 5/5] chore: wip --- .gitignore | 3 + package-lock.json | 580 ++++----------------- package.json | 6 +- src/utils/tar.ts | 2 +- test/integration/bee-class.browser.spec.ts | 8 +- test/integration/bee-class.spec.ts | 15 + webpack.config.ts | 10 +- 7 files changed, 142 insertions(+), 482 deletions(-) diff --git a/.gitignore b/.gitignore index 7506daae..f37cf1b8 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,9 @@ logs *.log +# OS data +.DS_Store + # Runtime data pids *.pid diff --git a/package-lock.json b/package-lock.json index e99162e3..6413af2f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,8 +15,7 @@ "js-sha3": "^0.8.0", "readable-web-to-node-stream": "^3.0.2", "tar-js": "^0.3.0", - "tar-stream": "^2.2.0", - "util": "^0.12.4", + "tar-stream": "auhau/tar-stream#feat/inherits", "ws": "^7.5.0" }, "devDependencies": { @@ -47,6 +46,7 @@ "@typescript-eslint/parser": "^4.28.0", "babel-jest": "^27.0.5", "babel-loader": "^8.2.2", + "buffer": "^5.7.1", "bufferutil": "^4.0.3", "constants-browserify": "^1.0.0", "debug": "^4.3.1", @@ -62,6 +62,7 @@ "jest-puppeteer": "^5.0.4", "nock": "^13.1.0", "prettier": "^2.3.1", + "process": "^0.11.10", "puppeteer": "^9.1.1", "readable-stream": "^3.6.0", "rimraf": "^3.0.2", @@ -71,6 +72,7 @@ "typedoc-plugin-markdown": "^3.10.0", "typescript": "^4.3.4", "utf-8-validate": "^5.0.5", + "web-file-polyfill": "^1.0.2", "webpack": "^5.40.0", "webpack-bundle-analyzer": "^4.4.1", "webpack-cli": "^4.7.2" @@ -4853,17 +4855,6 @@ "node": ">= 4.0.0" } }, - "node_modules/available-typed-arrays": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.4.tgz", - "integrity": "sha512-SA5mXJWrId1TaQjfxUYghbqQ/hYioKmLJvPJyDuYRtXXenFNMjj4hSSt1Cf1xsuXSXrtxrVC5Ot4eU6cOtBDdA==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/axios": { "version": "0.21.1", "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", @@ -5294,6 +5285,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, "dependencies": { "function-bind": "^1.1.1", "get-intrinsic": "^1.0.2" @@ -5829,6 +5821,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, "dependencies": { "object-keys": "^1.0.12" }, @@ -6130,57 +6123,12 @@ "is-arrayish": "^0.2.1" } }, - "node_modules/es-abstract": { - "version": "1.18.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz", - "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==", - "dependencies": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "is-callable": "^1.2.3", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.3", - "is-string": "^1.0.6", - "object-inspect": "^1.10.3", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/es-module-lexer": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.6.0.tgz", "integrity": "sha512-f8kcHX1ArhllUtb/wVSyvygoKCznIjnxhLxy7TCvIiMdT7fL4ZDTIKaadMe6eLvOXg6Wk02UeoFgUoZ2EKZZUA==", "dev": true }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -7263,11 +7211,6 @@ "node": ">=0.10.0" } }, - "node_modules/foreach": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" - }, "node_modules/form-data": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", @@ -7334,7 +7277,8 @@ "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true }, "node_modules/functional-red-black-tree": { "version": "1.0.1", @@ -7373,6 +7317,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, "dependencies": { "function-bind": "^1.1.1", "has": "^1.0.3", @@ -7620,6 +7565,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, "dependencies": { "function-bind": "^1.1.1" }, @@ -7627,14 +7573,6 @@ "node": ">= 0.4.0" } }, - "node_modules/has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -7648,6 +7586,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true, "engines": { "node": ">= 0.4" }, @@ -7941,34 +7880,12 @@ "loose-envify": "^1.0.0" } }, - "node_modules/is-arguments": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz", - "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==", - "dependencies": { - "call-bind": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, - "node_modules/is-bigint": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz", - "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -7985,6 +7902,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.0.tgz", "integrity": "sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA==", + "dev": true, "dependencies": { "call-bind": "^1.0.0" }, @@ -8001,17 +7919,6 @@ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, - "node_modules/is-callable": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", - "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-ci": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", @@ -8036,17 +7943,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-date-object": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz", - "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", @@ -8083,17 +7979,6 @@ "node": ">=6" } }, - "node_modules/is-generator-function": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.9.tgz", - "integrity": "sha512-ZJ34p1uvIfptHCN7sFTjGibB9/oBg17sHqzDLfuwhvmN/qLVvIQXRQ8licZQ35WJ8KuEQt/etnnzQFI9C9Ue/A==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-glob": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", @@ -8106,17 +7991,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -8130,6 +8004,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz", "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==", + "dev": true, "engines": { "node": ">= 0.4" }, @@ -8173,21 +8048,6 @@ "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", "dev": true }, - "node_modules/is-regex": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", - "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", - "dependencies": { - "call-bind": "^1.0.2", - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", @@ -8201,20 +8061,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dependencies": { - "has-symbols": "^1.0.2" - }, + "dev": true, "engines": { "node": ">= 0.4" }, @@ -8234,24 +8081,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-typed-array": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.5.tgz", - "integrity": "sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug==", - "dependencies": { - "available-typed-arrays": "^1.0.2", - "call-bind": "^1.0.2", - "es-abstract": "^1.18.0-next.2", - "foreach": "^2.0.5", - "has-symbols": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -12976,18 +12805,11 @@ "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", "dev": true }, - "node_modules/object-inspect": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", - "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, "engines": { "node": ">= 0.4" } @@ -12996,6 +12818,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, "dependencies": { "call-bind": "^1.0.0", "define-properties": "^1.1.3", @@ -13586,6 +13409,15 @@ "node": ">=8" } }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", @@ -14153,7 +13985,8 @@ "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true }, "node_modules/safer-buffer": { "version": "2.1.2", @@ -14584,30 +14417,6 @@ "node": ">=8" } }, - "node_modules/string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/strip-ansi": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", @@ -14787,8 +14596,8 @@ }, "node_modules/tar-stream": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "resolved": "git+ssh://git@github.com/auhau/tar-stream.git#38e8ef2f4b7371c38aadfe8d46228b7a9ace5077", + "license": "MIT", "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", @@ -15228,20 +15037,6 @@ "node": ">=0.8.0" } }, - "node_modules/unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "dependencies": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/unbzip2-stream": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", @@ -15326,19 +15121,6 @@ "node-gyp-build": "^4.2.0" } }, - "node_modules/util": { - "version": "0.12.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz", - "integrity": "sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==", - "dependencies": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "safe-buffer": "^5.1.2", - "which-typed-array": "^1.1.2" - } - }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -15486,6 +15268,33 @@ "node": ">=10.13.0" } }, + "node_modules/web-blob": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/web-blob/-/web-blob-2.1.3.tgz", + "integrity": "sha512-7ARypAQxyyqT7ZCHydKavBGCzvvhicGuUMFqg6Xua6H0HIqGgEH1VsMVr1P1Nx+D/maqrUNyOzHkTjBQH/bZOQ==", + "dev": true, + "dependencies": { + "web-streams-polyfill": "2.1.1" + } + }, + "node_modules/web-file-polyfill": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/web-file-polyfill/-/web-file-polyfill-1.0.2.tgz", + "integrity": "sha512-GWGSem+0h+DMBcsMTN7TzHUVjSxEUwP67ubgeo47kdU1lCgHbqnFnY0Dc5QIQzFbQqwx28JhnR3lbUUaw6siFQ==", + "dev": true, + "dependencies": { + "web-blob": "2.1.3" + } + }, + "node_modules/web-streams-polyfill": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-2.1.1.tgz", + "integrity": "sha512-dlNpL2aab3g8CKfGz6rl8FNmGaRWLLn2g/DtSc9IjB30mEdE6XxzPfPSig5BwGSzI+oLxHyETrQGKjrVVhbLCg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, "node_modules/webidl-conversions": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", @@ -15882,41 +15691,6 @@ "node": ">= 8" } }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.4.tgz", - "integrity": "sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA==", - "dependencies": { - "available-typed-arrays": "^1.0.2", - "call-bind": "^1.0.0", - "es-abstract": "^1.18.0-next.1", - "foreach": "^2.0.5", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.1", - "is-typed-array": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/wildcard": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", @@ -19751,11 +19525,6 @@ "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", "dev": true }, - "available-typed-arrays": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.4.tgz", - "integrity": "sha512-SA5mXJWrId1TaQjfxUYghbqQ/hYioKmLJvPJyDuYRtXXenFNMjj4hSSt1Cf1xsuXSXrtxrVC5Ot4eU6cOtBDdA==" - }, "axios": { "version": "0.21.1", "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", @@ -20073,6 +19842,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, "requires": { "function-bind": "^1.1.1", "get-intrinsic": "^1.0.2" @@ -20501,6 +20271,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, "requires": { "object-keys": "^1.0.12" } @@ -20734,45 +20505,12 @@ "is-arrayish": "^0.2.1" } }, - "es-abstract": { - "version": "1.18.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz", - "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==", - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "is-callable": "^1.2.3", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.3", - "is-string": "^1.0.6", - "object-inspect": "^1.10.3", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" - } - }, "es-module-lexer": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.6.0.tgz", "integrity": "sha512-f8kcHX1ArhllUtb/wVSyvygoKCznIjnxhLxy7TCvIiMdT7fL4ZDTIKaadMe6eLvOXg6Wk02UeoFgUoZ2EKZZUA==", "dev": true }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -21559,11 +21297,6 @@ "for-in": "^1.0.1" } }, - "foreach": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" - }, "form-data": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", @@ -21614,7 +21347,8 @@ "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true }, "functional-red-black-tree": { "version": "1.0.1", @@ -21647,6 +21381,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, "requires": { "function-bind": "^1.1.1", "has": "^1.0.3", @@ -21824,15 +21559,11 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, "requires": { "function-bind": "^1.1.1" } }, - "has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==" - }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -21842,7 +21573,8 @@ "has-symbols": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true }, "hash-sum": { "version": "2.0.0", @@ -22061,25 +21793,12 @@ "loose-envify": "^1.0.0" } }, - "is-arguments": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz", - "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==", - "requires": { - "call-bind": "^1.0.0" - } - }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, - "is-bigint": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz", - "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==" - }, "is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -22093,6 +21812,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.0.tgz", "integrity": "sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA==", + "dev": true, "requires": { "call-bind": "^1.0.0" } @@ -22103,11 +21823,6 @@ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, - "is-callable": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", - "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==" - }, "is-ci": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", @@ -22126,11 +21841,6 @@ "has": "^1.0.3" } }, - "is-date-object": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz", - "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==" - }, "is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", @@ -22155,11 +21865,6 @@ "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "dev": true }, - "is-generator-function": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.9.tgz", - "integrity": "sha512-ZJ34p1uvIfptHCN7sFTjGibB9/oBg17sHqzDLfuwhvmN/qLVvIQXRQ8licZQ35WJ8KuEQt/etnnzQFI9C9Ue/A==" - }, "is-glob": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", @@ -22169,11 +21874,6 @@ "is-extglob": "^2.1.1" } }, - "is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==" - }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -22183,7 +21883,8 @@ "is-number-object": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz", - "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==" + "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==", + "dev": true }, "is-obj": { "version": "2.0.0", @@ -22212,15 +21913,6 @@ "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", "dev": true }, - "is-regex": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", - "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", - "requires": { - "call-bind": "^1.0.2", - "has-symbols": "^1.0.2" - } - }, "is-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", @@ -22230,15 +21922,8 @@ "is-string": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", - "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==" - }, - "is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "requires": { - "has-symbols": "^1.0.2" - } + "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==", + "dev": true }, "is-text-path": { "version": "1.0.1", @@ -22249,18 +21934,6 @@ "text-extensions": "^1.0.0" } }, - "is-typed-array": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.5.tgz", - "integrity": "sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug==", - "requires": { - "available-typed-arrays": "^1.0.2", - "call-bind": "^1.0.2", - "es-abstract": "^1.18.0-next.2", - "foreach": "^2.0.5", - "has-symbols": "^1.0.1" - } - }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -25925,20 +25598,17 @@ "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", "dev": true }, - "object-inspect": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", - "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==" - }, "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true }, "object.assign": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, "requires": { "call-bind": "^1.0.0", "define-properties": "^1.1.3", @@ -26364,6 +26034,12 @@ } } }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true + }, "progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", @@ -26785,7 +26461,8 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true }, "safer-buffer": { "version": "2.1.2", @@ -27138,24 +26815,6 @@ "strip-ansi": "^6.0.0" } }, - "string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, "strip-ansi": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", @@ -27295,9 +26954,8 @@ "integrity": "sha1-aUmqv7C6GLsVYq5RpDn9DzAYOhc=" }, "tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "version": "git+ssh://git@github.com/auhau/tar-stream.git#38e8ef2f4b7371c38aadfe8d46228b7a9ace5077", + "from": "tar-stream@auhau/tar-stream#feat/inherits", "requires": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", @@ -27599,17 +27257,6 @@ "dev": true, "optional": true }, - "unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "requires": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" - } - }, "unbzip2-stream": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", @@ -27678,19 +27325,6 @@ "node-gyp-build": "^4.2.0" } }, - "util": { - "version": "0.12.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz", - "integrity": "sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==", - "requires": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "safe-buffer": "^5.1.2", - "which-typed-array": "^1.1.2" - } - }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -27818,6 +27452,30 @@ "graceful-fs": "^4.1.2" } }, + "web-blob": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/web-blob/-/web-blob-2.1.3.tgz", + "integrity": "sha512-7ARypAQxyyqT7ZCHydKavBGCzvvhicGuUMFqg6Xua6H0HIqGgEH1VsMVr1P1Nx+D/maqrUNyOzHkTjBQH/bZOQ==", + "dev": true, + "requires": { + "web-streams-polyfill": "2.1.1" + } + }, + "web-file-polyfill": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/web-file-polyfill/-/web-file-polyfill-1.0.2.tgz", + "integrity": "sha512-GWGSem+0h+DMBcsMTN7TzHUVjSxEUwP67ubgeo47kdU1lCgHbqnFnY0Dc5QIQzFbQqwx28JhnR3lbUUaw6siFQ==", + "dev": true, + "requires": { + "web-blob": "2.1.3" + } + }, + "web-streams-polyfill": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-2.1.1.tgz", + "integrity": "sha512-dlNpL2aab3g8CKfGz6rl8FNmGaRWLLn2g/DtSc9IjB30mEdE6XxzPfPSig5BwGSzI+oLxHyETrQGKjrVVhbLCg==", + "dev": true + }, "webidl-conversions": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", @@ -28095,32 +27753,6 @@ "isexe": "^2.0.0" } }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "which-typed-array": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.4.tgz", - "integrity": "sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA==", - "requires": { - "available-typed-arrays": "^1.0.2", - "call-bind": "^1.0.0", - "es-abstract": "^1.18.0-next.1", - "foreach": "^2.0.5", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.1", - "is-typed-array": "^1.1.3" - } - }, "wildcard": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", diff --git a/package.json b/package.json index 8adefb2d..1e99a7c5 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "js-sha3": "^0.8.0", "readable-web-to-node-stream": "^3.0.2", "tar-js": "^0.3.0", - "tar-stream": "^2.2.0", + "tar-stream": "auhau/tar-stream#feat/inherits", "ws": "^7.5.0" }, "devDependencies": { @@ -85,6 +85,7 @@ "@typescript-eslint/parser": "^4.28.0", "babel-jest": "^27.0.5", "babel-loader": "^8.2.2", + "buffer": "^5.7.1", "bufferutil": "^4.0.3", "constants-browserify": "^1.0.0", "debug": "^4.3.1", @@ -100,6 +101,7 @@ "jest-puppeteer": "^5.0.4", "nock": "^13.1.0", "prettier": "^2.3.1", + "process": "^0.11.10", "puppeteer": "^9.1.1", "readable-stream": "^3.6.0", "rimraf": "^3.0.2", @@ -109,7 +111,7 @@ "typedoc-plugin-markdown": "^3.10.0", "typescript": "^4.3.4", "utf-8-validate": "^5.0.5", - "util": "^0.12.4", + "web-file-polyfill": "^1.0.2", "webpack": "^5.40.0", "webpack-bundle-analyzer": "^4.4.1", "webpack-cli": "^4.7.2" diff --git a/src/utils/tar.ts b/src/utils/tar.ts index d40455d4..9ef7a5ce 100644 --- a/src/utils/tar.ts +++ b/src/utils/tar.ts @@ -92,7 +92,7 @@ export class TarArchive { } } -export async function makeTar(data: Collection): Promise { +export async function makeTar(data: Collection): Promise { const tar = new TarArchive() for (const entry of data) { diff --git a/test/integration/bee-class.browser.spec.ts b/test/integration/bee-class.browser.spec.ts index 2996eafc..95ec0c67 100644 --- a/test/integration/bee-class.browser.spec.ts +++ b/test/integration/bee-class.browser.spec.ts @@ -65,7 +65,11 @@ describe('Bee class - in browser', () => { const fileHash = await page.evaluate( async (BEE_URL, batchId) => { const bee = new window.BeeJs.Bee(BEE_URL) - const files: File[] = [new File(['hello'], 'hello')] + const files: File[] = [ + new File(['hello'], 'hello', { + type: 'text/plain', + }), + ] return await bee.uploadFiles(batchId, files) }, @@ -126,7 +130,7 @@ describe('Bee class - in browser', () => { expect(uploadEvent).toEqual({ loaded: 4, total: 4 }) }) - describe.skip('pss', () => { + describe('pss', () => { it( 'should send and receive pss message', done => { diff --git a/test/integration/bee-class.spec.ts b/test/integration/bee-class.spec.ts index 0e6eb342..f4c1f18c 100644 --- a/test/integration/bee-class.spec.ts +++ b/test/integration/bee-class.spec.ts @@ -27,6 +27,7 @@ import { tryDeleteChunkFromLocalStorage, } from '../utils' import { Readable } from 'stream' +import { File } from 'web-file-polyfill' commonMatchers() @@ -193,6 +194,20 @@ describe('Bee class', () => { expect(file.name).toEqual(directoryStructure[0].path) expect(file.data.text()).toEqual('hello-world') }) + + it('should upload browser files', async () => { + const bee = new Bee('http://localhost:7777') + const files = [ + new File(['hello'], 'hello.txt', { + type: 'text/plain', + }), + ] + + const reference = await bee.uploadFiles(getPostageBatch(), files) + + const file = await bee.downloadFile(reference, 'hello.txt') + expect(file.data.text()).toEqual('hello') + }) }) describe('tags', () => { diff --git a/webpack.config.ts b/webpack.config.ts index d009adfa..89fe6da9 100644 --- a/webpack.config.ts +++ b/webpack.config.ts @@ -1,6 +1,6 @@ /* eslint-disable no-console */ import Path from 'path' -import { DefinePlugin, Configuration, WebpackPluginInstance, NormalModuleReplacementPlugin } from 'webpack' +import { ProvidePlugin, DefinePlugin, Configuration, WebpackPluginInstance, NormalModuleReplacementPlugin } from 'webpack' import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer' import TerserPlugin from 'terser-webpack-plugin' import PackageJson from './package.json' @@ -27,6 +27,10 @@ const base = async (env?: Partial): Promise => 'process.env.ENV': env?.mode || 'development', 'process.env.IS_WEBPACK_BUILD': 'true', }), + new ProvidePlugin({ + Buffer: ['buffer', 'Buffer'], + process: ['process'], + }) ] if (target === 'web') { @@ -77,8 +81,8 @@ const base = async (env?: Partial): Promise => path: false, fs: false, stream: false, - util: require.resolve("util/"), - constants: require.resolve("constants-browserify") + buffer: require.resolve('buffer'), + constants: require.resolve('constants-browserify') }, }, optimization: {