diff --git a/package-lock.json b/package-lock.json index 3b9b47e0..e2b8153a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -75,7 +75,7 @@ "webpack-cli": "^4.7.2" }, "engines": { - "bee": "1.0.2-3c66e35-dirty", + "bee": "1.1.0-80cdea19", "node": ">=12.0.0", "npm": ">=6.0.0" } @@ -7649,6 +7649,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/hash-sum": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-2.0.0.tgz", @@ -8114,10 +8129,13 @@ } }, "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==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -21685,6 +21703,15 @@ "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", "dev": true }, + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, "hash-sum": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-2.0.0.tgz", @@ -22030,10 +22057,13 @@ "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.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } }, "is-text-path": { "version": "1.0.1", diff --git a/package.json b/package.json index a31d8a63..a640a953 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "test": "npm run compile:browser && jest --verbose --selectProjects=node:unit node:integration dom:integration --config=jest.config.ts", "test:integration:browser": "npm run compile:browser && jest --verbose --selectProjects=dom:integration --config=jest.config.ts", "test:integration:node": "jest --verbose --selectProjects=node:integration --config=jest.config.ts", - "test:integration": "npm run compile:browser && jest --verbose --selectProjects=node:integration dom:integration --config=jest.config.ts ", + "test:integration": "npm run compile:browser && jest --verbose --selectProjects=node:integration dom:integration --config=jest.config.ts", "test:unit": "jest --verbose --selectProjects=node:unit --config=jest.config.ts ", "test:node": "jest --verbose --selectProjects=node:unit node:integration --config=jest.config.ts", "test:browser": "npm run test:integration:browser", diff --git a/src/bee.ts b/src/bee.ts index 078bf8f3..931dfe27 100644 --- a/src/bee.ts +++ b/src/bee.ts @@ -36,15 +36,17 @@ import { makeTagUid, } from './utils/type' import { setJsonData, getJsonData } from './feed/json' -import { makeCollectionFromFS, makeCollectionFromFileList } from './utils/collection' +import { makeCollectionFromFS, makeCollectionFromFileList, assertCollection } from './utils/collection' import { AllTagsOptions, + Collection, Ky, NumberString, PostageBatchOptions, Readable, STAMPS_DEPTH_MAX, STAMPS_DEPTH_MIN, + UploadResult, } from './types' import type { Options as KyOptions } from 'ky-universal' @@ -155,7 +157,7 @@ export class Bee { postageBatchId: string | BatchId, data: string | Uint8Array, options?: UploadOptions, - ): Promise { + ): Promise { assertBatchId(postageBatchId) assertData(data) @@ -211,7 +213,7 @@ export class Bee { data: string | Uint8Array | Readable | File, name?: string, options?: FileUploadOptions, - ): Promise { + ): Promise { assertBatchId(postageBatchId) assertFileData(data) @@ -230,10 +232,10 @@ export class Bee { return bzz.uploadFile(this.ky, fileData, 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.ky, data, postageBatchId, name, options) - await this.updateTag(options.tag, reference) + const result = await bzz.uploadFile(this.ky, data, postageBatchId, name, options) + await this.updateTag(options.tag, result.reference) - return reference + return result } else { return bzz.uploadFile(this.ky, data, postageBatchId, name, options) } @@ -275,6 +277,9 @@ export class Bee { * * Uses the FileList API from the browser. * + * The returned `UploadResult.tag` might be undefined if called in CORS-enabled environment. + * This will be fixed upon next Bee release. https://github.com/ethersphere/bee-js/issues/406 + * * @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 @@ -287,7 +292,7 @@ export class Bee { postageBatchId: string | BatchId, fileList: FileList | File[], options?: CollectionUploadOptions, - ): Promise { + ): Promise { assertBatchId(postageBatchId) if (options) assertCollectionUploadOptions(options) @@ -297,11 +302,37 @@ export class Bee { return bzz.uploadCollection(this.ky, data, postageBatchId, options) } + /** + * Upload Collection that you can assembly yourself. + * + * The returned `UploadResult.tag` might be undefined if called in CORS-enabled environment. + * This will be fixed upon next Bee release. https://github.com/ethersphere/bee-js/issues/406 + * + * @param postageBatchId + * @param collection + * @param options + */ + async uploadCollection( + postageBatchId: string | BatchId, + collection: Collection, + options?: CollectionUploadOptions, + ): Promise { + assertBatchId(postageBatchId) + assertCollection(collection) + + if (options) assertCollectionUploadOptions(options) + + return bzz.uploadCollection(this.ky, collection, postageBatchId, options) + } + /** * Upload collection of files. * * Available only in Node.js as it uses the `fs` module. * + * The returned `UploadResult.tag` might be undefined if called in CORS-enabled environment. + * This will be fixed upon next Bee release. https://github.com/ethersphere/bee-js/issues/406 + * * @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 @@ -314,7 +345,7 @@ export class Bee { postageBatchId: string | BatchId, dir: string, options?: CollectionUploadOptions, - ): Promise { + ): Promise { assertBatchId(postageBatchId) if (options) assertCollectionUploadOptions(options) diff --git a/src/feed/json.ts b/src/feed/json.ts index 1a2f2288..b1e0c2fc 100644 --- a/src/feed/json.ts +++ b/src/feed/json.ts @@ -26,7 +26,7 @@ export async function setJsonData( data: AnyJson, ): Promise { const serializedData = serializeJson(data) - const reference = await bee.uploadData(postageBatchId, serializedData) + const { reference } = await bee.uploadData(postageBatchId, serializedData) return writer.upload(postageBatchId, reference) } diff --git a/src/modules/bytes.ts b/src/modules/bytes.ts index d8df2110..53397880 100644 --- a/src/modules/bytes.ts +++ b/src/modules/bytes.ts @@ -3,6 +3,8 @@ import { prepareData } from '../utils/data' import { extractUploadHeaders } from '../utils/headers' import { http } from '../utils/http' import { wrapBytesWithHelpers } from '../utils/bytes' +import { UploadResult } from '../types' +import { makeTagUid } from '../utils/type' const endpoint = 'bytes' @@ -19,7 +21,7 @@ export async function upload( data: string | Uint8Array, postageBatchId: BatchId, options?: UploadOptions, -): Promise { +): Promise { const response = await http<{ reference: Reference }>(ky, { path: endpoint, method: 'post', @@ -31,7 +33,10 @@ export async function upload( }, }) - return response.data.reference + return { + reference: response.data.reference, + tagUid: makeTagUid(response.headers.get('swarm-tag')), + } } /** diff --git a/src/modules/bzz.ts b/src/modules/bzz.ts index 1e9f0de4..1f8009da 100644 --- a/src/modules/bzz.ts +++ b/src/modules/bzz.ts @@ -9,6 +9,7 @@ import { Readable, Reference, UploadHeaders, + UploadResult, } from '../types' import { extractUploadHeaders, readFileHeaders } from '../utils/headers' import { http } from '../utils/http' @@ -17,6 +18,7 @@ import { makeTar } from '../utils/tar' import { assertCollection } from '../utils/collection' import { wrapBytesWithHelpers } from '../utils/bytes' import { isReadable } from '../utils/stream' +import { makeTagUid } from '../utils/type' const bzzEndpoint = 'bzz' @@ -50,7 +52,7 @@ export async function uploadFile( postageBatchId: BatchId, name?: string, options?: FileUploadOptions, -): Promise { +): Promise { if (isReadable(data) && !options?.contentType) { if (!options) options = {} @@ -68,7 +70,10 @@ export async function uploadFile( responseType: 'json', }) - return response.data.reference + return { + reference: response.data.reference, + tagUid: makeTagUid(response.headers.get('swarm-tag')), + } } /** @@ -151,7 +156,7 @@ export async function uploadCollection( collection: Collection, postageBatchId: BatchId, options?: CollectionUploadOptions, -): Promise { +): Promise { assertCollection(collection) const tarData = makeTar(collection) @@ -167,5 +172,8 @@ export async function uploadCollection( }, }) - return response.data.reference + return { + reference: response.data.reference, + tagUid: response.headers.get('swarm-tag') ? makeTagUid(response.headers.get('swarm-tag')) : undefined, + } } diff --git a/src/types/index.ts b/src/types/index.ts index 76ec15a1..845e729c 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -94,6 +94,26 @@ export interface BeeOptions { onResponse?: HookCallback } +/** + * Result of upload calls. + */ +export interface UploadResult { + /** + * Reference of the uploaded data + */ + reference: Reference + + /** + * Automatically created tag's UID. + * + * There is bug in Bee, that does not return correct CORS header (Access-Control-Expose-Headers) for the `Swarm-Tag` to be exposed + * in browser when uploading collection. The `tagUid` is marked as optional even though in 99% of results + * it is present. The Optional mark will be removed with next Bee release. + * TODO: Remove Optional with next Bee release: https://github.com/ethersphere/bee-js/issues/406 + */ + tagUid?: number +} + export interface UploadOptions { /** * Will pin the data locally in the Bee node as well. diff --git a/src/utils/type.ts b/src/utils/type.ts index e1ac6bd6..7ad41e66 100644 --- a/src/utils/type.ts +++ b/src/utils/type.ts @@ -275,13 +275,29 @@ export function assertAllTagsOptions(entry: unknown): asserts entry is AllTagsOp * Utility functions that return Tag UID * @param tagUid */ -export function makeTagUid(tagUid: number | Tag): number { +export function makeTagUid(tagUid: number | Tag | string | null | undefined): number { + if (tagUid === undefined || tagUid === null) { + throw new TypeError('TagUid was expected but got undefined or null instead!') + } + if (isTag(tagUid)) { return tagUid.uid } else if (typeof tagUid === 'number') { assertNonNegativeInteger(tagUid, 'UID') return tagUid + } else if (typeof tagUid === 'string') { + const int = parseInt(tagUid) + + if (isNaN(int)) { + throw new TypeError('Passed tagUid string is not valid integer!') + } + + if (int < 0) { + throw new TypeError(`TagUid was expected to be positive non-negative integer! Got ${int}`) + } + + return int } throw new TypeError('tagUid has to be either Tag or a number (UID)!') diff --git a/test/integration/bee-class.browser.spec.ts b/test/integration/bee-class.browser.spec.ts index 16aa9314..a111b953 100644 --- a/test/integration/bee-class.browser.spec.ts +++ b/test/integration/bee-class.browser.spec.ts @@ -76,7 +76,7 @@ describe('Bee class - in browser', () => { const bee = new window.BeeJs.Bee(BEE_URL) const files: File[] = [new File(['hello'], 'hello')] - return await bee.uploadFiles(batchId, files) + return (await bee.uploadFiles(batchId, files)).reference }, BEE_URL, batchId, @@ -139,7 +139,7 @@ describe('Bee class - in browser', () => { contentType: 'text/plain', }) - return reference + return reference.reference }, BEE_URL, batchId, @@ -152,7 +152,7 @@ describe('Bee class - in browser', () => { }) it('should download file with stream', async () => { - const reference = await bzz.uploadFile(beeKy(), 'hello awesome world', batchId) + const result = await bzz.uploadFile(beeKy(), 'hello awesome world', batchId) const content = (await page.evaluate( async (BEE_URL, reference) => { @@ -177,7 +177,7 @@ describe('Bee class - in browser', () => { return new TextDecoder().decode(await blob.arrayBuffer()) }, BEE_URL, - reference, + result.reference, )) as string expect(content).toEqual('hello awesome world') diff --git a/test/integration/bee-class.spec.ts b/test/integration/bee-class.spec.ts index 63a6a391..558b494d 100644 --- a/test/integration/bee-class.spec.ts +++ b/test/integration/bee-class.spec.ts @@ -52,8 +52,8 @@ describe('Bee class', () => { const name = 'hello.txt' const contentType = 'text/html' - const hash = await bee.uploadFile(getPostageBatch(), content, name, { contentType }) - const file = await bee.downloadFile(hash) + const result = await bee.uploadFile(getPostageBatch(), content, name, { contentType }) + const file = await bee.downloadFile(result.reference) expect(file.name).toEqual(name) expect(file.data).toEqual(content) @@ -67,8 +67,8 @@ describe('Bee class', () => { const name = 'hello.txt' const contentType = 'text/html' - const hash = await bee.uploadFile(getPostageBatch(), content, name, { contentType, tag: tag.uid }) - const file = await bee.downloadFile(hash) + const result = await bee.uploadFile(getPostageBatch(), content, name, { contentType, tag: tag.uid }) + const file = await bee.downloadFile(result.reference) expect(file.name).toEqual(name) expect(file.data).toEqual(content) @@ -87,8 +87,8 @@ describe('Bee class', () => { type, } as unknown as File - const hash = await bee.uploadFile(getPostageBatch(), file) - const downloadedFile = await bee.downloadFile(hash) + const result = await bee.uploadFile(getPostageBatch(), file) + const downloadedFile = await bee.downloadFile(result.reference) expect(downloadedFile.data).toEqual(content) expect(downloadedFile.name).toEqual(name) @@ -104,8 +104,8 @@ describe('Bee class', () => { } as unknown as File const nameOverride = 'hello-override.txt' - const hash = await bee.uploadFile(getPostageBatch(), file, nameOverride) - const downloadedFile = await bee.downloadFile(hash) + const result = await bee.uploadFile(getPostageBatch(), file, nameOverride) + const downloadedFile = await bee.downloadFile(result.reference) expect(downloadedFile.data).toEqual(content) expect(downloadedFile.name).toEqual(nameOverride) @@ -120,8 +120,8 @@ describe('Bee class', () => { } as unknown as File const contentTypeOverride = 'text/plain+override' - const hash = await bee.uploadFile(getPostageBatch(), file, undefined, { contentType: contentTypeOverride }) - const downloadedFile = await bee.downloadFile(hash) + const result = await bee.uploadFile(getPostageBatch(), file, undefined, { contentType: contentTypeOverride }) + const downloadedFile = await bee.downloadFile(result.reference) expect(downloadedFile.data).toEqual(content) expect(downloadedFile.contentType).toEqual(contentTypeOverride) @@ -132,8 +132,8 @@ describe('Bee class', () => { const name = 'hello.txt' const contentType = 'text/plain' - const hash = await bee.uploadFile(getPostageBatch(), readable, name, { contentType }) - const file = await bee.downloadFile(hash) + const result = await bee.uploadFile(getPostageBatch(), readable, name, { contentType }) + const file = await bee.downloadFile(result.reference) expect(file.name).toEqual(name) expect(file.data.text()).toEqual('hello world') @@ -144,8 +144,8 @@ describe('Bee class', () => { const name = 'hello.txt' const contentType = 'text/plain' - const hash = await bee.uploadFile(getPostageBatch(), readable, name, { contentType }) - const file = await bee.downloadFile(hash) + const result = await bee.uploadFile(getPostageBatch(), readable, name, { contentType }) + const file = await bee.downloadFile(result.reference) expect(file.name).toEqual(name) expect(file.data.text()).toEqual('hello world') @@ -158,12 +158,12 @@ describe('Bee class', () => { const name = 'hello.txt' const contentType = 'text/plain' - const hash = await bee.uploadFile(getPostageBatch(), readable, name, { + const result = await bee.uploadFile(getPostageBatch(), readable, name, { contentType, tag: tag.uid, }) - const file = await bee.downloadFile(hash) + const file = await bee.downloadFile(result.reference) expect(file.name).toEqual(name) expect(file.data.length).toEqual(13000) @@ -175,9 +175,24 @@ describe('Bee class', () => { describe('collections', () => { it('should work with directory with unicode filenames', async () => { - const hash = await bee.uploadFilesFromDirectory(getPostageBatch(), './test/data') + const result = await bee.uploadFilesFromDirectory(getPostageBatch(), './test/data') - expect(hash.length).toEqual(REFERENCE_HEX_LENGTH) + expect(result.reference.length).toEqual(REFERENCE_HEX_LENGTH) + }) + + it('should upload collection', async () => { + const directoryStructure: Collection = [ + { + path: '0', + data: new TextEncoder().encode('hello-world'), + }, + ] + + const result = await bee.uploadCollection(getPostageBatch(), directoryStructure) + const file = await bee.downloadFile(result.reference, directoryStructure[0].path) + + expect(file.name).toEqual(directoryStructure[0].path) + expect(file.data.text()).toEqual('hello-world') }) }) @@ -215,54 +230,54 @@ describe('Bee class', () => { describe('pinning', () => { it('should list all pins', async () => { const content = new Uint8Array([1, 2, 3]) - const hash = await bee.uploadFile(getPostageBatch(), content) + const result = await bee.uploadFile(getPostageBatch(), content) - await bee.pin(hash) // Nothing is asserted as nothing is returned, will throw error if something is wrong + await bee.pin(result.reference) // Nothing is asserted as nothing is returned, will throw error if something is wrong const pinnedChunks = await bee.getAllPins() expect(pinnedChunks).toBeType('array') - expect(pinnedChunks.includes(hash)).toBeTruthy() + expect(pinnedChunks.includes(result.reference)).toBeTruthy() }) it('should get pinning status', async () => { const content = randomByteArray(16, Date.now()) - const hash = await bee.uploadFile(getPostageBatch(), content, 'test', { + const result = await bee.uploadFile(getPostageBatch(), content, 'test', { pin: false, }) - const statusBeforePinning = bee.getPin(hash) + const statusBeforePinning = bee.getPin(result.reference) await expect(statusBeforePinning).rejects.toThrowError('Not Found') - await bee.pin(hash) // Nothing is asserted as nothing is returned, will throw error if something is wrong + await bee.pin(result.reference) // Nothing is asserted as nothing is returned, will throw error if something is wrong - const statusAfterPinning = await bee.getPin(hash) - expect(statusAfterPinning).toHaveProperty('reference', hash) + const statusAfterPinning = await bee.getPin(result.reference) + expect(statusAfterPinning).toHaveProperty('reference', result.reference) }) it('should pin and unpin files', async () => { const content = new Uint8Array([1, 2, 3]) - const hash = await bee.uploadFile(getPostageBatch(), content) + const result = await bee.uploadFile(getPostageBatch(), content) - await bee.pin(hash) // Nothing is asserted as nothing is returned, will throw error if something is wrong - await bee.unpin(hash) // Nothing is asserted as nothing is returned, will throw error if something is wrong + await bee.pin(result.reference) // Nothing is asserted as nothing is returned, will throw error if something is wrong + await bee.unpin(result.reference) // Nothing is asserted as nothing is returned, will throw error if something is wrong }) - it('should pin and unpin collection', async () => { + it('should pin and unpin collection from directory', async () => { const path = './test/data/' - const hash = await bee.uploadFilesFromDirectory(getPostageBatch(), path) + const result = await bee.uploadFilesFromDirectory(getPostageBatch(), path) - await bee.pin(hash) // Nothing is asserted as nothing is returned, will throw error if something is wrong - await bee.unpin(hash) // Nothing is asserted as nothing is returned, will throw error if something is wrong + await bee.pin(result.reference) // Nothing is asserted as nothing is returned, will throw error if something is wrong + await bee.unpin(result.reference) // Nothing is asserted as nothing is returned, will throw error if something is wrong }) it('should pin and unpin data', async () => { const content = new Uint8Array([1, 2, 3]) - const hash = await bee.uploadData(getPostageBatch(), content) + const result = await bee.uploadData(getPostageBatch(), content) - await bee.pin(hash) // Nothing is asserted as nothing is returned, will throw error if something is wrong - await bee.unpin(hash) // Nothing is asserted as nothing is returned, will throw error if something is wrong + await bee.pin(result.reference) // Nothing is asserted as nothing is returned, will throw error if something is wrong + await bee.unpin(result.reference) // Nothing is asserted as nothing is returned, will throw error if something is wrong }) }) @@ -270,17 +285,17 @@ describe('Bee class', () => { it('should reupload pinned data', async () => { const content = randomByteArray(16, Date.now()) - const hash = await bee.uploadData(getPostageBatch(), content, { pin: true }) + const result = await bee.uploadData(getPostageBatch(), content, { pin: true }) await sleep(10) - await bee.reuploadPinnedData(hash) // Does not return anything, but will throw exception if something is going wrong + await bee.reuploadPinnedData(result.reference) // Does not return anything, but will throw exception if something is going wrong }) it('should throw error if data is not pinned', async () => { const content = randomByteArray(16, Date.now()) - const hash = await bee.uploadData(getPostageBatch(), content) - await expect(bee.reuploadPinnedData(hash)).rejects.toThrowError(BeeArgumentError) + const result = await bee.uploadData(getPostageBatch(), content) + await expect(bee.reuploadPinnedData(result.reference)).rejects.toThrowError(BeeArgumentError) }) }) @@ -407,10 +422,10 @@ describe('Bee class', () => { data: new TextEncoder().encode('some data'), }, ] - const cacHash = await bzz.uploadCollection(BEE_KY, directoryStructure, getPostageBatch()) + const cacResult = await bzz.uploadCollection(BEE_KY, directoryStructure, getPostageBatch()) const feed = bee.makeFeedWriter('sequence', topic, signer) - await feed.upload(getPostageBatch(), cacHash) + await feed.upload(getPostageBatch(), cacResult.reference) const manifestReference = await bee.createFeedManifest(getPostageBatch(), 'sequence', topic, owner) expect(typeof manifestReference).toBe('string') @@ -532,8 +547,8 @@ describe('Bee class', () => { const hashedTopic = bee.makeFeedTopic(TOPIC) const writer = bee.makeFeedWriter('sequence', hashedTopic, testIdentity.privateKey) - const dataChunkReference = await bee.uploadData(getPostageBatch(), JSON.stringify(data)) - await writer.upload(getPostageBatch(), dataChunkReference) + const dataChunkResult = await bee.uploadData(getPostageBatch(), JSON.stringify(data)) + await writer.upload(getPostageBatch(), dataChunkResult.reference) const fetchedData = await bee.getJsonFeed(TOPIC, { signer: testIdentity.privateKey }) expect(fetchedData).toEqual(data) @@ -547,8 +562,8 @@ describe('Bee class', () => { const hashedTopic = bee.makeFeedTopic(TOPIC) const writer = bee.makeFeedWriter('sequence', hashedTopic, testIdentity.privateKey) - const dataChunkReference = await bee.uploadData(getPostageBatch(), JSON.stringify(data)) - await writer.upload(getPostageBatch(), dataChunkReference) + const dataChunkResult = await bee.uploadData(getPostageBatch(), JSON.stringify(data)) + await writer.upload(getPostageBatch(), dataChunkResult.reference) const fetchedData = await bee.getJsonFeed(TOPIC, { address: testIdentity.address }) expect(fetchedData).toEqual(data) diff --git a/test/integration/modules/bytes.spec.ts b/test/integration/modules/bytes.spec.ts index 0d79d498..8e02b9ec 100644 --- a/test/integration/modules/bytes.spec.ts +++ b/test/integration/modules/bytes.spec.ts @@ -7,8 +7,8 @@ describe('modules/bytes', () => { it('should store and retrieve data', async () => { const data = 'hello world' - const hash = await bytes.upload(BEE_KY, data, getPostageBatch()) - const downloadedData = await bytes.download(BEE_KY, hash) + const result = await bytes.upload(BEE_KY, data, getPostageBatch()) + const downloadedData = await bytes.download(BEE_KY, result.reference) expect(Buffer.from(downloadedData).toString()).toEqual(data) }) diff --git a/test/integration/modules/bzz.spec.ts b/test/integration/modules/bzz.spec.ts index 7cf7c420..cc481282 100644 --- a/test/integration/modules/bzz.spec.ts +++ b/test/integration/modules/bzz.spec.ts @@ -17,8 +17,8 @@ describe('modules/bzz', () => { }, ] - const hash = await bzz.uploadCollection(BEE_KY, directoryStructure, getPostageBatch()) - const file = await bzz.downloadFile(BEE_KY, hash, directoryStructure[0].path) + const result = await bzz.uploadCollection(BEE_KY, directoryStructure, getPostageBatch()) + const file = await bzz.downloadFile(BEE_KY, result.reference, directoryStructure[0].path) expect(file.name).toEqual(directoryStructure[0].path) expect(file.data).toEqual(directoryStructure[0].data) @@ -34,8 +34,8 @@ describe('modules/bzz', () => { }, ] - const hash = await bzz.uploadCollection(BEE_KY, directoryStructure, getPostageBatch()) - const file = await bzz.downloadFile(BEE_KY, hash, directoryStructure[0].path) + const result = await bzz.uploadCollection(BEE_KY, directoryStructure, getPostageBatch()) + const file = await bzz.downloadFile(BEE_KY, result.reference, directoryStructure[0].path) expect(file.name).toEqual(name) expect(file.data).toEqual(directoryStructure[0].data) @@ -49,8 +49,8 @@ describe('modules/bzz', () => { }, ] - const hash = await bzz.uploadCollection(BEE_KY, directoryStructure, getPostageBatch(), { pin: true }) - const file = await bzz.downloadFile(BEE_KY, hash, directoryStructure[0].path) + const result = await bzz.uploadCollection(BEE_KY, directoryStructure, getPostageBatch(), { pin: true }) + const file = await bzz.downloadFile(BEE_KY, result.reference, directoryStructure[0].path) expect(file.name).toEqual(directoryStructure[0].path) expect(file.data).toEqual(directoryStructure[0].data) @@ -64,12 +64,12 @@ describe('modules/bzz', () => { }, ] - const hash = await bzz.uploadCollection(BEE_KY, directoryStructure, getPostageBatch(), { encrypt: true }) - const file = await bzz.downloadFile(BEE_KY, hash, directoryStructure[0].path) + const result = await bzz.uploadCollection(BEE_KY, directoryStructure, getPostageBatch(), { encrypt: true }) + const file = await bzz.downloadFile(BEE_KY, result.reference, directoryStructure[0].path) expect(file.name).toEqual(directoryStructure[0].path) expect(file.data).toEqual(directoryStructure[0].data) - expect(hash.length).toEqual(ENCRYPTED_REFERENCE_HEX_LENGTH) + expect(result.reference.length).toEqual(ENCRYPTED_REFERENCE_HEX_LENGTH) }) it( @@ -84,7 +84,12 @@ describe('modules/bzz', () => { const response = await bzz.uploadCollection(BEE_KY, directoryStructure, getPostageBatch()) - expect(typeof response).toEqual('string') + expect(response).toEqual( + expect.objectContaining({ + reference: expect.any(String), + tagUid: expect.any(Number), + }), + ) }, BIG_FILE_TIMEOUT, ) @@ -101,13 +106,13 @@ describe('modules/bzz', () => { }, ] - const hash = await bzz.uploadCollection(BEE_KY, directoryStructure, getPostageBatch()) + const result = await bzz.uploadCollection(BEE_KY, directoryStructure, getPostageBatch()) - const file0 = await bzz.downloadFile(BEE_KY, hash, directoryStructure[0].path) + const file0 = await bzz.downloadFile(BEE_KY, result.reference, directoryStructure[0].path) expect(file0.name).toEqual(directoryStructure[0].path) expect(file0.data).toEqual(directoryStructure[0].data) - const file1 = await bzz.downloadFile(BEE_KY, hash, directoryStructure[1].path) + const file1 = await bzz.downloadFile(BEE_KY, result.reference, directoryStructure[1].path) expect(file1.name).toEqual(directoryStructure[1].path) expect(file1.data).toEqual(directoryStructure[1].data) }) @@ -124,11 +129,11 @@ describe('modules/bzz', () => { }, ] - const hash = await bzz.uploadCollection(BEE_KY, directoryStructure, getPostageBatch(), { + const result = await bzz.uploadCollection(BEE_KY, directoryStructure, getPostageBatch(), { indexDocument: '0', }) - const indexFile = await bzz.downloadFile(BEE_KY, hash) + const indexFile = await bzz.downloadFile(BEE_KY, result.reference) expect(indexFile.name).toEqual(directoryStructure[0].path) expect(indexFile.data).toEqual(directoryStructure[0].data) }) @@ -145,11 +150,11 @@ describe('modules/bzz', () => { }, ] - const hash = await bzz.uploadCollection(BEE_KY, directoryStructure, getPostageBatch(), { + const result = await bzz.uploadCollection(BEE_KY, directoryStructure, getPostageBatch(), { errorDocument: '0', }) - const errorFile = await bzz.downloadFile(BEE_KY, hash, 'error') + const errorFile = await bzz.downloadFile(BEE_KY, result.reference, 'error') expect(errorFile.name).toEqual(directoryStructure[0].path) expect(errorFile.data).toEqual(directoryStructure[0].data) }) @@ -161,9 +166,9 @@ describe('modules/bzz', () => { const subDir = 'sub/' const data = Uint8Array.from([51, 10]) const directoryStructure = await makeCollectionFromFS(dir) - const hash = await bzz.uploadCollection(BEE_KY, directoryStructure, getPostageBatch()) + const result = await bzz.uploadCollection(BEE_KY, directoryStructure, getPostageBatch()) - const file3 = await bzz.downloadFile(BEE_KY, hash, `${subDir}${file3Name}`) + const file3 = await bzz.downloadFile(BEE_KY, result.reference, `${subDir}${file3Name}`) expect(file3.name).toEqual(file3Name) expect(file3.data).toEqual(data) }) @@ -174,11 +179,11 @@ describe('modules/bzz', () => { const fileName = '1.txt' const data = Uint8Array.from([49, 10]) const directoryStructure = await makeCollectionFromFS(dir) - const hash = await bzz.uploadCollection(BEE_KY, directoryStructure, getPostageBatch(), { + const result = await bzz.uploadCollection(BEE_KY, directoryStructure, getPostageBatch(), { indexDocument: `${fileName}`, }) - const file1 = await bzz.downloadFile(BEE_KY, hash) + const file1 = await bzz.downloadFile(BEE_KY, result.reference) expect(file1.name).toEqual(fileName) expect(file1.data).toEqual(data) }) @@ -189,8 +194,8 @@ describe('modules/bzz', () => { const data = 'hello world' const filename = 'hello.txt' - const hash = await bzz.uploadFile(BEE_KY, data, getPostageBatch(), filename) - const fileData = await bzz.downloadFile(BEE_KY, hash) + const result = await bzz.uploadFile(BEE_KY, data, getPostageBatch(), filename) + const fileData = await bzz.downloadFile(BEE_KY, result.reference) expect(Buffer.from(fileData.data).toString()).toEqual(data) expect(fileData.name).toEqual(filename) @@ -199,8 +204,8 @@ describe('modules/bzz', () => { it('should store file without filename', async () => { const data = 'hello world' - const hash = await bzz.uploadFile(BEE_KY, data, getPostageBatch()) - const fileData = await bzz.downloadFile(BEE_KY, hash) + const result = await bzz.uploadFile(BEE_KY, data, getPostageBatch()) + const fileData = await bzz.downloadFile(BEE_KY, result.reference) expect(Buffer.from(fileData.data).toString()).toEqual(data) }) @@ -209,10 +214,10 @@ describe('modules/bzz', () => { const data = randomByteArray(5000, 1) const filename = 'hello.txt' - const hash = await bzz.uploadFile(BEE_KY, Readable.from([data]), getPostageBatch(), filename, { + const result = await bzz.uploadFile(BEE_KY, Readable.from([data]), getPostageBatch(), filename, { size: data.length, }) - const fileData = await bzz.downloadFile(BEE_KY, hash) + const fileData = await bzz.downloadFile(BEE_KY, result.reference) expect(fileData.data).toEqual(data) }) @@ -247,7 +252,12 @@ describe('modules/bzz', () => { const data = new Uint8Array(32 * 1024 * 1024) const response = await bzz.uploadFile(BEE_KY, data, getPostageBatch()) - expect(typeof response).toEqual('string') + expect(response).toEqual( + expect.objectContaining({ + reference: expect.any(String), + tagUid: expect.any(Number), + }), + ) }, BIG_FILE_TIMEOUT, ) diff --git a/test/integration/modules/pinning.spec.ts b/test/integration/modules/pinning.spec.ts index 02ca5d2a..6f9e55f4 100644 --- a/test/integration/modules/pinning.spec.ts +++ b/test/integration/modules/pinning.spec.ts @@ -22,13 +22,13 @@ describe('modules/pin', () => { const randomData = randomByteArray(5000) it('should pin an existing file', async () => { - const hash = await bzz.uploadFile(BEE_KY, randomData, getPostageBatch()) - await pinning.pin(BEE_KY, hash) + const result = await bzz.uploadFile(BEE_KY, randomData, getPostageBatch()) + await pinning.pin(BEE_KY, result.reference) }) it('should unpin an existing file', async () => { - const hash = await bzz.uploadFile(BEE_KY, randomData, getPostageBatch()) - await pinning.unpin(BEE_KY, hash) + const result = await bzz.uploadFile(BEE_KY, randomData, getPostageBatch()) + await pinning.unpin(BEE_KY, result.reference) }) it( @@ -57,13 +57,13 @@ describe('modules/pin', () => { ] it('should pin an existing collection', async () => { - const hash = await bzz.uploadCollection(BEE_KY, testCollection, getPostageBatch()) - await pinning.pin(BEE_KY, hash) // Nothing is asserted as nothing is returned, will throw error if something is wrong + const result = await bzz.uploadCollection(BEE_KY, testCollection, getPostageBatch()) + await pinning.pin(BEE_KY, result.reference) // Nothing is asserted as nothing is returned, will throw error if something is wrong }) it('should unpin an existing collections', async () => { - const hash = await bzz.uploadCollection(BEE_KY, testCollection, getPostageBatch()) - await pinning.unpin(BEE_KY, hash) // Nothing is asserted as nothing is returned, will throw error if something is wrong + const result = await bzz.uploadCollection(BEE_KY, testCollection, getPostageBatch()) + await pinning.unpin(BEE_KY, result.reference) // Nothing is asserted as nothing is returned, will throw error if something is wrong }) it( @@ -83,13 +83,13 @@ describe('modules/pin', () => { const randomData = randomByteArray(5000) it('should pin existing data', async () => { - const hash = await bytes.upload(BEE_KY, randomData, getPostageBatch()) - await pinning.pin(BEE_KY, hash) // Nothing is asserted as nothing is returned, will throw error if something is wrong + const result = await bytes.upload(BEE_KY, randomData, getPostageBatch()) + await pinning.pin(BEE_KY, result.reference) // Nothing is asserted as nothing is returned, will throw error if something is wrong }) it('should unpin existing data', async () => { - const hash = await bytes.upload(BEE_KY, randomData, getPostageBatch()) - await pinning.pin(BEE_KY, hash) // Nothing is asserted as nothing is returned, will throw error if something is wrong + const result = await bytes.upload(BEE_KY, randomData, getPostageBatch()) + await pinning.pin(BEE_KY, result.reference) // Nothing is asserted as nothing is returned, will throw error if something is wrong }) it( diff --git a/test/integration/modules/stewardship.spec.ts b/test/integration/modules/stewardship.spec.ts index 6092dc6e..f1acf24e 100644 --- a/test/integration/modules/stewardship.spec.ts +++ b/test/integration/modules/stewardship.spec.ts @@ -15,8 +15,8 @@ describe('modules/stewardship', () => { }, ] - const hash = await bzz.uploadCollection(BEE_KY, directoryStructure, getPostageBatch(), { pin: true }) - await stewardship.reupload(BEE_KY, hash) // Does not return anything, but will throw error if something is wrong + const result = await bzz.uploadCollection(BEE_KY, directoryStructure, getPostageBatch(), { pin: true }) + await stewardship.reupload(BEE_KY, result.reference) // Does not return anything, but will throw error if something is wrong }) }) @@ -25,8 +25,8 @@ describe('modules/stewardship', () => { const data = 'hello world' const filename = 'hello.txt' - const hash = await bzz.uploadFile(BEE_KY, data, getPostageBatch(), filename, { pin: true }) - await stewardship.reupload(BEE_KY, hash) // Does not return anything, but will throw error if something is wrong + const result = await bzz.uploadFile(BEE_KY, data, getPostageBatch(), filename, { pin: true }) + await stewardship.reupload(BEE_KY, result.reference) // Does not return anything, but will throw error if something is wrong }) }) }) diff --git a/test/unit/bee-class.spec.ts b/test/unit/bee-class.spec.ts index 735de78c..c4325871 100644 --- a/test/unit/bee-class.spec.ts +++ b/test/unit/bee-class.spec.ts @@ -76,7 +76,10 @@ describe('Bee class', () => { const bee = new Bee(MOCK_SERVER_URL, { defaultHeaders }) const reference = await bee.uploadFile(testBatchId, 'hello world', 'nice.txt') - expect(reference).toEqual(testJsonHash) + expect(reference).toEqual({ + reference: testJsonHash, + tagUid: 123, + }) }) describe('uploadData', () => { @@ -755,7 +758,10 @@ describe('Bee class', () => { const reference = await bee.uploadFile(testBatchId, 'hello world', 'nice.txt', { encrypt: true }) - expect(reference).toEqual(testJsonHash) + expect(reference).toEqual({ + reference: testJsonHash, + tagUid: 123, + }) expect(requestSpy.mock.calls.length).toEqual(1) expect(requestSpy.mock.calls[0].length).toEqual(1) diff --git a/test/unit/feed/json.spec.ts b/test/unit/feed/json.spec.ts index 6194cf91..7721129c 100644 --- a/test/unit/feed/json.spec.ts +++ b/test/unit/feed/json.spec.ts @@ -20,7 +20,7 @@ describe('JsonFeed', () => { function testSet(data: unknown, expectedBytes: Uint8Array): void { it(`should set feed for data: ${data}`, async () => { const bee = Substitute.for() - bee.uploadData(Arg.all()).resolves(DATA_REFERENCE) + bee.uploadData(Arg.all()).resolves({ reference: DATA_REFERENCE, tagUid: 0 }) const writer = Substitute.for() writer.upload(Arg.all()).resolves(FEED_REFERENCE_HASH) diff --git a/test/unit/nock.ts b/test/unit/nock.ts index 0bc0a945..81a0b998 100644 --- a/test/unit/nock.ts +++ b/test/unit/nock.ts @@ -63,6 +63,9 @@ export function uploadFileMock( }, {}) return nock(MOCK_SERVER_URL, { reqheaders: { 'swarm-postage-batch-id': batchId, ...headers, ...extraHeaders } }) + .defaultReplyHeaders({ + 'swarm-tag': '123', + }) .post(`${BZZ_ENDPOINT}`) .query({ name }) }