files.com 1.0.412 → 1.0.414
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/_VERSION +1 -1
- package/lib/Api.js +30 -18
- package/lib/Files.js +1 -1
- package/lib/isomorphic/File.node.js +21 -13
- package/lib/models/ActionNotificationExport.js +8 -5
- package/lib/models/ApiKey.js +8 -5
- package/lib/models/As2Partner.js +8 -5
- package/lib/models/As2Station.js +8 -5
- package/lib/models/Automation.js +8 -5
- package/lib/models/AutomationRun.js +8 -5
- package/lib/models/Behavior.js +15 -9
- package/lib/models/Bundle.js +8 -5
- package/lib/models/BundleNotification.js +8 -5
- package/lib/models/Clickwrap.js +8 -5
- package/lib/models/ExternalEvent.js +8 -5
- package/lib/models/File.js +212 -131
- package/lib/models/FileComment.js +8 -5
- package/lib/models/FileMigration.js +8 -5
- package/lib/models/Folder.js +14 -9
- package/lib/models/FormFieldSet.js +8 -5
- package/lib/models/GpgKey.js +8 -5
- package/lib/models/Group.js +8 -5
- package/lib/models/History.js +22 -13
- package/lib/models/HistoryExport.js +8 -5
- package/lib/models/Invoice.js +8 -5
- package/lib/models/Lock.js +15 -9
- package/lib/models/Message.js +8 -5
- package/lib/models/MessageComment.js +8 -5
- package/lib/models/MessageCommentReaction.js +8 -5
- package/lib/models/MessageReaction.js +8 -5
- package/lib/models/Notification.js +8 -5
- package/lib/models/Payment.js +8 -5
- package/lib/models/Priority.js +8 -5
- package/lib/models/Project.js +8 -5
- package/lib/models/PublicKey.js +8 -5
- package/lib/models/RemoteServer.js +15 -9
- package/lib/models/Request.js +8 -5
- package/lib/models/SftpHostKey.js +8 -5
- package/lib/models/ShareGroup.js +8 -5
- package/lib/models/Snapshot.js +8 -5
- package/lib/models/SsoStrategy.js +8 -5
- package/lib/models/Style.js +8 -5
- package/lib/models/User.js +8 -5
- package/lib/models/UserRequest.js +8 -5
- package/package.json +1 -1
- package/src/Files.js +1 -1
- package/src/models/File.js +86 -44
- package/test/src/index.js +30 -3
    
        package/src/models/File.js
    CHANGED
    
    | @@ -97,79 +97,121 @@ class File { | |
| 97 97 | 
             
                    let length = 0
         | 
| 98 98 | 
             
                    const concurrentUploads = []
         | 
| 99 99 |  | 
| 100 | 
            +
                    let chunkBuffer = null
         | 
| 101 | 
            +
                    let streamEnded = false
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                    const handleStreamEnd = async () => {
         | 
| 104 | 
            +
                      if (chunkBuffer !== null || !streamEnded) {
         | 
| 105 | 
            +
                        return
         | 
| 106 | 
            +
                      }
         | 
| 107 | 
            +
                
         | 
| 108 | 
            +
                      try {
         | 
| 109 | 
            +
                        if (chunks.length > 0) {
         | 
| 110 | 
            +
                          const buffer = Buffer.concat(chunks)
         | 
| 111 | 
            +
                          const nextFileUploadPart = await File._continueUpload(destinationPath, ++part, firstFileUploadPart, options)
         | 
| 112 | 
            +
                
         | 
| 113 | 
            +
                          const upload_uri = determinePartUploadUri(nextFileUploadPart)
         | 
| 114 | 
            +
                
         | 
| 115 | 
            +
                          // instantiate an httpsAgent dynamically if needed
         | 
| 116 | 
            +
                          const agent = options.getAgentForUrl?.(upload_uri) || options?.agent
         | 
| 117 | 
            +
                
         | 
| 118 | 
            +
                          concurrentUploads.push(Api.sendFilePart(upload_uri, 'PUT', buffer, { agent }))
         | 
| 119 | 
            +
                        }
         | 
| 120 | 
            +
                
         | 
| 121 | 
            +
                        await Promise.all(concurrentUploads)
         | 
| 122 | 
            +
                
         | 
| 123 | 
            +
                        const response = await File._completeUpload(firstFileUploadPart, options)
         | 
| 124 | 
            +
                        const createdFile = new File(response.data, options)
         | 
| 125 | 
            +
                
         | 
| 126 | 
            +
                        resolve(createdFile)
         | 
| 127 | 
            +
                      } catch (error) {
         | 
| 128 | 
            +
                        reject(error)
         | 
| 129 | 
            +
                      }
         | 
| 130 | 
            +
                    }
         | 
| 131 | 
            +
             | 
| 100 132 | 
             
                    readableStream.on('error', error => { reject(error) })
         | 
| 101 133 |  | 
| 134 | 
            +
                    // note that for a network stream, each chunk is typically less than partsize * 2, but
         | 
| 135 | 
            +
                    // if a stream has been created based on very large data, it's possible for a chunk to
         | 
| 136 | 
            +
                    // contain the entire file and we could get a single chunk with length >= partsize * 3
         | 
| 102 137 | 
             
                    readableStream.on('data', async chunk => {
         | 
| 103 138 | 
             
                      try {
         | 
| 104 | 
            -
                         | 
| 105 | 
            -
                        const excessLength = nextLength - firstFileUploadPart.partsize
         | 
| 139 | 
            +
                        let excessLength = (length + chunk.length) - firstFileUploadPart.partsize
         | 
| 106 140 |  | 
| 107 | 
            -
                         | 
| 141 | 
            +
                        chunkBuffer = Buffer.from(chunk)
         | 
| 108 142 |  | 
| 109 143 | 
             
                        if (excessLength > 0) {
         | 
| 110 144 | 
             
                          readableStream.pause()
         | 
| 111 145 |  | 
| 112 | 
            -
                           | 
| 113 | 
            -
             | 
| 146 | 
            +
                          while (chunkBuffer) {
         | 
| 147 | 
            +
                            // the amount to append this last part with to make it exactly the full partsize
         | 
| 148 | 
            +
                            const lengthForEndOfCurrentPart = chunkBuffer.length - excessLength
         | 
| 114 149 |  | 
| 115 | 
            -
             | 
| 116 | 
            -
             | 
| 150 | 
            +
                            const lastChunkForCurrentPart = chunkBuffer.subarray(0, lengthForEndOfCurrentPart)
         | 
| 151 | 
            +
                            const chunkBufferAfterCurrentPart = chunkBuffer.subarray(lengthForEndOfCurrentPart)
         | 
| 117 152 |  | 
| 118 | 
            -
             | 
| 153 | 
            +
                            chunks.push(lastChunkForCurrentPart)
         | 
| 119 154 |  | 
| 120 | 
            -
             | 
| 121 | 
            -
             | 
| 155 | 
            +
                            const buffer = Buffer.concat(chunks)
         | 
| 156 | 
            +
                            const nextFileUploadPart = await File._continueUpload(destinationPath, ++part, firstFileUploadPart, options)
         | 
| 122 157 |  | 
| 123 | 
            -
             | 
| 158 | 
            +
                            const upload_uri = determinePartUploadUri(nextFileUploadPart)
         | 
| 124 159 |  | 
| 125 | 
            -
             | 
| 126 | 
            -
             | 
| 160 | 
            +
                            // instantiate an httpsAgent dynamically if needed
         | 
| 161 | 
            +
                            const agent = options.getAgentForUrl?.(upload_uri) || options?.agent
         | 
| 127 162 |  | 
| 128 | 
            -
             | 
| 163 | 
            +
                            const uploadPromise = Api.sendFilePart(upload_uri, 'PUT', buffer, { agent })
         | 
| 129 164 |  | 
| 130 | 
            -
             | 
| 131 | 
            -
             | 
| 132 | 
            -
             | 
| 133 | 
            -
             | 
| 134 | 
            -
             | 
| 165 | 
            +
                            if (firstFileUploadPart.parallel_parts) {
         | 
| 166 | 
            +
                              concurrentUploads.push(uploadPromise)
         | 
| 167 | 
            +
                            } else {
         | 
| 168 | 
            +
                              await uploadPromise
         | 
| 169 | 
            +
                            }
         | 
| 170 | 
            +
             | 
| 171 | 
            +
                            // determine if the remainder of the excess chunk data is too large to be a single part
         | 
| 172 | 
            +
                            const isNextChunkAtLeastOnePart = chunkBufferAfterCurrentPart.length >= firstFileUploadPart.partsize
         | 
| 173 | 
            +
             | 
| 174 | 
            +
                            // the excess data contains >= 1 full part, so we'll loop again to enqueue
         | 
| 175 | 
            +
                            // the next part for upload and continue processing any excess beyond that
         | 
| 176 | 
            +
                            if (isNextChunkAtLeastOnePart) {
         | 
| 177 | 
            +
                              chunks = []
         | 
| 178 | 
            +
                              length = 0
         | 
| 135 179 |  | 
| 136 | 
            -
             | 
| 137 | 
            -
             | 
| 180 | 
            +
                              chunkBuffer = chunkBufferAfterCurrentPart
         | 
| 181 | 
            +
                              excessLength = chunkBuffer.length - firstFileUploadPart.partsize
         | 
| 182 | 
            +
                            // the excess data is less than a full part, so we'll enqueue it
         | 
| 183 | 
            +
                            } else if (chunkBufferAfterCurrentPart.length > 0) {
         | 
| 184 | 
            +
                              chunks = [chunkBufferAfterCurrentPart]
         | 
| 185 | 
            +
                              length = chunkBufferAfterCurrentPart.length
         | 
| 186 | 
            +
             | 
| 187 | 
            +
                              chunkBuffer = null
         | 
| 188 | 
            +
                            } else {
         | 
| 189 | 
            +
                              chunkBuffer = null
         | 
| 190 | 
            +
                            }
         | 
| 191 | 
            +
                          }
         | 
| 138 192 |  | 
| 139 193 | 
             
                          readableStream.resume()
         | 
| 140 194 | 
             
                        } else {
         | 
| 141 195 | 
             
                          chunks.push(chunkBuffer)
         | 
| 142 196 | 
             
                          length += chunk.length
         | 
| 143 | 
            -
                        }
         | 
| 144 | 
            -
                      } catch (error) {
         | 
| 145 | 
            -
                        reject(error)
         | 
| 146 | 
            -
                      }
         | 
| 147 | 
            -
                    })
         | 
| 148 | 
            -
             | 
| 149 | 
            -
                    readableStream.on('end', async () => {
         | 
| 150 | 
            -
                      try {
         | 
| 151 | 
            -
                        if (chunks.length > 0) {
         | 
| 152 | 
            -
                          const buffer = Buffer.concat(chunks)
         | 
| 153 | 
            -
                          const nextFileUploadPart = await File._continueUpload(destinationPath, ++part, firstFileUploadPart, options)
         | 
| 154 | 
            -
             | 
| 155 | 
            -
                          const upload_uri = determinePartUploadUri(nextFileUploadPart)
         | 
| 156 197 |  | 
| 157 | 
            -
                           | 
| 158 | 
            -
                          const agent = options.getAgentForUrl?.(upload_uri) || options?.agent
         | 
| 159 | 
            -
             | 
| 160 | 
            -
                          concurrentUploads.push(Api.sendFilePart(upload_uri, 'PUT', buffer, { agent }))
         | 
| 198 | 
            +
                          chunkBuffer = null
         | 
| 161 199 | 
             
                        }
         | 
| 162 200 |  | 
| 163 | 
            -
                         | 
| 164 | 
            -
             | 
| 165 | 
            -
                         | 
| 166 | 
            -
                        const createdFile = new File(response.data, options)
         | 
| 167 | 
            -
             | 
| 168 | 
            -
                        resolve(createdFile)
         | 
| 201 | 
            +
                        if (streamEnded) {
         | 
| 202 | 
            +
                          handleStreamEnd()
         | 
| 203 | 
            +
                        }
         | 
| 169 204 | 
             
                      } catch (error) {
         | 
| 170 205 | 
             
                        reject(error)
         | 
| 171 206 | 
             
                      }
         | 
| 172 207 | 
             
                    })
         | 
| 208 | 
            +
             | 
| 209 | 
            +
                    // note that this event may occur while there is still data being processed above
         | 
| 210 | 
            +
                    readableStream.on('end', () => {
         | 
| 211 | 
            +
                      streamEnded = true
         | 
| 212 | 
            +
              
         | 
| 213 | 
            +
                      handleStreamEnd()
         | 
| 214 | 
            +
                    })
         | 
| 173 215 | 
             
                  })
         | 
| 174 216 |  | 
| 175 217 | 
             
                  return file
         | 
    
        package/test/src/index.js
    CHANGED
    
    | @@ -142,7 +142,7 @@ const testSuite = async () => { | |
| 142 142 | 
             
              }
         | 
| 143 143 |  | 
| 144 144 | 
             
              /* to run this test, put a file (or symlink) at huge-file.ext * /
         | 
| 145 | 
            -
              const  | 
| 145 | 
            +
              const testUploadFileForHugeFile = async () => {
         | 
| 146 146 | 
             
                const sourceFilePath = '../huge-file.ext'
         | 
| 147 147 |  | 
| 148 148 | 
             
                const displayName = `huge-file__${nonce}.ext`
         | 
| @@ -161,7 +161,33 @@ const testSuite = async () => { | |
| 161 161 |  | 
| 162 162 | 
             
                await file.delete()
         | 
| 163 163 |  | 
| 164 | 
            -
                Logger.info('*****  | 
| 164 | 
            +
                Logger.info('***** testUploadFileForHugeFile() succeeded! *****')
         | 
| 165 | 
            +
              }
         | 
| 166 | 
            +
             | 
| 167 | 
            +
              /* to run this test, put a file (or symlink) at huge-file.ext * /
         | 
| 168 | 
            +
              const testUploadDataForHugeFile = async () => {
         | 
| 169 | 
            +
                const sourceFilePath = '../huge-file.ext'
         | 
| 170 | 
            +
             | 
| 171 | 
            +
                const displayName = `huge-file__${nonce}.ext`
         | 
| 172 | 
            +
                const destinationPath = `${SDK_TEST_ROOT_FOLDER}/${displayName}`
         | 
| 173 | 
            +
             | 
| 174 | 
            +
                const fs = require('fs/promises')
         | 
| 175 | 
            +
                const data = await fs.readFile(sourceFilePath, { encoding: "utf8" })
         | 
| 176 | 
            +
             | 
| 177 | 
            +
                const file = await File.uploadData(destinationPath, data)
         | 
| 178 | 
            +
             | 
| 179 | 
            +
                invariant(!!file.path, 'Uploaded file response object should have a path')
         | 
| 180 | 
            +
                invariant(file.display_name === displayName, 'Uploaded file response object should have the same display_name as the file we uploaded')
         | 
| 181 | 
            +
             | 
| 182 | 
            +
                const foundFile = await File.find(destinationPath)
         | 
| 183 | 
            +
             | 
| 184 | 
            +
                invariant(foundFile.path === destinationPath, 'Found file should have the same path as the file we uploaded')
         | 
| 185 | 
            +
                invariant(foundFile.display_name === displayName, 'Found file should have the same display_name as the file we uploaded')
         | 
| 186 | 
            +
                invariant(typeof foundFile.getDownloadUri() === 'undefined', 'Found file should not have a download uri yet')
         | 
| 187 | 
            +
             | 
| 188 | 
            +
                await file.delete()
         | 
| 189 | 
            +
             | 
| 190 | 
            +
                Logger.info('***** testUploadDataForHugeFile() succeeded! *****')
         | 
| 165 191 | 
             
              }
         | 
| 166 192 | 
             
              /**/
         | 
| 167 193 |  | 
| @@ -242,7 +268,8 @@ const testSuite = async () => { | |
| 242 268 | 
             
                await testFolderListAutoPagination()
         | 
| 243 269 | 
             
                await testUploadAndDownloadToFile()
         | 
| 244 270 | 
             
                await testUploadAndDownloadToString()
         | 
| 245 | 
            -
                // await  | 
| 271 | 
            +
                // await testUploadDataForHugeFile() // to run this test, put a file (or symlink) at huge-file.ext
         | 
| 272 | 
            +
                // await testUploadFileForHugeFile() // to run this test, put a file (or symlink) at huge-file.ext
         | 
| 246 273 | 
             
                await testSession()
         | 
| 247 274 | 
             
                await testFailure()
         | 
| 248 275 | 
             
                await testUserListAndUpdate()
         |