@backblaze-labs/b2-sdk 0.1.0 → 0.2.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 (701) hide show
  1. package/CHANGELOG.md +110 -5
  2. package/README.md +144 -33
  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/bucket.cjs +785 -787
  44. package/dist/bucket.cjs.map +1 -1
  45. package/dist/bucket.d.cts +35 -47
  46. package/dist/bucket.d.cts.map +1 -1
  47. package/dist/bucket.d.ts +35 -47
  48. package/dist/bucket.d.ts.map +1 -1
  49. package/dist/bucket.js +780 -782
  50. package/dist/bucket.js.map +1 -1
  51. package/dist/client.cjs +246 -228
  52. package/dist/client.cjs.map +1 -1
  53. package/dist/client.d.cts +25 -17
  54. package/dist/client.d.cts.map +1 -1
  55. package/dist/client.d.ts +25 -17
  56. package/dist/client.d.ts.map +1 -1
  57. package/dist/client.js +243 -225
  58. package/dist/client.js.map +1 -1
  59. package/dist/copy/large.cjs +114 -71
  60. package/dist/copy/large.cjs.map +1 -1
  61. package/dist/copy/large.d.cts +6 -0
  62. package/dist/copy/large.d.cts.map +1 -1
  63. package/dist/copy/large.d.ts +6 -0
  64. package/dist/copy/large.d.ts.map +1 -1
  65. package/dist/copy/large.js +112 -69
  66. package/dist/copy/large.js.map +1 -1
  67. package/dist/download/checksum.cjs +89 -0
  68. package/dist/download/checksum.cjs.map +1 -0
  69. package/dist/download/checksum.d.cts +40 -0
  70. package/dist/download/checksum.d.cts.map +1 -0
  71. package/dist/download/checksum.d.ts +40 -0
  72. package/dist/download/checksum.d.ts.map +1 -0
  73. package/dist/download/checksum.js +87 -0
  74. package/dist/download/checksum.js.map +1 -0
  75. package/dist/download/parallel.cjs +214 -118
  76. package/dist/download/parallel.cjs.map +1 -1
  77. package/dist/download/parallel.d.cts +5 -1
  78. package/dist/download/parallel.d.cts.map +1 -1
  79. package/dist/download/parallel.d.ts +5 -1
  80. package/dist/download/parallel.d.ts.map +1 -1
  81. package/dist/download/parallel.js +212 -116
  82. package/dist/download/parallel.js.map +1 -1
  83. package/dist/download/single.cjs +188 -97
  84. package/dist/download/single.cjs.map +1 -1
  85. package/dist/download/single.d.cts +6 -1
  86. package/dist/download/single.d.cts.map +1 -1
  87. package/dist/download/single.d.ts +6 -1
  88. package/dist/download/single.d.ts.map +1 -1
  89. package/dist/download/single.js +186 -98
  90. package/dist/download/single.js.map +1 -1
  91. package/dist/errors/index.cjs +699 -243
  92. package/dist/errors/index.cjs.map +1 -1
  93. package/dist/errors/index.d.cts +285 -82
  94. package/dist/errors/index.d.cts.map +1 -1
  95. package/dist/errors/index.d.ts +285 -82
  96. package/dist/errors/index.d.ts.map +1 -1
  97. package/dist/errors/index.js +678 -261
  98. package/dist/errors/index.js.map +1 -1
  99. package/dist/http/retry.cjs +45 -28
  100. package/dist/http/retry.cjs.map +1 -1
  101. package/dist/http/retry.d.cts +15 -2
  102. package/dist/http/retry.d.cts.map +1 -1
  103. package/dist/http/retry.d.ts +15 -2
  104. package/dist/http/retry.d.ts.map +1 -1
  105. package/dist/http/retry.js +46 -31
  106. package/dist/http/retry.js.map +1 -1
  107. package/dist/http/transport.cjs +438 -140
  108. package/dist/http/transport.cjs.map +1 -1
  109. package/dist/http/transport.d.cts +21 -2
  110. package/dist/http/transport.d.cts.map +1 -1
  111. package/dist/http/transport.d.ts +21 -2
  112. package/dist/http/transport.d.ts.map +1 -1
  113. package/dist/http/transport.js +437 -140
  114. package/dist/http/transport.js.map +1 -1
  115. package/dist/http/url-guard.cjs +154 -89
  116. package/dist/http/url-guard.cjs.map +1 -1
  117. package/dist/http/url-guard.d.cts +25 -3
  118. package/dist/http/url-guard.d.cts.map +1 -1
  119. package/dist/http/url-guard.d.ts +25 -3
  120. package/dist/http/url-guard.d.ts.map +1 -1
  121. package/dist/http/url-guard.js +152 -90
  122. package/dist/http/url-guard.js.map +1 -1
  123. package/dist/http/user-agent.cjs +84 -44
  124. package/dist/http/user-agent.cjs.map +1 -1
  125. package/dist/http/user-agent.js +84 -46
  126. package/dist/http/user-agent.js.map +1 -1
  127. package/dist/index.cjs +101 -77
  128. package/dist/index.d.cts +27 -21
  129. package/dist/index.d.cts.map +1 -1
  130. package/dist/index.d.ts +27 -21
  131. package/dist/index.d.ts.map +1 -1
  132. package/dist/index.js +15 -71
  133. package/dist/internal/b2-naming.cjs +66 -0
  134. package/dist/internal/b2-naming.cjs.map +1 -0
  135. package/dist/internal/b2-naming.d.cts +43 -0
  136. package/dist/internal/b2-naming.d.cts.map +1 -0
  137. package/dist/internal/b2-naming.d.ts +43 -0
  138. package/dist/internal/b2-naming.d.ts.map +1 -0
  139. package/dist/internal/b2-naming.js +60 -0
  140. package/dist/internal/b2-naming.js.map +1 -0
  141. package/dist/internal/upload-retry-options.cjs +21 -0
  142. package/dist/internal/upload-retry-options.cjs.map +1 -0
  143. package/dist/internal/upload-retry-options.d.cts +12 -0
  144. package/dist/internal/upload-retry-options.d.cts.map +1 -0
  145. package/dist/internal/upload-retry-options.d.ts +12 -0
  146. package/dist/internal/upload-retry-options.d.ts.map +1 -0
  147. package/dist/internal/upload-retry-options.js +21 -0
  148. package/dist/internal/upload-retry-options.js.map +1 -0
  149. package/dist/internal/url-redaction.cjs +31 -0
  150. package/dist/internal/url-redaction.cjs.map +1 -0
  151. package/dist/internal/url-redaction.d.cts +17 -0
  152. package/dist/internal/url-redaction.d.cts.map +1 -0
  153. package/dist/internal/url-redaction.d.ts +17 -0
  154. package/dist/internal/url-redaction.d.ts.map +1 -0
  155. package/dist/internal/url-redaction.js +31 -0
  156. package/dist/internal/url-redaction.js.map +1 -0
  157. package/dist/notifications/index.cjs +4 -6
  158. package/dist/notifications/index.d.cts +1 -1
  159. package/dist/notifications/index.d.cts.map +1 -1
  160. package/dist/notifications/index.d.ts +1 -1
  161. package/dist/notifications/index.d.ts.map +1 -1
  162. package/dist/notifications/index.js +1 -6
  163. package/dist/notifications/webhook.cjs +195 -85
  164. package/dist/notifications/webhook.cjs.map +1 -1
  165. package/dist/notifications/webhook.d.cts.map +1 -1
  166. package/dist/notifications/webhook.d.ts.map +1 -1
  167. package/dist/notifications/webhook.js +195 -87
  168. package/dist/notifications/webhook.js.map +1 -1
  169. package/dist/object.cjs +253 -210
  170. package/dist/object.cjs.map +1 -1
  171. package/dist/object.d.cts +9 -55
  172. package/dist/object.d.cts.map +1 -1
  173. package/dist/object.d.ts +9 -55
  174. package/dist/object.d.ts.map +1 -1
  175. package/dist/object.js +249 -206
  176. package/dist/object.js.map +1 -1
  177. package/dist/raw/encoding.cjs +74 -35
  178. package/dist/raw/encoding.cjs.map +1 -1
  179. package/dist/raw/encoding.js +74 -38
  180. package/dist/raw/encoding.js.map +1 -1
  181. package/dist/raw/index.cjs +678 -587
  182. package/dist/raw/index.cjs.map +1 -1
  183. package/dist/raw/index.d.cts +121 -18
  184. package/dist/raw/index.d.cts.map +1 -1
  185. package/dist/raw/index.d.ts +121 -18
  186. package/dist/raw/index.d.ts.map +1 -1
  187. package/dist/raw/index.js +674 -589
  188. package/dist/raw/index.js.map +1 -1
  189. package/dist/s3/index.cjs +355 -18
  190. package/dist/s3/index.cjs.map +1 -1
  191. package/dist/s3/index.d.cts +233 -5
  192. package/dist/s3/index.d.cts.map +1 -1
  193. package/dist/s3/index.d.ts +233 -5
  194. package/dist/s3/index.d.ts.map +1 -1
  195. package/dist/s3/index.js +351 -22
  196. package/dist/s3/index.js.map +1 -1
  197. package/dist/s3/sigv4.cjs +149 -0
  198. package/dist/s3/sigv4.cjs.map +1 -0
  199. package/dist/s3/sigv4.d.cts +43 -0
  200. package/dist/s3/sigv4.d.cts.map +1 -0
  201. package/dist/s3/sigv4.d.ts +43 -0
  202. package/dist/s3/sigv4.d.ts.map +1 -0
  203. package/dist/s3/sigv4.js +148 -0
  204. package/dist/s3/sigv4.js.map +1 -0
  205. package/dist/s3/validation.cjs +69 -0
  206. package/dist/s3/validation.cjs.map +1 -0
  207. package/dist/s3/validation.d.cts +43 -0
  208. package/dist/s3/validation.d.cts.map +1 -0
  209. package/dist/s3/validation.d.ts +43 -0
  210. package/dist/s3/validation.d.ts.map +1 -0
  211. package/dist/s3/validation.js +66 -0
  212. package/dist/s3/validation.js.map +1 -0
  213. package/dist/simulator/capabilities.cjs +63 -48
  214. package/dist/simulator/capabilities.cjs.map +1 -1
  215. package/dist/simulator/capabilities.js +63 -49
  216. package/dist/simulator/capabilities.js.map +1 -1
  217. package/dist/simulator/index.cjs +2124 -1548
  218. package/dist/simulator/index.cjs.map +1 -1
  219. package/dist/simulator/index.d.cts +79 -11
  220. package/dist/simulator/index.d.cts.map +1 -1
  221. package/dist/simulator/index.d.ts +79 -11
  222. package/dist/simulator/index.d.ts.map +1 -1
  223. package/dist/simulator/index.js +2112 -1546
  224. package/dist/simulator/index.js.map +1 -1
  225. package/dist/simulator/validation.cjs +191 -153
  226. package/dist/simulator/validation.cjs.map +1 -1
  227. package/dist/simulator/validation.d.cts +3 -21
  228. package/dist/simulator/validation.d.cts.map +1 -1
  229. package/dist/simulator/validation.d.ts +3 -21
  230. package/dist/simulator/validation.d.ts.map +1 -1
  231. package/dist/simulator/validation.js +188 -162
  232. package/dist/simulator/validation.js.map +1 -1
  233. package/dist/streams/collect.cjs +74 -24
  234. package/dist/streams/collect.cjs.map +1 -1
  235. package/dist/streams/collect.d.cts +14 -1
  236. package/dist/streams/collect.d.cts.map +1 -1
  237. package/dist/streams/collect.d.ts +14 -1
  238. package/dist/streams/collect.d.ts.map +1 -1
  239. package/dist/streams/collect.js +74 -25
  240. package/dist/streams/collect.js.map +1 -1
  241. package/dist/streams/file-source.cjs +287 -0
  242. package/dist/streams/file-source.cjs.map +1 -0
  243. package/dist/streams/file-source.d.cts +96 -0
  244. package/dist/streams/file-source.d.cts.map +1 -0
  245. package/dist/streams/file-source.d.ts +96 -0
  246. package/dist/streams/file-source.d.ts.map +1 -0
  247. package/dist/streams/file-source.js +286 -0
  248. package/dist/streams/file-source.js.map +1 -0
  249. package/dist/streams/hash.cjs +207 -115
  250. package/dist/streams/hash.cjs.map +1 -1
  251. package/dist/streams/hash.d.cts +5 -4
  252. package/dist/streams/hash.d.cts.map +1 -1
  253. package/dist/streams/hash.d.ts +5 -4
  254. package/dist/streams/hash.d.ts.map +1 -1
  255. package/dist/streams/hash.js +208 -95
  256. package/dist/streams/hash.js.map +1 -1
  257. package/dist/streams/index.cjs +12 -12
  258. package/dist/streams/index.d.cts +3 -3
  259. package/dist/streams/index.d.cts.map +1 -1
  260. package/dist/streams/index.d.ts +3 -3
  261. package/dist/streams/index.d.ts.map +1 -1
  262. package/dist/streams/index.js +2 -10
  263. package/dist/streams/progress.cjs +60 -46
  264. package/dist/streams/progress.cjs.map +1 -1
  265. package/dist/streams/progress.js +60 -46
  266. package/dist/streams/progress.js.map +1 -1
  267. package/dist/streams/source.cjs +316 -146
  268. package/dist/streams/source.cjs.map +1 -1
  269. package/dist/streams/source.d.cts +56 -18
  270. package/dist/streams/source.d.cts.map +1 -1
  271. package/dist/streams/source.d.ts +56 -18
  272. package/dist/streams/source.d.ts.map +1 -1
  273. package/dist/streams/source.js +312 -149
  274. package/dist/streams/source.js.map +1 -1
  275. package/dist/sync/actions/index.cjs +236 -184
  276. package/dist/sync/actions/index.cjs.map +1 -1
  277. package/dist/sync/actions/index.d.cts +29 -21
  278. package/dist/sync/actions/index.d.cts.map +1 -1
  279. package/dist/sync/actions/index.d.ts +29 -21
  280. package/dist/sync/actions/index.d.ts.map +1 -1
  281. package/dist/sync/actions/index.js +236 -190
  282. package/dist/sync/actions/index.js.map +1 -1
  283. package/dist/sync/b2-sha1-reader.cjs +148 -0
  284. package/dist/sync/b2-sha1-reader.cjs.map +1 -0
  285. package/dist/sync/b2-sha1-reader.d.cts +58 -0
  286. package/dist/sync/b2-sha1-reader.d.cts.map +1 -0
  287. package/dist/sync/b2-sha1-reader.d.ts +58 -0
  288. package/dist/sync/b2-sha1-reader.d.ts.map +1 -0
  289. package/dist/sync/b2-sha1-reader.js +145 -0
  290. package/dist/sync/b2-sha1-reader.js.map +1 -0
  291. package/dist/sync/download-staging.cjs +265 -0
  292. package/dist/sync/download-staging.cjs.map +1 -0
  293. package/dist/sync/download-staging.d.cts +54 -0
  294. package/dist/sync/download-staging.d.cts.map +1 -0
  295. package/dist/sync/download-staging.d.ts +54 -0
  296. package/dist/sync/download-staging.d.ts.map +1 -0
  297. package/dist/sync/download-staging.js +259 -0
  298. package/dist/sync/download-staging.js.map +1 -0
  299. package/dist/sync/filesystem-errors.cjs +32 -0
  300. package/dist/sync/filesystem-errors.cjs.map +1 -0
  301. package/dist/sync/filesystem-errors.d.cts +8 -0
  302. package/dist/sync/filesystem-errors.d.cts.map +1 -0
  303. package/dist/sync/filesystem-errors.d.ts +8 -0
  304. package/dist/sync/filesystem-errors.d.ts.map +1 -0
  305. package/dist/sync/filesystem-errors.js +32 -0
  306. package/dist/sync/filesystem-errors.js.map +1 -0
  307. package/dist/sync/filters.cjs +217 -0
  308. package/dist/sync/filters.cjs.map +1 -0
  309. package/dist/sync/filters.d.cts +51 -0
  310. package/dist/sync/filters.d.cts.map +1 -0
  311. package/dist/sync/filters.d.ts +51 -0
  312. package/dist/sync/filters.d.ts.map +1 -0
  313. package/dist/sync/filters.js +213 -0
  314. package/dist/sync/filters.js.map +1 -0
  315. package/dist/sync/index.cjs +39 -22
  316. package/dist/sync/index.d.cts +14 -9
  317. package/dist/sync/index.d.cts.map +1 -1
  318. package/dist/sync/index.d.ts +14 -9
  319. package/dist/sync/index.d.ts.map +1 -1
  320. package/dist/sync/index.js +9 -20
  321. package/dist/sync/local-file-identity.cjs +61 -0
  322. package/dist/sync/local-file-identity.cjs.map +1 -0
  323. package/dist/sync/local-file-identity.d.cts +37 -0
  324. package/dist/sync/local-file-identity.d.cts.map +1 -0
  325. package/dist/sync/local-file-identity.d.ts +37 -0
  326. package/dist/sync/local-file-identity.d.ts.map +1 -0
  327. package/dist/sync/local-file-identity.js +60 -0
  328. package/dist/sync/local-file-identity.js.map +1 -0
  329. package/dist/sync/local-file-io.cjs +364 -0
  330. package/dist/sync/local-file-io.cjs.map +1 -0
  331. package/dist/sync/local-file-io.d.cts +75 -0
  332. package/dist/sync/local-file-io.d.cts.map +1 -0
  333. package/dist/sync/local-file-io.d.ts +75 -0
  334. package/dist/sync/local-file-io.d.ts.map +1 -0
  335. package/dist/sync/local-file-io.js +360 -0
  336. package/dist/sync/local-file-io.js.map +1 -0
  337. package/dist/sync/local-filesystem-root.cjs +27 -0
  338. package/dist/sync/local-filesystem-root.cjs.map +1 -0
  339. package/dist/sync/local-filesystem-root.d.cts +18 -0
  340. package/dist/sync/local-filesystem-root.d.cts.map +1 -0
  341. package/dist/sync/local-filesystem-root.d.ts +18 -0
  342. package/dist/sync/local-filesystem-root.d.ts.map +1 -0
  343. package/dist/sync/local-filesystem-root.js +26 -0
  344. package/dist/sync/local-filesystem-root.js.map +1 -0
  345. package/dist/sync/local-sha1.cjs +119 -0
  346. package/dist/sync/local-sha1.cjs.map +1 -0
  347. package/dist/sync/local-sha1.d.cts +39 -0
  348. package/dist/sync/local-sha1.d.cts.map +1 -0
  349. package/dist/sync/local-sha1.d.ts +39 -0
  350. package/dist/sync/local-sha1.d.ts.map +1 -0
  351. package/dist/sync/local-sha1.js +117 -0
  352. package/dist/sync/local-sha1.js.map +1 -0
  353. package/dist/sync/pairing.cjs +118 -29
  354. package/dist/sync/pairing.cjs.map +1 -1
  355. package/dist/sync/pairing.d.cts +7 -2
  356. package/dist/sync/pairing.d.cts.map +1 -1
  357. package/dist/sync/pairing.d.ts +7 -2
  358. package/dist/sync/pairing.d.ts.map +1 -1
  359. package/dist/sync/pairing.js +120 -31
  360. package/dist/sync/pairing.js.map +1 -1
  361. package/dist/sync/path-order.cjs +30 -0
  362. package/dist/sync/path-order.cjs.map +1 -0
  363. package/dist/sync/path-order.d.cts +28 -0
  364. package/dist/sync/path-order.d.cts.map +1 -0
  365. package/dist/sync/path-order.d.ts +28 -0
  366. package/dist/sync/path-order.d.ts.map +1 -0
  367. package/dist/sync/path-order.js +29 -0
  368. package/dist/sync/path-order.js.map +1 -0
  369. package/dist/sync/path-safety.cjs +111 -0
  370. package/dist/sync/path-safety.cjs.map +1 -0
  371. package/dist/sync/path-safety.d.cts +78 -0
  372. package/dist/sync/path-safety.d.cts.map +1 -0
  373. package/dist/sync/path-safety.d.ts +78 -0
  374. package/dist/sync/path-safety.d.ts.map +1 -0
  375. package/dist/sync/path-safety.js +105 -0
  376. package/dist/sync/path-safety.js.map +1 -0
  377. package/dist/sync/paths.d.cts +19 -0
  378. package/dist/sync/paths.d.cts.map +1 -0
  379. package/dist/sync/paths.d.ts +19 -0
  380. package/dist/sync/paths.d.ts.map +1 -0
  381. package/dist/sync/policies/compare.cjs +389 -11
  382. package/dist/sync/policies/compare.cjs.map +1 -1
  383. package/dist/sync/policies/compare.d.cts +100 -2
  384. package/dist/sync/policies/compare.d.cts.map +1 -1
  385. package/dist/sync/policies/compare.d.ts +100 -2
  386. package/dist/sync/policies/compare.d.ts.map +1 -1
  387. package/dist/sync/policies/compare.js +387 -13
  388. package/dist/sync/policies/compare.js.map +1 -1
  389. package/dist/sync/policies/index.cjs +76 -65
  390. package/dist/sync/policies/index.cjs.map +1 -1
  391. package/dist/sync/policies/index.d.cts +35 -6
  392. package/dist/sync/policies/index.d.cts.map +1 -1
  393. package/dist/sync/policies/index.d.ts +35 -6
  394. package/dist/sync/policies/index.d.ts.map +1 -1
  395. package/dist/sync/policies/index.js +76 -65
  396. package/dist/sync/policies/index.js.map +1 -1
  397. package/dist/sync/prefix.cjs +96 -0
  398. package/dist/sync/prefix.cjs.map +1 -0
  399. package/dist/sync/prefix.d.cts +55 -0
  400. package/dist/sync/prefix.d.cts.map +1 -0
  401. package/dist/sync/prefix.d.ts +55 -0
  402. package/dist/sync/prefix.d.ts.map +1 -0
  403. package/dist/sync/prefix.js +92 -0
  404. package/dist/sync/prefix.js.map +1 -0
  405. package/dist/sync/regexp-safety.cjs +192 -0
  406. package/dist/sync/regexp-safety.cjs.map +1 -0
  407. package/dist/sync/regexp-safety.d.cts +29 -0
  408. package/dist/sync/regexp-safety.d.cts.map +1 -0
  409. package/dist/sync/regexp-safety.d.ts +29 -0
  410. package/dist/sync/regexp-safety.d.ts.map +1 -0
  411. package/dist/sync/regexp-safety.js +190 -0
  412. package/dist/sync/regexp-safety.js.map +1 -0
  413. package/dist/sync/scan-events.cjs +33 -0
  414. package/dist/sync/scan-events.cjs.map +1 -0
  415. package/dist/sync/scan-events.d.cts +17 -0
  416. package/dist/sync/scan-events.d.cts.map +1 -0
  417. package/dist/sync/scan-events.d.ts +17 -0
  418. package/dist/sync/scan-events.d.ts.map +1 -0
  419. package/dist/sync/scan-events.js +32 -0
  420. package/dist/sync/scan-events.js.map +1 -0
  421. package/dist/sync/scan-limit.cjs +33 -0
  422. package/dist/sync/scan-limit.cjs.map +1 -0
  423. package/dist/sync/scan-limit.d.cts +21 -0
  424. package/dist/sync/scan-limit.d.cts.map +1 -0
  425. package/dist/sync/scan-limit.d.ts +21 -0
  426. package/dist/sync/scan-limit.d.ts.map +1 -0
  427. package/dist/sync/scan-limit.js +31 -0
  428. package/dist/sync/scan-limit.js.map +1 -0
  429. package/dist/sync/scanners/b2.cjs +239 -55
  430. package/dist/sync/scanners/b2.cjs.map +1 -1
  431. package/dist/sync/scanners/b2.d.cts +26 -7
  432. package/dist/sync/scanners/b2.d.cts.map +1 -1
  433. package/dist/sync/scanners/b2.d.ts +26 -7
  434. package/dist/sync/scanners/b2.d.ts.map +1 -1
  435. package/dist/sync/scanners/b2.js +239 -55
  436. package/dist/sync/scanners/b2.js.map +1 -1
  437. package/dist/sync/scanners/local.cjs +215 -56
  438. package/dist/sync/scanners/local.cjs.map +1 -1
  439. package/dist/sync/scanners/local.d.cts +22 -7
  440. package/dist/sync/scanners/local.d.cts.map +1 -1
  441. package/dist/sync/scanners/local.d.ts +22 -7
  442. package/dist/sync/scanners/local.d.ts.map +1 -1
  443. package/dist/sync/scanners/local.js +216 -57
  444. package/dist/sync/scanners/local.js.map +1 -1
  445. package/dist/sync/sha1-metadata.cjs +94 -0
  446. package/dist/sync/sha1-metadata.cjs.map +1 -0
  447. package/dist/sync/sha1-metadata.d.cts +82 -0
  448. package/dist/sync/sha1-metadata.d.cts.map +1 -0
  449. package/dist/sync/sha1-metadata.d.ts +82 -0
  450. package/dist/sync/sha1-metadata.d.ts.map +1 -0
  451. package/dist/sync/sha1-metadata.js +89 -0
  452. package/dist/sync/sha1-metadata.js.map +1 -0
  453. package/dist/sync/sha1-options.cjs +23 -0
  454. package/dist/sync/sha1-options.cjs.map +1 -0
  455. package/dist/sync/sha1-options.d.cts +14 -0
  456. package/dist/sync/sha1-options.d.cts.map +1 -0
  457. package/dist/sync/sha1-options.d.ts +14 -0
  458. package/dist/sync/sha1-options.d.ts.map +1 -0
  459. package/dist/sync/sha1-options.js +21 -0
  460. package/dist/sync/sha1-options.js.map +1 -0
  461. package/dist/sync/synchronizer.cjs +782 -197
  462. package/dist/sync/synchronizer.cjs.map +1 -1
  463. package/dist/sync/synchronizer.d.cts +47 -1
  464. package/dist/sync/synchronizer.d.cts.map +1 -1
  465. package/dist/sync/synchronizer.d.ts +47 -1
  466. package/dist/sync/synchronizer.d.ts.map +1 -1
  467. package/dist/sync/synchronizer.js +779 -173
  468. package/dist/sync/synchronizer.js.map +1 -1
  469. package/dist/sync/types.d.cts +208 -16
  470. package/dist/sync/types.d.cts.map +1 -1
  471. package/dist/sync/types.d.ts +208 -16
  472. package/dist/sync/types.d.ts.map +1 -1
  473. package/dist/types/auth.cjs +76 -56
  474. package/dist/types/auth.cjs.map +1 -1
  475. package/dist/types/auth.d.cts +67 -9
  476. package/dist/types/auth.d.cts.map +1 -1
  477. package/dist/types/auth.d.ts +67 -9
  478. package/dist/types/auth.d.ts.map +1 -1
  479. package/dist/types/auth.js +77 -57
  480. package/dist/types/auth.js.map +1 -1
  481. package/dist/types/bucket.cjs +74 -38
  482. package/dist/types/bucket.cjs.map +1 -1
  483. package/dist/types/bucket.js +75 -41
  484. package/dist/types/bucket.js.map +1 -1
  485. package/dist/types/encryption.cjs +364 -327
  486. package/dist/types/encryption.cjs.map +1 -1
  487. package/dist/types/encryption.d.cts +16 -0
  488. package/dist/types/encryption.d.cts.map +1 -1
  489. package/dist/types/encryption.d.ts +16 -0
  490. package/dist/types/encryption.d.ts.map +1 -1
  491. package/dist/types/encryption.js +364 -310
  492. package/dist/types/encryption.js.map +1 -1
  493. package/dist/types/errors.cjs +47 -0
  494. package/dist/types/errors.cjs.map +1 -0
  495. package/dist/types/errors.d.cts +13 -4
  496. package/dist/types/errors.d.cts.map +1 -1
  497. package/dist/types/errors.d.ts +13 -4
  498. package/dist/types/errors.d.ts.map +1 -1
  499. package/dist/types/errors.js +47 -0
  500. package/dist/types/errors.js.map +1 -0
  501. package/dist/types/file.cjs +36 -19
  502. package/dist/types/file.cjs.map +1 -1
  503. package/dist/types/file.d.cts +2 -2
  504. package/dist/types/file.d.cts.map +1 -1
  505. package/dist/types/file.d.ts +2 -2
  506. package/dist/types/file.d.ts.map +1 -1
  507. package/dist/types/file.js +37 -21
  508. package/dist/types/file.js.map +1 -1
  509. package/dist/types/ids.cjs +53 -9
  510. package/dist/types/ids.cjs.map +1 -1
  511. package/dist/types/ids.js +54 -15
  512. package/dist/types/ids.js.map +1 -1
  513. package/dist/types/index.d.cts +12 -11
  514. package/dist/types/index.d.cts.map +1 -1
  515. package/dist/types/index.d.ts +12 -11
  516. package/dist/types/index.d.ts.map +1 -1
  517. package/dist/types/key.d.cts +44 -8
  518. package/dist/types/key.d.cts.map +1 -1
  519. package/dist/types/key.d.ts +44 -8
  520. package/dist/types/key.d.ts.map +1 -1
  521. package/dist/types/lock.cjs +33 -13
  522. package/dist/types/lock.cjs.map +1 -1
  523. package/dist/types/lock.js +34 -15
  524. package/dist/types/lock.js.map +1 -1
  525. package/dist/types/notifications.cjs +44 -22
  526. package/dist/types/notifications.cjs.map +1 -1
  527. package/dist/types/notifications.js +45 -23
  528. package/dist/types/notifications.js.map +1 -1
  529. package/dist/types/upload.d.cts +39 -5
  530. package/dist/types/upload.d.cts.map +1 -1
  531. package/dist/types/upload.d.ts +39 -5
  532. package/dist/types/upload.d.ts.map +1 -1
  533. package/dist/upload/abort-scope.cjs +91 -0
  534. package/dist/upload/abort-scope.cjs.map +1 -0
  535. package/dist/upload/abort-scope.d.cts +48 -0
  536. package/dist/upload/abort-scope.d.cts.map +1 -0
  537. package/dist/upload/abort-scope.d.ts +48 -0
  538. package/dist/upload/abort-scope.d.ts.map +1 -0
  539. package/dist/upload/abort-scope.js +88 -0
  540. package/dist/upload/abort-scope.js.map +1 -0
  541. package/dist/upload/cancel.cjs +183 -8
  542. package/dist/upload/cancel.cjs.map +1 -1
  543. package/dist/upload/cancel.d.cts +110 -2
  544. package/dist/upload/cancel.d.cts.map +1 -1
  545. package/dist/upload/cancel.d.ts +110 -2
  546. package/dist/upload/cancel.d.ts.map +1 -1
  547. package/dist/upload/cancel.js +178 -9
  548. package/dist/upload/cancel.js.map +1 -1
  549. package/dist/upload/concurrency.cjs +79 -52
  550. package/dist/upload/concurrency.cjs.map +1 -1
  551. package/dist/upload/concurrency.js +79 -53
  552. package/dist/upload/concurrency.js.map +1 -1
  553. package/dist/upload/finish.cjs +59 -0
  554. package/dist/upload/finish.cjs.map +1 -0
  555. package/dist/upload/finish.d.cts +26 -0
  556. package/dist/upload/finish.d.cts.map +1 -0
  557. package/dist/upload/finish.d.ts +26 -0
  558. package/dist/upload/finish.d.ts.map +1 -0
  559. package/dist/upload/finish.js +59 -0
  560. package/dist/upload/finish.js.map +1 -0
  561. package/dist/upload/large.cjs +301 -218
  562. package/dist/upload/large.cjs.map +1 -1
  563. package/dist/upload/large.d.cts +76 -9
  564. package/dist/upload/large.d.cts.map +1 -1
  565. package/dist/upload/large.d.ts +76 -9
  566. package/dist/upload/large.d.ts.map +1 -1
  567. package/dist/upload/large.js +301 -218
  568. package/dist/upload/large.js.map +1 -1
  569. package/dist/upload/options.cjs +28 -0
  570. package/dist/upload/options.cjs.map +1 -0
  571. package/dist/upload/options.d.cts +104 -0
  572. package/dist/upload/options.d.cts.map +1 -0
  573. package/dist/upload/options.d.ts +104 -0
  574. package/dist/upload/options.d.ts.map +1 -0
  575. package/dist/upload/options.js +27 -0
  576. package/dist/upload/options.js.map +1 -0
  577. package/dist/upload/resume.cjs +333 -33
  578. package/dist/upload/resume.cjs.map +1 -1
  579. package/dist/upload/resume.d.cts +82 -12
  580. package/dist/upload/resume.d.cts.map +1 -1
  581. package/dist/upload/resume.d.ts +82 -12
  582. package/dist/upload/resume.d.ts.map +1 -1
  583. package/dist/upload/resume.js +330 -33
  584. package/dist/upload/resume.js.map +1 -1
  585. package/dist/upload/retry.cjs +186 -0
  586. package/dist/upload/retry.cjs.map +1 -0
  587. package/dist/upload/retry.d.cts +127 -0
  588. package/dist/upload/retry.d.cts.map +1 -0
  589. package/dist/upload/retry.d.ts +127 -0
  590. package/dist/upload/retry.d.ts.map +1 -0
  591. package/dist/upload/retry.js +182 -0
  592. package/dist/upload/retry.js.map +1 -0
  593. package/dist/upload/single.cjs +68 -44
  594. package/dist/upload/single.cjs.map +1 -1
  595. package/dist/upload/single.d.cts +2 -1
  596. package/dist/upload/single.d.cts.map +1 -1
  597. package/dist/upload/single.d.ts +2 -1
  598. package/dist/upload/single.d.ts.map +1 -1
  599. package/dist/upload/single.js +68 -44
  600. package/dist/upload/single.js.map +1 -1
  601. package/dist/upload/stream.cjs +317 -193
  602. package/dist/upload/stream.cjs.map +1 -1
  603. package/dist/upload/stream.d.cts +3 -1
  604. package/dist/upload/stream.d.cts.map +1 -1
  605. package/dist/upload/stream.d.ts +3 -1
  606. package/dist/upload/stream.d.ts.map +1 -1
  607. package/dist/upload/stream.js +316 -192
  608. package/dist/upload/stream.js.map +1 -1
  609. package/dist/util/best-effort.cjs +42 -8
  610. package/dist/util/best-effort.cjs.map +1 -1
  611. package/dist/util/best-effort.d.cts +2 -1
  612. package/dist/util/best-effort.d.cts.map +1 -1
  613. package/dist/util/best-effort.d.ts +2 -1
  614. package/dist/util/best-effort.d.ts.map +1 -1
  615. package/dist/util/best-effort.js +43 -9
  616. package/dist/util/best-effort.js.map +1 -1
  617. package/dist/util/bytes.cjs +23 -0
  618. package/dist/util/bytes.cjs.map +1 -0
  619. package/dist/util/bytes.d.cts +15 -0
  620. package/dist/util/bytes.d.cts.map +1 -0
  621. package/dist/util/bytes.d.ts +15 -0
  622. package/dist/util/bytes.d.ts.map +1 -0
  623. package/dist/util/bytes.js +23 -0
  624. package/dist/util/bytes.js.map +1 -0
  625. package/dist/util/crypto.cjs +68 -0
  626. package/dist/util/crypto.cjs.map +1 -0
  627. package/dist/util/crypto.d.cts +26 -0
  628. package/dist/util/crypto.d.cts.map +1 -0
  629. package/dist/util/crypto.d.ts +26 -0
  630. package/dist/util/crypto.d.ts.map +1 -0
  631. package/dist/util/crypto.js +66 -0
  632. package/dist/util/crypto.js.map +1 -0
  633. package/dist/util/defaults.cjs +25 -9
  634. package/dist/util/defaults.cjs.map +1 -1
  635. package/dist/util/defaults.js +26 -11
  636. package/dist/util/defaults.js.map +1 -1
  637. package/dist/util/error-reason.cjs +41 -0
  638. package/dist/util/error-reason.cjs.map +1 -0
  639. package/dist/util/error-reason.d.cts +9 -0
  640. package/dist/util/error-reason.d.cts.map +1 -0
  641. package/dist/util/error-reason.d.ts +9 -0
  642. package/dist/util/error-reason.d.ts.map +1 -0
  643. package/dist/util/error-reason.js +41 -0
  644. package/dist/util/error-reason.js.map +1 -0
  645. package/dist/util/http.cjs +23 -0
  646. package/dist/util/http.cjs.map +1 -0
  647. package/dist/util/http.d.cts +13 -0
  648. package/dist/util/http.d.cts.map +1 -0
  649. package/dist/util/http.d.ts +13 -0
  650. package/dist/util/http.d.ts.map +1 -0
  651. package/dist/util/http.js +23 -0
  652. package/dist/util/http.js.map +1 -0
  653. package/dist/util/normalize.cjs +66 -7
  654. package/dist/util/normalize.cjs.map +1 -1
  655. package/dist/util/normalize.js +67 -10
  656. package/dist/util/normalize.js.map +1 -1
  657. package/dist/util/paginator.cjs +63 -14
  658. package/dist/util/paginator.cjs.map +1 -1
  659. package/dist/util/paginator.js +64 -16
  660. package/dist/util/paginator.js.map +1 -1
  661. package/dist/util/plan-ranges.cjs +47 -22
  662. package/dist/util/plan-ranges.cjs.map +1 -1
  663. package/dist/util/plan-ranges.js +48 -24
  664. package/dist/util/plan-ranges.js.map +1 -1
  665. package/dist/util/sha1.cjs +27 -0
  666. package/dist/util/sha1.cjs.map +1 -0
  667. package/dist/util/sha1.d.cts +17 -0
  668. package/dist/util/sha1.d.cts.map +1 -0
  669. package/dist/util/sha1.d.ts +17 -0
  670. package/dist/util/sha1.d.ts.map +1 -0
  671. package/dist/util/sha1.js +26 -0
  672. package/dist/util/sha1.js.map +1 -0
  673. package/dist/util/text-codec.cjs +29 -5
  674. package/dist/util/text-codec.cjs.map +1 -1
  675. package/dist/util/text-codec.js +30 -7
  676. package/dist/util/text-codec.js.map +1 -1
  677. package/dist/util/to-error.cjs +18 -4
  678. package/dist/util/to-error.cjs.map +1 -1
  679. package/dist/util/to-error.js +19 -5
  680. package/dist/util/to-error.js.map +1 -1
  681. package/dist/version.cjs +17 -5
  682. package/dist/version.cjs.map +1 -1
  683. package/dist/version.d.cts +3 -3
  684. package/dist/version.d.ts +3 -3
  685. package/dist/version.js +19 -6
  686. package/dist/version.js.map +1 -1
  687. package/package.json +19 -16
  688. package/dist/auth/index.cjs.map +0 -1
  689. package/dist/auth/index.js.map +0 -1
  690. package/dist/index.cjs.map +0 -1
  691. package/dist/index.js.map +0 -1
  692. package/dist/notifications/index.cjs.map +0 -1
  693. package/dist/notifications/index.js.map +0 -1
  694. package/dist/package.json.cjs +0 -9
  695. package/dist/package.json.cjs.map +0 -1
  696. package/dist/package.json.js +0 -9
  697. package/dist/package.json.js.map +0 -1
  698. package/dist/streams/index.cjs.map +0 -1
  699. package/dist/streams/index.js.map +0 -1
  700. package/dist/sync/index.cjs.map +0 -1
  701. package/dist/sync/index.js.map +0 -1
@@ -1,57 +1,241 @@
1
1
  import { FileAction } from "../../types/file.js";
2
- class B2Folder {
3
- type = "b2";
4
- bucket;
5
- prefix;
6
- /**
7
- * Creates a new B2Folder for the given bucket and optional prefix.
8
- * @param bucket - The B2 bucket to scan.
9
- * @param prefix - Optional key prefix to restrict the scan scope.
10
- */
11
- constructor(bucket, prefix = "") {
12
- this.bucket = bucket;
13
- this.prefix = prefix;
14
- }
15
- /** Lists all file versions in the bucket, groups by name, and yields the latest visible version. */
16
- async *scan() {
17
- const grouped = /* @__PURE__ */ new Map();
18
- let startFileName;
19
- let startFileId;
20
- while (true) {
21
- const listing = await this.bucket.listFileVersions({
22
- ...this.prefix !== "" ? { prefix: this.prefix } : {},
23
- ...startFileName !== void 0 ? { startFileName } : {},
24
- ...startFileId !== void 0 ? { startFileId } : {}
25
- });
26
- for (const fv of listing.files) {
27
- const existing = grouped.get(fv.fileName);
28
- if (existing) {
29
- existing.push(fv);
30
- } else {
31
- grouped.set(fv.fileName, [fv]);
32
- }
33
- }
34
- if (!listing.nextFileName) break;
35
- startFileName = listing.nextFileName;
36
- startFileId = listing.nextFileId;
37
- }
38
- const sorted = [...grouped.entries()].sort((a, b) => a[0].localeCompare(b[0]));
39
- for (const [fileName, versions] of sorted) {
40
- versions.sort((a, b) => b.uploadTimestamp - a.uploadTimestamp);
41
- const selected = versions[0];
42
- if (!selected || selected.action === FileAction.Hide) continue;
43
- const relativePath = this.prefix !== "" ? fileName.slice(this.prefix.length) : fileName;
44
- yield {
45
- relativePath,
46
- modTimeMillis: selected.uploadTimestamp,
47
- size: selected.contentLength,
48
- selectedVersion: selected,
49
- allVersions: versions
50
- };
51
- }
52
- }
53
- }
54
- export {
55
- B2Folder
2
+ import { validateSyncFilters } from "../regexp-safety.js";
3
+ import { emitScannerSkip, regexpInputTooLongSkip } from "../scan-events.js";
4
+ import { literalPrefixForSyncFilters, pathPassesSyncFilters, pathSkippedByRegExpInputLimit } from "../filters.js";
5
+ import { compareCodeUnits, compareSyncRelativePaths } from "../path-order.js";
6
+ import { assertScanEntryLimit, scanEntryLimit } from "../scan-limit.js";
7
+ import { sanitizeErrorReason } from "../../util/error-reason.js";
8
+ import { isAbortError } from "../local-sha1.js";
9
+ import { selectB2ComparableSha1, syncSha1StateOf } from "../sha1-metadata.js";
10
+ import { assertSyncPathAllowed } from "../path-safety.js";
11
+ import { asRawB2KeyPrefix, b2KeyToRelativePathUnderPrefix, localFilesystemCanonicalSyncPath, localFilesystemSyncPathIsUnsafe } from "../prefix.js";
12
+ //#region src/sync/scanners/b2.ts
13
+ var MAX_EMPTY_B2_SCAN_PAGES = 100;
14
+ /**
15
+ * Scans a B2 bucket (optionally filtered by a raw B2 key prefix) and yields
16
+ * {@link B2SyncPath} entries sorted by `compareSyncRelativePaths(relativePath)`. Hidden files are excluded.
17
+ * Raw B2 file names are used only as an internal tie-breaker after collision handling.
18
+ * All versions for the listed prefix are fetched, grouped, and sorted before
19
+ * yielding; exclude filters are applied client-side and do not reduce that
20
+ * B2 listing memory footprint.
21
+ * SDK-reserved temporary names fail the scan because syncing them could corrupt
22
+ * in-progress transfers.
23
+ */
24
+ var B2Folder = class {
25
+ type = "b2";
26
+ appliesScanFilters = true;
27
+ appliesScanSorting = true;
28
+ /** Raw B2 key prefix this folder scans, preserving caller-provided separators verbatim. */
29
+ rawPrefix;
30
+ bucket;
31
+ /**
32
+ * Creates a new B2Folder for the given bucket and optional prefix.
33
+ * @param bucket - The B2 bucket to scan.
34
+ * @param prefix - Optional raw B2 key prefix to restrict the scan scope.
35
+ * Backslashes are preserved as raw B2 key characters; pass `/` explicitly for slash prefixes.
36
+ */
37
+ constructor(bucket, prefix = "") {
38
+ this.bucket = bucket;
39
+ this.rawPrefix = asRawB2KeyPrefix(prefix);
40
+ }
41
+ /**
42
+ * Lists all file versions in the bucket, groups by name, and yields the latest visible version.
43
+ * @param options - Optional scan controls.
44
+ */
45
+ async *scan(options = {}) {
46
+ validateSyncFilters(options);
47
+ const maxScanEntries = scanEntryLimit(options);
48
+ const grouped = /* @__PURE__ */ new Map();
49
+ const listPrefix = this.listPrefixFor(options);
50
+ let listedVersions = 0;
51
+ let startFileName;
52
+ let startFileId;
53
+ let emptyPageCount = 0;
54
+ while (true) {
55
+ if (scanIsAborted(options)) return;
56
+ let listing;
57
+ try {
58
+ listing = await this.bucket.listFileVersions({
59
+ ...listPrefix !== "" ? { prefix: listPrefix } : {},
60
+ ...startFileName !== void 0 ? { startFileName } : {},
61
+ ...startFileId !== void 0 ? { startFileId } : {},
62
+ ...options.signal !== void 0 ? { signal: options.signal } : {}
63
+ });
64
+ } catch (err) {
65
+ if (scanIsAborted(options) || isAbortError(err)) return;
66
+ throw emitScanError(options, "failed to scan B2 file versions", err);
67
+ }
68
+ if (scanIsAborted(options)) return;
69
+ if (listing.files.length === 0) {
70
+ emptyPageCount++;
71
+ if (emptyPageCount > MAX_EMPTY_B2_SCAN_PAGES) throw emitScanError(options, "failed to scan B2 file versions", /* @__PURE__ */ new Error("B2 pagination returned too many empty pages"));
72
+ } else emptyPageCount = 0;
73
+ for (const fv of listing.files) {
74
+ if (scanIsAborted(options)) return;
75
+ assertScanEntryLimit(listedVersions + 1, maxScanEntries);
76
+ listedVersions++;
77
+ if (this.rawPrefix !== "" && !fv.fileName.startsWith(this.rawPrefix)) {
78
+ this.emitSkip(options, fv.fileName, fv.fileName, "outside-prefix", `listed object is outside configured B2 prefix ${JSON.stringify(this.rawPrefix)}`);
79
+ continue;
80
+ }
81
+ if (options.requireLocalSafePaths === true && fv.fileName.includes("\\")) {
82
+ this.emitSkip(options, fv.fileName, fv.fileName, "local-unsafe-name", "object name contains a backslash that is unsafe for local filesystem destinations");
83
+ continue;
84
+ }
85
+ const relativePath = this.tryToRelativePath(fv.fileName);
86
+ if (relativePath === null) {
87
+ this.emitSkip(options, fv.fileName, fv.fileName, "unsafe-name", "object name cannot be represented as a safe sync relative path");
88
+ continue;
89
+ }
90
+ if (!pathPassesSyncFilters(relativePath, options)) {
91
+ if (pathSkippedByRegExpInputLimit(relativePath, options)) emitScannerSkip(options, {
92
+ ...regexpInputTooLongSkip(relativePath),
93
+ b2FileName: fv.fileName
94
+ });
95
+ continue;
96
+ }
97
+ const existing = grouped.get(fv.fileName);
98
+ if (existing) existing.versions.push(fv);
99
+ else grouped.set(fv.fileName, {
100
+ relativePath,
101
+ versions: [fv]
102
+ });
103
+ }
104
+ if (!listing.nextFileName) break;
105
+ if (listing.nextFileName === startFileName && (listing.nextFileId ?? void 0) === startFileId) throw emitScanError(options, "failed to scan B2 file versions", /* @__PURE__ */ new Error("B2 pagination did not advance"));
106
+ startFileName = listing.nextFileName;
107
+ startFileId = listing.nextFileId ?? void 0;
108
+ }
109
+ const visible = this.visibleCandidates(grouped, options);
110
+ const withoutRelativeCollisions = this.rejectRelativePathCollisions(visible, options);
111
+ const sorted = (options.requireLocalSafePaths === true ? this.rejectLocalPathCollisions(withoutRelativeCollisions, options) : withoutRelativeCollisions).sort((a, b) => compareSyncRelativePaths(a.relativePath, b.relativePath) || compareCodeUnits(a.fileName, b.fileName));
112
+ for (const { relativePath, versions, selectedVersion } of sorted) {
113
+ if (scanIsAborted(options)) return;
114
+ assertSyncPathAllowed(relativePath);
115
+ const contentSha1 = selectB2ComparableSha1(selectedVersion);
116
+ yield {
117
+ relativePath,
118
+ modTimeMillis: selectedVersion.uploadTimestamp,
119
+ size: selectedVersion.contentLength,
120
+ contentSha1,
121
+ contentSha1State: syncSha1StateOf({ contentSha1 }),
122
+ selectedVersion,
123
+ allVersions: versions
124
+ };
125
+ }
126
+ }
127
+ tryToRelativePath(fileName) {
128
+ try {
129
+ return b2KeyToRelativePathUnderPrefix(this.rawPrefix, fileName);
130
+ } catch {
131
+ return null;
132
+ }
133
+ }
134
+ listPrefixFor(filters) {
135
+ const filterPrefix = literalPrefixForSyncFilters(filters);
136
+ if (filterPrefix === "") return this.rawPrefix;
137
+ if (this.rawPrefix !== "" && !this.rawPrefix.endsWith("/")) return this.rawPrefix;
138
+ return `${this.rawPrefix}${rawPrefixBeforeNormalizedSeparator(filterPrefix)}`;
139
+ }
140
+ visibleCandidates(grouped, filters) {
141
+ const visible = [];
142
+ for (const [fileName, entry] of grouped) {
143
+ entry.versions.sort((a, b) => b.uploadTimestamp - a.uploadTimestamp);
144
+ const selected = entry.versions[0];
145
+ if (!selected || selected.action === FileAction.Hide) continue;
146
+ if (filters?.requireLocalSafePaths === true && localFilesystemSyncPathIsUnsafe(entry.relativePath)) {
147
+ this.emitSkip(filters, entry.relativePath, fileName, "local-unsafe-name", "object name is unsafe for a local filesystem destination");
148
+ continue;
149
+ }
150
+ visible.push({
151
+ fileName,
152
+ relativePath: entry.relativePath,
153
+ versions: entry.versions,
154
+ selectedVersion: selected
155
+ });
156
+ }
157
+ return visible;
158
+ }
159
+ rejectRelativePathCollisions(candidates, filters) {
160
+ const accepted = [];
161
+ const owners = /* @__PURE__ */ new Map();
162
+ const collidedRelativePaths = /* @__PURE__ */ new Set();
163
+ for (const candidate of candidates) {
164
+ if (collidedRelativePaths.has(candidate.relativePath)) {
165
+ this.emitSkip(filters, candidate.relativePath, candidate.fileName, "relative-path-collision", "object normalizes to a relative path already rejected because of another raw B2 key");
166
+ continue;
167
+ }
168
+ const owner = owners.get(candidate.relativePath);
169
+ if (owner !== void 0 && owner.fileName !== candidate.fileName) {
170
+ owners.delete(candidate.relativePath);
171
+ removeAcceptedCandidate(accepted, owner);
172
+ collidedRelativePaths.add(candidate.relativePath);
173
+ this.emitSkip(filters, candidate.relativePath, owner.fileName, "relative-path-collision", `object normalizes to the same relative path as ${JSON.stringify(candidate.fileName)}`);
174
+ this.emitSkip(filters, candidate.relativePath, candidate.fileName, "relative-path-collision", `object normalizes to the same relative path as ${JSON.stringify(owner.fileName)}`);
175
+ continue;
176
+ }
177
+ owners.set(candidate.relativePath, candidate);
178
+ accepted.push(candidate);
179
+ }
180
+ return accepted;
181
+ }
182
+ rejectLocalPathCollisions(candidates, filters) {
183
+ const accepted = [];
184
+ const owners = /* @__PURE__ */ new Map();
185
+ const collidedLocalPaths = /* @__PURE__ */ new Set();
186
+ for (const candidate of candidates) {
187
+ const canonicalPath = localFilesystemCanonicalSyncPath(candidate.relativePath);
188
+ if (collidedLocalPaths.has(canonicalPath)) {
189
+ this.emitSkip(filters, candidate.relativePath, candidate.fileName, "local-path-collision", "object collides with another object on case-insensitive or Unicode-normalizing filesystems");
190
+ continue;
191
+ }
192
+ const owner = owners.get(canonicalPath);
193
+ if (owner !== void 0) {
194
+ owners.delete(canonicalPath);
195
+ removeAcceptedCandidate(accepted, owner);
196
+ collidedLocalPaths.add(canonicalPath);
197
+ this.emitSkip(filters, owner.relativePath, owner.fileName, "local-path-collision", `object collides with ${JSON.stringify(candidate.fileName)} on local filesystems`);
198
+ this.emitSkip(filters, candidate.relativePath, candidate.fileName, "local-path-collision", `object collides with ${JSON.stringify(owner.fileName)} on local filesystems`);
199
+ continue;
200
+ }
201
+ owners.set(canonicalPath, candidate);
202
+ accepted.push(candidate);
203
+ }
204
+ return accepted;
205
+ }
206
+ emitSkip(filters, path, b2FileName, reason, message) {
207
+ emitScannerSkip(filters, {
208
+ type: "skip",
209
+ path,
210
+ size: 0,
211
+ message: `Skipped B2 object ${JSON.stringify(b2FileName)}: ${message}`,
212
+ reason,
213
+ b2FileName
214
+ });
215
+ }
56
216
  };
57
- //# sourceMappingURL=b2.js.map
217
+ function rawPrefixBeforeNormalizedSeparator(filterPrefix) {
218
+ const separatorIndex = filterPrefix.indexOf("/");
219
+ return separatorIndex === -1 ? filterPrefix : filterPrefix.slice(0, separatorIndex);
220
+ }
221
+ function emitScanError(options, message, err) {
222
+ const event = {
223
+ type: "error",
224
+ path: "",
225
+ size: 0,
226
+ message: `${message}: ${sanitizeErrorReason(err)}`
227
+ };
228
+ options.onError?.(event);
229
+ return new Error(event.message);
230
+ }
231
+ function removeAcceptedCandidate(candidates, target) {
232
+ const index = candidates.indexOf(target);
233
+ if (index !== -1) candidates.splice(index, 1);
234
+ }
235
+ function scanIsAborted(filters) {
236
+ return filters?.signal?.aborted === true;
237
+ }
238
+ //#endregion
239
+ export { B2Folder };
240
+
241
+ //# sourceMappingURL=b2.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"b2.js","sources":["../../../src/sync/scanners/b2.ts"],"sourcesContent":["import type { Bucket } from '../../bucket.ts'\nimport { FileAction, type FileVersion } from '../../types/file.ts'\nimport type { B2SyncPath, SyncFolder } from '../types.ts'\n\n/**\n * Scans a B2 bucket (optionally filtered by prefix) and yields {@link B2SyncPath} entries\n * sorted by file name. Hidden files are excluded. All versions are fetched and grouped.\n */\nexport class B2Folder implements SyncFolder {\n readonly type = 'b2' as const\n private readonly bucket: Bucket\n private readonly prefix: string\n\n /**\n * Creates a new B2Folder for the given bucket and optional prefix.\n * @param bucket - The B2 bucket to scan.\n * @param prefix - Optional key prefix to restrict the scan scope.\n */\n constructor(bucket: Bucket, prefix = '') {\n this.bucket = bucket\n this.prefix = prefix\n }\n\n /** Lists all file versions in the bucket, groups by name, and yields the latest visible version. */\n async *scan(): AsyncGenerator<B2SyncPath> {\n const grouped = new Map<string, FileVersion[]>()\n\n let startFileName: string | undefined\n let startFileId: string | undefined\n\n while (true) {\n const listing = await this.bucket.listFileVersions({\n ...(this.prefix !== '' ? { prefix: this.prefix } : {}),\n ...(startFileName !== undefined ? { startFileName } : {}),\n ...(startFileId !== undefined\n ? { startFileId: startFileId as import('../../types/ids.ts').FileId }\n : {}),\n })\n\n for (const fv of listing.files) {\n const existing = grouped.get(fv.fileName)\n if (existing) {\n existing.push(fv)\n } else {\n grouped.set(fv.fileName, [fv])\n }\n }\n\n if (!listing.nextFileName) break\n startFileName = listing.nextFileName\n startFileId = listing.nextFileId as string | undefined\n }\n\n const sorted = [...grouped.entries()].sort((a, b) => a[0].localeCompare(b[0]))\n\n for (const [fileName, versions] of sorted) {\n versions.sort((a, b) => b.uploadTimestamp - a.uploadTimestamp)\n const selected = versions[0]\n if (!selected || selected.action === FileAction.Hide) continue\n\n const relativePath = this.prefix !== '' ? fileName.slice(this.prefix.length) : fileName\n\n yield {\n relativePath,\n modTimeMillis: selected.uploadTimestamp,\n size: selected.contentLength,\n selectedVersion: selected,\n allVersions: versions,\n }\n }\n }\n}\n"],"names":[],"mappings":";AAQO,MAAM,SAA+B;AAAA,EACjC,OAAO;AAAA,EACC;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOjB,YAAY,QAAgB,SAAS,IAAI;AACvC,SAAK,SAAS;AACd,SAAK,SAAS;AAAA,EAChB;AAAA;AAAA,EAGA,OAAO,OAAmC;AACxC,UAAM,8BAAc,IAAA;AAEpB,QAAI;AACJ,QAAI;AAEJ,WAAO,MAAM;AACX,YAAM,UAAU,MAAM,KAAK,OAAO,iBAAiB;AAAA,QACjD,GAAI,KAAK,WAAW,KAAK,EAAE,QAAQ,KAAK,OAAA,IAAW,CAAA;AAAA,QACnD,GAAI,kBAAkB,SAAY,EAAE,cAAA,IAAkB,CAAA;AAAA,QACtD,GAAI,gBAAgB,SAChB,EAAE,gBACF,CAAA;AAAA,MAAC,CACN;AAED,iBAAW,MAAM,QAAQ,OAAO;AAC9B,cAAM,WAAW,QAAQ,IAAI,GAAG,QAAQ;AACxC,YAAI,UAAU;AACZ,mBAAS,KAAK,EAAE;AAAA,QAClB,OAAO;AACL,kBAAQ,IAAI,GAAG,UAAU,CAAC,EAAE,CAAC;AAAA,QAC/B;AAAA,MACF;AAEA,UAAI,CAAC,QAAQ,aAAc;AAC3B,sBAAgB,QAAQ;AACxB,oBAAc,QAAQ;AAAA,IACxB;AAEA,UAAM,SAAS,CAAC,GAAG,QAAQ,QAAA,CAAS,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC;AAE7E,eAAW,CAAC,UAAU,QAAQ,KAAK,QAAQ;AACzC,eAAS,KAAK,CAAC,GAAG,MAAM,EAAE,kBAAkB,EAAE,eAAe;AAC7D,YAAM,WAAW,SAAS,CAAC;AAC3B,UAAI,CAAC,YAAY,SAAS,WAAW,WAAW,KAAM;AAEtD,YAAM,eAAe,KAAK,WAAW,KAAK,SAAS,MAAM,KAAK,OAAO,MAAM,IAAI;AAE/E,YAAM;AAAA,QACJ;AAAA,QACA,eAAe,SAAS;AAAA,QACxB,MAAM,SAAS;AAAA,QACf,iBAAiB;AAAA,QACjB,aAAa;AAAA,MAAA;AAAA,IAEjB;AAAA,EACF;AACF;"}
1
+ {"version":3,"file":"b2.js","names":[],"sources":["../../../src/sync/scanners/b2.ts"],"sourcesContent":["import type { Bucket } from '../../bucket.ts'\nimport { FileAction, type FileVersion } from '../../types/file.ts'\nimport type { FileId } from '../../types/ids.ts'\nimport { sanitizeErrorReason } from '../../util/error-reason.ts'\nimport {\n literalPrefixForSyncFilters,\n pathPassesSyncFilters,\n pathSkippedByRegExpInputLimit,\n} from '../filters.ts'\nimport { isAbortError } from '../local-sha1.ts'\nimport { compareCodeUnits, compareSyncRelativePaths } from '../path-order.ts'\nimport { assertSyncPathAllowed } from '../paths.ts'\nimport {\n asRawB2KeyPrefix,\n b2KeyToRelativePathUnderPrefix,\n localFilesystemCanonicalSyncPath,\n localFilesystemSyncPathIsUnsafe,\n} from '../prefix.ts'\nimport { validateSyncFilters } from '../regexp-safety.ts'\nimport { emitScannerSkip, regexpInputTooLongSkip } from '../scan-events.ts'\nimport { assertScanEntryLimit, scanEntryLimit } from '../scan-limit.ts'\nimport { selectB2ComparableSha1, syncSha1StateOf } from '../sha1-metadata.ts'\nimport type {\n B2SyncPath,\n SyncErrorEvent,\n SyncFolder,\n SyncScanOptions,\n SyncSkipReason,\n} from '../types.ts'\n\nconst MAX_EMPTY_B2_SCAN_PAGES = 100\n\ninterface B2ScanEntry {\n relativePath: string\n versions: FileVersion[]\n}\n\ninterface VisibleB2ScanEntry extends B2ScanEntry {\n fileName: string\n selectedVersion: FileVersion\n}\n\n/**\n * Scans a B2 bucket (optionally filtered by a raw B2 key prefix) and yields\n * {@link B2SyncPath} entries sorted by `compareSyncRelativePaths(relativePath)`. Hidden files are excluded.\n * Raw B2 file names are used only as an internal tie-breaker after collision handling.\n * All versions for the listed prefix are fetched, grouped, and sorted before\n * yielding; exclude filters are applied client-side and do not reduce that\n * B2 listing memory footprint.\n * SDK-reserved temporary names fail the scan because syncing them could corrupt\n * in-progress transfers.\n */\nexport class B2Folder implements SyncFolder {\n readonly type = 'b2' as const\n readonly appliesScanFilters = true as const\n readonly appliesScanSorting = true as const\n /** Raw B2 key prefix this folder scans, preserving caller-provided separators verbatim. */\n readonly rawPrefix: string\n private readonly bucket: Bucket\n\n /**\n * Creates a new B2Folder for the given bucket and optional prefix.\n * @param bucket - The B2 bucket to scan.\n * @param prefix - Optional raw B2 key prefix to restrict the scan scope.\n * Backslashes are preserved as raw B2 key characters; pass `/` explicitly for slash prefixes.\n */\n constructor(bucket: Bucket, prefix = '') {\n this.bucket = bucket\n this.rawPrefix = asRawB2KeyPrefix(prefix)\n }\n\n /**\n * Lists all file versions in the bucket, groups by name, and yields the latest visible version.\n * @param options - Optional scan controls.\n */\n // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: pagination, grouping, and filtering stay in one async iterator.\n async *scan(options: SyncScanOptions = {}): AsyncGenerator<B2SyncPath> {\n validateSyncFilters(options)\n const maxScanEntries = scanEntryLimit(options)\n const grouped = new Map<string, B2ScanEntry>()\n const listPrefix = this.listPrefixFor(options)\n\n let listedVersions = 0\n let startFileName: string | undefined\n let startFileId: FileId | undefined\n let emptyPageCount = 0\n\n while (true) {\n if (scanIsAborted(options)) return\n\n let listing: Awaited<ReturnType<Bucket['listFileVersions']>>\n try {\n listing = await this.bucket.listFileVersions({\n ...(listPrefix !== '' ? { prefix: listPrefix } : {}),\n ...(startFileName !== undefined ? { startFileName } : {}),\n ...(startFileId !== undefined ? { startFileId } : {}),\n ...(options.signal !== undefined ? { signal: options.signal } : {}),\n })\n } catch (err) {\n if (scanIsAborted(options) || isAbortError(err)) return\n throw emitScanError(options, 'failed to scan B2 file versions', err)\n }\n if (scanIsAborted(options)) return\n\n if (listing.files.length === 0) {\n emptyPageCount++\n if (emptyPageCount > MAX_EMPTY_B2_SCAN_PAGES) {\n throw emitScanError(\n options,\n 'failed to scan B2 file versions',\n new Error('B2 pagination returned too many empty pages'),\n )\n }\n } else {\n emptyPageCount = 0\n }\n\n for (const fv of listing.files) {\n if (scanIsAborted(options)) return\n assertScanEntryLimit(listedVersions + 1, maxScanEntries)\n listedVersions++\n\n // Real B2 honors the prefix in listFileVersions, but custom\n // transports and the simulator can over-return. Guard before\n // stripping the raw prefix so relativePath is never corrupted.\n if (this.rawPrefix !== '' && !fv.fileName.startsWith(this.rawPrefix)) {\n this.emitSkip(\n options,\n fv.fileName,\n fv.fileName,\n 'outside-prefix',\n `listed object is outside configured B2 prefix ${JSON.stringify(this.rawPrefix)}`,\n )\n continue\n }\n\n if (options.requireLocalSafePaths === true && fv.fileName.includes('\\\\')) {\n this.emitSkip(\n options,\n fv.fileName,\n fv.fileName,\n 'local-unsafe-name',\n 'object name contains a backslash that is unsafe for local filesystem destinations',\n )\n continue\n }\n\n const relativePath = this.tryToRelativePath(fv.fileName)\n if (relativePath === null) {\n this.emitSkip(\n options,\n fv.fileName,\n fv.fileName,\n 'unsafe-name',\n 'object name cannot be represented as a safe sync relative path',\n )\n continue\n }\n\n if (!pathPassesSyncFilters(relativePath, options)) {\n if (pathSkippedByRegExpInputLimit(relativePath, options)) {\n emitScannerSkip(options, {\n ...regexpInputTooLongSkip(relativePath),\n b2FileName: fv.fileName,\n })\n }\n continue\n }\n\n const existing = grouped.get(fv.fileName)\n if (existing) {\n existing.versions.push(fv)\n } else {\n grouped.set(fv.fileName, { relativePath, versions: [fv] })\n }\n }\n\n if (!listing.nextFileName) break\n if (\n listing.nextFileName === startFileName &&\n (listing.nextFileId ?? undefined) === startFileId\n ) {\n throw emitScanError(\n options,\n 'failed to scan B2 file versions',\n new Error('B2 pagination did not advance'),\n )\n }\n startFileName = listing.nextFileName\n startFileId = listing.nextFileId ?? undefined\n }\n\n const visible = this.visibleCandidates(grouped, options)\n const withoutRelativeCollisions = this.rejectRelativePathCollisions(visible, options)\n const safeCandidates =\n options.requireLocalSafePaths === true\n ? this.rejectLocalPathCollisions(withoutRelativeCollisions, options)\n : withoutRelativeCollisions\n const sorted = safeCandidates.sort(\n (a, b) =>\n compareSyncRelativePaths(a.relativePath, b.relativePath) ||\n compareCodeUnits(a.fileName, b.fileName),\n )\n\n for (const { relativePath, versions, selectedVersion } of sorted) {\n if (scanIsAborted(options)) return\n // Reserved SDK temp names are a hard safety failure, not an ordinary filter.\n assertSyncPathAllowed(relativePath)\n const contentSha1 = selectB2ComparableSha1(selectedVersion)\n yield {\n relativePath,\n modTimeMillis: selectedVersion.uploadTimestamp,\n size: selectedVersion.contentLength,\n contentSha1,\n contentSha1State: syncSha1StateOf({ contentSha1 }),\n selectedVersion,\n allVersions: versions,\n }\n }\n }\n\n private tryToRelativePath(fileName: string): string | null {\n try {\n return b2KeyToRelativePathUnderPrefix(this.rawPrefix, fileName)\n } catch {\n return null\n }\n }\n\n private listPrefixFor(filters: SyncScanOptions | undefined): string {\n const filterPrefix = literalPrefixForSyncFilters(filters)\n if (filterPrefix === '') return this.rawPrefix\n if (this.rawPrefix !== '' && !this.rawPrefix.endsWith('/')) return this.rawPrefix\n return `${this.rawPrefix}${rawPrefixBeforeNormalizedSeparator(filterPrefix)}`\n }\n\n private visibleCandidates(\n grouped: Map<string, B2ScanEntry>,\n filters: SyncScanOptions | undefined,\n ): VisibleB2ScanEntry[] {\n const visible: VisibleB2ScanEntry[] = []\n\n for (const [fileName, entry] of grouped) {\n entry.versions.sort((a, b) => b.uploadTimestamp - a.uploadTimestamp)\n const selected = entry.versions[0]\n if (!selected || selected.action === FileAction.Hide) continue\n\n if (\n filters?.requireLocalSafePaths === true &&\n localFilesystemSyncPathIsUnsafe(entry.relativePath)\n ) {\n this.emitSkip(\n filters,\n entry.relativePath,\n fileName,\n 'local-unsafe-name',\n 'object name is unsafe for a local filesystem destination',\n )\n continue\n }\n\n visible.push({\n fileName,\n relativePath: entry.relativePath,\n versions: entry.versions,\n selectedVersion: selected,\n })\n }\n\n return visible\n }\n\n private rejectRelativePathCollisions(\n candidates: VisibleB2ScanEntry[],\n filters: SyncScanOptions | undefined,\n ): VisibleB2ScanEntry[] {\n const accepted: VisibleB2ScanEntry[] = []\n const owners = new Map<string, VisibleB2ScanEntry>()\n const collidedRelativePaths = new Set<string>()\n\n for (const candidate of candidates) {\n if (collidedRelativePaths.has(candidate.relativePath)) {\n this.emitSkip(\n filters,\n candidate.relativePath,\n candidate.fileName,\n 'relative-path-collision',\n 'object normalizes to a relative path already rejected because of another raw B2 key',\n )\n continue\n }\n\n const owner = owners.get(candidate.relativePath)\n if (owner !== undefined && owner.fileName !== candidate.fileName) {\n owners.delete(candidate.relativePath)\n removeAcceptedCandidate(accepted, owner)\n collidedRelativePaths.add(candidate.relativePath)\n this.emitSkip(\n filters,\n candidate.relativePath,\n owner.fileName,\n 'relative-path-collision',\n `object normalizes to the same relative path as ${JSON.stringify(candidate.fileName)}`,\n )\n this.emitSkip(\n filters,\n candidate.relativePath,\n candidate.fileName,\n 'relative-path-collision',\n `object normalizes to the same relative path as ${JSON.stringify(owner.fileName)}`,\n )\n continue\n }\n\n owners.set(candidate.relativePath, candidate)\n accepted.push(candidate)\n }\n\n return accepted\n }\n\n private rejectLocalPathCollisions(\n candidates: VisibleB2ScanEntry[],\n filters: SyncScanOptions | undefined,\n ): VisibleB2ScanEntry[] {\n const accepted: VisibleB2ScanEntry[] = []\n const owners = new Map<string, VisibleB2ScanEntry>()\n const collidedLocalPaths = new Set<string>()\n\n for (const candidate of candidates) {\n const canonicalPath = localFilesystemCanonicalSyncPath(candidate.relativePath)\n if (collidedLocalPaths.has(canonicalPath)) {\n this.emitSkip(\n filters,\n candidate.relativePath,\n candidate.fileName,\n 'local-path-collision',\n 'object collides with another object on case-insensitive or Unicode-normalizing filesystems',\n )\n continue\n }\n\n const owner = owners.get(canonicalPath)\n if (owner !== undefined) {\n owners.delete(canonicalPath)\n removeAcceptedCandidate(accepted, owner)\n collidedLocalPaths.add(canonicalPath)\n this.emitSkip(\n filters,\n owner.relativePath,\n owner.fileName,\n 'local-path-collision',\n `object collides with ${JSON.stringify(candidate.fileName)} on local filesystems`,\n )\n this.emitSkip(\n filters,\n candidate.relativePath,\n candidate.fileName,\n 'local-path-collision',\n `object collides with ${JSON.stringify(owner.fileName)} on local filesystems`,\n )\n continue\n }\n\n owners.set(canonicalPath, candidate)\n accepted.push(candidate)\n }\n\n return accepted\n }\n\n private emitSkip(\n filters: SyncScanOptions | undefined,\n path: string,\n b2FileName: string,\n reason: SyncSkipReason,\n message: string,\n ): void {\n emitScannerSkip(filters, {\n type: 'skip',\n path,\n size: 0,\n message: `Skipped B2 object ${JSON.stringify(b2FileName)}: ${message}`,\n reason,\n b2FileName,\n })\n }\n}\n\nfunction rawPrefixBeforeNormalizedSeparator(filterPrefix: string): string {\n const separatorIndex = filterPrefix.indexOf('/')\n return separatorIndex === -1 ? filterPrefix : filterPrefix.slice(0, separatorIndex)\n}\n\nfunction emitScanError(options: SyncScanOptions, message: string, err: unknown): Error {\n const event: SyncErrorEvent = {\n type: 'error',\n path: '',\n size: 0,\n message: `${message}: ${sanitizeErrorReason(err)}`,\n }\n options.onError?.(event)\n return new Error(event.message)\n}\n\nfunction removeAcceptedCandidate(\n candidates: VisibleB2ScanEntry[],\n target: VisibleB2ScanEntry,\n): void {\n const index = candidates.indexOf(target)\n if (index !== -1) candidates.splice(index, 1)\n}\n\nfunction scanIsAborted(filters: SyncScanOptions | undefined): boolean {\n return filters?.signal?.aborted === true\n}\n"],"mappings":"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"}
@@ -1,58 +1,217 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const promises = require("node:fs/promises");
4
- const node_path = require("node:path");
5
- class LocalFolder {
6
- type = "local";
7
- /** Absolute path to the local root directory. */
8
- root;
9
- /**
10
- * Creates a new LocalFolder for the given root directory.
11
- * @param root - Absolute path to the local directory to scan.
12
- */
13
- constructor(root) {
14
- this.root = root;
15
- }
16
- /** Recursively walks the directory and yields files sorted by relative path. */
17
- async *scan() {
18
- const collected = [];
19
- await this.walk(this.root, collected);
20
- collected.sort((a, b) => a.relativePath.localeCompare(b.relativePath));
21
- for (const entry of collected) {
22
- yield entry;
23
- }
24
- }
25
- /**
26
- * Recursively collects files from {@link dir} into {@link out}.
27
- * @param dir - Absolute path of the directory to scan.
28
- * @param out - Accumulator array that receives discovered file entries.
29
- */
30
- async walk(dir, out) {
31
- let entries;
32
- try {
33
- entries = await promises.readdir(dir, { withFileTypes: true });
34
- } catch {
35
- return;
36
- }
37
- for (const entry of entries) {
38
- const fullPath = node_path.join(dir, entry.name);
39
- if (entry.isDirectory()) {
40
- await this.walk(fullPath, out);
41
- } else if (entry.isFile()) {
42
- try {
43
- const s = await promises.stat(fullPath);
44
- const rel = node_path.relative(this.root, fullPath).split(node_path.sep).join("/");
45
- out.push({
46
- relativePath: rel,
47
- absolutePath: fullPath,
48
- modTimeMillis: Math.floor(s.mtimeMs),
49
- size: s.size
50
- });
51
- } catch {
52
- }
53
- }
54
- }
55
- }
1
+ const require_regexp_safety = require("../regexp-safety.cjs");
2
+ const require_scan_events = require("../scan-events.cjs");
3
+ const require_filters = require("../filters.cjs");
4
+ const require_path_order = require("../path-order.cjs");
5
+ const require_scan_limit = require("../scan-limit.cjs");
6
+ const require_local_file_identity = require("../local-file-identity.cjs");
7
+ const require_path_safety = require("../path-safety.cjs");
8
+ const require_download_staging = require("../download-staging.cjs");
9
+ const require_filesystem_errors = require("../filesystem-errors.cjs");
10
+ const require_local_filesystem_root = require("../local-filesystem-root.cjs");
11
+ //#region src/sync/scanners/local.ts
12
+ /**
13
+ * Scans a local directory tree and yields {@link LocalSyncPath} entries sorted by relative path.
14
+ * A root directory read failure aborts the scan with an error diagnostic. Per-entry file or
15
+ * directory failures are reported through `onError` and the scan continues over readable siblings.
16
+ * SDK-managed partial download file names are skipped so unfinished internal
17
+ * temp files are not synchronized.
18
+ * The current implementation collects matching entries before sorting, so memory usage is
19
+ * proportional to the number of matched files.
20
+ */
21
+ var LocalFolder = class {
22
+ type = "local";
23
+ appliesScanFilters = true;
24
+ appliesScanSorting = true;
25
+ /** Resolved absolute path to the local root directory. */
26
+ root;
27
+ /**
28
+ * Creates a new LocalFolder for the given root directory.
29
+ * @param root - Absolute or relative path to the local directory to scan.
30
+ */
31
+ constructor(root) {
32
+ this.root = resolvePathAtConstruction(root);
33
+ require_local_filesystem_root.registerLocalFilesystemRoot(this);
34
+ }
35
+ /**
36
+ * Recursively walks the directory and yields files in sync path order.
37
+ * @param options - Optional scan controls.
38
+ */
39
+ async *scan(options = {}) {
40
+ require_regexp_safety.validateSyncFilters(options);
41
+ const nodeDeps = await loadLocalNodeDeps();
42
+ const root = nodeDeps.resolve(this.root);
43
+ const collected = [];
44
+ await this.walk(root, root, collected, options, require_scan_limit.scanEntryLimit(options), nodeDeps);
45
+ collected.sort((a, b) => require_path_order.compareSyncRelativePaths(a.relativePath, b.relativePath));
46
+ for (const entry of collected) {
47
+ throwIfScanAborted(options);
48
+ yield entry;
49
+ }
50
+ }
51
+ /**
52
+ * Recursively collects files from {@link dir} into {@link out}.
53
+ * @param root - Resolved scan root used for relative path calculation.
54
+ * @param dir - Absolute path of the directory to scan.
55
+ * @param out - Accumulator array that receives discovered file entries.
56
+ * @param options - Optional scan controls.
57
+ * @param maxScanEntries - Maximum number of entries to retain before failing.
58
+ * @param nodeDeps - Lazy-loaded Node filesystem and path helpers.
59
+ */
60
+ async walk(root, dir, out, options, maxScanEntries, nodeDeps) {
61
+ throwIfScanAborted(options);
62
+ let entries;
63
+ try {
64
+ entries = await nodeDeps.readdir(dir, { withFileTypes: true });
65
+ } catch (err) {
66
+ const error = this.emitScanError(options, relativePathFromRoot(root, dir, nodeDeps), "directory", err);
67
+ if (dir === root) throw error;
68
+ return;
69
+ }
70
+ for (const entry of entries) {
71
+ throwIfScanAborted(options);
72
+ const fullPath = nodeDeps.join(dir, entry.name);
73
+ const rel = relativePathFromRoot(root, fullPath, nodeDeps);
74
+ if (require_download_staging.isDownloadStagingDirectorySegment(rel) && entry.isDirectory() && require_download_staging.isDownloadStagingDirectorySegment(entry.name) && await require_download_staging.isManagedDownloadStagingRoot(fullPath)) continue;
75
+ if (rel.includes("\\")) {
76
+ require_scan_events.emitScannerSkip(options, {
77
+ type: "skip",
78
+ path: rel,
79
+ size: 0,
80
+ reason: "unsafe-name",
81
+ message: `Skipped local path ${JSON.stringify(rel)}: backslashes are not safe sync path characters`
82
+ });
83
+ continue;
84
+ }
85
+ if (require_path_safety.isReservedSyncTempFileName(entry.name)) {
86
+ require_scan_events.emitScannerSkip(options, {
87
+ type: "skip",
88
+ path: rel,
89
+ size: 0,
90
+ reason: "stale-download-partial",
91
+ message: `Skipped local path ${JSON.stringify(rel)}: reserved SDK partial download file`
92
+ });
93
+ continue;
94
+ }
95
+ if (entry.isDirectory()) {
96
+ if (require_filters.directoryMayContainSyncPaths(rel, options)) await this.walk(root, fullPath, out, options, maxScanEntries, nodeDeps);
97
+ } else if (entry.isFile()) {
98
+ if (!require_filters.pathPassesSyncFilters(rel, options)) {
99
+ if (require_filters.pathSkippedByRegExpInputLimit(rel, options)) require_scan_events.emitScannerSkip(options, require_scan_events.regexpInputTooLongSkip(rel));
100
+ continue;
101
+ }
102
+ let s;
103
+ try {
104
+ s = await nodeDeps.lstat(fullPath);
105
+ /* v8 ignore start -- lstat race after a Dirent file result is not deterministic */
106
+ if (!s.isFile()) {
107
+ this.emitScanError(options, rel, "file", /* @__PURE__ */ new Error("not a regular file"));
108
+ continue;
109
+ }
110
+ } catch (err) {
111
+ /* v8 ignore next -- stat TOCTOU failures are not deterministic to trigger */
112
+ this.emitScanError(options, relativePathFromRoot(root, fullPath, nodeDeps), "file", err);
113
+ continue;
114
+ }
115
+ require_scan_limit.assertScanEntryLimit(out.length + 1, maxScanEntries);
116
+ out.push({
117
+ relativePath: rel,
118
+ absolutePath: fullPath,
119
+ modTimeMillis: Math.floor(s.mtimeMs),
120
+ size: s.size,
121
+ fileIdentity: require_local_file_identity.localFileIdentityFromStats(s)
122
+ });
123
+ }
124
+ }
125
+ }
126
+ emitScanError(options, path, kind, err) {
127
+ const event = {
128
+ type: "error",
129
+ path,
130
+ size: 0,
131
+ message: `failed to scan local ${kind}: ${require_filesystem_errors.localFilesystemErrorReason(err)}`
132
+ };
133
+ options.onError?.(event);
134
+ return new Error(event.message);
135
+ }
136
+ };
137
+ async function loadLocalNodeDeps() {
138
+ const [fsPromises, path] = await Promise.all([import("node:fs/promises"), import("node:path")]);
139
+ return {
140
+ readdir: fsPromises.readdir,
141
+ lstat: fsPromises.lstat,
142
+ join: path.join,
143
+ relative: path.relative,
144
+ resolve: path.resolve,
145
+ sep: path.sep
146
+ };
56
147
  }
148
+ function resolvePathAtConstruction(root) {
149
+ const processLike = globalThis.process;
150
+ if (typeof processLike?.cwd !== "function") return root;
151
+ const cwd = processLike.cwd();
152
+ if (processLike.platform === "win32") return resolveWindowsPath(cwd, root);
153
+ return resolvePosixPath(cwd, root);
154
+ }
155
+ function resolvePosixPath(cwd, root) {
156
+ const resolved = normalizePathSegments((root.startsWith("/") ? root : `${cwd}/${root}`).split("/"), "/");
157
+ return resolved === "" ? "/" : `/${resolved}`;
158
+ }
159
+ function resolveWindowsPath(cwd, root) {
160
+ const normalizedRoot = root.replaceAll("/", "\\");
161
+ const normalizedCwd = cwd.replaceAll("/", "\\");
162
+ const drive = /^[A-Za-z]:/.exec(normalizedCwd)?.[0] ?? "";
163
+ const cwdUnc = splitUncPath(normalizedCwd);
164
+ if (/^\\\\/.test(normalizedRoot)) return normalizeUncPath(normalizedRoot);
165
+ if (/^[A-Za-z]:\\/.test(normalizedRoot)) return joinWindowsRoot(normalizedRoot.slice(0, 2), normalizePathSegments(normalizedRoot.slice(3).split("\\"), "\\"));
166
+ if (/^[A-Za-z]:/.test(normalizedRoot)) throw new Error("LocalFolder root must not be a drive-relative Windows path");
167
+ if (normalizedRoot.startsWith("\\")) {
168
+ const rest = normalizePathSegments(normalizedRoot.slice(1).split("\\"), "\\");
169
+ return joinWindowsRoot(cwdUnc?.prefix ?? drive, rest);
170
+ }
171
+ if (cwdUnc !== void 0) {
172
+ const resolved = normalizePathSegments([...cwdUnc.rest, ...normalizedRoot.split("\\")], "\\");
173
+ return joinWindowsRoot(cwdUnc.prefix, resolved);
174
+ }
175
+ const base = /^[A-Za-z]:\\/.test(normalizedCwd) ? normalizedCwd : `${drive}\\`;
176
+ const prefix = /^[A-Za-z]:/.exec(base)?.[0] ?? drive;
177
+ return joinWindowsRoot(prefix, normalizePathSegments([...base.slice(prefix.length).replace(/^\\/, "").split("\\"), ...normalizedRoot.split("\\")], "\\"));
178
+ }
179
+ function normalizeUncPath(path) {
180
+ const unc = splitUncPath(path);
181
+ if (unc === void 0) return path;
182
+ return joinWindowsRoot(unc.prefix, normalizePathSegments(unc.rest, "\\"));
183
+ }
184
+ function splitUncPath(path) {
185
+ if (!path.startsWith("\\\\")) return void 0;
186
+ const [server, share, ...rest] = path.split("\\").filter((part) => part !== "");
187
+ if (server === void 0 || share === void 0) return void 0;
188
+ return {
189
+ prefix: `\\\\${server}\\${share}`,
190
+ rest
191
+ };
192
+ }
193
+ function joinWindowsRoot(prefix, rest) {
194
+ return rest === "" ? `${prefix}\\` : `${prefix}\\${rest}`;
195
+ }
196
+ function normalizePathSegments(segments, separator) {
197
+ const out = [];
198
+ for (const segment of segments) {
199
+ if (segment === "" || segment === ".") continue;
200
+ if (segment === "..") {
201
+ out.pop();
202
+ continue;
203
+ }
204
+ out.push(segment);
205
+ }
206
+ return out.join(separator);
207
+ }
208
+ function relativePathFromRoot(root, path, nodeDeps) {
209
+ return nodeDeps.relative(root, path).split(nodeDeps.sep).join("/");
210
+ }
211
+ function throwIfScanAborted(options) {
212
+ if (options.signal?.aborted === true) throw options.signal.reason ?? new DOMException("Aborted", "AbortError");
213
+ }
214
+ //#endregion
57
215
  exports.LocalFolder = LocalFolder;
58
- //# sourceMappingURL=local.cjs.map
216
+
217
+ //# sourceMappingURL=local.cjs.map