@milaboratories/pl-drivers 1.9.1 → 1.10.1

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.
Files changed (156) hide show
  1. package/dist/clients/constructors.d.ts +4 -3
  2. package/dist/clients/constructors.d.ts.map +1 -0
  3. package/dist/clients/download.d.ts +8 -7
  4. package/dist/clients/download.d.ts.map +1 -0
  5. package/dist/clients/logs.d.ts +7 -6
  6. package/dist/clients/logs.d.ts.map +1 -0
  7. package/dist/clients/ls_api.d.ts +6 -5
  8. package/dist/clients/ls_api.d.ts.map +1 -0
  9. package/dist/clients/progress.d.ts +7 -6
  10. package/dist/clients/progress.d.ts.map +1 -0
  11. package/dist/clients/upload.cjs +31 -10
  12. package/dist/clients/upload.cjs.map +1 -1
  13. package/dist/clients/upload.d.ts +14 -7
  14. package/dist/clients/upload.d.ts.map +1 -0
  15. package/dist/clients/upload.js +31 -11
  16. package/dist/clients/upload.js.map +1 -1
  17. package/dist/drivers/download_blob/blob_key.d.ts +2 -1
  18. package/dist/drivers/download_blob/blob_key.d.ts.map +1 -0
  19. package/dist/drivers/download_blob/download_blob.d.ts +9 -6
  20. package/dist/drivers/download_blob/download_blob.d.ts.map +1 -0
  21. package/dist/drivers/download_blob/download_blob_task.d.ts +8 -5
  22. package/dist/drivers/download_blob/download_blob_task.d.ts.map +1 -0
  23. package/dist/drivers/download_blob/sparse_cache/cache.d.ts +1 -0
  24. package/dist/drivers/download_blob/sparse_cache/cache.d.ts.map +1 -0
  25. package/dist/drivers/download_blob/sparse_cache/file.d.ts +2 -1
  26. package/dist/drivers/download_blob/sparse_cache/file.d.ts.map +1 -0
  27. package/dist/drivers/download_blob/sparse_cache/ranges.d.ts +4 -3
  28. package/dist/drivers/download_blob/sparse_cache/ranges.d.ts.map +1 -0
  29. package/dist/drivers/download_blob_url/driver.d.ts +9 -7
  30. package/dist/drivers/download_blob_url/driver.d.ts.map +1 -0
  31. package/dist/drivers/download_blob_url/driver_id.d.ts +3 -2
  32. package/dist/drivers/download_blob_url/driver_id.d.ts.map +1 -0
  33. package/dist/drivers/download_blob_url/snapshot.d.ts +4 -3
  34. package/dist/drivers/download_blob_url/snapshot.d.ts.map +1 -0
  35. package/dist/drivers/download_blob_url/task.d.ts +8 -5
  36. package/dist/drivers/download_blob_url/task.d.ts.map +1 -0
  37. package/dist/drivers/download_blob_url/url.d.ts +1 -0
  38. package/dist/drivers/download_blob_url/url.d.ts.map +1 -0
  39. package/dist/drivers/download_url/driver.d.ts +6 -4
  40. package/dist/drivers/download_url/driver.d.ts.map +1 -0
  41. package/dist/drivers/download_url/task.d.ts +7 -4
  42. package/dist/drivers/download_url/task.d.ts.map +1 -0
  43. package/dist/drivers/helpers/download_local_handle.d.ts +5 -2
  44. package/dist/drivers/helpers/download_local_handle.d.ts.map +1 -0
  45. package/dist/drivers/helpers/download_remote_handle.d.ts +6 -3
  46. package/dist/drivers/helpers/download_remote_handle.d.ts.map +1 -0
  47. package/dist/drivers/helpers/files_cache.d.ts +2 -1
  48. package/dist/drivers/helpers/files_cache.d.ts.map +1 -0
  49. package/dist/drivers/helpers/helpers.d.ts +1 -0
  50. package/dist/drivers/helpers/helpers.d.ts.map +1 -0
  51. package/dist/drivers/helpers/logs_handle.d.ts +4 -1
  52. package/dist/drivers/helpers/logs_handle.d.ts.map +1 -0
  53. package/dist/drivers/helpers/ls_remote_import_handle.d.ts +3 -2
  54. package/dist/drivers/helpers/ls_remote_import_handle.d.ts.map +1 -0
  55. package/dist/drivers/helpers/ls_storage_entry.d.ts +2 -1
  56. package/dist/drivers/helpers/ls_storage_entry.d.ts.map +1 -0
  57. package/dist/drivers/helpers/polling_ops.d.ts +1 -0
  58. package/dist/drivers/helpers/polling_ops.d.ts.map +1 -0
  59. package/dist/drivers/helpers/read_file.d.ts +2 -1
  60. package/dist/drivers/helpers/read_file.d.ts.map +1 -0
  61. package/dist/drivers/helpers/test_helpers.d.ts +1 -0
  62. package/dist/drivers/helpers/test_helpers.d.ts.map +1 -0
  63. package/dist/drivers/logs.d.ts +7 -5
  64. package/dist/drivers/logs.d.ts.map +1 -0
  65. package/dist/drivers/logs_stream.d.ts +7 -5
  66. package/dist/drivers/logs_stream.d.ts.map +1 -0
  67. package/dist/drivers/ls.cjs +15 -6
  68. package/dist/drivers/ls.cjs.map +1 -1
  69. package/dist/drivers/ls.d.ts +5 -4
  70. package/dist/drivers/ls.d.ts.map +1 -0
  71. package/dist/drivers/ls.js +14 -5
  72. package/dist/drivers/ls.js.map +1 -1
  73. package/dist/drivers/types.d.ts +5 -4
  74. package/dist/drivers/types.d.ts.map +1 -0
  75. package/dist/drivers/upload.d.ts +9 -7
  76. package/dist/drivers/upload.d.ts.map +1 -0
  77. package/dist/drivers/upload_task.cjs +7 -3
  78. package/dist/drivers/upload_task.cjs.map +1 -1
  79. package/dist/drivers/upload_task.d.ts +10 -7
  80. package/dist/drivers/upload_task.d.ts.map +1 -0
  81. package/dist/drivers/upload_task.js +8 -4
  82. package/dist/drivers/upload_task.js.map +1 -1
  83. package/dist/drivers/urls/url.d.ts +3 -2
  84. package/dist/drivers/urls/url.d.ts.map +1 -0
  85. package/dist/drivers/virtual_storages.d.ts +2 -1
  86. package/dist/drivers/virtual_storages.d.ts.map +1 -0
  87. package/dist/helpers/download.d.ts +4 -3
  88. package/dist/helpers/download.d.ts.map +1 -0
  89. package/dist/helpers/validate.d.ts +1 -0
  90. package/dist/helpers/validate.d.ts.map +1 -0
  91. package/dist/index.cjs +1 -0
  92. package/dist/index.cjs.map +1 -1
  93. package/dist/index.d.ts +1 -0
  94. package/dist/index.d.ts.map +1 -0
  95. package/dist/index.js +1 -1
  96. package/dist/proto/github.com/googleapis/googleapis/google/rpc/status.d.ts +8 -2
  97. package/dist/proto/github.com/googleapis/googleapis/google/rpc/status.d.ts.map +1 -0
  98. package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.client.d.ts +9 -4
  99. package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.client.d.ts.map +1 -0
  100. package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.d.ts +8 -2
  101. package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.d.ts.map +1 -0
  102. package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.client.d.ts +9 -4
  103. package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.client.d.ts.map +1 -0
  104. package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.d.ts +9 -3
  105. package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.d.ts.map +1 -0
  106. package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.client.d.ts +12 -4
  107. package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.client.d.ts.map +1 -0
  108. package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.d.ts +9 -3
  109. package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.d.ts.map +1 -0
  110. package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.client.d.ts +14 -4
  111. package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.client.d.ts.map +1 -0
  112. package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.d.ts +8 -2
  113. package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.d.ts.map +1 -0
  114. package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.cjs +47 -1
  115. package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.cjs.map +1 -1
  116. package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client.d.ts +15 -4
  117. package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client.d.ts.map +1 -0
  118. package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.d.ts +44 -2
  119. package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.d.ts.map +1 -0
  120. package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.js +48 -2
  121. package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.js.map +1 -1
  122. package/dist/proto/github.com/milaboratory/pl/plapi/plapiproto/api.client.d.ts +58 -4
  123. package/dist/proto/github.com/milaboratory/pl/plapi/plapiproto/api.client.d.ts.map +1 -0
  124. package/dist/proto/github.com/milaboratory/pl/plapi/plapiproto/api.d.ts +22 -7
  125. package/dist/proto/github.com/milaboratory/pl/plapi/plapiproto/api.d.ts.map +1 -0
  126. package/dist/proto/github.com/milaboratory/pl/plapi/plapiproto/api_types.d.ts +12 -4
  127. package/dist/proto/github.com/milaboratory/pl/plapi/plapiproto/api_types.d.ts.map +1 -0
  128. package/dist/proto/github.com/milaboratory/pl/plapi/plapiproto/base_types.d.ts +7 -1
  129. package/dist/proto/github.com/milaboratory/pl/plapi/plapiproto/base_types.d.ts.map +1 -0
  130. package/dist/proto/github.com/milaboratory/pl/plapi/plapiproto/import.d.ts +23 -7
  131. package/dist/proto/github.com/milaboratory/pl/plapi/plapiproto/import.d.ts.map +1 -0
  132. package/dist/proto/github.com/milaboratory/pl/plapi/plapiproto/resource_types.d.ts +8 -2
  133. package/dist/proto/github.com/milaboratory/pl/plapi/plapiproto/resource_types.d.ts.map +1 -0
  134. package/dist/proto/google/api/http.d.ts +7 -1
  135. package/dist/proto/google/api/http.d.ts.map +1 -0
  136. package/dist/proto/google/protobuf/any.d.ts +11 -1
  137. package/dist/proto/google/protobuf/any.d.ts.map +1 -0
  138. package/dist/proto/google/protobuf/descriptor.d.ts +7 -1
  139. package/dist/proto/google/protobuf/descriptor.d.ts.map +1 -0
  140. package/dist/proto/google/protobuf/duration.d.ts +10 -1
  141. package/dist/proto/google/protobuf/duration.d.ts.map +1 -0
  142. package/dist/proto/google/protobuf/empty.d.ts +7 -1
  143. package/dist/proto/google/protobuf/empty.d.ts.map +1 -0
  144. package/dist/proto/google/protobuf/struct.d.ts +10 -1
  145. package/dist/proto/google/protobuf/struct.d.ts.map +1 -0
  146. package/dist/proto/google/protobuf/timestamp.d.ts +10 -1
  147. package/dist/proto/google/protobuf/timestamp.d.ts.map +1 -0
  148. package/dist/proto/google/protobuf/wrappers.d.ts +10 -1
  149. package/dist/proto/google/protobuf/wrappers.d.ts.map +1 -0
  150. package/dist/test_env.d.ts +1 -0
  151. package/dist/test_env.d.ts.map +1 -0
  152. package/package.json +12 -11
  153. package/src/clients/upload.ts +38 -14
  154. package/src/drivers/ls.ts +17 -6
  155. package/src/drivers/upload_task.ts +10 -3
  156. package/src/proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.ts +69 -1
@@ -1,13 +1,14 @@
1
- import { PlClient } from '@milaboratories/pl-client';
2
- import { MiLogger } from '@milaboratories/ts-helpers';
1
+ import type { PlClient } from '@milaboratories/pl-client';
2
+ import type { MiLogger } from '@milaboratories/ts-helpers';
3
3
  import { ClientDownload } from './download';
4
4
  import { ClientLogs } from './logs';
5
5
  import { ClientProgress } from './progress';
6
6
  import { ClientUpload } from './upload';
7
7
  import { ClientLs } from './ls_api';
8
- import { LocalStorageProjection } from '../drivers/types';
8
+ import type { LocalStorageProjection } from '../drivers/types';
9
9
  export declare function createDownloadClient(logger: MiLogger, client: PlClient, localProjections: LocalStorageProjection[]): ClientDownload;
10
10
  export declare function createLogsClient(client: PlClient, logger: MiLogger): ClientLogs;
11
11
  export declare function createUploadProgressClient(client: PlClient, logger: MiLogger): ClientProgress;
12
12
  export declare function createUploadBlobClient(client: PlClient, logger: MiLogger): ClientUpload;
13
13
  export declare function createLsFilesClient(client: PlClient, logger: MiLogger): ClientLs;
14
+ //# sourceMappingURL=constructors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constructors.d.ts","sourceRoot":"","sources":["../../src/clients/constructors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA6B,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACrF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAE3D,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAE/D,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,QAAQ,EAChB,MAAM,EAAE,QAAQ,EAChB,gBAAgB,EAAE,sBAAsB,EAAE,kBAO3C;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,cAMlE;AAED,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,kBAM5E;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,gBAMxE;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,YAMrE"}
@@ -1,10 +1,10 @@
1
- import { GrpcClientProvider, GrpcClientProviderFactory } from '@milaboratories/pl-client';
2
- import { ResourceInfo } from '@milaboratories/pl-tree';
3
- import { MiLogger } from '@milaboratories/ts-helpers';
4
- import { RpcOptions } from '@protobuf-ts/runtime-rpc';
5
- import { Dispatcher } from 'undici';
6
- import { LocalStorageProjection } from '../drivers/types';
7
- import { DownloadOps, ContentHandler } from '../helpers/download';
1
+ import type { GrpcClientProvider, GrpcClientProviderFactory } from '@milaboratories/pl-client';
2
+ import type { ResourceInfo } from '@milaboratories/pl-tree';
3
+ import type { MiLogger } from '@milaboratories/ts-helpers';
4
+ import type { RpcOptions } from '@protobuf-ts/runtime-rpc';
5
+ import type { Dispatcher } from 'undici';
6
+ import type { LocalStorageProjection } from '../drivers/types';
7
+ import type { DownloadOps, ContentHandler } from '../helpers/download';
8
8
  import { DownloadClient } from '../proto/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.client';
9
9
  /** Gets URLs for downloading from pl-core, parses them and reads or downloads
10
10
  * files locally and from the web. */
@@ -45,3 +45,4 @@ export declare class UnknownStorageError extends Error {
45
45
  name: string;
46
46
  }
47
47
  export declare function newLocalStorageIdsToRoot(projections: LocalStorageProjection[]): Map<string, string>;
48
+ //# sourceMappingURL=download.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../../src/clients/download.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AAE/F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAE3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAK3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAIvE,OAAO,EAAE,cAAc,EAAE,MAAM,yFAAyF,CAAC;AAEzH;qCACqC;AACrC,qBAAa,cAAc;aAYP,UAAU,EAAE,UAAU;aACtB,MAAM,EAAE,QAAQ;IAZlC,SAAgB,UAAU,EAAE,kBAAkB,CAAC,cAAc,CAAC,CAAC;IAC/D,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAuB;IAE5D,8EAA8E;IAC9E,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAsB;IAE5D,4EAA4E;IAC5E,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAuC;gBAG1E,yBAAyB,EAAE,yBAAyB,EACpC,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,QAAQ;IAChC,oCAAoC;IACpC,gBAAgB,EAAE,sBAAsB,EAAE;IAO5C,KAAK;IAEL;;;;;OAKG;IACG,eAAe,CAAC,CAAC,EACrB,IAAI,EAAE,YAAY,EAClB,OAAO,EAAE,UAAU,GAAG,SAAS,EAC/B,GAAG,EAAE,WAAW,EAChB,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,GACzB,OAAO,CAAC,CAAC,CAAC;IAWP,oBAAoB,CAAC,CAAC,EAC1B,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,WAAW,EAChB,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,GACzB,OAAO,CAAC,CAAC,CAAC;YA8BC,kBAAkB;CAajC;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM;;;EASxC;AAED,wBAAgB,WAAW,CACzB,SAAS,EAAE,MAAM,EACjB,qBAAqB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAC1C,YAAY,EAAE,MAAM,UAQrB;AAOD,mDAAmD;AACnD,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,IAAI,SAAuB;CAC5B;AAED,+DAA+D;AAC/D,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,IAAI,SAAyB;CAC9B;AAED,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,sBAAsB,EAAE,uBAW7E"}
@@ -1,10 +1,10 @@
1
1
  import { StreamingClient } from '../proto/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.client';
2
- import { RpcOptions } from '@protobuf-ts/runtime-rpc';
3
- import { MiLogger } from '@milaboratories/ts-helpers';
4
- import { Dispatcher } from 'undici';
5
- import { GrpcClientProvider, GrpcClientProviderFactory } from '@milaboratories/pl-client';
6
- import { StreamingAPI_Response } from '../proto/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol';
7
- import { ResourceInfo } from '@milaboratories/pl-tree';
2
+ import type { RpcOptions } from '@protobuf-ts/runtime-rpc';
3
+ import type { MiLogger } from '@milaboratories/ts-helpers';
4
+ import type { Dispatcher } from 'undici';
5
+ import type { GrpcClientProvider, GrpcClientProviderFactory } from '@milaboratories/pl-client';
6
+ import type { StreamingAPI_Response } from '../proto/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol';
7
+ import type { ResourceInfo } from '@milaboratories/pl-tree';
8
8
  export declare class ClientLogs {
9
9
  readonly httpClient: Dispatcher;
10
10
  readonly logger: MiLogger;
@@ -22,3 +22,4 @@ export declare class ClientLogs {
22
22
  readText({ id: rId, type: rType }: ResourceInfo, lineCount: number, offsetBytes?: bigint, // if 0n, then start from the beginning.
23
23
  searchStr?: string, options?: RpcOptions): Promise<StreamingAPI_Response>;
24
24
  }
25
+ //# sourceMappingURL=logs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../src/clients/logs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,0FAA0F,CAAC;AAC3H,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAE3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,KAAK,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AAE/F,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mFAAmF,CAAC;AAC/H,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAE5D,qBAAa,UAAU;aAKH,UAAU,EAAE,UAAU;aACtB,MAAM,EAAE,QAAQ;IALlC,SAAgB,UAAU,EAAE,kBAAkB,CAAC,eAAe,CAAC,CAAC;gBAG9D,yBAAyB,EAAE,yBAAyB,EACpC,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,QAAQ;IAKlC,KAAK;IAEL;;8DAE0D;IAC7C,SAAS,CACpB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,YAAY,EACtC,SAAS,EAAE,MAAM,EACjB,WAAW,GAAE,MAAW,EAAE,kCAAkC;IAC5D,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,UAAU,GACnB,OAAO,CAAC,qBAAqB,CAAC;IAcjC;;8DAE0D;IAC7C,QAAQ,CACnB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,YAAY,EACtC,SAAS,EAAE,MAAM,EACjB,WAAW,GAAE,MAAW,EAAE,wCAAwC;IAClE,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,UAAU,GACnB,OAAO,CAAC,qBAAqB,CAAC;CAalC"}
@@ -1,8 +1,8 @@
1
- import { MiLogger } from '@milaboratories/ts-helpers';
2
- import { LsAPI_List_Response } from '../proto/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol';
3
- import { RpcOptions } from '@protobuf-ts/runtime-rpc';
4
- import { GrpcClientProviderFactory } from '@milaboratories/pl-client';
5
- import { ResourceInfo } from '@milaboratories/pl-tree';
1
+ import type { MiLogger } from '@milaboratories/ts-helpers';
2
+ import type { LsAPI_List_Response } from '../proto/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol';
3
+ import type { RpcOptions } from '@protobuf-ts/runtime-rpc';
4
+ import type { GrpcClientProviderFactory } from '@milaboratories/pl-client';
5
+ import type { ResourceInfo } from '@milaboratories/pl-tree';
6
6
  export declare class ClientLs {
7
7
  private readonly logger;
8
8
  private readonly grpcClient;
@@ -10,3 +10,4 @@ export declare class ClientLs {
10
10
  close(): void;
11
11
  list(rInfo: ResourceInfo, path: string, options?: RpcOptions): Promise<LsAPI_List_Response>;
12
12
  }
13
+ //# sourceMappingURL=ls_api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ls_api.d.ts","sourceRoot":"","sources":["../../src/clients/ls_api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4EAA4E,CAAC;AAEtH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,EAAsB,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AAE/F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAE5D,qBAAa,QAAQ;IAKjB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAJzB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA+B;gBAGxD,yBAAyB,EAAE,yBAAyB,EACnC,MAAM,EAAE,QAAQ;IAKnC,KAAK;IAEQ,IAAI,CACf,KAAK,EAAE,YAAY,EACnB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,UAAU,GACnB,OAAO,CAAC,mBAAmB,CAAC;CAShC"}
@@ -1,9 +1,9 @@
1
1
  import { ProgressClient } from '../proto/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.client';
2
- import { RpcOptions } from '@protobuf-ts/runtime-rpc';
3
- import { GrpcClientProvider, GrpcClientProviderFactory, PlClient } from '@milaboratories/pl-client';
4
- import { MiLogger } from '@milaboratories/ts-helpers';
5
- import { Dispatcher } from 'undici';
6
- import { ResourceInfo } from '@milaboratories/pl-tree';
2
+ import type { RpcOptions } from '@protobuf-ts/runtime-rpc';
3
+ import type { GrpcClientProvider, GrpcClientProviderFactory, PlClient } from '@milaboratories/pl-client';
4
+ import type { MiLogger } from '@milaboratories/ts-helpers';
5
+ import type { Dispatcher } from 'undici';
6
+ import type { ResourceInfo } from '@milaboratories/pl-tree';
7
7
  export type ProgressStatus = {
8
8
  done: boolean;
9
9
  progress: number;
@@ -18,5 +18,6 @@ export declare class ClientProgress {
18
18
  close(): void;
19
19
  /** getStatus gets a progress status by given rId and rType. */
20
20
  getStatus({ id, type }: ResourceInfo, options?: RpcOptions): Promise<ProgressStatus>;
21
- realtimeStatus({ id, type }: ResourceInfo, updateIntervalMs?: number, options?: RpcOptions): AsyncGenerator<import('../proto/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol').ProgressAPI_RealtimeStatus_Response, void, any>;
21
+ realtimeStatus({ id, type }: ResourceInfo, updateIntervalMs?: number, options?: RpcOptions): AsyncGenerator<import("../proto/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol").ProgressAPI_RealtimeStatus_Response, void, any>;
22
22
  }
23
+ //# sourceMappingURL=progress.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../src/clients/progress.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,yFAAyF,CAAC;AACzH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAE3D,OAAO,KAAK,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAEzG,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAE3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAE5D,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAMF,qBAAa,cAAc;aAMP,MAAM,EAAE,QAAQ;aAChB,MAAM,EAAE,QAAQ;IANlC,SAAgB,UAAU,EAAE,kBAAkB,CAAC,cAAc,CAAC,CAAC;gBAG7D,yBAAyB,EAAE,yBAAyB,EACpD,CAAC,EAAE,UAAU,EACG,MAAM,EAAE,QAAQ,EAChB,MAAM,EAAE,QAAQ;IAKlC,KAAK;IAEL,+DAA+D;IACzD,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,cAAc,CAAC;IAkBnF,cAAc,CACnB,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,YAAY,EAC1B,gBAAgB,GAAE,MAAY,EAC9B,OAAO,CAAC,EAAE,UAAU;CA0BvB"}
@@ -3,6 +3,8 @@
3
3
  var plClient = require('@milaboratories/pl-client');
4
4
  var fsp = require('node:fs/promises');
5
5
  var undici = require('undici');
6
+ var crc32 = require('@node-rs/crc32');
7
+ var protocol = require('../proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.cjs');
6
8
  var protocol_client = require('../proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client.cjs');
7
9
 
8
10
  function _interopNamespaceDefault(e) {
@@ -37,6 +39,9 @@ class NetworkError extends Error {
37
39
  class NoFileForUploading extends Error {
38
40
  name = 'NoFileForUploading';
39
41
  }
42
+ class BadRequestError extends Error {
43
+ name = 'BadRequestError';
44
+ }
40
45
  /** Low-level client for grpc uploadapi.
41
46
  * The user should pass here a concrete BlobUpload/<storageId> resource,
42
47
  * it can be got from handle field of BlobUpload. */
@@ -55,26 +60,24 @@ class ClientUpload {
55
60
  return {
56
61
  overall: init.partsCount,
57
62
  toUpload: this.partsToUpload(init.partsCount, init.uploadedParts),
63
+ checksumAlgorithm: init.checksumAlgorithm,
64
+ checksumHeader: init.checksumHeader,
58
65
  };
59
66
  }
60
- async partUpload({ id, type }, path, expectedMTimeUnix, partNumber, options) {
67
+ async partUpload({ id, type }, path, expectedMTimeUnix, partNumber, checksumAlgorithm, checksumHeader, options) {
61
68
  const info = await this.grpcGetPartUrl({ id, type }, partNumber, 0n, // we update progress as a separate call later.
62
69
  options);
63
70
  const chunk = await readFileChunk(path, info.chunkStart, info.chunkEnd);
64
71
  await checkExpectedMTime(path, expectedMTimeUnix);
72
+ const crc32cChecksum = calculateCrc32cChecksum(chunk);
73
+ if (checksumAlgorithm === protocol.uploadapi_ChecksumAlgorithm.CRC32C) {
74
+ info.headers.push({ name: checksumHeader, value: crc32cChecksum });
75
+ }
65
76
  const contentLength = Number(info.chunkEnd - info.chunkStart);
66
77
  if (chunk.length !== contentLength) {
67
78
  throw new Error(`Chunk size mismatch: expected ${contentLength} bytes, but read ${chunk.length} bytes from file`);
68
79
  }
69
80
  const headers = Object.fromEntries(info.headers.map(({ name, value }) => [name, value]));
70
- const contentLengthKey = Object.keys(headers).find((key) => key.toLowerCase() === 'content-length');
71
- if (contentLengthKey) {
72
- const existingContentLength = Number(headers[contentLengthKey]);
73
- if (existingContentLength !== contentLength) {
74
- throw new Error(`Content-Length mismatch: expected ${contentLength}, but got ${existingContentLength} in headers`);
75
- }
76
- }
77
- // content length will be automatically added by undici, so we don't need to set it here
78
81
  try {
79
82
  const { body: rawBody, statusCode, headers: responseHeaders, } = await undici.request(info.uploadUrl, {
80
83
  dispatcher: this.httpClient,
@@ -99,6 +102,8 @@ class ClientUpload {
99
102
  catch (e) {
100
103
  if (e instanceof NetworkError)
101
104
  throw e;
105
+ if (e instanceof BadRequestError)
106
+ throw e;
102
107
  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)}`);
103
108
  }
104
109
  await this.grpcUpdateProgress({ id, type }, BigInt(info.chunkEnd - info.chunkStart), options);
@@ -122,7 +127,8 @@ class ClientUpload {
122
127
  .response;
123
128
  }
124
129
  async grpcGetPartUrl({ id, type }, partNumber, uploadedPartSize, options) {
125
- return await this.grpcClient.get().getPartURL({ resourceId: id, partNumber, uploadedPartSize, isInternalUse: false }, plClient.addRTypeToMetadata(type, options)).response;
130
+ // partChecksum isn't used for now but protoc requires it to be set
131
+ return await this.grpcClient.get().getPartURL({ resourceId: id, partNumber, uploadedPartSize, isInternalUse: false, partChecksum: '' }, plClient.addRTypeToMetadata(type, options)).response;
126
132
  }
127
133
  async grpcUpdateProgress({ id, type }, bytesProcessed, options) {
128
134
  await this.grpcClient.get().updateProgress({
@@ -174,12 +180,27 @@ async function checkExpectedMTime(path, expectedMTimeUnix) {
174
180
  }
175
181
  }
176
182
  function checkStatusCodeOk(statusCode, body, headers, info) {
183
+ if (statusCode == 400) {
184
+ throw new BadRequestError(`response is not ok, status code: ${statusCode},`
185
+ + ` body: ${body}, headers: ${JSON.stringify(headers)}, url: ${info.uploadUrl}`);
186
+ }
177
187
  if (statusCode != 200) {
178
188
  throw new NetworkError(`response is not ok, status code: ${statusCode},`
179
189
  + ` body: ${body}, headers: ${JSON.stringify(headers)}, url: ${info.uploadUrl}`);
180
190
  }
181
191
  }
192
+ /** Calculate CRC32C checksum of a buffer and return as base64 string */
193
+ function calculateCrc32cChecksum(data) {
194
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call
195
+ const checksum = crc32.crc32c(data);
196
+ // Convert to unsigned 32-bit integer and then to base64
197
+ const buffer = Buffer.alloc(4);
198
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
199
+ buffer.writeUInt32BE(checksum, 0);
200
+ return buffer.toString('base64');
201
+ }
182
202
 
203
+ exports.BadRequestError = BadRequestError;
183
204
  exports.ClientUpload = ClientUpload;
184
205
  exports.MTimeError = MTimeError;
185
206
  exports.NetworkError = NetworkError;
@@ -1 +1 @@
1
- {"version":3,"file":"upload.cjs","sources":["../../src/clients/upload.ts"],"sourcesContent":["import type { GrpcClientProvider, GrpcClientProviderFactory, PlClient, ResourceId, ResourceType } from '@milaboratories/pl-client';\nimport { addRTypeToMetadata } 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 type { uploadapi_GetPartURL_Response } from '../proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol';\nimport { UploadClient } from '../proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client';\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\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 grpcClient: GrpcClientProvider<UploadClient>;\n\n constructor(\n grpcClientProviderFactory: GrpcClientProviderFactory,\n public readonly httpClient: Dispatcher,\n _: PlClient,\n public readonly logger: MiLogger,\n ) {\n this.grpcClient = grpcClientProviderFactory.createGrpcClientProvider((transport) => new UploadClient(transport));\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 }> {\n const init = await this.grpcInit(id, type, options);\n return {\n overall: init.partsCount,\n toUpload: this.partsToUpload(init.partsCount, init.uploadedParts),\n };\n }\n\n public async partUpload(\n { id, type }: ResourceInfo,\n path: string,\n expectedMTimeUnix: bigint,\n partNumber: bigint,\n options?: RpcOptions,\n ) {\n const info = await this.grpcGetPartUrl(\n { id, type },\n partNumber,\n 0n, // we update progress as a separate call later.\n options,\n );\n\n const chunk = await readFileChunk(path, info.chunkStart, info.chunkEnd);\n await checkExpectedMTime(path, expectedMTimeUnix);\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(info.headers.map(({ name, value }) => [name, value]));\n\n const contentLengthKey = Object.keys(headers).find((key) => key.toLowerCase() === 'content-length');\n if (contentLengthKey) {\n const existingContentLength = Number(headers[contentLengthKey]);\n if (existingContentLength !== contentLength) {\n throw new Error(\n `Content-Length mismatch: expected ${contentLength}, but got ${existingContentLength} in headers`,\n );\n }\n }\n\n // content length will be automatically added by undici, so we don't need to set it here\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)\n throw e;\n\n 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)}`);\n }\n\n await this.grpcUpdateProgress({ id, type }, BigInt(info.chunkEnd - info.chunkStart), options);\n }\n\n public async finalize(info: ResourceInfo, options?: RpcOptions) {\n return await this.grpcFinalize(info, options);\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 grpcInit(id: ResourceId, type: ResourceType, options?: RpcOptions) {\n return await this.grpcClient.get().init({ resourceId: id }, addRTypeToMetadata(type, options))\n .response;\n }\n\n private async grpcGetPartUrl(\n { id, type }: ResourceInfo,\n partNumber: bigint,\n uploadedPartSize: bigint,\n options?: RpcOptions,\n ) {\n return await this.grpcClient.get().getPartURL(\n { resourceId: id, partNumber, uploadedPartSize, isInternalUse: false },\n addRTypeToMetadata(type, options),\n ).response;\n }\n\n private async grpcUpdateProgress(\n { id, type }: ResourceInfo,\n bytesProcessed: bigint,\n options?: RpcOptions,\n ) {\n await this.grpcClient.get().updateProgress(\n {\n resourceId: id,\n bytesProcessed,\n },\n addRTypeToMetadata(type, options),\n ).response;\n }\n\n private async grpcFinalize({ id, type }: ResourceInfo, options?: RpcOptions) {\n return await this.grpcClient.get().finalize({ resourceId: id }, addRTypeToMetadata(type, options))\n .response;\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') 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 != 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"],"names":["UploadClient","request","addRTypeToMetadata","fs"],"mappings":"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"}
1
+ {"version":3,"file":"upload.cjs","sources":["../../src/clients/upload.ts"],"sourcesContent":["import type { GrpcClientProvider, GrpcClientProviderFactory, PlClient, ResourceId, ResourceType } from '@milaboratories/pl-client';\nimport { addRTypeToMetadata } 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 { crc32c } from '@node-rs/crc32';\nimport { uploadapi_ChecksumAlgorithm, type uploadapi_GetPartURL_Response } from '../proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol';\nimport { UploadClient } from '../proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client';\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 grpcClient: GrpcClientProvider<UploadClient>;\n\n constructor(\n grpcClientProviderFactory: GrpcClientProviderFactory,\n public readonly httpClient: Dispatcher,\n _: PlClient,\n public readonly logger: MiLogger,\n ) {\n this.grpcClient = grpcClientProviderFactory.createGrpcClientProvider((transport) => new UploadClient(transport));\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 init = await this.grpcInit(id, type, options);\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 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 info = await this.grpcGetPartUrl(\n { id, type },\n partNumber,\n 0n, // we update progress as a separate call later.\n options,\n );\n\n const chunk = await readFileChunk(path, info.chunkStart, info.chunkEnd);\n await checkExpectedMTime(path, expectedMTimeUnix);\n\n const crc32cChecksum = calculateCrc32cChecksum(chunk);\n if (checksumAlgorithm === uploadapi_ChecksumAlgorithm.CRC32C) {\n info.headers.push({ name: checksumHeader, value: crc32cChecksum });\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(info.headers.map(({ name, value }) => [name, value]));\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)\n throw e;\n\n if (e instanceof BadRequestError)\n throw e;\n\n 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)}`);\n }\n\n await this.grpcUpdateProgress({ id, type }, BigInt(info.chunkEnd - info.chunkStart), options);\n }\n\n public async finalize(info: ResourceInfo, options?: RpcOptions) {\n return await this.grpcFinalize(info, options);\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 grpcInit(id: ResourceId, type: ResourceType, options?: RpcOptions) {\n return await this.grpcClient.get().init({ resourceId: id }, addRTypeToMetadata(type, options))\n .response;\n }\n\n private async grpcGetPartUrl(\n { id, type }: ResourceInfo,\n partNumber: bigint,\n uploadedPartSize: bigint,\n options?: RpcOptions,\n ) {\n // partChecksum isn't used for now but protoc requires it to be set\n return await this.grpcClient.get().getPartURL(\n { resourceId: id, partNumber, uploadedPartSize, isInternalUse: false, partChecksum: '' },\n addRTypeToMetadata(type, options),\n ).response;\n }\n\n private async grpcUpdateProgress(\n { id, type }: ResourceInfo,\n bytesProcessed: bigint,\n options?: RpcOptions,\n ) {\n await this.grpcClient.get().updateProgress(\n {\n resourceId: id,\n bytesProcessed,\n },\n addRTypeToMetadata(type, options),\n ).response;\n }\n\n private async grpcFinalize({ id, type }: ResourceInfo, options?: RpcOptions) {\n return await this.grpcClient.get().finalize({ resourceId: id }, addRTypeToMetadata(type, options))\n .response;\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') 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(`response is not ok, status code: ${statusCode},`\n + ` body: ${body}, headers: ${JSON.stringify(headers)}, url: ${info.uploadUrl}`);\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 // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call\n const checksum = crc32c(data);\n // Convert to unsigned 32-bit integer and then to base64\n const buffer = Buffer.alloc(4);\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n buffer.writeUInt32BE(checksum, 0);\n return buffer.toString('base64');\n}\n"],"names":["UploadClient","uploadapi_ChecksumAlgorithm","request","addRTypeToMetadata","fs","crc32c"],"mappings":"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"}
@@ -1,8 +1,9 @@
1
- import { GrpcClientProviderFactory, PlClient } from '@milaboratories/pl-client';
2
- import { ResourceInfo } from '@milaboratories/pl-tree';
3
- import { MiLogger } from '@milaboratories/ts-helpers';
4
- import { RpcOptions } from '@protobuf-ts/runtime-rpc';
5
- import { Dispatcher } from 'undici';
1
+ import type { GrpcClientProviderFactory, PlClient } from '@milaboratories/pl-client';
2
+ import type { ResourceInfo } from '@milaboratories/pl-tree';
3
+ import type { MiLogger } from '@milaboratories/ts-helpers';
4
+ import type { RpcOptions } from '@protobuf-ts/runtime-rpc';
5
+ import type { Dispatcher } from 'undici';
6
+ import { uploadapi_ChecksumAlgorithm } from '../proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol';
6
7
  export declare class MTimeError extends Error {
7
8
  name: string;
8
9
  }
@@ -16,6 +17,9 @@ export declare class NetworkError extends Error {
16
17
  export declare class NoFileForUploading extends Error {
17
18
  name: string;
18
19
  }
20
+ export declare class BadRequestError extends Error {
21
+ name: string;
22
+ }
19
23
  /** Low-level client for grpc uploadapi.
20
24
  * The user should pass here a concrete BlobUpload/<storageId> resource,
21
25
  * it can be got from handle field of BlobUpload. */
@@ -28,9 +32,11 @@ export declare class ClientUpload {
28
32
  initUpload({ id, type }: ResourceInfo, options?: RpcOptions): Promise<{
29
33
  overall: bigint;
30
34
  toUpload: bigint[];
35
+ checksumAlgorithm: uploadapi_ChecksumAlgorithm;
36
+ checksumHeader: string;
31
37
  }>;
32
- partUpload({ id, type }: ResourceInfo, path: string, expectedMTimeUnix: bigint, partNumber: bigint, options?: RpcOptions): Promise<void>;
33
- finalize(info: ResourceInfo, options?: RpcOptions): Promise<import('../proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol').uploadapi_Finalize_Response>;
38
+ partUpload({ id, type }: ResourceInfo, path: string, expectedMTimeUnix: bigint, partNumber: bigint, checksumAlgorithm: uploadapi_ChecksumAlgorithm, checksumHeader: string, options?: RpcOptions): Promise<void>;
39
+ finalize(info: ResourceInfo, options?: RpcOptions): Promise<import("../proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol").uploadapi_Finalize_Response>;
34
40
  /** Calculates parts that need to be uploaded from the parts that were
35
41
  * already uploaded. */
36
42
  private partsToUpload;
@@ -39,3 +45,4 @@ export declare class ClientUpload {
39
45
  private grpcUpdateProgress;
40
46
  private grpcFinalize;
41
47
  }
48
+ //# sourceMappingURL=upload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../src/clients/upload.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsB,yBAAyB,EAAE,QAAQ,EAA4B,MAAM,2BAA2B,CAAC;AAEnI,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAE3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAGzC,OAAO,EAAE,2BAA2B,EAAsC,MAAM,gFAAgF,CAAC;AAKjK,qBAAa,UAAW,SAAQ,KAAK;IACnC,IAAI,SAAgB;CACrB;AAED,qBAAa,aAAc,SAAQ,KAAK;IACtC,IAAI,SAAmB;CACxB;AAED,qBAAa,YAAa,SAAQ,KAAK;IACrC,IAAI,SAAkB;CACvB;AAED,0CAA0C;AAC1C,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,IAAI,SAAwB;CAC7B;AAED,qBAAa,eAAgB,SAAQ,KAAK;IACxC,IAAI,SAAqB;CAC1B;AAED;;oDAEoD;AACpD,qBAAa,YAAY;aAKL,UAAU,EAAE,UAAU;aAEtB,MAAM,EAAE,QAAQ;IANlC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAmC;gBAG5D,yBAAyB,EAAE,yBAAyB,EACpC,UAAU,EAAE,UAAU,EACtC,CAAC,EAAE,QAAQ,EACK,MAAM,EAAE,QAAQ;IAKlC,KAAK;IAEQ,UAAU,CACrB,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,YAAY,EAC1B,OAAO,CAAC,EAAE,UAAU,GACnB,OAAO,CAAC;QACP,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;QACnB,iBAAiB,EAAE,2BAA2B,CAAC;QAC/C,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;IAUS,UAAU,CACrB,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,YAAY,EAC1B,IAAI,EAAE,MAAM,EACZ,iBAAiB,EAAE,MAAM,EACzB,UAAU,EAAE,MAAM,EAClB,iBAAiB,EAAE,2BAA2B,EAC9C,cAAc,EAAE,MAAM,EACtB,OAAO,CAAC,EAAE,UAAU;IAgET,QAAQ,CAAC,IAAI,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,UAAU;IAI9D;2BACuB;IACvB,OAAO,CAAC,aAAa;YAWP,QAAQ;YAKR,cAAc;YAad,kBAAkB;YAclB,YAAY;CAI3B"}
@@ -1,6 +1,8 @@
1
1
  import { addRTypeToMetadata } from '@milaboratories/pl-client';
2
2
  import * as fsp from 'node:fs/promises';
3
3
  import { request } from 'undici';
4
+ import { crc32c } from '@node-rs/crc32';
5
+ import { uploadapi_ChecksumAlgorithm } from '../proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.js';
4
6
  import { UploadClient } from '../proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client.js';
5
7
 
6
8
  class MTimeError extends Error {
@@ -16,6 +18,9 @@ class NetworkError extends Error {
16
18
  class NoFileForUploading extends Error {
17
19
  name = 'NoFileForUploading';
18
20
  }
21
+ class BadRequestError extends Error {
22
+ name = 'BadRequestError';
23
+ }
19
24
  /** Low-level client for grpc uploadapi.
20
25
  * The user should pass here a concrete BlobUpload/<storageId> resource,
21
26
  * it can be got from handle field of BlobUpload. */
@@ -34,26 +39,24 @@ class ClientUpload {
34
39
  return {
35
40
  overall: init.partsCount,
36
41
  toUpload: this.partsToUpload(init.partsCount, init.uploadedParts),
42
+ checksumAlgorithm: init.checksumAlgorithm,
43
+ checksumHeader: init.checksumHeader,
37
44
  };
38
45
  }
39
- async partUpload({ id, type }, path, expectedMTimeUnix, partNumber, options) {
46
+ async partUpload({ id, type }, path, expectedMTimeUnix, partNumber, checksumAlgorithm, checksumHeader, options) {
40
47
  const info = await this.grpcGetPartUrl({ id, type }, partNumber, 0n, // we update progress as a separate call later.
41
48
  options);
42
49
  const chunk = await readFileChunk(path, info.chunkStart, info.chunkEnd);
43
50
  await checkExpectedMTime(path, expectedMTimeUnix);
51
+ const crc32cChecksum = calculateCrc32cChecksum(chunk);
52
+ if (checksumAlgorithm === uploadapi_ChecksumAlgorithm.CRC32C) {
53
+ info.headers.push({ name: checksumHeader, value: crc32cChecksum });
54
+ }
44
55
  const contentLength = Number(info.chunkEnd - info.chunkStart);
45
56
  if (chunk.length !== contentLength) {
46
57
  throw new Error(`Chunk size mismatch: expected ${contentLength} bytes, but read ${chunk.length} bytes from file`);
47
58
  }
48
59
  const headers = Object.fromEntries(info.headers.map(({ name, value }) => [name, value]));
49
- const contentLengthKey = Object.keys(headers).find((key) => key.toLowerCase() === 'content-length');
50
- if (contentLengthKey) {
51
- const existingContentLength = Number(headers[contentLengthKey]);
52
- if (existingContentLength !== contentLength) {
53
- throw new Error(`Content-Length mismatch: expected ${contentLength}, but got ${existingContentLength} in headers`);
54
- }
55
- }
56
- // content length will be automatically added by undici, so we don't need to set it here
57
60
  try {
58
61
  const { body: rawBody, statusCode, headers: responseHeaders, } = await request(info.uploadUrl, {
59
62
  dispatcher: this.httpClient,
@@ -78,6 +81,8 @@ class ClientUpload {
78
81
  catch (e) {
79
82
  if (e instanceof NetworkError)
80
83
  throw e;
84
+ if (e instanceof BadRequestError)
85
+ throw e;
81
86
  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)}`);
82
87
  }
83
88
  await this.grpcUpdateProgress({ id, type }, BigInt(info.chunkEnd - info.chunkStart), options);
@@ -101,7 +106,8 @@ class ClientUpload {
101
106
  .response;
102
107
  }
103
108
  async grpcGetPartUrl({ id, type }, partNumber, uploadedPartSize, options) {
104
- return await this.grpcClient.get().getPartURL({ resourceId: id, partNumber, uploadedPartSize, isInternalUse: false }, addRTypeToMetadata(type, options)).response;
109
+ // partChecksum isn't used for now but protoc requires it to be set
110
+ return await this.grpcClient.get().getPartURL({ resourceId: id, partNumber, uploadedPartSize, isInternalUse: false, partChecksum: '' }, addRTypeToMetadata(type, options)).response;
105
111
  }
106
112
  async grpcUpdateProgress({ id, type }, bytesProcessed, options) {
107
113
  await this.grpcClient.get().updateProgress({
@@ -153,11 +159,25 @@ async function checkExpectedMTime(path, expectedMTimeUnix) {
153
159
  }
154
160
  }
155
161
  function checkStatusCodeOk(statusCode, body, headers, info) {
162
+ if (statusCode == 400) {
163
+ throw new BadRequestError(`response is not ok, status code: ${statusCode},`
164
+ + ` body: ${body}, headers: ${JSON.stringify(headers)}, url: ${info.uploadUrl}`);
165
+ }
156
166
  if (statusCode != 200) {
157
167
  throw new NetworkError(`response is not ok, status code: ${statusCode},`
158
168
  + ` body: ${body}, headers: ${JSON.stringify(headers)}, url: ${info.uploadUrl}`);
159
169
  }
160
170
  }
171
+ /** Calculate CRC32C checksum of a buffer and return as base64 string */
172
+ function calculateCrc32cChecksum(data) {
173
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call
174
+ const checksum = crc32c(data);
175
+ // Convert to unsigned 32-bit integer and then to base64
176
+ const buffer = Buffer.alloc(4);
177
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
178
+ buffer.writeUInt32BE(checksum, 0);
179
+ return buffer.toString('base64');
180
+ }
161
181
 
162
- export { ClientUpload, MTimeError, NetworkError, NoFileForUploading, UnexpectedEOF };
182
+ export { BadRequestError, ClientUpload, MTimeError, NetworkError, NoFileForUploading, UnexpectedEOF };
163
183
  //# sourceMappingURL=upload.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"upload.js","sources":["../../src/clients/upload.ts"],"sourcesContent":["import type { GrpcClientProvider, GrpcClientProviderFactory, PlClient, ResourceId, ResourceType } from '@milaboratories/pl-client';\nimport { addRTypeToMetadata } 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 type { uploadapi_GetPartURL_Response } from '../proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol';\nimport { UploadClient } from '../proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client';\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\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 grpcClient: GrpcClientProvider<UploadClient>;\n\n constructor(\n grpcClientProviderFactory: GrpcClientProviderFactory,\n public readonly httpClient: Dispatcher,\n _: PlClient,\n public readonly logger: MiLogger,\n ) {\n this.grpcClient = grpcClientProviderFactory.createGrpcClientProvider((transport) => new UploadClient(transport));\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 }> {\n const init = await this.grpcInit(id, type, options);\n return {\n overall: init.partsCount,\n toUpload: this.partsToUpload(init.partsCount, init.uploadedParts),\n };\n }\n\n public async partUpload(\n { id, type }: ResourceInfo,\n path: string,\n expectedMTimeUnix: bigint,\n partNumber: bigint,\n options?: RpcOptions,\n ) {\n const info = await this.grpcGetPartUrl(\n { id, type },\n partNumber,\n 0n, // we update progress as a separate call later.\n options,\n );\n\n const chunk = await readFileChunk(path, info.chunkStart, info.chunkEnd);\n await checkExpectedMTime(path, expectedMTimeUnix);\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(info.headers.map(({ name, value }) => [name, value]));\n\n const contentLengthKey = Object.keys(headers).find((key) => key.toLowerCase() === 'content-length');\n if (contentLengthKey) {\n const existingContentLength = Number(headers[contentLengthKey]);\n if (existingContentLength !== contentLength) {\n throw new Error(\n `Content-Length mismatch: expected ${contentLength}, but got ${existingContentLength} in headers`,\n );\n }\n }\n\n // content length will be automatically added by undici, so we don't need to set it here\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)\n throw e;\n\n 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)}`);\n }\n\n await this.grpcUpdateProgress({ id, type }, BigInt(info.chunkEnd - info.chunkStart), options);\n }\n\n public async finalize(info: ResourceInfo, options?: RpcOptions) {\n return await this.grpcFinalize(info, options);\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 grpcInit(id: ResourceId, type: ResourceType, options?: RpcOptions) {\n return await this.grpcClient.get().init({ resourceId: id }, addRTypeToMetadata(type, options))\n .response;\n }\n\n private async grpcGetPartUrl(\n { id, type }: ResourceInfo,\n partNumber: bigint,\n uploadedPartSize: bigint,\n options?: RpcOptions,\n ) {\n return await this.grpcClient.get().getPartURL(\n { resourceId: id, partNumber, uploadedPartSize, isInternalUse: false },\n addRTypeToMetadata(type, options),\n ).response;\n }\n\n private async grpcUpdateProgress(\n { id, type }: ResourceInfo,\n bytesProcessed: bigint,\n options?: RpcOptions,\n ) {\n await this.grpcClient.get().updateProgress(\n {\n resourceId: id,\n bytesProcessed,\n },\n addRTypeToMetadata(type, options),\n ).response;\n }\n\n private async grpcFinalize({ id, type }: ResourceInfo, options?: RpcOptions) {\n return await this.grpcClient.get().finalize({ resourceId: id }, addRTypeToMetadata(type, options))\n .response;\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') 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 != 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"],"names":["fs"],"mappings":"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"}
1
+ {"version":3,"file":"upload.js","sources":["../../src/clients/upload.ts"],"sourcesContent":["import type { GrpcClientProvider, GrpcClientProviderFactory, PlClient, ResourceId, ResourceType } from '@milaboratories/pl-client';\nimport { addRTypeToMetadata } 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 { crc32c } from '@node-rs/crc32';\nimport { uploadapi_ChecksumAlgorithm, type uploadapi_GetPartURL_Response } from '../proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol';\nimport { UploadClient } from '../proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client';\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 grpcClient: GrpcClientProvider<UploadClient>;\n\n constructor(\n grpcClientProviderFactory: GrpcClientProviderFactory,\n public readonly httpClient: Dispatcher,\n _: PlClient,\n public readonly logger: MiLogger,\n ) {\n this.grpcClient = grpcClientProviderFactory.createGrpcClientProvider((transport) => new UploadClient(transport));\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 init = await this.grpcInit(id, type, options);\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 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 info = await this.grpcGetPartUrl(\n { id, type },\n partNumber,\n 0n, // we update progress as a separate call later.\n options,\n );\n\n const chunk = await readFileChunk(path, info.chunkStart, info.chunkEnd);\n await checkExpectedMTime(path, expectedMTimeUnix);\n\n const crc32cChecksum = calculateCrc32cChecksum(chunk);\n if (checksumAlgorithm === uploadapi_ChecksumAlgorithm.CRC32C) {\n info.headers.push({ name: checksumHeader, value: crc32cChecksum });\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(info.headers.map(({ name, value }) => [name, value]));\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)\n throw e;\n\n if (e instanceof BadRequestError)\n throw e;\n\n 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)}`);\n }\n\n await this.grpcUpdateProgress({ id, type }, BigInt(info.chunkEnd - info.chunkStart), options);\n }\n\n public async finalize(info: ResourceInfo, options?: RpcOptions) {\n return await this.grpcFinalize(info, options);\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 grpcInit(id: ResourceId, type: ResourceType, options?: RpcOptions) {\n return await this.grpcClient.get().init({ resourceId: id }, addRTypeToMetadata(type, options))\n .response;\n }\n\n private async grpcGetPartUrl(\n { id, type }: ResourceInfo,\n partNumber: bigint,\n uploadedPartSize: bigint,\n options?: RpcOptions,\n ) {\n // partChecksum isn't used for now but protoc requires it to be set\n return await this.grpcClient.get().getPartURL(\n { resourceId: id, partNumber, uploadedPartSize, isInternalUse: false, partChecksum: '' },\n addRTypeToMetadata(type, options),\n ).response;\n }\n\n private async grpcUpdateProgress(\n { id, type }: ResourceInfo,\n bytesProcessed: bigint,\n options?: RpcOptions,\n ) {\n await this.grpcClient.get().updateProgress(\n {\n resourceId: id,\n bytesProcessed,\n },\n addRTypeToMetadata(type, options),\n ).response;\n }\n\n private async grpcFinalize({ id, type }: ResourceInfo, options?: RpcOptions) {\n return await this.grpcClient.get().finalize({ resourceId: id }, addRTypeToMetadata(type, options))\n .response;\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') 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(`response is not ok, status code: ${statusCode},`\n + ` body: ${body}, headers: ${JSON.stringify(headers)}, url: ${info.uploadUrl}`);\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 // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call\n const checksum = crc32c(data);\n // Convert to unsigned 32-bit integer and then to base64\n const buffer = Buffer.alloc(4);\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n buffer.writeUInt32BE(checksum, 0);\n return buffer.toString('base64');\n}\n"],"names":["fs"],"mappings":"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"}
@@ -1,4 +1,5 @@
1
- import { ResourceId } from '@milaboratories/pl-client';
1
+ import { ResourceId } from "@milaboratories/pl-client";
2
2
  export declare function blobKey(rId: ResourceId): string;
3
3
  export declare function pathToKey(fPath: string): string;
4
4
  export declare function pathToBlobInfo(fPath: string): ResourceId | undefined;
5
+ //# sourceMappingURL=blob_key.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blob_key.d.ts","sourceRoot":"","sources":["../../../src/drivers/download_blob/blob_key.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAG3E,wBAAgB,OAAO,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,CAE/C;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAGpE"}
@@ -1,9 +1,11 @@
1
- import { ComputableCtx, ComputableStableDefined, Computable } from '@milaboratories/computable';
2
- import { AnyLogHandle, BlobDriver, LocalBlobHandle, LocalBlobHandleAndSize, ReadyLogHandle, RemoteBlobHandle, RemoteBlobHandleAndSize, StreamingApiResponse, RangeBytes } from '@milaboratories/pl-model-common';
3
- import { PlTreeEntry, ResourceInfo } from '@milaboratories/pl-tree';
4
- import { MiLogger, Signer } from '@milaboratories/ts-helpers';
5
- import { ClientDownload } from '../../clients/download';
6
- import { ClientLogs } from '../../clients/logs';
1
+ import type { ComputableCtx, ComputableStableDefined } from '@milaboratories/computable';
2
+ import { Computable } from '@milaboratories/computable';
3
+ import type { AnyLogHandle, BlobDriver, LocalBlobHandle, LocalBlobHandleAndSize, ReadyLogHandle, RemoteBlobHandle, RemoteBlobHandleAndSize, StreamingApiResponse } from '@milaboratories/pl-model-common';
4
+ import { type RangeBytes } from '@milaboratories/pl-model-common';
5
+ import type { PlTreeEntry, ResourceInfo } from '@milaboratories/pl-tree';
6
+ import type { MiLogger, Signer } from '@milaboratories/ts-helpers';
7
+ import type { ClientDownload } from '../../clients/download';
8
+ import type { ClientLogs } from '../../clients/logs';
7
9
  import { OnDemandBlobResourceSnapshot } from '../types';
8
10
  export type DownloadDriverOps = {
9
11
  /**
@@ -92,3 +94,4 @@ export declare class DownloadDriver implements BlobDriver {
92
94
  /** Removes all files from a hard drive. */
93
95
  releaseAll(): Promise<void>;
94
96
  }
97
+ //# sourceMappingURL=download_blob.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"download_blob.d.ts","sourceRoot":"","sources":["../../../src/drivers/download_blob/download_blob.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,10 @@
1
- import { Watcher, ChangeSource } from '@milaboratories/computable';
2
- import { LocalBlobHandle, LocalBlobHandleAndSize } from '@milaboratories/pl-model-common';
3
- import { ResourceSnapshot } from '@milaboratories/pl-tree';
4
- import { ValueOrError, MiLogger, CallersCounter } from '@milaboratories/ts-helpers';
5
- import { ClientDownload } from '../../clients/download';
1
+ import type { Watcher } from '@milaboratories/computable';
2
+ import { ChangeSource } from '@milaboratories/computable';
3
+ import type { LocalBlobHandle, LocalBlobHandleAndSize } from '@milaboratories/pl-model-common';
4
+ import type { ResourceSnapshot } from '@milaboratories/pl-tree';
5
+ import type { ValueOrError, MiLogger } from '@milaboratories/ts-helpers';
6
+ import { CallersCounter } from '@milaboratories/ts-helpers';
7
+ import type { ClientDownload } from '../../clients/download';
6
8
  /** Downloads a blob and holds callers and watchers for the blob. */
7
9
  export declare class DownloadBlobTask {
8
10
  private readonly logger;
@@ -51,3 +53,4 @@ type DownloadState = {
51
53
  done?: boolean;
52
54
  };
53
55
  export {};
56
+ //# sourceMappingURL=download_blob_task.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"download_blob_task.d.ts","sourceRoot":"","sources":["../../../src/drivers/download_blob/download_blob_task.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAC/F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,KAAK,EACV,YAAY,EACZ,QAAQ,EACT,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAIL,cAAc,EACf,MAAM,4BAA4B,CAAC;AAKpC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAK7D,oEAAoE;AACpE,qBAAa,gBAAgB;IAUzB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,QAAQ,CAAC,KAAK,EAAE,gBAAgB;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM;IAbvB,QAAQ,CAAC,MAAM,eAAsB;IACrC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyB;IACnD,SAAgB,OAAO,iBAAwB;IAC/C,OAAO,CAAC,KAAK,CAAsB;IACnC,OAAO,CAAC,IAAI,CAAS;IACd,IAAI,SAAK;IAChB,OAAO,CAAC,KAAK,CAAqB;gBAGf,MAAM,EAAE,QAAQ,EAChB,cAAc,EAAE,cAAc,EACtC,KAAK,EAAE,gBAAgB,EACf,MAAM,EAAE,eAAe,EAC/B,IAAI,EAAE,MAAM;IAGvB,+EAA+E;IACxE,IAAI;;;;;;;IAUJ,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM;IAK7B,QAAQ;YAkBP,gBAAgB;IA2CvB,KAAK,CAAC,MAAM,EAAE,MAAM;IAIpB,OAAO,IACV;QAAE,IAAI,EAAE,KAAK,CAAA;KAAE,GACf;QACA,IAAI,EAAE,IAAI,CAAC;QACX,MAAM,EAAE,YAAY,CAAC,sBAAsB,CAAC,CAAC;KAC9C;IASH,OAAO,CAAC,OAAO;IAKf,OAAO,CAAC,QAAQ;CAIjB;AAED,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,GAAG,WAWzC;AAQD,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,eAAe,GAAG,SAAS,EACnC,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,OAAO,GACd,YAAY,CAAC,sBAAsB,CAAC,CAgBtC;AAED,KAAK,aAAa,GAAG;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,CAAA"}