@backblaze-labs/b2-sdk 0.1.0 → 0.3.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 (885) hide show
  1. package/CHANGELOG.md +151 -5
  2. package/README.md +163 -34
  3. package/dist/_virtual/_b2-sdk-version-json.cjs +4 -0
  4. package/dist/_virtual/_b2-sdk-version-json.js +4 -0
  5. package/dist/auth/account-info.d.cts +32 -0
  6. package/dist/auth/account-info.d.cts.map +1 -1
  7. package/dist/auth/account-info.d.ts +32 -0
  8. package/dist/auth/account-info.d.ts.map +1 -1
  9. package/dist/auth/file.cjs +408 -207
  10. package/dist/auth/file.cjs.map +1 -1
  11. package/dist/auth/file.d.cts +77 -3
  12. package/dist/auth/file.d.cts.map +1 -1
  13. package/dist/auth/file.d.ts +77 -3
  14. package/dist/auth/file.d.ts.map +1 -1
  15. package/dist/auth/file.js +407 -207
  16. package/dist/auth/file.js.map +1 -1
  17. package/dist/auth/in-memory.cjs +212 -183
  18. package/dist/auth/in-memory.cjs.map +1 -1
  19. package/dist/auth/in-memory.d.cts +8 -0
  20. package/dist/auth/in-memory.d.cts.map +1 -1
  21. package/dist/auth/in-memory.d.ts +8 -0
  22. package/dist/auth/in-memory.d.ts.map +1 -1
  23. package/dist/auth/in-memory.js +211 -182
  24. package/dist/auth/in-memory.js.map +1 -1
  25. package/dist/auth/index.cjs +7 -9
  26. package/dist/auth/index.d.cts +3 -2
  27. package/dist/auth/index.d.cts.map +1 -1
  28. package/dist/auth/index.d.ts +3 -2
  29. package/dist/auth/index.d.ts.map +1 -1
  30. package/dist/auth/index.js +2 -8
  31. package/dist/auth/realms.cjs +80 -7
  32. package/dist/auth/realms.cjs.map +1 -1
  33. package/dist/auth/realms.d.cts +27 -4
  34. package/dist/auth/realms.d.cts.map +1 -1
  35. package/dist/auth/realms.d.ts +27 -4
  36. package/dist/auth/realms.d.ts.map +1 -1
  37. package/dist/auth/realms.js +80 -9
  38. package/dist/auth/realms.js.map +1 -1
  39. package/dist/auth/upload-url-pool.cjs +55 -51
  40. package/dist/auth/upload-url-pool.cjs.map +1 -1
  41. package/dist/auth/upload-url-pool.js +55 -51
  42. package/dist/auth/upload-url-pool.js.map +1 -1
  43. package/dist/backup/client.cjs +206 -0
  44. package/dist/backup/client.cjs.map +1 -0
  45. package/dist/backup/client.d.cts +238 -0
  46. package/dist/backup/client.d.cts.map +1 -0
  47. package/dist/backup/client.d.ts +238 -0
  48. package/dist/backup/client.d.ts.map +1 -0
  49. package/dist/backup/client.js +206 -0
  50. package/dist/backup/client.js.map +1 -0
  51. package/dist/backup/index.cjs +15 -0
  52. package/dist/backup/index.d.cts +22 -0
  53. package/dist/backup/index.d.cts.map +1 -0
  54. package/dist/backup/index.d.ts +22 -0
  55. package/dist/backup/index.d.ts.map +1 -0
  56. package/dist/backup/index.js +7 -0
  57. package/dist/backup/raw.cjs +146 -0
  58. package/dist/backup/raw.cjs.map +1 -0
  59. package/dist/backup/raw.d.cts +122 -0
  60. package/dist/backup/raw.d.cts.map +1 -0
  61. package/dist/backup/raw.d.ts +122 -0
  62. package/dist/backup/raw.d.ts.map +1 -0
  63. package/dist/backup/raw.js +146 -0
  64. package/dist/backup/raw.js.map +1 -0
  65. package/dist/bucket.cjs +786 -787
  66. package/dist/bucket.cjs.map +1 -1
  67. package/dist/bucket.d.cts +35 -47
  68. package/dist/bucket.d.cts.map +1 -1
  69. package/dist/bucket.d.ts +35 -47
  70. package/dist/bucket.d.ts.map +1 -1
  71. package/dist/bucket.js +781 -782
  72. package/dist/bucket.js.map +1 -1
  73. package/dist/client.cjs +246 -228
  74. package/dist/client.cjs.map +1 -1
  75. package/dist/client.d.cts +25 -17
  76. package/dist/client.d.cts.map +1 -1
  77. package/dist/client.d.ts +25 -17
  78. package/dist/client.d.ts.map +1 -1
  79. package/dist/client.js +243 -225
  80. package/dist/client.js.map +1 -1
  81. package/dist/copy/large.cjs +116 -71
  82. package/dist/copy/large.cjs.map +1 -1
  83. package/dist/copy/large.d.cts +6 -0
  84. package/dist/copy/large.d.cts.map +1 -1
  85. package/dist/copy/large.d.ts +6 -0
  86. package/dist/copy/large.d.ts.map +1 -1
  87. package/dist/copy/large.js +114 -69
  88. package/dist/copy/large.js.map +1 -1
  89. package/dist/download/checksum.cjs +93 -0
  90. package/dist/download/checksum.cjs.map +1 -0
  91. package/dist/download/checksum.d.cts +40 -0
  92. package/dist/download/checksum.d.cts.map +1 -0
  93. package/dist/download/checksum.d.ts +40 -0
  94. package/dist/download/checksum.d.ts.map +1 -0
  95. package/dist/download/checksum.js +91 -0
  96. package/dist/download/checksum.js.map +1 -0
  97. package/dist/download/parallel.cjs +251 -118
  98. package/dist/download/parallel.cjs.map +1 -1
  99. package/dist/download/parallel.d.cts +13 -2
  100. package/dist/download/parallel.d.cts.map +1 -1
  101. package/dist/download/parallel.d.ts +13 -2
  102. package/dist/download/parallel.d.ts.map +1 -1
  103. package/dist/download/parallel.js +249 -116
  104. package/dist/download/parallel.js.map +1 -1
  105. package/dist/download/single.cjs +323 -97
  106. package/dist/download/single.cjs.map +1 -1
  107. package/dist/download/single.d.cts +6 -1
  108. package/dist/download/single.d.cts.map +1 -1
  109. package/dist/download/single.d.ts +6 -1
  110. package/dist/download/single.d.ts.map +1 -1
  111. package/dist/download/single.js +322 -99
  112. package/dist/download/single.js.map +1 -1
  113. package/dist/errors/index.cjs +869 -243
  114. package/dist/errors/index.cjs.map +1 -1
  115. package/dist/errors/index.d.cts +404 -82
  116. package/dist/errors/index.d.cts.map +1 -1
  117. package/dist/errors/index.d.ts +404 -82
  118. package/dist/errors/index.d.ts.map +1 -1
  119. package/dist/errors/index.js +835 -261
  120. package/dist/errors/index.js.map +1 -1
  121. package/dist/http/retry.cjs +45 -28
  122. package/dist/http/retry.cjs.map +1 -1
  123. package/dist/http/retry.d.cts +15 -2
  124. package/dist/http/retry.d.cts.map +1 -1
  125. package/dist/http/retry.d.ts +15 -2
  126. package/dist/http/retry.d.ts.map +1 -1
  127. package/dist/http/retry.js +46 -31
  128. package/dist/http/retry.js.map +1 -1
  129. package/dist/http/transport.cjs +476 -140
  130. package/dist/http/transport.cjs.map +1 -1
  131. package/dist/http/transport.d.cts +46 -5
  132. package/dist/http/transport.d.cts.map +1 -1
  133. package/dist/http/transport.d.ts +46 -5
  134. package/dist/http/transport.d.ts.map +1 -1
  135. package/dist/http/transport.js +474 -140
  136. package/dist/http/transport.js.map +1 -1
  137. package/dist/http/url-guard.cjs +154 -89
  138. package/dist/http/url-guard.cjs.map +1 -1
  139. package/dist/http/url-guard.d.cts +25 -3
  140. package/dist/http/url-guard.d.cts.map +1 -1
  141. package/dist/http/url-guard.d.ts +25 -3
  142. package/dist/http/url-guard.d.ts.map +1 -1
  143. package/dist/http/url-guard.js +152 -90
  144. package/dist/http/url-guard.js.map +1 -1
  145. package/dist/http/user-agent.cjs +84 -44
  146. package/dist/http/user-agent.cjs.map +1 -1
  147. package/dist/http/user-agent.js +84 -46
  148. package/dist/http/user-agent.js.map +1 -1
  149. package/dist/index.cjs +124 -77
  150. package/dist/index.d.cts +29 -21
  151. package/dist/index.d.cts.map +1 -1
  152. package/dist/index.d.ts +29 -21
  153. package/dist/index.d.ts.map +1 -1
  154. package/dist/index.js +18 -72
  155. package/dist/internal/b2-naming.cjs +66 -0
  156. package/dist/internal/b2-naming.cjs.map +1 -0
  157. package/dist/internal/b2-naming.d.cts +43 -0
  158. package/dist/internal/b2-naming.d.cts.map +1 -0
  159. package/dist/internal/b2-naming.d.ts +43 -0
  160. package/dist/internal/b2-naming.d.ts.map +1 -0
  161. package/dist/internal/b2-naming.js +60 -0
  162. package/dist/internal/b2-naming.js.map +1 -0
  163. package/dist/internal/upload-retry-options.cjs +21 -0
  164. package/dist/internal/upload-retry-options.cjs.map +1 -0
  165. package/dist/internal/upload-retry-options.d.cts +12 -0
  166. package/dist/internal/upload-retry-options.d.cts.map +1 -0
  167. package/dist/internal/upload-retry-options.d.ts +12 -0
  168. package/dist/internal/upload-retry-options.d.ts.map +1 -0
  169. package/dist/internal/upload-retry-options.js +21 -0
  170. package/dist/internal/upload-retry-options.js.map +1 -0
  171. package/dist/internal/url-redaction.cjs +31 -0
  172. package/dist/internal/url-redaction.cjs.map +1 -0
  173. package/dist/internal/url-redaction.d.cts +17 -0
  174. package/dist/internal/url-redaction.d.cts.map +1 -0
  175. package/dist/internal/url-redaction.d.ts +17 -0
  176. package/dist/internal/url-redaction.d.ts.map +1 -0
  177. package/dist/internal/url-redaction.js +31 -0
  178. package/dist/internal/url-redaction.js.map +1 -0
  179. package/dist/notifications/index.cjs +4 -6
  180. package/dist/notifications/index.d.cts +1 -1
  181. package/dist/notifications/index.d.cts.map +1 -1
  182. package/dist/notifications/index.d.ts +1 -1
  183. package/dist/notifications/index.d.ts.map +1 -1
  184. package/dist/notifications/index.js +1 -6
  185. package/dist/notifications/webhook.cjs +195 -85
  186. package/dist/notifications/webhook.cjs.map +1 -1
  187. package/dist/notifications/webhook.d.cts.map +1 -1
  188. package/dist/notifications/webhook.d.ts.map +1 -1
  189. package/dist/notifications/webhook.js +195 -87
  190. package/dist/notifications/webhook.js.map +1 -1
  191. package/dist/object.cjs +253 -210
  192. package/dist/object.cjs.map +1 -1
  193. package/dist/object.d.cts +13 -57
  194. package/dist/object.d.cts.map +1 -1
  195. package/dist/object.d.ts +13 -57
  196. package/dist/object.d.ts.map +1 -1
  197. package/dist/object.js +249 -206
  198. package/dist/object.js.map +1 -1
  199. package/dist/partner/account-info.d.cts +43 -0
  200. package/dist/partner/account-info.d.cts.map +1 -0
  201. package/dist/partner/account-info.d.ts +43 -0
  202. package/dist/partner/account-info.d.ts.map +1 -0
  203. package/dist/partner/auth-clone.cjs +64 -0
  204. package/dist/partner/auth-clone.cjs.map +1 -0
  205. package/dist/partner/auth-clone.d.cts +27 -0
  206. package/dist/partner/auth-clone.d.cts.map +1 -0
  207. package/dist/partner/auth-clone.d.ts +27 -0
  208. package/dist/partner/auth-clone.d.ts.map +1 -0
  209. package/dist/partner/auth-clone.js +63 -0
  210. package/dist/partner/auth-clone.js.map +1 -0
  211. package/dist/partner/auth-core.cjs +175 -0
  212. package/dist/partner/auth-core.cjs.map +1 -0
  213. package/dist/partner/auth-core.d.cts +111 -0
  214. package/dist/partner/auth-core.d.cts.map +1 -0
  215. package/dist/partner/auth-core.d.ts +111 -0
  216. package/dist/partner/auth-core.d.ts.map +1 -0
  217. package/dist/partner/auth-core.js +175 -0
  218. package/dist/partner/auth-core.js.map +1 -0
  219. package/dist/partner/auth-shape.cjs +36 -0
  220. package/dist/partner/auth-shape.cjs.map +1 -0
  221. package/dist/partner/auth-shape.d.cts +12 -0
  222. package/dist/partner/auth-shape.d.cts.map +1 -0
  223. package/dist/partner/auth-shape.d.ts +12 -0
  224. package/dist/partner/auth-shape.d.ts.map +1 -0
  225. package/dist/partner/auth-shape.js +36 -0
  226. package/dist/partner/auth-shape.js.map +1 -0
  227. package/dist/partner/client.cjs +255 -0
  228. package/dist/partner/client.cjs.map +1 -0
  229. package/dist/partner/client.d.cts +335 -0
  230. package/dist/partner/client.d.cts.map +1 -0
  231. package/dist/partner/client.d.ts +335 -0
  232. package/dist/partner/client.d.ts.map +1 -0
  233. package/dist/partner/client.js +255 -0
  234. package/dist/partner/client.js.map +1 -0
  235. package/dist/partner/endpoint-url.cjs +108 -0
  236. package/dist/partner/endpoint-url.cjs.map +1 -0
  237. package/dist/partner/endpoint-url.d.cts +72 -0
  238. package/dist/partner/endpoint-url.d.cts.map +1 -0
  239. package/dist/partner/endpoint-url.d.ts +72 -0
  240. package/dist/partner/endpoint-url.d.ts.map +1 -0
  241. package/dist/partner/endpoint-url.js +105 -0
  242. package/dist/partner/endpoint-url.js.map +1 -0
  243. package/dist/partner/in-memory.cjs +135 -0
  244. package/dist/partner/in-memory.cjs.map +1 -0
  245. package/dist/partner/in-memory.d.cts +99 -0
  246. package/dist/partner/in-memory.d.cts.map +1 -0
  247. package/dist/partner/in-memory.d.ts +99 -0
  248. package/dist/partner/in-memory.d.ts.map +1 -0
  249. package/dist/partner/in-memory.js +135 -0
  250. package/dist/partner/in-memory.js.map +1 -0
  251. package/dist/partner/index.cjs +18 -0
  252. package/dist/partner/index.d.cts +23 -0
  253. package/dist/partner/index.d.cts.map +1 -0
  254. package/dist/partner/index.d.ts +23 -0
  255. package/dist/partner/index.d.ts.map +1 -0
  256. package/dist/partner/index.js +7 -0
  257. package/dist/partner/raw.cjs +392 -0
  258. package/dist/partner/raw.cjs.map +1 -0
  259. package/dist/partner/raw.d.cts +223 -0
  260. package/dist/partner/raw.d.cts.map +1 -0
  261. package/dist/partner/raw.d.ts +223 -0
  262. package/dist/partner/raw.d.ts.map +1 -0
  263. package/dist/partner/raw.js +390 -0
  264. package/dist/partner/raw.js.map +1 -0
  265. package/dist/partner/redaction-placeholders.cjs +10 -0
  266. package/dist/partner/redaction-placeholders.cjs.map +1 -0
  267. package/dist/partner/redaction-placeholders.d.cts +5 -0
  268. package/dist/partner/redaction-placeholders.d.cts.map +1 -0
  269. package/dist/partner/redaction-placeholders.d.ts +5 -0
  270. package/dist/partner/redaction-placeholders.d.ts.map +1 -0
  271. package/dist/partner/redaction-placeholders.js +9 -0
  272. package/dist/partner/redaction-placeholders.js.map +1 -0
  273. package/dist/partner/redaction.cjs +267 -0
  274. package/dist/partner/redaction.cjs.map +1 -0
  275. package/dist/partner/redaction.d.cts +124 -0
  276. package/dist/partner/redaction.d.cts.map +1 -0
  277. package/dist/partner/redaction.d.ts +124 -0
  278. package/dist/partner/redaction.d.ts.map +1 -0
  279. package/dist/partner/redaction.js +257 -0
  280. package/dist/partner/redaction.js.map +1 -0
  281. package/dist/raw/encoding.cjs +74 -35
  282. package/dist/raw/encoding.cjs.map +1 -1
  283. package/dist/raw/encoding.js +74 -38
  284. package/dist/raw/encoding.js.map +1 -1
  285. package/dist/raw/index.cjs +740 -587
  286. package/dist/raw/index.cjs.map +1 -1
  287. package/dist/raw/index.d.cts +126 -19
  288. package/dist/raw/index.d.cts.map +1 -1
  289. package/dist/raw/index.d.ts +126 -19
  290. package/dist/raw/index.d.ts.map +1 -1
  291. package/dist/raw/index.js +736 -589
  292. package/dist/raw/index.js.map +1 -1
  293. package/dist/raw/url.cjs +111 -0
  294. package/dist/raw/url.cjs.map +1 -0
  295. package/dist/raw/url.d.cts +41 -0
  296. package/dist/raw/url.d.cts.map +1 -0
  297. package/dist/raw/url.d.ts +41 -0
  298. package/dist/raw/url.d.ts.map +1 -0
  299. package/dist/raw/url.js +110 -0
  300. package/dist/raw/url.js.map +1 -0
  301. package/dist/s3/index.cjs +355 -18
  302. package/dist/s3/index.cjs.map +1 -1
  303. package/dist/s3/index.d.cts +233 -5
  304. package/dist/s3/index.d.cts.map +1 -1
  305. package/dist/s3/index.d.ts +233 -5
  306. package/dist/s3/index.d.ts.map +1 -1
  307. package/dist/s3/index.js +351 -22
  308. package/dist/s3/index.js.map +1 -1
  309. package/dist/s3/sigv4.cjs +154 -0
  310. package/dist/s3/sigv4.cjs.map +1 -0
  311. package/dist/s3/sigv4.d.cts +43 -0
  312. package/dist/s3/sigv4.d.cts.map +1 -0
  313. package/dist/s3/sigv4.d.ts +43 -0
  314. package/dist/s3/sigv4.d.ts.map +1 -0
  315. package/dist/s3/sigv4.js +153 -0
  316. package/dist/s3/sigv4.js.map +1 -0
  317. package/dist/s3/validation.cjs +69 -0
  318. package/dist/s3/validation.cjs.map +1 -0
  319. package/dist/s3/validation.d.cts +43 -0
  320. package/dist/s3/validation.d.cts.map +1 -0
  321. package/dist/s3/validation.d.ts +43 -0
  322. package/dist/s3/validation.d.ts.map +1 -0
  323. package/dist/s3/validation.js +66 -0
  324. package/dist/s3/validation.js.map +1 -0
  325. package/dist/simulator/capabilities.cjs +63 -48
  326. package/dist/simulator/capabilities.cjs.map +1 -1
  327. package/dist/simulator/capabilities.js +63 -49
  328. package/dist/simulator/capabilities.js.map +1 -1
  329. package/dist/simulator/index.cjs +3114 -1547
  330. package/dist/simulator/index.cjs.map +1 -1
  331. package/dist/simulator/index.d.cts +186 -20
  332. package/dist/simulator/index.d.cts.map +1 -1
  333. package/dist/simulator/index.d.ts +186 -20
  334. package/dist/simulator/index.d.ts.map +1 -1
  335. package/dist/simulator/index.js +3098 -1545
  336. package/dist/simulator/index.js.map +1 -1
  337. package/dist/simulator/partner.cjs +719 -0
  338. package/dist/simulator/partner.cjs.map +1 -0
  339. package/dist/simulator/partner.d.cts +183 -0
  340. package/dist/simulator/partner.d.cts.map +1 -0
  341. package/dist/simulator/partner.d.ts +183 -0
  342. package/dist/simulator/partner.d.ts.map +1 -0
  343. package/dist/simulator/partner.js +718 -0
  344. package/dist/simulator/partner.js.map +1 -0
  345. package/dist/simulator/validation.cjs +772 -157
  346. package/dist/simulator/validation.cjs.map +1 -1
  347. package/dist/simulator/validation.d.cts +120 -21
  348. package/dist/simulator/validation.d.cts.map +1 -1
  349. package/dist/simulator/validation.d.ts +120 -21
  350. package/dist/simulator/validation.d.ts.map +1 -1
  351. package/dist/simulator/validation.js +755 -167
  352. package/dist/simulator/validation.js.map +1 -1
  353. package/dist/streams/collect.cjs +74 -24
  354. package/dist/streams/collect.cjs.map +1 -1
  355. package/dist/streams/collect.d.cts +14 -1
  356. package/dist/streams/collect.d.cts.map +1 -1
  357. package/dist/streams/collect.d.ts +14 -1
  358. package/dist/streams/collect.d.ts.map +1 -1
  359. package/dist/streams/collect.js +74 -25
  360. package/dist/streams/collect.js.map +1 -1
  361. package/dist/streams/file-source.cjs +287 -0
  362. package/dist/streams/file-source.cjs.map +1 -0
  363. package/dist/streams/file-source.d.cts +96 -0
  364. package/dist/streams/file-source.d.cts.map +1 -0
  365. package/dist/streams/file-source.d.ts +96 -0
  366. package/dist/streams/file-source.d.ts.map +1 -0
  367. package/dist/streams/file-source.js +286 -0
  368. package/dist/streams/file-source.js.map +1 -0
  369. package/dist/streams/hash.cjs +207 -115
  370. package/dist/streams/hash.cjs.map +1 -1
  371. package/dist/streams/hash.d.cts +5 -4
  372. package/dist/streams/hash.d.cts.map +1 -1
  373. package/dist/streams/hash.d.ts +5 -4
  374. package/dist/streams/hash.d.ts.map +1 -1
  375. package/dist/streams/hash.js +208 -95
  376. package/dist/streams/hash.js.map +1 -1
  377. package/dist/streams/index.cjs +12 -12
  378. package/dist/streams/index.d.cts +3 -3
  379. package/dist/streams/index.d.cts.map +1 -1
  380. package/dist/streams/index.d.ts +3 -3
  381. package/dist/streams/index.d.ts.map +1 -1
  382. package/dist/streams/index.js +3 -11
  383. package/dist/streams/progress.cjs +60 -46
  384. package/dist/streams/progress.cjs.map +1 -1
  385. package/dist/streams/progress.js +60 -46
  386. package/dist/streams/progress.js.map +1 -1
  387. package/dist/streams/source.cjs +317 -146
  388. package/dist/streams/source.cjs.map +1 -1
  389. package/dist/streams/source.d.cts +56 -18
  390. package/dist/streams/source.d.cts.map +1 -1
  391. package/dist/streams/source.d.ts +56 -18
  392. package/dist/streams/source.d.ts.map +1 -1
  393. package/dist/streams/source.js +313 -149
  394. package/dist/streams/source.js.map +1 -1
  395. package/dist/sync/actions/index.cjs +236 -184
  396. package/dist/sync/actions/index.cjs.map +1 -1
  397. package/dist/sync/actions/index.d.cts +29 -21
  398. package/dist/sync/actions/index.d.cts.map +1 -1
  399. package/dist/sync/actions/index.d.ts +29 -21
  400. package/dist/sync/actions/index.d.ts.map +1 -1
  401. package/dist/sync/actions/index.js +236 -190
  402. package/dist/sync/actions/index.js.map +1 -1
  403. package/dist/sync/b2-sha1-reader.cjs +152 -0
  404. package/dist/sync/b2-sha1-reader.cjs.map +1 -0
  405. package/dist/sync/b2-sha1-reader.d.cts +58 -0
  406. package/dist/sync/b2-sha1-reader.d.cts.map +1 -0
  407. package/dist/sync/b2-sha1-reader.d.ts +58 -0
  408. package/dist/sync/b2-sha1-reader.d.ts.map +1 -0
  409. package/dist/sync/b2-sha1-reader.js +149 -0
  410. package/dist/sync/b2-sha1-reader.js.map +1 -0
  411. package/dist/sync/download-staging.cjs +266 -0
  412. package/dist/sync/download-staging.cjs.map +1 -0
  413. package/dist/sync/download-staging.d.cts +55 -0
  414. package/dist/sync/download-staging.d.cts.map +1 -0
  415. package/dist/sync/download-staging.d.ts +55 -0
  416. package/dist/sync/download-staging.d.ts.map +1 -0
  417. package/dist/sync/download-staging.js +260 -0
  418. package/dist/sync/download-staging.js.map +1 -0
  419. package/dist/sync/filesystem-errors.cjs +32 -0
  420. package/dist/sync/filesystem-errors.cjs.map +1 -0
  421. package/dist/sync/filesystem-errors.d.cts +8 -0
  422. package/dist/sync/filesystem-errors.d.cts.map +1 -0
  423. package/dist/sync/filesystem-errors.d.ts +8 -0
  424. package/dist/sync/filesystem-errors.d.ts.map +1 -0
  425. package/dist/sync/filesystem-errors.js +32 -0
  426. package/dist/sync/filesystem-errors.js.map +1 -0
  427. package/dist/sync/filters.cjs +217 -0
  428. package/dist/sync/filters.cjs.map +1 -0
  429. package/dist/sync/filters.d.cts +51 -0
  430. package/dist/sync/filters.d.cts.map +1 -0
  431. package/dist/sync/filters.d.ts +51 -0
  432. package/dist/sync/filters.d.ts.map +1 -0
  433. package/dist/sync/filters.js +213 -0
  434. package/dist/sync/filters.js.map +1 -0
  435. package/dist/sync/index.cjs +39 -22
  436. package/dist/sync/index.d.cts +14 -9
  437. package/dist/sync/index.d.cts.map +1 -1
  438. package/dist/sync/index.d.ts +14 -9
  439. package/dist/sync/index.d.ts.map +1 -1
  440. package/dist/sync/index.js +9 -20
  441. package/dist/sync/local-file-identity.cjs +61 -0
  442. package/dist/sync/local-file-identity.cjs.map +1 -0
  443. package/dist/sync/local-file-identity.d.cts +37 -0
  444. package/dist/sync/local-file-identity.d.cts.map +1 -0
  445. package/dist/sync/local-file-identity.d.ts +37 -0
  446. package/dist/sync/local-file-identity.d.ts.map +1 -0
  447. package/dist/sync/local-file-identity.js +60 -0
  448. package/dist/sync/local-file-identity.js.map +1 -0
  449. package/dist/sync/local-file-io.cjs +369 -0
  450. package/dist/sync/local-file-io.cjs.map +1 -0
  451. package/dist/sync/local-file-io.d.cts +76 -0
  452. package/dist/sync/local-file-io.d.cts.map +1 -0
  453. package/dist/sync/local-file-io.d.ts +76 -0
  454. package/dist/sync/local-file-io.d.ts.map +1 -0
  455. package/dist/sync/local-file-io.js +365 -0
  456. package/dist/sync/local-file-io.js.map +1 -0
  457. package/dist/sync/local-filesystem-root.cjs +27 -0
  458. package/dist/sync/local-filesystem-root.cjs.map +1 -0
  459. package/dist/sync/local-filesystem-root.d.cts +18 -0
  460. package/dist/sync/local-filesystem-root.d.cts.map +1 -0
  461. package/dist/sync/local-filesystem-root.d.ts +18 -0
  462. package/dist/sync/local-filesystem-root.d.ts.map +1 -0
  463. package/dist/sync/local-filesystem-root.js +26 -0
  464. package/dist/sync/local-filesystem-root.js.map +1 -0
  465. package/dist/sync/local-sha1.cjs +110 -0
  466. package/dist/sync/local-sha1.cjs.map +1 -0
  467. package/dist/sync/local-sha1.d.cts +31 -0
  468. package/dist/sync/local-sha1.d.cts.map +1 -0
  469. package/dist/sync/local-sha1.d.ts +31 -0
  470. package/dist/sync/local-sha1.d.ts.map +1 -0
  471. package/dist/sync/local-sha1.js +109 -0
  472. package/dist/sync/local-sha1.js.map +1 -0
  473. package/dist/sync/pairing.cjs +118 -29
  474. package/dist/sync/pairing.cjs.map +1 -1
  475. package/dist/sync/pairing.d.cts +7 -2
  476. package/dist/sync/pairing.d.cts.map +1 -1
  477. package/dist/sync/pairing.d.ts +7 -2
  478. package/dist/sync/pairing.d.ts.map +1 -1
  479. package/dist/sync/pairing.js +120 -31
  480. package/dist/sync/pairing.js.map +1 -1
  481. package/dist/sync/path-order.cjs +30 -0
  482. package/dist/sync/path-order.cjs.map +1 -0
  483. package/dist/sync/path-order.d.cts +28 -0
  484. package/dist/sync/path-order.d.cts.map +1 -0
  485. package/dist/sync/path-order.d.ts +28 -0
  486. package/dist/sync/path-order.d.ts.map +1 -0
  487. package/dist/sync/path-order.js +29 -0
  488. package/dist/sync/path-order.js.map +1 -0
  489. package/dist/sync/path-safety.cjs +111 -0
  490. package/dist/sync/path-safety.cjs.map +1 -0
  491. package/dist/sync/path-safety.d.cts +78 -0
  492. package/dist/sync/path-safety.d.cts.map +1 -0
  493. package/dist/sync/path-safety.d.ts +78 -0
  494. package/dist/sync/path-safety.d.ts.map +1 -0
  495. package/dist/sync/path-safety.js +105 -0
  496. package/dist/sync/path-safety.js.map +1 -0
  497. package/dist/sync/paths.d.cts +19 -0
  498. package/dist/sync/paths.d.cts.map +1 -0
  499. package/dist/sync/paths.d.ts +19 -0
  500. package/dist/sync/paths.d.ts.map +1 -0
  501. package/dist/sync/policies/compare.cjs +391 -11
  502. package/dist/sync/policies/compare.cjs.map +1 -1
  503. package/dist/sync/policies/compare.d.cts +100 -2
  504. package/dist/sync/policies/compare.d.cts.map +1 -1
  505. package/dist/sync/policies/compare.d.ts +100 -2
  506. package/dist/sync/policies/compare.d.ts.map +1 -1
  507. package/dist/sync/policies/compare.js +389 -13
  508. package/dist/sync/policies/compare.js.map +1 -1
  509. package/dist/sync/policies/index.cjs +70 -65
  510. package/dist/sync/policies/index.cjs.map +1 -1
  511. package/dist/sync/policies/index.d.cts +35 -6
  512. package/dist/sync/policies/index.d.cts.map +1 -1
  513. package/dist/sync/policies/index.d.ts +35 -6
  514. package/dist/sync/policies/index.d.ts.map +1 -1
  515. package/dist/sync/policies/index.js +70 -65
  516. package/dist/sync/policies/index.js.map +1 -1
  517. package/dist/sync/prefix.cjs +96 -0
  518. package/dist/sync/prefix.cjs.map +1 -0
  519. package/dist/sync/prefix.d.cts +55 -0
  520. package/dist/sync/prefix.d.cts.map +1 -0
  521. package/dist/sync/prefix.d.ts +55 -0
  522. package/dist/sync/prefix.d.ts.map +1 -0
  523. package/dist/sync/prefix.js +92 -0
  524. package/dist/sync/prefix.js.map +1 -0
  525. package/dist/sync/regexp-safety.cjs +192 -0
  526. package/dist/sync/regexp-safety.cjs.map +1 -0
  527. package/dist/sync/regexp-safety.d.cts +29 -0
  528. package/dist/sync/regexp-safety.d.cts.map +1 -0
  529. package/dist/sync/regexp-safety.d.ts +29 -0
  530. package/dist/sync/regexp-safety.d.ts.map +1 -0
  531. package/dist/sync/regexp-safety.js +190 -0
  532. package/dist/sync/regexp-safety.js.map +1 -0
  533. package/dist/sync/scan-events.cjs +33 -0
  534. package/dist/sync/scan-events.cjs.map +1 -0
  535. package/dist/sync/scan-events.d.cts +17 -0
  536. package/dist/sync/scan-events.d.cts.map +1 -0
  537. package/dist/sync/scan-events.d.ts +17 -0
  538. package/dist/sync/scan-events.d.ts.map +1 -0
  539. package/dist/sync/scan-events.js +32 -0
  540. package/dist/sync/scan-events.js.map +1 -0
  541. package/dist/sync/scan-limit.cjs +33 -0
  542. package/dist/sync/scan-limit.cjs.map +1 -0
  543. package/dist/sync/scan-limit.d.cts +21 -0
  544. package/dist/sync/scan-limit.d.cts.map +1 -0
  545. package/dist/sync/scan-limit.d.ts +21 -0
  546. package/dist/sync/scan-limit.d.ts.map +1 -0
  547. package/dist/sync/scan-limit.js +31 -0
  548. package/dist/sync/scan-limit.js.map +1 -0
  549. package/dist/sync/scanners/b2.cjs +239 -55
  550. package/dist/sync/scanners/b2.cjs.map +1 -1
  551. package/dist/sync/scanners/b2.d.cts +26 -7
  552. package/dist/sync/scanners/b2.d.cts.map +1 -1
  553. package/dist/sync/scanners/b2.d.ts +26 -7
  554. package/dist/sync/scanners/b2.d.ts.map +1 -1
  555. package/dist/sync/scanners/b2.js +239 -55
  556. package/dist/sync/scanners/b2.js.map +1 -1
  557. package/dist/sync/scanners/local.cjs +215 -56
  558. package/dist/sync/scanners/local.cjs.map +1 -1
  559. package/dist/sync/scanners/local.d.cts +22 -7
  560. package/dist/sync/scanners/local.d.cts.map +1 -1
  561. package/dist/sync/scanners/local.d.ts +22 -7
  562. package/dist/sync/scanners/local.d.ts.map +1 -1
  563. package/dist/sync/scanners/local.js +216 -57
  564. package/dist/sync/scanners/local.js.map +1 -1
  565. package/dist/sync/sha1-metadata.cjs +94 -0
  566. package/dist/sync/sha1-metadata.cjs.map +1 -0
  567. package/dist/sync/sha1-metadata.d.cts +82 -0
  568. package/dist/sync/sha1-metadata.d.cts.map +1 -0
  569. package/dist/sync/sha1-metadata.d.ts +82 -0
  570. package/dist/sync/sha1-metadata.d.ts.map +1 -0
  571. package/dist/sync/sha1-metadata.js +89 -0
  572. package/dist/sync/sha1-metadata.js.map +1 -0
  573. package/dist/sync/sha1-options.cjs +23 -0
  574. package/dist/sync/sha1-options.cjs.map +1 -0
  575. package/dist/sync/sha1-options.d.cts +14 -0
  576. package/dist/sync/sha1-options.d.cts.map +1 -0
  577. package/dist/sync/sha1-options.d.ts +14 -0
  578. package/dist/sync/sha1-options.d.ts.map +1 -0
  579. package/dist/sync/sha1-options.js +21 -0
  580. package/dist/sync/sha1-options.js.map +1 -0
  581. package/dist/sync/synchronizer.cjs +783 -197
  582. package/dist/sync/synchronizer.cjs.map +1 -1
  583. package/dist/sync/synchronizer.d.cts +47 -1
  584. package/dist/sync/synchronizer.d.cts.map +1 -1
  585. package/dist/sync/synchronizer.d.ts +47 -1
  586. package/dist/sync/synchronizer.d.ts.map +1 -1
  587. package/dist/sync/synchronizer.js +780 -173
  588. package/dist/sync/synchronizer.js.map +1 -1
  589. package/dist/sync/types.d.cts +208 -16
  590. package/dist/sync/types.d.cts.map +1 -1
  591. package/dist/sync/types.d.ts +208 -16
  592. package/dist/sync/types.d.ts.map +1 -1
  593. package/dist/types/auth.cjs +80 -56
  594. package/dist/types/auth.cjs.map +1 -1
  595. package/dist/types/auth.d.cts +71 -9
  596. package/dist/types/auth.d.cts.map +1 -1
  597. package/dist/types/auth.d.ts +71 -9
  598. package/dist/types/auth.d.ts.map +1 -1
  599. package/dist/types/auth.js +81 -57
  600. package/dist/types/auth.js.map +1 -1
  601. package/dist/types/backup.d.cts +80 -0
  602. package/dist/types/backup.d.cts.map +1 -0
  603. package/dist/types/backup.d.ts +80 -0
  604. package/dist/types/backup.d.ts.map +1 -0
  605. package/dist/types/bucket.cjs +74 -38
  606. package/dist/types/bucket.cjs.map +1 -1
  607. package/dist/types/bucket.d.cts +4 -2
  608. package/dist/types/bucket.d.cts.map +1 -1
  609. package/dist/types/bucket.d.ts +4 -2
  610. package/dist/types/bucket.d.ts.map +1 -1
  611. package/dist/types/bucket.js +75 -41
  612. package/dist/types/bucket.js.map +1 -1
  613. package/dist/types/download.cjs +62 -0
  614. package/dist/types/download.cjs.map +1 -0
  615. package/dist/types/download.d.cts +98 -0
  616. package/dist/types/download.d.cts.map +1 -1
  617. package/dist/types/download.d.ts +98 -0
  618. package/dist/types/download.d.ts.map +1 -1
  619. package/dist/types/download.js +61 -0
  620. package/dist/types/download.js.map +1 -0
  621. package/dist/types/encryption.cjs +194 -328
  622. package/dist/types/encryption.cjs.map +1 -1
  623. package/dist/types/encryption.d.cts +48 -0
  624. package/dist/types/encryption.d.cts.map +1 -1
  625. package/dist/types/encryption.d.ts +48 -0
  626. package/dist/types/encryption.d.ts.map +1 -1
  627. package/dist/types/encryption.js +192 -311
  628. package/dist/types/encryption.js.map +1 -1
  629. package/dist/types/errors.cjs +56 -0
  630. package/dist/types/errors.cjs.map +1 -0
  631. package/dist/types/errors.d.cts +13 -4
  632. package/dist/types/errors.d.cts.map +1 -1
  633. package/dist/types/errors.d.ts +13 -4
  634. package/dist/types/errors.d.ts.map +1 -1
  635. package/dist/types/errors.js +56 -0
  636. package/dist/types/errors.js.map +1 -0
  637. package/dist/types/file.cjs +36 -19
  638. package/dist/types/file.cjs.map +1 -1
  639. package/dist/types/file.d.cts +17 -4
  640. package/dist/types/file.d.cts.map +1 -1
  641. package/dist/types/file.d.ts +17 -4
  642. package/dist/types/file.d.ts.map +1 -1
  643. package/dist/types/file.js +37 -21
  644. package/dist/types/file.js.map +1 -1
  645. package/dist/types/ids.cjs +83 -9
  646. package/dist/types/ids.cjs.map +1 -1
  647. package/dist/types/ids.d.cts +32 -0
  648. package/dist/types/ids.d.cts.map +1 -1
  649. package/dist/types/ids.d.ts +32 -0
  650. package/dist/types/ids.d.ts.map +1 -1
  651. package/dist/types/ids.js +82 -16
  652. package/dist/types/ids.js.map +1 -1
  653. package/dist/types/index.d.cts +18 -13
  654. package/dist/types/index.d.cts.map +1 -1
  655. package/dist/types/index.d.ts +18 -13
  656. package/dist/types/index.d.ts.map +1 -1
  657. package/dist/types/key.d.cts +44 -8
  658. package/dist/types/key.d.cts.map +1 -1
  659. package/dist/types/key.d.ts +44 -8
  660. package/dist/types/key.d.ts.map +1 -1
  661. package/dist/types/lock.cjs +33 -13
  662. package/dist/types/lock.cjs.map +1 -1
  663. package/dist/types/lock.d.cts +14 -0
  664. package/dist/types/lock.d.cts.map +1 -1
  665. package/dist/types/lock.d.ts +14 -0
  666. package/dist/types/lock.d.ts.map +1 -1
  667. package/dist/types/lock.js +34 -15
  668. package/dist/types/lock.js.map +1 -1
  669. package/dist/types/notifications.cjs +44 -22
  670. package/dist/types/notifications.cjs.map +1 -1
  671. package/dist/types/notifications.d.cts +5 -3
  672. package/dist/types/notifications.d.cts.map +1 -1
  673. package/dist/types/notifications.d.ts +5 -3
  674. package/dist/types/notifications.d.ts.map +1 -1
  675. package/dist/types/notifications.js +45 -23
  676. package/dist/types/notifications.js.map +1 -1
  677. package/dist/types/partner.cjs +32 -0
  678. package/dist/types/partner.cjs.map +1 -0
  679. package/dist/types/partner.d.cts +394 -0
  680. package/dist/types/partner.d.cts.map +1 -0
  681. package/dist/types/partner.d.ts +394 -0
  682. package/dist/types/partner.d.ts.map +1 -0
  683. package/dist/types/partner.js +29 -0
  684. package/dist/types/partner.js.map +1 -0
  685. package/dist/types/upload.d.cts +53 -6
  686. package/dist/types/upload.d.cts.map +1 -1
  687. package/dist/types/upload.d.ts +53 -6
  688. package/dist/types/upload.d.ts.map +1 -1
  689. package/dist/upload/abort-scope.cjs +46 -0
  690. package/dist/upload/abort-scope.cjs.map +1 -0
  691. package/dist/upload/abort-scope.d.cts +26 -0
  692. package/dist/upload/abort-scope.d.cts.map +1 -0
  693. package/dist/upload/abort-scope.d.ts +26 -0
  694. package/dist/upload/abort-scope.d.ts.map +1 -0
  695. package/dist/upload/abort-scope.js +45 -0
  696. package/dist/upload/abort-scope.js.map +1 -0
  697. package/dist/upload/cancel.cjs +183 -8
  698. package/dist/upload/cancel.cjs.map +1 -1
  699. package/dist/upload/cancel.d.cts +110 -2
  700. package/dist/upload/cancel.d.cts.map +1 -1
  701. package/dist/upload/cancel.d.ts +110 -2
  702. package/dist/upload/cancel.d.ts.map +1 -1
  703. package/dist/upload/cancel.js +178 -9
  704. package/dist/upload/cancel.js.map +1 -1
  705. package/dist/upload/concurrency.cjs +79 -52
  706. package/dist/upload/concurrency.cjs.map +1 -1
  707. package/dist/upload/concurrency.js +79 -53
  708. package/dist/upload/concurrency.js.map +1 -1
  709. package/dist/upload/finish.cjs +54 -0
  710. package/dist/upload/finish.cjs.map +1 -0
  711. package/dist/upload/finish.d.cts +26 -0
  712. package/dist/upload/finish.d.cts.map +1 -0
  713. package/dist/upload/finish.d.ts +26 -0
  714. package/dist/upload/finish.d.ts.map +1 -0
  715. package/dist/upload/finish.js +54 -0
  716. package/dist/upload/finish.js.map +1 -0
  717. package/dist/upload/large.cjs +305 -218
  718. package/dist/upload/large.cjs.map +1 -1
  719. package/dist/upload/large.d.cts +90 -9
  720. package/dist/upload/large.d.cts.map +1 -1
  721. package/dist/upload/large.d.ts +90 -9
  722. package/dist/upload/large.d.ts.map +1 -1
  723. package/dist/upload/large.js +305 -218
  724. package/dist/upload/large.js.map +1 -1
  725. package/dist/upload/options.cjs +28 -0
  726. package/dist/upload/options.cjs.map +1 -0
  727. package/dist/upload/options.d.cts +116 -0
  728. package/dist/upload/options.d.cts.map +1 -0
  729. package/dist/upload/options.d.ts +116 -0
  730. package/dist/upload/options.d.ts.map +1 -0
  731. package/dist/upload/options.js +27 -0
  732. package/dist/upload/options.js.map +1 -0
  733. package/dist/upload/resume.cjs +334 -33
  734. package/dist/upload/resume.cjs.map +1 -1
  735. package/dist/upload/resume.d.cts +84 -12
  736. package/dist/upload/resume.d.cts.map +1 -1
  737. package/dist/upload/resume.d.ts +84 -12
  738. package/dist/upload/resume.d.ts.map +1 -1
  739. package/dist/upload/resume.js +331 -33
  740. package/dist/upload/resume.js.map +1 -1
  741. package/dist/upload/retry.cjs +191 -0
  742. package/dist/upload/retry.cjs.map +1 -0
  743. package/dist/upload/retry.d.cts +127 -0
  744. package/dist/upload/retry.d.cts.map +1 -0
  745. package/dist/upload/retry.d.ts +127 -0
  746. package/dist/upload/retry.d.ts.map +1 -0
  747. package/dist/upload/retry.js +187 -0
  748. package/dist/upload/retry.js.map +1 -0
  749. package/dist/upload/single.cjs +69 -44
  750. package/dist/upload/single.cjs.map +1 -1
  751. package/dist/upload/single.d.cts +8 -1
  752. package/dist/upload/single.d.cts.map +1 -1
  753. package/dist/upload/single.d.ts +8 -1
  754. package/dist/upload/single.d.ts.map +1 -1
  755. package/dist/upload/single.js +69 -44
  756. package/dist/upload/single.js.map +1 -1
  757. package/dist/upload/stream.cjs +319 -193
  758. package/dist/upload/stream.cjs.map +1 -1
  759. package/dist/upload/stream.d.cts +9 -1
  760. package/dist/upload/stream.d.cts.map +1 -1
  761. package/dist/upload/stream.d.ts +9 -1
  762. package/dist/upload/stream.d.ts.map +1 -1
  763. package/dist/upload/stream.js +318 -192
  764. package/dist/upload/stream.js.map +1 -1
  765. package/dist/util/abort.cjs +114 -0
  766. package/dist/util/abort.cjs.map +1 -0
  767. package/dist/util/abort.d.cts +65 -0
  768. package/dist/util/abort.d.cts.map +1 -0
  769. package/dist/util/abort.d.ts +65 -0
  770. package/dist/util/abort.d.ts.map +1 -0
  771. package/dist/util/abort.js +109 -0
  772. package/dist/util/abort.js.map +1 -0
  773. package/dist/util/best-effort.cjs +42 -8
  774. package/dist/util/best-effort.cjs.map +1 -1
  775. package/dist/util/best-effort.d.cts +2 -1
  776. package/dist/util/best-effort.d.cts.map +1 -1
  777. package/dist/util/best-effort.d.ts +2 -1
  778. package/dist/util/best-effort.d.ts.map +1 -1
  779. package/dist/util/best-effort.js +43 -9
  780. package/dist/util/best-effort.js.map +1 -1
  781. package/dist/util/bytes.cjs +23 -0
  782. package/dist/util/bytes.cjs.map +1 -0
  783. package/dist/util/bytes.d.cts +15 -0
  784. package/dist/util/bytes.d.cts.map +1 -0
  785. package/dist/util/bytes.d.ts +15 -0
  786. package/dist/util/bytes.d.ts.map +1 -0
  787. package/dist/util/bytes.js +23 -0
  788. package/dist/util/bytes.js.map +1 -0
  789. package/dist/util/crypto.cjs +68 -0
  790. package/dist/util/crypto.cjs.map +1 -0
  791. package/dist/util/crypto.d.cts +26 -0
  792. package/dist/util/crypto.d.cts.map +1 -0
  793. package/dist/util/crypto.d.ts +26 -0
  794. package/dist/util/crypto.d.ts.map +1 -0
  795. package/dist/util/crypto.js +66 -0
  796. package/dist/util/crypto.js.map +1 -0
  797. package/dist/util/defaults.cjs +28 -9
  798. package/dist/util/defaults.cjs.map +1 -1
  799. package/dist/util/defaults.d.cts +2 -0
  800. package/dist/util/defaults.d.cts.map +1 -1
  801. package/dist/util/defaults.d.ts +2 -0
  802. package/dist/util/defaults.d.ts.map +1 -1
  803. package/dist/util/defaults.js +28 -11
  804. package/dist/util/defaults.js.map +1 -1
  805. package/dist/util/error-reason.cjs +41 -0
  806. package/dist/util/error-reason.cjs.map +1 -0
  807. package/dist/util/error-reason.d.cts +9 -0
  808. package/dist/util/error-reason.d.cts.map +1 -0
  809. package/dist/util/error-reason.d.ts +9 -0
  810. package/dist/util/error-reason.d.ts.map +1 -0
  811. package/dist/util/error-reason.js +41 -0
  812. package/dist/util/error-reason.js.map +1 -0
  813. package/dist/util/http.cjs +23 -0
  814. package/dist/util/http.cjs.map +1 -0
  815. package/dist/util/http.d.cts +13 -0
  816. package/dist/util/http.d.cts.map +1 -0
  817. package/dist/util/http.d.ts +13 -0
  818. package/dist/util/http.d.ts.map +1 -0
  819. package/dist/util/http.js +23 -0
  820. package/dist/util/http.js.map +1 -0
  821. package/dist/util/md5.cjs +211 -0
  822. package/dist/util/md5.cjs.map +1 -0
  823. package/dist/util/md5.d.cts +43 -0
  824. package/dist/util/md5.d.cts.map +1 -0
  825. package/dist/util/md5.d.ts +43 -0
  826. package/dist/util/md5.d.ts.map +1 -0
  827. package/dist/util/md5.js +209 -0
  828. package/dist/util/md5.js.map +1 -0
  829. package/dist/util/normalize.cjs +66 -7
  830. package/dist/util/normalize.cjs.map +1 -1
  831. package/dist/util/normalize.d.cts +7 -7
  832. package/dist/util/normalize.d.cts.map +1 -1
  833. package/dist/util/normalize.d.ts +7 -7
  834. package/dist/util/normalize.d.ts.map +1 -1
  835. package/dist/util/normalize.js +67 -10
  836. package/dist/util/normalize.js.map +1 -1
  837. package/dist/util/paginator.cjs +69 -14
  838. package/dist/util/paginator.cjs.map +1 -1
  839. package/dist/util/paginator.d.cts +3 -1
  840. package/dist/util/paginator.d.cts.map +1 -1
  841. package/dist/util/paginator.d.ts +3 -1
  842. package/dist/util/paginator.d.ts.map +1 -1
  843. package/dist/util/paginator.js +70 -16
  844. package/dist/util/paginator.js.map +1 -1
  845. package/dist/util/plan-ranges.cjs +47 -22
  846. package/dist/util/plan-ranges.cjs.map +1 -1
  847. package/dist/util/plan-ranges.js +48 -24
  848. package/dist/util/plan-ranges.js.map +1 -1
  849. package/dist/util/sha1.cjs +27 -0
  850. package/dist/util/sha1.cjs.map +1 -0
  851. package/dist/util/sha1.d.cts +17 -0
  852. package/dist/util/sha1.d.cts.map +1 -0
  853. package/dist/util/sha1.d.ts +17 -0
  854. package/dist/util/sha1.d.ts.map +1 -0
  855. package/dist/util/sha1.js +26 -0
  856. package/dist/util/sha1.js.map +1 -0
  857. package/dist/util/text-codec.cjs +29 -5
  858. package/dist/util/text-codec.cjs.map +1 -1
  859. package/dist/util/text-codec.js +30 -7
  860. package/dist/util/text-codec.js.map +1 -1
  861. package/dist/util/to-error.cjs +18 -4
  862. package/dist/util/to-error.cjs.map +1 -1
  863. package/dist/util/to-error.js +19 -5
  864. package/dist/util/to-error.js.map +1 -1
  865. package/dist/version.cjs +17 -5
  866. package/dist/version.cjs.map +1 -1
  867. package/dist/version.d.cts +3 -3
  868. package/dist/version.d.ts +3 -3
  869. package/dist/version.js +19 -6
  870. package/dist/version.js.map +1 -1
  871. package/package.json +45 -20
  872. package/dist/auth/index.cjs.map +0 -1
  873. package/dist/auth/index.js.map +0 -1
  874. package/dist/index.cjs.map +0 -1
  875. package/dist/index.js.map +0 -1
  876. package/dist/notifications/index.cjs.map +0 -1
  877. package/dist/notifications/index.js.map +0 -1
  878. package/dist/package.json.cjs +0 -9
  879. package/dist/package.json.cjs.map +0 -1
  880. package/dist/package.json.js +0 -9
  881. package/dist/package.json.js.map +0 -1
  882. package/dist/streams/index.cjs.map +0 -1
  883. package/dist/streams/index.js.map +0 -1
  884. package/dist/sync/index.cjs.map +0 -1
  885. package/dist/sync/index.js.map +0 -1
@@ -0,0 +1,369 @@
1
+ const require_error_reason = require("../util/error-reason.cjs");
2
+ const require_local_file_identity = require("./local-file-identity.cjs");
3
+ const require_path_safety = require("./path-safety.cjs");
4
+ const require_download_staging = require("./download-staging.cjs");
5
+ const require_b2_sha1_reader = require("./b2-sha1-reader.cjs");
6
+ //#region src/sync/local-file-io.ts
7
+ /** @internal */
8
+ var localFileIoTestHooks = {};
9
+ /**
10
+ * Verifies that a previously scanned local file still points at the same regular file.
11
+ *
12
+ * @param path - Scanned local path and file identity.
13
+ *
14
+ * @internal
15
+ */
16
+ async function validateScannedLocalFile(path) {
17
+ await (await openValidatedScannedLocalFile(path)).close();
18
+ }
19
+ async function openValidatedScannedLocalFile(path) {
20
+ const { constants } = await import("node:fs");
21
+ const { open } = await import("node:fs/promises");
22
+ const flags = constants.O_RDONLY | require_path_safety.noFollowFlag(constants) | (constants.O_NONBLOCK ?? 0);
23
+ const handle = await open(path.absolutePath, flags).catch((err) => {
24
+ if (require_path_safety.hasErrorCode(err, "ELOOP")) throw new Error("local file changed before upload: not a regular file");
25
+ throw new Error(`local file changed before upload: could not open scanned file: ${require_error_reason.sanitizeErrorReason(err)}`);
26
+ });
27
+ try {
28
+ const stats = await handle.stat();
29
+ require_local_file_identity.assertSameScannedRegularFile(stats, path, "upload", { platform: localFileIoTestHooks.platform });
30
+ return handle;
31
+ } catch (err) {
32
+ await handle.close().catch(() => {});
33
+ throw err;
34
+ }
35
+ }
36
+ /**
37
+ * Streams a B2 download under a local sync root with path, timeout, and size checks.
38
+ *
39
+ * @param root - Local sync root.
40
+ * @param relPath - Destination path relative to the root.
41
+ * @param body - Download body stream.
42
+ * @param options - Expected byte count, idle timeout, and optional abort signal.
43
+ *
44
+ * @internal
45
+ */
46
+ async function writeLocalStreamInsideRoot(root, relPath, body, options) {
47
+ const { constants } = await import("node:fs");
48
+ const { link, lstat, mkdir, open, realpath, rename, rm, stat } = await import("node:fs/promises");
49
+ const path = await import("node:path");
50
+ const { randomUUID } = await import("node:crypto");
51
+ assertValidExpectedBytes(options.expectedBytes);
52
+ const segments = require_path_safety.safeRelativePathSegments(relPath);
53
+ if (require_download_staging.isDownloadStagingDirectorySegment(segments[0])) throw new Error(`unsafe local destination path: ${require_download_staging.DOWNLOAD_STAGING_DIRECTORY_NAME} is reserved for SDK download staging`);
54
+ const rootRealPath = await realpath(root);
55
+ let current = rootRealPath;
56
+ for (const segment of segments.slice(0, -1)) {
57
+ current = path.join(current, segment);
58
+ try {
59
+ await mkdir(current);
60
+ } catch (err) {
61
+ if (!require_path_safety.hasErrorCode(err, "EEXIST")) throw err;
62
+ }
63
+ if (!(await lstat(current)).isDirectory()) throw new Error("unsafe local destination path: parent is not a directory");
64
+ await localFileIoTestHooks.afterParentDirectoryValidated?.(current);
65
+ }
66
+ const destPath = path.join(rootRealPath, ...segments);
67
+ require_path_safety.assertPathInsideRoot(rootRealPath, destPath, path);
68
+ const parentRealPath = await realpath(path.dirname(destPath));
69
+ const finalPath = path.join(parentRealPath, path.basename(destPath));
70
+ require_path_safety.assertPathInsideRoot(rootRealPath, finalPath, path);
71
+ try {
72
+ const targetStats = await lstat(finalPath);
73
+ if (targetStats.isSymbolicLink()) throw new Error("unsafe local destination path: target is a symbolic link");
74
+ if (targetStats.isFile() && targetStats.nlink > 1) throw new Error("unsafe local destination path: target has multiple hard links");
75
+ } catch (err) {
76
+ if (!require_path_safety.hasErrorCode(err, "ENOENT")) throw err;
77
+ }
78
+ const statForDeviceCheck = localFileIoTestHooks.statForDeviceCheck ?? stat;
79
+ await require_download_staging.assertDownloadPathSameDevice(rootRealPath, parentRealPath, statForDeviceCheck, "unsafe local destination path: cannot publish download across filesystems");
80
+ let parentHandle;
81
+ let anchoredParentPath;
82
+ /* v8 ignore start -- Linux-only fd-relative path support is covered by Linux CI */
83
+ if (globalThis.process?.platform === "linux" && constants.O_DIRECTORY !== void 0 && localFileIoTestHooks.disableProcFdAnchoring !== true) try {
84
+ parentHandle = await open(parentRealPath, constants.O_RDONLY | constants.O_DIRECTORY | require_path_safety.noFollowFlag(constants));
85
+ anchoredParentPath = `/proc/self/fd/${parentHandle.fd}`;
86
+ } catch (err) {
87
+ if (require_path_safety.hasErrorCode(err, "ELOOP") || require_path_safety.hasErrorCode(err, "ENOTDIR")) throw new Error("unsafe local destination path: parent is not a directory");
88
+ throw err;
89
+ }
90
+ /* v8 ignore stop */
91
+ const finalName = path.basename(destPath);
92
+ const finalWritePath = path.join(anchoredParentPath ?? parentRealPath, finalName);
93
+ let publishMode;
94
+ try {
95
+ publishMode = await replacementFileMode(finalPath);
96
+ } catch (err) {
97
+ /* v8 ignore next -- best-effort close during setup failure */
98
+ await parentHandle?.close().catch(() => {});
99
+ throw err;
100
+ }
101
+ let stagingDirectory;
102
+ try {
103
+ stagingDirectory = await require_download_staging.createDownloadStagingDirectory(rootRealPath, path, randomUUID, statForDeviceCheck, localFileIoTestHooks.beforeStagingMarkerWrite, localFileIoTestHooks.downloadStagingActivityEntryLimit);
104
+ } catch (err) {
105
+ /* v8 ignore next -- best-effort close during setup failure */
106
+ await parentHandle?.close().catch(() => {});
107
+ throw err;
108
+ }
109
+ const tmpPath = path.join(stagingDirectory, `.b2sdk-${randomUUID()}.partial`);
110
+ let handle;
111
+ try {
112
+ handle = await open(tmpPath, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | require_path_safety.noFollowFlag(constants), PRIVATE_DOWNLOAD_FILE_MODE);
113
+ /* v8 ignore next -- best-effort chmod */
114
+ await handle.chmod(PRIVATE_DOWNLOAD_FILE_MODE).catch(() => {});
115
+ await localFileIoTestHooks.afterTempFileCreated?.(tmpPath, stagingDirectory);
116
+ } catch (err) {
117
+ await parentHandle?.close().catch(() => {});
118
+ await rm(stagingDirectory, {
119
+ recursive: true,
120
+ force: true
121
+ }).catch(() => {});
122
+ throw err;
123
+ }
124
+ /* v8 ignore stop */
125
+ try {
126
+ const tmpRealPath = await realpath(tmpPath);
127
+ require_path_safety.assertPathInsideRoot(stagingDirectory, tmpRealPath, path);
128
+ } catch (err) {
129
+ /* v8 ignore next -- best-effort cleanup */
130
+ await handle?.close().catch(() => {});
131
+ /* v8 ignore next -- best-effort cleanup */
132
+ await rm(tmpPath, { force: true }).catch(() => {});
133
+ /* v8 ignore next -- best-effort cleanup */
134
+ await rm(stagingDirectory, {
135
+ recursive: true,
136
+ force: true
137
+ }).catch(() => {});
138
+ /* v8 ignore next -- best-effort cleanup */
139
+ await parentHandle?.close().catch(() => {});
140
+ throw err;
141
+ }
142
+ const writeHandle = handle;
143
+ const reader = body.getReader();
144
+ let completed = false;
145
+ try {
146
+ let bytesWritten = 0;
147
+ while (true) {
148
+ const { done, value } = await require_b2_sha1_reader.readStreamChunkWithTimeout(reader, options.idleTimeoutMillis, `download read stalled for ${options.idleTimeoutMillis} ms`, options.signal);
149
+ if (done) break;
150
+ if (bytesWritten + value.byteLength > options.expectedBytes) throw new Error(`download read exceeded ${options.expectedBytes} byte limit`);
151
+ await writeAll(writeHandle, value, bytesWritten);
152
+ bytesWritten += value.byteLength;
153
+ }
154
+ if (bytesWritten !== options.expectedBytes) throw new Error(`download read ended after ${bytesWritten} bytes, expected ${options.expectedBytes}`);
155
+ if (publishMode !== PRIVATE_DOWNLOAD_FILE_MODE)
156
+ /* v8 ignore next -- best-effort mode preservation */
157
+ await writeHandle.chmod(publishMode).catch(() => {});
158
+ await writeHandle.close();
159
+ handle = void 0;
160
+ const [parentRealPathBeforeRename, parentStatsBeforeRename] = await Promise.all([realpath(path.dirname(destPath)), stat(path.dirname(destPath))]);
161
+ const finalPathBeforeRename = path.join(parentRealPathBeforeRename, path.basename(destPath));
162
+ require_path_safety.assertPathInsideRoot(rootRealPath, finalPathBeforeRename, path);
163
+ await localFileIoTestHooks.beforeFinalRename?.(parentRealPathBeforeRename);
164
+ let publishPath = finalWritePath;
165
+ if (anchoredParentPath === void 0) {
166
+ const [parentRealPathAfterHook, parentStatsAfterHook] = await Promise.all([realpath(path.dirname(destPath)), stat(path.dirname(destPath))]);
167
+ if (parentRealPathAfterHook !== parentRealPathBeforeRename || !sameParentIdentity(parentStatsAfterHook, parentStatsBeforeRename)) throw new Error("unsafe local destination path: parent changed before final publish");
168
+ publishPath = path.join(parentRealPathAfterHook, path.basename(destPath));
169
+ require_path_safety.assertPathInsideRoot(rootRealPath, publishPath, path);
170
+ }
171
+ await publishDownload(lstat, link, path, randomUUID, rename, rm, tmpPath, publishPath, options.expectedDestination);
172
+ completed = true;
173
+ } catch (err) {
174
+ /* v8 ignore next -- best-effort cleanup */
175
+ reader.cancel(err).catch(() => {});
176
+ throw err;
177
+ } finally {
178
+ reader.releaseLock();
179
+ if (!completed) {
180
+ /* v8 ignore next -- best-effort cleanup */
181
+ await handle?.close().catch(() => {});
182
+ /* v8 ignore next -- best-effort cleanup */
183
+ await rm(tmpPath, { force: true }).catch(() => {});
184
+ }
185
+ /* v8 ignore next -- best-effort cleanup */
186
+ await rm(stagingDirectory, {
187
+ recursive: true,
188
+ force: true
189
+ }).catch(() => {});
190
+ /* v8 ignore next -- best-effort cleanup */
191
+ await parentHandle?.close().catch(() => {});
192
+ }
193
+ }
194
+ function assertValidExpectedBytes(expectedBytes) {
195
+ if (!Number.isSafeInteger(expectedBytes) || expectedBytes < 0) throw new Error("download expectedBytes must be a non-negative safe integer");
196
+ }
197
+ async function assertExpectedDownloadDestination(lstat, finalPath, expectedDestination) {
198
+ if (expectedDestination === void 0) return;
199
+ try {
200
+ const stats = await lstat(finalPath);
201
+ if (expectedDestination === null) throw new Error("local destination changed before download: file was created");
202
+ require_local_file_identity.assertSameScannedRegularFile(stats, {
203
+ ...expectedDestination,
204
+ absolutePath: finalPath
205
+ }, "download", { platform: localFileIoTestHooks.platform });
206
+ } catch (err) {
207
+ if (require_path_safety.hasErrorCode(err, "ENOENT")) {
208
+ if (expectedDestination === null) return;
209
+ throw new Error("local file changed before download: file missing");
210
+ }
211
+ throw err;
212
+ }
213
+ }
214
+ async function publishDownload(lstat, link, path, randomUUID, rename, rm, tmpPath, publishPath, expectedDestination) {
215
+ await assertExpectedDownloadDestination(lstat, publishPath, expectedDestination);
216
+ await localFileIoTestHooks.beforeDownloadPublish?.(publishPath);
217
+ if (expectedDestination === void 0) {
218
+ await rename(tmpPath, publishPath);
219
+ return;
220
+ }
221
+ if (expectedDestination === null) {
222
+ await linkDownloadNoOverwrite(link, tmpPath, publishPath, "local destination changed before download: file was created");
223
+ /* v8 ignore next -- staging cleanup is best-effort after a guarded publish succeeds. */
224
+ await rm(tmpPath, { force: true }).catch(() => {});
225
+ return;
226
+ }
227
+ const backupPath = path.join(path.dirname(publishPath), require_path_safety.makeReservedSyncTempFileName(path.basename(publishPath), randomUUID()));
228
+ let backupExists = false;
229
+ let removeBackup = false;
230
+ try {
231
+ try {
232
+ await rename(publishPath, backupPath);
233
+ backupExists = true;
234
+ await localFileIoTestHooks.afterDownloadBackupRename?.(backupPath);
235
+ } catch (err) {
236
+ if (require_path_safety.hasErrorCode(err, "ENOENT")) throw new Error("local file changed before download: file missing");
237
+ throw err;
238
+ }
239
+ const backupStats = await lstat(backupPath);
240
+ require_local_file_identity.assertSameScannedRegularFile(backupStats, {
241
+ ...expectedDestination,
242
+ absolutePath: backupPath
243
+ }, "download", {
244
+ compareChangeTime: false,
245
+ platform: localFileIoTestHooks.platform
246
+ });
247
+ await linkDownloadNoOverwrite(link, tmpPath, publishPath, "local destination changed before download: file was created");
248
+ removeBackup = true;
249
+ /* v8 ignore next -- staging cleanup is best-effort after a guarded publish succeeds. */
250
+ await rm(tmpPath, { force: true }).catch(() => {});
251
+ } catch (err) {
252
+ if (backupExists && !removeBackup) await restoreBackupWithoutOverwrite(link, rm, backupPath, publishPath).catch(() => {});
253
+ throw err;
254
+ } finally {
255
+ if (removeBackup)
256
+ /* v8 ignore next -- old destination cleanup is best-effort after publish succeeds. */
257
+ await rm(backupPath, { force: true }).catch(() => {});
258
+ }
259
+ }
260
+ async function linkDownloadNoOverwrite(link, sourcePath, destPath, message) {
261
+ try {
262
+ await link(sourcePath, destPath);
263
+ } catch (err) {
264
+ if (require_path_safety.hasErrorCode(err, "EEXIST")) throw new Error(message);
265
+ throw err;
266
+ }
267
+ }
268
+ async function restoreBackupWithoutOverwrite(link, rm, backupPath, publishPath) {
269
+ try {
270
+ await link(backupPath, publishPath);
271
+ await rm(backupPath, { force: true });
272
+ } catch (err) {
273
+ if (require_path_safety.hasErrorCode(err, "EEXIST")) return;
274
+ throw err;
275
+ }
276
+ }
277
+ var PRIVATE_DOWNLOAD_FILE_MODE = 384;
278
+ async function replacementFileMode(filePath) {
279
+ const { lstat } = await import("node:fs/promises");
280
+ try {
281
+ const stats = await lstat(filePath);
282
+ return stats.isFile() ? stats.mode & 511 : PRIVATE_DOWNLOAD_FILE_MODE;
283
+ } catch (err) {
284
+ if (require_path_safety.hasErrorCode(err, "ENOENT")) return PRIVATE_DOWNLOAD_FILE_MODE;
285
+ throw err;
286
+ }
287
+ }
288
+ /**
289
+ * Deletes a scanned local file under a sync root without re-resolving attacker-controlled parents.
290
+ *
291
+ * @param root - Local sync root.
292
+ * @param scannedPath - Previously scanned local file metadata.
293
+ *
294
+ * @internal
295
+ */
296
+ async function deleteLocalFileInsideRoot(root, scannedPath) {
297
+ if (root === "") throw new Error("Local sync root required for filesystem mutation");
298
+ const { constants } = await import("node:fs");
299
+ const { lstat, open, realpath, stat, unlink } = await import("node:fs/promises");
300
+ const path = await import("node:path");
301
+ const segments = require_path_safety.safeRelativePathSegments(scannedPath.relativePath);
302
+ const safeRoot = path.resolve(root);
303
+ const rootStats = await lstat(safeRoot);
304
+ if (rootStats.isSymbolicLink()) throw new Error(`Refusing to access sync root through symlink: ${scannedPath.relativePath}`);
305
+ if (!rootStats.isDirectory()) throw new Error(`Local sync root is not a directory: ${scannedPath.relativePath}`);
306
+ const rootRealPath = await realpath(safeRoot);
307
+ const expectedPath = path.join(rootRealPath, ...segments);
308
+ require_path_safety.assertPathInsideRoot(rootRealPath, expectedPath, path);
309
+ if (path.resolve(scannedPath.absolutePath) !== expectedPath) throw new Error(`Refusing to delete outside sync root: ${scannedPath.relativePath}`);
310
+ const [parentRealPath, parentStats] = await Promise.all([realpath(path.dirname(expectedPath)), stat(path.dirname(expectedPath))]);
311
+ const finalPath = path.join(parentRealPath, path.basename(expectedPath));
312
+ require_path_safety.assertPathInsideRoot(rootRealPath, finalPath, path);
313
+ const platform = globalThis.process?.platform;
314
+ let parentHandle;
315
+ let anchoredParentPath;
316
+ /* v8 ignore start -- Linux-only fd-relative path support is covered by Linux CI */
317
+ if (platform === "linux" && constants.O_DIRECTORY !== void 0 && localFileIoTestHooks.disableProcFdAnchoring !== true) try {
318
+ await localFileIoTestHooks.beforeLocalDeleteOpenParent?.(parentRealPath);
319
+ parentHandle = await open(parentRealPath, constants.O_RDONLY | constants.O_DIRECTORY | require_path_safety.noFollowFlag(constants));
320
+ anchoredParentPath = `/proc/self/fd/${parentHandle.fd}`;
321
+ } catch (err) {
322
+ if (require_path_safety.hasErrorCode(err, "ELOOP") || require_path_safety.hasErrorCode(err, "ENOTDIR")) throw new Error("unsafe local delete path: parent is not a directory");
323
+ throw err;
324
+ }
325
+ /* v8 ignore stop */
326
+ try {
327
+ const unlinkPath = anchoredParentPath === void 0 ? finalPath : path.join(anchoredParentPath, path.basename(expectedPath));
328
+ const stats = await lstat(unlinkPath);
329
+ require_local_file_identity.assertSameScannedRegularFile(stats, {
330
+ ...scannedPath,
331
+ absolutePath: unlinkPath
332
+ }, "delete", { platform: localFileIoTestHooks.platform });
333
+ await localFileIoTestHooks.beforeLocalDeleteUnlink?.(parentRealPath);
334
+ if (anchoredParentPath === void 0 && localFileIoTestHooks.disableProcFdAnchoring === true && parentRealPath !== rootRealPath) throw new Error("unsafe local delete path: stable parent handle unavailable for unlink");
335
+ if (anchoredParentPath === void 0) {
336
+ const [parentRealPathBeforeUnlink, parentStatsBeforeUnlink] = await Promise.all([realpath(path.dirname(expectedPath)), stat(path.dirname(expectedPath))]);
337
+ if (parentRealPathBeforeUnlink !== parentRealPath || !sameParentIdentity(parentStatsBeforeUnlink, parentStats)) throw new Error("unsafe local delete path: parent changed before unlink");
338
+ }
339
+ const finalStats = await lstat(unlinkPath);
340
+ require_local_file_identity.assertSameScannedRegularFile(finalStats, {
341
+ ...scannedPath,
342
+ absolutePath: unlinkPath
343
+ }, "delete", { platform: localFileIoTestHooks.platform });
344
+ await unlink(unlinkPath);
345
+ } finally {
346
+ /* v8 ignore next -- best-effort cleanup */
347
+ await parentHandle?.close().catch(() => {});
348
+ }
349
+ }
350
+ function sameParentIdentity(current, expected) {
351
+ return current.dev === expected.dev && current.ino === expected.ino;
352
+ }
353
+ async function writeAll(handle, data, position) {
354
+ let offset = 0;
355
+ while (offset < data.byteLength) {
356
+ const { bytesWritten } = await handle.write(data, offset, data.byteLength - offset, position + offset);
357
+ /* v8 ignore next -- defensive: FileHandle.write should progress for non-empty chunks. */
358
+ if (bytesWritten <= 0) throw new Error("download write made no progress");
359
+ offset += bytesWritten;
360
+ }
361
+ }
362
+ //#endregion
363
+ exports.DOWNLOAD_STAGING_DIRECTORY_NAME = require_download_staging.DOWNLOAD_STAGING_DIRECTORY_NAME;
364
+ exports.deleteLocalFileInsideRoot = deleteLocalFileInsideRoot;
365
+ exports.localFileIoTestHooks = localFileIoTestHooks;
366
+ exports.validateScannedLocalFile = validateScannedLocalFile;
367
+ exports.writeLocalStreamInsideRoot = writeLocalStreamInsideRoot;
368
+
369
+ //# sourceMappingURL=local-file-io.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-file-io.cjs","names":[],"sources":["../../src/sync/local-file-io.ts"],"sourcesContent":["import { sanitizeErrorReason } from '../util/error-reason.ts'\nimport { readStreamChunkWithTimeout } from './b2-sha1-reader.ts'\nimport {\n assertDownloadPathSameDevice,\n createDownloadStagingDirectory,\n DOWNLOAD_STAGING_DIRECTORY_NAME,\n isDownloadStagingDirectorySegment,\n} from './download-staging.ts'\nimport { assertSameScannedRegularFile } from './local-file-identity.ts'\nimport {\n assertPathInsideRoot,\n hasErrorCode,\n makeReservedSyncTempFileName,\n noFollowFlag,\n safeRelativePathSegments,\n} from './path-safety.ts'\nimport { DEFAULT_SHA1_IDLE_TIMEOUT_MILLIS } from './sha1-options.ts'\nimport type { LocalSyncPath } from './types.ts'\n\ntype DeviceStat = { readonly dev: number | bigint }\ntype DeviceStatFn = (path: string) => Promise<DeviceStat>\n\nexport { DOWNLOAD_STAGING_DIRECTORY_NAME }\n\n/** @internal */\nexport const localFileIoTestHooks: {\n afterParentDirectoryValidated?: (path: string) => Promise<void> | void\n afterDownloadBackupRename?: (path: string) => Promise<void> | void\n afterTempFileCreated?: (path: string, stagingDirectory: string) => Promise<void> | void\n beforeDownloadPublish?: (path: string) => Promise<void> | void\n beforeFinalRename?: (path: string) => Promise<void> | void\n beforeLocalDeleteOpenParent?: (path: string) => Promise<void> | void\n beforeLocalDeleteUnlink?: (path: string) => Promise<void> | void\n beforeStagingMarkerWrite?: (path: string) => Promise<void> | void\n disableProcFdAnchoring?: boolean\n downloadStagingActivityEntryLimit?: number\n platform?: string\n statForDeviceCheck?: DeviceStatFn\n} = {}\n\ninterface ScannedLocalFileHandle {\n stat(): Promise<{\n isFile(): boolean\n readonly dev: number\n readonly ino: number\n readonly mtimeMs: number\n readonly ctimeMs: number\n readonly size: number\n }>\n readFile(): Promise<Uint8Array>\n close(): Promise<void>\n}\n\n/**\n * Verifies that a previously scanned local file still points at the same regular file.\n *\n * @param path - Scanned local path and file identity.\n *\n * @internal\n */\nexport async function validateScannedLocalFile(path: LocalSyncPath): Promise<void> {\n const handle = await openValidatedScannedLocalFile(path)\n await handle.close()\n}\n\n/**\n * Reads a previously scanned local file while rejecting symlink swaps and metadata drift.\n *\n * @param path - Scanned local path and file identity.\n *\n * @returns The file bytes.\n *\n * @internal\n */\nexport async function readScannedLocalFile(path: LocalSyncPath): Promise<Uint8Array> {\n const handle = await openValidatedScannedLocalFile(path)\n try {\n const data = await handle.readFile()\n if (data.byteLength !== path.size) {\n throw new Error('local file changed before upload: size changed while reading')\n }\n return data\n } finally {\n await handle.close()\n }\n}\n\nasync function openValidatedScannedLocalFile(path: LocalSyncPath): Promise<ScannedLocalFileHandle> {\n const { constants } = await import('node:fs')\n const { open } = await import('node:fs/promises')\n const flags =\n constants.O_RDONLY |\n noFollowFlag(constants) |\n ((constants as { O_NONBLOCK?: number }).O_NONBLOCK ?? 0)\n const handle = await open(path.absolutePath, flags).catch((err: unknown) => {\n if (hasErrorCode(err, 'ELOOP')) {\n throw new Error('local file changed before upload: not a regular file')\n }\n throw new Error(\n `local file changed before upload: could not open scanned file: ${sanitizeErrorReason(err)}`,\n )\n })\n try {\n const stats = await handle.stat()\n assertSameScannedRegularFile(stats, path, 'upload', {\n platform: localFileIoTestHooks.platform,\n })\n return handle\n } catch (err) {\n await handle.close().catch(() => {})\n throw err\n }\n}\n\n/**\n * Writes bytes under a local sync root after path containment checks.\n *\n * @param root - Local sync root.\n * @param relPath - Destination path relative to the root.\n * @param data - Bytes to write.\n *\n * @internal\n */\nexport async function writeLocalFileInsideRoot(\n root: string,\n relPath: string,\n data: Uint8Array,\n): Promise<void> {\n await writeLocalStreamInsideRoot(\n root,\n relPath,\n new ReadableStream<Uint8Array>({\n start(controller) {\n controller.enqueue(data)\n controller.close()\n },\n }),\n {\n expectedBytes: data.byteLength,\n idleTimeoutMillis: DEFAULT_SHA1_IDLE_TIMEOUT_MILLIS,\n },\n )\n}\n\n/**\n * Streams a B2 download under a local sync root with path, timeout, and size checks.\n *\n * @param root - Local sync root.\n * @param relPath - Destination path relative to the root.\n * @param body - Download body stream.\n * @param options - Expected byte count, idle timeout, and optional abort signal.\n *\n * @internal\n */\nexport async function writeLocalStreamInsideRoot(\n root: string,\n relPath: string,\n body: ReadableStream<Uint8Array>,\n options: {\n readonly expectedBytes: number\n readonly expectedDestination?: LocalSyncPath | null\n readonly idleTimeoutMillis: number\n readonly signal?: AbortSignal\n },\n): Promise<void> {\n const { constants } = await import('node:fs')\n const { link, lstat, mkdir, open, realpath, rename, rm, stat } = await import('node:fs/promises')\n const path = await import('node:path')\n const { randomUUID } = await import('node:crypto')\n assertValidExpectedBytes(options.expectedBytes)\n const segments = safeRelativePathSegments(relPath)\n if (isDownloadStagingDirectorySegment(segments[0])) {\n throw new Error(\n `unsafe local destination path: ${DOWNLOAD_STAGING_DIRECTORY_NAME} is reserved for SDK download staging`,\n )\n }\n const rootRealPath = await realpath(root)\n\n let current = rootRealPath\n for (const segment of segments.slice(0, -1)) {\n current = path.join(current, segment)\n try {\n await mkdir(current)\n } catch (err) {\n if (!hasErrorCode(err, 'EEXIST')) throw err\n }\n const stats = await lstat(current)\n if (!stats.isDirectory()) {\n throw new Error('unsafe local destination path: parent is not a directory')\n }\n await localFileIoTestHooks.afterParentDirectoryValidated?.(current)\n }\n\n const destPath = path.join(rootRealPath, ...segments)\n assertPathInsideRoot(rootRealPath, destPath, path)\n\n const parentRealPath = await realpath(path.dirname(destPath))\n const finalPath = path.join(parentRealPath, path.basename(destPath))\n assertPathInsideRoot(rootRealPath, finalPath, path)\n try {\n const targetStats = await lstat(finalPath)\n if (targetStats.isSymbolicLink()) {\n throw new Error('unsafe local destination path: target is a symbolic link')\n }\n if (targetStats.isFile() && targetStats.nlink > 1) {\n throw new Error('unsafe local destination path: target has multiple hard links')\n }\n } catch (err) {\n if (!hasErrorCode(err, 'ENOENT')) throw err\n }\n const statForDeviceCheck = localFileIoTestHooks.statForDeviceCheck ?? stat\n await assertDownloadPathSameDevice(\n rootRealPath,\n parentRealPath,\n statForDeviceCheck,\n 'unsafe local destination path: cannot publish download across filesystems',\n )\n\n let parentHandle: Awaited<ReturnType<typeof open>> | undefined\n let anchoredParentPath: string | undefined\n const platform = (globalThis as { process?: { platform?: string } }).process?.platform\n /* v8 ignore start -- Linux-only fd-relative path support is covered by Linux CI */\n if (\n platform === 'linux' &&\n constants.O_DIRECTORY !== undefined &&\n localFileIoTestHooks.disableProcFdAnchoring !== true\n ) {\n try {\n parentHandle = await open(\n parentRealPath,\n constants.O_RDONLY | constants.O_DIRECTORY | noFollowFlag(constants),\n )\n anchoredParentPath = `/proc/self/fd/${parentHandle.fd}`\n } catch (err) {\n if (hasErrorCode(err, 'ELOOP') || hasErrorCode(err, 'ENOTDIR')) {\n throw new Error('unsafe local destination path: parent is not a directory')\n }\n throw err\n }\n }\n /* v8 ignore stop */\n const finalName = path.basename(destPath)\n const finalWritePath = path.join(anchoredParentPath ?? parentRealPath, finalName)\n let publishMode: number\n try {\n publishMode = await replacementFileMode(finalPath)\n } catch (err) {\n /* v8 ignore next -- best-effort close during setup failure */\n await parentHandle?.close().catch(() => {})\n throw err\n }\n let stagingDirectory: string\n try {\n stagingDirectory = await createDownloadStagingDirectory(\n rootRealPath,\n path,\n randomUUID,\n statForDeviceCheck,\n localFileIoTestHooks.beforeStagingMarkerWrite,\n localFileIoTestHooks.downloadStagingActivityEntryLimit,\n )\n } catch (err) {\n /* v8 ignore next -- best-effort close during setup failure */\n await parentHandle?.close().catch(() => {})\n throw err\n }\n const tmpPath = path.join(stagingDirectory, `.b2sdk-${randomUUID()}.partial`)\n let handle: Awaited<ReturnType<typeof open>> | undefined\n try {\n handle = await open(\n tmpPath,\n constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | noFollowFlag(constants),\n PRIVATE_DOWNLOAD_FILE_MODE,\n )\n /* v8 ignore next -- best-effort chmod */\n await handle.chmod(PRIVATE_DOWNLOAD_FILE_MODE).catch(() => {})\n await localFileIoTestHooks.afterTempFileCreated?.(tmpPath, stagingDirectory)\n /* v8 ignore start -- defensive cleanup before the main write try/finally exists */\n } catch (err) {\n await parentHandle?.close().catch(() => {})\n await rm(stagingDirectory, { recursive: true, force: true }).catch(() => {})\n throw err\n }\n /* v8 ignore stop */\n try {\n const tmpRealPath = await realpath(tmpPath)\n assertPathInsideRoot(stagingDirectory, tmpRealPath, path)\n } catch (err) {\n /* v8 ignore next -- best-effort cleanup */\n await handle?.close().catch(() => {})\n /* v8 ignore next -- best-effort cleanup */\n await rm(tmpPath, { force: true }).catch(() => {})\n /* v8 ignore next -- best-effort cleanup */\n await rm(stagingDirectory, { recursive: true, force: true }).catch(() => {})\n /* v8 ignore next -- best-effort cleanup */\n await parentHandle?.close().catch(() => {})\n throw err\n }\n const writeHandle = handle\n const reader = body.getReader()\n let completed = false\n try {\n let bytesWritten = 0\n while (true) {\n const { done, value } = await readStreamChunkWithTimeout(\n reader,\n options.idleTimeoutMillis,\n `download read stalled for ${options.idleTimeoutMillis} ms`,\n options.signal,\n )\n if (done) break\n if (bytesWritten + value.byteLength > options.expectedBytes) {\n throw new Error(`download read exceeded ${options.expectedBytes} byte limit`)\n }\n await writeAll(writeHandle, value, bytesWritten)\n bytesWritten += value.byteLength\n }\n if (bytesWritten !== options.expectedBytes) {\n throw new Error(\n `download read ended after ${bytesWritten} bytes, expected ${options.expectedBytes}`,\n )\n }\n if (publishMode !== PRIVATE_DOWNLOAD_FILE_MODE) {\n /* v8 ignore next -- best-effort mode preservation */\n await writeHandle.chmod(publishMode).catch(() => {})\n }\n await writeHandle.close()\n handle = undefined\n\n const [parentRealPathBeforeRename, parentStatsBeforeRename] = await Promise.all([\n realpath(path.dirname(destPath)),\n stat(path.dirname(destPath)),\n ])\n const finalPathBeforeRename = path.join(parentRealPathBeforeRename, path.basename(destPath))\n assertPathInsideRoot(rootRealPath, finalPathBeforeRename, path)\n await localFileIoTestHooks.beforeFinalRename?.(parentRealPathBeforeRename)\n let publishPath = finalWritePath\n if (anchoredParentPath === undefined) {\n const [parentRealPathAfterHook, parentStatsAfterHook] = await Promise.all([\n realpath(path.dirname(destPath)),\n stat(path.dirname(destPath)),\n ])\n if (\n parentRealPathAfterHook !== parentRealPathBeforeRename ||\n !sameParentIdentity(parentStatsAfterHook, parentStatsBeforeRename)\n ) {\n throw new Error('unsafe local destination path: parent changed before final publish')\n }\n publishPath = path.join(parentRealPathAfterHook, path.basename(destPath))\n assertPathInsideRoot(rootRealPath, publishPath, path)\n }\n await publishDownload(\n lstat,\n link,\n path,\n randomUUID,\n rename,\n rm,\n tmpPath,\n publishPath,\n options.expectedDestination,\n )\n completed = true\n } catch (err) {\n /* v8 ignore next -- best-effort cleanup */\n void reader.cancel(err).catch(() => {})\n throw err\n } finally {\n reader.releaseLock()\n if (!completed) {\n /* v8 ignore next -- best-effort cleanup */\n await handle?.close().catch(() => {})\n /* v8 ignore next -- best-effort cleanup */\n await rm(tmpPath, { force: true }).catch(() => {})\n }\n /* v8 ignore next -- best-effort cleanup */\n await rm(stagingDirectory, { recursive: true, force: true }).catch(() => {})\n /* v8 ignore next -- best-effort cleanup */\n await parentHandle?.close().catch(() => {})\n }\n}\n\nfunction assertValidExpectedBytes(expectedBytes: number): void {\n if (!Number.isSafeInteger(expectedBytes) || expectedBytes < 0) {\n throw new Error('download expectedBytes must be a non-negative safe integer')\n }\n}\n\nasync function assertExpectedDownloadDestination(\n lstat: typeof import('node:fs/promises')['lstat'],\n finalPath: string,\n expectedDestination: LocalSyncPath | null | undefined,\n): Promise<void> {\n if (expectedDestination === undefined) return\n\n try {\n const stats = await lstat(finalPath)\n if (expectedDestination === null) {\n throw new Error('local destination changed before download: file was created')\n }\n assertSameScannedRegularFile(\n stats,\n { ...expectedDestination, absolutePath: finalPath },\n 'download',\n { platform: localFileIoTestHooks.platform },\n )\n } catch (err) {\n if (hasErrorCode(err, 'ENOENT')) {\n if (expectedDestination === null) return\n throw new Error('local file changed before download: file missing')\n }\n throw err\n }\n}\n\nasync function publishDownload(\n lstat: typeof import('node:fs/promises')['lstat'],\n link: typeof import('node:fs/promises')['link'],\n path: typeof import('node:path'),\n randomUUID: () => string,\n rename: typeof import('node:fs/promises')['rename'],\n rm: typeof import('node:fs/promises')['rm'],\n tmpPath: string,\n publishPath: string,\n expectedDestination: LocalSyncPath | null | undefined,\n): Promise<void> {\n await assertExpectedDownloadDestination(lstat, publishPath, expectedDestination)\n await localFileIoTestHooks.beforeDownloadPublish?.(publishPath)\n\n if (expectedDestination === undefined) {\n await rename(tmpPath, publishPath)\n return\n }\n\n if (expectedDestination === null) {\n await linkDownloadNoOverwrite(\n link,\n tmpPath,\n publishPath,\n 'local destination changed before download: file was created',\n )\n /* v8 ignore next -- staging cleanup is best-effort after a guarded publish succeeds. */\n await rm(tmpPath, { force: true }).catch(() => {})\n return\n }\n\n const backupPath = path.join(\n path.dirname(publishPath),\n makeReservedSyncTempFileName(path.basename(publishPath), randomUUID()),\n )\n let backupExists = false\n let removeBackup = false\n\n try {\n try {\n await rename(publishPath, backupPath)\n backupExists = true\n await localFileIoTestHooks.afterDownloadBackupRename?.(backupPath)\n } catch (err) {\n if (hasErrorCode(err, 'ENOENT')) {\n throw new Error('local file changed before download: file missing')\n }\n throw err\n }\n\n const backupStats = await lstat(backupPath)\n assertSameScannedRegularFile(\n backupStats,\n { ...expectedDestination, absolutePath: backupPath },\n 'download',\n { compareChangeTime: false, platform: localFileIoTestHooks.platform },\n )\n await linkDownloadNoOverwrite(\n link,\n tmpPath,\n publishPath,\n 'local destination changed before download: file was created',\n )\n removeBackup = true\n /* v8 ignore next -- staging cleanup is best-effort after a guarded publish succeeds. */\n await rm(tmpPath, { force: true }).catch(() => {})\n } catch (err) {\n if (backupExists && !removeBackup) {\n await restoreBackupWithoutOverwrite(link, rm, backupPath, publishPath).catch(() => {})\n }\n throw err\n } finally {\n if (removeBackup) {\n /* v8 ignore next -- old destination cleanup is best-effort after publish succeeds. */\n await rm(backupPath, { force: true }).catch(() => {})\n }\n }\n}\n\nasync function linkDownloadNoOverwrite(\n link: typeof import('node:fs/promises')['link'],\n sourcePath: string,\n destPath: string,\n message: string,\n): Promise<void> {\n try {\n await link(sourcePath, destPath)\n } catch (err) {\n if (hasErrorCode(err, 'EEXIST')) throw new Error(message)\n throw err\n }\n}\n\nasync function restoreBackupWithoutOverwrite(\n link: typeof import('node:fs/promises')['link'],\n rm: typeof import('node:fs/promises')['rm'],\n backupPath: string,\n publishPath: string,\n): Promise<void> {\n try {\n await link(backupPath, publishPath)\n await rm(backupPath, { force: true })\n } catch (err) {\n if (hasErrorCode(err, 'EEXIST')) return\n throw err\n }\n}\n\nconst PRIVATE_DOWNLOAD_FILE_MODE = 0o600\nasync function replacementFileMode(filePath: string): Promise<number> {\n const { lstat } = await import('node:fs/promises')\n try {\n const stats = await lstat(filePath)\n return stats.isFile() ? stats.mode & 0o777 : PRIVATE_DOWNLOAD_FILE_MODE\n } catch (err) {\n if (hasErrorCode(err, 'ENOENT')) return PRIVATE_DOWNLOAD_FILE_MODE\n throw err\n }\n}\n\n/**\n * Deletes a scanned local file under a sync root without re-resolving attacker-controlled parents.\n *\n * @param root - Local sync root.\n * @param scannedPath - Previously scanned local file metadata.\n *\n * @internal\n */\nexport async function deleteLocalFileInsideRoot(\n root: string,\n scannedPath: LocalSyncPath,\n): Promise<void> {\n if (root === '') {\n throw new Error('Local sync root required for filesystem mutation')\n }\n\n const { constants } = await import('node:fs')\n const { lstat, open, realpath, stat, unlink } = await import('node:fs/promises')\n const path = await import('node:path')\n const segments = safeRelativePathSegments(scannedPath.relativePath)\n const safeRoot = path.resolve(root)\n const rootStats = await lstat(safeRoot)\n if (rootStats.isSymbolicLink()) {\n throw new Error(`Refusing to access sync root through symlink: ${scannedPath.relativePath}`)\n }\n if (!rootStats.isDirectory()) {\n throw new Error(`Local sync root is not a directory: ${scannedPath.relativePath}`)\n }\n const rootRealPath = await realpath(safeRoot)\n const expectedPath = path.join(rootRealPath, ...segments)\n assertPathInsideRoot(rootRealPath, expectedPath, path)\n\n const scannerPath = path.resolve(scannedPath.absolutePath)\n if (scannerPath !== expectedPath) {\n throw new Error(`Refusing to delete outside sync root: ${scannedPath.relativePath}`)\n }\n\n const [parentRealPath, parentStats] = await Promise.all([\n realpath(path.dirname(expectedPath)),\n stat(path.dirname(expectedPath)),\n ])\n const finalPath = path.join(parentRealPath, path.basename(expectedPath))\n assertPathInsideRoot(rootRealPath, finalPath, path)\n\n const platform = (globalThis as { process?: { platform?: string } }).process?.platform\n let parentHandle: Awaited<ReturnType<typeof open>> | undefined\n let anchoredParentPath: string | undefined\n /* v8 ignore start -- Linux-only fd-relative path support is covered by Linux CI */\n if (\n platform === 'linux' &&\n constants.O_DIRECTORY !== undefined &&\n localFileIoTestHooks.disableProcFdAnchoring !== true\n ) {\n try {\n await localFileIoTestHooks.beforeLocalDeleteOpenParent?.(parentRealPath)\n parentHandle = await open(\n parentRealPath,\n constants.O_RDONLY | constants.O_DIRECTORY | noFollowFlag(constants),\n )\n anchoredParentPath = `/proc/self/fd/${parentHandle.fd}`\n } catch (err) {\n if (hasErrorCode(err, 'ELOOP') || hasErrorCode(err, 'ENOTDIR')) {\n throw new Error('unsafe local delete path: parent is not a directory')\n }\n throw err\n }\n }\n /* v8 ignore stop */\n\n try {\n const unlinkPath =\n anchoredParentPath === undefined\n ? finalPath\n : path.join(anchoredParentPath, path.basename(expectedPath))\n const stats = await lstat(unlinkPath)\n assertSameScannedRegularFile(stats, { ...scannedPath, absolutePath: unlinkPath }, 'delete', {\n platform: localFileIoTestHooks.platform,\n })\n await localFileIoTestHooks.beforeLocalDeleteUnlink?.(parentRealPath)\n if (\n anchoredParentPath === undefined &&\n localFileIoTestHooks.disableProcFdAnchoring === true &&\n parentRealPath !== rootRealPath\n ) {\n throw new Error('unsafe local delete path: stable parent handle unavailable for unlink')\n }\n\n if (anchoredParentPath === undefined) {\n const [parentRealPathBeforeUnlink, parentStatsBeforeUnlink] = await Promise.all([\n realpath(path.dirname(expectedPath)),\n stat(path.dirname(expectedPath)),\n ])\n if (\n parentRealPathBeforeUnlink !== parentRealPath ||\n !sameParentIdentity(parentStatsBeforeUnlink, parentStats)\n ) {\n throw new Error('unsafe local delete path: parent changed before unlink')\n }\n }\n const finalStats = await lstat(unlinkPath)\n assertSameScannedRegularFile(\n finalStats,\n { ...scannedPath, absolutePath: unlinkPath },\n 'delete',\n { platform: localFileIoTestHooks.platform },\n )\n await unlink(unlinkPath)\n } finally {\n /* v8 ignore next -- best-effort cleanup */\n await parentHandle?.close().catch(() => {})\n }\n}\n\nfunction sameParentIdentity(\n current: { readonly dev: number | bigint; readonly ino: number | bigint },\n expected: { readonly dev: number | bigint; readonly ino: number | bigint },\n): boolean {\n return current.dev === expected.dev && current.ino === expected.ino\n}\n\nasync function writeAll(\n handle: {\n write(\n buffer: Uint8Array,\n offset: number,\n length: number,\n position: number,\n ): Promise<{ readonly bytesWritten: number }>\n },\n data: Uint8Array,\n position: number,\n): Promise<void> {\n let offset = 0\n while (offset < data.byteLength) {\n const { bytesWritten } = await handle.write(\n data,\n offset,\n data.byteLength - offset,\n position + offset,\n )\n /* v8 ignore next -- defensive: FileHandle.write should progress for non-empty chunks. */\n if (bytesWritten <= 0) throw new Error('download write made no progress')\n offset += bytesWritten\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ import { DOWNLOAD_STAGING_DIRECTORY_NAME } from './download-staging.js';
2
+ import { LocalSyncPath } from './types.js';
3
+ type DeviceStat = {
4
+ readonly dev: number | bigint;
5
+ };
6
+ type DeviceStatFn = (path: string) => Promise<DeviceStat>;
7
+ export { DOWNLOAD_STAGING_DIRECTORY_NAME };
8
+ /** @internal */
9
+ export declare const localFileIoTestHooks: {
10
+ afterParentDirectoryValidated?: (path: string) => Promise<void> | void;
11
+ afterDownloadBackupRename?: (path: string) => Promise<void> | void;
12
+ afterTempFileCreated?: (path: string, stagingDirectory: string) => Promise<void> | void;
13
+ beforeDownloadPublish?: (path: string) => Promise<void> | void;
14
+ beforeFinalRename?: (path: string) => Promise<void> | void;
15
+ beforeLocalDeleteOpenParent?: (path: string) => Promise<void> | void;
16
+ beforeLocalDeleteUnlink?: (path: string) => Promise<void> | void;
17
+ beforeStagingMarkerWrite?: (path: string) => Promise<void> | void;
18
+ disableProcFdAnchoring?: boolean;
19
+ downloadStagingActivityEntryLimit?: number;
20
+ platform?: string;
21
+ statForDeviceCheck?: DeviceStatFn;
22
+ };
23
+ /**
24
+ * Verifies that a previously scanned local file still points at the same regular file.
25
+ *
26
+ * @param path - Scanned local path and file identity.
27
+ *
28
+ * @internal
29
+ */
30
+ export declare function validateScannedLocalFile(path: LocalSyncPath): Promise<void>;
31
+ /**
32
+ * Reads a previously scanned local file while rejecting symlink swaps and metadata drift.
33
+ *
34
+ * @param path - Scanned local path and file identity.
35
+ *
36
+ * @returns The file bytes.
37
+ *
38
+ * @internal
39
+ */
40
+ export declare function readScannedLocalFile(path: LocalSyncPath): Promise<Uint8Array>;
41
+ /**
42
+ * Writes bytes under a local sync root after path containment checks.
43
+ *
44
+ * @param root - Local sync root.
45
+ * @param relPath - Destination path relative to the root.
46
+ * @param data - Bytes to write.
47
+ *
48
+ * @internal
49
+ */
50
+ export declare function writeLocalFileInsideRoot(root: string, relPath: string, data: Uint8Array): Promise<void>;
51
+ /**
52
+ * Streams a B2 download under a local sync root with path, timeout, and size checks.
53
+ *
54
+ * @param root - Local sync root.
55
+ * @param relPath - Destination path relative to the root.
56
+ * @param body - Download body stream.
57
+ * @param options - Expected byte count, idle timeout, and optional abort signal.
58
+ *
59
+ * @internal
60
+ */
61
+ export declare function writeLocalStreamInsideRoot(root: string, relPath: string, body: ReadableStream<Uint8Array>, options: {
62
+ readonly expectedBytes: number;
63
+ readonly expectedDestination?: LocalSyncPath | null;
64
+ readonly idleTimeoutMillis: number;
65
+ readonly signal?: AbortSignal;
66
+ }): Promise<void>;
67
+ /**
68
+ * Deletes a scanned local file under a sync root without re-resolving attacker-controlled parents.
69
+ *
70
+ * @param root - Local sync root.
71
+ * @param scannedPath - Previously scanned local file metadata.
72
+ *
73
+ * @internal
74
+ */
75
+ export declare function deleteLocalFileInsideRoot(root: string, scannedPath: LocalSyncPath): Promise<void>;
76
+ //# sourceMappingURL=local-file-io.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-file-io.d.ts","sourceRoot":"","sources":["../../src/sync/local-file-io.js"],"names":[],"mappings":"AAEA,OAAO,EAGL,+BAA+B,EAEhC,MAAM,uBAAuB,CAAA;AAU9B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE/C,KAAK,UAAU,GAAG;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAAA;AACnD,KAAK,YAAY,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,CAAA;AAEzD,OAAO,EAAE,+BAA+B,EAAE,CAAA;AAE1C,gBAAgB;AAChB,eAAO,MAAM,oBAAoB,EAAE;IACjC,6BAA6B,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IACtE,yBAAyB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IAClE,oBAAoB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IACvF,qBAAqB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IAC9D,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IAC1D,2BAA2B,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IACpE,uBAAuB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IAChE,wBAAwB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IACjE,sBAAsB,CAAC,EAAE,OAAO,CAAA;IAChC,iCAAiC,CAAC,EAAE,MAAM,CAAA;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,kBAAkB,CAAC,EAAE,YAAY,CAAA;CAC7B,CAAA;AAeN;;;;;;GAMG;AACH,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAGjF;AAED;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,UAAU,CAAC,CAWnF;AA6BD;;;;;;;;GAQG;AACH,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,IAAI,CAAC,CAef;AAED;;;;;;;;;GASG;AACH,wBAAsB,0BAA0B,CAC9C,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,cAAc,CAAC,UAAU,CAAC,EAChC,OAAO,EAAE;IACP,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,mBAAmB,CAAC,EAAE,aAAa,GAAG,IAAI,CAAA;IACnD,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAA;IAClC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAC9B,GACA,OAAO,CAAC,IAAI,CAAC,CAwNf;AA2JD;;;;;;;GAOG;AACH,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,aAAa,GACzB,OAAO,CAAC,IAAI,CAAC,CAoGf"}
@@ -0,0 +1,76 @@
1
+ import { DOWNLOAD_STAGING_DIRECTORY_NAME } from './download-staging.js';
2
+ import { LocalSyncPath } from './types.js';
3
+ type DeviceStat = {
4
+ readonly dev: number | bigint;
5
+ };
6
+ type DeviceStatFn = (path: string) => Promise<DeviceStat>;
7
+ export { DOWNLOAD_STAGING_DIRECTORY_NAME };
8
+ /** @internal */
9
+ export declare const localFileIoTestHooks: {
10
+ afterParentDirectoryValidated?: (path: string) => Promise<void> | void;
11
+ afterDownloadBackupRename?: (path: string) => Promise<void> | void;
12
+ afterTempFileCreated?: (path: string, stagingDirectory: string) => Promise<void> | void;
13
+ beforeDownloadPublish?: (path: string) => Promise<void> | void;
14
+ beforeFinalRename?: (path: string) => Promise<void> | void;
15
+ beforeLocalDeleteOpenParent?: (path: string) => Promise<void> | void;
16
+ beforeLocalDeleteUnlink?: (path: string) => Promise<void> | void;
17
+ beforeStagingMarkerWrite?: (path: string) => Promise<void> | void;
18
+ disableProcFdAnchoring?: boolean;
19
+ downloadStagingActivityEntryLimit?: number;
20
+ platform?: string;
21
+ statForDeviceCheck?: DeviceStatFn;
22
+ };
23
+ /**
24
+ * Verifies that a previously scanned local file still points at the same regular file.
25
+ *
26
+ * @param path - Scanned local path and file identity.
27
+ *
28
+ * @internal
29
+ */
30
+ export declare function validateScannedLocalFile(path: LocalSyncPath): Promise<void>;
31
+ /**
32
+ * Reads a previously scanned local file while rejecting symlink swaps and metadata drift.
33
+ *
34
+ * @param path - Scanned local path and file identity.
35
+ *
36
+ * @returns The file bytes.
37
+ *
38
+ * @internal
39
+ */
40
+ export declare function readScannedLocalFile(path: LocalSyncPath): Promise<Uint8Array>;
41
+ /**
42
+ * Writes bytes under a local sync root after path containment checks.
43
+ *
44
+ * @param root - Local sync root.
45
+ * @param relPath - Destination path relative to the root.
46
+ * @param data - Bytes to write.
47
+ *
48
+ * @internal
49
+ */
50
+ export declare function writeLocalFileInsideRoot(root: string, relPath: string, data: Uint8Array): Promise<void>;
51
+ /**
52
+ * Streams a B2 download under a local sync root with path, timeout, and size checks.
53
+ *
54
+ * @param root - Local sync root.
55
+ * @param relPath - Destination path relative to the root.
56
+ * @param body - Download body stream.
57
+ * @param options - Expected byte count, idle timeout, and optional abort signal.
58
+ *
59
+ * @internal
60
+ */
61
+ export declare function writeLocalStreamInsideRoot(root: string, relPath: string, body: ReadableStream<Uint8Array>, options: {
62
+ readonly expectedBytes: number;
63
+ readonly expectedDestination?: LocalSyncPath | null;
64
+ readonly idleTimeoutMillis: number;
65
+ readonly signal?: AbortSignal;
66
+ }): Promise<void>;
67
+ /**
68
+ * Deletes a scanned local file under a sync root without re-resolving attacker-controlled parents.
69
+ *
70
+ * @param root - Local sync root.
71
+ * @param scannedPath - Previously scanned local file metadata.
72
+ *
73
+ * @internal
74
+ */
75
+ export declare function deleteLocalFileInsideRoot(root: string, scannedPath: LocalSyncPath): Promise<void>;
76
+ //# sourceMappingURL=local-file-io.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-file-io.d.ts","sourceRoot":"","sources":["../../src/sync/local-file-io.js"],"names":[],"mappings":"AAEA,OAAO,EAGL,+BAA+B,EAEhC,MAAM,uBAAuB,CAAA;AAU9B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE/C,KAAK,UAAU,GAAG;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAAA;AACnD,KAAK,YAAY,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,CAAA;AAEzD,OAAO,EAAE,+BAA+B,EAAE,CAAA;AAE1C,gBAAgB;AAChB,eAAO,MAAM,oBAAoB,EAAE;IACjC,6BAA6B,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IACtE,yBAAyB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IAClE,oBAAoB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IACvF,qBAAqB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IAC9D,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IAC1D,2BAA2B,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IACpE,uBAAuB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IAChE,wBAAwB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IACjE,sBAAsB,CAAC,EAAE,OAAO,CAAA;IAChC,iCAAiC,CAAC,EAAE,MAAM,CAAA;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,kBAAkB,CAAC,EAAE,YAAY,CAAA;CAC7B,CAAA;AAeN;;;;;;GAMG;AACH,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAGjF;AAED;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,UAAU,CAAC,CAWnF;AA6BD;;;;;;;;GAQG;AACH,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,IAAI,CAAC,CAef;AAED;;;;;;;;;GASG;AACH,wBAAsB,0BAA0B,CAC9C,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,cAAc,CAAC,UAAU,CAAC,EAChC,OAAO,EAAE;IACP,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,mBAAmB,CAAC,EAAE,aAAa,GAAG,IAAI,CAAA;IACnD,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAA;IAClC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAC9B,GACA,OAAO,CAAC,IAAI,CAAC,CAwNf;AA2JD;;;;;;;GAOG;AACH,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,aAAa,GACzB,OAAO,CAAC,IAAI,CAAC,CAoGf"}