@@ -15,6 +15,10 @@ import { ErrorUtils } from '../utils/errors.utils';
1515import { MissingCredentialsError , NotValidDirectoryError , NotValidFolderUuidError } from '../types/command.types' ;
1616import { ValidationService } from '../services/validation.service' ;
1717import { EncryptionVersion } from '@internxt/sdk/dist/drive/storage/types' ;
18+ import { ThumbnailService } from '../services/thumbnail.service' ;
19+ import { BufferStream } from '../utils/stream.utils' ;
20+ import { isFileThumbnailable } from '../utils/thumbnail.utils' ;
21+ import { Readable } from 'node:stream' ;
1822
1923export default class UploadFile extends Command {
2024 static readonly args = { } ;
@@ -52,6 +56,9 @@ export default class UploadFile extends Command {
5256 throw new Error ( 'The file is empty. Uploading empty files is not allowed.' ) ;
5357 }
5458
59+ const fileInfo = path . parse ( filePath ) ;
60+ const fileType = fileInfo . ext . replaceAll ( '.' , '' ) ;
61+
5562 let destinationFolderUuid = await this . getDestinationFolderUuid ( flags [ 'destination' ] , nonInteractive ) ;
5663 if ( destinationFolderUuid . trim ( ) . length === 0 ) {
5764 // destinationFolderUuid is empty from flags&prompt, which means we should use RootFolderUuid
@@ -75,45 +82,34 @@ export default class UploadFile extends Command {
7582 CLIUtils . done ( ) ;
7683
7784 // 2. Upload file to the Network
78- const fileStream = createReadStream ( filePath ) ;
85+ const readStream = createReadStream ( filePath ) ;
7986 const timer = CLIUtils . timer ( ) ;
8087 const progressBar = CLIUtils . progress ( {
8188 format : 'Uploading file [{bar}] {percentage}%' ,
8289 linewrap : true ,
8390 } ) ;
8491 progressBar . start ( 100 , 0 ) ;
8592
86- const minimumMultipartThreshold = 100 * 1024 * 1024 ;
87- const useMultipart = stats . size > minimumMultipartThreshold ;
88- const partSize = 30 * 1024 * 1024 ;
89- const parts = Math . ceil ( stats . size / partSize ) ;
90-
91- let uploadOperation : Promise <
92- [
93- Promise < {
94- fileId : string ;
95- hash : Buffer ;
96- } > ,
97- AbortController ,
98- ]
99- > ;
100-
101- if ( useMultipart ) {
102- uploadOperation = networkFacade . uploadMultipartFromStream ( user . bucket , user . mnemonic , stats . size , fileStream , {
103- parts,
104- progressCallback : ( progress ) => {
105- progressBar . update ( progress * 0.99 ) ;
106- } ,
107- } ) ;
108- } else {
109- uploadOperation = networkFacade . uploadFromStream ( user . bucket , user . mnemonic , stats . size , fileStream , {
110- progressCallback : ( progress ) => {
111- progressBar . update ( progress * 0.99 ) ;
112- } ,
113- } ) ;
93+ let bufferStream : BufferStream | undefined ;
94+ let fileStream : Readable = readStream ;
95+ const isThumbnailable = isFileThumbnailable ( fileType ) ;
96+ if ( isThumbnailable ) {
97+ bufferStream = new BufferStream ( ) ;
98+ fileStream = readStream . pipe ( bufferStream ) ;
11499 }
115100
116- const [ uploadPromise , abortable ] = await uploadOperation ;
101+ const progressCallback = ( progress : number ) => {
102+ progressBar . update ( progress * 0.99 ) ;
103+ } ;
104+
105+ const [ uploadPromise , abortable ] = await UploadService . instance . uploadFileStream (
106+ fileStream ,
107+ user . bucket ,
108+ user . mnemonic ,
109+ stats . size ,
110+ networkFacade ,
111+ progressCallback ,
112+ ) ;
117113
118114 process . on ( 'SIGINT' , ( ) => {
119115 abortable . abort ( 'SIGINT received' ) ;
@@ -123,10 +119,9 @@ export default class UploadFile extends Command {
123119 const uploadResult = await uploadPromise ;
124120
125121 // 3. Create the file in Drive
126- const fileInfo = path . parse ( filePath ) ;
127122 const createdDriveFile = await DriveFileService . instance . createFile ( {
128123 plain_name : fileInfo . name ,
129- type : fileInfo . ext . replaceAll ( '.' , '' ) ,
124+ type : fileType ,
130125 size : stats . size ,
131126 folder_id : destinationFolderUuid ,
132127 id : uploadResult . fileId ,
@@ -135,6 +130,25 @@ export default class UploadFile extends Command {
135130 name : '' ,
136131 } ) ;
137132
133+ try {
134+ if ( isThumbnailable && bufferStream ) {
135+ const thumbnailBuffer = bufferStream . getBuffer ( ) ;
136+
137+ if ( thumbnailBuffer ) {
138+ await ThumbnailService . instance . uploadThumbnail (
139+ thumbnailBuffer ,
140+ fileType ,
141+ user . bucket ,
142+ user . mnemonic ,
143+ createdDriveFile . id ,
144+ networkFacade ,
145+ ) ;
146+ }
147+ }
148+ } catch ( error ) {
149+ ErrorUtils . report ( this . error . bind ( this ) , error , { command : this . id } ) ;
150+ }
151+
138152 progressBar . update ( 100 ) ;
139153 progressBar . stop ( ) ;
140154
0 commit comments