From c1c729843e88d3f9d6e287254732571c9c20f3a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Jim=C3=A9nez=20Rivera?= Date: Thu, 5 Mar 2026 13:04:10 +0100 Subject: [PATCH 1/5] Add abort signal to upload --- package.json | 2 +- src/index.ts | 70 ++++++++------------------------ src/lib/core/upload/index.ts | 3 +- src/lib/core/upload/multipart.ts | 2 +- src/lib/core/upload/strategy.ts | 4 +- src/lib/core/upload/uploadV2.ts | 34 ++++------------ 6 files changed, 30 insertions(+), 85 deletions(-) diff --git a/package.json b/package.json index fb6e603..7c6cd13 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@internxt/inxt-js", "author": "Internxt ", - "version": "2.3.1", + "version": "2.3.2", "description": "", "main": "build/index.js", "types": "build/index.d.ts", diff --git a/src/index.ts b/src/index.ts index eb43e77..8d0f7f4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -150,25 +150,17 @@ export class Environment { this.config.encryptionKey = newEncryptionKey; } - uploadMultipartFile(bucketId: string, opts: UploadOptions): ActionState { - const uploadState = new ActionState(ActionTypes.Upload); - + uploadMultipartFile: UploadStrategyFunction = async (bucketId: string, opts: UploadOptions) => { if (!this.config.encryptionKey) { - opts.finishedCallback(Error('Mnemonic was not provided, please, provide a mnemonic'), null); - - return uploadState; + throw Error('Mnemonic was not provided, please, provide a mnemonic'); } if (!this.config.bridgeUrl) { - opts.finishedCallback(Error('Missing param "bridgeUrl"'), null); - - return uploadState; + throw Error('Missing param "bridgeUrl"'); } if (!bucketId) { - opts.finishedCallback(Error('Bucket id was not provided'), null); - - return uploadState; + throw Error('Bucket id was not provided'); } // if (!opts.parts || isNaN(opts.parts) || opts.parts < 2) { @@ -177,7 +169,7 @@ export class Environment { // return uploadState; // } - uploadFileMultipart( + return await uploadFileMultipart( opts.fileSize, opts.source, bucketId, @@ -187,45 +179,26 @@ export class Environment { user: this.config.bridgeUser, pass: this.config.bridgePass, }, - opts.progressCallback, - uploadState, this.config.appDetails, - ) - .then((fileId) => { - opts.finishedCallback(null, fileId); - }) - .catch((err) => { - opts.finishedCallback( - err.message === 'The operation was aborted' ? new Error('Process killed by user') : err, - null, - ); - }); - - return uploadState; - } - - upload: UploadStrategyFunction = (bucketId: string, opts: UploadOptions) => { - const uploadState = new ActionState(ActionTypes.Upload); + opts.progressCallback, + opts.abortSignal, + ); + }; + upload: UploadStrategyFunction = async (bucketId: string, opts: UploadOptions) => { if (!this.config.encryptionKey) { - opts.finishedCallback(Error('Mnemonic was not provided, please, provide a mnemonic'), null); - - return uploadState; + throw Error('Mnemonic was not provided, please, provide a mnemonic'); } if (!this.config.bridgeUrl) { - opts.finishedCallback(Error('Missing param "bridgeUrl"'), null); - - return uploadState; + throw Error('Missing param "bridgeUrl"'); } if (!bucketId) { - opts.finishedCallback(Error('Bucket id was not provided'), null); - - return uploadState; + throw Error('Bucket id was not provided'); } - uploadFileV2( + return await uploadFileV2( opts.fileSize, opts.source, bucketId, @@ -237,19 +210,8 @@ export class Environment { }, this.config.appDetails, opts.progressCallback, - uploadState, - ) - .then((fileId) => { - opts.finishedCallback(null, fileId); - }) - .catch((err) => { - opts.finishedCallback( - err.message === 'The operation was aborted' ? new Error('Process killed by user') : err, - null, - ); - }); - - return uploadState; + opts.abortSignal, + ); }; download: DownloadStrategyFunction = ( diff --git a/src/lib/core/upload/index.ts b/src/lib/core/upload/index.ts index 1c7d4be..ddeb0cc 100644 --- a/src/lib/core/upload/index.ts +++ b/src/lib/core/upload/index.ts @@ -13,14 +13,13 @@ export type UploadProgressCallback = ( totalBytes: number | null, ) => void; export type EncryptProgressCallback = (progress: number) => void; -export type UploadFinishCallback = (err: Error | null, response: string | null) => void; export interface UploadOptions { progressCallback: UploadProgressCallback; - finishedCallback: UploadFinishCallback; encryptProgressCallback?: EncryptProgressCallback; fileSize: number; source: Readable; + abortSignal: AbortSignal; } type FileId = string; diff --git a/src/lib/core/upload/multipart.ts b/src/lib/core/upload/multipart.ts index cf3a1ca..4d73424 100644 --- a/src/lib/core/upload/multipart.ts +++ b/src/lib/core/upload/multipart.ts @@ -8,7 +8,7 @@ type Part = { PartNumber: number; ETag: string }; async function uploadPart( partUrl: string, partStream: { size: number; stream: Buffer; index: number }, - signal?: AbortSignal, + signal: AbortSignal, ) { const { statusCode, headers, body } = await request(partUrl, { signal, diff --git a/src/lib/core/upload/strategy.ts b/src/lib/core/upload/strategy.ts index bdddd06..89a3b5b 100644 --- a/src/lib/core/upload/strategy.ts +++ b/src/lib/core/upload/strategy.ts @@ -1,7 +1,7 @@ import { EventEmitter } from 'events'; import { UploadOneStreamStrategyObject, UploadOneShardStrategyObject, UploadOptions } from '.'; -import { Abortable, ActionState, ContractMeta } from '../../../api'; +import { Abortable, ContractMeta } from '../../../api'; import { ShardMeta } from '../../models'; export type NegotiateContract = (shardMeta: ShardMeta) => Promise; @@ -14,7 +14,7 @@ export type UploadStrategyLabel = string; export type UploadStrategyObject = UploadOneStreamStrategyObject | UploadOneShardStrategyObject; -export type UploadStrategyFunction = (bucketId: string, opts: UploadOptions) => ActionState; +export type UploadStrategyFunction = (bucketId: string, opts: UploadOptions) => Promise; export abstract class UploadStrategy extends EventEmitter implements Abortable { fileEncryptionKey: Buffer = Buffer.alloc(0); diff --git a/src/lib/core/upload/uploadV2.ts b/src/lib/core/upload/uploadV2.ts index 3d1eb0e..3dadd78 100644 --- a/src/lib/core/upload/uploadV2.ts +++ b/src/lib/core/upload/uploadV2.ts @@ -9,8 +9,6 @@ import { ALGORITHMS, Network } from '@internxt/sdk/dist/network'; import { GenerateFileKey, sha256 } from '../../utils/crypto'; import { Events as ProgressEvents, HashStream, ProgressNotifier } from '../../utils/streams'; -import { ActionState } from '../../../api'; -import { Events } from '..'; import Errors from '../download/errors'; import { UploadProgressCallback } from '.'; import { logger } from '../../utils/logger'; @@ -39,14 +37,8 @@ export function uploadFileV2( creds: { pass: string; user: string }, appDetails: AppDetails, notifyProgress: UploadProgressCallback, - actionState: ActionState, + abortSignal: AbortSignal, ): Promise { - const abortController = new AbortController(); - - actionState.once(Events.Upload.Abort, () => { - abortController.abort(); - }); - const network = Network.client( bridgeUrl, { @@ -84,6 +76,7 @@ export function uploadFileV2( bucketId, mnemonic, fileSize, + abortSignal, async (algorithm, key, iv) => { logger.debug('Encrypting file using %s (key %s, iv %s)...', algorithm, key.toString('hex'), iv.toString('hex')); @@ -93,13 +86,13 @@ export function uploadFileV2( cipher = createCipheriv('aes-256-ctr', key as Buffer, iv as Buffer); }, - async (url: string) => { + async (url) => { logger.debug('Uploading file to %s...', url); const hasher = new HashStream(); await pipeline(source, cipher, hasher, progress, putStream(url, fileSize), { - signal: abortController.signal, + signal: abortSignal, }); const fileHash = hasher.getHash().toString('hex'); @@ -118,16 +111,10 @@ export function uploadFileMultipart( mnemonic: string, bridgeUrl: string, creds: { pass: string; user: string }, - notifyProgress: UploadProgressCallback, - actionState: ActionState, appDetails: AppDetails, + notifyProgress: UploadProgressCallback, + abortSignal: AbortSignal, ): Promise { - const abortController = new AbortController(); - - actionState.once(Events.Upload.Abort, () => { - abortController.abort(); - }); - const network = Network.client( bridgeUrl, { @@ -167,6 +154,7 @@ export function uploadFileMultipart( bucketId, mnemonic, fileSize, + abortSignal, async (algorithm, key, iv) => { logger.debug('Encrypting file using %s (key %s, iv %s)...', algorithm, key.toString('hex'), iv.toString('hex')); @@ -181,17 +169,13 @@ export function uploadFileMultipart( const hasher = new HashStream(); const pipelineToFinish = pipeline(source, cipher, hasher, progress, { - signal: abortController.signal, + signal: abortSignal, }); - const parts = await uploadParts(urls, progress, abortController.signal); + const parts = await uploadParts(urls, progress, abortSignal); await pipelineToFinish; - if (abortController.signal.aborted) { - throw new Error('Process killed by user'); - } - const fileHash = hasher.getHash().toString('hex'); logger.debug('File uploaded (hash %s)', fileHash); From 8213b277e786d91ef2b22fa977cc9dad74bf00d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Jim=C3=A9nez=20Rivera?= Date: Fri, 6 Mar 2026 10:09:04 +0100 Subject: [PATCH 2/5] Make abort signal optional --- package.json | 4 ++-- src/lib/core/upload/index.ts | 2 +- src/lib/core/upload/multipart.ts | 4 ++-- src/lib/core/upload/uploadV2.ts | 4 ++-- yarn.lock | 8 ++++---- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index 7c6cd13..e936f7c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@internxt/inxt-js", "author": "Internxt ", - "version": "2.3.2", + "version": "3.0.0", "description": "", "main": "build/index.js", "types": "build/index.d.ts", @@ -45,7 +45,7 @@ }, "dependencies": { "@internxt/lib": "1.4.1", - "@internxt/sdk": "1.15.1", + "@internxt/sdk": "1.15.2", "async": "3.2.6", "axios": "1.13.5", "bip39": "3.1.0", diff --git a/src/lib/core/upload/index.ts b/src/lib/core/upload/index.ts index ddeb0cc..f27462b 100644 --- a/src/lib/core/upload/index.ts +++ b/src/lib/core/upload/index.ts @@ -19,7 +19,7 @@ export interface UploadOptions { encryptProgressCallback?: EncryptProgressCallback; fileSize: number; source: Readable; - abortSignal: AbortSignal; + abortSignal?: AbortSignal; } type FileId = string; diff --git a/src/lib/core/upload/multipart.ts b/src/lib/core/upload/multipart.ts index 4d73424..0491269 100644 --- a/src/lib/core/upload/multipart.ts +++ b/src/lib/core/upload/multipart.ts @@ -8,7 +8,7 @@ type Part = { PartNumber: number; ETag: string }; async function uploadPart( partUrl: string, partStream: { size: number; stream: Buffer; index: number }, - signal: AbortSignal, + signal?: AbortSignal, ) { const { statusCode, headers, body } = await request(partUrl, { signal, @@ -31,7 +31,7 @@ interface PartUpload { source: { size: number; stream: Buffer; index: number }; } -export async function uploadParts(partUrls: string[], stream: Readable, signal: AbortSignal): Promise { +export async function uploadParts(partUrls: string[], stream: Readable, signal?: AbortSignal): Promise { const parts: Part[] = []; const concurrency = 10; diff --git a/src/lib/core/upload/uploadV2.ts b/src/lib/core/upload/uploadV2.ts index 3dadd78..c8d74a0 100644 --- a/src/lib/core/upload/uploadV2.ts +++ b/src/lib/core/upload/uploadV2.ts @@ -37,7 +37,7 @@ export function uploadFileV2( creds: { pass: string; user: string }, appDetails: AppDetails, notifyProgress: UploadProgressCallback, - abortSignal: AbortSignal, + abortSignal?: AbortSignal, ): Promise { const network = Network.client( bridgeUrl, @@ -113,7 +113,7 @@ export function uploadFileMultipart( creds: { pass: string; user: string }, appDetails: AppDetails, notifyProgress: UploadProgressCallback, - abortSignal: AbortSignal, + abortSignal?: AbortSignal, ): Promise { const network = Network.client( bridgeUrl, diff --git a/yarn.lock b/yarn.lock index 4b7eef1..b73abdd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -412,10 +412,10 @@ version "1.0.2" resolved "https://codeload.github.com/internxt/prettier-config/tar.gz/9fa74e9a2805e1538b50c3809324f1c9d0f3e4f9" -"@internxt/sdk@1.15.1": - version "1.15.1" - resolved "https://registry.yarnpkg.com/@internxt/sdk/-/sdk-1.15.1.tgz#69ad13a3c8cacbd929f025f24adc6fd2d1faf8ef" - integrity sha512-CEH/fNjDWenmFAl8NHaykb85AY4uEZDO5pA2ap8/GD4SXmxC3rcWsKnMsYO9jc8R2vpOPxmE3oBlNqOVcI/llQ== +"@internxt/sdk@1.15.2": + version "1.15.2" + resolved "https://npm.pkg.github.com/download/@internxt/sdk/1.15.2/9c6e01d70ceb2035b451f373de18629c4d6ed9e9#9c6e01d70ceb2035b451f373de18629c4d6ed9e9" + integrity sha512-IDuCMm/ByA6MHux1Hh3YTvVIj/tjOGZUho2v/XKo1i+FnjnMnbTKXClUI2080BbcDiacxL1QD013+l5dREX5RQ== dependencies: axios "1.13.5" internxt-crypto "0.0.13" From a3a99be71150dfeae335862343c7a86f1c038837 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Jim=C3=A9nez=20Rivera?= Date: Fri, 6 Mar 2026 10:12:03 +0100 Subject: [PATCH 3/5] Update yarn.lock --- yarn.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/yarn.lock b/yarn.lock index b73abdd..97656b1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -414,8 +414,8 @@ "@internxt/sdk@1.15.2": version "1.15.2" - resolved "https://npm.pkg.github.com/download/@internxt/sdk/1.15.2/9c6e01d70ceb2035b451f373de18629c4d6ed9e9#9c6e01d70ceb2035b451f373de18629c4d6ed9e9" - integrity sha512-IDuCMm/ByA6MHux1Hh3YTvVIj/tjOGZUho2v/XKo1i+FnjnMnbTKXClUI2080BbcDiacxL1QD013+l5dREX5RQ== + resolved "https://registry.yarnpkg.com/@internxt/sdk/-/sdk-1.15.2.tgz#240dfb0f9ad3d18bf0ea32a36b15aabc5cc6bed9" + integrity sha512-Hial7LUBGQ0nUTQc9G6ANRCYyVseGA73JG9ZMQCywkqGlEBslrLod0TuxyvrEcvFLkfS4iNvATWGZGNFMsMceg== dependencies: axios "1.13.5" internxt-crypto "0.0.13" From fe276e22e1cd2d0353bdef070271cf44a464447e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Jim=C3=A9nez=20Rivera?= Date: Fri, 6 Mar 2026 10:14:19 +0100 Subject: [PATCH 4/5] Update uploadV2.ts --- src/lib/core/upload/uploadV2.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/core/upload/uploadV2.ts b/src/lib/core/upload/uploadV2.ts index c8d74a0..d230345 100644 --- a/src/lib/core/upload/uploadV2.ts +++ b/src/lib/core/upload/uploadV2.ts @@ -76,7 +76,6 @@ export function uploadFileV2( bucketId, mnemonic, fileSize, - abortSignal, async (algorithm, key, iv) => { logger.debug('Encrypting file using %s (key %s, iv %s)...', algorithm, key.toString('hex'), iv.toString('hex')); @@ -101,6 +100,7 @@ export function uploadFileV2( return fileHash; }, + abortSignal, ); } @@ -154,7 +154,6 @@ export function uploadFileMultipart( bucketId, mnemonic, fileSize, - abortSignal, async (algorithm, key, iv) => { logger.debug('Encrypting file using %s (key %s, iv %s)...', algorithm, key.toString('hex'), iv.toString('hex')); @@ -185,6 +184,7 @@ export function uploadFileMultipart( parts, }; }, + abortSignal, parts, ); } From 1be28e8dc96217504f50ee62f4a80a6b472830a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Jim=C3=A9nez=20Rivera?= Date: Fri, 6 Mar 2026 12:00:28 +0100 Subject: [PATCH 5/5] Join upload and uploadMultipart --- src/index.ts | 37 +---- src/lib/core/upload/uploadV2.ts | 130 ++++++++---------- .../{uploadV2.test.ts => upload.test.ts} | 10 +- 3 files changed, 66 insertions(+), 111 deletions(-) rename tests/lib/core/upload/{uploadV2.test.ts => upload.test.ts} (83%) diff --git a/src/index.ts b/src/index.ts index 8d0f7f4..20297d2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -22,7 +22,7 @@ import { Bridge, CreateFileTokenResponse, GetDownloadLinksResponse } from './ser import { HashStream } from './lib/utils/streams'; import { downloadFileV2 } from './lib/core/download/downloadV2'; import { FileVersionOneError } from '@internxt/sdk/dist/network/download'; -import { uploadFileMultipart, uploadFileV2 } from './lib/core/upload/uploadV2'; +import { upload as uploadFileV2 } from './lib/core/upload/uploadV2'; type GetBucketsCallback = (err: Error | null, result: any) => void; @@ -150,41 +150,6 @@ export class Environment { this.config.encryptionKey = newEncryptionKey; } - uploadMultipartFile: UploadStrategyFunction = async (bucketId: string, opts: UploadOptions) => { - if (!this.config.encryptionKey) { - throw Error('Mnemonic was not provided, please, provide a mnemonic'); - } - - if (!this.config.bridgeUrl) { - throw Error('Missing param "bridgeUrl"'); - } - - if (!bucketId) { - throw Error('Bucket id was not provided'); - } - - // if (!opts.parts || isNaN(opts.parts) || opts.parts < 2) { - // opts.finishedCallback(Error('Invalid "parts" parameter. Expected number > 1'), null); - - // return uploadState; - // } - - return await uploadFileMultipart( - opts.fileSize, - opts.source, - bucketId, - this.config.encryptionKey, - this.config.bridgeUrl, - { - user: this.config.bridgeUser, - pass: this.config.bridgePass, - }, - this.config.appDetails, - opts.progressCallback, - opts.abortSignal, - ); - }; - upload: UploadStrategyFunction = async (bucketId: string, opts: UploadOptions) => { if (!this.config.encryptionKey) { throw Error('Mnemonic was not provided, please, provide a mnemonic'); diff --git a/src/lib/core/upload/uploadV2.ts b/src/lib/core/upload/uploadV2.ts index d230345..29f0bde 100644 --- a/src/lib/core/upload/uploadV2.ts +++ b/src/lib/core/upload/uploadV2.ts @@ -5,7 +5,7 @@ import { pipeline as undiciPipeline } from 'undici'; import { validateMnemonic } from 'bip39'; import { uploadFile, uploadMultipartFile } from '@internxt/sdk/dist/network/upload'; -import { ALGORITHMS, Network } from '@internxt/sdk/dist/network'; +import { ALGORITHMS, Crypto, Network } from '@internxt/sdk/dist/network'; import { GenerateFileKey, sha256 } from '../../utils/crypto'; import { Events as ProgressEvents, HashStream, ProgressNotifier } from '../../utils/streams'; @@ -15,7 +15,20 @@ import { logger } from '../../utils/logger'; import { uploadParts } from './multipart'; import { AppDetails } from '@internxt/sdk/dist/shared'; -function putStream(url: string, fileSize?: number): Writable { +const MULTIPART_THRESHOLD = 100 * 1024 * 1024; // 100MB + +const crypto: Crypto = { + validateMnemonic: (mnemonic: string) => { + return validateMnemonic(mnemonic); + }, + algorithm: ALGORITHMS.AES256CTR, + generateFileKey: (mnemonic, bucketId, index) => { + return GenerateFileKey(mnemonic, bucketId, index as Buffer); + }, + randomBytes, +}; + +function putStream(url: string, fileSize: number): Writable { const formattedUrl = new URL(url); let headers: Record = { 'Content-Type': 'application/octet-stream', @@ -29,50 +42,19 @@ function putStream(url: string, fileSize?: number): Writable { } export function uploadFileV2( + network: Network, fileSize: number, source: Readable, bucketId: string, mnemonic: string, - bridgeUrl: string, - creds: { pass: string; user: string }, - appDetails: AppDetails, - notifyProgress: UploadProgressCallback, + progress: ProgressNotifier, abortSignal?: AbortSignal, ): Promise { - const network = Network.client( - bridgeUrl, - { - ...appDetails, - customHeaders: { - lib: 'inxt-js', - ...appDetails.customHeaders, - }, - }, - { - bridgeUser: creds.user, - userId: sha256(Buffer.from(creds.pass)).toString('hex'), - }, - ); - let cipher: Cipheriv; - const progress = new ProgressNotifier(fileSize, 2000, { emitClose: false }); - - progress.on(ProgressEvents.Progress, (progress: number) => { - notifyProgress(progress, null, null); - }); return uploadFile( network, - { - validateMnemonic: (mnemonic: string) => { - return validateMnemonic(mnemonic); - }, - algorithm: ALGORITHMS.AES256CTR, - generateFileKey: (mnemonic, bucketId, index) => { - return GenerateFileKey(mnemonic, bucketId, index as Buffer); - }, - randomBytes, - }, + crypto, bucketId, mnemonic, fileSize, @@ -105,52 +87,21 @@ export function uploadFileV2( } export function uploadFileMultipart( + network: Network, fileSize: number, source: Readable, bucketId: string, mnemonic: string, - bridgeUrl: string, - creds: { pass: string; user: string }, - appDetails: AppDetails, - notifyProgress: UploadProgressCallback, + progress: ProgressNotifier, abortSignal?: AbortSignal, ): Promise { - const network = Network.client( - bridgeUrl, - { - ...appDetails, - customHeaders: { - lib: 'inxt-js', - ...appDetails.customHeaders, - }, - }, - { - bridgeUser: creds.user, - userId: sha256(Buffer.from(creds.pass)).toString('hex'), - }, - ); - let cipher: Cipheriv; - const progress = new ProgressNotifier(fileSize, 2000, { emitClose: false }); const partSize = 15 * 1024 * 1024; const parts = Math.ceil(fileSize / partSize); - progress.on(ProgressEvents.Progress, (progress: number) => { - notifyProgress(progress, null, null); - }); - return uploadMultipartFile( network, - { - validateMnemonic: (mnemonic: string) => { - return validateMnemonic(mnemonic); - }, - algorithm: ALGORITHMS.AES256CTR, - generateFileKey: (mnemonic, bucketId, index) => { - return GenerateFileKey(mnemonic, bucketId, index as Buffer); - }, - randomBytes, - }, + crypto, bucketId, mnemonic, fileSize, @@ -188,3 +139,42 @@ export function uploadFileMultipart( parts, ); } + +export function upload( + fileSize: number, + source: Readable, + bucketId: string, + mnemonic: string, + bridgeUrl: string, + creds: { pass: string; user: string }, + appDetails: AppDetails, + notifyProgress: UploadProgressCallback, + abortSignal?: AbortSignal, +): Promise { + const network = Network.client( + bridgeUrl, + { + ...appDetails, + customHeaders: { + lib: 'inxt-js', + ...appDetails.customHeaders, + }, + }, + { + bridgeUser: creds.user, + userId: sha256(Buffer.from(creds.pass)).toString('hex'), + }, + ); + + const progress = new ProgressNotifier(fileSize, 2000, { emitClose: false }); + + progress.on(ProgressEvents.Progress, (progress: number) => { + notifyProgress(progress, null, null); + }); + + if (fileSize > MULTIPART_THRESHOLD) { + return uploadFileMultipart(network, fileSize, source, bucketId, mnemonic, progress, abortSignal); + } + + return uploadFileV2(network, fileSize, source, bucketId, mnemonic, progress, abortSignal); +} diff --git a/tests/lib/core/upload/uploadV2.test.ts b/tests/lib/core/upload/upload.test.ts similarity index 83% rename from tests/lib/core/upload/uploadV2.test.ts rename to tests/lib/core/upload/upload.test.ts index 9dffa26..3c0ad3b 100644 --- a/tests/lib/core/upload/uploadV2.test.ts +++ b/tests/lib/core/upload/upload.test.ts @@ -2,8 +2,7 @@ import { describe, expect, it } from 'vitest'; import { fail } from 'node:assert'; import { Readable } from 'stream'; import { UploadInvalidMnemonicError } from '@internxt/sdk/dist/network/errors'; -import { ActionState, ActionTypes } from '../../../../src/api'; -import { uploadFileV2 } from '../../../../src/lib/core/upload/uploadV2'; +import { upload } from '../../../../src/lib/core/upload/uploadV2'; import { getBridgeUrl, getBucketId, @@ -16,16 +15,17 @@ import { const creds = getNetworkCredentials(); const bucketId = getBucketId(); const bridgeUrl = getBridgeUrl(); +const abortSignal = new AbortController().signal; const fileContent = 'some text that i have in the file'; const fileBytes = getFileBytes(fileContent); const validMnemonic = getValidMnemonic(); const invalidMnemonic = getInvalidMnemonic(); -describe('uploadFileV2()', () => { +describe('upload()', () => { describe('Should handle errors properly', () => { it('Should throw if the mnemonic is invalid', async () => { try { - await uploadFileV2( + await upload( 0, Readable.from(fileBytes), bucketId, @@ -34,7 +34,7 @@ describe('uploadFileV2()', () => { creds, { clientName: 'inxt-js', clientVersion: '1.0' }, () => {}, - new ActionState(ActionTypes.Upload), + abortSignal, ); fail('Expected function to throw an error, but it did not.');