@milaboratories/pl-drivers 1.11.59 → 1.11.61
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/dist/_virtual/_rolldown/runtime.cjs +29 -0
- package/dist/clients/constructors.cjs +28 -28
- package/dist/clients/constructors.cjs.map +1 -1
- package/dist/clients/constructors.d.ts +17 -13
- package/dist/clients/constructors.js +28 -26
- package/dist/clients/constructors.js.map +1 -1
- package/dist/clients/crc32c.cjs +8 -13
- package/dist/clients/crc32c.cjs.map +1 -1
- package/dist/clients/crc32c.js +8 -12
- package/dist/clients/crc32c.js.map +1 -1
- package/dist/clients/download.cjs +119 -160
- package/dist/clients/download.cjs.map +1 -1
- package/dist/clients/download.d.ts +45 -41
- package/dist/clients/download.js +115 -137
- package/dist/clients/download.js.map +1 -1
- package/dist/clients/logs.cjs +78 -82
- package/dist/clients/logs.cjs.map +1 -1
- package/dist/clients/logs.d.ts +34 -24
- package/dist/clients/logs.js +77 -80
- package/dist/clients/logs.js.map +1 -1
- package/dist/clients/ls_api.cjs +62 -68
- package/dist/clients/ls_api.cjs.map +1 -1
- package/dist/clients/ls_api.d.ts +15 -11
- package/dist/clients/ls_api.js +61 -66
- package/dist/clients/ls_api.js.map +1 -1
- package/dist/clients/progress.cjs +49 -59
- package/dist/clients/progress.cjs.map +1 -1
- package/dist/clients/progress.d.ts +27 -20
- package/dist/clients/progress.js +48 -57
- package/dist/clients/progress.js.map +1 -1
- package/dist/clients/upload.cjs +189 -250
- package/dist/clients/upload.cjs.map +1 -1
- package/dist/clients/upload.d.ts +44 -34
- package/dist/clients/upload.js +187 -229
- package/dist/clients/upload.js.map +1 -1
- package/dist/drivers/download_blob/blob_key.cjs +9 -26
- package/dist/drivers/download_blob/blob_key.cjs.map +1 -1
- package/dist/drivers/download_blob/blob_key.js +7 -5
- package/dist/drivers/download_blob/blob_key.js.map +1 -1
- package/dist/drivers/download_blob/download_blob.cjs +395 -478
- package/dist/drivers/download_blob/download_blob.cjs.map +1 -1
- package/dist/drivers/download_blob/download_blob.d.ts +102 -100
- package/dist/drivers/download_blob/download_blob.js +388 -453
- package/dist/drivers/download_blob/download_blob.js.map +1 -1
- package/dist/drivers/download_blob/download_blob_task.cjs +128 -163
- package/dist/drivers/download_blob/download_blob_task.cjs.map +1 -1
- package/dist/drivers/download_blob/download_blob_task.js +125 -141
- package/dist/drivers/download_blob/download_blob_task.js.map +1 -1
- package/dist/drivers/download_blob/sparse_cache/cache.cjs +166 -195
- package/dist/drivers/download_blob/sparse_cache/cache.cjs.map +1 -1
- package/dist/drivers/download_blob/sparse_cache/cache.js +164 -193
- package/dist/drivers/download_blob/sparse_cache/cache.js.map +1 -1
- package/dist/drivers/download_blob/sparse_cache/file.cjs +29 -50
- package/dist/drivers/download_blob/sparse_cache/file.cjs.map +1 -1
- package/dist/drivers/download_blob/sparse_cache/file.js +28 -29
- package/dist/drivers/download_blob/sparse_cache/file.js.map +1 -1
- package/dist/drivers/download_blob/sparse_cache/ranges.cjs +48 -76
- package/dist/drivers/download_blob/sparse_cache/ranges.cjs.map +1 -1
- package/dist/drivers/download_blob/sparse_cache/ranges.js +47 -54
- package/dist/drivers/download_blob/sparse_cache/ranges.js.map +1 -1
- package/dist/drivers/download_blob_url/driver.cjs +125 -165
- package/dist/drivers/download_blob_url/driver.cjs.map +1 -1
- package/dist/drivers/download_blob_url/driver.d.ts +45 -42
- package/dist/drivers/download_blob_url/driver.js +123 -144
- package/dist/drivers/download_blob_url/driver.js.map +1 -1
- package/dist/drivers/download_blob_url/driver_id.cjs +4 -4
- package/dist/drivers/download_blob_url/driver_id.cjs.map +1 -1
- package/dist/drivers/download_blob_url/driver_id.js +4 -3
- package/dist/drivers/download_blob_url/driver_id.js.map +1 -1
- package/dist/drivers/download_blob_url/snapshot.cjs +7 -11
- package/dist/drivers/download_blob_url/snapshot.cjs.map +1 -1
- package/dist/drivers/download_blob_url/snapshot.d.ts +10 -5
- package/dist/drivers/download_blob_url/snapshot.js +5 -8
- package/dist/drivers/download_blob_url/snapshot.js.map +1 -1
- package/dist/drivers/download_blob_url/task.cjs +147 -194
- package/dist/drivers/download_blob_url/task.cjs.map +1 -1
- package/dist/drivers/download_blob_url/task.d.ts +55 -57
- package/dist/drivers/download_blob_url/task.js +140 -170
- package/dist/drivers/download_blob_url/task.js.map +1 -1
- package/dist/drivers/download_url/driver.cjs +109 -146
- package/dist/drivers/download_url/driver.cjs.map +1 -1
- package/dist/drivers/download_url/driver.d.ts +59 -57
- package/dist/drivers/download_url/driver.js +107 -125
- package/dist/drivers/download_url/driver.js.map +1 -1
- package/dist/drivers/download_url/task.cjs +104 -137
- package/dist/drivers/download_url/task.cjs.map +1 -1
- package/dist/drivers/download_url/task.d.ts +33 -37
- package/dist/drivers/download_url/task.js +99 -113
- package/dist/drivers/download_url/task.js.map +1 -1
- package/dist/drivers/helpers/download_local_handle.cjs +13 -14
- package/dist/drivers/helpers/download_local_handle.cjs.map +1 -1
- package/dist/drivers/helpers/download_local_handle.js +13 -13
- package/dist/drivers/helpers/download_local_handle.js.map +1 -1
- package/dist/drivers/helpers/download_remote_handle.cjs +23 -24
- package/dist/drivers/helpers/download_remote_handle.cjs.map +1 -1
- package/dist/drivers/helpers/download_remote_handle.js +22 -22
- package/dist/drivers/helpers/download_remote_handle.js.map +1 -1
- package/dist/drivers/helpers/files_cache.cjs +53 -64
- package/dist/drivers/helpers/files_cache.cjs.map +1 -1
- package/dist/drivers/helpers/files_cache.js +52 -62
- package/dist/drivers/helpers/files_cache.js.map +1 -1
- package/dist/drivers/helpers/helpers.cjs +24 -28
- package/dist/drivers/helpers/helpers.cjs.map +1 -1
- package/dist/drivers/helpers/helpers.d.ts +10 -7
- package/dist/drivers/helpers/helpers.js +24 -27
- package/dist/drivers/helpers/helpers.js.map +1 -1
- package/dist/drivers/helpers/logs_handle.cjs +24 -33
- package/dist/drivers/helpers/logs_handle.cjs.map +1 -1
- package/dist/drivers/helpers/logs_handle.js +24 -29
- package/dist/drivers/helpers/logs_handle.js.map +1 -1
- package/dist/drivers/helpers/ls_remote_import_handle.cjs +20 -20
- package/dist/drivers/helpers/ls_remote_import_handle.cjs.map +1 -1
- package/dist/drivers/helpers/ls_remote_import_handle.js +20 -18
- package/dist/drivers/helpers/ls_remote_import_handle.js.map +1 -1
- package/dist/drivers/helpers/ls_storage_entry.cjs +36 -40
- package/dist/drivers/helpers/ls_storage_entry.cjs.map +1 -1
- package/dist/drivers/helpers/ls_storage_entry.js +36 -37
- package/dist/drivers/helpers/ls_storage_entry.js.map +1 -1
- package/dist/drivers/helpers/polling_ops.d.ts +6 -5
- package/dist/drivers/helpers/read_file.cjs +34 -57
- package/dist/drivers/helpers/read_file.cjs.map +1 -1
- package/dist/drivers/helpers/read_file.js +30 -34
- package/dist/drivers/helpers/read_file.js.map +1 -1
- package/dist/drivers/logs.cjs +94 -112
- package/dist/drivers/logs.cjs.map +1 -1
- package/dist/drivers/logs.d.ts +35 -32
- package/dist/drivers/logs.js +93 -110
- package/dist/drivers/logs.js.map +1 -1
- package/dist/drivers/logs_stream.cjs +210 -242
- package/dist/drivers/logs_stream.cjs.map +1 -1
- package/dist/drivers/logs_stream.d.ts +55 -53
- package/dist/drivers/logs_stream.js +209 -240
- package/dist/drivers/logs_stream.js.map +1 -1
- package/dist/drivers/ls.cjs +151 -238
- package/dist/drivers/ls.cjs.map +1 -1
- package/dist/drivers/ls.d.ts +53 -49
- package/dist/drivers/ls.js +148 -216
- package/dist/drivers/ls.js.map +1 -1
- package/dist/drivers/types.cjs +25 -53
- package/dist/drivers/types.cjs.map +1 -1
- package/dist/drivers/types.d.ts +91 -106
- package/dist/drivers/types.js +23 -50
- package/dist/drivers/types.js.map +1 -1
- package/dist/drivers/upload.cjs +127 -153
- package/dist/drivers/upload.cjs.map +1 -1
- package/dist/drivers/upload.d.ts +52 -50
- package/dist/drivers/upload.js +126 -151
- package/dist/drivers/upload.js.map +1 -1
- package/dist/drivers/upload_task.cjs +223 -260
- package/dist/drivers/upload_task.cjs.map +1 -1
- package/dist/drivers/upload_task.d.ts +54 -52
- package/dist/drivers/upload_task.js +221 -258
- package/dist/drivers/upload_task.js.map +1 -1
- package/dist/drivers/urls/url.cjs +30 -35
- package/dist/drivers/urls/url.cjs.map +1 -1
- package/dist/drivers/urls/url.js +28 -33
- package/dist/drivers/urls/url.js.map +1 -1
- package/dist/drivers/virtual_storages.cjs +36 -48
- package/dist/drivers/virtual_storages.cjs.map +1 -1
- package/dist/drivers/virtual_storages.d.ts +6 -2
- package/dist/drivers/virtual_storages.js +32 -46
- package/dist/drivers/virtual_storages.js.map +1 -1
- package/dist/helpers/download.cjs +72 -95
- package/dist/helpers/download.cjs.map +1 -1
- package/dist/helpers/download.d.ts +13 -9
- package/dist/helpers/download.js +71 -93
- package/dist/helpers/download.js.map +1 -1
- package/dist/helpers/download_errors.cjs +28 -27
- package/dist/helpers/download_errors.cjs.map +1 -1
- package/dist/helpers/download_errors.d.ts +16 -13
- package/dist/helpers/download_errors.js +28 -26
- package/dist/helpers/download_errors.js.map +1 -1
- package/dist/helpers/validate.cjs +8 -7
- package/dist/helpers/validate.cjs.map +1 -1
- package/dist/helpers/validate.d.ts +4 -1
- package/dist/helpers/validate.js +6 -5
- package/dist/helpers/validate.js.map +1 -1
- package/dist/index.cjs +75 -79
- package/dist/index.d.ts +22 -22
- package/dist/index.js +22 -21
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.cjs +238 -249
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.cjs.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.client.cjs +27 -27
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.client.cjs.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.client.d.ts +25 -23
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.client.js +26 -25
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.client.js.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.d.ts +51 -87
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.js +238 -245
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.js.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.cjs +295 -289
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.cjs.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.client.cjs +30 -30
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.client.cjs.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.client.js +29 -28
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.client.js.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.d.ts +86 -150
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.js +295 -285
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.js.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.cjs +385 -393
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.cjs.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.client.cjs +34 -34
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.client.cjs.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.client.d.ts +33 -34
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.client.js +33 -32
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.client.js.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.d.ts +78 -129
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.js +385 -387
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.js.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.cjs +570 -468
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.cjs.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.client.cjs +82 -82
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.client.cjs.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.client.d.ts +109 -112
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.client.js +81 -80
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.client.js.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.d.ts +243 -264
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.js +569 -460
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.js.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.cjs +751 -729
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.cjs.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client.cjs +67 -67
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client.cjs.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client.js +66 -65
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client.js.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.d.ts +15 -381
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.js +749 -718
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.js.map +1 -1
- package/dist/proto-grpc/google/protobuf/duration.cjs +92 -100
- package/dist/proto-grpc/google/protobuf/duration.cjs.map +1 -1
- package/dist/proto-grpc/google/protobuf/duration.d.ts +38 -43
- package/dist/proto-grpc/google/protobuf/duration.js +91 -98
- package/dist/proto-grpc/google/protobuf/duration.js.map +1 -1
- package/dist/proto-grpc/google/protobuf/timestamp.cjs +117 -128
- package/dist/proto-grpc/google/protobuf/timestamp.cjs.map +1 -1
- package/dist/proto-grpc/google/protobuf/timestamp.d.ts +50 -55
- package/dist/proto-grpc/google/protobuf/timestamp.js +116 -126
- package/dist/proto-grpc/google/protobuf/timestamp.js.map +1 -1
- package/dist/proto-rest/downloadapi.d.ts +85 -91
- package/dist/proto-rest/index.d.ts +11 -16
- package/dist/proto-rest/progressapi.d.ts +130 -140
- package/dist/proto-rest/streamingapi.d.ts +413 -434
- package/package.json +12 -12
- package/dist/clients/constructors.d.ts.map +0 -1
- package/dist/clients/crc32c.d.ts +0 -2
- package/dist/clients/crc32c.d.ts.map +0 -1
- package/dist/clients/download.d.ts.map +0 -1
- package/dist/clients/logs.d.ts.map +0 -1
- package/dist/clients/ls_api.d.ts.map +0 -1
- package/dist/clients/progress.d.ts.map +0 -1
- package/dist/clients/upload.d.ts.map +0 -1
- package/dist/drivers/download_blob/blob_key.d.ts +0 -5
- package/dist/drivers/download_blob/blob_key.d.ts.map +0 -1
- package/dist/drivers/download_blob/download_blob.d.ts.map +0 -1
- package/dist/drivers/download_blob/download_blob_task.d.ts +0 -56
- package/dist/drivers/download_blob/download_blob_task.d.ts.map +0 -1
- package/dist/drivers/download_blob/sparse_cache/cache.d.ts +0 -82
- package/dist/drivers/download_blob/sparse_cache/cache.d.ts.map +0 -1
- package/dist/drivers/download_blob/sparse_cache/file.d.ts +0 -8
- package/dist/drivers/download_blob/sparse_cache/file.d.ts.map +0 -1
- package/dist/drivers/download_blob/sparse_cache/ranges.d.ts +0 -46
- package/dist/drivers/download_blob/sparse_cache/ranges.d.ts.map +0 -1
- package/dist/drivers/download_blob_url/driver.d.ts.map +0 -1
- package/dist/drivers/download_blob_url/driver_id.d.ts +0 -6
- package/dist/drivers/download_blob_url/driver_id.d.ts.map +0 -1
- package/dist/drivers/download_blob_url/snapshot.d.ts.map +0 -1
- package/dist/drivers/download_blob_url/task.d.ts.map +0 -1
- package/dist/drivers/download_url/driver.d.ts.map +0 -1
- package/dist/drivers/download_url/task.d.ts.map +0 -1
- package/dist/drivers/helpers/download_local_handle.d.ts +0 -11
- package/dist/drivers/helpers/download_local_handle.d.ts.map +0 -1
- package/dist/drivers/helpers/download_remote_handle.d.ts +0 -13
- package/dist/drivers/helpers/download_remote_handle.d.ts.map +0 -1
- package/dist/drivers/helpers/files_cache.d.ts +0 -29
- package/dist/drivers/helpers/files_cache.d.ts.map +0 -1
- package/dist/drivers/helpers/helpers.d.ts.map +0 -1
- package/dist/drivers/helpers/logs_handle.d.ts +0 -15
- package/dist/drivers/helpers/logs_handle.d.ts.map +0 -1
- package/dist/drivers/helpers/ls_remote_import_handle.d.ts +0 -8
- package/dist/drivers/helpers/ls_remote_import_handle.d.ts.map +0 -1
- package/dist/drivers/helpers/ls_storage_entry.d.ts +0 -23
- package/dist/drivers/helpers/ls_storage_entry.d.ts.map +0 -1
- package/dist/drivers/helpers/polling_ops.d.ts.map +0 -1
- package/dist/drivers/helpers/read_file.d.ts +0 -12
- package/dist/drivers/helpers/read_file.d.ts.map +0 -1
- package/dist/drivers/helpers/test_helpers.d.ts +0 -2
- package/dist/drivers/helpers/test_helpers.d.ts.map +0 -1
- package/dist/drivers/logs.d.ts.map +0 -1
- package/dist/drivers/logs_stream.d.ts.map +0 -1
- package/dist/drivers/ls.d.ts.map +0 -1
- package/dist/drivers/types.d.ts.map +0 -1
- package/dist/drivers/upload.d.ts.map +0 -1
- package/dist/drivers/upload_task.d.ts.map +0 -1
- package/dist/drivers/urls/url.d.ts +0 -13
- package/dist/drivers/urls/url.d.ts.map +0 -1
- package/dist/drivers/virtual_storages.d.ts.map +0 -1
- package/dist/helpers/download.d.ts.map +0 -1
- package/dist/helpers/download_errors.d.ts.map +0 -1
- package/dist/helpers/validate.d.ts.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.client.d.ts.map +0 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.d.ts.map +0 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.client.d.ts +0 -46
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.client.d.ts.map +0 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.d.ts.map +0 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.client.d.ts.map +0 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.d.ts.map +0 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.client.d.ts.map +0 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.d.ts.map +0 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client.d.ts +0 -108
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client.d.ts.map +0 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.d.ts.map +0 -1
- package/dist/proto-grpc/google/api/http.d.ts +0 -460
- package/dist/proto-grpc/google/api/http.d.ts.map +0 -1
- package/dist/proto-grpc/google/protobuf/descriptor.d.ts +0 -2340
- package/dist/proto-grpc/google/protobuf/descriptor.d.ts.map +0 -1
- package/dist/proto-grpc/google/protobuf/duration.d.ts.map +0 -1
- package/dist/proto-grpc/google/protobuf/timestamp.d.ts.map +0 -1
- package/dist/proto-rest/downloadapi.d.ts.map +0 -1
- package/dist/proto-rest/index.d.ts.map +0 -1
- package/dist/proto-rest/lsapi.d.ts +0 -148
- package/dist/proto-rest/lsapi.d.ts.map +0 -1
- package/dist/proto-rest/progressapi.d.ts.map +0 -1
- package/dist/proto-rest/streamingapi.d.ts.map +0 -1
- package/dist/proto-rest/uploadapi.d.ts +0 -355
- package/dist/proto-rest/uploadapi.d.ts.map +0 -1
- package/dist/test_env.d.ts +0 -6
- package/dist/test_env.d.ts.map +0 -1
package/dist/clients/upload.cjs
CHANGED
|
@@ -1,272 +1,211 @@
|
|
|
1
|
-
|
|
1
|
+
const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
|
|
2
|
+
const require_protocol = require('../proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.cjs');
|
|
3
|
+
const require_protocol_client = require('../proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client.cjs');
|
|
4
|
+
const require_crc32c = require('./crc32c.cjs');
|
|
5
|
+
let _milaboratories_pl_client = require("@milaboratories/pl-client");
|
|
6
|
+
let node_fs_promises = require("node:fs/promises");
|
|
7
|
+
node_fs_promises = require_runtime.__toESM(node_fs_promises);
|
|
8
|
+
let undici = require("undici");
|
|
2
9
|
|
|
3
|
-
|
|
4
|
-
var
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
var
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
Object.keys(e).forEach(function (k) {
|
|
14
|
-
if (k !== 'default') {
|
|
15
|
-
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
16
|
-
Object.defineProperty(n, k, d.get ? d : {
|
|
17
|
-
enumerable: true,
|
|
18
|
-
get: function () { return e[k]; }
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
});
|
|
22
|
-
}
|
|
23
|
-
n.default = e;
|
|
24
|
-
return Object.freeze(n);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
var fsp__namespace = /*#__PURE__*/_interopNamespaceDefault(fsp);
|
|
28
|
-
|
|
29
|
-
class MTimeError extends Error {
|
|
30
|
-
name = "MTimeError";
|
|
31
|
-
}
|
|
32
|
-
class UnexpectedEOF extends Error {
|
|
33
|
-
name = "UnexpectedEOF";
|
|
34
|
-
}
|
|
35
|
-
class NetworkError extends Error {
|
|
36
|
-
name = "NetworkError";
|
|
37
|
-
}
|
|
10
|
+
//#region src/clients/upload.ts
|
|
11
|
+
var MTimeError = class extends Error {
|
|
12
|
+
name = "MTimeError";
|
|
13
|
+
};
|
|
14
|
+
var UnexpectedEOF = class extends Error {
|
|
15
|
+
name = "UnexpectedEOF";
|
|
16
|
+
};
|
|
17
|
+
var NetworkError = class extends Error {
|
|
18
|
+
name = "NetworkError";
|
|
19
|
+
};
|
|
38
20
|
/** Happens when the file doesn't exist */
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
21
|
+
var NoFileForUploading = class extends Error {
|
|
22
|
+
name = "NoFileForUploading";
|
|
23
|
+
};
|
|
24
|
+
var BadRequestError = class extends Error {
|
|
25
|
+
name = "BadRequestError";
|
|
26
|
+
};
|
|
45
27
|
/** Low-level client for grpc uploadapi.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
/** Calculates parts that need to be uploaded from the parts that were
|
|
180
|
-
* already uploaded. */
|
|
181
|
-
partsToUpload(partsCount, uploadedParts) {
|
|
182
|
-
const toUpload = [];
|
|
183
|
-
const uploaded = new Set(uploadedParts);
|
|
184
|
-
for (let i = 1n; i <= partsCount; i++) {
|
|
185
|
-
if (!uploaded.has(i))
|
|
186
|
-
toUpload.push(i);
|
|
187
|
-
}
|
|
188
|
-
return toUpload;
|
|
189
|
-
}
|
|
190
|
-
async updateProgress({ id, type }, bytesProcessed, options) {
|
|
191
|
-
const client = this.wire.get();
|
|
192
|
-
if (client instanceof protocol_client.UploadClient) {
|
|
193
|
-
await client.updateProgress({
|
|
194
|
-
resourceId: id,
|
|
195
|
-
bytesProcessed,
|
|
196
|
-
}, plClient.addRTypeToMetadata(type, options)).response;
|
|
197
|
-
return;
|
|
198
|
-
}
|
|
199
|
-
await client.POST("/v1/upload/update-progress", {
|
|
200
|
-
body: {
|
|
201
|
-
resourceId: id.toString(),
|
|
202
|
-
bytesProcessed: bytesProcessed.toString(),
|
|
203
|
-
},
|
|
204
|
-
headers: { ...plClient.createRTypeRoutingHeader(type) },
|
|
205
|
-
});
|
|
206
|
-
return;
|
|
207
|
-
}
|
|
208
|
-
}
|
|
28
|
+
* The user should pass here a concrete BlobUpload/<storageId> resource,
|
|
29
|
+
* it can be got from handle field of BlobUpload. */
|
|
30
|
+
var ClientUpload = class {
|
|
31
|
+
wire;
|
|
32
|
+
constructor(wireClientProviderFactory, httpClient, _, logger) {
|
|
33
|
+
this.httpClient = httpClient;
|
|
34
|
+
this.logger = logger;
|
|
35
|
+
this.wire = wireClientProviderFactory.createWireClientProvider((wire) => {
|
|
36
|
+
if (wire.type === "grpc") return new require_protocol_client.UploadClient(wire.Transport);
|
|
37
|
+
return _milaboratories_pl_client.RestAPI.createClient({
|
|
38
|
+
hostAndPort: wire.Config.hostAndPort,
|
|
39
|
+
ssl: wire.Config.ssl,
|
|
40
|
+
dispatcher: wire.Dispatcher,
|
|
41
|
+
middlewares: wire.Middlewares
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
close() {}
|
|
46
|
+
async initUpload({ id, type }, options) {
|
|
47
|
+
const client = this.wire.get();
|
|
48
|
+
if (client instanceof require_protocol_client.UploadClient) {
|
|
49
|
+
const init = (await client.init({ resourceId: id }, (0, _milaboratories_pl_client.addRTypeToMetadata)(type, options))).response;
|
|
50
|
+
return {
|
|
51
|
+
overall: init.partsCount,
|
|
52
|
+
toUpload: this.partsToUpload(init.partsCount, init.uploadedParts),
|
|
53
|
+
checksumAlgorithm: init.checksumAlgorithm,
|
|
54
|
+
checksumHeader: init.checksumHeader
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
const init = (await client.POST("/v1/upload/init", {
|
|
58
|
+
body: { resourceId: id.toString() },
|
|
59
|
+
headers: { ...(0, _milaboratories_pl_client.createRTypeRoutingHeader)(type) }
|
|
60
|
+
})).data;
|
|
61
|
+
return {
|
|
62
|
+
overall: BigInt(init.partsCount),
|
|
63
|
+
toUpload: this.partsToUpload(BigInt(init.partsCount), init.uploadedParts.map(BigInt)),
|
|
64
|
+
checksumAlgorithm: init.checksumAlgorithm,
|
|
65
|
+
checksumHeader: init.checksumHeader
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
async partUpload({ id, type }, path, expectedMTimeUnix, partNumber, checksumAlgorithm, checksumHeader, options) {
|
|
69
|
+
const client = this.wire.get();
|
|
70
|
+
let info;
|
|
71
|
+
if (client instanceof require_protocol_client.UploadClient) info = (await client.getPartURL({
|
|
72
|
+
resourceId: id,
|
|
73
|
+
partNumber,
|
|
74
|
+
uploadedPartSize: 0n,
|
|
75
|
+
isInternalUse: false,
|
|
76
|
+
partChecksum: ""
|
|
77
|
+
}, (0, _milaboratories_pl_client.addRTypeToMetadata)(type, options))).response;
|
|
78
|
+
else {
|
|
79
|
+
const resp = (await client.POST("/v1/upload/get-part-url", {
|
|
80
|
+
body: {
|
|
81
|
+
resourceId: id.toString(),
|
|
82
|
+
partNumber: partNumber.toString(),
|
|
83
|
+
uploadedPartSize: "0",
|
|
84
|
+
isInternalUse: false,
|
|
85
|
+
partChecksum: ""
|
|
86
|
+
},
|
|
87
|
+
headers: { ...(0, _milaboratories_pl_client.createRTypeRoutingHeader)(type) }
|
|
88
|
+
})).data;
|
|
89
|
+
info = {
|
|
90
|
+
uploadUrl: resp.uploadUrl,
|
|
91
|
+
method: resp.method,
|
|
92
|
+
headers: resp.headers,
|
|
93
|
+
chunkStart: BigInt(resp.chunkStart),
|
|
94
|
+
chunkEnd: BigInt(resp.chunkEnd)
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
const chunk = await readFileChunk(path, info.chunkStart, info.chunkEnd);
|
|
98
|
+
await checkExpectedMTime(path, expectedMTimeUnix);
|
|
99
|
+
if (checksumHeader && checksumAlgorithm === require_protocol.UploadAPI_ChecksumAlgorithm.CRC32C) info.headers.push({
|
|
100
|
+
name: checksumHeader,
|
|
101
|
+
value: calculateCrc32cChecksum(chunk)
|
|
102
|
+
});
|
|
103
|
+
const contentLength = Number(info.chunkEnd - info.chunkStart);
|
|
104
|
+
if (chunk.length !== contentLength) throw new Error(`Chunk size mismatch: expected ${contentLength} bytes, but read ${chunk.length} bytes from file`);
|
|
105
|
+
const headers = Object.fromEntries(info.headers.map(({ name, value }) => [name.toLowerCase(), value]));
|
|
106
|
+
try {
|
|
107
|
+
const { body: rawBody, statusCode, headers: responseHeaders } = await (0, undici.request)(info.uploadUrl, {
|
|
108
|
+
dispatcher: this.httpClient,
|
|
109
|
+
body: chunk,
|
|
110
|
+
headersTimeout: 6e4,
|
|
111
|
+
bodyTimeout: 6e4,
|
|
112
|
+
reset: true,
|
|
113
|
+
headers,
|
|
114
|
+
method: info.method.toUpperCase()
|
|
115
|
+
});
|
|
116
|
+
checkStatusCodeOk(statusCode, await rawBody.text(), responseHeaders, info);
|
|
117
|
+
} catch (e) {
|
|
118
|
+
if (e instanceof NetworkError) throw e;
|
|
119
|
+
if (e instanceof BadRequestError) throw e;
|
|
120
|
+
throw new Error(`partUpload: error ${JSON.stringify(e)} happened while trying to do part upload to the url ${info.uploadUrl}, headers: ${JSON.stringify(info.headers)}`);
|
|
121
|
+
}
|
|
122
|
+
await this.updateProgress({
|
|
123
|
+
id,
|
|
124
|
+
type
|
|
125
|
+
}, BigInt(info.chunkEnd - info.chunkStart), options);
|
|
126
|
+
}
|
|
127
|
+
async finalize(info, options) {
|
|
128
|
+
const client = this.wire.get();
|
|
129
|
+
if (client instanceof require_protocol_client.UploadClient) await client.finalize({ resourceId: info.id }, (0, _milaboratories_pl_client.addRTypeToMetadata)(info.type, options));
|
|
130
|
+
else await client.POST("/v1/upload/finalize", {
|
|
131
|
+
body: { resourceId: info.id.toString() },
|
|
132
|
+
headers: { ...(0, _milaboratories_pl_client.createRTypeRoutingHeader)(info.type) }
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
/** Calculates parts that need to be uploaded from the parts that were
|
|
136
|
+
* already uploaded. */
|
|
137
|
+
partsToUpload(partsCount, uploadedParts) {
|
|
138
|
+
const toUpload = [];
|
|
139
|
+
const uploaded = new Set(uploadedParts);
|
|
140
|
+
for (let i = 1n; i <= partsCount; i++) if (!uploaded.has(i)) toUpload.push(i);
|
|
141
|
+
return toUpload;
|
|
142
|
+
}
|
|
143
|
+
async updateProgress({ id, type }, bytesProcessed, options) {
|
|
144
|
+
const client = this.wire.get();
|
|
145
|
+
if (client instanceof require_protocol_client.UploadClient) {
|
|
146
|
+
await client.updateProgress({
|
|
147
|
+
resourceId: id,
|
|
148
|
+
bytesProcessed
|
|
149
|
+
}, (0, _milaboratories_pl_client.addRTypeToMetadata)(type, options)).response;
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
await client.POST("/v1/upload/update-progress", {
|
|
153
|
+
body: {
|
|
154
|
+
resourceId: id.toString(),
|
|
155
|
+
bytesProcessed: bytesProcessed.toString()
|
|
156
|
+
},
|
|
157
|
+
headers: { ...(0, _milaboratories_pl_client.createRTypeRoutingHeader)(type) }
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
};
|
|
209
161
|
async function readFileChunk(path, chunkStart, chunkEnd) {
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
finally {
|
|
225
|
-
await f?.close();
|
|
226
|
-
}
|
|
162
|
+
let f;
|
|
163
|
+
try {
|
|
164
|
+
f = await node_fs_promises.open(path);
|
|
165
|
+
const len = Number(chunkEnd - chunkStart);
|
|
166
|
+
const pos = Number(chunkStart);
|
|
167
|
+
const b = Buffer.alloc(len);
|
|
168
|
+
const bytesRead = await readBytesFromPosition(f, b, len, pos);
|
|
169
|
+
return b.subarray(0, bytesRead);
|
|
170
|
+
} catch (e) {
|
|
171
|
+
if (e && typeof e === "object" && "code" in e && e.code == "ENOENT") throw new NoFileForUploading(`there is no file ${path} for uploading`);
|
|
172
|
+
throw e;
|
|
173
|
+
} finally {
|
|
174
|
+
await f?.close();
|
|
175
|
+
}
|
|
227
176
|
}
|
|
228
177
|
/** Read len bytes from a given position.
|
|
229
|
-
|
|
178
|
+
* Without this, `FileHandle.read` can read less bytes than needed. */
|
|
230
179
|
async function readBytesFromPosition(f, b, len, position) {
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
}
|
|
239
|
-
return bytesReadTotal;
|
|
180
|
+
let bytesReadTotal = 0;
|
|
181
|
+
while (bytesReadTotal < len) {
|
|
182
|
+
const { bytesRead } = await f.read(b, bytesReadTotal, len - bytesReadTotal, position + bytesReadTotal);
|
|
183
|
+
if (bytesRead === 0) throw new UnexpectedEOF("file ended earlier than expected.");
|
|
184
|
+
bytesReadTotal += bytesRead;
|
|
185
|
+
}
|
|
186
|
+
return bytesReadTotal;
|
|
240
187
|
}
|
|
241
188
|
async function checkExpectedMTime(path, expectedMTimeUnix) {
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
throw new MTimeError(`file was modified, expected mtime: ${expectedMTimeUnix}, got: ${mTime}.`);
|
|
245
|
-
}
|
|
189
|
+
const mTime = BigInt(Math.floor((await node_fs_promises.stat(path)).mtimeMs / 1e3));
|
|
190
|
+
if (mTime > expectedMTimeUnix) throw new MTimeError(`file was modified, expected mtime: ${expectedMTimeUnix}, got: ${mTime}.`);
|
|
246
191
|
}
|
|
247
192
|
function checkStatusCodeOk(statusCode, body, headers, info) {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
` body: ${body}, headers: ${JSON.stringify(headers)}, url: ${info.uploadUrl}`);
|
|
251
|
-
}
|
|
252
|
-
if (statusCode != 200) {
|
|
253
|
-
throw new NetworkError(`response is not ok, status code: ${statusCode},` +
|
|
254
|
-
` body: ${body}, headers: ${JSON.stringify(headers)}, url: ${info.uploadUrl}`);
|
|
255
|
-
}
|
|
193
|
+
if (statusCode == 400) throw new BadRequestError(`response is not ok, status code: ${statusCode}, body: ${body}, headers: ${JSON.stringify(headers)}, url: ${info.uploadUrl}`);
|
|
194
|
+
if (statusCode != 200) throw new NetworkError(`response is not ok, status code: ${statusCode}, body: ${body}, headers: ${JSON.stringify(headers)}, url: ${info.uploadUrl}`);
|
|
256
195
|
}
|
|
257
196
|
/** Calculate CRC32C checksum of a buffer and return as base64 string */
|
|
258
197
|
function calculateCrc32cChecksum(data) {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
return buffer.toString("base64");
|
|
198
|
+
const checksum = require_crc32c.crc32c(data);
|
|
199
|
+
const buffer = Buffer.alloc(4);
|
|
200
|
+
buffer.writeUInt32BE(checksum, 0);
|
|
201
|
+
return buffer.toString("base64");
|
|
264
202
|
}
|
|
265
203
|
|
|
204
|
+
//#endregion
|
|
266
205
|
exports.BadRequestError = BadRequestError;
|
|
267
206
|
exports.ClientUpload = ClientUpload;
|
|
268
207
|
exports.MTimeError = MTimeError;
|
|
269
208
|
exports.NetworkError = NetworkError;
|
|
270
209
|
exports.NoFileForUploading = NoFileForUploading;
|
|
271
210
|
exports.UnexpectedEOF = UnexpectedEOF;
|
|
272
|
-
//# sourceMappingURL=upload.cjs.map
|
|
211
|
+
//# sourceMappingURL=upload.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload.cjs","sources":["../../src/clients/upload.ts"],"sourcesContent":["import type {\n WireClientProvider,\n WireClientProviderFactory,\n PlClient,\n} from \"@milaboratories/pl-client\";\nimport { addRTypeToMetadata, createRTypeRoutingHeader, RestAPI } from \"@milaboratories/pl-client\";\nimport type { ResourceInfo } from \"@milaboratories/pl-tree\";\nimport type { MiLogger } from \"@milaboratories/ts-helpers\";\nimport type { RpcOptions } from \"@protobuf-ts/runtime-rpc\";\nimport * as fs from \"node:fs/promises\";\nimport type { Dispatcher } from \"undici\";\nimport { request } from \"undici\";\nimport {\n UploadAPI_ChecksumAlgorithm,\n type UploadAPI_GetPartURL_Response,\n} from \"../proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol\";\nimport { UploadClient } from \"../proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client\";\nimport type { UploadApiPaths, UploadRestClientType } from \"../proto-rest\";\nimport { crc32c } from \"./crc32c\";\n\nimport type { IncomingHttpHeaders } from \"undici/types/header\";\n\nexport class MTimeError extends Error {\n name = \"MTimeError\";\n}\n\nexport class UnexpectedEOF extends Error {\n name = \"UnexpectedEOF\";\n}\n\nexport class NetworkError extends Error {\n name = \"NetworkError\";\n}\n\n/** Happens when the file doesn't exist */\nexport class NoFileForUploading extends Error {\n name = \"NoFileForUploading\";\n}\n\nexport class BadRequestError extends Error {\n name = \"BadRequestError\";\n}\n\n/** Low-level client for grpc uploadapi.\n * The user should pass here a concrete BlobUpload/<storageId> resource,\n * it can be got from handle field of BlobUpload. */\nexport class ClientUpload {\n private readonly wire: WireClientProvider<UploadRestClientType | UploadClient>;\n\n constructor(\n wireClientProviderFactory: WireClientProviderFactory,\n public readonly httpClient: Dispatcher,\n _: PlClient,\n public readonly logger: MiLogger,\n ) {\n this.wire = wireClientProviderFactory.createWireClientProvider((wire) => {\n if (wire.type === \"grpc\") {\n return new UploadClient(wire.Transport);\n }\n\n return RestAPI.createClient<UploadApiPaths>({\n hostAndPort: wire.Config.hostAndPort,\n ssl: wire.Config.ssl,\n dispatcher: wire.Dispatcher,\n middlewares: wire.Middlewares,\n });\n });\n }\n\n close() {}\n\n public async initUpload(\n { id, type }: ResourceInfo,\n options?: RpcOptions,\n ): Promise<{\n overall: bigint;\n toUpload: bigint[];\n checksumAlgorithm: UploadAPI_ChecksumAlgorithm;\n checksumHeader: string;\n }> {\n const client = this.wire.get();\n\n if (client instanceof UploadClient) {\n const init = (await client.init({ resourceId: id }, addRTypeToMetadata(type, options)))\n .response;\n\n return {\n overall: init.partsCount,\n toUpload: this.partsToUpload(init.partsCount, init.uploadedParts),\n checksumAlgorithm: init.checksumAlgorithm,\n checksumHeader: init.checksumHeader,\n };\n }\n\n const init = (\n await client.POST(\"/v1/upload/init\", {\n body: {\n resourceId: id.toString(),\n },\n headers: { ...createRTypeRoutingHeader(type) },\n })\n ).data!;\n\n return {\n overall: BigInt(init.partsCount),\n toUpload: this.partsToUpload(BigInt(init.partsCount), init.uploadedParts.map(BigInt)),\n checksumAlgorithm: init.checksumAlgorithm,\n checksumHeader: init.checksumHeader,\n };\n }\n\n public async partUpload(\n { id, type }: ResourceInfo,\n path: string,\n expectedMTimeUnix: bigint,\n partNumber: bigint,\n checksumAlgorithm: UploadAPI_ChecksumAlgorithm,\n checksumHeader: string,\n options?: RpcOptions,\n ) {\n const client = this.wire.get();\n\n let info: UploadAPI_GetPartURL_Response;\n if (client instanceof UploadClient) {\n // partChecksum isn't used for now but protoc requires it to be set\n info = (\n await client.getPartURL(\n {\n resourceId: id,\n partNumber,\n uploadedPartSize: 0n,\n isInternalUse: false,\n partChecksum: \"\",\n },\n addRTypeToMetadata(type, options),\n )\n ).response;\n } else {\n const resp = (\n await client.POST(\"/v1/upload/get-part-url\", {\n body: {\n resourceId: id.toString(),\n partNumber: partNumber.toString(),\n uploadedPartSize: \"0\",\n isInternalUse: false,\n partChecksum: \"\",\n },\n headers: { ...createRTypeRoutingHeader(type) },\n })\n ).data!;\n info = {\n uploadUrl: resp.uploadUrl,\n method: resp.method,\n headers: resp.headers,\n chunkStart: BigInt(resp.chunkStart),\n chunkEnd: BigInt(resp.chunkEnd),\n };\n }\n\n const chunk = await readFileChunk(path, info.chunkStart, info.chunkEnd);\n await checkExpectedMTime(path, expectedMTimeUnix);\n\n if (checksumHeader && checksumAlgorithm === UploadAPI_ChecksumAlgorithm.CRC32C) {\n info.headers.push({ name: checksumHeader, value: calculateCrc32cChecksum(chunk) });\n }\n\n const contentLength = Number(info.chunkEnd - info.chunkStart);\n if (chunk.length !== contentLength) {\n throw new Error(\n `Chunk size mismatch: expected ${contentLength} bytes, but read ${chunk.length} bytes from file`,\n );\n }\n\n const headers = Object.fromEntries(\n info.headers.map(({ name, value }) => [name.toLowerCase(), value]),\n );\n\n try {\n const {\n body: rawBody,\n statusCode,\n headers: responseHeaders,\n } = await request(info.uploadUrl, {\n dispatcher: this.httpClient,\n body: chunk,\n // We got headers only after we send\n // the whole body (in case of S3 PUT requests it's 5 MB).\n // It might be slow with a slow connection (or with SSH),\n // that's why we got big timeout here.\n headersTimeout: 60000,\n bodyTimeout: 60000,\n // Prevent connection reuse by setting \"Connection: close\" header.\n // This works around an issue with the backend's built-in S3 implementation\n // that caused HTTP/1.1 protocol lines to be included in the uploaded file content.\n reset: true,\n headers,\n method: info.method.toUpperCase() as Dispatcher.HttpMethod,\n });\n\n // always read the body for resources to be garbage collected.\n const body = await rawBody.text();\n checkStatusCodeOk(statusCode, body, responseHeaders, info);\n } catch (e: unknown) {\n if (e instanceof NetworkError) throw e;\n\n if (e instanceof BadRequestError) throw e;\n\n throw new Error(\n `partUpload: error ${JSON.stringify(e)} happened while trying to do part upload to the url ${info.uploadUrl}, headers: ${JSON.stringify(info.headers)}`,\n );\n }\n\n await this.updateProgress({ id, type }, BigInt(info.chunkEnd - info.chunkStart), options);\n }\n\n public async finalize(info: ResourceInfo, options?: RpcOptions) {\n const client = this.wire.get();\n\n if (client instanceof UploadClient) {\n await client.finalize({ resourceId: info.id }, addRTypeToMetadata(info.type, options));\n } else {\n await client.POST(\"/v1/upload/finalize\", {\n body: {\n resourceId: info.id.toString(),\n },\n headers: { ...createRTypeRoutingHeader(info.type) },\n });\n }\n }\n\n /** Calculates parts that need to be uploaded from the parts that were\n * already uploaded. */\n private partsToUpload(partsCount: bigint, uploadedParts: bigint[]): bigint[] {\n const toUpload: bigint[] = [];\n const uploaded = new Set(uploadedParts);\n\n for (let i = 1n; i <= partsCount; i++) {\n if (!uploaded.has(i)) toUpload.push(i);\n }\n\n return toUpload;\n }\n\n private async updateProgress(\n { id, type }: ResourceInfo,\n bytesProcessed: bigint,\n options?: RpcOptions,\n ): Promise<void> {\n const client = this.wire.get();\n\n if (client instanceof UploadClient) {\n await client.updateProgress(\n {\n resourceId: id,\n bytesProcessed,\n },\n addRTypeToMetadata(type, options),\n ).response;\n return;\n }\n\n await client.POST(\"/v1/upload/update-progress\", {\n body: {\n resourceId: id.toString(),\n bytesProcessed: bytesProcessed.toString(),\n },\n headers: { ...createRTypeRoutingHeader(type) },\n });\n return;\n }\n}\n\nasync function readFileChunk(path: string, chunkStart: bigint, chunkEnd: bigint): Promise<Buffer> {\n let f: fs.FileHandle | undefined;\n try {\n f = await fs.open(path);\n const len = Number(chunkEnd - chunkStart);\n const pos = Number(chunkStart);\n const b = Buffer.alloc(len);\n const bytesRead = await readBytesFromPosition(f, b, len, pos);\n\n return b.subarray(0, bytesRead);\n } catch (e: unknown) {\n if (e && typeof e === \"object\" && \"code\" in e && e.code == \"ENOENT\")\n throw new NoFileForUploading(`there is no file ${path} for uploading`);\n throw e;\n } finally {\n await f?.close();\n }\n}\n\n/** Read len bytes from a given position.\n * Without this, `FileHandle.read` can read less bytes than needed. */\nasync function readBytesFromPosition(f: fs.FileHandle, b: Buffer, len: number, position: number) {\n let bytesReadTotal = 0;\n while (bytesReadTotal < len) {\n const { bytesRead } = await f.read(\n b,\n bytesReadTotal,\n len - bytesReadTotal,\n position + bytesReadTotal,\n );\n if (bytesRead === 0) {\n throw new UnexpectedEOF(\"file ended earlier than expected.\");\n }\n bytesReadTotal += bytesRead;\n }\n\n return bytesReadTotal;\n}\n\nasync function checkExpectedMTime(path: string, expectedMTimeUnix: bigint) {\n const mTime = BigInt(Math.floor((await fs.stat(path)).mtimeMs / 1000));\n if (mTime > expectedMTimeUnix) {\n throw new MTimeError(`file was modified, expected mtime: ${expectedMTimeUnix}, got: ${mTime}.`);\n }\n}\n\nfunction checkStatusCodeOk(\n statusCode: number,\n body: string,\n headers: IncomingHttpHeaders,\n info: UploadAPI_GetPartURL_Response,\n) {\n if (statusCode == 400) {\n throw new BadRequestError(\n `response is not ok, status code: ${statusCode},` +\n ` body: ${body}, headers: ${JSON.stringify(headers)}, url: ${info.uploadUrl}`,\n );\n }\n\n if (statusCode != 200) {\n throw new NetworkError(\n `response is not ok, status code: ${statusCode},` +\n ` body: ${body}, headers: ${JSON.stringify(headers)}, url: ${info.uploadUrl}`,\n );\n }\n}\n\n/** Calculate CRC32C checksum of a buffer and return as base64 string */\nfunction calculateCrc32cChecksum(data: Buffer): string {\n const checksum = crc32c(data);\n // Convert to unsigned 32-bit integer and then to base64\n const buffer = Buffer.alloc(4);\n\n buffer.writeUInt32BE(checksum, 0);\n return buffer.toString(\"base64\");\n}\n"],"names":["UploadClient","RestAPI","addRTypeToMetadata","createRTypeRoutingHeader","UploadAPI_ChecksumAlgorithm","request","fs","crc32c"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"upload.cjs","names":["UploadClient","RestAPI","UploadAPI_ChecksumAlgorithm","fs","crc32c"],"sources":["../../src/clients/upload.ts"],"sourcesContent":["import type {\n WireClientProvider,\n WireClientProviderFactory,\n PlClient,\n} from \"@milaboratories/pl-client\";\nimport { addRTypeToMetadata, createRTypeRoutingHeader, RestAPI } from \"@milaboratories/pl-client\";\nimport type { ResourceInfo } from \"@milaboratories/pl-tree\";\nimport type { MiLogger } from \"@milaboratories/ts-helpers\";\nimport type { RpcOptions } from \"@protobuf-ts/runtime-rpc\";\nimport * as fs from \"node:fs/promises\";\nimport type { Dispatcher } from \"undici\";\nimport { request } from \"undici\";\nimport {\n UploadAPI_ChecksumAlgorithm,\n type UploadAPI_GetPartURL_Response,\n} from \"../proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol\";\nimport { UploadClient } from \"../proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client\";\nimport type { UploadApiPaths, UploadRestClientType } from \"../proto-rest\";\nimport { crc32c } from \"./crc32c\";\n\nimport type { IncomingHttpHeaders } from \"undici/types/header\";\n\nexport class MTimeError extends Error {\n name = \"MTimeError\";\n}\n\nexport class UnexpectedEOF extends Error {\n name = \"UnexpectedEOF\";\n}\n\nexport class NetworkError extends Error {\n name = \"NetworkError\";\n}\n\n/** Happens when the file doesn't exist */\nexport class NoFileForUploading extends Error {\n name = \"NoFileForUploading\";\n}\n\nexport class BadRequestError extends Error {\n name = \"BadRequestError\";\n}\n\n/** Low-level client for grpc uploadapi.\n * The user should pass here a concrete BlobUpload/<storageId> resource,\n * it can be got from handle field of BlobUpload. */\nexport class ClientUpload {\n private readonly wire: WireClientProvider<UploadRestClientType | UploadClient>;\n\n constructor(\n wireClientProviderFactory: WireClientProviderFactory,\n public readonly httpClient: Dispatcher,\n _: PlClient,\n public readonly logger: MiLogger,\n ) {\n this.wire = wireClientProviderFactory.createWireClientProvider((wire) => {\n if (wire.type === \"grpc\") {\n return new UploadClient(wire.Transport);\n }\n\n return RestAPI.createClient<UploadApiPaths>({\n hostAndPort: wire.Config.hostAndPort,\n ssl: wire.Config.ssl,\n dispatcher: wire.Dispatcher,\n middlewares: wire.Middlewares,\n });\n });\n }\n\n close() {}\n\n public async initUpload(\n { id, type }: ResourceInfo,\n options?: RpcOptions,\n ): Promise<{\n overall: bigint;\n toUpload: bigint[];\n checksumAlgorithm: UploadAPI_ChecksumAlgorithm;\n checksumHeader: string;\n }> {\n const client = this.wire.get();\n\n if (client instanceof UploadClient) {\n const init = (await client.init({ resourceId: id }, addRTypeToMetadata(type, options)))\n .response;\n\n return {\n overall: init.partsCount,\n toUpload: this.partsToUpload(init.partsCount, init.uploadedParts),\n checksumAlgorithm: init.checksumAlgorithm,\n checksumHeader: init.checksumHeader,\n };\n }\n\n const init = (\n await client.POST(\"/v1/upload/init\", {\n body: {\n resourceId: id.toString(),\n },\n headers: { ...createRTypeRoutingHeader(type) },\n })\n ).data!;\n\n return {\n overall: BigInt(init.partsCount),\n toUpload: this.partsToUpload(BigInt(init.partsCount), init.uploadedParts.map(BigInt)),\n checksumAlgorithm: init.checksumAlgorithm,\n checksumHeader: init.checksumHeader,\n };\n }\n\n public async partUpload(\n { id, type }: ResourceInfo,\n path: string,\n expectedMTimeUnix: bigint,\n partNumber: bigint,\n checksumAlgorithm: UploadAPI_ChecksumAlgorithm,\n checksumHeader: string,\n options?: RpcOptions,\n ) {\n const client = this.wire.get();\n\n let info: UploadAPI_GetPartURL_Response;\n if (client instanceof UploadClient) {\n // partChecksum isn't used for now but protoc requires it to be set\n info = (\n await client.getPartURL(\n {\n resourceId: id,\n partNumber,\n uploadedPartSize: 0n,\n isInternalUse: false,\n partChecksum: \"\",\n },\n addRTypeToMetadata(type, options),\n )\n ).response;\n } else {\n const resp = (\n await client.POST(\"/v1/upload/get-part-url\", {\n body: {\n resourceId: id.toString(),\n partNumber: partNumber.toString(),\n uploadedPartSize: \"0\",\n isInternalUse: false,\n partChecksum: \"\",\n },\n headers: { ...createRTypeRoutingHeader(type) },\n })\n ).data!;\n info = {\n uploadUrl: resp.uploadUrl,\n method: resp.method,\n headers: resp.headers,\n chunkStart: BigInt(resp.chunkStart),\n chunkEnd: BigInt(resp.chunkEnd),\n };\n }\n\n const chunk = await readFileChunk(path, info.chunkStart, info.chunkEnd);\n await checkExpectedMTime(path, expectedMTimeUnix);\n\n if (checksumHeader && checksumAlgorithm === UploadAPI_ChecksumAlgorithm.CRC32C) {\n info.headers.push({ name: checksumHeader, value: calculateCrc32cChecksum(chunk) });\n }\n\n const contentLength = Number(info.chunkEnd - info.chunkStart);\n if (chunk.length !== contentLength) {\n throw new Error(\n `Chunk size mismatch: expected ${contentLength} bytes, but read ${chunk.length} bytes from file`,\n );\n }\n\n const headers = Object.fromEntries(\n info.headers.map(({ name, value }) => [name.toLowerCase(), value]),\n );\n\n try {\n const {\n body: rawBody,\n statusCode,\n headers: responseHeaders,\n } = await request(info.uploadUrl, {\n dispatcher: this.httpClient,\n body: chunk,\n // We got headers only after we send\n // the whole body (in case of S3 PUT requests it's 5 MB).\n // It might be slow with a slow connection (or with SSH),\n // that's why we got big timeout here.\n headersTimeout: 60000,\n bodyTimeout: 60000,\n // Prevent connection reuse by setting \"Connection: close\" header.\n // This works around an issue with the backend's built-in S3 implementation\n // that caused HTTP/1.1 protocol lines to be included in the uploaded file content.\n reset: true,\n headers,\n method: info.method.toUpperCase() as Dispatcher.HttpMethod,\n });\n\n // always read the body for resources to be garbage collected.\n const body = await rawBody.text();\n checkStatusCodeOk(statusCode, body, responseHeaders, info);\n } catch (e: unknown) {\n if (e instanceof NetworkError) throw e;\n\n if (e instanceof BadRequestError) throw e;\n\n throw new Error(\n `partUpload: error ${JSON.stringify(e)} happened while trying to do part upload to the url ${info.uploadUrl}, headers: ${JSON.stringify(info.headers)}`,\n );\n }\n\n await this.updateProgress({ id, type }, BigInt(info.chunkEnd - info.chunkStart), options);\n }\n\n public async finalize(info: ResourceInfo, options?: RpcOptions) {\n const client = this.wire.get();\n\n if (client instanceof UploadClient) {\n await client.finalize({ resourceId: info.id }, addRTypeToMetadata(info.type, options));\n } else {\n await client.POST(\"/v1/upload/finalize\", {\n body: {\n resourceId: info.id.toString(),\n },\n headers: { ...createRTypeRoutingHeader(info.type) },\n });\n }\n }\n\n /** Calculates parts that need to be uploaded from the parts that were\n * already uploaded. */\n private partsToUpload(partsCount: bigint, uploadedParts: bigint[]): bigint[] {\n const toUpload: bigint[] = [];\n const uploaded = new Set(uploadedParts);\n\n for (let i = 1n; i <= partsCount; i++) {\n if (!uploaded.has(i)) toUpload.push(i);\n }\n\n return toUpload;\n }\n\n private async updateProgress(\n { id, type }: ResourceInfo,\n bytesProcessed: bigint,\n options?: RpcOptions,\n ): Promise<void> {\n const client = this.wire.get();\n\n if (client instanceof UploadClient) {\n await client.updateProgress(\n {\n resourceId: id,\n bytesProcessed,\n },\n addRTypeToMetadata(type, options),\n ).response;\n return;\n }\n\n await client.POST(\"/v1/upload/update-progress\", {\n body: {\n resourceId: id.toString(),\n bytesProcessed: bytesProcessed.toString(),\n },\n headers: { ...createRTypeRoutingHeader(type) },\n });\n return;\n }\n}\n\nasync function readFileChunk(path: string, chunkStart: bigint, chunkEnd: bigint): Promise<Buffer> {\n let f: fs.FileHandle | undefined;\n try {\n f = await fs.open(path);\n const len = Number(chunkEnd - chunkStart);\n const pos = Number(chunkStart);\n const b = Buffer.alloc(len);\n const bytesRead = await readBytesFromPosition(f, b, len, pos);\n\n return b.subarray(0, bytesRead);\n } catch (e: unknown) {\n if (e && typeof e === \"object\" && \"code\" in e && e.code == \"ENOENT\")\n throw new NoFileForUploading(`there is no file ${path} for uploading`);\n throw e;\n } finally {\n await f?.close();\n }\n}\n\n/** Read len bytes from a given position.\n * Without this, `FileHandle.read` can read less bytes than needed. */\nasync function readBytesFromPosition(f: fs.FileHandle, b: Buffer, len: number, position: number) {\n let bytesReadTotal = 0;\n while (bytesReadTotal < len) {\n const { bytesRead } = await f.read(\n b,\n bytesReadTotal,\n len - bytesReadTotal,\n position + bytesReadTotal,\n );\n if (bytesRead === 0) {\n throw new UnexpectedEOF(\"file ended earlier than expected.\");\n }\n bytesReadTotal += bytesRead;\n }\n\n return bytesReadTotal;\n}\n\nasync function checkExpectedMTime(path: string, expectedMTimeUnix: bigint) {\n const mTime = BigInt(Math.floor((await fs.stat(path)).mtimeMs / 1000));\n if (mTime > expectedMTimeUnix) {\n throw new MTimeError(`file was modified, expected mtime: ${expectedMTimeUnix}, got: ${mTime}.`);\n }\n}\n\nfunction checkStatusCodeOk(\n statusCode: number,\n body: string,\n headers: IncomingHttpHeaders,\n info: UploadAPI_GetPartURL_Response,\n) {\n if (statusCode == 400) {\n throw new BadRequestError(\n `response is not ok, status code: ${statusCode},` +\n ` body: ${body}, headers: ${JSON.stringify(headers)}, url: ${info.uploadUrl}`,\n );\n }\n\n if (statusCode != 200) {\n throw new NetworkError(\n `response is not ok, status code: ${statusCode},` +\n ` body: ${body}, headers: ${JSON.stringify(headers)}, url: ${info.uploadUrl}`,\n );\n }\n}\n\n/** Calculate CRC32C checksum of a buffer and return as base64 string */\nfunction calculateCrc32cChecksum(data: Buffer): string {\n const checksum = crc32c(data);\n // Convert to unsigned 32-bit integer and then to base64\n const buffer = Buffer.alloc(4);\n\n buffer.writeUInt32BE(checksum, 0);\n return buffer.toString(\"base64\");\n}\n"],"mappings":"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"}
|