@lossless.org/client 0.1.0

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 (255) hide show
  1. package/.smartconfig.json +37 -0
  2. package/dist_ts/00_commitinfo_data.d.ts +8 -0
  3. package/dist_ts/00_commitinfo_data.js +9 -0
  4. package/dist_ts/classes.losslessorgclient.d.ts +32 -0
  5. package/dist_ts/classes.losslessorgclient.js +103 -0
  6. package/dist_ts/core/classes.error.d.ts +16 -0
  7. package/dist_ts/core/classes.error.js +29 -0
  8. package/dist_ts/core/classes.operation.d.ts +17 -0
  9. package/dist_ts/core/classes.operation.js +70 -0
  10. package/dist_ts/core/interfaces.d.ts +18 -0
  11. package/dist_ts/core/interfaces.js +2 -0
  12. package/dist_ts/index.d.ts +4 -0
  13. package/dist_ts/index.js +3 -0
  14. package/dist_ts/nosqldb/classes.atomicdelete.d.ts +26 -0
  15. package/dist_ts/nosqldb/classes.atomicdelete.js +44 -0
  16. package/dist_ts/nosqldb/classes.atomicfindoneandupdate.d.ts +27 -0
  17. package/dist_ts/nosqldb/classes.atomicfindoneandupdate.js +86 -0
  18. package/dist_ts/nosqldb/classes.atomicupdate.d.ts +26 -0
  19. package/dist_ts/nosqldb/classes.atomicupdate.js +55 -0
  20. package/dist_ts/nosqldb/classes.bootstraprecord.d.ts +14 -0
  21. package/dist_ts/nosqldb/classes.bootstraprecord.js +80 -0
  22. package/dist_ts/nosqldb/classes.bsonassertion.d.ts +2 -0
  23. package/dist_ts/nosqldb/classes.bsonassertion.js +29 -0
  24. package/dist_ts/nosqldb/classes.bsonobjectid.d.ts +2 -0
  25. package/dist_ts/nosqldb/classes.bsonobjectid.js +50 -0
  26. package/dist_ts/nosqldb/classes.bsonsnapshot.d.ts +3 -0
  27. package/dist_ts/nosqldb/classes.bsonsnapshot.js +126 -0
  28. package/dist_ts/nosqldb/classes.cached-document.d.ts +27 -0
  29. package/dist_ts/nosqldb/classes.cached-document.js +112 -0
  30. package/dist_ts/nosqldb/classes.collection.d.ts +302 -0
  31. package/dist_ts/nosqldb/classes.collection.js +1568 -0
  32. package/dist_ts/nosqldb/classes.collectionfactory.d.ts +30 -0
  33. package/dist_ts/nosqldb/classes.collectionfactory.js +65 -0
  34. package/dist_ts/nosqldb/classes.collectionlifecycle.d.ts +4 -0
  35. package/dist_ts/nosqldb/classes.collectionlifecycle.js +15 -0
  36. package/dist_ts/nosqldb/classes.collectionpreparation.d.ts +34 -0
  37. package/dist_ts/nosqldb/classes.collectionpreparation.js +134 -0
  38. package/dist_ts/nosqldb/classes.collectiontopology.d.ts +47 -0
  39. package/dist_ts/nosqldb/classes.collectiontopology.js +388 -0
  40. package/dist_ts/nosqldb/classes.connection.d.ts +18 -0
  41. package/dist_ts/nosqldb/classes.connection.js +23 -0
  42. package/dist_ts/nosqldb/classes.convenience.d.ts +1 -0
  43. package/dist_ts/nosqldb/classes.convenience.js +5 -0
  44. package/dist_ts/nosqldb/classes.cursor.d.ts +15 -0
  45. package/dist_ts/nosqldb/classes.cursor.js +82 -0
  46. package/dist_ts/nosqldb/classes.cursoroperation.d.ts +7 -0
  47. package/dist_ts/nosqldb/classes.cursoroperation.js +36 -0
  48. package/dist_ts/nosqldb/classes.db.d.ts +98 -0
  49. package/dist_ts/nosqldb/classes.db.js +434 -0
  50. package/dist_ts/nosqldb/classes.distributedcoordinator.d.ts +52 -0
  51. package/dist_ts/nosqldb/classes.distributedcoordinator.js +314 -0
  52. package/dist_ts/nosqldb/classes.doc.d.ts +722 -0
  53. package/dist_ts/nosqldb/classes.doc.js +2976 -0
  54. package/dist_ts/nosqldb/classes.easystore.d.ts +42 -0
  55. package/dist_ts/nosqldb/classes.easystore.js +199 -0
  56. package/dist_ts/nosqldb/classes.exactpersistence.d.ts +141 -0
  57. package/dist_ts/nosqldb/classes.exactpersistence.js +1110 -0
  58. package/dist_ts/nosqldb/classes.lucene.adapter.d.ts +173 -0
  59. package/dist_ts/nosqldb/classes.lucene.adapter.js +623 -0
  60. package/dist_ts/nosqldb/classes.mongoadministration.d.ts +73 -0
  61. package/dist_ts/nosqldb/classes.mongoadministration.js +497 -0
  62. package/dist_ts/nosqldb/classes.namespaceinspection.d.ts +42 -0
  63. package/dist_ts/nosqldb/classes.namespaceinspection.js +138 -0
  64. package/dist_ts/nosqldb/classes.operationbudget.d.ts +22 -0
  65. package/dist_ts/nosqldb/classes.operationbudget.js +65 -0
  66. package/dist_ts/nosqldb/classes.ordinarypersistence.d.ts +18 -0
  67. package/dist_ts/nosqldb/classes.ordinarypersistence.js +71 -0
  68. package/dist_ts/nosqldb/classes.persistence.d.ts +14 -0
  69. package/dist_ts/nosqldb/classes.persistence.js +34 -0
  70. package/dist_ts/nosqldb/classes.session.d.ts +28 -0
  71. package/dist_ts/nosqldb/classes.session.js +246 -0
  72. package/dist_ts/nosqldb/classes.storedinspection.d.ts +44 -0
  73. package/dist_ts/nosqldb/classes.storedinspection.js +100 -0
  74. package/dist_ts/nosqldb/classes.testdatabase.d.ts +56 -0
  75. package/dist_ts/nosqldb/classes.testdatabase.js +250 -0
  76. package/dist_ts/nosqldb/classes.watcher.d.ts +37 -0
  77. package/dist_ts/nosqldb/classes.watcher.js +98 -0
  78. package/dist_ts/nosqldb/index.d.ts +27 -0
  79. package/dist_ts/nosqldb/index.js +18 -0
  80. package/dist_ts/nosqldb/logging.d.ts +2 -0
  81. package/dist_ts/nosqldb/logging.js +3 -0
  82. package/dist_ts/nosqldb/plugins.d.ts +17 -0
  83. package/dist_ts/nosqldb/plugins.js +20 -0
  84. package/dist_ts/nosqldb/shim.d.ts +1 -0
  85. package/dist_ts/nosqldb/shim.js +8 -0
  86. package/dist_ts/nosqldb/testsupport.d.ts +3 -0
  87. package/dist_ts/nosqldb/testsupport.js +3 -0
  88. package/dist_ts/objectstorage/classes.bucket.d.ts +227 -0
  89. package/dist_ts/objectstorage/classes.bucket.js +939 -0
  90. package/dist_ts/objectstorage/classes.connection.d.ts +21 -0
  91. package/dist_ts/objectstorage/classes.connection.js +27 -0
  92. package/dist_ts/objectstorage/classes.directory.d.ts +124 -0
  93. package/dist_ts/objectstorage/classes.directory.js +335 -0
  94. package/dist_ts/objectstorage/classes.exactpathpurgeerror.d.ts +5 -0
  95. package/dist_ts/objectstorage/classes.exactpathpurgeerror.js +18 -0
  96. package/dist_ts/objectstorage/classes.exactuploaderror.d.ts +5 -0
  97. package/dist_ts/objectstorage/classes.exactuploaderror.js +19 -0
  98. package/dist_ts/objectstorage/classes.file.d.ts +91 -0
  99. package/dist_ts/objectstorage/classes.file.js +255 -0
  100. package/dist_ts/objectstorage/classes.listcursor.d.ts +41 -0
  101. package/dist_ts/objectstorage/classes.listcursor.js +67 -0
  102. package/dist_ts/objectstorage/classes.metadata.d.ts +57 -0
  103. package/dist_ts/objectstorage/classes.metadata.js +113 -0
  104. package/dist_ts/objectstorage/classes.smartbucket.d.ts +57 -0
  105. package/dist_ts/objectstorage/classes.smartbucket.js +357 -0
  106. package/dist_ts/objectstorage/classes.trash.d.ts +11 -0
  107. package/dist_ts/objectstorage/classes.trash.js +22 -0
  108. package/dist_ts/objectstorage/classes.watcher.d.ts +79 -0
  109. package/dist_ts/objectstorage/classes.watcher.js +249 -0
  110. package/dist_ts/objectstorage/helpers.d.ts +25 -0
  111. package/dist_ts/objectstorage/helpers.js +215 -0
  112. package/dist_ts/objectstorage/index.d.ts +13 -0
  113. package/dist_ts/objectstorage/index.js +13 -0
  114. package/dist_ts/objectstorage/interfaces.d.ts +276 -0
  115. package/dist_ts/objectstorage/interfaces.js +2 -0
  116. package/dist_ts/objectstorage/internal.exactpathpurge.operations.d.ts +11 -0
  117. package/dist_ts/objectstorage/internal.exactpathpurge.operations.js +1069 -0
  118. package/dist_ts/objectstorage/internal.exactupload.capability.d.ts +40 -0
  119. package/dist_ts/objectstorage/internal.exactupload.capability.js +382 -0
  120. package/dist_ts/objectstorage/internal.exactupload.operations.d.ts +11 -0
  121. package/dist_ts/objectstorage/internal.exactupload.operations.js +1104 -0
  122. package/dist_ts/objectstorage/internal.multipart.planner.d.ts +8 -0
  123. package/dist_ts/objectstorage/internal.multipart.planner.js +63 -0
  124. package/dist_ts/objectstorage/internal.multipart.stream.d.ts +17 -0
  125. package/dist_ts/objectstorage/internal.multipart.stream.js +440 -0
  126. package/dist_ts/objectstorage/internal.multipart.types.d.ts +82 -0
  127. package/dist_ts/objectstorage/internal.multipart.types.js +2 -0
  128. package/dist_ts/objectstorage/plugins.d.ts +17 -0
  129. package/dist_ts/objectstorage/plugins.js +23 -0
  130. package/dist_ts/plugins.d.ts +4 -0
  131. package/dist_ts/plugins.js +5 -0
  132. package/dist_ts/sqldb/classes.clickhouseconnection.d.ts +39 -0
  133. package/dist_ts/sqldb/classes.clickhouseconnection.js +225 -0
  134. package/dist_ts/sqldb/classes.sqlconnection.d.ts +50 -0
  135. package/dist_ts/sqldb/classes.sqlconnection.js +376 -0
  136. package/dist_ts/sqldb/classes.sqltable.d.ts +29 -0
  137. package/dist_ts/sqldb/classes.sqltable.js +70 -0
  138. package/dist_ts/sqldb/clickhouse/classes.metricwriter.d.ts +27 -0
  139. package/dist_ts/sqldb/clickhouse/classes.metricwriter.js +89 -0
  140. package/dist_ts/sqldb/clickhouse/index.d.ts +9 -0
  141. package/dist_ts/sqldb/clickhouse/index.js +13 -0
  142. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.clickhousetable.d.ts +88 -0
  143. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.clickhousetable.js +304 -0
  144. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.httpclient.d.ts +28 -0
  145. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.httpclient.js +46 -0
  146. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.querybuilder.d.ts +43 -0
  147. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.querybuilder.js +155 -0
  148. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.resultset.d.ts +13 -0
  149. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.resultset.js +36 -0
  150. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.smartclickhouse.d.ts +49 -0
  151. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.smartclickhouse.js +106 -0
  152. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.timedatatable.d.ts +51 -0
  153. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.timedatatable.js +96 -0
  154. package/dist_ts/sqldb/clickhouse/smartclickhouse.plugins.d.ts +5 -0
  155. package/dist_ts/sqldb/clickhouse/smartclickhouse.plugins.js +6 -0
  156. package/dist_ts/sqldb/clickhouse/smartclickhouse.types.d.ts +53 -0
  157. package/dist_ts/sqldb/clickhouse/smartclickhouse.types.js +41 -0
  158. package/dist_ts/sqldb/index.d.ts +6 -0
  159. package/dist_ts/sqldb/index.js +6 -0
  160. package/dist_ts/sqldb/interfaces.d.ts +53 -0
  161. package/dist_ts/sqldb/interfaces.js +19 -0
  162. package/dist_ts/sqldb/internal.sqlpool.d.ts +51 -0
  163. package/dist_ts/sqldb/internal.sqlpool.js +214 -0
  164. package/dist_ts/sqldb/plugins.clickhouse.d.ts +4 -0
  165. package/dist_ts/sqldb/plugins.clickhouse.js +5 -0
  166. package/dist_ts/sqldb/plugins.mariadb.d.ts +4 -0
  167. package/dist_ts/sqldb/plugins.mariadb.js +5 -0
  168. package/docs/source/smartbucket/license.md +19 -0
  169. package/docs/source/smartclickhouse/license.md +19 -0
  170. package/license.md +21 -0
  171. package/package.json +101 -0
  172. package/readme.md +157 -0
  173. package/ts/00_commitinfo_data.ts +8 -0
  174. package/ts/classes.losslessorgclient.ts +104 -0
  175. package/ts/core/classes.error.ts +31 -0
  176. package/ts/core/classes.operation.ts +60 -0
  177. package/ts/core/interfaces.ts +24 -0
  178. package/ts/index.ts +4 -0
  179. package/ts/nosqldb/classes.atomicdelete.ts +81 -0
  180. package/ts/nosqldb/classes.atomicfindoneandupdate.ts +152 -0
  181. package/ts/nosqldb/classes.atomicupdate.ts +99 -0
  182. package/ts/nosqldb/classes.bootstraprecord.ts +107 -0
  183. package/ts/nosqldb/classes.bsonassertion.ts +25 -0
  184. package/ts/nosqldb/classes.bsonobjectid.ts +45 -0
  185. package/ts/nosqldb/classes.bsonsnapshot.ts +105 -0
  186. package/ts/nosqldb/classes.cached-document.ts +67 -0
  187. package/ts/nosqldb/classes.collection.ts +2399 -0
  188. package/ts/nosqldb/classes.collectionfactory.ts +87 -0
  189. package/ts/nosqldb/classes.collectionlifecycle.ts +24 -0
  190. package/ts/nosqldb/classes.collectionpreparation.ts +164 -0
  191. package/ts/nosqldb/classes.collectiontopology.ts +645 -0
  192. package/ts/nosqldb/classes.connection.ts +31 -0
  193. package/ts/nosqldb/classes.convenience.ts +5 -0
  194. package/ts/nosqldb/classes.cursor.ts +88 -0
  195. package/ts/nosqldb/classes.cursoroperation.ts +38 -0
  196. package/ts/nosqldb/classes.db.ts +637 -0
  197. package/ts/nosqldb/classes.distributedcoordinator.ts +305 -0
  198. package/ts/nosqldb/classes.doc.ts +4928 -0
  199. package/ts/nosqldb/classes.easystore.ts +154 -0
  200. package/ts/nosqldb/classes.exactpersistence.ts +1974 -0
  201. package/ts/nosqldb/classes.lucene.adapter.ts +780 -0
  202. package/ts/nosqldb/classes.mongoadministration.ts +867 -0
  203. package/ts/nosqldb/classes.namespaceinspection.ts +199 -0
  204. package/ts/nosqldb/classes.operationbudget.ts +75 -0
  205. package/ts/nosqldb/classes.ordinarypersistence.ts +84 -0
  206. package/ts/nosqldb/classes.persistence.ts +62 -0
  207. package/ts/nosqldb/classes.session.ts +389 -0
  208. package/ts/nosqldb/classes.storedinspection.ts +151 -0
  209. package/ts/nosqldb/classes.testdatabase.ts +272 -0
  210. package/ts/nosqldb/classes.watcher.ts +96 -0
  211. package/ts/nosqldb/index.ts +51 -0
  212. package/ts/nosqldb/logging.ts +3 -0
  213. package/ts/nosqldb/plugins.ts +37 -0
  214. package/ts/nosqldb/shim.ts +6 -0
  215. package/ts/nosqldb/testsupport.ts +13 -0
  216. package/ts/objectstorage/classes.bucket.ts +1114 -0
  217. package/ts/objectstorage/classes.connection.ts +36 -0
  218. package/ts/objectstorage/classes.directory.ts +425 -0
  219. package/ts/objectstorage/classes.exactpathpurgeerror.ts +24 -0
  220. package/ts/objectstorage/classes.exactuploaderror.ts +25 -0
  221. package/ts/objectstorage/classes.file.ts +303 -0
  222. package/ts/objectstorage/classes.listcursor.ts +89 -0
  223. package/ts/objectstorage/classes.metadata.ts +134 -0
  224. package/ts/objectstorage/classes.smartbucket.ts +445 -0
  225. package/ts/objectstorage/classes.trash.ts +30 -0
  226. package/ts/objectstorage/classes.watcher.ts +289 -0
  227. package/ts/objectstorage/helpers.ts +254 -0
  228. package/ts/objectstorage/index.ts +13 -0
  229. package/ts/objectstorage/interfaces.ts +389 -0
  230. package/ts/objectstorage/internal.exactpathpurge.operations.ts +1936 -0
  231. package/ts/objectstorage/internal.exactupload.capability.ts +580 -0
  232. package/ts/objectstorage/internal.exactupload.operations.ts +1715 -0
  233. package/ts/objectstorage/internal.multipart.planner.ts +90 -0
  234. package/ts/objectstorage/internal.multipart.stream.ts +606 -0
  235. package/ts/objectstorage/internal.multipart.types.ts +106 -0
  236. package/ts/objectstorage/plugins.ts +35 -0
  237. package/ts/plugins.ts +4 -0
  238. package/ts/sqldb/classes.clickhouseconnection.ts +189 -0
  239. package/ts/sqldb/classes.sqlconnection.ts +350 -0
  240. package/ts/sqldb/classes.sqltable.ts +70 -0
  241. package/ts/sqldb/clickhouse/classes.metricwriter.ts +72 -0
  242. package/ts/sqldb/clickhouse/index.ts +16 -0
  243. package/ts/sqldb/clickhouse/smartclickhouse.classes.clickhousetable.ts +372 -0
  244. package/ts/sqldb/clickhouse/smartclickhouse.classes.httpclient.ts +52 -0
  245. package/ts/sqldb/clickhouse/smartclickhouse.classes.querybuilder.ts +120 -0
  246. package/ts/sqldb/clickhouse/smartclickhouse.classes.resultset.ts +44 -0
  247. package/ts/sqldb/clickhouse/smartclickhouse.classes.smartclickhouse.ts +123 -0
  248. package/ts/sqldb/clickhouse/smartclickhouse.classes.timedatatable.ts +114 -0
  249. package/ts/sqldb/clickhouse/smartclickhouse.plugins.ts +5 -0
  250. package/ts/sqldb/clickhouse/smartclickhouse.types.ts +134 -0
  251. package/ts/sqldb/index.ts +6 -0
  252. package/ts/sqldb/interfaces.ts +61 -0
  253. package/ts/sqldb/internal.sqlpool.ts +179 -0
  254. package/ts/sqldb/plugins.clickhouse.ts +4 -0
  255. package/ts/sqldb/plugins.mariadb.ts +4 -0
@@ -0,0 +1,1104 @@
1
+ import * as plugins from './plugins.js';
2
+ import { ExactUploadError } from './classes.exactuploaderror.js';
3
+ import { beginExactUploadCapabilityOperation, beginExactUploadProbeOperation, mintExactUploadCapability, } from './internal.exactupload.capability.js';
4
+ import { planMultipartUpload } from './internal.multipart.planner.js';
5
+ import { consumeExactMultipartStream, MultipartStreamConsumptionError, } from './internal.multipart.stream.js';
6
+ class ExactUploadProbeSemanticError extends Error {
7
+ reason;
8
+ constructor(reason) {
9
+ super(reason);
10
+ this.reason = reason;
11
+ this.name = 'ExactUploadProbeSemanticError';
12
+ }
13
+ }
14
+ const cleanupTimeoutMs = 30_000;
15
+ const cleanupVerificationMaximumPages = 100;
16
+ const multipartAbortMaximumAttempts = 64;
17
+ const multipartAbortRetryDelayMs = 100;
18
+ const probeMetadata = {
19
+ 'smartbucket-probe': 'exact-upload-v1',
20
+ };
21
+ const snapshotNativeObjectProperties = (valueArg) => {
22
+ if (valueArg === undefined) {
23
+ return undefined;
24
+ }
25
+ if (valueArg === null
26
+ || typeof valueArg !== 'object'
27
+ || Array.isArray(valueArg)) {
28
+ throw new TypeError('nativeObjectProperties must be an object.');
29
+ }
30
+ const keys = Object.keys(valueArg);
31
+ if (keys.some((keyArg) => keyArg !== 'contentType')) {
32
+ throw new TypeError('nativeObjectProperties contains an unsupported property.');
33
+ }
34
+ if (valueArg.contentType !== undefined
35
+ && (typeof valueArg.contentType !== 'string'
36
+ || valueArg.contentType.length === 0
37
+ || /[\0\r\n]/.test(valueArg.contentType))) {
38
+ throw new TypeError('nativeObjectProperties.contentType must be a non-empty HTTP header value.');
39
+ }
40
+ return Object.freeze({
41
+ ...(valueArg.contentType === undefined
42
+ ? {}
43
+ : { contentType: valueArg.contentType }),
44
+ });
45
+ };
46
+ const detachedOperationSendSettlements = new WeakMap();
47
+ const trackDetachedOperationSend = (signalArg, settlementArg) => {
48
+ let settlements = detachedOperationSendSettlements.get(signalArg);
49
+ if (!settlements) {
50
+ settlements = new Set();
51
+ detachedOperationSendSettlements.set(signalArg, settlements);
52
+ }
53
+ settlements.add(settlementArg);
54
+ void settlementArg.then(() => {
55
+ settlements?.delete(settlementArg);
56
+ if (settlements?.size === 0) {
57
+ detachedOperationSendSettlements.delete(signalArg);
58
+ }
59
+ });
60
+ };
61
+ const getDetachedOperationSendSettlement = (signalArg) => {
62
+ const settlements = detachedOperationSendSettlements.get(signalArg);
63
+ if (!settlements || settlements.size === 0) {
64
+ return undefined;
65
+ }
66
+ return Promise.allSettled([...settlements]).then(() => undefined);
67
+ };
68
+ const finishOperationAfterOwnedSettlements = (operationArg, additionalSettlementsArg = []) => {
69
+ const detachedSendSettlement = getDetachedOperationSendSettlement(operationArg.signal);
70
+ const ownedSettlements = detachedSendSettlement
71
+ ? [detachedSendSettlement, ...additionalSettlementsArg]
72
+ : additionalSettlementsArg;
73
+ if (ownedSettlements.length === 0) {
74
+ operationArg.finish();
75
+ return;
76
+ }
77
+ void Promise.allSettled(ownedSettlements).then(() => {
78
+ operationArg.finish();
79
+ });
80
+ };
81
+ const sendOperationCommand = async (operationArg, sendArg) => {
82
+ operationArg.assertCurrent();
83
+ const sendOutcome = Promise.resolve()
84
+ .then(() => {
85
+ operationArg.assertCurrent();
86
+ return sendArg(operationArg.signal);
87
+ })
88
+ .then((valueArg) => ({
89
+ status: 'fulfilled',
90
+ value: valueArg,
91
+ }), (causeArg) => ({
92
+ status: 'rejected',
93
+ cause: causeArg,
94
+ }));
95
+ let abortListener;
96
+ const abortOutcome = new Promise((resolveArg) => {
97
+ abortListener = () => {
98
+ resolveArg({
99
+ status: 'aborted',
100
+ });
101
+ };
102
+ operationArg.signal.addEventListener('abort', abortListener, {
103
+ once: true,
104
+ });
105
+ if (operationArg.signal.aborted) {
106
+ abortListener();
107
+ }
108
+ });
109
+ const outcome = await Promise.race([sendOutcome, abortOutcome]);
110
+ if (abortListener) {
111
+ operationArg.signal.removeEventListener('abort', abortListener);
112
+ }
113
+ if (outcome.status === 'aborted') {
114
+ trackDetachedOperationSend(operationArg.signal, sendOutcome.then(() => undefined));
115
+ operationArg.assertCurrent();
116
+ throw new Error('Unreachable exact-upload abort state.');
117
+ }
118
+ if (outcome.status === 'rejected') {
119
+ throw outcome.cause;
120
+ }
121
+ operationArg.assertCurrent();
122
+ return outcome.value;
123
+ };
124
+ const isHttpStatus = (errorArg, statusCodeArg) => {
125
+ if (typeof errorArg !== 'object' || errorArg === null) {
126
+ return false;
127
+ }
128
+ const metadata = errorArg.$metadata;
129
+ return metadata?.httpStatusCode === statusCodeArg;
130
+ };
131
+ const isDefinitiveConditionalWriteRejection = (errorArg) => {
132
+ return isHttpStatus(errorArg, 409) || isHttpStatus(errorArg, 412);
133
+ };
134
+ const requireNonEmptyString = (valueArg, fieldNameArg) => {
135
+ if (typeof valueArg !== 'string' || valueArg.length === 0) {
136
+ throw new Error(`${fieldNameArg} was not returned by the object provider.`);
137
+ }
138
+ return valueArg;
139
+ };
140
+ const getOptionalNonEmptyString = (valueArg) => {
141
+ return typeof valueArg === 'string' && valueArg.length > 0
142
+ ? valueArg
143
+ : undefined;
144
+ };
145
+ const toWebReadableStream = (readableStreamArg) => {
146
+ if (typeof readableStreamArg === 'object' &&
147
+ readableStreamArg !== null &&
148
+ typeof readableStreamArg.getReader ===
149
+ 'function') {
150
+ return readableStreamArg;
151
+ }
152
+ if (readableStreamArg instanceof plugins.stream.Readable) {
153
+ return plugins.stream.Readable.toWeb(readableStreamArg);
154
+ }
155
+ throw new TypeError('readableStream must be a Node.js Readable or a web ReadableStream.');
156
+ };
157
+ const runIndependentCleanup = async (cleanupTasksArg, operationArg) => {
158
+ const cleanupErrors = [];
159
+ if (cleanupTasksArg.length === 0) {
160
+ return {
161
+ errors: cleanupErrors,
162
+ timedOut: false,
163
+ settlement: Promise.resolve(),
164
+ };
165
+ }
166
+ const cleanupAbortController = new AbortController();
167
+ const cleanupDeadlineToken = Symbol('exact-upload-cleanup-deadline');
168
+ let resolveCleanupDeadline;
169
+ const cleanupDeadlineOutcome = new Promise((resolveArg) => {
170
+ resolveCleanupDeadline = resolveArg;
171
+ });
172
+ const cleanupDeadline = setTimeout(() => {
173
+ const deadlineError = new Error(`Exact-upload cleanup exceeded its ${cleanupTimeoutMs}ms deadline.`);
174
+ cleanupAbortController.abort(deadlineError);
175
+ resolveCleanupDeadline(cleanupDeadlineToken);
176
+ }, cleanupTimeoutMs);
177
+ let cleanupDeadlineDisposed = false;
178
+ const disposeCleanupDeadline = () => {
179
+ if (cleanupDeadlineDisposed) {
180
+ return;
181
+ }
182
+ cleanupDeadlineDisposed = true;
183
+ clearTimeout(cleanupDeadline);
184
+ };
185
+ let releaseOwnedAbort;
186
+ try {
187
+ releaseOwnedAbort = operationArg.registerOwnedIndependentAbort(cleanupAbortController, disposeCleanupDeadline);
188
+ }
189
+ catch (error) {
190
+ cleanupAbortController.abort(error);
191
+ disposeCleanupDeadline();
192
+ throw error;
193
+ }
194
+ const cleanupTaskSequence = Promise.resolve().then(async () => {
195
+ for (const cleanupTask of cleanupTasksArg) {
196
+ if (cleanupAbortController.signal.aborted) {
197
+ break;
198
+ }
199
+ try {
200
+ await cleanupTask(cleanupAbortController.signal);
201
+ }
202
+ catch (error) {
203
+ cleanupErrors.push(error);
204
+ }
205
+ }
206
+ });
207
+ const normalizedTaskSequence = cleanupTaskSequence.then(() => ({
208
+ status: 'settled',
209
+ }), (causeArg) => {
210
+ cleanupErrors.push(causeArg);
211
+ return {
212
+ status: 'settled',
213
+ };
214
+ });
215
+ const settlement = normalizedTaskSequence.then(() => undefined);
216
+ void settlement.then(() => {
217
+ releaseOwnedAbort();
218
+ });
219
+ try {
220
+ const outcome = await Promise.race([
221
+ normalizedTaskSequence,
222
+ cleanupDeadlineOutcome,
223
+ ]);
224
+ if (outcome === cleanupDeadlineToken) {
225
+ cleanupErrors.push(cleanupAbortController.signal.reason ??
226
+ new Error('Exact-upload cleanup exceeded its deadline.'));
227
+ return {
228
+ errors: cleanupErrors,
229
+ timedOut: true,
230
+ settlement,
231
+ };
232
+ }
233
+ return {
234
+ errors: cleanupErrors,
235
+ timedOut: false,
236
+ settlement,
237
+ };
238
+ }
239
+ finally {
240
+ disposeCleanupDeadline();
241
+ }
242
+ };
243
+ const assertCleanupActive = (signalArg, assertCurrentArg) => {
244
+ if (signalArg.aborted) {
245
+ throw (signalArg.reason ??
246
+ new Error('Exact-upload cleanup was aborted.'));
247
+ }
248
+ assertCurrentArg();
249
+ };
250
+ const sendCleanupRequest = async (signalArg, assertCurrentArg, sendArg) => {
251
+ assertCleanupActive(signalArg, assertCurrentArg);
252
+ const output = await sendArg();
253
+ assertCleanupActive(signalArg, assertCurrentArg);
254
+ return output;
255
+ };
256
+ const listProbeMultipartUploads = async (clientArg, bucketNameArg, probeRootArg, signalArg, assertCurrentArg) => {
257
+ const uploads = [];
258
+ let keyMarker;
259
+ let uploadIdMarker;
260
+ for (let pageNumber = 1; pageNumber <= cleanupVerificationMaximumPages; pageNumber++) {
261
+ const output = await sendCleanupRequest(signalArg, assertCurrentArg, () => clientArg.send(new plugins.s3.ListMultipartUploadsCommand({
262
+ Bucket: bucketNameArg,
263
+ Prefix: probeRootArg,
264
+ KeyMarker: keyMarker,
265
+ UploadIdMarker: uploadIdMarker,
266
+ }), {
267
+ abortSignal: signalArg,
268
+ }));
269
+ for (const upload of output.Uploads ?? []) {
270
+ if (typeof upload.Key !== 'string' ||
271
+ !upload.Key.startsWith(probeRootArg)) {
272
+ throw new Error('Multipart cleanup reconciliation returned an invalid prefixed entry.');
273
+ }
274
+ if (typeof upload.UploadId !== 'string' ||
275
+ upload.UploadId.length === 0) {
276
+ throw new Error(`Probe multipart upload '${upload.Key}' has no UploadId.`);
277
+ }
278
+ uploads.push({
279
+ key: upload.Key,
280
+ uploadId: upload.UploadId,
281
+ });
282
+ }
283
+ if (!output.IsTruncated) {
284
+ return uploads;
285
+ }
286
+ if (!output.NextKeyMarker ||
287
+ (output.NextKeyMarker === keyMarker &&
288
+ output.NextUploadIdMarker === uploadIdMarker)) {
289
+ throw new Error('Multipart cleanup reconciliation returned a non-advancing page.');
290
+ }
291
+ keyMarker = output.NextKeyMarker;
292
+ uploadIdMarker = output.NextUploadIdMarker;
293
+ }
294
+ throw new Error('Multipart cleanup reconciliation exceeded its page bound.');
295
+ };
296
+ const listProbeObjectVersions = async (clientArg, bucketNameArg, probeRootArg, signalArg, assertCurrentArg) => {
297
+ const versions = [];
298
+ let keyMarker;
299
+ let versionIdMarker;
300
+ for (let pageNumber = 1; pageNumber <= cleanupVerificationMaximumPages; pageNumber++) {
301
+ const output = await sendCleanupRequest(signalArg, assertCurrentArg, () => clientArg.send(new plugins.s3.ListObjectVersionsCommand({
302
+ Bucket: bucketNameArg,
303
+ Prefix: probeRootArg,
304
+ KeyMarker: keyMarker,
305
+ VersionIdMarker: versionIdMarker,
306
+ }), {
307
+ abortSignal: signalArg,
308
+ }));
309
+ for (const version of [
310
+ ...(output.Versions ?? []),
311
+ ...(output.DeleteMarkers ?? []),
312
+ ]) {
313
+ if (typeof version.Key !== 'string' ||
314
+ !version.Key.startsWith(probeRootArg)) {
315
+ throw new Error('Version cleanup reconciliation returned an invalid prefixed entry.');
316
+ }
317
+ if (typeof version.VersionId !== 'string' ||
318
+ version.VersionId.length === 0) {
319
+ throw new Error(`Probe object version '${version.Key}' has no VersionId.`);
320
+ }
321
+ versions.push({
322
+ key: version.Key,
323
+ versionId: version.VersionId,
324
+ });
325
+ }
326
+ if (!output.IsTruncated) {
327
+ return versions;
328
+ }
329
+ if (!output.NextKeyMarker ||
330
+ (output.NextKeyMarker === keyMarker &&
331
+ output.NextVersionIdMarker === versionIdMarker)) {
332
+ throw new Error('Version cleanup reconciliation returned a non-advancing page.');
333
+ }
334
+ keyMarker = output.NextKeyMarker;
335
+ versionIdMarker = output.NextVersionIdMarker;
336
+ }
337
+ throw new Error('Version cleanup reconciliation exceeded its page bound.');
338
+ };
339
+ const listProbeObjectKeys = async (clientArg, bucketNameArg, probeRootArg, signalArg, assertCurrentArg) => {
340
+ const keys = [];
341
+ let continuationToken;
342
+ for (let pageNumber = 1; pageNumber <= cleanupVerificationMaximumPages; pageNumber++) {
343
+ const output = await sendCleanupRequest(signalArg, assertCurrentArg, () => clientArg.send(new plugins.s3.ListObjectsV2Command({
344
+ Bucket: bucketNameArg,
345
+ Prefix: probeRootArg,
346
+ ContinuationToken: continuationToken,
347
+ }), {
348
+ abortSignal: signalArg,
349
+ }));
350
+ for (const object of output.Contents ?? []) {
351
+ if (typeof object.Key !== 'string' ||
352
+ !object.Key.startsWith(probeRootArg)) {
353
+ throw new Error('Object cleanup reconciliation returned an invalid prefixed entry.');
354
+ }
355
+ keys.push(object.Key);
356
+ }
357
+ if (!output.IsTruncated) {
358
+ return keys;
359
+ }
360
+ if (!output.NextContinuationToken ||
361
+ output.NextContinuationToken === continuationToken) {
362
+ throw new Error('Object cleanup reconciliation returned a non-advancing page.');
363
+ }
364
+ continuationToken = output.NextContinuationToken;
365
+ }
366
+ throw new Error('Object cleanup reconciliation exceeded its page bound.');
367
+ };
368
+ const getHttpStatus = (errorArg) => {
369
+ if (typeof errorArg !== 'object' || errorArg === null) {
370
+ return undefined;
371
+ }
372
+ const statusCode = errorArg.$metadata?.httpStatusCode;
373
+ return typeof statusCode === 'number' ? statusCode : undefined;
374
+ };
375
+ const isRetryableCleanupError = (errorArg) => {
376
+ const statusCode = getHttpStatus(errorArg);
377
+ return (statusCode === undefined ||
378
+ statusCode === 409 ||
379
+ statusCode === 429 ||
380
+ statusCode >= 500);
381
+ };
382
+ const waitForMultipartAbortRetry = (signalArg) => {
383
+ return new Promise((resolveArg, rejectArg) => {
384
+ const retryTimer = setTimeout(() => {
385
+ signalArg.removeEventListener('abort', abortRetryWait);
386
+ resolveArg();
387
+ }, multipartAbortRetryDelayMs);
388
+ const abortRetryWait = () => {
389
+ clearTimeout(retryTimer);
390
+ rejectArg(signalArg.reason ??
391
+ new Error('Multipart abort reconciliation was aborted.'));
392
+ };
393
+ signalArg.addEventListener('abort', abortRetryWait, { once: true });
394
+ if (signalArg.aborted) {
395
+ abortRetryWait();
396
+ }
397
+ });
398
+ };
399
+ const reconcileMultipartUploadAbort = async (clientArg, bucketNameArg, keyArg, uploadIdArg, signalArg, assertCurrentArg) => {
400
+ const reconciliationErrors = [];
401
+ for (let attempt = 1; attempt <= multipartAbortMaximumAttempts; attempt++) {
402
+ let abortError;
403
+ let abortRequestSucceeded = false;
404
+ try {
405
+ await sendCleanupRequest(signalArg, assertCurrentArg, () => clientArg.send(new plugins.s3.AbortMultipartUploadCommand({
406
+ Bucket: bucketNameArg,
407
+ Key: keyArg,
408
+ UploadId: uploadIdArg,
409
+ }), {
410
+ abortSignal: signalArg,
411
+ }));
412
+ abortRequestSucceeded = true;
413
+ }
414
+ catch (error) {
415
+ if (isHttpStatus(error, 404)) {
416
+ return 'absent';
417
+ }
418
+ abortError = error;
419
+ reconciliationErrors.push(error);
420
+ }
421
+ try {
422
+ await sendCleanupRequest(signalArg, assertCurrentArg, () => clientArg.send(new plugins.s3.ListPartsCommand({
423
+ Bucket: bucketNameArg,
424
+ Key: keyArg,
425
+ UploadId: uploadIdArg,
426
+ MaxParts: 1,
427
+ }), {
428
+ abortSignal: signalArg,
429
+ }));
430
+ }
431
+ catch (error) {
432
+ if (isHttpStatus(error, 404)) {
433
+ return abortRequestSucceeded ? 'aborted' : 'absent';
434
+ }
435
+ reconciliationErrors.push(error);
436
+ if (!isRetryableCleanupError(error)) {
437
+ throw new AggregateError(reconciliationErrors, `Multipart upload '${uploadIdArg}' could not be verified as aborted.`);
438
+ }
439
+ }
440
+ if (abortError && !isRetryableCleanupError(abortError)) {
441
+ throw new AggregateError(reconciliationErrors, `Multipart upload '${uploadIdArg}' could not be aborted.`);
442
+ }
443
+ if (attempt === multipartAbortMaximumAttempts) {
444
+ break;
445
+ }
446
+ if (attempt > 3) {
447
+ await waitForMultipartAbortRetry(signalArg);
448
+ }
449
+ }
450
+ throw new AggregateError(reconciliationErrors, `Multipart upload '${uploadIdArg}' still exists after repeated aborts.`);
451
+ };
452
+ const createProbeCleanupTasks = (clientArg, bucketNameArg, probeRootArg, providerUsesVersionsArg, multipartUploadsArg, objectsArg, assertCurrentArg) => {
453
+ const cleanupTasks = [];
454
+ for (const multipartUpload of multipartUploadsArg) {
455
+ cleanupTasks.push((signalArg) => reconcileMultipartUploadAbort(clientArg, bucketNameArg, multipartUpload.key, multipartUpload.uploadId, signalArg, assertCurrentArg));
456
+ }
457
+ for (const object of objectsArg) {
458
+ cleanupTasks.push((signalArg) => sendCleanupRequest(signalArg, assertCurrentArg, () => clientArg.send(new plugins.s3.DeleteObjectCommand({
459
+ Bucket: bucketNameArg,
460
+ Key: object.key,
461
+ VersionId: object.versionId,
462
+ }), {
463
+ abortSignal: signalArg,
464
+ })));
465
+ }
466
+ cleanupTasks.push(async (signalArg) => {
467
+ const discoveredUploads = await listProbeMultipartUploads(clientArg, bucketNameArg, probeRootArg, signalArg, assertCurrentArg);
468
+ for (const upload of discoveredUploads) {
469
+ await reconcileMultipartUploadAbort(clientArg, bucketNameArg, upload.key, upload.uploadId, signalArg, assertCurrentArg);
470
+ }
471
+ const remainingUploads = await listProbeMultipartUploads(clientArg, bucketNameArg, probeRootArg, signalArg, assertCurrentArg);
472
+ if (remainingUploads.length > 0) {
473
+ throw new Error(`Probe multipart upload '${remainingUploads[0].uploadId}' remains after cleanup.`);
474
+ }
475
+ });
476
+ if (providerUsesVersionsArg) {
477
+ cleanupTasks.push(async (signalArg) => {
478
+ const discoveredVersions = await listProbeObjectVersions(clientArg, bucketNameArg, probeRootArg, signalArg, assertCurrentArg);
479
+ for (const version of discoveredVersions) {
480
+ await sendCleanupRequest(signalArg, assertCurrentArg, () => clientArg.send(new plugins.s3.DeleteObjectCommand({
481
+ Bucket: bucketNameArg,
482
+ Key: version.key,
483
+ VersionId: version.versionId,
484
+ }), {
485
+ abortSignal: signalArg,
486
+ }));
487
+ }
488
+ const remainingVersions = await listProbeObjectVersions(clientArg, bucketNameArg, probeRootArg, signalArg, assertCurrentArg);
489
+ if (remainingVersions.length > 0) {
490
+ throw new Error(`Probe object version '${remainingVersions[0].versionId}' remains after cleanup.`);
491
+ }
492
+ });
493
+ }
494
+ else {
495
+ cleanupTasks.push(async (signalArg) => {
496
+ const discoveredKeys = await listProbeObjectKeys(clientArg, bucketNameArg, probeRootArg, signalArg, assertCurrentArg);
497
+ for (const key of discoveredKeys) {
498
+ await sendCleanupRequest(signalArg, assertCurrentArg, () => clientArg.send(new plugins.s3.DeleteObjectCommand({
499
+ Bucket: bucketNameArg,
500
+ Key: key,
501
+ }), {
502
+ abortSignal: signalArg,
503
+ }));
504
+ }
505
+ const remainingKeys = await listProbeObjectKeys(clientArg, bucketNameArg, probeRootArg, signalArg, assertCurrentArg);
506
+ if (remainingKeys.length > 0) {
507
+ throw new Error(`Probe object '${remainingKeys[0]}' remains after cleanup.`);
508
+ }
509
+ });
510
+ }
511
+ return cleanupTasks;
512
+ };
513
+ export const probeExactUploadCapability = async (bucketRefArg, optionsArg) => {
514
+ let operation;
515
+ try {
516
+ operation = beginExactUploadProbeOperation(bucketRefArg, optionsArg.signal);
517
+ }
518
+ catch (error) {
519
+ return {
520
+ supported: false,
521
+ reason: 'unavailable',
522
+ cause: error,
523
+ };
524
+ }
525
+ const probeRoot = `.smartbucket-probes/exact-upload-v1/${plugins.smartunique.uuid4()}`;
526
+ const conditionalPutKey = `${probeRoot}/conditional-put`;
527
+ const conditionalCompleteKey = `${probeRoot}/conditional-complete`;
528
+ const unfinishedMultipartUploads = [];
529
+ const probeObjects = [];
530
+ let providerUsesVersions = false;
531
+ let failureReason;
532
+ let failureCause;
533
+ const recordProbeObject = (keyArg, outputArg) => {
534
+ const versionId = getOptionalNonEmptyString(outputArg.VersionId);
535
+ if (versionId) {
536
+ providerUsesVersions = true;
537
+ }
538
+ probeObjects.push({
539
+ key: keyArg,
540
+ versionId,
541
+ });
542
+ };
543
+ try {
544
+ const versioningOutput = await sendOperationCommand(operation, (signalArg) => operation.client.send(new plugins.s3.GetBucketVersioningCommand({
545
+ Bucket: operation.bucketName,
546
+ }), {
547
+ abortSignal: signalArg,
548
+ }));
549
+ providerUsesVersions =
550
+ versioningOutput.Status === 'Enabled' ||
551
+ versioningOutput.Status === 'Suspended';
552
+ const firstPutOutput = await sendOperationCommand(operation, (signalArg) => operation.client.send(new plugins.s3.PutObjectCommand({
553
+ Bucket: operation.bucketName,
554
+ Key: conditionalPutKey,
555
+ Body: new Uint8Array(0),
556
+ ContentLength: 0,
557
+ Metadata: probeMetadata,
558
+ IfNoneMatch: '*',
559
+ }), {
560
+ abortSignal: signalArg,
561
+ }));
562
+ recordProbeObject(conditionalPutKey, firstPutOutput);
563
+ requireNonEmptyString(firstPutOutput.ETag, 'PutObject ETag');
564
+ try {
565
+ const duplicatePutOutput = await sendOperationCommand(operation, (signalArg) => operation.client.send(new plugins.s3.PutObjectCommand({
566
+ Bucket: operation.bucketName,
567
+ Key: conditionalPutKey,
568
+ Body: new Uint8Array(0),
569
+ ContentLength: 0,
570
+ Metadata: probeMetadata,
571
+ IfNoneMatch: '*',
572
+ }), {
573
+ abortSignal: signalArg,
574
+ }));
575
+ recordProbeObject(conditionalPutKey, duplicatePutOutput);
576
+ throw new ExactUploadProbeSemanticError('conditional-put-not-enforced');
577
+ }
578
+ catch (error) {
579
+ if (error instanceof ExactUploadProbeSemanticError) {
580
+ throw error;
581
+ }
582
+ operation.assertCurrent();
583
+ if (!isHttpStatus(error, 412)) {
584
+ throw error;
585
+ }
586
+ }
587
+ const createFirstOutput = await sendOperationCommand(operation, (signalArg) => operation.client.send(new plugins.s3.CreateMultipartUploadCommand({
588
+ Bucket: operation.bucketName,
589
+ Key: conditionalCompleteKey,
590
+ Metadata: probeMetadata,
591
+ }), {
592
+ abortSignal: signalArg,
593
+ }));
594
+ const firstUploadId = requireNonEmptyString(createFirstOutput.UploadId, 'CreateMultipartUpload UploadId');
595
+ unfinishedMultipartUploads.push({
596
+ key: conditionalCompleteKey,
597
+ uploadId: firstUploadId,
598
+ });
599
+ const firstPartOutput = await sendOperationCommand(operation, (signalArg) => operation.client.send(new plugins.s3.UploadPartCommand({
600
+ Bucket: operation.bucketName,
601
+ Key: conditionalCompleteKey,
602
+ UploadId: firstUploadId,
603
+ PartNumber: 1,
604
+ Body: new Uint8Array([1]),
605
+ ContentLength: 1,
606
+ }), {
607
+ abortSignal: signalArg,
608
+ }));
609
+ const firstPartEtag = requireNonEmptyString(firstPartOutput.ETag, 'UploadPart ETag');
610
+ const firstCompleteOutput = await sendOperationCommand(operation, (signalArg) => operation.client.send(new plugins.s3.CompleteMultipartUploadCommand({
611
+ Bucket: operation.bucketName,
612
+ Key: conditionalCompleteKey,
613
+ UploadId: firstUploadId,
614
+ MultipartUpload: {
615
+ Parts: [
616
+ {
617
+ PartNumber: 1,
618
+ ETag: firstPartEtag,
619
+ },
620
+ ],
621
+ },
622
+ IfNoneMatch: '*',
623
+ MpuObjectSize: 1,
624
+ }), {
625
+ abortSignal: signalArg,
626
+ }));
627
+ unfinishedMultipartUploads.splice(unfinishedMultipartUploads.findIndex((uploadArg) => uploadArg.uploadId === firstUploadId), 1);
628
+ recordProbeObject(conditionalCompleteKey, firstCompleteOutput);
629
+ requireNonEmptyString(firstCompleteOutput.ETag, 'CompleteMultipartUpload ETag');
630
+ const createSecondOutput = await sendOperationCommand(operation, (signalArg) => operation.client.send(new plugins.s3.CreateMultipartUploadCommand({
631
+ Bucket: operation.bucketName,
632
+ Key: conditionalCompleteKey,
633
+ Metadata: probeMetadata,
634
+ }), {
635
+ abortSignal: signalArg,
636
+ }));
637
+ const secondUploadId = requireNonEmptyString(createSecondOutput.UploadId, 'CreateMultipartUpload UploadId');
638
+ unfinishedMultipartUploads.push({
639
+ key: conditionalCompleteKey,
640
+ uploadId: secondUploadId,
641
+ });
642
+ const secondPartOutput = await sendOperationCommand(operation, (signalArg) => operation.client.send(new plugins.s3.UploadPartCommand({
643
+ Bucket: operation.bucketName,
644
+ Key: conditionalCompleteKey,
645
+ UploadId: secondUploadId,
646
+ PartNumber: 1,
647
+ Body: new Uint8Array([2]),
648
+ ContentLength: 1,
649
+ }), {
650
+ abortSignal: signalArg,
651
+ }));
652
+ const secondPartEtag = requireNonEmptyString(secondPartOutput.ETag, 'UploadPart ETag');
653
+ try {
654
+ const duplicateCompleteOutput = await sendOperationCommand(operation, (signalArg) => operation.client.send(new plugins.s3.CompleteMultipartUploadCommand({
655
+ Bucket: operation.bucketName,
656
+ Key: conditionalCompleteKey,
657
+ UploadId: secondUploadId,
658
+ MultipartUpload: {
659
+ Parts: [
660
+ {
661
+ PartNumber: 1,
662
+ ETag: secondPartEtag,
663
+ },
664
+ ],
665
+ },
666
+ IfNoneMatch: '*',
667
+ MpuObjectSize: 1,
668
+ }), {
669
+ abortSignal: signalArg,
670
+ }));
671
+ unfinishedMultipartUploads.splice(unfinishedMultipartUploads.findIndex((uploadArg) => uploadArg.uploadId === secondUploadId), 1);
672
+ recordProbeObject(conditionalCompleteKey, duplicateCompleteOutput);
673
+ throw new ExactUploadProbeSemanticError('conditional-complete-not-enforced');
674
+ }
675
+ catch (error) {
676
+ if (error instanceof ExactUploadProbeSemanticError) {
677
+ throw error;
678
+ }
679
+ operation.assertCurrent();
680
+ if (!isHttpStatus(error, 412)) {
681
+ throw error;
682
+ }
683
+ }
684
+ }
685
+ catch (error) {
686
+ if (error instanceof ExactUploadProbeSemanticError) {
687
+ failureReason = error.reason;
688
+ }
689
+ else if (operation.signal.aborted) {
690
+ failureReason = 'aborted';
691
+ failureCause = operation.signal.reason;
692
+ }
693
+ else {
694
+ failureReason = 'unavailable';
695
+ failureCause = error;
696
+ }
697
+ }
698
+ const probeCleanupTasks = createProbeCleanupTasks(operation.client, operation.bucketName, probeRoot, providerUsesVersions, unfinishedMultipartUploads, probeObjects, () => operation.assertLifecycleCurrent());
699
+ const primaryProviderSettlement = getDetachedOperationSendSettlement(operation.signal);
700
+ if (primaryProviderSettlement) {
701
+ const deferredCleanup = primaryProviderSettlement
702
+ .then(async () => {
703
+ try {
704
+ operation.assertLifecycleCurrent();
705
+ const cleanupResult = await runIndependentCleanup(probeCleanupTasks, operation);
706
+ await cleanupResult.settlement;
707
+ }
708
+ catch {
709
+ // Lifecycle close makes deferred probe cleanup indeterminate.
710
+ }
711
+ })
712
+ .then(() => undefined, () => undefined);
713
+ finishOperationAfterOwnedSettlements(operation, [deferredCleanup]);
714
+ return {
715
+ supported: false,
716
+ reason: failureReason ?? 'aborted',
717
+ cause: failureCause ?? operation.signal.reason,
718
+ };
719
+ }
720
+ const cleanupResult = await runIndependentCleanup(probeCleanupTasks, operation);
721
+ try {
722
+ if (cleanupResult.errors.length > 0) {
723
+ return {
724
+ supported: false,
725
+ reason: 'cleanup-failed',
726
+ cause: new AggregateError(cleanupResult.errors, 'The exact-upload capability probe could not clean up safely.'),
727
+ };
728
+ }
729
+ if (failureReason) {
730
+ return {
731
+ supported: false,
732
+ reason: failureReason,
733
+ cause: failureCause,
734
+ };
735
+ }
736
+ return {
737
+ supported: true,
738
+ capability: mintExactUploadCapability(bucketRefArg, operation),
739
+ };
740
+ }
741
+ catch (error) {
742
+ return {
743
+ supported: false,
744
+ reason: operation.signal.aborted ? 'aborted' : 'unavailable',
745
+ cause: error,
746
+ };
747
+ }
748
+ finally {
749
+ if (cleanupResult.timedOut) {
750
+ finishOperationAfterOwnedSettlements(operation, [
751
+ cleanupResult.settlement,
752
+ ]);
753
+ }
754
+ else {
755
+ finishOperationAfterOwnedSettlements(operation);
756
+ }
757
+ }
758
+ };
759
+ const abortMultipartUpload = async (operationArg, keyArg, uploadIdArg) => {
760
+ let reconciliationResult;
761
+ const cleanupResult = await runIndependentCleanup([
762
+ async (signalArg) => {
763
+ reconciliationResult = await reconcileMultipartUploadAbort(operationArg.client, operationArg.bucketName, keyArg, uploadIdArg, signalArg, () => operationArg.assertLifecycleCurrent());
764
+ },
765
+ ], operationArg);
766
+ return {
767
+ cleanup: cleanupResult.timedOut
768
+ ? {
769
+ status: 'deferred',
770
+ }
771
+ : cleanupResult.errors.length === 0
772
+ ? {
773
+ status: reconciliationResult ?? 'absent',
774
+ }
775
+ : {
776
+ status: 'abort-failed',
777
+ cause: new AggregateError(cleanupResult.errors, 'The multipart upload could not be aborted safely.'),
778
+ },
779
+ timedOut: cleanupResult.timedOut,
780
+ settlement: cleanupResult.settlement,
781
+ };
782
+ };
783
+ export const fastPutStreamExact = async (bucketRefArg, optionsArg) => {
784
+ if (typeof optionsArg.path !== 'string' || optionsArg.path.length === 0) {
785
+ throw new TypeError('path must be a non-empty string.');
786
+ }
787
+ const nativeObjectProperties = snapshotNativeObjectProperties(optionsArg.nativeObjectProperties);
788
+ const plan = planMultipartUpload({
789
+ objectSize: optionsArg.contentLength,
790
+ requestedPartSize: optionsArg.requestedPartSize,
791
+ requestedConcurrency: optionsArg.requestedConcurrency,
792
+ });
793
+ let operation;
794
+ try {
795
+ operation = beginExactUploadCapabilityOperation(bucketRefArg, optionsArg.capability, optionsArg.signal);
796
+ }
797
+ catch (error) {
798
+ throw new ExactUploadError({
799
+ phase: 'capability',
800
+ destinationPath: optionsArg.path,
801
+ expectedContentLength: optionsArg.contentLength,
802
+ destinationPublication: 'not-published',
803
+ multipartCleanup: {
804
+ status: 'not-required',
805
+ },
806
+ }, error);
807
+ }
808
+ let readableStream;
809
+ try {
810
+ readableStream = toWebReadableStream(optionsArg.readableStream);
811
+ }
812
+ catch (error) {
813
+ operation.finish();
814
+ throw new ExactUploadError({
815
+ phase: 'source',
816
+ destinationPath: optionsArg.path,
817
+ expectedContentLength: optionsArg.contentLength,
818
+ destinationPublication: 'not-published',
819
+ multipartCleanup: {
820
+ status: 'not-required',
821
+ },
822
+ }, error);
823
+ }
824
+ if (plan.classification === 'zero') {
825
+ let putRequestAttempted = false;
826
+ let zeroFinishSettlement;
827
+ try {
828
+ let consumptionResult;
829
+ try {
830
+ consumptionResult = await consumeExactMultipartStream({
831
+ readableStream,
832
+ plan,
833
+ signal: operation.signal,
834
+ failureSettlementTimeoutMs: optionsArg.failureSettlementTimeoutMs,
835
+ async onPart() {
836
+ throw new Error('A zero-byte upload cannot contain multipart parts.');
837
+ },
838
+ });
839
+ }
840
+ catch (error) {
841
+ if (error instanceof MultipartStreamConsumptionError &&
842
+ (error.state.cleanup.callbacks === 'detached' ||
843
+ error.state.cleanup.reader.status === 'cancel-detached')) {
844
+ zeroFinishSettlement = error.ownedSettlement;
845
+ }
846
+ throw new ExactUploadError({
847
+ phase: 'source',
848
+ destinationPath: optionsArg.path,
849
+ expectedContentLength: optionsArg.contentLength,
850
+ destinationPublication: 'not-published',
851
+ multipartCleanup: {
852
+ status: 'not-required',
853
+ },
854
+ }, error);
855
+ }
856
+ try {
857
+ const putOutput = await sendOperationCommand(operation, (signalArg) => {
858
+ putRequestAttempted = true;
859
+ return operation.client.send(new plugins.s3.PutObjectCommand({
860
+ Bucket: operation.bucketName,
861
+ Key: optionsArg.path,
862
+ Body: new Uint8Array(0),
863
+ ContentLength: 0,
864
+ Metadata: optionsArg.nativeMetadata,
865
+ ContentType: nativeObjectProperties?.contentType,
866
+ IfNoneMatch: '*',
867
+ }), {
868
+ abortSignal: signalArg,
869
+ });
870
+ });
871
+ return {
872
+ destinationPath: optionsArg.path,
873
+ contentLength: 0,
874
+ etag: requireNonEmptyString(putOutput.ETag, 'PutObject ETag'),
875
+ versionId: getOptionalNonEmptyString(putOutput.VersionId),
876
+ partCount: 0,
877
+ peakBufferedBytes: consumptionResult.peakBufferedBytes,
878
+ maximumBufferedBytes: consumptionResult.maximumBufferedBytes,
879
+ };
880
+ }
881
+ catch (error) {
882
+ if (error instanceof ExactUploadError) {
883
+ throw error;
884
+ }
885
+ throw new ExactUploadError({
886
+ phase: 'put-zero',
887
+ destinationPath: optionsArg.path,
888
+ expectedContentLength: optionsArg.contentLength,
889
+ destinationPublication: putRequestAttempted &&
890
+ !isDefinitiveConditionalWriteRejection(error)
891
+ ? 'ambiguous'
892
+ : 'not-published',
893
+ multipartCleanup: {
894
+ status: 'not-required',
895
+ },
896
+ }, error);
897
+ }
898
+ }
899
+ finally {
900
+ if (zeroFinishSettlement) {
901
+ finishOperationAfterOwnedSettlements(operation, [
902
+ zeroFinishSettlement,
903
+ ]);
904
+ }
905
+ else {
906
+ finishOperationAfterOwnedSettlements(operation);
907
+ }
908
+ }
909
+ }
910
+ let phase = 'create-multipart';
911
+ let uploadId;
912
+ let createRequestAttempted = false;
913
+ let completeRequestAttempted = false;
914
+ let operationFinishSettlement;
915
+ let detachedStreamError;
916
+ try {
917
+ const createOutput = await sendOperationCommand(operation, (signalArg) => {
918
+ createRequestAttempted = true;
919
+ return operation.client.send(new plugins.s3.CreateMultipartUploadCommand({
920
+ Bucket: operation.bucketName,
921
+ Key: optionsArg.path,
922
+ Metadata: optionsArg.nativeMetadata,
923
+ ContentType: nativeObjectProperties?.contentType,
924
+ }), {
925
+ abortSignal: signalArg,
926
+ });
927
+ });
928
+ uploadId = requireNonEmptyString(createOutput.UploadId, 'CreateMultipartUpload UploadId');
929
+ phase = 'source';
930
+ const completedParts = [];
931
+ let consumptionResult;
932
+ try {
933
+ consumptionResult = await consumeExactMultipartStream({
934
+ readableStream,
935
+ plan,
936
+ signal: operation.signal,
937
+ failureSettlementTimeoutMs: optionsArg.failureSettlementTimeoutMs,
938
+ async onPart(partArg) {
939
+ operation.assertCurrent();
940
+ const uploadPartOutput = await operation.client.send(new plugins.s3.UploadPartCommand({
941
+ Bucket: operation.bucketName,
942
+ Key: optionsArg.path,
943
+ UploadId: uploadId,
944
+ PartNumber: partArg.partNumber,
945
+ Body: partArg.data,
946
+ ContentLength: partArg.data.byteLength,
947
+ }), {
948
+ abortSignal: partArg.signal,
949
+ });
950
+ operation.assertCurrent();
951
+ completedParts[partArg.partNumber - 1] = {
952
+ PartNumber: partArg.partNumber,
953
+ ETag: requireNonEmptyString(uploadPartOutput.ETag, 'UploadPart ETag'),
954
+ };
955
+ },
956
+ });
957
+ }
958
+ catch (error) {
959
+ if (error instanceof MultipartStreamConsumptionError &&
960
+ error.state.kind === 'part-callback') {
961
+ phase = 'upload-part';
962
+ }
963
+ if (error instanceof MultipartStreamConsumptionError &&
964
+ (error.state.cleanup.callbacks === 'detached' ||
965
+ error.state.cleanup.reader.status === 'cancel-detached')) {
966
+ detachedStreamError = error;
967
+ }
968
+ throw error;
969
+ }
970
+ phase = 'complete-multipart';
971
+ const completeOutput = await sendOperationCommand(operation, (signalArg) => {
972
+ completeRequestAttempted = true;
973
+ return operation.client.send(new plugins.s3.CompleteMultipartUploadCommand({
974
+ Bucket: operation.bucketName,
975
+ Key: optionsArg.path,
976
+ UploadId: uploadId,
977
+ MultipartUpload: {
978
+ Parts: completedParts,
979
+ },
980
+ IfNoneMatch: '*',
981
+ MpuObjectSize: optionsArg.contentLength,
982
+ }), {
983
+ abortSignal: signalArg,
984
+ });
985
+ });
986
+ return {
987
+ destinationPath: optionsArg.path,
988
+ contentLength: optionsArg.contentLength,
989
+ etag: requireNonEmptyString(completeOutput.ETag, 'CompleteMultipartUpload ETag'),
990
+ versionId: getOptionalNonEmptyString(completeOutput.VersionId),
991
+ partCount: completedParts.length,
992
+ peakBufferedBytes: consumptionResult.peakBufferedBytes,
993
+ maximumBufferedBytes: consumptionResult.maximumBufferedBytes,
994
+ };
995
+ }
996
+ catch (error) {
997
+ let multipartCleanup;
998
+ const primaryProviderSettlement = getDetachedOperationSendSettlement(operation.signal);
999
+ if (uploadId &&
1000
+ detachedStreamError?.state.cleanup.callbacks === 'detached') {
1001
+ multipartCleanup = {
1002
+ status: 'deferred',
1003
+ };
1004
+ const callbackGatedCleanup = detachedStreamError.callbackSettlement
1005
+ .then(async () => {
1006
+ try {
1007
+ operation.assertLifecycleCurrent();
1008
+ const abortResult = await abortMultipartUpload(operation, optionsArg.path, uploadId);
1009
+ await abortResult.settlement;
1010
+ }
1011
+ catch {
1012
+ // Lifecycle close makes deferred cleanup indeterminate.
1013
+ }
1014
+ })
1015
+ .then(() => undefined, () => undefined);
1016
+ operationFinishSettlement = Promise.allSettled([
1017
+ callbackGatedCleanup,
1018
+ detachedStreamError.ownedSettlement,
1019
+ ]).then(() => undefined);
1020
+ }
1021
+ else if (uploadId && primaryProviderSettlement) {
1022
+ multipartCleanup = {
1023
+ status: 'deferred',
1024
+ };
1025
+ const providerGatedCleanup = primaryProviderSettlement
1026
+ .then(async () => {
1027
+ try {
1028
+ operation.assertLifecycleCurrent();
1029
+ const abortResult = await abortMultipartUpload(operation, optionsArg.path, uploadId);
1030
+ await abortResult.settlement;
1031
+ }
1032
+ catch {
1033
+ // Lifecycle close makes deferred cleanup indeterminate.
1034
+ }
1035
+ })
1036
+ .then(() => undefined, () => undefined);
1037
+ operationFinishSettlement = Promise.allSettled([
1038
+ primaryProviderSettlement,
1039
+ providerGatedCleanup,
1040
+ ]).then(() => undefined);
1041
+ }
1042
+ else if (uploadId) {
1043
+ const abortResult = await abortMultipartUpload(operation, optionsArg.path, uploadId);
1044
+ multipartCleanup = abortResult.cleanup;
1045
+ if (abortResult.timedOut) {
1046
+ operationFinishSettlement = abortResult.settlement;
1047
+ }
1048
+ }
1049
+ else if (createRequestAttempted) {
1050
+ multipartCleanup = {
1051
+ ...(primaryProviderSettlement
1052
+ ? {
1053
+ status: 'deferred',
1054
+ }
1055
+ : {
1056
+ status: 'abort-failed',
1057
+ cause: new Error('The multipart upload could not be aborted because no UploadId was returned.'),
1058
+ }),
1059
+ };
1060
+ if (primaryProviderSettlement) {
1061
+ operationFinishSettlement = primaryProviderSettlement;
1062
+ }
1063
+ }
1064
+ else {
1065
+ multipartCleanup = {
1066
+ status: 'not-required',
1067
+ };
1068
+ }
1069
+ if (detachedStreamError?.state.cleanup.reader.status ===
1070
+ 'cancel-detached' &&
1071
+ detachedStreamError.state.cleanup.callbacks !== 'detached') {
1072
+ const ownedSettlements = [
1073
+ detachedStreamError.ownedSettlement,
1074
+ ];
1075
+ if (operationFinishSettlement) {
1076
+ ownedSettlements.push(operationFinishSettlement);
1077
+ }
1078
+ operationFinishSettlement = Promise.allSettled(ownedSettlements).then(() => undefined);
1079
+ }
1080
+ throw new ExactUploadError({
1081
+ phase,
1082
+ destinationPath: optionsArg.path,
1083
+ expectedContentLength: optionsArg.contentLength,
1084
+ destinationPublication: phase === 'complete-multipart' &&
1085
+ completeRequestAttempted &&
1086
+ !isDefinitiveConditionalWriteRejection(error)
1087
+ ? 'ambiguous'
1088
+ : 'not-published',
1089
+ multipartUploadId: uploadId,
1090
+ multipartCleanup,
1091
+ }, error);
1092
+ }
1093
+ finally {
1094
+ if (operationFinishSettlement) {
1095
+ finishOperationAfterOwnedSettlements(operation, [
1096
+ operationFinishSettlement,
1097
+ ]);
1098
+ }
1099
+ else {
1100
+ finishOperationAfterOwnedSettlements(operation);
1101
+ }
1102
+ }
1103
+ };
1104
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJuYWwuZXhhY3R1cGxvYWQub3BlcmF0aW9ucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL29iamVjdHN0b3JhZ2UvaW50ZXJuYWwuZXhhY3R1cGxvYWQub3BlcmF0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUN4QyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQVVqRSxPQUFPLEVBQ0wsbUNBQW1DLEVBQ25DLDhCQUE4QixFQUM5Qix5QkFBeUIsR0FFMUIsTUFBTSxzQ0FBc0MsQ0FBQztBQUM5QyxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUN0RSxPQUFPLEVBQ0wsMkJBQTJCLEVBQzNCLCtCQUErQixHQUNoQyxNQUFNLGdDQUFnQyxDQUFDO0FBK0J4QyxNQUFNLDZCQUE4QixTQUFRLEtBQUs7SUFFN0I7SUFEbEIsWUFDa0IsTUFHZjtRQUVELEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUxFLFdBQU0sR0FBTixNQUFNLENBR3JCO1FBR0QsSUFBSSxDQUFDLElBQUksR0FBRywrQkFBK0IsQ0FBQztJQUM5QyxDQUFDO0NBQ0Y7QUFFRCxNQUFNLGdCQUFnQixHQUFHLE1BQU0sQ0FBQztBQUNoQyxNQUFNLCtCQUErQixHQUFHLEdBQUcsQ0FBQztBQUM1QyxNQUFNLDZCQUE2QixHQUFHLEVBQUUsQ0FBQztBQUN6QyxNQUFNLDBCQUEwQixHQUFHLEdBQUcsQ0FBQztBQUN2QyxNQUFNLGFBQWEsR0FBRztJQUNwQixtQkFBbUIsRUFBRSxpQkFBaUI7Q0FDdkMsQ0FBQztBQUVGLE1BQU0sOEJBQThCLEdBQUcsQ0FDckMsUUFBOEQsRUFDUixFQUFFO0lBQ3hELElBQUksUUFBUSxLQUFLLFNBQVMsRUFBRSxDQUFDO1FBQzNCLE9BQU8sU0FBUyxDQUFDO0lBQ25CLENBQUM7SUFDRCxJQUNFLFFBQVEs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