filemail-sdk 9.4.7 → 9.4.9
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/LICENSE +10 -10
- package/dist/src/autoDownloader/autoDownloader.js.map +1 -1
- package/dist/src/autoDownloader/autoDownloaderDestroyer.js.map +1 -1
- package/dist/src/autoDownloader/autoDownloaderError.js.map +1 -1
- package/dist/src/autoDownloader/autoDownloaderEvent.js.map +1 -1
- package/dist/src/autoDownloader/autoDownloaderOptions.js.map +1 -1
- package/dist/src/autoDownloader/autoDownloaderStateSerializer.js.map +1 -1
- package/dist/src/autoDownloader/eventArgs/autoDownloadEventArgs.js.map +1 -1
- package/dist/src/autoDownloader/eventArgs/autoDownloadFailedEventArgs.js.map +1 -1
- package/dist/src/autoDownloader/eventArgs/autoDownloadProgressedEventArgs.js.map +1 -1
- package/dist/src/autoDownloader/eventArgs/autoDownloadStartedEventArgs.js.map +1 -1
- package/dist/src/autoDownloader/eventArgs/autoDownloadStartingFailedEventArgs.js.map +1 -1
- package/dist/src/autoDownloader/eventArgs/autoDownloadUnhealthyEventArgs.js.map +1 -1
- package/dist/src/autoDownloader/eventArgs/checkingForNewTransfersStartedEventArgs.js.map +1 -1
- package/dist/src/autoDownloader/eventArgs/newTransfersCheckCompletedEventArgs.js.map +1 -1
- package/dist/src/autoDownloader/factory/nodeAutoDownloaderFactory.js.map +1 -1
- package/dist/src/autoDownloader/factory/nodeAutoDownloaderFactoryOptions.js.map +1 -1
- package/dist/src/autoDownloader/newInboxTransfersRetriever/newInboxTransfer.js.map +1 -1
- package/dist/src/autoDownloader/newInboxTransfersRetriever/newInboxTransfersRetriever.js.map +1 -1
- package/dist/src/autoDownloader/node/nodeAutoDownloaderStateSerializer.js.map +1 -1
- package/dist/src/autoDownloader/node/nodeTransferDownloaderFactory.js.map +1 -1
- package/dist/src/autoDownloader/state/autoDownloaderRecoverableState.js.map +1 -1
- package/dist/src/autoDownloader/state/autoDownloaderState.js.map +1 -1
- package/dist/src/autoDownloader/state/autoDownloaderStateRecoverableTransfer.js.map +1 -1
- package/dist/src/autoDownloader/state/autoDownloaderStateRunningTransfer.js.map +1 -1
- package/dist/src/autoDownloader/state/autoDownloaderStateSnapshot.js.map +1 -1
- package/dist/src/autoDownloader/transferDownloaderFactory.js.map +1 -1
- package/dist/src/autoDownloader/transferHandler/autoDownloaderNewTransferHandler.js.map +1 -1
- package/dist/src/autoDownloader/transferHandler/autoDownloaderRecoverableTransferHandler.js.map +1 -1
- package/dist/src/autoDownloader/transferHandler/autoDownloaderTransferHandlerBase.js.map +1 -1
- package/dist/src/client/downloader/downloaderCore.js.map +1 -1
- package/dist/src/client/downloader/node/nodeTransferDownloader.js.map +1 -1
- package/dist/src/client/downloader/transferDownloader.js.map +1 -1
- package/dist/src/client/environmentVariables.js.map +1 -1
- package/dist/src/client/healthMonitor/events/eventArgs/healthMonitorHealthyEventArgs.js.map +1 -1
- package/dist/src/client/healthMonitor/events/eventArgs/healthMonitorUnhealthyEventArgs.js.map +1 -1
- package/dist/src/client/healthMonitor/events/transferHealthMonitorEvent.js.map +1 -1
- package/dist/src/client/healthMonitor/onlineChecker/nodeOnlineChecker.js.map +1 -1
- package/dist/src/client/healthMonitor/onlineChecker/onlineChecker.js.map +1 -1
- package/dist/src/client/healthMonitor/onlineChecker/webOnlineChecker.js.map +1 -1
- package/dist/src/client/healthMonitor/transferDownloaderHealthMonitor.js.map +1 -1
- package/dist/src/client/healthMonitor/transferHealthMonitorBase.js.map +1 -1
- package/dist/src/client/healthMonitor/transferUploaderHealthMonitor.js.map +1 -1
- package/dist/src/client/loggers/dummyLogger.js.map +1 -1
- package/dist/src/client/loggers/logger.js.map +1 -1
- package/dist/src/client/loggers/utils/logHealthyStatus.js.map +1 -1
- package/dist/src/client/node/nodeFileDetailsProvider.js.map +1 -1
- package/dist/src/client/uploader/node/nodeTransferUploader.js.map +1 -1
- package/dist/src/client/uploader/transferUploader.js.map +1 -1
- package/dist/src/client/uploader/transferUploaderBase.js.map +1 -1
- package/dist/src/client/uploader/transferUploaderConfig.js.map +1 -1
- package/dist/src/client/uploader/utils/uploaderUtils.js.map +1 -1
- package/dist/src/client/uploader/web/webTransferUploader.js.map +1 -1
- package/dist/src/downloader/api/fileServerDownloadClient.js.map +1 -1
- package/dist/src/downloader/api/node/nodeFileServerDownloadClient.js.map +1 -1
- package/dist/src/downloader/chunkDownloader.js.map +1 -1
- package/dist/src/downloader/downloadFolderResolver.js.map +1 -1
- package/dist/src/downloader/downloadLogger.js.map +1 -1
- package/dist/src/downloader/downloadOptions.js.map +1 -1
- package/dist/src/downloader/downloadStatus/downloadFileChunkProgress.js.map +1 -1
- package/dist/src/downloader/downloadStatus/downloadFileProgress.js.map +1 -1
- package/dist/src/downloader/downloadStatus/downloadFilePromise.js.map +1 -1
- package/dist/src/downloader/downloadStatus/downloadState.js.map +1 -1
- package/dist/src/downloader/downloadTracker.js.map +1 -1
- package/dist/src/downloader/dtos/downloadCommand.js.map +1 -1
- package/dist/src/downloader/dtos/downloadError.js.map +1 -1
- package/dist/src/downloader/dtos/downloadErrorCode.js.map +1 -1
- package/dist/src/downloader/dtos/downloadEvent.js.map +1 -1
- package/dist/src/downloader/dtos/downloadFileChunkInfo.js.map +1 -1
- package/dist/src/downloader/dtos/downloadFileInfo.js.map +1 -1
- package/dist/src/downloader/dtos/downloadFilesCommand.js.map +1 -1
- package/dist/src/downloader/dtos/downloadInfo.js.map +1 -1
- package/dist/src/downloader/dtos/downloadRegistrationMode.js.map +1 -1
- package/dist/src/downloader/dtos/downloadTrackerFileInfo.js.map +1 -1
- package/dist/src/downloader/dtos/downloadTrackerFileProgressInfo.js.map +1 -1
- package/dist/src/downloader/dtos/downloadTrackerProgressInfo.js.map +1 -1
- package/dist/src/downloader/dtos/downloadTrackingMetadata.js.map +1 -1
- package/dist/src/downloader/dtos/downloaderRestoredState.js.map +1 -1
- package/dist/src/downloader/eventArgs/chunkDownloadEventArgs.js.map +1 -1
- package/dist/src/downloader/eventArgs/chunkDownloadFailedEventArgs.js.map +1 -1
- package/dist/src/downloader/eventArgs/downloadCompletedEventArgs.js.map +1 -1
- package/dist/src/downloader/eventArgs/downloadEventArgs.js.map +1 -1
- package/dist/src/downloader/eventArgs/downloadMetadataDeterminedEventArgs.js.map +1 -1
- package/dist/src/downloader/eventArgs/downloadPauseEventArgs.js.map +1 -1
- package/dist/src/downloader/eventArgs/downloadTrackingFailedEventArgs.js.map +1 -1
- package/dist/src/downloader/eventArgs/fileDownloadEventArgs.js.map +1 -1
- package/dist/src/downloader/eventArgs/fileDownloadFailedEventArgs.js.map +1 -1
- package/dist/src/downloader/filesDownloader.js.map +1 -1
- package/dist/src/downloader/filesPreparer.js.map +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/index.node.js.map +1 -1
- package/dist/src/index.web.js.map +1 -1
- package/dist/src/uploader/api/dtos/handshakeRequest.js.map +1 -1
- package/dist/src/uploader/api/dtos/handshakeResponse.js.map +1 -1
- package/dist/src/uploader/api/dtos/pingResponse.js.map +1 -1
- package/dist/src/uploader/api/dtos/sendChunkRequest.js.map +1 -1
- package/dist/src/uploader/api/fileServerUdpClient.js.map +1 -1
- package/dist/src/uploader/api/fileServerUploadClient.js.map +1 -1
- package/dist/src/uploader/api/node/nodeFileServerUdpClient.js +8 -8
- package/dist/src/uploader/api/node/nodeFileServerUdpClient.js.map +1 -1
- package/dist/src/uploader/api/node/nodeFileServerUploadClient.js.map +1 -1
- package/dist/src/uploader/api/web/utils/axiosIdleTimeoutManager.js.map +1 -1
- package/dist/src/uploader/api/web/webFileServerUploadClient.js.map +1 -1
- package/dist/src/uploader/chunkStreamProviderFactory/nodeFileDetailsUploaderChunkStreamProviderFactory.js.map +1 -1
- package/dist/src/uploader/chunkStreamProviderFactory/uploaderChunkStreamProviderFactory.js.map +1 -1
- package/dist/src/uploader/chunkStreamProviderFactory/webFileDetailsUploaderChunkStreamProviderFactory.js.map +1 -1
- package/dist/src/uploader/chunksIterator/chunksIterator.js.map +1 -1
- package/dist/src/uploader/eventArgs/fileChunkUploadCompletedEventArgs.js.map +1 -1
- package/dist/src/uploader/eventArgs/fileChunkUploadCompletedPartiallyEventArgs.js.map +1 -1
- package/dist/src/uploader/eventArgs/fileChunkUploadEventArgs.js.map +1 -1
- package/dist/src/uploader/eventArgs/fileChunkUploadFailedEventArgs.js.map +1 -1
- package/dist/src/uploader/eventArgs/fileChunkUploadProgressedEventArgs.js.map +1 -1
- package/dist/src/uploader/eventArgs/fileUploadEventArgs.js.map +1 -1
- package/dist/src/uploader/eventArgs/fileUploadFailedEventArgs.js.map +1 -1
- package/dist/src/uploader/eventArgs/transferMetadataDeterminedEventArgs.js.map +1 -1
- package/dist/src/uploader/eventArgs/transferUploadCompletedEventArgs.d.ts +7 -0
- package/dist/src/uploader/eventArgs/transferUploadCompletedEventArgs.d.ts.map +1 -1
- package/dist/src/uploader/eventArgs/transferUploadCompletedEventArgs.js.map +1 -1
- package/dist/src/uploader/eventArgs/transferUploadModeChosenEventArgs.js.map +1 -1
- package/dist/src/uploader/eventArgs/transferUploadProgressedEventArgs.js.map +1 -1
- package/dist/src/uploader/export/transferUploadExportData.js.map +1 -1
- package/dist/src/uploader/export/transferUploadExportState.js.map +1 -1
- package/dist/src/uploader/export/transferUploadMetadata.js.map +1 -1
- package/dist/src/uploader/optimizer/optimizationValues.js.map +1 -1
- package/dist/src/uploader/optimizer/strategies/udpConcurrencyBasedOptimizationStrategy.js.map +1 -1
- package/dist/src/uploader/optimizer/strategies/udpSleepBasedOptimizationStrategy.js.map +1 -1
- package/dist/src/uploader/optimizer/transferUploadOptimizationStrategy.js.map +1 -1
- package/dist/src/uploader/optimizer/transferUploadOptimizer.js.map +1 -1
- package/dist/src/uploader/optimizer/uploadOptimizer.js.map +1 -1
- package/dist/src/uploader/options/transferUploadAppendInfo.js.map +1 -1
- package/dist/src/uploader/options/transferUploadConfig.js.map +1 -1
- package/dist/src/uploader/options/transferUploadInfo.js.map +1 -1
- package/dist/src/uploader/options/transferUploadInfoBase.js.map +1 -1
- package/dist/src/uploader/pauseController.js.map +1 -1
- package/dist/src/uploader/state/continuousChunksCalculator.js.map +1 -1
- package/dist/src/uploader/state/readonlyTransferUploadStateFile.js.map +1 -1
- package/dist/src/uploader/state/readonlyTransferUploadStateFiles.js.map +1 -1
- package/dist/src/uploader/state/transferUploadProgressCalculator.js.map +1 -1
- package/dist/src/uploader/state/transferUploadState.d.ts +2 -1
- package/dist/src/uploader/state/transferUploadState.d.ts.map +1 -1
- package/dist/src/uploader/state/transferUploadState.js +9 -2
- package/dist/src/uploader/state/transferUploadState.js.map +1 -1
- package/dist/src/uploader/state/transferUploadStateFile.js.map +1 -1
- package/dist/src/uploader/state/transferUploadStateFiles.js.map +1 -1
- package/dist/src/uploader/transferFailureAbortReason.js.map +1 -1
- package/dist/src/uploader/transferUpload.d.ts.map +1 -1
- package/dist/src/uploader/transferUpload.js +3 -1
- package/dist/src/uploader/transferUpload.js.map +1 -1
- package/dist/src/uploader/transferUploadError.js.map +1 -1
- package/dist/src/uploader/transferUploadEvent.js.map +1 -1
- package/dist/src/utils/api/apiClient.js.map +1 -1
- package/dist/src/utils/api/apiClientBase.js.map +1 -1
- package/dist/src/utils/api/apiError.js.map +1 -1
- package/dist/src/utils/api/apiFilemail449Error.js.map +1 -1
- package/dist/src/utils/api/apiFilemailError.js.map +1 -1
- package/dist/src/utils/api/dtos/baseResponse.js.map +1 -1
- package/dist/src/utils/api/dtos/cancelTransferRequest.js.map +1 -1
- package/dist/src/utils/api/dtos/finalizeTransferRequest.js.map +1 -1
- package/dist/src/utils/api/dtos/finalizeTransferResponse.d.ts +13 -0
- package/dist/src/utils/api/dtos/finalizeTransferResponse.d.ts.map +1 -1
- package/dist/src/utils/api/dtos/finalizeTransferResponse.js.map +1 -1
- package/dist/src/utils/api/dtos/getCompanyResponse.js.map +1 -1
- package/dist/src/utils/api/dtos/getCompressedFileMetadataResponse.js.map +1 -1
- package/dist/src/utils/api/dtos/getInboxTransfersRequest.js.map +1 -1
- package/dist/src/utils/api/dtos/getInboxTransfersResponse.js.map +1 -1
- package/dist/src/utils/api/dtos/getRangehashResponse.js.map +1 -1
- package/dist/src/utils/api/dtos/getTransferRequest.js.map +1 -1
- package/dist/src/utils/api/dtos/getTransferResponse.js.map +1 -1
- package/dist/src/utils/api/dtos/initializeTransferRequest.js.map +1 -1
- package/dist/src/utils/api/dtos/initializeTransferResponse.js.map +1 -1
- package/dist/src/utils/api/dtos/loginRequest.js.map +1 -1
- package/dist/src/utils/api/dtos/loginResponse.js.map +1 -1
- package/dist/src/utils/api/dtos/registerFileDownloadRequest.js.map +1 -1
- package/dist/src/utils/api/dtos/registerTransferDownloadRequest.js.map +1 -1
- package/dist/src/utils/api/dtos/resetTransferRequest.js.map +1 -1
- package/dist/src/utils/api/dtos/sendFileChunkRequest.js.map +1 -1
- package/dist/src/utils/api/dtos/transferCustomFieldDto.js.map +1 -1
- package/dist/src/utils/api/dtos/transferFileDto.js.map +1 -1
- package/dist/src/utils/api/fileServerClientFactory.js.map +1 -1
- package/dist/src/utils/api/node/gotWorkarounds.js.map +1 -1
- package/dist/src/utils/api/node/nodeApiClient.d.ts.map +1 -1
- package/dist/src/utils/api/node/nodeApiClient.js +4 -0
- package/dist/src/utils/api/node/nodeApiClient.js.map +1 -1
- package/dist/src/utils/api/node/nodeClientBase.js.map +1 -1
- package/dist/src/utils/api/node/nodeFileServerClientFactory.js.map +1 -1
- package/dist/src/utils/api/node/nodeFileserverClientBase.js.map +1 -1
- package/dist/src/utils/api/urlUtil.js.map +1 -1
- package/dist/src/utils/api/web/webApiClient.d.ts.map +1 -1
- package/dist/src/utils/api/web/webApiClient.js +4 -0
- package/dist/src/utils/api/web/webApiClient.js.map +1 -1
- package/dist/src/utils/api/web/webClientBase.js.map +1 -1
- package/dist/src/utils/api/web/webFileServerClientFactory.js.map +1 -1
- package/dist/src/utils/api/web/webFileserverClientBase.js.map +1 -1
- package/dist/src/utils/concurrencyController/concurrencyController.js.map +1 -1
- package/dist/src/utils/concurrencyController/concurrencyReleaser.js.map +1 -1
- package/dist/src/utils/concurrencyController/transferConcurrencyController.js.map +1 -1
- package/dist/src/utils/crypto/cryptographyProvider.js.map +1 -1
- package/dist/src/utils/crypto/node/nodeCryptographyProvider.js.map +1 -1
- package/dist/src/utils/crypto/web/webCryptographyProvider.js.map +1 -1
- package/dist/src/utils/dateAndTime/simpleDateFormatter.js.map +1 -1
- package/dist/src/utils/events/chunkProgressEvent.js.map +1 -1
- package/dist/src/utils/events/eventsEngine.js.map +1 -1
- package/dist/src/utils/events/node/nodeEventsEngine.js.map +1 -1
- package/dist/src/utils/events/web/webEventsEngine.js.map +1 -1
- package/dist/src/utils/fileSystem/chunkStreamProvider.js.map +1 -1
- package/dist/src/utils/fileSystem/chunkStreamProviderFactory.js.map +1 -1
- package/dist/src/utils/fileSystem/fileDetails.js.map +1 -1
- package/dist/src/utils/fileSystem/fileSystemService.js.map +1 -1
- package/dist/src/utils/fileSystem/fsError.js.map +1 -1
- package/dist/src/utils/fileSystem/node/nodeChunkStreamProvider.js.map +1 -1
- package/dist/src/utils/fileSystem/node/nodeChunkStreamProviderFactory.js.map +1 -1
- package/dist/src/utils/fileSystem/node/nodeFileDetails.js.map +1 -1
- package/dist/src/utils/fileSystem/node/nodeFileSystemService.js.map +1 -1
- package/dist/src/utils/fileSystem/parsedPath.js.map +1 -1
- package/dist/src/utils/fileSystem/web/chunkStreamProvider/webChunkStreamEncrypter.js.map +1 -1
- package/dist/src/utils/fileSystem/web/chunkStreamProvider/webChunkStreamProvider.js.map +1 -1
- package/dist/src/utils/fileSystem/web/webChunkStreamProviderFactory.js.map +1 -1
- package/dist/src/utils/fileSystem/web/webFileDetails.js.map +1 -1
- package/dist/src/utils/jsonParsing.js.map +1 -1
- package/dist/src/utils/logging/logEventPropertyNames.js.map +1 -1
- package/dist/src/utils/mergeAbortAndPauseSignals.js.map +1 -1
- package/dist/src/utils/networking/throttlingOptions.js.map +1 -1
- package/dist/src/utils/promiseAll.js.map +1 -1
- package/dist/src/utils/types/transferStatus.js.map +1 -1
- package/dist/src/utils/uint8ArrayUtils.js.map +1 -1
- package/package.json +79 -79
- package/readme.md +18 -18
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filesDownloader.js","sourceRoot":"","sources":["../../../src/downloader/filesDownloader.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-await-in-loop */\r\nimport DownloadState from \"./downloadStatus/downloadState.js\";\r\nimport DownloadFilePromise from \"./downloadStatus/downloadFilePromise.js\";\r\nimport DownloadFileInfo from \"./dtos/downloadFileInfo.js\";\r\nimport DownloadFileProgress from \"./downloadStatus/downloadFileProgress.js\";\r\nimport DownloadError from \"./dtos/downloadError.js\";\r\nimport TransferDownloadEvent from \"./dtos/downloadEvent.js\";\r\nimport ChunkDownloader from \"./chunkDownloader.js\";\r\nimport TransferStatus from \"../utils/types/transferStatus.js\";\r\nimport DownloadErrorCode from \"./dtos/downloadErrorCode.js\";\r\nimport DownloadRegistrationMode from \"./dtos/downloadRegistrationMode.js\";\r\nimport { promiseAllSettled } from \"../utils/promiseAll.js\";\r\n\r\nimport type FileSystemService from \"../utils/fileSystem/fileSystemService.js\";\r\nimport type DownloadOptions from \"./downloadOptions.js\";\r\nimport type ConcurrencyController from \"../utils/concurrencyController/concurrencyController.js\";\r\nimport type DownloaderRestoredState from \"./dtos/downloaderRestoredState.js\";\r\nimport type FileServerClientFactory from \"../utils/api/fileServerClientFactory.js\";\r\nimport type ChunkStreamProviderFactory from \"../utils/fileSystem/chunkStreamProviderFactory.js\";\r\nimport type EventsEngine from \"../utils/events/eventsEngine.js\";\r\nimport type DownloadEventArgs from \"./eventArgs/downloadEventArgs.js\";\r\nimport type ApiClient from \"../utils/api/apiClient.js\";\r\nimport type FileDownloadEventArgs from \"./eventArgs/fileDownloadEventArgs.js\";\r\nimport type FileDownloadFailedEventArgs from \"./eventArgs/fileDownloadFailedEventArgs.js\";\r\nimport type DownloadFileChunkInfo from \"./dtos/downloadFileChunkInfo.js\";\r\nimport type DownloadLogger from \"./downloadLogger.js\";\r\nimport type { ChunkStreamProviderEncryptionData } from \"../utils/fileSystem/chunkStreamProvider.js\";\r\nimport type { DownloadCommandE2eeData } from \"./dtos/downloadCommand.js\";\r\nimport type CryptographyProvider from \"../utils/crypto/cryptographyProvider.js\";\r\n\r\nexport default class FilesDownloader {\r\n readonly #logger: DownloadLogger;\r\n readonly #transferId: string;\r\n readonly #trackId: string | undefined;\r\n readonly #downloadId: string;\r\n readonly #region?: string;\r\n readonly #files: Array<DownloadFileInfo>;\r\n readonly #downloadState: DownloadState;\r\n readonly #options: DownloadOptions;\r\n readonly #concurrencyController: ConcurrencyController;\r\n readonly #fileSystem: FileSystemService;\r\n readonly #apiClient: ApiClient;\r\n readonly #fileserverClientFactory: FileServerClientFactory;\r\n readonly #chunkStreamProviderFactory: ChunkStreamProviderFactory<string>;\r\n readonly #downloadRegistrationMode: DownloadRegistrationMode;\r\n readonly #eventsEngine: EventsEngine;\r\n readonly #cryptography: CryptographyProvider;\r\n readonly #ongoingChunkDownloads: Record<string, Promise<void>>;\r\n readonly #ongoingFileDownloads: Record<string, DownloadFilePromise>;\r\n readonly #encryptionData?: ChunkStreamProviderEncryptionData;\r\n\r\n constructor(\r\n logger: DownloadLogger,\r\n transferId: string,\r\n trackId: string | undefined,\r\n downloadId: string,\r\n region: string | undefined,\r\n files: DownloadFileInfo | Array<DownloadFileInfo>,\r\n oldState: DownloaderRestoredState | undefined,\r\n fileSystem: FileSystemService,\r\n concurrencyController: ConcurrencyController,\r\n eventsEngine: EventsEngine,\r\n cryptography: CryptographyProvider,\r\n options: DownloadOptions,\r\n apiClient: ApiClient,\r\n fileserverClientFactory: FileServerClientFactory,\r\n chunkStreamProviderFactory: ChunkStreamProviderFactory<string>,\r\n downloadRegistrationMode: DownloadRegistrationMode,\r\n e2eeData?: DownloadCommandE2eeData,\r\n ) {\r\n if (!transferId)\r\n throw new DownloadError(`No transfer specified`);\r\n\r\n if (!files)\r\n throw new DownloadError(`No files added to downloader`);\r\n\r\n if (Array.isArray(files) && files.length === 0)\r\n throw new DownloadError(`No files added to downloader`);\r\n\r\n if (!options.downloadFolder)\r\n throw new DownloadError(`No downloadFolder specified`);\r\n\r\n if (e2eeData && e2eeData.iv.length !== 16)\r\n throw new DownloadError(`IV must be 16 bytes long`);\r\n\r\n if (e2eeData && e2eeData.key.length !== 32)\r\n throw new DownloadError(`Encryption key must be 32 bytes long`);\r\n\r\n this.#logger = logger;\r\n this.#downloadId = downloadId;\r\n this.#transferId = transferId;\r\n this.#trackId = trackId;\r\n this.#region = region;\r\n this.#fileSystem = fileSystem;\r\n this.#files = Array.isArray(files) ? files : [files];\r\n this.#options = options;\r\n this.#eventsEngine = eventsEngine;\r\n this.#cryptography = cryptography;\r\n this.#downloadState = new DownloadState(this.#downloadId, this.#transferId, this.#files, this.#options, eventsEngine, oldState);\r\n this.#concurrencyController = concurrencyController;\r\n this.#apiClient = apiClient;\r\n this.#fileserverClientFactory = fileserverClientFactory;\r\n this.#chunkStreamProviderFactory = chunkStreamProviderFactory;\r\n this.#downloadRegistrationMode = downloadRegistrationMode;\r\n this.#ongoingChunkDownloads = {};\r\n this.#ongoingFileDownloads = {};\r\n\r\n if (e2eeData)\r\n this.#encryptionData = this.createEncryptionData(e2eeData);\r\n }\r\n\r\n private createEncryptionData(e2eeData: DownloadCommandE2eeData): ChunkStreamProviderEncryptionData {\r\n return {\r\n iv: e2eeData.iv,\r\n key: e2eeData.key,\r\n };\r\n }\r\n\r\n async start(): Promise<DownloadEventArgs> {\r\n try {\r\n await this.#throwIfNotEnoughDiskSpaceBeforeStart();\r\n\r\n this.#addEventListeners();\r\n\r\n let isDownloaderRunning = true;\r\n\r\n while (isDownloaderRunning) {\r\n this.#downloadState.start();\r\n\r\n const fileServerUrl = new URL(this.#files[0].url).origin;\r\n this.#downloadState.notifyMetadataDetermined(fileServerUrl, this.#region);\r\n\r\n // MAIN FILE LOOP\r\n for (const file of this.#files) {\r\n if (file.isCompleted || file.isFailed)\r\n continue;\r\n\r\n if (this.#downloadState.isRunning === false)\r\n break;\r\n\r\n // figure out if we are downloading a new file or resuming a file that was interrupted\r\n if (file.wasEverWritten) {\r\n // this a resumed file (recreated from progress.json) - it must already exist under its temporary path\r\n if (!file.temporaryDownloadPath) {\r\n this.#downloadState.fileFailed(file, new DownloadError(`File ${file.downloadPath} was supposed to be resumed but its temporary path is not known.`, undefined, DownloadErrorCode.ResumedFilePathNotSpecified));\r\n continue;\r\n }\r\n\r\n if ((await this.#fileSystem.pathExists(file.temporaryDownloadPath!)) === false) {\r\n this.#downloadState.fileFailed(file, new DownloadError(`File ${file.downloadPath} was supposed to be resumed at ${file.temporaryDownloadPath}, but it does not exist on disk anymore.`, undefined, DownloadErrorCode.ResumedFileNotFound));\r\n continue;\r\n }\r\n }\r\n else {\r\n // in some edge cases the temporary file may exist and its name be persisted in the tracker file\r\n // but the wasEverWritten flag was not yet set - just abandon such temporary file (it will be 'empty' - null bytes only)\r\n if (file.temporaryDownloadPath) {\r\n this.#logDeletingFile(file, file.temporaryDownloadPath, `start`);\r\n this.#fileSystem.deleteFile(file.temporaryDownloadPath);\r\n }\r\n\r\n // this is a new file - create it\r\n await this.#createDownloadFile(file);\r\n }\r\n\r\n this.#ongoingFileDownloads[file.externalId] = new DownloadFilePromise(file.externalId);\r\n this.#ongoingFileDownloads[file.externalId]!.awaiter.then(id => {\r\n delete this.#ongoingFileDownloads[id];\r\n });\r\n\r\n this.#downloadState.fileStarting(file);\r\n\r\n // note: this call does not really wait for all chunks to be downloaded, but until all chunks of a file have been **scheduled**\r\n await this.#downloadAllChunksForFile(file);\r\n\r\n // so when we are here, the file is not complete\r\n // to track completeness of a file we look at events emitted by this.#downloadState\r\n }\r\n\r\n // when we got here it's either pause request, stop request (which is just like pause but without waiting for pending chunks), abort request (cancel the download entirely) or everything is complete;\r\n\r\n // wait for any remaining pending chunks\r\n await promiseAllSettled(Object.values(this.#ongoingChunkDownloads));\r\n\r\n // Wait for any remaining pending files\r\n // Note: we cannot rely just on chunk downloads being completed, because downloading chunks\r\n // doesn't mean that a file is complete; last phase of file completion is renaming the file\r\n // from a temporary name (unconfirmed_somefile.txt_qweasd1234.fmdownload) to its real name, which may need adjustments if a file with same name already exists.\r\n // When file already exists - a unique filename will be generated automatically e.g.: file.txt --> file (1).txt\r\n await promiseAllSettled(Object.values(this.#ongoingFileDownloads).map(x => x.awaiter));\r\n\r\n if (this.#downloadState.status === TransferStatus.Pausing) {\r\n // set status to paused and await until resume/abort\r\n await this.#downloadState.paused();\r\n }\r\n\r\n isDownloaderRunning = await this.#prepareDownloaderForAnotherIteration();\r\n }\r\n\r\n await this.#cleanupEmptyDownloadFolderIfConfigured();\r\n }\r\n catch (error) {\r\n this.#logger.logError(error as Error, `Unhandled downloader error occured.`);\r\n this.#downloadState.completed(error as Error);\r\n }\r\n finally {\r\n this.#removeEventListeners();\r\n }\r\n\r\n return this.#downloadState.getCurrentState(true);\r\n }\r\n\r\n async #throwIfNotEnoughDiskSpaceBeforeStart() {\r\n await this.#fileSystem.createFolder(this.#options.downloadFolder!);\r\n\r\n const requiredBytes = this.#getRemainingBytesToDownload();\r\n\r\n if (requiredBytes <= 0n)\r\n return;\r\n\r\n try {\r\n const availableBytes = await this.#fileSystem.getAvailableDiskSpace(this.#options.downloadFolder!);\r\n\r\n if (availableBytes < requiredBytes)\r\n throw new DownloadError(`ENOSPC: Not enough disk space. Required=${requiredBytes}B, available=${availableBytes}B`, undefined, DownloadErrorCode.DiskFull);\r\n }\r\n catch (error) {\r\n if (this.#shouldSkipFreeDiskSpaceCheck(error)) {\r\n this.#logger.logWarning(`Skipping free disk space check because filesystem does not support statfs`, { error });\r\n return;\r\n }\r\n\r\n throw this.#toDownloadError(error, `Checking free disk space before download failed for ${this.#options.downloadFolder!}`);\r\n }\r\n }\r\n\r\n #getRemainingBytesToDownload(): bigint {\r\n let requiredBytes = 0n;\r\n\r\n for (const file of this.#files) {\r\n if (file.isCompleted || file.isFailed)\r\n continue;\r\n\r\n const remaining = file.sizeInBytes - file.downloadedBytes;\r\n requiredBytes += BigInt(remaining);\r\n }\r\n\r\n return requiredBytes;\r\n }\r\n\r\n #shouldSkipFreeDiskSpaceCheck(error: unknown): boolean {\r\n const code = this.#extractErrorCode(error);\r\n if (code === `ENOSYS` || code === `ENOTSUP` || code === `EOPNOTSUPP`)\r\n return true;\r\n\r\n const message = this.#extractErrorMessage(error)?.toLowerCase() ?? ``;\r\n if (code === `ENOENT` && message.includes(`statfs`))\r\n return true;\r\n\r\n return false;\r\n }\r\n\r\n #extractErrorCode(error: unknown): string | undefined {\r\n let current = error as { code?: string, cause?: unknown } | undefined;\r\n\r\n for (let depth = 0; depth < 8 && current; depth++) {\r\n if (typeof current.code === `string`)\r\n return current.code;\r\n\r\n current = current.cause as { code?: string, cause?: unknown } | undefined;\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n #extractErrorMessage(error: unknown): string | undefined {\r\n let current = error as { message?: string, cause?: unknown } | undefined;\r\n\r\n for (let depth = 0; depth < 8 && current; depth++) {\r\n if (typeof current.message === `string`)\r\n return current.message;\r\n\r\n current = current.cause as { message?: string, cause?: unknown } | undefined;\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n #logDeletingFile(file: DownloadFileInfo | DownloadFileProgress, path: string, method: string) {\r\n let fileDataToLog = file;\r\n if (file instanceof DownloadFileInfo)\r\n fileDataToLog = DownloadFileProgress.FromFileDownloadInfo(file);\r\n\r\n this.#logger.logInfo(`[DELETE_TEMPFILE] Deleting temp file path=${path} method=${method}\\n\\n${JSON.stringify(fileDataToLog, null, 4)}\\n`);\r\n }\r\n\r\n requestPause(options: { interruptPendingChunks: boolean, pausedTrigger?: (paused: boolean) => void }): void {\r\n Object.values(this.#ongoingFileDownloads).forEach(filePromise => filePromise.complete());\r\n this.#downloadState.requestPause(options);\r\n }\r\n\r\n resume(): boolean {\r\n return this.#downloadState.resume();\r\n }\r\n\r\n requestAbort(): boolean {\r\n Object.values(this.#ongoingFileDownloads).forEach(filePromise => filePromise.complete());\r\n return this.#downloadState.requestAbort();\r\n }\r\n\r\n getCurrentState(withFiles: boolean): DownloadEventArgs {\r\n return this.#downloadState.getCurrentState(withFiles);\r\n }\r\n\r\n get status(): TransferStatus {\r\n return this.#downloadState.status;\r\n }\r\n\r\n async #deleteAllTemporaryAndCompletedFiles() {\r\n for (const file of this.#files) {\r\n if (file.temporaryDownloadPath) {\r\n this.#logDeletingFile(file, file.temporaryDownloadPath, `deleteAllTemporaryAndCompletedFiles`);\r\n await this.#fileSystem.deleteFile(file.temporaryDownloadPath);\r\n }\r\n\r\n if (file.isCompleted)\r\n await this.#fileSystem.deleteFile(file.downloadPath);\r\n }\r\n }\r\n\r\n async #registerTransferDownload() {\r\n this.#downloadState.registeringTransferDownload();\r\n await this.#apiClient.registerTransferDownload({\r\n transferid: this.#transferId,\r\n track: this.#trackId,\r\n bps: this.#downloadState.averageBytesPerSecond,\r\n browser: this.#options.userAgent,\r\n });\r\n }\r\n\r\n async #registerFileDownload(filename: string, filesize: number) {\r\n this.#downloadState.registeringFileDownload();\r\n await this.#apiClient.registerFileDownload({\r\n transferid: this.#transferId,\r\n track: this.#trackId,\r\n bps: this.#downloadState.averageBytesPerSecond,\r\n browser: this.#options.userAgent,\r\n filename,\r\n filesize,\r\n });\r\n }\r\n\r\n #addEventListeners() {\r\n this.#eventsEngine.addEventListener(TransferDownloadEvent.FileDownloadCompleted, this.#onFileCompleted);\r\n this.#eventsEngine.addEventListener(TransferDownloadEvent.FileDownloadCompleting, this.#onFileCompleting);\r\n this.#eventsEngine.addEventListener(TransferDownloadEvent.FileDownloadFailed, this.#onFileFailed);\r\n this.#eventsEngine.addEventListener(TransferDownloadEvent.PossibleSupersizedFile, this.#onFileSupersized);\r\n }\r\n\r\n #removeEventListeners() {\r\n this.#eventsEngine.removeEventListener(TransferDownloadEvent.FileDownloadCompleted, this.#onFileCompleted);\r\n this.#eventsEngine.removeEventListener(TransferDownloadEvent.FileDownloadCompleting, this.#onFileCompleting);\r\n this.#eventsEngine.removeEventListener(TransferDownloadEvent.FileDownloadFailed, this.#onFileFailed);\r\n this.#eventsEngine.removeEventListener(TransferDownloadEvent.PossibleSupersizedFile, this.#onFileSupersized);\r\n }\r\n\r\n #onFileCompleted = async (args: FileDownloadEventArgs) => {\r\n if (this.#downloadRegistrationMode === DownloadRegistrationMode.EverySingleFile && !this.#options.skipRegistration)\r\n await this.#registerFileDownload(args.file.name, args.file.size);\r\n\r\n this.#ongoingFileDownloads[args.file.id]?.complete();\r\n };\r\n\r\n #onFileCompleting = async (args: FileDownloadEventArgs) => {\r\n // note the args.file.downloadPath may not be final - if a file with this name eixsts the following method will generate new name e.g. \"file.txt\" --> \"file (1).txt\"\r\n try {\r\n const finalDownloadPath = await this.#doTheFinalFileRenameAfterFilesIsDownloaded(args.file);\r\n this.#downloadState.fileCompleted(args.file.id, finalDownloadPath);\r\n }\r\n catch (error) {\r\n this.#downloadState.fileFailedById(args.file.id, error as DownloadError);\r\n }\r\n };\r\n\r\n #onFileSupersized = async (fileArgs: FileDownloadEventArgs) => {\r\n if (fileArgs.file.temporaryDownloadPath && await this.#fileSystem.getFileSize(fileArgs.file.temporaryDownloadPath) > fileArgs.file.size)\r\n await this.#fileSystem.truncateFile(fileArgs.file.temporaryDownloadPath, fileArgs.file.size);\r\n };\r\n\r\n #onFileFailed = async (args: FileDownloadFailedEventArgs) => {\r\n this.#ongoingFileDownloads[args.file.id]?.complete();\r\n\r\n const shouldKeepTemporaryFile = this.#shouldKeepTemporaryFileOnFailure();\r\n\r\n if (this.#options.deleteFailedFilesFromDisk) {\r\n if (args.file.temporaryDownloadPath && !shouldKeepTemporaryFile) {\r\n this.#logDeletingFile(args.file, args.file.temporaryDownloadPath, `onFileFailed`);\r\n await this.#fileSystem.deleteFile(args.file.temporaryDownloadPath);\r\n }\r\n }\r\n };\r\n\r\n #shouldKeepTemporaryFileOnFailure(): boolean {\r\n // Resuming failed files requires tracking state + preserved temporary files.\r\n // If tracking is disabled there is no benefit in leaving temp files behind.\r\n return this.#options.downloadTrackingBaseFolder !== null;\r\n }\r\n\r\n async #createDownloadFile(file: DownloadFileInfo) {\r\n this.#downloadState.fileCreating(file);\r\n\r\n try {\r\n await this.#autoGenerateUniqueDownloadFile(file);\r\n this.#downloadState.fileCreated(file);\r\n }\r\n catch (error) {\r\n throw this.#toDownloadError(error, `Creating download file failed for ${file.downloadPath}`);\r\n }\r\n }\r\n\r\n async #autoGenerateUniqueDownloadFile(file: DownloadFileInfo) {\r\n let counter = 0;\r\n const fileLeafName = this.#fileSystem.parseFilePath(file.name).base;\r\n do {\r\n const newFileName = `unconfirmed_${fileLeafName}_${this.#cryptography.generateRandomString(10)}.fmdownload`;\r\n const newPath = this.#fileSystem.replaceFilenameInPath(file.downloadPath, newFileName);\r\n if (await this.#fileSystem.createFile(newPath, false)) {\r\n // eslint-disable-next-line no-param-reassign\r\n file.temporaryDownloadPath = newPath;\r\n return;\r\n }\r\n\r\n counter += 1;\r\n } while (counter < 10000);\r\n\r\n throw new DownloadError(`Downloader could not generate unique download path for ${file.downloadPath}. It tried until counter=${counter}`, undefined, DownloadErrorCode.TooManyFileRenameAttempts);\r\n }\r\n\r\n #toDownloadError(error: unknown, message: string): DownloadError {\r\n if (error instanceof DownloadError)\r\n return error;\r\n\r\n const wrappedError = error instanceof Error\r\n ? error\r\n : new Error(`${error}`);\r\n\r\n const code = this.#fileSystem.fileErrorToDownloadErrorCode(wrappedError);\r\n return new DownloadError(message, { cause: wrappedError }, code);\r\n }\r\n\r\n async #downloadAllChunksForFile(file: DownloadFileInfo) {\r\n if (file.chunks.length) {\r\n // MAIN CHUNK LOOP\r\n for (const chunk of file.chunks) {\r\n if (chunk.isCompleted || chunk.isFailed)\r\n continue;\r\n\r\n const downloadScheduled = await this.#downloadSingleChunk(file, chunk);\r\n if (downloadScheduled === false) {\r\n // downloader is not running or file is in failed state - stop the chunk loop\r\n break;\r\n }\r\n }\r\n\r\n // Restored files can have all chunks already completed (e.g. rename failed in a previous run).\r\n // In such case there is nothing to schedule, so we need to trigger finalization explicitly.\r\n if (!file.isFailed && file.chunks.every(chunk => chunk.isCompleted)) {\r\n this.#downloadState.ensureFileStarted(file);\r\n file.updateProgress();\r\n this.#downloadState.fileCompleting(file);\r\n }\r\n }\r\n else {\r\n // zerobyte file\r\n file.updateProgress();\r\n this.#downloadState.fileCompleting(file);\r\n }\r\n }\r\n\r\n async #downloadSingleChunk(file: DownloadFileInfo, chunk: DownloadFileChunkInfo): Promise<boolean> {\r\n const releaseSemaphore = await this.#concurrencyController.acquire();\r\n\r\n if (this.#downloadState.isRunning === false) {\r\n // downloader is not running - stop trying more chunks\r\n releaseSemaphore();\r\n return false;\r\n }\r\n\r\n if (file.isFailed) {\r\n // do not try to download more chunks if the file has failed\r\n releaseSemaphore();\r\n return false;\r\n }\r\n\r\n const chunkDownloader = new ChunkDownloader(this.#transferId, file, chunk, this.#downloadState, this.#options, this.#fileserverClientFactory, this.#chunkStreamProviderFactory, this.#eventsEngine, this.#logger, this.#encryptionData);\r\n const chunkPromise: Promise<void> = chunkDownloader.download();\r\n this.#ongoingChunkDownloads[chunk.id] = chunkPromise;\r\n\r\n chunkPromise.finally(() => {\r\n releaseSemaphore();\r\n delete this.#ongoingChunkDownloads[chunk.id];\r\n });\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Prepares downloader for next loop iteration. Handles two main scenarios:\r\n * 1. Aborting - cleans up the disk state, calls downloadState to trigger Aborted event and returns a false flag (to break the loop).\r\n * 2. Completed - registers download to web api, calls downloadState to trigger Completed event and returns a false flag (to break the loop).\r\n * 3. For all other cases returns true - to continue the loop.\r\n */\r\n async #prepareDownloaderForAnotherIteration(): Promise<boolean> {\r\n let shouldDownloaderContinue = true;\r\n if (this.#downloadState.status === TransferStatus.Aborting) {\r\n shouldDownloaderContinue = false;\r\n if (this.#options.deleteAbortedDownloadsFromDisk)\r\n await this.#deleteAllTemporaryAndCompletedFiles();\r\n\r\n this.#downloadState.aborted();\r\n }\r\n else if (this.#downloadState.allFilesCompletedOrFailed) {\r\n shouldDownloaderContinue = false;\r\n if (this.#downloadRegistrationMode === DownloadRegistrationMode.Transfer && !this.#options.skipRegistration)\r\n await this.#registerTransferDownload();\r\n\r\n this.#downloadState.completed();\r\n }\r\n return shouldDownloaderContinue;\r\n }\r\n\r\n async #cleanupEmptyDownloadFolderIfConfigured() {\r\n try {\r\n if (this.#options.deleteEmptyDownloadFoldersAfterDownload && await this.#fileSystem.folderIsEmpty(this.#options.downloadFolder!))\r\n await this.#fileSystem.deleteFolder(this.#options.downloadFolder!);\r\n }\r\n catch (error) {\r\n this.#logger.logWarning(`cleanupEmptyDownloadFolderIfConfigured failed`, { error });\r\n }\r\n }\r\n\r\n async #doTheFinalFileRenameAfterFilesIsDownloaded(file: DownloadFileProgress) {\r\n let created = false;\r\n let createCounter = 0;\r\n const original = this.#fileSystem.parseFilePath(file.downloadPath);\r\n let newPathFormatted = file.downloadPath;\r\n do {\r\n // we do not want to re-reserve disk space when creating the target file (final name) - so file size is omitted\r\n created = await this.#fileSystem.createFile(newPathFormatted, false);\r\n if (!created) {\r\n createCounter += 1;\r\n const newPath = {\r\n dir: original.dir,\r\n name: `${original.name} (${createCounter})`,\r\n ext: original.ext,\r\n };\r\n newPathFormatted = this.#fileSystem.formatFilePath(newPath);\r\n }\r\n } while (created === false && createCounter < 10000);\r\n\r\n if (!created)\r\n throw new DownloadError(`Downloader could not rename temp file ${file.temporaryDownloadPath} to ${file.downloadPath}. It tried until counter=${createCounter}`, undefined, DownloadErrorCode.TooManyFileRenameAttempts);\r\n\r\n let renamed = false;\r\n let renameCounter = 0;\r\n let lastError: Error | undefined;\r\n while (!renamed && renameCounter < 5) {\r\n renameCounter += 1;\r\n try {\r\n await this.#fileSystem.renameFile(file.temporaryDownloadPath!, newPathFormatted);\r\n renamed = true;\r\n this.#logger.logInfo(`Downloader renamed ${file.temporaryDownloadPath} to ${newPathFormatted} at attempt ${renameCounter}`);\r\n }\r\n catch (error) {\r\n lastError = error as Error;\r\n this.#logger.logError(lastError, `Downloader could not rename ${file.temporaryDownloadPath} to ${newPathFormatted} attempt ${renameCounter}`);\r\n }\r\n }\r\n if (!renamed)\r\n await this.#cleanupFailedRenameTarget(newPathFormatted);\r\n\r\n if (!renamed)\r\n throw new DownloadError(`Downloader could not rename ${file.temporaryDownloadPath} to ${newPathFormatted} after ${renameCounter} attempts.`, { cause: lastError }, DownloadErrorCode.RenameFromTemporaryFilenameToFinalFailure);\r\n else\r\n return newPathFormatted;\r\n }\r\n\r\n async #cleanupFailedRenameTarget(pathToDelete: string) {\r\n try {\r\n await this.#fileSystem.deleteFile(pathToDelete);\r\n }\r\n catch (error) {\r\n this.#logger.logWarning(`Could not cleanup failed rename target ${pathToDelete}`, { error });\r\n }\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"filesDownloader.js","sourceRoot":"","sources":["../../../src/downloader/filesDownloader.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-await-in-loop */\nimport DownloadState from \"./downloadStatus/downloadState.js\";\nimport DownloadFilePromise from \"./downloadStatus/downloadFilePromise.js\";\nimport DownloadFileInfo from \"./dtos/downloadFileInfo.js\";\nimport DownloadFileProgress from \"./downloadStatus/downloadFileProgress.js\";\nimport DownloadError from \"./dtos/downloadError.js\";\nimport TransferDownloadEvent from \"./dtos/downloadEvent.js\";\nimport ChunkDownloader from \"./chunkDownloader.js\";\nimport TransferStatus from \"../utils/types/transferStatus.js\";\nimport DownloadErrorCode from \"./dtos/downloadErrorCode.js\";\nimport DownloadRegistrationMode from \"./dtos/downloadRegistrationMode.js\";\nimport { promiseAllSettled } from \"../utils/promiseAll.js\";\n\nimport type FileSystemService from \"../utils/fileSystem/fileSystemService.js\";\nimport type DownloadOptions from \"./downloadOptions.js\";\nimport type ConcurrencyController from \"../utils/concurrencyController/concurrencyController.js\";\nimport type DownloaderRestoredState from \"./dtos/downloaderRestoredState.js\";\nimport type FileServerClientFactory from \"../utils/api/fileServerClientFactory.js\";\nimport type ChunkStreamProviderFactory from \"../utils/fileSystem/chunkStreamProviderFactory.js\";\nimport type EventsEngine from \"../utils/events/eventsEngine.js\";\nimport type DownloadEventArgs from \"./eventArgs/downloadEventArgs.js\";\nimport type ApiClient from \"../utils/api/apiClient.js\";\nimport type FileDownloadEventArgs from \"./eventArgs/fileDownloadEventArgs.js\";\nimport type FileDownloadFailedEventArgs from \"./eventArgs/fileDownloadFailedEventArgs.js\";\nimport type DownloadFileChunkInfo from \"./dtos/downloadFileChunkInfo.js\";\nimport type DownloadLogger from \"./downloadLogger.js\";\nimport type { ChunkStreamProviderEncryptionData } from \"../utils/fileSystem/chunkStreamProvider.js\";\nimport type { DownloadCommandE2eeData } from \"./dtos/downloadCommand.js\";\nimport type CryptographyProvider from \"../utils/crypto/cryptographyProvider.js\";\n\nexport default class FilesDownloader {\n readonly #logger: DownloadLogger;\n readonly #transferId: string;\n readonly #trackId: string | undefined;\n readonly #downloadId: string;\n readonly #region?: string;\n readonly #files: Array<DownloadFileInfo>;\n readonly #downloadState: DownloadState;\n readonly #options: DownloadOptions;\n readonly #concurrencyController: ConcurrencyController;\n readonly #fileSystem: FileSystemService;\n readonly #apiClient: ApiClient;\n readonly #fileserverClientFactory: FileServerClientFactory;\n readonly #chunkStreamProviderFactory: ChunkStreamProviderFactory<string>;\n readonly #downloadRegistrationMode: DownloadRegistrationMode;\n readonly #eventsEngine: EventsEngine;\n readonly #cryptography: CryptographyProvider;\n readonly #ongoingChunkDownloads: Record<string, Promise<void>>;\n readonly #ongoingFileDownloads: Record<string, DownloadFilePromise>;\n readonly #encryptionData?: ChunkStreamProviderEncryptionData;\n\n constructor(\n logger: DownloadLogger,\n transferId: string,\n trackId: string | undefined,\n downloadId: string,\n region: string | undefined,\n files: DownloadFileInfo | Array<DownloadFileInfo>,\n oldState: DownloaderRestoredState | undefined,\n fileSystem: FileSystemService,\n concurrencyController: ConcurrencyController,\n eventsEngine: EventsEngine,\n cryptography: CryptographyProvider,\n options: DownloadOptions,\n apiClient: ApiClient,\n fileserverClientFactory: FileServerClientFactory,\n chunkStreamProviderFactory: ChunkStreamProviderFactory<string>,\n downloadRegistrationMode: DownloadRegistrationMode,\n e2eeData?: DownloadCommandE2eeData,\n ) {\n if (!transferId)\n throw new DownloadError(`No transfer specified`);\n\n if (!files)\n throw new DownloadError(`No files added to downloader`);\n\n if (Array.isArray(files) && files.length === 0)\n throw new DownloadError(`No files added to downloader`);\n\n if (!options.downloadFolder)\n throw new DownloadError(`No downloadFolder specified`);\n\n if (e2eeData && e2eeData.iv.length !== 16)\n throw new DownloadError(`IV must be 16 bytes long`);\n\n if (e2eeData && e2eeData.key.length !== 32)\n throw new DownloadError(`Encryption key must be 32 bytes long`);\n\n this.#logger = logger;\n this.#downloadId = downloadId;\n this.#transferId = transferId;\n this.#trackId = trackId;\n this.#region = region;\n this.#fileSystem = fileSystem;\n this.#files = Array.isArray(files) ? files : [files];\n this.#options = options;\n this.#eventsEngine = eventsEngine;\n this.#cryptography = cryptography;\n this.#downloadState = new DownloadState(this.#downloadId, this.#transferId, this.#files, this.#options, eventsEngine, oldState);\n this.#concurrencyController = concurrencyController;\n this.#apiClient = apiClient;\n this.#fileserverClientFactory = fileserverClientFactory;\n this.#chunkStreamProviderFactory = chunkStreamProviderFactory;\n this.#downloadRegistrationMode = downloadRegistrationMode;\n this.#ongoingChunkDownloads = {};\n this.#ongoingFileDownloads = {};\n\n if (e2eeData)\n this.#encryptionData = this.createEncryptionData(e2eeData);\n }\n\n private createEncryptionData(e2eeData: DownloadCommandE2eeData): ChunkStreamProviderEncryptionData {\n return {\n iv: e2eeData.iv,\n key: e2eeData.key,\n };\n }\n\n async start(): Promise<DownloadEventArgs> {\n try {\n await this.#throwIfNotEnoughDiskSpaceBeforeStart();\n\n this.#addEventListeners();\n\n let isDownloaderRunning = true;\n\n while (isDownloaderRunning) {\n this.#downloadState.start();\n\n const fileServerUrl = new URL(this.#files[0].url).origin;\n this.#downloadState.notifyMetadataDetermined(fileServerUrl, this.#region);\n\n // MAIN FILE LOOP\n for (const file of this.#files) {\n if (file.isCompleted || file.isFailed)\n continue;\n\n if (this.#downloadState.isRunning === false)\n break;\n\n // figure out if we are downloading a new file or resuming a file that was interrupted\n if (file.wasEverWritten) {\n // this a resumed file (recreated from progress.json) - it must already exist under its temporary path\n if (!file.temporaryDownloadPath) {\n this.#downloadState.fileFailed(file, new DownloadError(`File ${file.downloadPath} was supposed to be resumed but its temporary path is not known.`, undefined, DownloadErrorCode.ResumedFilePathNotSpecified));\n continue;\n }\n\n if ((await this.#fileSystem.pathExists(file.temporaryDownloadPath!)) === false) {\n this.#downloadState.fileFailed(file, new DownloadError(`File ${file.downloadPath} was supposed to be resumed at ${file.temporaryDownloadPath}, but it does not exist on disk anymore.`, undefined, DownloadErrorCode.ResumedFileNotFound));\n continue;\n }\n }\n else {\n // in some edge cases the temporary file may exist and its name be persisted in the tracker file\n // but the wasEverWritten flag was not yet set - just abandon such temporary file (it will be 'empty' - null bytes only)\n if (file.temporaryDownloadPath) {\n this.#logDeletingFile(file, file.temporaryDownloadPath, `start`);\n this.#fileSystem.deleteFile(file.temporaryDownloadPath);\n }\n\n // this is a new file - create it\n await this.#createDownloadFile(file);\n }\n\n this.#ongoingFileDownloads[file.externalId] = new DownloadFilePromise(file.externalId);\n this.#ongoingFileDownloads[file.externalId]!.awaiter.then(id => {\n delete this.#ongoingFileDownloads[id];\n });\n\n this.#downloadState.fileStarting(file);\n\n // note: this call does not really wait for all chunks to be downloaded, but until all chunks of a file have been **scheduled**\n await this.#downloadAllChunksForFile(file);\n\n // so when we are here, the file is not complete\n // to track completeness of a file we look at events emitted by this.#downloadState\n }\n\n // when we got here it's either pause request, stop request (which is just like pause but without waiting for pending chunks), abort request (cancel the download entirely) or everything is complete;\n\n // wait for any remaining pending chunks\n await promiseAllSettled(Object.values(this.#ongoingChunkDownloads));\n\n // Wait for any remaining pending files\n // Note: we cannot rely just on chunk downloads being completed, because downloading chunks\n // doesn't mean that a file is complete; last phase of file completion is renaming the file\n // from a temporary name (unconfirmed_somefile.txt_qweasd1234.fmdownload) to its real name, which may need adjustments if a file with same name already exists.\n // When file already exists - a unique filename will be generated automatically e.g.: file.txt --> file (1).txt\n await promiseAllSettled(Object.values(this.#ongoingFileDownloads).map(x => x.awaiter));\n\n if (this.#downloadState.status === TransferStatus.Pausing) {\n // set status to paused and await until resume/abort\n await this.#downloadState.paused();\n }\n\n isDownloaderRunning = await this.#prepareDownloaderForAnotherIteration();\n }\n\n await this.#cleanupEmptyDownloadFolderIfConfigured();\n }\n catch (error) {\n this.#logger.logError(error as Error, `Unhandled downloader error occured.`);\n this.#downloadState.completed(error as Error);\n }\n finally {\n this.#removeEventListeners();\n }\n\n return this.#downloadState.getCurrentState(true);\n }\n\n async #throwIfNotEnoughDiskSpaceBeforeStart() {\n await this.#fileSystem.createFolder(this.#options.downloadFolder!);\n\n const requiredBytes = this.#getRemainingBytesToDownload();\n\n if (requiredBytes <= 0n)\n return;\n\n try {\n const availableBytes = await this.#fileSystem.getAvailableDiskSpace(this.#options.downloadFolder!);\n\n if (availableBytes < requiredBytes)\n throw new DownloadError(`ENOSPC: Not enough disk space. Required=${requiredBytes}B, available=${availableBytes}B`, undefined, DownloadErrorCode.DiskFull);\n }\n catch (error) {\n if (this.#shouldSkipFreeDiskSpaceCheck(error)) {\n this.#logger.logWarning(`Skipping free disk space check because filesystem does not support statfs`, { error });\n return;\n }\n\n throw this.#toDownloadError(error, `Checking free disk space before download failed for ${this.#options.downloadFolder!}`);\n }\n }\n\n #getRemainingBytesToDownload(): bigint {\n let requiredBytes = 0n;\n\n for (const file of this.#files) {\n if (file.isCompleted || file.isFailed)\n continue;\n\n const remaining = file.sizeInBytes - file.downloadedBytes;\n requiredBytes += BigInt(remaining);\n }\n\n return requiredBytes;\n }\n\n #shouldSkipFreeDiskSpaceCheck(error: unknown): boolean {\n const code = this.#extractErrorCode(error);\n if (code === `ENOSYS` || code === `ENOTSUP` || code === `EOPNOTSUPP`)\n return true;\n\n const message = this.#extractErrorMessage(error)?.toLowerCase() ?? ``;\n if (code === `ENOENT` && message.includes(`statfs`))\n return true;\n\n return false;\n }\n\n #extractErrorCode(error: unknown): string | undefined {\n let current = error as { code?: string, cause?: unknown } | undefined;\n\n for (let depth = 0; depth < 8 && current; depth++) {\n if (typeof current.code === `string`)\n return current.code;\n\n current = current.cause as { code?: string, cause?: unknown } | undefined;\n }\n\n return undefined;\n }\n\n #extractErrorMessage(error: unknown): string | undefined {\n let current = error as { message?: string, cause?: unknown } | undefined;\n\n for (let depth = 0; depth < 8 && current; depth++) {\n if (typeof current.message === `string`)\n return current.message;\n\n current = current.cause as { message?: string, cause?: unknown } | undefined;\n }\n\n return undefined;\n }\n\n #logDeletingFile(file: DownloadFileInfo | DownloadFileProgress, path: string, method: string) {\n let fileDataToLog = file;\n if (file instanceof DownloadFileInfo)\n fileDataToLog = DownloadFileProgress.FromFileDownloadInfo(file);\n\n this.#logger.logInfo(`[DELETE_TEMPFILE] Deleting temp file path=${path} method=${method}\\n\\n${JSON.stringify(fileDataToLog, null, 4)}\\n`);\n }\n\n requestPause(options: { interruptPendingChunks: boolean, pausedTrigger?: (paused: boolean) => void }): void {\n Object.values(this.#ongoingFileDownloads).forEach(filePromise => filePromise.complete());\n this.#downloadState.requestPause(options);\n }\n\n resume(): boolean {\n return this.#downloadState.resume();\n }\n\n requestAbort(): boolean {\n Object.values(this.#ongoingFileDownloads).forEach(filePromise => filePromise.complete());\n return this.#downloadState.requestAbort();\n }\n\n getCurrentState(withFiles: boolean): DownloadEventArgs {\n return this.#downloadState.getCurrentState(withFiles);\n }\n\n get status(): TransferStatus {\n return this.#downloadState.status;\n }\n\n async #deleteAllTemporaryAndCompletedFiles() {\n for (const file of this.#files) {\n if (file.temporaryDownloadPath) {\n this.#logDeletingFile(file, file.temporaryDownloadPath, `deleteAllTemporaryAndCompletedFiles`);\n await this.#fileSystem.deleteFile(file.temporaryDownloadPath);\n }\n\n if (file.isCompleted)\n await this.#fileSystem.deleteFile(file.downloadPath);\n }\n }\n\n async #registerTransferDownload() {\n this.#downloadState.registeringTransferDownload();\n await this.#apiClient.registerTransferDownload({\n transferid: this.#transferId,\n track: this.#trackId,\n bps: this.#downloadState.averageBytesPerSecond,\n browser: this.#options.userAgent,\n });\n }\n\n async #registerFileDownload(filename: string, filesize: number) {\n this.#downloadState.registeringFileDownload();\n await this.#apiClient.registerFileDownload({\n transferid: this.#transferId,\n track: this.#trackId,\n bps: this.#downloadState.averageBytesPerSecond,\n browser: this.#options.userAgent,\n filename,\n filesize,\n });\n }\n\n #addEventListeners() {\n this.#eventsEngine.addEventListener(TransferDownloadEvent.FileDownloadCompleted, this.#onFileCompleted);\n this.#eventsEngine.addEventListener(TransferDownloadEvent.FileDownloadCompleting, this.#onFileCompleting);\n this.#eventsEngine.addEventListener(TransferDownloadEvent.FileDownloadFailed, this.#onFileFailed);\n this.#eventsEngine.addEventListener(TransferDownloadEvent.PossibleSupersizedFile, this.#onFileSupersized);\n }\n\n #removeEventListeners() {\n this.#eventsEngine.removeEventListener(TransferDownloadEvent.FileDownloadCompleted, this.#onFileCompleted);\n this.#eventsEngine.removeEventListener(TransferDownloadEvent.FileDownloadCompleting, this.#onFileCompleting);\n this.#eventsEngine.removeEventListener(TransferDownloadEvent.FileDownloadFailed, this.#onFileFailed);\n this.#eventsEngine.removeEventListener(TransferDownloadEvent.PossibleSupersizedFile, this.#onFileSupersized);\n }\n\n #onFileCompleted = async (args: FileDownloadEventArgs) => {\n if (this.#downloadRegistrationMode === DownloadRegistrationMode.EverySingleFile && !this.#options.skipRegistration)\n await this.#registerFileDownload(args.file.name, args.file.size);\n\n this.#ongoingFileDownloads[args.file.id]?.complete();\n };\n\n #onFileCompleting = async (args: FileDownloadEventArgs) => {\n // note the args.file.downloadPath may not be final - if a file with this name eixsts the following method will generate new name e.g. \"file.txt\" --> \"file (1).txt\"\n try {\n const finalDownloadPath = await this.#doTheFinalFileRenameAfterFilesIsDownloaded(args.file);\n this.#downloadState.fileCompleted(args.file.id, finalDownloadPath);\n }\n catch (error) {\n this.#downloadState.fileFailedById(args.file.id, error as DownloadError);\n }\n };\n\n #onFileSupersized = async (fileArgs: FileDownloadEventArgs) => {\n if (fileArgs.file.temporaryDownloadPath && await this.#fileSystem.getFileSize(fileArgs.file.temporaryDownloadPath) > fileArgs.file.size)\n await this.#fileSystem.truncateFile(fileArgs.file.temporaryDownloadPath, fileArgs.file.size);\n };\n\n #onFileFailed = async (args: FileDownloadFailedEventArgs) => {\n this.#ongoingFileDownloads[args.file.id]?.complete();\n\n const shouldKeepTemporaryFile = this.#shouldKeepTemporaryFileOnFailure();\n\n if (this.#options.deleteFailedFilesFromDisk) {\n if (args.file.temporaryDownloadPath && !shouldKeepTemporaryFile) {\n this.#logDeletingFile(args.file, args.file.temporaryDownloadPath, `onFileFailed`);\n await this.#fileSystem.deleteFile(args.file.temporaryDownloadPath);\n }\n }\n };\n\n #shouldKeepTemporaryFileOnFailure(): boolean {\n // Resuming failed files requires tracking state + preserved temporary files.\n // If tracking is disabled there is no benefit in leaving temp files behind.\n return this.#options.downloadTrackingBaseFolder !== null;\n }\n\n async #createDownloadFile(file: DownloadFileInfo) {\n this.#downloadState.fileCreating(file);\n\n try {\n await this.#autoGenerateUniqueDownloadFile(file);\n this.#downloadState.fileCreated(file);\n }\n catch (error) {\n throw this.#toDownloadError(error, `Creating download file failed for ${file.downloadPath}`);\n }\n }\n\n async #autoGenerateUniqueDownloadFile(file: DownloadFileInfo) {\n let counter = 0;\n const fileLeafName = this.#fileSystem.parseFilePath(file.name).base;\n do {\n const newFileName = `unconfirmed_${fileLeafName}_${this.#cryptography.generateRandomString(10)}.fmdownload`;\n const newPath = this.#fileSystem.replaceFilenameInPath(file.downloadPath, newFileName);\n if (await this.#fileSystem.createFile(newPath, false)) {\n // eslint-disable-next-line no-param-reassign\n file.temporaryDownloadPath = newPath;\n return;\n }\n\n counter += 1;\n } while (counter < 10000);\n\n throw new DownloadError(`Downloader could not generate unique download path for ${file.downloadPath}. It tried until counter=${counter}`, undefined, DownloadErrorCode.TooManyFileRenameAttempts);\n }\n\n #toDownloadError(error: unknown, message: string): DownloadError {\n if (error instanceof DownloadError)\n return error;\n\n const wrappedError = error instanceof Error\n ? error\n : new Error(`${error}`);\n\n const code = this.#fileSystem.fileErrorToDownloadErrorCode(wrappedError);\n return new DownloadError(message, { cause: wrappedError }, code);\n }\n\n async #downloadAllChunksForFile(file: DownloadFileInfo) {\n if (file.chunks.length) {\n // MAIN CHUNK LOOP\n for (const chunk of file.chunks) {\n if (chunk.isCompleted || chunk.isFailed)\n continue;\n\n const downloadScheduled = await this.#downloadSingleChunk(file, chunk);\n if (downloadScheduled === false) {\n // downloader is not running or file is in failed state - stop the chunk loop\n break;\n }\n }\n\n // Restored files can have all chunks already completed (e.g. rename failed in a previous run).\n // In such case there is nothing to schedule, so we need to trigger finalization explicitly.\n if (!file.isFailed && file.chunks.every(chunk => chunk.isCompleted)) {\n this.#downloadState.ensureFileStarted(file);\n file.updateProgress();\n this.#downloadState.fileCompleting(file);\n }\n }\n else {\n // zerobyte file\n file.updateProgress();\n this.#downloadState.fileCompleting(file);\n }\n }\n\n async #downloadSingleChunk(file: DownloadFileInfo, chunk: DownloadFileChunkInfo): Promise<boolean> {\n const releaseSemaphore = await this.#concurrencyController.acquire();\n\n if (this.#downloadState.isRunning === false) {\n // downloader is not running - stop trying more chunks\n releaseSemaphore();\n return false;\n }\n\n if (file.isFailed) {\n // do not try to download more chunks if the file has failed\n releaseSemaphore();\n return false;\n }\n\n const chunkDownloader = new ChunkDownloader(this.#transferId, file, chunk, this.#downloadState, this.#options, this.#fileserverClientFactory, this.#chunkStreamProviderFactory, this.#eventsEngine, this.#logger, this.#encryptionData);\n const chunkPromise: Promise<void> = chunkDownloader.download();\n this.#ongoingChunkDownloads[chunk.id] = chunkPromise;\n\n chunkPromise.finally(() => {\n releaseSemaphore();\n delete this.#ongoingChunkDownloads[chunk.id];\n });\n\n return true;\n }\n\n /**\n * Prepares downloader for next loop iteration. Handles two main scenarios:\n * 1. Aborting - cleans up the disk state, calls downloadState to trigger Aborted event and returns a false flag (to break the loop).\n * 2. Completed - registers download to web api, calls downloadState to trigger Completed event and returns a false flag (to break the loop).\n * 3. For all other cases returns true - to continue the loop.\n */\n async #prepareDownloaderForAnotherIteration(): Promise<boolean> {\n let shouldDownloaderContinue = true;\n if (this.#downloadState.status === TransferStatus.Aborting) {\n shouldDownloaderContinue = false;\n if (this.#options.deleteAbortedDownloadsFromDisk)\n await this.#deleteAllTemporaryAndCompletedFiles();\n\n this.#downloadState.aborted();\n }\n else if (this.#downloadState.allFilesCompletedOrFailed) {\n shouldDownloaderContinue = false;\n if (this.#downloadRegistrationMode === DownloadRegistrationMode.Transfer && !this.#options.skipRegistration)\n await this.#registerTransferDownload();\n\n this.#downloadState.completed();\n }\n return shouldDownloaderContinue;\n }\n\n async #cleanupEmptyDownloadFolderIfConfigured() {\n try {\n if (this.#options.deleteEmptyDownloadFoldersAfterDownload && await this.#fileSystem.folderIsEmpty(this.#options.downloadFolder!))\n await this.#fileSystem.deleteFolder(this.#options.downloadFolder!);\n }\n catch (error) {\n this.#logger.logWarning(`cleanupEmptyDownloadFolderIfConfigured failed`, { error });\n }\n }\n\n async #doTheFinalFileRenameAfterFilesIsDownloaded(file: DownloadFileProgress) {\n let created = false;\n let createCounter = 0;\n const original = this.#fileSystem.parseFilePath(file.downloadPath);\n let newPathFormatted = file.downloadPath;\n do {\n // we do not want to re-reserve disk space when creating the target file (final name) - so file size is omitted\n created = await this.#fileSystem.createFile(newPathFormatted, false);\n if (!created) {\n createCounter += 1;\n const newPath = {\n dir: original.dir,\n name: `${original.name} (${createCounter})`,\n ext: original.ext,\n };\n newPathFormatted = this.#fileSystem.formatFilePath(newPath);\n }\n } while (created === false && createCounter < 10000);\n\n if (!created)\n throw new DownloadError(`Downloader could not rename temp file ${file.temporaryDownloadPath} to ${file.downloadPath}. It tried until counter=${createCounter}`, undefined, DownloadErrorCode.TooManyFileRenameAttempts);\n\n let renamed = false;\n let renameCounter = 0;\n let lastError: Error | undefined;\n while (!renamed && renameCounter < 5) {\n renameCounter += 1;\n try {\n await this.#fileSystem.renameFile(file.temporaryDownloadPath!, newPathFormatted);\n renamed = true;\n this.#logger.logInfo(`Downloader renamed ${file.temporaryDownloadPath} to ${newPathFormatted} at attempt ${renameCounter}`);\n }\n catch (error) {\n lastError = error as Error;\n this.#logger.logError(lastError, `Downloader could not rename ${file.temporaryDownloadPath} to ${newPathFormatted} attempt ${renameCounter}`);\n }\n }\n if (!renamed)\n await this.#cleanupFailedRenameTarget(newPathFormatted);\n\n if (!renamed)\n throw new DownloadError(`Downloader could not rename ${file.temporaryDownloadPath} to ${newPathFormatted} after ${renameCounter} attempts.`, { cause: lastError }, DownloadErrorCode.RenameFromTemporaryFilenameToFinalFailure);\n else\n return newPathFormatted;\n }\n\n async #cleanupFailedRenameTarget(pathToDelete: string) {\n try {\n await this.#fileSystem.deleteFile(pathToDelete);\n }\n catch (error) {\n this.#logger.logWarning(`Could not cleanup failed rename target ${pathToDelete}`, { error });\n }\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filesPreparer.js","sourceRoot":"","sources":["../../../src/downloader/filesPreparer.ts"],"names":[],"mappings":"AACA,OAAO,aAAa,MAAM,yBAAyB,CAAC;AACpD,OAAO,qBAAqB,MAAM,iCAAiC,CAAC;AAGpE,MAAM,CAAC,OAAO,OAAO,aAAa;IAC9B,mBAAmB,CAAS;IAC5B,aAAa,CAAgB;IAC7B,WAAW,CAAa;IAExB,YAAY,kBAA0B,EAAE,YAA2B,EAAE,UAAsB;QACvF,IAAI,CAAC,mBAAmB,GAAG,kBAAkB,CAAC;QAC9C,IAAI,CAAC,aAAa,GAAG,YAAY,CAAC;QAClC,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC;IAClC,CAAC;IAED,YAAY,CAAC,KAA8B;QACvC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACvB,IAAI,CAAC,IAAI,CAAC,UAAU;gBAChB,MAAM,IAAI,aAAa,CAAC,qCAAqC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;YAE7E,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,CAAC;YAEpC,IAAI,IAAI,CAAC,WAAW,GAAG,CAAC,EAAE,CAAC;gBACvB,IAAI,IAAI,CAAC,aAAa,KAAK,IAAI;oBAC3B,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;;oBAEpB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,aAAc,CAAC,CAAC;YAC5E,CAAC;;gBAEG,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;YAExB,IAAI,CAAC,MAAM,GAAG,IAAI,KAAK,CAAwB,IAAI,CAAC,UAAU,CAAC,CAAC;YAChE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE;gBACpC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,qBAAqB,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,CAAC;QACxF,CAAC;IACL,CAAC;IAED,wBAAwB,CAAC,IAAsB;QAC3C,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;YACxB,6CAA6C;YAC7C,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,mBAAoB,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QACxF,CAAC;IACL,CAAC;CACJ","sourcesContent":["import type FileSystem from \"../utils/fileSystem/fileSystemService.js\";\
|
|
1
|
+
{"version":3,"file":"filesPreparer.js","sourceRoot":"","sources":["../../../src/downloader/filesPreparer.ts"],"names":[],"mappings":"AACA,OAAO,aAAa,MAAM,yBAAyB,CAAC;AACpD,OAAO,qBAAqB,MAAM,iCAAiC,CAAC;AAGpE,MAAM,CAAC,OAAO,OAAO,aAAa;IAC9B,mBAAmB,CAAS;IAC5B,aAAa,CAAgB;IAC7B,WAAW,CAAa;IAExB,YAAY,kBAA0B,EAAE,YAA2B,EAAE,UAAsB;QACvF,IAAI,CAAC,mBAAmB,GAAG,kBAAkB,CAAC;QAC9C,IAAI,CAAC,aAAa,GAAG,YAAY,CAAC;QAClC,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC;IAClC,CAAC;IAED,YAAY,CAAC,KAA8B;QACvC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACvB,IAAI,CAAC,IAAI,CAAC,UAAU;gBAChB,MAAM,IAAI,aAAa,CAAC,qCAAqC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;YAE7E,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,CAAC;YAEpC,IAAI,IAAI,CAAC,WAAW,GAAG,CAAC,EAAE,CAAC;gBACvB,IAAI,IAAI,CAAC,aAAa,KAAK,IAAI;oBAC3B,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;;oBAEpB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,aAAc,CAAC,CAAC;YAC5E,CAAC;;gBAEG,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;YAExB,IAAI,CAAC,MAAM,GAAG,IAAI,KAAK,CAAwB,IAAI,CAAC,UAAU,CAAC,CAAC;YAChE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE;gBACpC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,qBAAqB,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,CAAC;QACxF,CAAC;IACL,CAAC;IAED,wBAAwB,CAAC,IAAsB;QAC3C,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;YACxB,6CAA6C;YAC7C,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,mBAAoB,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QACxF,CAAC;IACL,CAAC;CACJ","sourcesContent":["import type FileSystem from \"../utils/fileSystem/fileSystemService.js\";\nimport DownloadError from \"./dtos/downloadError.js\";\nimport DownloadFileChunkInfo from \"./dtos/downloadFileChunkInfo.js\";\nimport type DownloadFileInfo from \"./dtos/downloadFileInfo.js\";\n\nexport default class FilesPreparer {\n #downloadBaseFolder: string;\n #maxChunkSize: number | null;\n #fileSystem: FileSystem;\n\n constructor(downloadBaseFolder: string, maxChunkSize: number | null, fileSystem: FileSystem) {\n this.#downloadBaseFolder = downloadBaseFolder;\n this.#maxChunkSize = maxChunkSize;\n this.#fileSystem = fileSystem;\n }\n\n prepareFiles(files: Array<DownloadFileInfo>) {\n for (const file of files) {\n if (!file.externalId)\n throw new DownloadError(`All files require an external ID: ${file.url}`);\n\n this.#computeFileDownloadPath(file);\n\n if (file.sizeInBytes > 0) {\n if (this.#maxChunkSize === null)\n file.chunkCount = 1;\n else\n file.chunkCount = Math.ceil(file.sizeInBytes / this.#maxChunkSize!);\n }\n else\n file.chunkCount = 0;\n\n file.chunks = new Array<DownloadFileChunkInfo>(file.chunkCount);\n for (let k = 0; k < file.chunkCount; k++)\n file.chunks[k] = new DownloadFileChunkInfo(file, k, this.#maxChunkSize || null);\n }\n }\n\n #computeFileDownloadPath(file: DownloadFileInfo): void {\n if (!file.hasDownloadPath) {\n // eslint-disable-next-line no-param-reassign\n file.downloadPath = this.#fileSystem.pathJoin(this.#downloadBaseFolder!, file.name);\n }\n }\n}"]}
|
package/dist/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAC9E,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AASpF,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,+BAA+B,CAAC;AAInE,OAAO,EAAE,OAAO,IAAI,6BAA6B,EAAE,MAAM,gEAAgE,CAAC;AAsB1H,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,6CAA6C,CAAC;AAC5F,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,8CAA8C,CAAC;AAE9F,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAE3E,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACnF,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAKnF,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,yCAAyC,CAAC;AACnF,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAE5E,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAMzE,OAAO,EAAE,OAAO,IAAI,yBAAyB,EAAE,MAAM,qDAAqD,CAAC;AAC3G,OAAO,EAAE,OAAO,IAAI,6BAA6B,EAAE,MAAM,yDAAyD,CAAC;AACnH,OAAO,EAAE,OAAO,IAAI,+BAA+B,EAAE,MAAM,2DAA2D,CAAC;AACvH,OAAO,EAAE,OAAO,IAAI,0BAA0B,EAAE,MAAM,6DAA6D,CAAC;AAGpH,OAAO,EAAE,OAAO,IAAI,aAAa,EAAuB,MAAM,uDAAuD,CAAC;AACtH,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,2DAA2D,CAAC;AACzG,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,0DAA0D,CAAC;AAEvG,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,oCAAoC,CAAC;AAC9E,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AACtF,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,oCAAoC,CAAC","sourcesContent":["export { default as CancelTransferRequest } from \"./utils/api/dtos/cancelTransferRequest.js\";\
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAC9E,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AASpF,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,+BAA+B,CAAC;AAInE,OAAO,EAAE,OAAO,IAAI,6BAA6B,EAAE,MAAM,gEAAgE,CAAC;AAsB1H,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,6CAA6C,CAAC;AAC5F,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,8CAA8C,CAAC;AAE9F,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAE3E,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACnF,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAKnF,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,yCAAyC,CAAC;AACnF,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAE5E,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAMzE,OAAO,EAAE,OAAO,IAAI,yBAAyB,EAAE,MAAM,qDAAqD,CAAC;AAC3G,OAAO,EAAE,OAAO,IAAI,6BAA6B,EAAE,MAAM,yDAAyD,CAAC;AACnH,OAAO,EAAE,OAAO,IAAI,+BAA+B,EAAE,MAAM,2DAA2D,CAAC;AACvH,OAAO,EAAE,OAAO,IAAI,0BAA0B,EAAE,MAAM,6DAA6D,CAAC;AAGpH,OAAO,EAAE,OAAO,IAAI,aAAa,EAAuB,MAAM,uDAAuD,CAAC;AACtH,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,2DAA2D,CAAC;AACzG,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,0DAA0D,CAAC;AAEvG,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,oCAAoC,CAAC;AAC9E,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AACtF,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,oCAAoC,CAAC","sourcesContent":["export { default as CancelTransferRequest } from \"./utils/api/dtos/cancelTransferRequest.js\";\nexport { BaseResponse } from \"./utils/api/dtos/baseResponse.js\";\nexport { default as FinalizeTransferRequest } from \"./utils/api/dtos/finalizeTransferRequest.js\";\nexport { default as FinalizeTransferResponse } from \"./utils/api/dtos/finalizeTransferResponse.js\";\nexport { default as ResetTransferRequest } from \"./utils/api/dtos/resetTransferRequest.js\";\nexport { InitializeTransferRequest, InitializeTransferRequestCustomField, InitializeTransferRequestRaw, InitializeTransferRequestCustomFieldRaw } from \"./utils/api/dtos/initializeTransferRequest.js\";\nexport { default as InitializeTransferResponse } from \"./utils/api/dtos/initializeTransferResponse.js\";\nexport { default as LoginRequest } from \"./utils/api/dtos/loginRequest.js\";\nexport { default as LoginResponse } from \"./utils/api/dtos/loginResponse.js\";\nexport { default as SendFileChunkRequest } from \"./utils/api/dtos/sendFileChunkRequest.js\";\nexport { default as GetTransferRequest } from \"./utils/api/dtos/getTransferRequest.js\";\nexport { default as GetTransferResponse } from \"./utils/api/dtos/getTransferResponse.js\";\nexport { default as TransferFileDto } from \"./utils/api/dtos/transferFileDto.js\";\nexport { default as RegisterTransferDownloadRequest } from \"./utils/api/dtos/registerTransferDownloadRequest.js\";\nexport { default as RegisterFileDownloadRequest } from \"./utils/api/dtos/registerFileDownloadRequest.js\";\nexport { default as TransferCustomFieldDto } from \"./utils/api/dtos/transferCustomFieldDto.js\";\n\nexport { default as ChunkProgressEvent } from \"./utils/events/chunkProgressEvent.js\";\n\nexport { default as ApiClient } from \"./utils/api/apiClient.js\";\nexport { default as ApiError } from \"./utils/api/apiError.js\";\nexport { default as ApiFilemailError } from \"./utils/api/apiFilemailError.js\";\nexport { default as ApiFilemail449Error } from \"./utils/api/apiFilemail449Error.js\";\nexport { default as FileServerClient } from \"./uploader/api/fileServerUploadClient.js\";\nexport { default as FileServerClientFactory } from \"./utils/api/fileServerClientFactory.js\";\n\nexport { default as EventsEngine } from \"./utils/events/eventsEngine.js\";\nexport { EventsEngineEventHandler } from \"./utils/events/eventsEngine.js\";\n\nexport { default as ChunkStreamProvider } from \"./utils/fileSystem/chunkStreamProvider.js\";\nexport { default as FileDetails } from \"./utils/fileSystem/fileDetails.js\";\nexport { default as FsError } from \"./utils/fileSystem/fsError.js\";\n\nexport { default as ConcurrencyController } from \"./utils/concurrencyController/concurrencyController.js\";\nexport { default as ConcurrencyReleaser } from \"./utils/concurrencyController/concurrencyReleaser.js\";\nexport { default as TransferConcurrencyController } from \"./utils/concurrencyController/transferConcurrencyController.js\";\n\nexport { TransferUploadExportData, TransferUploadExportDataMetadata } from \"./uploader/export/transferUploadExportData.js\";\nexport { default as TransferUploadMetadata } from \"./uploader/export/transferUploadMetadata.js\";\nexport { default as TransferUploadExportState } from \"./uploader/export/transferUploadExportState.js\";\n\nexport { ContinuousChunksCalculatorState, ContinuousChunk } from \"./uploader/state/continuousChunksCalculator.js\";\n\nexport { default as FileChunkUploadFailedEventArgs } from \"./uploader/eventArgs/fileChunkUploadFailedEventArgs.js\";\nexport { default as FileChunkUploadCompletedPartiallyEventArgs } from \"./uploader/eventArgs/fileChunkUploadCompletedPartiallyEventArgs.js\";\nexport { default as FileChunkUploadEventArgs } from \"./uploader/eventArgs/fileChunkUploadEventArgs.js\";\nexport { default as FileChunkUploadCompletedEventArgs } from \"./uploader/eventArgs/fileChunkUploadCompletedEventArgs.js\";\nexport { default as FileChunkUploadProgressedEventArgs } from \"./uploader/eventArgs/fileChunkUploadProgressedEventArgs.js\";\nexport { default as TransferUploadProgressedEventArgs } from \"./uploader/eventArgs/transferUploadProgressedEventArgs.js\";\nexport { default as FileUploadEventArgs } from \"./uploader/eventArgs/fileUploadEventArgs.js\";\nexport { default as FileUploadFailedEventArgs } from \"./uploader/eventArgs/fileUploadFailedEventArgs.js\";\nexport { default as TransferUploadCompletedEventArgs } from \"./uploader/eventArgs/transferUploadCompletedEventArgs.js\";\nexport { default as TransferMetadataDeterminedEventArgs } from \"./uploader/eventArgs/transferMetadataDeterminedEventArgs.js\";\nexport { default as TransferUploadModeChosenEventArgs } from \"./uploader/eventArgs/transferUploadModeChosenEventArgs.js\";\n\nexport { default as ReadonlyTransferUploadStateFile } from \"./uploader/state/readonlyTransferUploadStateFile.js\";\nexport { default as ReadonlyTransferUploadStateFiles } from \"./uploader/state/readonlyTransferUploadStateFiles.js\";\nexport { default as TransferStatusFile } from \"./uploader/state/transferUploadStateFile.js\";\nexport { default as TransferStatusFiles } from \"./uploader/state/transferUploadStateFiles.js\";\n\nexport { default as PauseController } from \"./uploader/pauseController.js\";\nexport { PauseSignal } from \"./uploader/pauseController.js\";\nexport { default as Transfer } from \"./uploader/transferUpload.js\";\nexport { default as TransferUploadError } from \"./uploader/transferUploadError.js\";\nexport { default as TransferUploadEvent } from \"./uploader/transferUploadEvent.js\";\nexport { default as TransferUploadConfig } from \"./uploader/options/transferUploadConfig.js\";\nexport { default as TransferUploadInfo, TransferUploadInfoCustomField } from \"./uploader/options/transferUploadInfo.js\";\nexport { TransferUploadAppendInfo, TransferUploadAppendInfoE2eeData } from \"./uploader/options/transferUploadAppendInfo.js\";\nexport { default as TransferUploadInfoBase } from \"./uploader/options/transferUploadInfoBase.js\";\nexport { default as TransferState } from \"./uploader/state/transferUploadState.js\";\nexport { default as TransferStatus } from \"./utils/types/transferStatus.js\";\n\nexport { default as DummyLogger } from \"./client/loggers/dummyLogger.js\";\nexport { default as Logger } from \"./client/loggers/logger.js\";\nexport { default as TransferUploader } from \"./client/uploader/transferUploader.js\";\nexport { default as EnvironmentVariables } from \"./client/environmentVariables.js\";\nexport { default as TransferUploaderConfig } from \"./client/uploader/transferUploaderConfig.js\";\n\nexport { default as TransferHealthMonitorBase } from \"./client/healthMonitor/transferHealthMonitorBase.js\";\nexport { default as TransferUploaderHealthMonitor } from \"./client/healthMonitor/transferUploaderHealthMonitor.js\";\nexport { default as TransferDownloaderHealthMonitor } from \"./client/healthMonitor/transferDownloaderHealthMonitor.js\";\nexport { default as TransferHealthMonitorEvent } from \"./client/healthMonitor/events/transferHealthMonitorEvent.js\";\nexport { default as HealthMonitorHealthyEventArgs } from \"./client/healthMonitor/events/eventArgs/healthMonitorHealthyEventArgs.js\";\nexport { default as HealthMonitorUnhealthyEventArgs, HealthMonitorUnhealthyEventArgsReason, HealthMonitorUnhealthyEventArgsReasonValue } from \"./client/healthMonitor/events/eventArgs/healthMonitorUnhealthyEventArgs.js\";\nexport { default as OnlineChecker, OnlineCheckerResult } from \"./client/healthMonitor/onlineChecker/onlineChecker.js\";\nexport { default as NodeOnlineChecker } from \"./client/healthMonitor/onlineChecker/nodeOnlineChecker.js\";\nexport { default as WebOnlineChecker } from \"./client/healthMonitor/onlineChecker/webOnlineChecker.js\";\n\nexport { default as DownloadError } from \"./downloader/dtos/downloadError.js\";\nexport { default as DownloadErrorCode } from \"./downloader/dtos/downloadErrorCode.js\";\nexport { default as TransferDownloadEvent } from \"./downloader/dtos/downloadEvent.js\";"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.node.js","sourceRoot":"","sources":["../../src/index.node.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAE3B,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAC7E,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAC/E,OAAO,EAAE,OAAO,IAAI,0BAA0B,EAAE,MAAM,mDAAmD,CAAC;AAC1G,OAAO,EAAE,OAAO,IAAI,4BAA4B,EAAE,MAAM,uDAAuD,CAAC;AAChH,OAAO,EAAE,OAAO,IAAI,2BAA2B,EAAE,MAAM,iDAAiD,CAAC;AAEzG,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAEtF,OAAO,EAAE,OAAO,IAAI,uBAAuB,EAAE,MAAM,oDAAoD,CAAC;AACxG,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,4CAA4C,CAAC;AAExF,OAAO,EAAE,OAAO,IAAI,uBAAuB,EAAE,MAAM,0CAA0C,CAAC;AAC9F,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,gDAAgD,CAAC;AAEjG,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,kDAAkD,CAAC;AACpG,OAAO,EAAE,OAAO,IAAI,8BAA8B,EAAE,MAAM,2DAA2D,CAAC;AAEtH,OAAO,EAAE,OAAO,IAAI,sBAAsB,EAAE,MAAM,oDAAoD,CAAC;AAEvG,OAAO,EAAE,OAAO,IAAI,yBAAyB,EAAE,MAAM,uDAAuD,CAAC;AAG7G,OAAO,EAAE,OAAO,IAAI,iCAAiC,EAAE,MAAM,4DAA4D,CAAC;AAC1H,OAAO,EAAE,OAAO,IAAI,6BAA6B,EAAE,MAAM,wDAAwD,CAAC;AAElH,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAC7E,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAS3E,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAC7E,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,oCAAoC,CAAC;AAC9E,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AACtF,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,uCAAuC,CAAC;AAGpF,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,4CAA4C,CAAC;AAC9F,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAMtF,OAAO,EAAE,OAAO,IAAI,wBAAwB,EAAE,MAAM,+CAA+C,CAAC;AACpG,OAAO,EAAE,OAAO,IAAI,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AAG3F,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAgBlF,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAC/E,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AACzF,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,yCAAyC,CAAC","sourcesContent":["export * from \"./index.js\";\
|
|
1
|
+
{"version":3,"file":"index.node.js","sourceRoot":"","sources":["../../src/index.node.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAE3B,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAC7E,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAC/E,OAAO,EAAE,OAAO,IAAI,0BAA0B,EAAE,MAAM,mDAAmD,CAAC;AAC1G,OAAO,EAAE,OAAO,IAAI,4BAA4B,EAAE,MAAM,uDAAuD,CAAC;AAChH,OAAO,EAAE,OAAO,IAAI,2BAA2B,EAAE,MAAM,iDAAiD,CAAC;AAEzG,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAEtF,OAAO,EAAE,OAAO,IAAI,uBAAuB,EAAE,MAAM,oDAAoD,CAAC;AACxG,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,4CAA4C,CAAC;AAExF,OAAO,EAAE,OAAO,IAAI,uBAAuB,EAAE,MAAM,0CAA0C,CAAC;AAC9F,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,gDAAgD,CAAC;AAEjG,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,kDAAkD,CAAC;AACpG,OAAO,EAAE,OAAO,IAAI,8BAA8B,EAAE,MAAM,2DAA2D,CAAC;AAEtH,OAAO,EAAE,OAAO,IAAI,sBAAsB,EAAE,MAAM,oDAAoD,CAAC;AAEvG,OAAO,EAAE,OAAO,IAAI,yBAAyB,EAAE,MAAM,uDAAuD,CAAC;AAG7G,OAAO,EAAE,OAAO,IAAI,iCAAiC,EAAE,MAAM,4DAA4D,CAAC;AAC1H,OAAO,EAAE,OAAO,IAAI,6BAA6B,EAAE,MAAM,wDAAwD,CAAC;AAElH,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAC7E,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAS3E,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAC7E,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,oCAAoC,CAAC;AAC9E,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AACtF,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,uCAAuC,CAAC;AAGpF,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,4CAA4C,CAAC;AAC9F,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAMtF,OAAO,EAAE,OAAO,IAAI,wBAAwB,EAAE,MAAM,+CAA+C,CAAC;AACpG,OAAO,EAAE,OAAO,IAAI,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AAG3F,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAgBlF,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAC/E,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AACzF,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,yCAAyC,CAAC","sourcesContent":["export * from \"./index.js\";\n\nexport { default as NodeApiClient } from \"./utils/api/node/nodeApiClient.js\";\nexport { default as NodeClientBase } from \"./utils/api/node/nodeClientBase.js\";\nexport { default as NodeFileServerUploadClient } from \"./uploader/api/node/nodeFileServerUploadClient.js\";\nexport { default as NodeFileServerDownloadClient } from \"./downloader/api/node/nodeFileServerDownloadClient.js\";\nexport { default as NodeFileServerClientFactory } from \"./utils/api/node/nodeFileServerClientFactory.js\";\n\nexport { default as NodeEventsEngine } from \"./utils/events/node/nodeEventsEngine.js\";\n\nexport { default as NodeChunkStreamProvider } from \"./utils/fileSystem/node/nodeChunkStreamProvider.js\";\nexport { default as NodeFileDetails } from \"./utils/fileSystem/node/nodeFileDetails.js\";\n\nexport { default as NodeFileDetailsProvider } from \"./client/node/nodeFileDetailsProvider.js\";\nexport { default as NodeTransferUploader } from \"./client/uploader/node/nodeTransferUploader.js\";\n\nexport { default as NodeFileSystemService } from \"./utils/fileSystem/node/nodeFileSystemService.js\";\nexport { default as NodeChunkStreamProviderFactory } from \"./utils/fileSystem/node/nodeChunkStreamProviderFactory.js\";\n\nexport { default as NodeTransferDownloader } from \"./client/downloader/node/nodeTransferDownloader.js\";\n\nexport { default as NodeAutoDownloaderFactory } from \"./autoDownloader/factory/nodeAutoDownloaderFactory.js\";\nexport { default as NodeAutoDownloaderFactoryOptions } from \"./autoDownloader/factory/nodeAutoDownloaderFactoryOptions.js\";\n\nexport { default as NodeAutoDownloaderStateSerializer } from \"./autoDownloader/node/nodeAutoDownloaderStateSerializer.js\";\nexport { default as NodeTransferDownloaderFactory } from \"./autoDownloader/node/nodeTransferDownloaderFactory.js\";\n\nexport { default as FilesDownloader } from \"./downloader/filesDownloader.js\";\nexport { default as DownloadLogger } from \"./downloader/downloadLogger.js\";\nexport { default as DownloadEventArgs } from \"./downloader/eventArgs/downloadEventArgs.js\";\nexport { default as DownloadPauseEventArgs } from \"./downloader/eventArgs/downloadPauseEventArgs.js\";\nexport { default as DownloadCompletedEventArgs } from \"./downloader/eventArgs/downloadCompletedEventArgs.js\";\nexport { default as DownloadMetadataDeterminedEventArgs } from \"./downloader/eventArgs/downloadMetadataDeterminedEventArgs.js\";\nexport { default as FileDownloadEventArgs } from \"./downloader/eventArgs/fileDownloadEventArgs.js\";\nexport { default as FileDownloadFailedEventArgs } from \"./downloader/eventArgs/fileDownloadFailedEventArgs.js\";\nexport { default as ChunkDownloadEventArgs } from \"./downloader/eventArgs/chunkDownloadEventArgs.js\";\nexport { default as ChunkDownloadFailedEventArgs } from \"./downloader/eventArgs/chunkDownloadFailedEventArgs.js\";\nexport { default as DownloadOptions } from \"./downloader/downloadOptions.js\";\nexport { default as DownloadError } from \"./downloader/dtos/downloadError.js\";\nexport { default as DownloadErrorCode } from \"./downloader/dtos/downloadErrorCode.js\";\nexport { default as DownloadFileInfo } from \"./downloader/dtos/downloadFileInfo.js\";\nexport { default as DownloadInfo } from \"./downloader/dtos/downloadInfo.js\";\nexport { default as DownloaderRestoredState } from \"./downloader/dtos/downloaderRestoredState.js\";\nexport { default as DownloadFileChunkInfo } from \"./downloader/dtos/downloadFileChunkInfo.js\";\nexport { default as TransferDownloadEvent } from \"./downloader/dtos/downloadEvent.js\";\nexport { default as DownloadCommand } from \"./downloader/dtos/downloadCommand.js\";\nexport { default as DownloadFilesCommand } from \"./downloader/dtos/downloadFilesCommand.js\";\nexport { default as TransferFileDto } from \"./utils/api/dtos/transferFileDto.js\";\nexport { default as DownloadTrackerFileInfo } from \"./downloader/dtos/downloadTrackerFileInfo.js\";\nexport { default as DownloadTrackerProgressInfo } from \"./downloader/dtos/downloadTrackerProgressInfo.js\";\nexport { default as DownloadRegistrationMode } from \"./downloader/dtos/downloadRegistrationMode.js\";\nexport { default as DownloadFolderResolver } from \"./downloader/downloadFolderResolver.js\";\n\nexport { default as TransferDownloader } from \"./client/downloader/transferDownloader.js\";\nexport { default as DownloaderCore } from \"./client/downloader/downloaderCore.js\";\n\nexport { default as AutoDownloadEventArgs } from \"./autoDownloader/eventArgs/autoDownloadEventArgs.js\";\nexport { default as AutoDownloadFailedEventArgs } from \"./autoDownloader/eventArgs/autoDownloadFailedEventArgs.js\";\nexport { default as AutoDownloadProgressedEventArgs } from \"./autoDownloader/eventArgs/autoDownloadProgressedEventArgs.js\";\nexport { default as AutoDownloadUnhealthyEventArgs } from \"./autoDownloader/eventArgs/autoDownloadUnhealthyEventArgs.js\";\nexport { default as AutoDownloadStartedEventArgs } from \"./autoDownloader/eventArgs/autoDownloadStartedEventArgs.js\";\nexport { default as NewTransfersCheckCompletedEventArgs } from \"./autoDownloader/eventArgs/newTransfersCheckCompletedEventArgs.js\";\nexport { default as AutoDownloadStartingFailedEventArgs } from \"./autoDownloader/eventArgs/autoDownloadStartingFailedEventArgs.js\";\nexport { default as CheckingForNewTransfersStartedEventArgs } from \"./autoDownloader/eventArgs/checkingForNewTransfersStartedEventArgs.js\";\n\nexport { default as NewInboxTransfer } from \"./autoDownloader/newInboxTransfersRetriever/newInboxTransfer.js\";\n\nexport { default as AutoDownloaderRecoverableState } from \"./autoDownloader/state/autoDownloaderRecoverableState.js\";\nexport { default as AutoDownloaderStateSnapshot } from \"./autoDownloader/state/autoDownloaderStateSnapshot.js\";\n\nexport { default as AutoDownloader } from \"./autoDownloader/autoDownloader.js\";\nexport { default as AutoDownloaderError } from \"./autoDownloader/autoDownloaderError.js\";\nexport { default as AutoDownloaderEvent } from \"./autoDownloader/autoDownloaderEvent.js\";\nexport { default as AutoDownloaderOptions } from \"./autoDownloader/autoDownloaderOptions.js\";\nexport { default as AutoDownloaderStateSerializer } from \"./autoDownloader/autoDownloaderStateSerializer.js\";\nexport { default as TransferDownloaderFactory } from \"./autoDownloader/transferDownloaderFactory.js\";"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.web.js","sourceRoot":"","sources":["../../src/index.web.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAE3B,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,kCAAkC,CAAC;AAC5E,OAAO,EAAE,OAAO,IAAI,yBAAyB,EAAE,MAAM,iDAAiD,CAAC;AACvG,OAAO,EAAE,OAAO,IAAI,0BAA0B,EAAE,MAAM,+CAA+C,CAAC;AAEtG,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,uCAAuC,CAAC;AAEnF,OAAO,EAAE,OAAO,IAAI,sBAAsB,EAAE,MAAM,sEAAsE,CAAC;AACzH,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAErF,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,8CAA8C,CAAC;AAE9F,OAAO,EAAE,OAAO,IAAI,6BAA6B,EAAE,MAAM,yDAAyD,CAAC","sourcesContent":["export * from \"./index.js\";\
|
|
1
|
+
{"version":3,"file":"index.web.js","sourceRoot":"","sources":["../../src/index.web.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAE3B,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,kCAAkC,CAAC;AAC5E,OAAO,EAAE,OAAO,IAAI,yBAAyB,EAAE,MAAM,iDAAiD,CAAC;AACvG,OAAO,EAAE,OAAO,IAAI,0BAA0B,EAAE,MAAM,+CAA+C,CAAC;AAEtG,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,uCAAuC,CAAC;AAEnF,OAAO,EAAE,OAAO,IAAI,sBAAsB,EAAE,MAAM,sEAAsE,CAAC;AACzH,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAErF,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,8CAA8C,CAAC;AAE9F,OAAO,EAAE,OAAO,IAAI,6BAA6B,EAAE,MAAM,yDAAyD,CAAC","sourcesContent":["export * from \"./index.js\";\n\nexport { default as WebApiClient } from \"./utils/api/web/webApiClient.js\";\nexport { default as WebClientBase } from \"./utils/api/web/webClientBase.js\";\nexport { default as WebFileServerUploadClient } from \"./uploader/api/web/webFileServerUploadClient.js\";\nexport { default as WebFileServerClientFactory } from \"./utils/api/web/webFileServerClientFactory.js\";\n\nexport { default as WebEventsEngine } from \"./utils/events/web/webEventsEngine.js\";\n\nexport { default as WebChunkStreamProvider } from \"./utils/fileSystem/web/chunkStreamProvider/webChunkStreamProvider.js\";\nexport { default as WebFileDetails } from \"./utils/fileSystem/web/webFileDetails.js\";\n\nexport { default as WebTransferUploader } from \"./client/uploader/web/webTransferUploader.js\";\n\nexport { default as WebChunkStreamProviderFactory } from \"./utils/fileSystem/web/webChunkStreamProviderFactory.js\";"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handshakeRequest.js","sourceRoot":"","sources":["../../../../../src/uploader/api/dtos/handshakeRequest.ts"],"names":[],"mappings":"","sourcesContent":["interface HandshakeRequest {\
|
|
1
|
+
{"version":3,"file":"handshakeRequest.js","sourceRoot":"","sources":["../../../../../src/uploader/api/dtos/handshakeRequest.ts"],"names":[],"mappings":"","sourcesContent":["interface HandshakeRequest {\n transferKey: string,\n transferId: string,\n}\n\nexport default HandshakeRequest;"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handshakeResponse.js","sourceRoot":"","sources":["../../../../../src/uploader/api/dtos/handshakeResponse.ts"],"names":[],"mappings":"","sourcesContent":["interface HandshakeResponse {\
|
|
1
|
+
{"version":3,"file":"handshakeResponse.js","sourceRoot":"","sources":["../../../../../src/uploader/api/dtos/handshakeResponse.ts"],"names":[],"mappings":"","sourcesContent":["interface HandshakeResponse {\n sessionGuid: string,\n aesKey: Buffer,\n}\n\nexport default HandshakeResponse;"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pingResponse.js","sourceRoot":"","sources":["../../../../../src/uploader/api/dtos/pingResponse.ts"],"names":[],"mappings":"","sourcesContent":["interface LatencyResponse {\
|
|
1
|
+
{"version":3,"file":"pingResponse.js","sourceRoot":"","sources":["../../../../../src/uploader/api/dtos/pingResponse.ts"],"names":[],"mappings":"","sourcesContent":["interface LatencyResponse {\n latencyInMs: number;\n}\n\nexport default LatencyResponse;"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sendChunkRequest.js","sourceRoot":"","sources":["../../../../../src/uploader/api/dtos/sendChunkRequest.ts"],"names":[],"mappings":"","sourcesContent":["interface SendChunkRequest {\
|
|
1
|
+
{"version":3,"file":"sendChunkRequest.js","sourceRoot":"","sources":["../../../../../src/uploader/api/dtos/sendChunkRequest.ts"],"names":[],"mappings":"","sourcesContent":["interface SendChunkRequest {\n sessionGuid: string,\n fileSizeInBytes: number,\n chunkStartPosition: number,\n aesKey: Uint8Array,\n fileDestinationPathInTransfer: string,\n fileName: string,\n}\n\nexport default SendChunkRequest;"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fileServerUdpClient.js","sourceRoot":"","sources":["../../../../src/uploader/api/fileServerUdpClient.ts"],"names":[],"mappings":"","sourcesContent":["import type { RemoteInfo } from 'dgram';\
|
|
1
|
+
{"version":3,"file":"fileServerUdpClient.js","sourceRoot":"","sources":["../../../../src/uploader/api/fileServerUdpClient.ts"],"names":[],"mappings":"","sourcesContent":["import type { RemoteInfo } from 'dgram';\n\nimport type LatencyResponse from \"./dtos/pingResponse.js\";\nimport type HandshakeRequest from './dtos/handshakeRequest.js';\nimport type SendChunkRequest from './dtos/sendChunkRequest.js';\nimport type HandshakeResponse from './dtos/handshakeResponse.js';\nimport type ChunkStreamProvider from '../../utils/fileSystem/chunkStreamProvider.js';\n\ninterface FileServerUdpClient {\n addMessageListener(listener: (msg: Buffer, rinfo: RemoteInfo) => void): void;\n removeMessageListener(listener: (msg: Buffer, rinfo: RemoteInfo) => void): void;\n addErrorListener(listener: (msg: Buffer, rinfo: RemoteInfo) => void): void;\n removeErrorListener(listener: (msg: Buffer, rinfo: RemoteInfo) => void): void;\n connect(): Promise<void>;\n close(): Promise<void>;\n ping(): Promise<LatencyResponse>;\n handshake(request: HandshakeRequest): Promise<HandshakeResponse>;\n sendChunk(request: SendChunkRequest, chunkStreamProvider: ChunkStreamProvider): Promise<LatencyResponse>;\n}\n\nexport default FileServerUdpClient;"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fileServerUploadClient.js","sourceRoot":"","sources":["../../../../src/uploader/api/fileServerUploadClient.ts"],"names":[],"mappings":"","sourcesContent":["import type ChunkProgressEvent from \"../../utils/events/chunkProgressEvent.js\";\
|
|
1
|
+
{"version":3,"file":"fileServerUploadClient.js","sourceRoot":"","sources":["../../../../src/uploader/api/fileServerUploadClient.ts"],"names":[],"mappings":"","sourcesContent":["import type ChunkProgressEvent from \"../../utils/events/chunkProgressEvent.js\";\nimport type ChunkStreamProvider from \"../../utils/fileSystem/chunkStreamProvider.js\";\nimport type SendFileChunkRequest from \"../../utils/api/dtos/sendFileChunkRequest.js\";\nimport type { PauseSignal } from \"../pauseController.js\";\n\n// This should be used as a transient object - a new instance for every chunk\ninterface FileServerUploadClient {\n sendFileChunk(request: SendFileChunkRequest, chunkStreamProvider: ChunkStreamProvider, pauseSignal: PauseSignal, abortSignal: AbortSignal): Promise<void>\n addEventListener(eventName: `progress`, handler: (event: ChunkProgressEvent) => void): void\n}\n\nexport default FileServerUploadClient;"]}
|
|
@@ -10,14 +10,14 @@ const pingPrefix = Buffer.from(`P2`);
|
|
|
10
10
|
const handshakePrefix = Buffer.from(`H2`);
|
|
11
11
|
const chunkDataPrefix = Buffer.from(`D2`);
|
|
12
12
|
const encryptedPrefix = Buffer.from(`E2`);
|
|
13
|
-
const filemailPublicKey = `-----BEGIN PUBLIC KEY-----
|
|
14
|
-
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvmW7lnKl2UN7gLrLjsIP
|
|
15
|
-
WMMA2Nc8zROtwcGuumiN5bpw8ju/58MSE2DiYnGJKOVXxI2A52FgVK4I9hXKstwZ
|
|
16
|
-
5Sotcf3BXw1wMusnHwVGYRsQob76EJKiqQODc/pLyLtRDiFRY5tgafkW0dU1X8AU
|
|
17
|
-
kjtAawPp7ed/Z6DJaV2jWOQyJ9sCBXGhnNSExPOeSFvRKFM5vfurPXPXG4ii6tGU
|
|
18
|
-
XaqjVeX5+b9dJFTJ2HzUSUxAkYUCS1y4E9jehlimM7gGTR0m7ISQa/bg1eE1X8iA
|
|
19
|
-
D2DVevYVGqs9A6p+e/WJ2dMXU4XxBmfxWZe+szqgfU3wqvOmCS5JrGUKi6SAx8a5
|
|
20
|
-
WQIDAQAB
|
|
13
|
+
const filemailPublicKey = `-----BEGIN PUBLIC KEY-----
|
|
14
|
+
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvmW7lnKl2UN7gLrLjsIP
|
|
15
|
+
WMMA2Nc8zROtwcGuumiN5bpw8ju/58MSE2DiYnGJKOVXxI2A52FgVK4I9hXKstwZ
|
|
16
|
+
5Sotcf3BXw1wMusnHwVGYRsQob76EJKiqQODc/pLyLtRDiFRY5tgafkW0dU1X8AU
|
|
17
|
+
kjtAawPp7ed/Z6DJaV2jWOQyJ9sCBXGhnNSExPOeSFvRKFM5vfurPXPXG4ii6tGU
|
|
18
|
+
XaqjVeX5+b9dJFTJ2HzUSUxAkYUCS1y4E9jehlimM7gGTR0m7ISQa/bg1eE1X8iA
|
|
19
|
+
D2DVevYVGqs9A6p+e/WJ2dMXU4XxBmfxWZe+szqgfU3wqvOmCS5JrGUKi6SAx8a5
|
|
20
|
+
WQIDAQAB
|
|
21
21
|
-----END PUBLIC KEY-----`;
|
|
22
22
|
export default class NodeFileServerUdpClient {
|
|
23
23
|
#address;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nodeFileServerUdpClient.js","sourceRoot":"","sources":["../../../../../src/uploader/api/node/nodeFileServerUdpClient.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-await-in-loop */\r\nimport path from 'path';\r\nimport { clearTimeout } from 'timers';\r\nimport { publicEncrypt, randomBytes, createCipheriv } from 'crypto';\r\n\r\nimport type { RemoteInfo } from 'dgram';\r\nimport type { ReadableStream as NodeReadableStream } from \"stream/web\";\r\n\r\nimport UdpClient from 'promisified-udp-client';\r\nimport sleep from 'abortable-sleep';\r\n\r\nimport { v4 as newGuid, parse as guidToBytes, stringify as bytesToGuid } from 'uuid';\r\n\r\nimport FsError from '../../../utils/fileSystem/fsError.js';\r\n\r\nimport type LatencyResponse from \"../dtos/pingResponse.js\";\r\nimport type HandshakeRequest from '../dtos/handshakeRequest.js';\r\nimport type SendChunkRequest from '../dtos/sendChunkRequest.js';\r\nimport type FileServerUdpClient from '../fileServerUdpClient.js';\r\nimport type HandshakeResponse from '../dtos/handshakeResponse.js';\r\nimport type ChunkStreamProvider from '../../../utils/fileSystem/chunkStreamProvider.js';\r\n\r\nconst pingPrefix = Buffer.from(`P2`);\r\nconst handshakePrefix = Buffer.from(`H2`);\r\nconst chunkDataPrefix = Buffer.from(`D2`);\r\nconst encryptedPrefix = Buffer.from(`E2`);\r\n\r\nconst filemailPublicKey = `-----BEGIN PUBLIC KEY-----\r\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvmW7lnKl2UN7gLrLjsIP\r\nWMMA2Nc8zROtwcGuumiN5bpw8ju/58MSE2DiYnGJKOVXxI2A52FgVK4I9hXKstwZ\r\n5Sotcf3BXw1wMusnHwVGYRsQob76EJKiqQODc/pLyLtRDiFRY5tgafkW0dU1X8AU\r\nkjtAawPp7ed/Z6DJaV2jWOQyJ9sCBXGhnNSExPOeSFvRKFM5vfurPXPXG4ii6tGU\r\nXaqjVeX5+b9dJFTJ2HzUSUxAkYUCS1y4E9jehlimM7gGTR0m7ISQa/bg1eE1X8iA\r\nD2DVevYVGqs9A6p+e/WJ2dMXU4XxBmfxWZe+szqgfU3wqvOmCS5JrGUKi6SAx8a5\r\nWQIDAQAB\r\n-----END PUBLIC KEY-----`;\r\n\r\nexport default class NodeFileServerUdpClient implements FileServerUdpClient {\r\n #address: string;\r\n #port: number;\r\n\r\n #requestTimeout: number;\r\n #retries: number;\r\n #retryDelay: number;\r\n\r\n #abortSignal?: AbortSignal;\r\n\r\n #udpClient: UdpClient;\r\n\r\n constructor(address: string, port: number, requestTimeout: number, retries: number, abortSignal?: AbortSignal, retryDelay: number = 1000) {\r\n this.#address = address;\r\n this.#port = port;\r\n this.#requestTimeout = requestTimeout;\r\n this.#retries = retries;\r\n this.#retryDelay = retryDelay;\r\n this.#abortSignal = abortSignal;\r\n\r\n this.#udpClient = new UdpClient(abortSignal);\r\n }\r\n\r\n addMessageListener(listener: (msg: Buffer, rinfo: RemoteInfo) => void) {\r\n this.#udpClient.addMessageListener(listener);\r\n }\r\n\r\n removeMessageListener(listener: (msg: Buffer, rinfo: RemoteInfo) => void) {\r\n this.#udpClient.removeMessageListener(listener);\r\n }\r\n\r\n addErrorListener(listener: (msg: Buffer, rinfo: RemoteInfo) => void) {\r\n this.#udpClient.addErrorListener(listener);\r\n }\r\n\r\n removeErrorListener(listener: (msg: Buffer, rinfo: RemoteInfo) => void) {\r\n this.#udpClient.removeErrorListener(listener);\r\n }\r\n\r\n async connect(): Promise<void> {\r\n await this.#udpClient.connect(this.#port, this.#address);\r\n }\r\n\r\n async close(): Promise<void> {\r\n await this.#udpClient.close();\r\n }\r\n\r\n private async retryMechanism<T>(apiCall: () => Promise<T>): Promise<T> {\r\n let lastError: Error | undefined;\r\n\r\n for (let attempt = 0; attempt <= this.#retries; attempt++) {\r\n try {\r\n const result = await apiCall();\r\n return result;\r\n }\r\n catch (error) {\r\n if (attempt < this.#retries) {\r\n lastError = error as Error;\r\n await sleep(this.#retryDelay * attempt, this.#abortSignal);\r\n }\r\n\r\n if (this.#abortSignal?.aborted)\r\n throw new Error(`Aborted`);\r\n }\r\n }\r\n\r\n throw lastError;\r\n }\r\n\r\n async ping(): Promise<LatencyResponse> {\r\n return await this.retryMechanism(async () => await this.pingCall());\r\n }\r\n\r\n async handshake(request: HandshakeRequest): Promise<HandshakeResponse> {\r\n return await this.retryMechanism(async () => await this.handshakeCall(request));\r\n }\r\n\r\n async sendChunk(request: SendChunkRequest, chunkStreamProvider: ChunkStreamProvider): Promise<LatencyResponse> {\r\n try {\r\n return await this.retryMechanism(async () => await this.sendChunkCall(request, chunkStreamProvider));\r\n }\r\n catch (error) {\r\n if (this.isWrappedCreatingFileReadStreamException(error as Error))\r\n throw new FsError((error as Error).message);\r\n\r\n throw error;\r\n }\r\n finally {\r\n if (!chunkStreamProvider.isReleased)\r\n await chunkStreamProvider.release();\r\n }\r\n }\r\n\r\n private isWrappedCreatingFileReadStreamException(error: Error): boolean {\r\n return error.message === `CreatingFileReadStreamException`;\r\n }\r\n\r\n private async pingCall(): Promise<LatencyResponse> {\r\n const packetGuid = newGuid();\r\n\r\n const udpRequest = this.createPingRequest(packetGuid);\r\n\r\n return await this.makeCall(udpRequest, packetGuid, (sentTime, responseTime) => this.createLatencyResponse(sentTime, responseTime));\r\n }\r\n\r\n private createPingRequest(packetGuid: string): Buffer {\r\n const guidBytes = guidToBytes(packetGuid);\r\n return Buffer.concat([pingPrefix, guidBytes]);\r\n }\r\n\r\n private createLatencyResponse(sentTime: number, responseTime: number): LatencyResponse {\r\n return {\r\n latencyInMs: responseTime - sentTime,\r\n };\r\n }\r\n\r\n private async handshakeCall(request: HandshakeRequest): Promise<HandshakeResponse> {\r\n const packetGuid = newGuid();\r\n const sessionGuid = newGuid();\r\n const aesKey = this.generateAes256Key();\r\n\r\n const udpRequest = this.createHandshakeRequest(packetGuid, sessionGuid, aesKey, request);\r\n\r\n return await this.makeCall(udpRequest, packetGuid, () => this.createHandshakeResponse(sessionGuid, aesKey));\r\n }\r\n\r\n private generateAes256Key(): Buffer {\r\n return randomBytes(32);\r\n }\r\n\r\n private createHandshakeRequest(packetGuid: string, sessionGuid: string, aesKey: Buffer, request: HandshakeRequest) {\r\n const packetGuidBytes = guidToBytes(packetGuid);\r\n const sessionGuidBytes = guidToBytes(sessionGuid);\r\n const transferKeyBytes = guidToBytes(this.transferKeyToGuid(request.transferKey));\r\n const transferIdBytes = Buffer.from(request.transferId);\r\n\r\n const encryptableRequestPart = Buffer.concat([\r\n packetGuidBytes,\r\n sessionGuidBytes,\r\n transferKeyBytes,\r\n transferIdBytes,\r\n aesKey,\r\n ]);\r\n\r\n const encryptedRequestPart = this.publicRsaEncrypt(encryptableRequestPart);\r\n\r\n return Buffer.concat([handshakePrefix, encryptedRequestPart]);\r\n }\r\n\r\n private transferKeyToGuid(transferKey: string): string {\r\n return `${transferKey.slice(0, 8)}-${transferKey.slice(8, 12)}-${transferKey.slice(12, 16)}-${transferKey.slice(16, 20)}-${transferKey.slice(20)}`;\r\n }\r\n\r\n private publicRsaEncrypt(data: Buffer) {\r\n return publicEncrypt(filemailPublicKey, data);\r\n }\r\n\r\n private createHandshakeResponse(sessionGuid: string, aesKey: Buffer): HandshakeResponse {\r\n return {\r\n aesKey,\r\n sessionGuid,\r\n };\r\n }\r\n\r\n private async sendChunkCall(request: SendChunkRequest, chunkStreamProvider: ChunkStreamProvider): Promise<LatencyResponse> {\r\n const packetGuid = newGuid();\r\n\r\n const chunkReadStream = await chunkStreamProvider.getChunkReadStream(undefined, this.#abortSignal);\r\n const chunkBytes = await this.readStreamToEnd(chunkReadStream);\r\n\r\n const udpRequest = this.createSendChunkRequest(packetGuid, request, chunkBytes);\r\n\r\n return await this.makeCall(udpRequest, packetGuid, (sentTime, responseTime) => this.createLatencyResponse(sentTime, responseTime));\r\n }\r\n\r\n private async readStreamToEnd(stream: ReadableStream | NodeReadableStream) {\r\n const reader = stream.getReader();\r\n\r\n const chunks: Uint8Array[] = [];\r\n\r\n while (true) {\r\n const { done, value } = await reader.read();\r\n\r\n if (done)\r\n break;\r\n\r\n if (value)\r\n chunks.push(value);\r\n }\r\n\r\n const totalLength = chunks.reduce((sum, c) => sum + c.length, 0);\r\n const merged = new Uint8Array(totalLength);\r\n\r\n let offset = 0;\r\n\r\n for (const c of chunks) {\r\n merged.set(c, offset);\r\n offset += c.length;\r\n }\r\n\r\n return Buffer.from(merged);\r\n }\r\n\r\n private createSendChunkRequest(packetGuid: string, request: SendChunkRequest, chunkBytes: Buffer) {\r\n const fullDestinationFileNameString = path.posix.join(request.fileDestinationPathInTransfer, request.fileName);\r\n const fullDestinationFileName = Buffer.from(fullDestinationFileNameString);\r\n\r\n const fullDestinationFileNameLength = Buffer.alloc(2);\r\n fullDestinationFileNameLength.writeUint16BE(fullDestinationFileName.length);\r\n\r\n const fileSize = Buffer.alloc(8);\r\n fileSize.writeBigInt64BE(BigInt(request.fileSizeInBytes));\r\n\r\n const chunkStartPosition = Buffer.alloc(8);\r\n chunkStartPosition.writeBigInt64BE(BigInt(request.chunkStartPosition));\r\n\r\n const encryptableRequestPart = Buffer.concat([\r\n chunkDataPrefix,\r\n fullDestinationFileNameLength,\r\n fileSize,\r\n chunkStartPosition,\r\n fullDestinationFileName,\r\n chunkBytes,\r\n ]);\r\n\r\n const aesKey = Buffer.from(request.aesKey).subarray(0, 16); // .subarray directly on request.aesKey throws in Electron\r\n\r\n const { encryptedData, iv, authTag } = this.aesEncrypt(encryptableRequestPart, aesKey);\r\n\r\n const packetGuidBytes = guidToBytes(packetGuid);\r\n const sessionGuidBytes = guidToBytes(request.sessionGuid);\r\n\r\n return Buffer.concat([\r\n encryptedPrefix,\r\n packetGuidBytes,\r\n sessionGuidBytes,\r\n iv,\r\n authTag,\r\n encryptedData,\r\n ]);\r\n }\r\n\r\n private aesEncrypt(data: Buffer, aesKey: Buffer): { encryptedData: Buffer, iv: Buffer, authTag: Buffer } {\r\n const iv = randomBytes(12);\r\n\r\n const cipher = createCipheriv(`aes-128-gcm`, aesKey, iv);\r\n\r\n let encryptedData = cipher.update(data);\r\n encryptedData = Buffer.concat([encryptedData, cipher.final()]);\r\n\r\n const authTag = cipher.getAuthTag();\r\n\r\n return { encryptedData, iv, authTag };\r\n }\r\n\r\n private async makeCall<T>(request: string | readonly any[] | Uint8Array, packetGuid: string, createResponse?: (sentTime: number, responseTime: number, message: Buffer) => T): Promise<T> {\r\n return new Promise<T>((resolve, reject) => {\r\n const sentTime = new Date().getTime();\r\n\r\n const timeout = setTimeout(() => {\r\n cleanup();\r\n reject(new Error(`Timeout`));\r\n }, this.#requestTimeout);\r\n\r\n const responseListener = (msg: Buffer) => {\r\n const responseTime = new Date().getTime();\r\n\r\n if (!this.isAckResponse(msg, packetGuid))\r\n return;\r\n\r\n cleanup();\r\n\r\n if (!createResponse)\r\n resolve(undefined as any);\r\n else {\r\n const response = createResponse(sentTime, responseTime, msg);\r\n resolve(response);\r\n }\r\n };\r\n\r\n this.addMessageListener(responseListener);\r\n\r\n const sendPromise = this.#udpClient.send(request);\r\n\r\n const errorAndAbortHandler = (error: Error) => {\r\n cleanup();\r\n reject(error);\r\n };\r\n\r\n const abortSignalListener = () => errorAndAbortHandler(new Error(`Aborted`));\r\n\r\n const cleanup = () => {\r\n this.removeMessageListener(responseListener);\r\n clearTimeout(timeout);\r\n this.#abortSignal?.removeEventListener(`abort`, abortSignalListener);\r\n };\r\n\r\n sendPromise.catch(error => errorAndAbortHandler(error));\r\n this.#abortSignal?.addEventListener(`abort`, abortSignalListener);\r\n });\r\n }\r\n\r\n private isAckResponse(msg: Buffer, guid: string) {\r\n try {\r\n if (!this.isAck(msg) || msg.length !== 18)\r\n return false;\r\n\r\n const responseGuid = bytesToGuid(msg, 2);\r\n\r\n return guid === responseGuid;\r\n }\r\n catch {\r\n return false;\r\n }\r\n }\r\n\r\n private isAck(msg: Buffer) {\r\n const prefix = msg.subarray(0, 2).toString(`utf8`);\r\n return prefix === `A1`;\r\n }\r\n}"]}
|
|
1
|
+
{"version":3,"file":"nodeFileServerUdpClient.js","sourceRoot":"","sources":["../../../../../src/uploader/api/node/nodeFileServerUdpClient.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-await-in-loop */\nimport path from 'path';\nimport { clearTimeout } from 'timers';\nimport { publicEncrypt, randomBytes, createCipheriv } from 'crypto';\n\nimport type { RemoteInfo } from 'dgram';\nimport type { ReadableStream as NodeReadableStream } from \"stream/web\";\n\nimport UdpClient from 'promisified-udp-client';\nimport sleep from 'abortable-sleep';\n\nimport { v4 as newGuid, parse as guidToBytes, stringify as bytesToGuid } from 'uuid';\n\nimport FsError from '../../../utils/fileSystem/fsError.js';\n\nimport type LatencyResponse from \"../dtos/pingResponse.js\";\nimport type HandshakeRequest from '../dtos/handshakeRequest.js';\nimport type SendChunkRequest from '../dtos/sendChunkRequest.js';\nimport type FileServerUdpClient from '../fileServerUdpClient.js';\nimport type HandshakeResponse from '../dtos/handshakeResponse.js';\nimport type ChunkStreamProvider from '../../../utils/fileSystem/chunkStreamProvider.js';\n\nconst pingPrefix = Buffer.from(`P2`);\nconst handshakePrefix = Buffer.from(`H2`);\nconst chunkDataPrefix = Buffer.from(`D2`);\nconst encryptedPrefix = Buffer.from(`E2`);\n\nconst filemailPublicKey = `-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvmW7lnKl2UN7gLrLjsIP\nWMMA2Nc8zROtwcGuumiN5bpw8ju/58MSE2DiYnGJKOVXxI2A52FgVK4I9hXKstwZ\n5Sotcf3BXw1wMusnHwVGYRsQob76EJKiqQODc/pLyLtRDiFRY5tgafkW0dU1X8AU\nkjtAawPp7ed/Z6DJaV2jWOQyJ9sCBXGhnNSExPOeSFvRKFM5vfurPXPXG4ii6tGU\nXaqjVeX5+b9dJFTJ2HzUSUxAkYUCS1y4E9jehlimM7gGTR0m7ISQa/bg1eE1X8iA\nD2DVevYVGqs9A6p+e/WJ2dMXU4XxBmfxWZe+szqgfU3wqvOmCS5JrGUKi6SAx8a5\nWQIDAQAB\n-----END PUBLIC KEY-----`;\n\nexport default class NodeFileServerUdpClient implements FileServerUdpClient {\n #address: string;\n #port: number;\n\n #requestTimeout: number;\n #retries: number;\n #retryDelay: number;\n\n #abortSignal?: AbortSignal;\n\n #udpClient: UdpClient;\n\n constructor(address: string, port: number, requestTimeout: number, retries: number, abortSignal?: AbortSignal, retryDelay: number = 1000) {\n this.#address = address;\n this.#port = port;\n this.#requestTimeout = requestTimeout;\n this.#retries = retries;\n this.#retryDelay = retryDelay;\n this.#abortSignal = abortSignal;\n\n this.#udpClient = new UdpClient(abortSignal);\n }\n\n addMessageListener(listener: (msg: Buffer, rinfo: RemoteInfo) => void) {\n this.#udpClient.addMessageListener(listener);\n }\n\n removeMessageListener(listener: (msg: Buffer, rinfo: RemoteInfo) => void) {\n this.#udpClient.removeMessageListener(listener);\n }\n\n addErrorListener(listener: (msg: Buffer, rinfo: RemoteInfo) => void) {\n this.#udpClient.addErrorListener(listener);\n }\n\n removeErrorListener(listener: (msg: Buffer, rinfo: RemoteInfo) => void) {\n this.#udpClient.removeErrorListener(listener);\n }\n\n async connect(): Promise<void> {\n await this.#udpClient.connect(this.#port, this.#address);\n }\n\n async close(): Promise<void> {\n await this.#udpClient.close();\n }\n\n private async retryMechanism<T>(apiCall: () => Promise<T>): Promise<T> {\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt <= this.#retries; attempt++) {\n try {\n const result = await apiCall();\n return result;\n }\n catch (error) {\n if (attempt < this.#retries) {\n lastError = error as Error;\n await sleep(this.#retryDelay * attempt, this.#abortSignal);\n }\n\n if (this.#abortSignal?.aborted)\n throw new Error(`Aborted`);\n }\n }\n\n throw lastError;\n }\n\n async ping(): Promise<LatencyResponse> {\n return await this.retryMechanism(async () => await this.pingCall());\n }\n\n async handshake(request: HandshakeRequest): Promise<HandshakeResponse> {\n return await this.retryMechanism(async () => await this.handshakeCall(request));\n }\n\n async sendChunk(request: SendChunkRequest, chunkStreamProvider: ChunkStreamProvider): Promise<LatencyResponse> {\n try {\n return await this.retryMechanism(async () => await this.sendChunkCall(request, chunkStreamProvider));\n }\n catch (error) {\n if (this.isWrappedCreatingFileReadStreamException(error as Error))\n throw new FsError((error as Error).message);\n\n throw error;\n }\n finally {\n if (!chunkStreamProvider.isReleased)\n await chunkStreamProvider.release();\n }\n }\n\n private isWrappedCreatingFileReadStreamException(error: Error): boolean {\n return error.message === `CreatingFileReadStreamException`;\n }\n\n private async pingCall(): Promise<LatencyResponse> {\n const packetGuid = newGuid();\n\n const udpRequest = this.createPingRequest(packetGuid);\n\n return await this.makeCall(udpRequest, packetGuid, (sentTime, responseTime) => this.createLatencyResponse(sentTime, responseTime));\n }\n\n private createPingRequest(packetGuid: string): Buffer {\n const guidBytes = guidToBytes(packetGuid);\n return Buffer.concat([pingPrefix, guidBytes]);\n }\n\n private createLatencyResponse(sentTime: number, responseTime: number): LatencyResponse {\n return {\n latencyInMs: responseTime - sentTime,\n };\n }\n\n private async handshakeCall(request: HandshakeRequest): Promise<HandshakeResponse> {\n const packetGuid = newGuid();\n const sessionGuid = newGuid();\n const aesKey = this.generateAes256Key();\n\n const udpRequest = this.createHandshakeRequest(packetGuid, sessionGuid, aesKey, request);\n\n return await this.makeCall(udpRequest, packetGuid, () => this.createHandshakeResponse(sessionGuid, aesKey));\n }\n\n private generateAes256Key(): Buffer {\n return randomBytes(32);\n }\n\n private createHandshakeRequest(packetGuid: string, sessionGuid: string, aesKey: Buffer, request: HandshakeRequest) {\n const packetGuidBytes = guidToBytes(packetGuid);\n const sessionGuidBytes = guidToBytes(sessionGuid);\n const transferKeyBytes = guidToBytes(this.transferKeyToGuid(request.transferKey));\n const transferIdBytes = Buffer.from(request.transferId);\n\n const encryptableRequestPart = Buffer.concat([\n packetGuidBytes,\n sessionGuidBytes,\n transferKeyBytes,\n transferIdBytes,\n aesKey,\n ]);\n\n const encryptedRequestPart = this.publicRsaEncrypt(encryptableRequestPart);\n\n return Buffer.concat([handshakePrefix, encryptedRequestPart]);\n }\n\n private transferKeyToGuid(transferKey: string): string {\n return `${transferKey.slice(0, 8)}-${transferKey.slice(8, 12)}-${transferKey.slice(12, 16)}-${transferKey.slice(16, 20)}-${transferKey.slice(20)}`;\n }\n\n private publicRsaEncrypt(data: Buffer) {\n return publicEncrypt(filemailPublicKey, data);\n }\n\n private createHandshakeResponse(sessionGuid: string, aesKey: Buffer): HandshakeResponse {\n return {\n aesKey,\n sessionGuid,\n };\n }\n\n private async sendChunkCall(request: SendChunkRequest, chunkStreamProvider: ChunkStreamProvider): Promise<LatencyResponse> {\n const packetGuid = newGuid();\n\n const chunkReadStream = await chunkStreamProvider.getChunkReadStream(undefined, this.#abortSignal);\n const chunkBytes = await this.readStreamToEnd(chunkReadStream);\n\n const udpRequest = this.createSendChunkRequest(packetGuid, request, chunkBytes);\n\n return await this.makeCall(udpRequest, packetGuid, (sentTime, responseTime) => this.createLatencyResponse(sentTime, responseTime));\n }\n\n private async readStreamToEnd(stream: ReadableStream | NodeReadableStream) {\n const reader = stream.getReader();\n\n const chunks: Uint8Array[] = [];\n\n while (true) {\n const { done, value } = await reader.read();\n\n if (done)\n break;\n\n if (value)\n chunks.push(value);\n }\n\n const totalLength = chunks.reduce((sum, c) => sum + c.length, 0);\n const merged = new Uint8Array(totalLength);\n\n let offset = 0;\n\n for (const c of chunks) {\n merged.set(c, offset);\n offset += c.length;\n }\n\n return Buffer.from(merged);\n }\n\n private createSendChunkRequest(packetGuid: string, request: SendChunkRequest, chunkBytes: Buffer) {\n const fullDestinationFileNameString = path.posix.join(request.fileDestinationPathInTransfer, request.fileName);\n const fullDestinationFileName = Buffer.from(fullDestinationFileNameString);\n\n const fullDestinationFileNameLength = Buffer.alloc(2);\n fullDestinationFileNameLength.writeUint16BE(fullDestinationFileName.length);\n\n const fileSize = Buffer.alloc(8);\n fileSize.writeBigInt64BE(BigInt(request.fileSizeInBytes));\n\n const chunkStartPosition = Buffer.alloc(8);\n chunkStartPosition.writeBigInt64BE(BigInt(request.chunkStartPosition));\n\n const encryptableRequestPart = Buffer.concat([\n chunkDataPrefix,\n fullDestinationFileNameLength,\n fileSize,\n chunkStartPosition,\n fullDestinationFileName,\n chunkBytes,\n ]);\n\n const aesKey = Buffer.from(request.aesKey).subarray(0, 16); // .subarray directly on request.aesKey throws in Electron\n\n const { encryptedData, iv, authTag } = this.aesEncrypt(encryptableRequestPart, aesKey);\n\n const packetGuidBytes = guidToBytes(packetGuid);\n const sessionGuidBytes = guidToBytes(request.sessionGuid);\n\n return Buffer.concat([\n encryptedPrefix,\n packetGuidBytes,\n sessionGuidBytes,\n iv,\n authTag,\n encryptedData,\n ]);\n }\n\n private aesEncrypt(data: Buffer, aesKey: Buffer): { encryptedData: Buffer, iv: Buffer, authTag: Buffer } {\n const iv = randomBytes(12);\n\n const cipher = createCipheriv(`aes-128-gcm`, aesKey, iv);\n\n let encryptedData = cipher.update(data);\n encryptedData = Buffer.concat([encryptedData, cipher.final()]);\n\n const authTag = cipher.getAuthTag();\n\n return { encryptedData, iv, authTag };\n }\n\n private async makeCall<T>(request: string | readonly any[] | Uint8Array, packetGuid: string, createResponse?: (sentTime: number, responseTime: number, message: Buffer) => T): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n const sentTime = new Date().getTime();\n\n const timeout = setTimeout(() => {\n cleanup();\n reject(new Error(`Timeout`));\n }, this.#requestTimeout);\n\n const responseListener = (msg: Buffer) => {\n const responseTime = new Date().getTime();\n\n if (!this.isAckResponse(msg, packetGuid))\n return;\n\n cleanup();\n\n if (!createResponse)\n resolve(undefined as any);\n else {\n const response = createResponse(sentTime, responseTime, msg);\n resolve(response);\n }\n };\n\n this.addMessageListener(responseListener);\n\n const sendPromise = this.#udpClient.send(request);\n\n const errorAndAbortHandler = (error: Error) => {\n cleanup();\n reject(error);\n };\n\n const abortSignalListener = () => errorAndAbortHandler(new Error(`Aborted`));\n\n const cleanup = () => {\n this.removeMessageListener(responseListener);\n clearTimeout(timeout);\n this.#abortSignal?.removeEventListener(`abort`, abortSignalListener);\n };\n\n sendPromise.catch(error => errorAndAbortHandler(error));\n this.#abortSignal?.addEventListener(`abort`, abortSignalListener);\n });\n }\n\n private isAckResponse(msg: Buffer, guid: string) {\n try {\n if (!this.isAck(msg) || msg.length !== 18)\n return false;\n\n const responseGuid = bytesToGuid(msg, 2);\n\n return guid === responseGuid;\n }\n catch {\n return false;\n }\n }\n\n private isAck(msg: Buffer) {\n const prefix = msg.subarray(0, 2).toString(`utf8`);\n return prefix === `A1`;\n }\n}"]}
|