@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
@@ -1,74 +1,79 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const index = require("../actions/index.cjs");
4
- const compare = require("./compare.cjs");
1
+ const require_index = require("../actions/index.cjs");
2
+ const require_compare = require("./compare.cjs");
3
+ //#region src/sync/policies/index.ts
4
+ /**
5
+ * Converts a paired source/dest tuple into zero or more sync actions based on the
6
+ * sync direction, compare mode, and keep policy.
7
+ * For `compareMode: 'sha1'`, prefer the high-level `synchronize()` API so local
8
+ * file hashes and comparable B2 hashes are prepared before actions are generated.
9
+ * Low-level callers must pass pairs with local `contentSha1` values already
10
+ * computed and B2 `contentSha1` values containing any comparable metadata fallback.
11
+ *
12
+ * @param pair - The source/dest file pair from {@link zipFolders}.
13
+ * @param direction - The sync direction.
14
+ * @param compareMode - How to compare files for differences.
15
+ * @param keepMode - Policy for destination-only files.
16
+ * @param keepDays - Retention period when keepMode is 'keep-days'.
17
+ * @param nowMillis - Current time in milliseconds, used for keep-days calculation.
18
+ * @param factory - Factory to create the concrete action objects.
19
+ * @param compareThreshold - Tolerance for the comparison.
20
+ */
5
21
  function* generateActions(pair, direction, compareMode, keepMode, keepDays, nowMillis, factory, compareThreshold) {
6
- const [source, dest] = pair;
7
- if (source !== null && dest === null) {
8
- yield* actionsForSourceOnly(source, direction, factory);
9
- } else if (source === null && dest !== null) {
10
- yield* actionsForDestOnly(dest, direction, keepMode, keepDays, nowMillis, factory);
11
- } else if (source !== null && dest !== null) {
12
- yield* actionsForBoth(source, dest, direction, compareMode, compareThreshold, factory);
13
- }
22
+ require_compare.assertSupportedCompareMode(compareMode);
23
+ const [source, dest] = pair;
24
+ if (source !== null && dest === null) yield* actionsForSourceOnly(source, direction, factory);
25
+ else if (source === null && dest !== null) yield* actionsForDestOnly(dest, direction, keepMode, keepDays, nowMillis, factory);
26
+ else if (source !== null && dest !== null) yield* actionsForBoth(source, dest, direction, compareMode, compareThreshold, factory);
14
27
  }
15
28
  function* actionsForSourceOnly(source, direction, factory) {
16
- switch (direction) {
17
- case "local-to-b2":
18
- yield factory.upload(source);
19
- break;
20
- case "b2-to-local":
21
- yield factory.download(source);
22
- break;
23
- case "b2-to-b2":
24
- yield factory.copy(source, source.relativePath);
25
- break;
26
- }
29
+ switch (direction) {
30
+ case "local-to-b2":
31
+ yield factory.upload(source);
32
+ break;
33
+ case "b2-to-local":
34
+ yield factory.download(source, null);
35
+ break;
36
+ case "b2-to-b2": yield factory.copy(source, source.relativePath);
37
+ }
27
38
  }
28
39
  function* actionsForDestOnly(dest, direction, keepMode, keepDays, nowMillis, factory) {
29
- if (keepMode === "no-delete") {
30
- yield new index.SkipAction(dest.relativePath, "not in source, keep-mode is no-delete");
31
- return;
32
- }
33
- if (keepMode === "keep-days") {
34
- const ageMillis = nowMillis - dest.modTimeMillis;
35
- const ageDays = ageMillis / (24 * 60 * 60 * 1e3);
36
- if (ageDays < keepDays) {
37
- yield new index.SkipAction(
38
- dest.relativePath,
39
- `not in source, keeping for ${Math.ceil(keepDays - ageDays)} more days`
40
- );
41
- return;
42
- }
43
- }
44
- switch (direction) {
45
- case "local-to-b2":
46
- yield factory.removeOrphan(dest);
47
- break;
48
- case "b2-to-local":
49
- yield factory.deleteLocal(dest);
50
- break;
51
- case "b2-to-b2":
52
- yield factory.removeOrphan(dest);
53
- break;
54
- }
40
+ if (keepMode === "no-delete") {
41
+ yield new require_index.SkipAction(dest.relativePath, "not in source, keep-mode is no-delete");
42
+ return;
43
+ }
44
+ if (keepMode === "keep-days") {
45
+ const ageDays = (nowMillis - dest.modTimeMillis) / 864e5;
46
+ if (ageDays < keepDays) {
47
+ yield new require_index.SkipAction(dest.relativePath, `not in source, keeping for ${Math.ceil(keepDays - ageDays)} more days`);
48
+ return;
49
+ }
50
+ }
51
+ switch (direction) {
52
+ case "local-to-b2":
53
+ yield factory.removeOrphan(dest);
54
+ break;
55
+ case "b2-to-local":
56
+ yield factory.deleteLocal(dest);
57
+ break;
58
+ case "b2-to-b2": yield factory.removeOrphan(dest);
59
+ }
55
60
  }
56
61
  function* actionsForBoth(source, dest, direction, compareMode, compareThreshold, factory) {
57
- if (!compare.filesAreDifferent(source, dest, compareMode, compareThreshold)) {
58
- yield new index.SkipAction(source.relativePath, "files are the same");
59
- return;
60
- }
61
- switch (direction) {
62
- case "local-to-b2":
63
- yield factory.upload(source);
64
- break;
65
- case "b2-to-local":
66
- yield factory.download(source);
67
- break;
68
- case "b2-to-b2":
69
- yield factory.copy(source, dest.relativePath);
70
- break;
71
- }
62
+ if (!require_compare.filesAreDifferent(source, dest, compareMode, compareThreshold)) {
63
+ yield new require_index.SkipAction(source.relativePath, "files are the same");
64
+ return;
65
+ }
66
+ switch (direction) {
67
+ case "local-to-b2":
68
+ yield factory.upload(source, dest);
69
+ break;
70
+ case "b2-to-local":
71
+ yield factory.download(source, dest);
72
+ break;
73
+ case "b2-to-b2": yield factory.copyB2Path?.(source, dest) ?? factory.copy(source, dest.relativePath);
74
+ }
72
75
  }
76
+ //#endregion
73
77
  exports.generateActions = generateActions;
74
- //# sourceMappingURL=index.cjs.map
78
+
79
+ //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../../src/sync/policies/index.ts"],"sourcesContent":["import type { SyncAction } from '../actions/index.ts'\nimport { SkipAction } from '../actions/index.ts'\nimport type { SyncPair } from '../pairing.ts'\nimport type {\n B2SyncPath,\n CompareMode,\n KeepMode,\n LocalSyncPath,\n SyncDirection,\n SyncPath,\n} from '../types.ts'\nimport { filesAreDifferent } from './compare.ts'\n\n/** Factory for creating concrete sync actions. Used by {@link generateActions} to decouple policy from execution. */\nexport interface ActionFactory {\n /** Creates an action to upload a local file to B2. */\n upload(source: LocalSyncPath): SyncAction\n /** Creates an action to download a B2 file to the local filesystem. */\n download(source: B2SyncPath): SyncAction\n /** Creates an action to server-side copy a B2 file to a new destination path. */\n copy(source: B2SyncPath, destPath: string): SyncAction\n /** Creates an action to hide a file in B2 (soft delete). */\n hide(path: string): SyncAction\n /** Creates an action to permanently delete a remote B2 file version. */\n deleteRemote(path: B2SyncPath): SyncAction\n /** Creates an action to delete a local file. */\n deleteLocal(path: LocalSyncPath): SyncAction\n /**\n * Creates the right \"remove this orphan from B2\" action for the bucket's\n * configuration: a hide on a file-lock-enabled bucket (where direct\n * delete may be blocked or stack hide markers), a plain\n * delete-file-version on a vanilla bucket. Used by `actionsForDestOnly`\n * to avoid yielding both a hide AND a delete when only one of them is\n * the correct semantic for the destination bucket.\n */\n removeOrphan(dest: B2SyncPath): SyncAction\n}\n\n/**\n * Converts a paired source/dest tuple into zero or more sync actions based on the\n * sync direction, compare mode, and keep policy.\n *\n * @param pair - The source/dest file pair from {@link zipFolders}.\n * @param direction - The sync direction.\n * @param compareMode - How to compare files for differences.\n * @param keepMode - Policy for destination-only files.\n * @param keepDays - Retention period when keepMode is 'keep-days'.\n * @param nowMillis - Current time in milliseconds, used for keep-days calculation.\n * @param factory - Factory to create the concrete action objects.\n * @param compareThreshold - Tolerance for the comparison.\n */\nexport function* generateActions(\n pair: SyncPair,\n direction: SyncDirection,\n compareMode: CompareMode,\n keepMode: KeepMode,\n keepDays: number,\n nowMillis: number,\n factory: ActionFactory,\n compareThreshold: number,\n): Generator<SyncAction> {\n const [source, dest] = pair\n\n if (source !== null && dest === null) {\n yield* actionsForSourceOnly(source, direction, factory)\n } else if (source === null && dest !== null) {\n yield* actionsForDestOnly(dest, direction, keepMode, keepDays, nowMillis, factory)\n } else if (source !== null && dest !== null) {\n yield* actionsForBoth(source, dest, direction, compareMode, compareThreshold, factory)\n }\n}\n\nfunction* actionsForSourceOnly(\n source: SyncPath,\n direction: SyncDirection,\n factory: ActionFactory,\n): Generator<SyncAction> {\n switch (direction) {\n case 'local-to-b2':\n yield factory.upload(source as LocalSyncPath)\n break\n case 'b2-to-local':\n yield factory.download(source as B2SyncPath)\n break\n case 'b2-to-b2':\n yield factory.copy(source as B2SyncPath, source.relativePath)\n break\n }\n}\n\nfunction* actionsForDestOnly(\n dest: SyncPath,\n direction: SyncDirection,\n keepMode: KeepMode,\n keepDays: number,\n nowMillis: number,\n factory: ActionFactory,\n): Generator<SyncAction> {\n if (keepMode === 'no-delete') {\n yield new SkipAction(dest.relativePath, 'not in source, keep-mode is no-delete')\n return\n }\n\n if (keepMode === 'keep-days') {\n const ageMillis = nowMillis - dest.modTimeMillis\n const ageDays = ageMillis / (24 * 60 * 60 * 1000)\n if (ageDays < keepDays) {\n yield new SkipAction(\n dest.relativePath,\n `not in source, keeping for ${Math.ceil(keepDays - ageDays)} more days`,\n )\n return\n }\n }\n\n switch (direction) {\n case 'local-to-b2':\n // Single action — `removeOrphan` picks hide vs delete based on\n // the destination bucket's `fileLockEnabled` state. The previous\n // \"yield both\" behaviour stacked hide markers on vanilla buckets\n // even though the delete that followed made them redundant.\n yield factory.removeOrphan(dest as B2SyncPath)\n break\n case 'b2-to-local':\n yield factory.deleteLocal(dest as LocalSyncPath)\n break\n case 'b2-to-b2':\n yield factory.removeOrphan(dest as B2SyncPath)\n break\n }\n}\n\nfunction* actionsForBoth(\n source: SyncPath,\n dest: SyncPath,\n direction: SyncDirection,\n compareMode: CompareMode,\n compareThreshold: number,\n factory: ActionFactory,\n): Generator<SyncAction> {\n if (!filesAreDifferent(source, dest, compareMode, compareThreshold)) {\n yield new SkipAction(source.relativePath, 'files are the same')\n return\n }\n\n switch (direction) {\n case 'local-to-b2':\n yield factory.upload(source as LocalSyncPath)\n break\n case 'b2-to-local':\n yield factory.download(source as B2SyncPath)\n break\n case 'b2-to-b2':\n yield factory.copy(source as B2SyncPath, dest.relativePath)\n break\n }\n}\n"],"names":["SkipAction","filesAreDifferent"],"mappings":";;;;AAmDO,UAAU,gBACf,MACA,WACA,aACA,UACA,UACA,WACA,SACA,kBACuB;AACvB,QAAM,CAAC,QAAQ,IAAI,IAAI;AAEvB,MAAI,WAAW,QAAQ,SAAS,MAAM;AACpC,WAAO,qBAAqB,QAAQ,WAAW,OAAO;AAAA,EACxD,WAAW,WAAW,QAAQ,SAAS,MAAM;AAC3C,WAAO,mBAAmB,MAAM,WAAW,UAAU,UAAU,WAAW,OAAO;AAAA,EACnF,WAAW,WAAW,QAAQ,SAAS,MAAM;AAC3C,WAAO,eAAe,QAAQ,MAAM,WAAW,aAAa,kBAAkB,OAAO;AAAA,EACvF;AACF;AAEA,UAAU,qBACR,QACA,WACA,SACuB;AACvB,UAAQ,WAAA;AAAA,IACN,KAAK;AACH,YAAM,QAAQ,OAAO,MAAuB;AAC5C;AAAA,IACF,KAAK;AACH,YAAM,QAAQ,SAAS,MAAoB;AAC3C;AAAA,IACF,KAAK;AACH,YAAM,QAAQ,KAAK,QAAsB,OAAO,YAAY;AAC5D;AAAA,EAAA;AAEN;AAEA,UAAU,mBACR,MACA,WACA,UACA,UACA,WACA,SACuB;AACvB,MAAI,aAAa,aAAa;AAC5B,UAAM,IAAIA,MAAAA,WAAW,KAAK,cAAc,uCAAuC;AAC/E;AAAA,EACF;AAEA,MAAI,aAAa,aAAa;AAC5B,UAAM,YAAY,YAAY,KAAK;AACnC,UAAM,UAAU,aAAa,KAAK,KAAK,KAAK;AAC5C,QAAI,UAAU,UAAU;AACtB,YAAM,IAAIA,MAAAA;AAAAA,QACR,KAAK;AAAA,QACL,8BAA8B,KAAK,KAAK,WAAW,OAAO,CAAC;AAAA,MAAA;AAE7D;AAAA,IACF;AAAA,EACF;AAEA,UAAQ,WAAA;AAAA,IACN,KAAK;AAKH,YAAM,QAAQ,aAAa,IAAkB;AAC7C;AAAA,IACF,KAAK;AACH,YAAM,QAAQ,YAAY,IAAqB;AAC/C;AAAA,IACF,KAAK;AACH,YAAM,QAAQ,aAAa,IAAkB;AAC7C;AAAA,EAAA;AAEN;AAEA,UAAU,eACR,QACA,MACA,WACA,aACA,kBACA,SACuB;AACvB,MAAI,CAACC,QAAAA,kBAAkB,QAAQ,MAAM,aAAa,gBAAgB,GAAG;AACnE,UAAM,IAAID,MAAAA,WAAW,OAAO,cAAc,oBAAoB;AAC9D;AAAA,EACF;AAEA,UAAQ,WAAA;AAAA,IACN,KAAK;AACH,YAAM,QAAQ,OAAO,MAAuB;AAC5C;AAAA,IACF,KAAK;AACH,YAAM,QAAQ,SAAS,MAAoB;AAC3C;AAAA,IACF,KAAK;AACH,YAAM,QAAQ,KAAK,QAAsB,KAAK,YAAY;AAC1D;AAAA,EAAA;AAEN;;"}
1
+ {"version":3,"file":"index.cjs","names":[],"sources":["../../../src/sync/policies/index.ts"],"sourcesContent":["import type { SyncAction } from '../actions/index.ts'\nimport { SkipAction } from '../actions/index.ts'\nimport type { SyncPair } from '../pairing.ts'\nimport type {\n B2SyncPath,\n CompareMode,\n KeepMode,\n LocalSyncPath,\n SyncDirection,\n SyncPath,\n} from '../types.ts'\nimport { assertSupportedCompareMode, filesAreDifferent } from './compare.ts'\n\n/** Factory for creating concrete sync actions. Used by {@link generateActions} to decouple policy from execution. */\nexport interface ActionFactory {\n /** Creates an action to upload a local file to B2. */\n upload(source: LocalSyncPath, dest?: B2SyncPath): SyncAction\n /**\n * Creates an action to download a B2 file to the local filesystem.\n *\n * `generateActions` passes `null` when the B2 source has no scanned local\n * destination, a `LocalSyncPath` when the download replaces an existing\n * scanned destination file, and leaves the value `undefined` only for\n * callers that invoke a factory without destination scan context.\n */\n download(source: B2SyncPath, scannedDest?: LocalSyncPath | null): SyncAction\n /**\n * Creates an action to server-side copy a B2 file to a sync-relative destination path.\n * Kept for compatibility with custom factories that accept a sync-relative string.\n */\n copy(source: B2SyncPath, destRelativePath: string): SyncAction\n /**\n * Creates an action to server-side copy a B2 file using full destination path metadata.\n * Implementations can use `dest.selectedVersion.fileName` when a raw B2 prefix or normalized\n * sync path differs from the stored object key.\n */\n copyB2Path?(source: B2SyncPath, dest: B2SyncPath): SyncAction\n /**\n * Creates an action to hide a file in B2 (soft delete).\n * Kept for compatibility with custom factories that accept a sync-relative string.\n */\n hide(path: string): SyncAction\n /**\n * Creates an action to hide a B2 file using its full scanned path metadata.\n * Implementations can use `selectedVersion.fileName` when a raw B2 prefix or normalized sync path\n * differs from the stored object key.\n */\n hideB2Path?(path: B2SyncPath): SyncAction\n /** Creates an action to permanently delete a remote B2 file version. */\n deleteRemote(path: B2SyncPath): SyncAction\n /** Creates an action to delete a local file. */\n deleteLocal(path: LocalSyncPath): SyncAction\n /**\n * Creates the right \"remove this orphan from B2\" action for the bucket's\n * configuration: a hide on a file-lock-enabled bucket (where direct\n * delete may be blocked or stack hide markers), a plain\n * delete-file-version on a vanilla bucket. Used by `actionsForDestOnly`\n * to avoid yielding both a hide AND a delete when only one of them is\n * the correct semantic for the destination bucket.\n */\n removeOrphan(dest: B2SyncPath): SyncAction\n}\n\n/**\n * Converts a paired source/dest tuple into zero or more sync actions based on the\n * sync direction, compare mode, and keep policy.\n * For `compareMode: 'sha1'`, prefer the high-level `synchronize()` API so local\n * file hashes and comparable B2 hashes are prepared before actions are generated.\n * Low-level callers must pass pairs with local `contentSha1` values already\n * computed and B2 `contentSha1` values containing any comparable metadata fallback.\n *\n * @param pair - The source/dest file pair from {@link zipFolders}.\n * @param direction - The sync direction.\n * @param compareMode - How to compare files for differences.\n * @param keepMode - Policy for destination-only files.\n * @param keepDays - Retention period when keepMode is 'keep-days'.\n * @param nowMillis - Current time in milliseconds, used for keep-days calculation.\n * @param factory - Factory to create the concrete action objects.\n * @param compareThreshold - Tolerance for the comparison.\n */\nexport function* generateActions(\n pair: SyncPair,\n direction: SyncDirection,\n compareMode: CompareMode,\n keepMode: KeepMode,\n keepDays: number,\n nowMillis: number,\n factory: ActionFactory,\n compareThreshold: number,\n): Generator<SyncAction> {\n assertSupportedCompareMode(compareMode)\n\n const [source, dest] = pair\n\n if (source !== null && dest === null) {\n yield* actionsForSourceOnly(source, direction, factory)\n } else if (source === null && dest !== null) {\n yield* actionsForDestOnly(dest, direction, keepMode, keepDays, nowMillis, factory)\n } else if (source !== null && dest !== null) {\n yield* actionsForBoth(source, dest, direction, compareMode, compareThreshold, factory)\n }\n}\n\nfunction* actionsForSourceOnly(\n source: SyncPath,\n direction: SyncDirection,\n factory: ActionFactory,\n): Generator<SyncAction> {\n switch (direction) {\n case 'local-to-b2':\n yield factory.upload(source as LocalSyncPath)\n break\n case 'b2-to-local':\n yield factory.download(source as B2SyncPath, null)\n break\n case 'b2-to-b2':\n yield factory.copy(source as B2SyncPath, source.relativePath)\n break\n }\n}\n\nfunction* actionsForDestOnly(\n dest: SyncPath,\n direction: SyncDirection,\n keepMode: KeepMode,\n keepDays: number,\n nowMillis: number,\n factory: ActionFactory,\n): Generator<SyncAction> {\n if (keepMode === 'no-delete') {\n yield new SkipAction(dest.relativePath, 'not in source, keep-mode is no-delete')\n return\n }\n\n if (keepMode === 'keep-days') {\n const ageMillis = nowMillis - dest.modTimeMillis\n const ageDays = ageMillis / (24 * 60 * 60 * 1000)\n if (ageDays < keepDays) {\n yield new SkipAction(\n dest.relativePath,\n `not in source, keeping for ${Math.ceil(keepDays - ageDays)} more days`,\n )\n return\n }\n }\n\n switch (direction) {\n case 'local-to-b2':\n // Single action — `removeOrphan` picks hide vs delete based on\n // the destination bucket's `fileLockEnabled` state. The previous\n // \"yield both\" behaviour stacked hide markers on vanilla buckets\n // even though the delete that followed made them redundant.\n yield factory.removeOrphan(dest as B2SyncPath)\n break\n case 'b2-to-local':\n yield factory.deleteLocal(dest as LocalSyncPath)\n break\n case 'b2-to-b2':\n yield factory.removeOrphan(dest as B2SyncPath)\n break\n }\n}\n\nfunction* actionsForBoth(\n source: SyncPath,\n dest: SyncPath,\n direction: SyncDirection,\n compareMode: CompareMode,\n compareThreshold: number,\n factory: ActionFactory,\n): Generator<SyncAction> {\n if (!filesAreDifferent(source, dest, compareMode, compareThreshold)) {\n yield new SkipAction(source.relativePath, 'files are the same')\n return\n }\n\n switch (direction) {\n case 'local-to-b2':\n yield factory.upload(source as LocalSyncPath, dest as B2SyncPath)\n break\n case 'b2-to-local':\n yield factory.download(source as B2SyncPath, dest as LocalSyncPath)\n break\n case 'b2-to-b2': {\n const action =\n factory.copyB2Path?.(source as B2SyncPath, dest as B2SyncPath) ??\n factory.copy(source as B2SyncPath, dest.relativePath)\n yield action\n break\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAgFA,UAAiB,gBACf,MACA,WACA,aACA,UACA,UACA,WACA,SACA,kBACuB;CACvB,gBAAA,2BAA2B,WAAW;CAEtC,MAAM,CAAC,QAAQ,QAAQ;CAEvB,IAAI,WAAW,QAAQ,SAAS,MAC9B,OAAO,qBAAqB,QAAQ,WAAW,OAAO;MACjD,IAAI,WAAW,QAAQ,SAAS,MACrC,OAAO,mBAAmB,MAAM,WAAW,UAAU,UAAU,WAAW,OAAO;MAC5E,IAAI,WAAW,QAAQ,SAAS,MACrC,OAAO,eAAe,QAAQ,MAAM,WAAW,aAAa,kBAAkB,OAAO;AAEzF;AAEA,UAAU,qBACR,QACA,WACA,SACuB;CACvB,QAAQ,WAAR;EACE,KAAK;GACH,MAAM,QAAQ,OAAO,MAAuB;GAC5C;EACF,KAAK;GACH,MAAM,QAAQ,SAAS,QAAsB,IAAI;GACjD;EACF,KAAK,YACH,MAAM,QAAQ,KAAK,QAAsB,OAAO,YAAY;CAEhE;AACF;AAEA,UAAU,mBACR,MACA,WACA,UACA,UACA,WACA,SACuB;CACvB,IAAI,aAAa,aAAa;EAC5B,MAAM,IAAI,cAAA,WAAW,KAAK,cAAc,uCAAuC;EAC/E;CACF;CAEA,IAAI,aAAa,aAAa;EAE5B,MAAM,WADY,YAAY,KAAK,iBACN;EAC7B,IAAI,UAAU,UAAU;GACtB,MAAM,IAAI,cAAA,WACR,KAAK,cACL,8BAA8B,KAAK,KAAK,WAAW,OAAO,EAAE,WAC9D;GACA;EACF;CACF;CAEA,QAAQ,WAAR;EACE,KAAK;GAKH,MAAM,QAAQ,aAAa,IAAkB;GAC7C;EACF,KAAK;GACH,MAAM,QAAQ,YAAY,IAAqB;GAC/C;EACF,KAAK,YACH,MAAM,QAAQ,aAAa,IAAkB;CAEjD;AACF;AAEA,UAAU,eACR,QACA,MACA,WACA,aACA,kBACA,SACuB;CACvB,IAAI,CAAC,gBAAA,kBAAkB,QAAQ,MAAM,aAAa,gBAAgB,GAAG;EACnE,MAAM,IAAI,cAAA,WAAW,OAAO,cAAc,oBAAoB;EAC9D;CACF;CAEA,QAAQ,WAAR;EACE,KAAK;GACH,MAAM,QAAQ,OAAO,QAAyB,IAAkB;GAChE;EACF,KAAK;GACH,MAAM,QAAQ,SAAS,QAAsB,IAAqB;GAClE;EACF,KAAK,YAIH,MAFE,QAAQ,aAAa,QAAsB,IAAkB,KAC7D,QAAQ,KAAK,QAAsB,KAAK,YAAY;CAI1D;AACF"}
@@ -4,13 +4,38 @@ import { B2SyncPath, CompareMode, KeepMode, LocalSyncPath, SyncDirection } from
4
4
  /** Factory for creating concrete sync actions. Used by {@link generateActions} to decouple policy from execution. */
5
5
  export interface ActionFactory {
6
6
  /** Creates an action to upload a local file to B2. */
7
- upload(source: LocalSyncPath): SyncAction;
8
- /** Creates an action to download a B2 file to the local filesystem. */
9
- download(source: B2SyncPath): SyncAction;
10
- /** Creates an action to server-side copy a B2 file to a new destination path. */
11
- copy(source: B2SyncPath, destPath: string): SyncAction;
12
- /** Creates an action to hide a file in B2 (soft delete). */
7
+ upload(source: LocalSyncPath, dest?: B2SyncPath): SyncAction;
8
+ /**
9
+ * Creates an action to download a B2 file to the local filesystem.
10
+ *
11
+ * `generateActions` passes `null` when the B2 source has no scanned local
12
+ * destination, a `LocalSyncPath` when the download replaces an existing
13
+ * scanned destination file, and leaves the value `undefined` only for
14
+ * callers that invoke a factory without destination scan context.
15
+ */
16
+ download(source: B2SyncPath, scannedDest?: LocalSyncPath | null): SyncAction;
17
+ /**
18
+ * Creates an action to server-side copy a B2 file to a sync-relative destination path.
19
+ * Kept for compatibility with custom factories that accept a sync-relative string.
20
+ */
21
+ copy(source: B2SyncPath, destRelativePath: string): SyncAction;
22
+ /**
23
+ * Creates an action to server-side copy a B2 file using full destination path metadata.
24
+ * Implementations can use `dest.selectedVersion.fileName` when a raw B2 prefix or normalized
25
+ * sync path differs from the stored object key.
26
+ */
27
+ copyB2Path?(source: B2SyncPath, dest: B2SyncPath): SyncAction;
28
+ /**
29
+ * Creates an action to hide a file in B2 (soft delete).
30
+ * Kept for compatibility with custom factories that accept a sync-relative string.
31
+ */
13
32
  hide(path: string): SyncAction;
33
+ /**
34
+ * Creates an action to hide a B2 file using its full scanned path metadata.
35
+ * Implementations can use `selectedVersion.fileName` when a raw B2 prefix or normalized sync path
36
+ * differs from the stored object key.
37
+ */
38
+ hideB2Path?(path: B2SyncPath): SyncAction;
14
39
  /** Creates an action to permanently delete a remote B2 file version. */
15
40
  deleteRemote(path: B2SyncPath): SyncAction;
16
41
  /** Creates an action to delete a local file. */
@@ -28,6 +53,10 @@ export interface ActionFactory {
28
53
  /**
29
54
  * Converts a paired source/dest tuple into zero or more sync actions based on the
30
55
  * sync direction, compare mode, and keep policy.
56
+ * For `compareMode: 'sha1'`, prefer the high-level `synchronize()` API so local
57
+ * file hashes and comparable B2 hashes are prepared before actions are generated.
58
+ * Low-level callers must pass pairs with local `contentSha1` values already
59
+ * computed and B2 `contentSha1` values containing any comparable metadata fallback.
31
60
  *
32
61
  * @param pair - The source/dest file pair from {@link zipFolders}.
33
62
  * @param direction - The sync direction.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/sync/policies/index.js"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAErD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAC7C,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,QAAQ,EACR,aAAa,EACb,aAAa,EAEd,MAAM,aAAa,CAAA;AAGpB,qHAAqH;AACrH,MAAM,WAAW,aAAa;IAC5B,sDAAsD;IACtD,MAAM,CAAC,MAAM,EAAE,aAAa,GAAG,UAAU,CAAA;IACzC,uEAAuE;IACvE,QAAQ,CAAC,MAAM,EAAE,UAAU,GAAG,UAAU,CAAA;IACxC,iFAAiF;IACjF,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU,CAAA;IACtD,4DAA4D;IAC5D,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAAA;IAC9B,wEAAwE;IACxE,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAAA;IAC1C,gDAAgD;IAChD,WAAW,CAAC,IAAI,EAAE,aAAa,GAAG,UAAU,CAAA;IAC5C;;;;;;;OAOG;IACH,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAAA;CAC3C;AAED;;;;;;;;;;;;GAYG;AACH,wBAAiB,eAAe,CAC9B,IAAI,EAAE,QAAQ,EACd,SAAS,EAAE,aAAa,EACxB,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,aAAa,EACtB,gBAAgB,EAAE,MAAM,GACvB,SAAS,CAAC,UAAU,CAAC,CAUvB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/sync/policies/index.js"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAErD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAC7C,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,QAAQ,EACR,aAAa,EACb,aAAa,EAEd,MAAM,aAAa,CAAA;AAGpB,qHAAqH;AACrH,MAAM,WAAW,aAAa;IAC5B,sDAAsD;IACtD,MAAM,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,CAAC,EAAE,UAAU,GAAG,UAAU,CAAA;IAC5D;;;;;;;OAOG;IACH,QAAQ,CAAC,MAAM,EAAE,UAAU,EAAE,WAAW,CAAC,EAAE,aAAa,GAAG,IAAI,GAAG,UAAU,CAAA;IAC5E;;;OAGG;IACH,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,GAAG,UAAU,CAAA;IAC9D;;;;OAIG;IACH,UAAU,CAAC,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,GAAG,UAAU,CAAA;IAC7D;;;OAGG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAAA;IAC9B;;;;OAIG;IACH,UAAU,CAAC,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAAA;IACzC,wEAAwE;IACxE,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAAA;IAC1C,gDAAgD;IAChD,WAAW,CAAC,IAAI,EAAE,aAAa,GAAG,UAAU,CAAA;IAC5C;;;;;;;OAOG;IACH,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAAA;CAC3C;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAiB,eAAe,CAC9B,IAAI,EAAE,QAAQ,EACd,SAAS,EAAE,aAAa,EACxB,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,aAAa,EACtB,gBAAgB,EAAE,MAAM,GACvB,SAAS,CAAC,UAAU,CAAC,CAYvB"}
@@ -4,13 +4,38 @@ import { B2SyncPath, CompareMode, KeepMode, LocalSyncPath, SyncDirection } from
4
4
  /** Factory for creating concrete sync actions. Used by {@link generateActions} to decouple policy from execution. */
5
5
  export interface ActionFactory {
6
6
  /** Creates an action to upload a local file to B2. */
7
- upload(source: LocalSyncPath): SyncAction;
8
- /** Creates an action to download a B2 file to the local filesystem. */
9
- download(source: B2SyncPath): SyncAction;
10
- /** Creates an action to server-side copy a B2 file to a new destination path. */
11
- copy(source: B2SyncPath, destPath: string): SyncAction;
12
- /** Creates an action to hide a file in B2 (soft delete). */
7
+ upload(source: LocalSyncPath, dest?: B2SyncPath): SyncAction;
8
+ /**
9
+ * Creates an action to download a B2 file to the local filesystem.
10
+ *
11
+ * `generateActions` passes `null` when the B2 source has no scanned local
12
+ * destination, a `LocalSyncPath` when the download replaces an existing
13
+ * scanned destination file, and leaves the value `undefined` only for
14
+ * callers that invoke a factory without destination scan context.
15
+ */
16
+ download(source: B2SyncPath, scannedDest?: LocalSyncPath | null): SyncAction;
17
+ /**
18
+ * Creates an action to server-side copy a B2 file to a sync-relative destination path.
19
+ * Kept for compatibility with custom factories that accept a sync-relative string.
20
+ */
21
+ copy(source: B2SyncPath, destRelativePath: string): SyncAction;
22
+ /**
23
+ * Creates an action to server-side copy a B2 file using full destination path metadata.
24
+ * Implementations can use `dest.selectedVersion.fileName` when a raw B2 prefix or normalized
25
+ * sync path differs from the stored object key.
26
+ */
27
+ copyB2Path?(source: B2SyncPath, dest: B2SyncPath): SyncAction;
28
+ /**
29
+ * Creates an action to hide a file in B2 (soft delete).
30
+ * Kept for compatibility with custom factories that accept a sync-relative string.
31
+ */
13
32
  hide(path: string): SyncAction;
33
+ /**
34
+ * Creates an action to hide a B2 file using its full scanned path metadata.
35
+ * Implementations can use `selectedVersion.fileName` when a raw B2 prefix or normalized sync path
36
+ * differs from the stored object key.
37
+ */
38
+ hideB2Path?(path: B2SyncPath): SyncAction;
14
39
  /** Creates an action to permanently delete a remote B2 file version. */
15
40
  deleteRemote(path: B2SyncPath): SyncAction;
16
41
  /** Creates an action to delete a local file. */
@@ -28,6 +53,10 @@ export interface ActionFactory {
28
53
  /**
29
54
  * Converts a paired source/dest tuple into zero or more sync actions based on the
30
55
  * sync direction, compare mode, and keep policy.
56
+ * For `compareMode: 'sha1'`, prefer the high-level `synchronize()` API so local
57
+ * file hashes and comparable B2 hashes are prepared before actions are generated.
58
+ * Low-level callers must pass pairs with local `contentSha1` values already
59
+ * computed and B2 `contentSha1` values containing any comparable metadata fallback.
31
60
  *
32
61
  * @param pair - The source/dest file pair from {@link zipFolders}.
33
62
  * @param direction - The sync direction.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/sync/policies/index.js"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAErD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAC7C,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,QAAQ,EACR,aAAa,EACb,aAAa,EAEd,MAAM,aAAa,CAAA;AAGpB,qHAAqH;AACrH,MAAM,WAAW,aAAa;IAC5B,sDAAsD;IACtD,MAAM,CAAC,MAAM,EAAE,aAAa,GAAG,UAAU,CAAA;IACzC,uEAAuE;IACvE,QAAQ,CAAC,MAAM,EAAE,UAAU,GAAG,UAAU,CAAA;IACxC,iFAAiF;IACjF,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU,CAAA;IACtD,4DAA4D;IAC5D,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAAA;IAC9B,wEAAwE;IACxE,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAAA;IAC1C,gDAAgD;IAChD,WAAW,CAAC,IAAI,EAAE,aAAa,GAAG,UAAU,CAAA;IAC5C;;;;;;;OAOG;IACH,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAAA;CAC3C;AAED;;;;;;;;;;;;GAYG;AACH,wBAAiB,eAAe,CAC9B,IAAI,EAAE,QAAQ,EACd,SAAS,EAAE,aAAa,EACxB,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,aAAa,EACtB,gBAAgB,EAAE,MAAM,GACvB,SAAS,CAAC,UAAU,CAAC,CAUvB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/sync/policies/index.js"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAErD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAC7C,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,QAAQ,EACR,aAAa,EACb,aAAa,EAEd,MAAM,aAAa,CAAA;AAGpB,qHAAqH;AACrH,MAAM,WAAW,aAAa;IAC5B,sDAAsD;IACtD,MAAM,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,CAAC,EAAE,UAAU,GAAG,UAAU,CAAA;IAC5D;;;;;;;OAOG;IACH,QAAQ,CAAC,MAAM,EAAE,UAAU,EAAE,WAAW,CAAC,EAAE,aAAa,GAAG,IAAI,GAAG,UAAU,CAAA;IAC5E;;;OAGG;IACH,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,GAAG,UAAU,CAAA;IAC9D;;;;OAIG;IACH,UAAU,CAAC,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,GAAG,UAAU,CAAA;IAC7D;;;OAGG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAAA;IAC9B;;;;OAIG;IACH,UAAU,CAAC,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAAA;IACzC,wEAAwE;IACxE,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAAA;IAC1C,gDAAgD;IAChD,WAAW,CAAC,IAAI,EAAE,aAAa,GAAG,UAAU,CAAA;IAC5C;;;;;;;OAOG;IACH,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAAA;CAC3C;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAiB,eAAe,CAC9B,IAAI,EAAE,QAAQ,EACd,SAAS,EAAE,aAAa,EACxB,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,aAAa,EACtB,gBAAgB,EAAE,MAAM,GACvB,SAAS,CAAC,UAAU,CAAC,CAYvB"}
@@ -1,74 +1,79 @@
1
1
  import { SkipAction } from "../actions/index.js";
2
- import { filesAreDifferent } from "./compare.js";
2
+ import { assertSupportedCompareMode, filesAreDifferent } from "./compare.js";
3
+ //#region src/sync/policies/index.ts
4
+ /**
5
+ * Converts a paired source/dest tuple into zero or more sync actions based on the
6
+ * sync direction, compare mode, and keep policy.
7
+ * For `compareMode: 'sha1'`, prefer the high-level `synchronize()` API so local
8
+ * file hashes and comparable B2 hashes are prepared before actions are generated.
9
+ * Low-level callers must pass pairs with local `contentSha1` values already
10
+ * computed and B2 `contentSha1` values containing any comparable metadata fallback.
11
+ *
12
+ * @param pair - The source/dest file pair from {@link zipFolders}.
13
+ * @param direction - The sync direction.
14
+ * @param compareMode - How to compare files for differences.
15
+ * @param keepMode - Policy for destination-only files.
16
+ * @param keepDays - Retention period when keepMode is 'keep-days'.
17
+ * @param nowMillis - Current time in milliseconds, used for keep-days calculation.
18
+ * @param factory - Factory to create the concrete action objects.
19
+ * @param compareThreshold - Tolerance for the comparison.
20
+ */
3
21
  function* generateActions(pair, direction, compareMode, keepMode, keepDays, nowMillis, factory, compareThreshold) {
4
- const [source, dest] = pair;
5
- if (source !== null && dest === null) {
6
- yield* actionsForSourceOnly(source, direction, factory);
7
- } else if (source === null && dest !== null) {
8
- yield* actionsForDestOnly(dest, direction, keepMode, keepDays, nowMillis, factory);
9
- } else if (source !== null && dest !== null) {
10
- yield* actionsForBoth(source, dest, direction, compareMode, compareThreshold, factory);
11
- }
22
+ assertSupportedCompareMode(compareMode);
23
+ const [source, dest] = pair;
24
+ if (source !== null && dest === null) yield* actionsForSourceOnly(source, direction, factory);
25
+ else if (source === null && dest !== null) yield* actionsForDestOnly(dest, direction, keepMode, keepDays, nowMillis, factory);
26
+ else if (source !== null && dest !== null) yield* actionsForBoth(source, dest, direction, compareMode, compareThreshold, factory);
12
27
  }
13
28
  function* actionsForSourceOnly(source, direction, factory) {
14
- switch (direction) {
15
- case "local-to-b2":
16
- yield factory.upload(source);
17
- break;
18
- case "b2-to-local":
19
- yield factory.download(source);
20
- break;
21
- case "b2-to-b2":
22
- yield factory.copy(source, source.relativePath);
23
- break;
24
- }
29
+ switch (direction) {
30
+ case "local-to-b2":
31
+ yield factory.upload(source);
32
+ break;
33
+ case "b2-to-local":
34
+ yield factory.download(source, null);
35
+ break;
36
+ case "b2-to-b2": yield factory.copy(source, source.relativePath);
37
+ }
25
38
  }
26
39
  function* actionsForDestOnly(dest, direction, keepMode, keepDays, nowMillis, factory) {
27
- if (keepMode === "no-delete") {
28
- yield new SkipAction(dest.relativePath, "not in source, keep-mode is no-delete");
29
- return;
30
- }
31
- if (keepMode === "keep-days") {
32
- const ageMillis = nowMillis - dest.modTimeMillis;
33
- const ageDays = ageMillis / (24 * 60 * 60 * 1e3);
34
- if (ageDays < keepDays) {
35
- yield new SkipAction(
36
- dest.relativePath,
37
- `not in source, keeping for ${Math.ceil(keepDays - ageDays)} more days`
38
- );
39
- return;
40
- }
41
- }
42
- switch (direction) {
43
- case "local-to-b2":
44
- yield factory.removeOrphan(dest);
45
- break;
46
- case "b2-to-local":
47
- yield factory.deleteLocal(dest);
48
- break;
49
- case "b2-to-b2":
50
- yield factory.removeOrphan(dest);
51
- break;
52
- }
40
+ if (keepMode === "no-delete") {
41
+ yield new SkipAction(dest.relativePath, "not in source, keep-mode is no-delete");
42
+ return;
43
+ }
44
+ if (keepMode === "keep-days") {
45
+ const ageDays = (nowMillis - dest.modTimeMillis) / 864e5;
46
+ if (ageDays < keepDays) {
47
+ yield new SkipAction(dest.relativePath, `not in source, keeping for ${Math.ceil(keepDays - ageDays)} more days`);
48
+ return;
49
+ }
50
+ }
51
+ switch (direction) {
52
+ case "local-to-b2":
53
+ yield factory.removeOrphan(dest);
54
+ break;
55
+ case "b2-to-local":
56
+ yield factory.deleteLocal(dest);
57
+ break;
58
+ case "b2-to-b2": yield factory.removeOrphan(dest);
59
+ }
53
60
  }
54
61
  function* actionsForBoth(source, dest, direction, compareMode, compareThreshold, factory) {
55
- if (!filesAreDifferent(source, dest, compareMode, compareThreshold)) {
56
- yield new SkipAction(source.relativePath, "files are the same");
57
- return;
58
- }
59
- switch (direction) {
60
- case "local-to-b2":
61
- yield factory.upload(source);
62
- break;
63
- case "b2-to-local":
64
- yield factory.download(source);
65
- break;
66
- case "b2-to-b2":
67
- yield factory.copy(source, dest.relativePath);
68
- break;
69
- }
62
+ if (!filesAreDifferent(source, dest, compareMode, compareThreshold)) {
63
+ yield new SkipAction(source.relativePath, "files are the same");
64
+ return;
65
+ }
66
+ switch (direction) {
67
+ case "local-to-b2":
68
+ yield factory.upload(source, dest);
69
+ break;
70
+ case "b2-to-local":
71
+ yield factory.download(source, dest);
72
+ break;
73
+ case "b2-to-b2": yield factory.copyB2Path?.(source, dest) ?? factory.copy(source, dest.relativePath);
74
+ }
70
75
  }
71
- export {
72
- generateActions
73
- };
74
- //# sourceMappingURL=index.js.map
76
+ //#endregion
77
+ export { generateActions };
78
+
79
+ //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../src/sync/policies/index.ts"],"sourcesContent":["import type { SyncAction } from '../actions/index.ts'\nimport { SkipAction } from '../actions/index.ts'\nimport type { SyncPair } from '../pairing.ts'\nimport type {\n B2SyncPath,\n CompareMode,\n KeepMode,\n LocalSyncPath,\n SyncDirection,\n SyncPath,\n} from '../types.ts'\nimport { filesAreDifferent } from './compare.ts'\n\n/** Factory for creating concrete sync actions. Used by {@link generateActions} to decouple policy from execution. */\nexport interface ActionFactory {\n /** Creates an action to upload a local file to B2. */\n upload(source: LocalSyncPath): SyncAction\n /** Creates an action to download a B2 file to the local filesystem. */\n download(source: B2SyncPath): SyncAction\n /** Creates an action to server-side copy a B2 file to a new destination path. */\n copy(source: B2SyncPath, destPath: string): SyncAction\n /** Creates an action to hide a file in B2 (soft delete). */\n hide(path: string): SyncAction\n /** Creates an action to permanently delete a remote B2 file version. */\n deleteRemote(path: B2SyncPath): SyncAction\n /** Creates an action to delete a local file. */\n deleteLocal(path: LocalSyncPath): SyncAction\n /**\n * Creates the right \"remove this orphan from B2\" action for the bucket's\n * configuration: a hide on a file-lock-enabled bucket (where direct\n * delete may be blocked or stack hide markers), a plain\n * delete-file-version on a vanilla bucket. Used by `actionsForDestOnly`\n * to avoid yielding both a hide AND a delete when only one of them is\n * the correct semantic for the destination bucket.\n */\n removeOrphan(dest: B2SyncPath): SyncAction\n}\n\n/**\n * Converts a paired source/dest tuple into zero or more sync actions based on the\n * sync direction, compare mode, and keep policy.\n *\n * @param pair - The source/dest file pair from {@link zipFolders}.\n * @param direction - The sync direction.\n * @param compareMode - How to compare files for differences.\n * @param keepMode - Policy for destination-only files.\n * @param keepDays - Retention period when keepMode is 'keep-days'.\n * @param nowMillis - Current time in milliseconds, used for keep-days calculation.\n * @param factory - Factory to create the concrete action objects.\n * @param compareThreshold - Tolerance for the comparison.\n */\nexport function* generateActions(\n pair: SyncPair,\n direction: SyncDirection,\n compareMode: CompareMode,\n keepMode: KeepMode,\n keepDays: number,\n nowMillis: number,\n factory: ActionFactory,\n compareThreshold: number,\n): Generator<SyncAction> {\n const [source, dest] = pair\n\n if (source !== null && dest === null) {\n yield* actionsForSourceOnly(source, direction, factory)\n } else if (source === null && dest !== null) {\n yield* actionsForDestOnly(dest, direction, keepMode, keepDays, nowMillis, factory)\n } else if (source !== null && dest !== null) {\n yield* actionsForBoth(source, dest, direction, compareMode, compareThreshold, factory)\n }\n}\n\nfunction* actionsForSourceOnly(\n source: SyncPath,\n direction: SyncDirection,\n factory: ActionFactory,\n): Generator<SyncAction> {\n switch (direction) {\n case 'local-to-b2':\n yield factory.upload(source as LocalSyncPath)\n break\n case 'b2-to-local':\n yield factory.download(source as B2SyncPath)\n break\n case 'b2-to-b2':\n yield factory.copy(source as B2SyncPath, source.relativePath)\n break\n }\n}\n\nfunction* actionsForDestOnly(\n dest: SyncPath,\n direction: SyncDirection,\n keepMode: KeepMode,\n keepDays: number,\n nowMillis: number,\n factory: ActionFactory,\n): Generator<SyncAction> {\n if (keepMode === 'no-delete') {\n yield new SkipAction(dest.relativePath, 'not in source, keep-mode is no-delete')\n return\n }\n\n if (keepMode === 'keep-days') {\n const ageMillis = nowMillis - dest.modTimeMillis\n const ageDays = ageMillis / (24 * 60 * 60 * 1000)\n if (ageDays < keepDays) {\n yield new SkipAction(\n dest.relativePath,\n `not in source, keeping for ${Math.ceil(keepDays - ageDays)} more days`,\n )\n return\n }\n }\n\n switch (direction) {\n case 'local-to-b2':\n // Single action — `removeOrphan` picks hide vs delete based on\n // the destination bucket's `fileLockEnabled` state. The previous\n // \"yield both\" behaviour stacked hide markers on vanilla buckets\n // even though the delete that followed made them redundant.\n yield factory.removeOrphan(dest as B2SyncPath)\n break\n case 'b2-to-local':\n yield factory.deleteLocal(dest as LocalSyncPath)\n break\n case 'b2-to-b2':\n yield factory.removeOrphan(dest as B2SyncPath)\n break\n }\n}\n\nfunction* actionsForBoth(\n source: SyncPath,\n dest: SyncPath,\n direction: SyncDirection,\n compareMode: CompareMode,\n compareThreshold: number,\n factory: ActionFactory,\n): Generator<SyncAction> {\n if (!filesAreDifferent(source, dest, compareMode, compareThreshold)) {\n yield new SkipAction(source.relativePath, 'files are the same')\n return\n }\n\n switch (direction) {\n case 'local-to-b2':\n yield factory.upload(source as LocalSyncPath)\n break\n case 'b2-to-local':\n yield factory.download(source as B2SyncPath)\n break\n case 'b2-to-b2':\n yield factory.copy(source as B2SyncPath, dest.relativePath)\n break\n }\n}\n"],"names":[],"mappings":";;AAmDO,UAAU,gBACf,MACA,WACA,aACA,UACA,UACA,WACA,SACA,kBACuB;AACvB,QAAM,CAAC,QAAQ,IAAI,IAAI;AAEvB,MAAI,WAAW,QAAQ,SAAS,MAAM;AACpC,WAAO,qBAAqB,QAAQ,WAAW,OAAO;AAAA,EACxD,WAAW,WAAW,QAAQ,SAAS,MAAM;AAC3C,WAAO,mBAAmB,MAAM,WAAW,UAAU,UAAU,WAAW,OAAO;AAAA,EACnF,WAAW,WAAW,QAAQ,SAAS,MAAM;AAC3C,WAAO,eAAe,QAAQ,MAAM,WAAW,aAAa,kBAAkB,OAAO;AAAA,EACvF;AACF;AAEA,UAAU,qBACR,QACA,WACA,SACuB;AACvB,UAAQ,WAAA;AAAA,IACN,KAAK;AACH,YAAM,QAAQ,OAAO,MAAuB;AAC5C;AAAA,IACF,KAAK;AACH,YAAM,QAAQ,SAAS,MAAoB;AAC3C;AAAA,IACF,KAAK;AACH,YAAM,QAAQ,KAAK,QAAsB,OAAO,YAAY;AAC5D;AAAA,EAAA;AAEN;AAEA,UAAU,mBACR,MACA,WACA,UACA,UACA,WACA,SACuB;AACvB,MAAI,aAAa,aAAa;AAC5B,UAAM,IAAI,WAAW,KAAK,cAAc,uCAAuC;AAC/E;AAAA,EACF;AAEA,MAAI,aAAa,aAAa;AAC5B,UAAM,YAAY,YAAY,KAAK;AACnC,UAAM,UAAU,aAAa,KAAK,KAAK,KAAK;AAC5C,QAAI,UAAU,UAAU;AACtB,YAAM,IAAI;AAAA,QACR,KAAK;AAAA,QACL,8BAA8B,KAAK,KAAK,WAAW,OAAO,CAAC;AAAA,MAAA;AAE7D;AAAA,IACF;AAAA,EACF;AAEA,UAAQ,WAAA;AAAA,IACN,KAAK;AAKH,YAAM,QAAQ,aAAa,IAAkB;AAC7C;AAAA,IACF,KAAK;AACH,YAAM,QAAQ,YAAY,IAAqB;AAC/C;AAAA,IACF,KAAK;AACH,YAAM,QAAQ,aAAa,IAAkB;AAC7C;AAAA,EAAA;AAEN;AAEA,UAAU,eACR,QACA,MACA,WACA,aACA,kBACA,SACuB;AACvB,MAAI,CAAC,kBAAkB,QAAQ,MAAM,aAAa,gBAAgB,GAAG;AACnE,UAAM,IAAI,WAAW,OAAO,cAAc,oBAAoB;AAC9D;AAAA,EACF;AAEA,UAAQ,WAAA;AAAA,IACN,KAAK;AACH,YAAM,QAAQ,OAAO,MAAuB;AAC5C;AAAA,IACF,KAAK;AACH,YAAM,QAAQ,SAAS,MAAoB;AAC3C;AAAA,IACF,KAAK;AACH,YAAM,QAAQ,KAAK,QAAsB,KAAK,YAAY;AAC1D;AAAA,EAAA;AAEN;"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/sync/policies/index.ts"],"sourcesContent":["import type { SyncAction } from '../actions/index.ts'\nimport { SkipAction } from '../actions/index.ts'\nimport type { SyncPair } from '../pairing.ts'\nimport type {\n B2SyncPath,\n CompareMode,\n KeepMode,\n LocalSyncPath,\n SyncDirection,\n SyncPath,\n} from '../types.ts'\nimport { assertSupportedCompareMode, filesAreDifferent } from './compare.ts'\n\n/** Factory for creating concrete sync actions. Used by {@link generateActions} to decouple policy from execution. */\nexport interface ActionFactory {\n /** Creates an action to upload a local file to B2. */\n upload(source: LocalSyncPath, dest?: B2SyncPath): SyncAction\n /**\n * Creates an action to download a B2 file to the local filesystem.\n *\n * `generateActions` passes `null` when the B2 source has no scanned local\n * destination, a `LocalSyncPath` when the download replaces an existing\n * scanned destination file, and leaves the value `undefined` only for\n * callers that invoke a factory without destination scan context.\n */\n download(source: B2SyncPath, scannedDest?: LocalSyncPath | null): SyncAction\n /**\n * Creates an action to server-side copy a B2 file to a sync-relative destination path.\n * Kept for compatibility with custom factories that accept a sync-relative string.\n */\n copy(source: B2SyncPath, destRelativePath: string): SyncAction\n /**\n * Creates an action to server-side copy a B2 file using full destination path metadata.\n * Implementations can use `dest.selectedVersion.fileName` when a raw B2 prefix or normalized\n * sync path differs from the stored object key.\n */\n copyB2Path?(source: B2SyncPath, dest: B2SyncPath): SyncAction\n /**\n * Creates an action to hide a file in B2 (soft delete).\n * Kept for compatibility with custom factories that accept a sync-relative string.\n */\n hide(path: string): SyncAction\n /**\n * Creates an action to hide a B2 file using its full scanned path metadata.\n * Implementations can use `selectedVersion.fileName` when a raw B2 prefix or normalized sync path\n * differs from the stored object key.\n */\n hideB2Path?(path: B2SyncPath): SyncAction\n /** Creates an action to permanently delete a remote B2 file version. */\n deleteRemote(path: B2SyncPath): SyncAction\n /** Creates an action to delete a local file. */\n deleteLocal(path: LocalSyncPath): SyncAction\n /**\n * Creates the right \"remove this orphan from B2\" action for the bucket's\n * configuration: a hide on a file-lock-enabled bucket (where direct\n * delete may be blocked or stack hide markers), a plain\n * delete-file-version on a vanilla bucket. Used by `actionsForDestOnly`\n * to avoid yielding both a hide AND a delete when only one of them is\n * the correct semantic for the destination bucket.\n */\n removeOrphan(dest: B2SyncPath): SyncAction\n}\n\n/**\n * Converts a paired source/dest tuple into zero or more sync actions based on the\n * sync direction, compare mode, and keep policy.\n * For `compareMode: 'sha1'`, prefer the high-level `synchronize()` API so local\n * file hashes and comparable B2 hashes are prepared before actions are generated.\n * Low-level callers must pass pairs with local `contentSha1` values already\n * computed and B2 `contentSha1` values containing any comparable metadata fallback.\n *\n * @param pair - The source/dest file pair from {@link zipFolders}.\n * @param direction - The sync direction.\n * @param compareMode - How to compare files for differences.\n * @param keepMode - Policy for destination-only files.\n * @param keepDays - Retention period when keepMode is 'keep-days'.\n * @param nowMillis - Current time in milliseconds, used for keep-days calculation.\n * @param factory - Factory to create the concrete action objects.\n * @param compareThreshold - Tolerance for the comparison.\n */\nexport function* generateActions(\n pair: SyncPair,\n direction: SyncDirection,\n compareMode: CompareMode,\n keepMode: KeepMode,\n keepDays: number,\n nowMillis: number,\n factory: ActionFactory,\n compareThreshold: number,\n): Generator<SyncAction> {\n assertSupportedCompareMode(compareMode)\n\n const [source, dest] = pair\n\n if (source !== null && dest === null) {\n yield* actionsForSourceOnly(source, direction, factory)\n } else if (source === null && dest !== null) {\n yield* actionsForDestOnly(dest, direction, keepMode, keepDays, nowMillis, factory)\n } else if (source !== null && dest !== null) {\n yield* actionsForBoth(source, dest, direction, compareMode, compareThreshold, factory)\n }\n}\n\nfunction* actionsForSourceOnly(\n source: SyncPath,\n direction: SyncDirection,\n factory: ActionFactory,\n): Generator<SyncAction> {\n switch (direction) {\n case 'local-to-b2':\n yield factory.upload(source as LocalSyncPath)\n break\n case 'b2-to-local':\n yield factory.download(source as B2SyncPath, null)\n break\n case 'b2-to-b2':\n yield factory.copy(source as B2SyncPath, source.relativePath)\n break\n }\n}\n\nfunction* actionsForDestOnly(\n dest: SyncPath,\n direction: SyncDirection,\n keepMode: KeepMode,\n keepDays: number,\n nowMillis: number,\n factory: ActionFactory,\n): Generator<SyncAction> {\n if (keepMode === 'no-delete') {\n yield new SkipAction(dest.relativePath, 'not in source, keep-mode is no-delete')\n return\n }\n\n if (keepMode === 'keep-days') {\n const ageMillis = nowMillis - dest.modTimeMillis\n const ageDays = ageMillis / (24 * 60 * 60 * 1000)\n if (ageDays < keepDays) {\n yield new SkipAction(\n dest.relativePath,\n `not in source, keeping for ${Math.ceil(keepDays - ageDays)} more days`,\n )\n return\n }\n }\n\n switch (direction) {\n case 'local-to-b2':\n // Single action — `removeOrphan` picks hide vs delete based on\n // the destination bucket's `fileLockEnabled` state. The previous\n // \"yield both\" behaviour stacked hide markers on vanilla buckets\n // even though the delete that followed made them redundant.\n yield factory.removeOrphan(dest as B2SyncPath)\n break\n case 'b2-to-local':\n yield factory.deleteLocal(dest as LocalSyncPath)\n break\n case 'b2-to-b2':\n yield factory.removeOrphan(dest as B2SyncPath)\n break\n }\n}\n\nfunction* actionsForBoth(\n source: SyncPath,\n dest: SyncPath,\n direction: SyncDirection,\n compareMode: CompareMode,\n compareThreshold: number,\n factory: ActionFactory,\n): Generator<SyncAction> {\n if (!filesAreDifferent(source, dest, compareMode, compareThreshold)) {\n yield new SkipAction(source.relativePath, 'files are the same')\n return\n }\n\n switch (direction) {\n case 'local-to-b2':\n yield factory.upload(source as LocalSyncPath, dest as B2SyncPath)\n break\n case 'b2-to-local':\n yield factory.download(source as B2SyncPath, dest as LocalSyncPath)\n break\n case 'b2-to-b2': {\n const action =\n factory.copyB2Path?.(source as B2SyncPath, dest as B2SyncPath) ??\n factory.copy(source as B2SyncPath, dest.relativePath)\n yield action\n break\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAgFA,UAAiB,gBACf,MACA,WACA,aACA,UACA,UACA,WACA,SACA,kBACuB;CACvB,2BAA2B,WAAW;CAEtC,MAAM,CAAC,QAAQ,QAAQ;CAEvB,IAAI,WAAW,QAAQ,SAAS,MAC9B,OAAO,qBAAqB,QAAQ,WAAW,OAAO;MACjD,IAAI,WAAW,QAAQ,SAAS,MACrC,OAAO,mBAAmB,MAAM,WAAW,UAAU,UAAU,WAAW,OAAO;MAC5E,IAAI,WAAW,QAAQ,SAAS,MACrC,OAAO,eAAe,QAAQ,MAAM,WAAW,aAAa,kBAAkB,OAAO;AAEzF;AAEA,UAAU,qBACR,QACA,WACA,SACuB;CACvB,QAAQ,WAAR;EACE,KAAK;GACH,MAAM,QAAQ,OAAO,MAAuB;GAC5C;EACF,KAAK;GACH,MAAM,QAAQ,SAAS,QAAsB,IAAI;GACjD;EACF,KAAK,YACH,MAAM,QAAQ,KAAK,QAAsB,OAAO,YAAY;CAEhE;AACF;AAEA,UAAU,mBACR,MACA,WACA,UACA,UACA,WACA,SACuB;CACvB,IAAI,aAAa,aAAa;EAC5B,MAAM,IAAI,WAAW,KAAK,cAAc,uCAAuC;EAC/E;CACF;CAEA,IAAI,aAAa,aAAa;EAE5B,MAAM,WADY,YAAY,KAAK,iBACN;EAC7B,IAAI,UAAU,UAAU;GACtB,MAAM,IAAI,WACR,KAAK,cACL,8BAA8B,KAAK,KAAK,WAAW,OAAO,EAAE,WAC9D;GACA;EACF;CACF;CAEA,QAAQ,WAAR;EACE,KAAK;GAKH,MAAM,QAAQ,aAAa,IAAkB;GAC7C;EACF,KAAK;GACH,MAAM,QAAQ,YAAY,IAAqB;GAC/C;EACF,KAAK,YACH,MAAM,QAAQ,aAAa,IAAkB;CAEjD;AACF;AAEA,UAAU,eACR,QACA,MACA,WACA,aACA,kBACA,SACuB;CACvB,IAAI,CAAC,kBAAkB,QAAQ,MAAM,aAAa,gBAAgB,GAAG;EACnE,MAAM,IAAI,WAAW,OAAO,cAAc,oBAAoB;EAC9D;CACF;CAEA,QAAQ,WAAR;EACE,KAAK;GACH,MAAM,QAAQ,OAAO,QAAyB,IAAkB;GAChE;EACF,KAAK;GACH,MAAM,QAAQ,SAAS,QAAsB,IAAqB;GAClE;EACF,KAAK,YAIH,MAFE,QAAQ,aAAa,QAAsB,IAAkB,KAC7D,QAAQ,KAAK,QAAsB,KAAK,YAAY;CAI1D;AACF"}
@@ -0,0 +1,96 @@
1
+ const require_download_staging = require("./download-staging.cjs");
2
+ //#region src/sync/prefix.ts
3
+ /**
4
+ * Treats the supplied string as a raw B2 key prefix without adding a folder boundary.
5
+ *
6
+ * B2 keys are byte-oriented names, not local filesystem paths. A backslash in a prefix is a real
7
+ * key character and must not be rewritten to `/`; callers that want slash-delimited prefixes should
8
+ * pass `/` explicitly.
9
+ *
10
+ * @param prefix - User-supplied raw B2 key prefix.
11
+ *
12
+ * @returns Raw B2 key prefix.
13
+ */
14
+ function asRawB2KeyPrefix(prefix) {
15
+ return prefix;
16
+ }
17
+ /**
18
+ * Normalizes a B2 object name into a safe folder-relative sync path.
19
+ *
20
+ * Object names are converted to forward-slash sync paths for local compatibility. Callers that scan
21
+ * B2 must detect normalized-path collisions between distinct raw B2 keys before yielding entries.
22
+ *
23
+ * @param path - B2 object name or prefix-stripped suffix returned by a listing.
24
+ * @param options - Optional normalization behavior for legacy slashless raw prefixes.
25
+ *
26
+ * @returns Folder-relative sync path.
27
+ *
28
+ * @throws When the object name cannot be represented as a safe relative path.
29
+ */
30
+ function normalizeB2RelativePath(path, options = {}) {
31
+ const slashPath = path.split("\\").join("/");
32
+ const relativePath = options.stripLeadingSlashes === true ? stripSingleLeadingSlash(slashPath) : slashPath;
33
+ const segments = relativePath.split("/");
34
+ if (/^[A-Za-z]:/.test(relativePath) || segments.some((segment) => segmentIsUnsafe(segment))) throw new Error("Unsafe B2 file name cannot be used as a sync relative path");
35
+ return relativePath;
36
+ }
37
+ /**
38
+ * Converts a B2 object key under a configured raw prefix into a sync relative path.
39
+ *
40
+ * @param prefix - Raw B2 key prefix used for the scan or mutation guard.
41
+ * @param fileName - Full B2 object key.
42
+ *
43
+ * @returns The normalized sync relative path for the key suffix.
44
+ */
45
+ function b2KeyToRelativePathUnderPrefix(prefix, fileName) {
46
+ const rawPrefix = asRawB2KeyPrefix(prefix);
47
+ return normalizeB2RelativePath(rawPrefix === "" ? fileName : fileName.slice(rawPrefix.length), { stripLeadingSlashes: rawPrefix !== "" && !rawPrefix.endsWith("/") });
48
+ }
49
+ /**
50
+ * Returns whether a sync path is unsafe to materialize on Windows-compatible local filesystems.
51
+ * B2-to-B2 syncs can preserve these object names, but B2-to-local syncs skip them before writing.
52
+ *
53
+ * @param relativePath - Folder-relative sync path.
54
+ *
55
+ * @returns True when any segment is Windows-dangerous or ambiguous.
56
+ */
57
+ function localFilesystemSyncPathIsUnsafe(relativePath) {
58
+ const segments = relativePath.split("/");
59
+ return require_download_staging.isDownloadStagingDirectorySegment(segments[0]) || segments.some((segment) => segmentIsLocalFilesystemUnsafe(segment));
60
+ }
61
+ /**
62
+ * Produces an approximate Windows/macOS-style canonical key for local collision detection.
63
+ *
64
+ * @param relativePath - Folder-relative sync path.
65
+ *
66
+ * @returns A canonicalized path key for detecting case/Unicode collisions before local writes.
67
+ */
68
+ function localFilesystemCanonicalSyncPath(relativePath) {
69
+ return relativePath.split("/").map((segment) => segment.normalize("NFC").toLocaleLowerCase("en-US")).join("/");
70
+ }
71
+ function segmentIsUnsafe(segment) {
72
+ return segment === "" || segment === "." || segment === ".." || containsControlCharacter(segment);
73
+ }
74
+ function segmentIsLocalFilesystemUnsafe(segment) {
75
+ if (segment.includes(":") || segment.endsWith(".") || segment.endsWith(" ")) return true;
76
+ const basename = segment.split(".")[0]?.toUpperCase();
77
+ return basename !== void 0 && /^(CON|PRN|AUX|NUL|CONIN\$|CONOUT\$|COM[0-9¹²³]|LPT[0-9¹²³])$/u.test(basename);
78
+ }
79
+ function containsControlCharacter(segment) {
80
+ for (let index = 0; index < segment.length; index++) {
81
+ const code = segment.charCodeAt(index);
82
+ if (code >= 0 && code <= 31) return true;
83
+ }
84
+ return false;
85
+ }
86
+ function stripSingleLeadingSlash(path) {
87
+ return path.startsWith("/") ? path.slice(1) : path;
88
+ }
89
+ //#endregion
90
+ exports.asRawB2KeyPrefix = asRawB2KeyPrefix;
91
+ exports.b2KeyToRelativePathUnderPrefix = b2KeyToRelativePathUnderPrefix;
92
+ exports.localFilesystemCanonicalSyncPath = localFilesystemCanonicalSyncPath;
93
+ exports.localFilesystemSyncPathIsUnsafe = localFilesystemSyncPathIsUnsafe;
94
+ exports.normalizeB2RelativePath = normalizeB2RelativePath;
95
+
96
+ //# sourceMappingURL=prefix.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prefix.cjs","names":[],"sources":["../../src/sync/prefix.ts"],"sourcesContent":["import { isDownloadStagingDirectorySegment } from './download-staging.ts'\n\n/**\n * Treats the supplied string as a raw B2 key prefix without adding a folder boundary.\n *\n * B2 keys are byte-oriented names, not local filesystem paths. A backslash in a prefix is a real\n * key character and must not be rewritten to `/`; callers that want slash-delimited prefixes should\n * pass `/` explicitly.\n *\n * @param prefix - User-supplied raw B2 key prefix.\n *\n * @returns Raw B2 key prefix.\n */\nexport function asRawB2KeyPrefix(prefix: string): string {\n return prefix\n}\n\n/**\n * Normalizes a B2 object name into a safe folder-relative sync path.\n *\n * Object names are converted to forward-slash sync paths for local compatibility. Callers that scan\n * B2 must detect normalized-path collisions between distinct raw B2 keys before yielding entries.\n *\n * @param path - B2 object name or prefix-stripped suffix returned by a listing.\n * @param options - Optional normalization behavior for legacy slashless raw prefixes.\n *\n * @returns Folder-relative sync path.\n *\n * @throws When the object name cannot be represented as a safe relative path.\n */\nexport function normalizeB2RelativePath(\n path: string,\n options: { readonly stripLeadingSlashes?: boolean } = {},\n): string {\n const slashPath = path.split('\\\\').join('/')\n const relativePath =\n options.stripLeadingSlashes === true ? stripSingleLeadingSlash(slashPath) : slashPath\n const segments = relativePath.split('/')\n if (/^[A-Za-z]:/.test(relativePath) || segments.some((segment) => segmentIsUnsafe(segment))) {\n throw new Error('Unsafe B2 file name cannot be used as a sync relative path')\n }\n return relativePath\n}\n\n/**\n * Converts a B2 object key under a configured raw prefix into a sync relative path.\n *\n * @param prefix - Raw B2 key prefix used for the scan or mutation guard.\n * @param fileName - Full B2 object key.\n *\n * @returns The normalized sync relative path for the key suffix.\n */\nexport function b2KeyToRelativePathUnderPrefix(prefix: string, fileName: string): string {\n const rawPrefix = asRawB2KeyPrefix(prefix)\n const suffix = rawPrefix === '' ? fileName : fileName.slice(rawPrefix.length)\n return normalizeB2RelativePath(suffix, {\n stripLeadingSlashes: rawPrefix !== '' && !rawPrefix.endsWith('/'),\n })\n}\n\n/**\n * Returns whether a sync path is unsafe to materialize on Windows-compatible local filesystems.\n * B2-to-B2 syncs can preserve these object names, but B2-to-local syncs skip them before writing.\n *\n * @param relativePath - Folder-relative sync path.\n *\n * @returns True when any segment is Windows-dangerous or ambiguous.\n */\nexport function localFilesystemSyncPathIsUnsafe(relativePath: string): boolean {\n const segments = relativePath.split('/')\n return (\n isDownloadStagingDirectorySegment(segments[0]) ||\n segments.some((segment) => segmentIsLocalFilesystemUnsafe(segment))\n )\n}\n\n/**\n * Produces an approximate Windows/macOS-style canonical key for local collision detection.\n *\n * @param relativePath - Folder-relative sync path.\n *\n * @returns A canonicalized path key for detecting case/Unicode collisions before local writes.\n */\nexport function localFilesystemCanonicalSyncPath(relativePath: string): string {\n return relativePath\n .split('/')\n .map((segment) => segment.normalize('NFC').toLocaleLowerCase('en-US'))\n .join('/')\n}\n\nfunction segmentIsUnsafe(segment: string): boolean {\n return segment === '' || segment === '.' || segment === '..' || containsControlCharacter(segment)\n}\n\nfunction segmentIsLocalFilesystemUnsafe(segment: string): boolean {\n if (segment.includes(':') || segment.endsWith('.') || segment.endsWith(' ')) return true\n const basename = segment.split('.')[0]?.toUpperCase()\n return (\n basename !== undefined &&\n /^(CON|PRN|AUX|NUL|CONIN\\$|CONOUT\\$|COM[0-9¹²³]|LPT[0-9¹²³])$/u.test(basename)\n )\n}\n\nfunction containsControlCharacter(segment: string): boolean {\n for (let index = 0; index < segment.length; index++) {\n const code = segment.charCodeAt(index)\n if (code >= 0 && code <= 31) return true\n }\n return false\n}\n\nfunction stripSingleLeadingSlash(path: string): string {\n return path.startsWith('/') ? path.slice(1) : path\n}\n"],"mappings":";;;;;;;;;;;;;AAaA,SAAgB,iBAAiB,QAAwB;CACvD,OAAO;AACT;;;;;;;;;;;;;;AAeA,SAAgB,wBACd,MACA,UAAsD,CAAC,GAC/C;CACR,MAAM,YAAY,KAAK,MAAM,IAAI,CAAC,CAAC,KAAK,GAAG;CAC3C,MAAM,eACJ,QAAQ,wBAAwB,OAAO,wBAAwB,SAAS,IAAI;CAC9E,MAAM,WAAW,aAAa,MAAM,GAAG;CACvC,IAAI,aAAa,KAAK,YAAY,KAAK,SAAS,MAAM,YAAY,gBAAgB,OAAO,CAAC,GACxF,MAAM,IAAI,MAAM,4DAA4D;CAE9E,OAAO;AACT;;;;;;;;;AAUA,SAAgB,+BAA+B,QAAgB,UAA0B;CACvF,MAAM,YAAY,iBAAiB,MAAM;CAEzC,OAAO,wBADQ,cAAc,KAAK,WAAW,SAAS,MAAM,UAAU,MAAM,GACrC,EACrC,qBAAqB,cAAc,MAAM,CAAC,UAAU,SAAS,GAAG,EAClE,CAAC;AACH;;;;;;;;;AAUA,SAAgB,gCAAgC,cAA+B;CAC7E,MAAM,WAAW,aAAa,MAAM,GAAG;CACvC,OACE,yBAAA,kCAAkC,SAAS,EAAE,KAC7C,SAAS,MAAM,YAAY,+BAA+B,OAAO,CAAC;AAEtE;;;;;;;;AASA,SAAgB,iCAAiC,cAA8B;CAC7E,OAAO,aACJ,MAAM,GAAG,CAAC,CACV,KAAK,YAAY,QAAQ,UAAU,KAAK,CAAC,CAAC,kBAAkB,OAAO,CAAC,CAAC,CACrE,KAAK,GAAG;AACb;AAEA,SAAS,gBAAgB,SAA0B;CACjD,OAAO,YAAY,MAAM,YAAY,OAAO,YAAY,QAAQ,yBAAyB,OAAO;AAClG;AAEA,SAAS,+BAA+B,SAA0B;CAChE,IAAI,QAAQ,SAAS,GAAG,KAAK,QAAQ,SAAS,GAAG,KAAK,QAAQ,SAAS,GAAG,GAAG,OAAO;CACpF,MAAM,WAAW,QAAQ,MAAM,GAAG,CAAC,CAAC,EAAE,EAAE,YAAY;CACpD,OACE,aAAa,KAAA,KACb,gEAAgE,KAAK,QAAQ;AAEjF;AAEA,SAAS,yBAAyB,SAA0B;CAC1D,KAAK,IAAI,QAAQ,GAAG,QAAQ,QAAQ,QAAQ,SAAS;EACnD,MAAM,OAAO,QAAQ,WAAW,KAAK;EACrC,IAAI,QAAQ,KAAK,QAAQ,IAAI,OAAO;CACtC;CACA,OAAO;AACT;AAEA,SAAS,wBAAwB,MAAsB;CACrD,OAAO,KAAK,WAAW,GAAG,IAAI,KAAK,MAAM,CAAC,IAAI;AAChD"}