@backblaze-labs/b2-sdk 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (701) hide show
  1. package/CHANGELOG.md +110 -5
  2. package/README.md +144 -33
  3. package/dist/_virtual/_b2-sdk-version-json.cjs +4 -0
  4. package/dist/_virtual/_b2-sdk-version-json.js +4 -0
  5. package/dist/auth/account-info.d.cts +32 -0
  6. package/dist/auth/account-info.d.cts.map +1 -1
  7. package/dist/auth/account-info.d.ts +32 -0
  8. package/dist/auth/account-info.d.ts.map +1 -1
  9. package/dist/auth/file.cjs +408 -207
  10. package/dist/auth/file.cjs.map +1 -1
  11. package/dist/auth/file.d.cts +77 -3
  12. package/dist/auth/file.d.cts.map +1 -1
  13. package/dist/auth/file.d.ts +77 -3
  14. package/dist/auth/file.d.ts.map +1 -1
  15. package/dist/auth/file.js +407 -207
  16. package/dist/auth/file.js.map +1 -1
  17. package/dist/auth/in-memory.cjs +212 -183
  18. package/dist/auth/in-memory.cjs.map +1 -1
  19. package/dist/auth/in-memory.d.cts +8 -0
  20. package/dist/auth/in-memory.d.cts.map +1 -1
  21. package/dist/auth/in-memory.d.ts +8 -0
  22. package/dist/auth/in-memory.d.ts.map +1 -1
  23. package/dist/auth/in-memory.js +211 -182
  24. package/dist/auth/in-memory.js.map +1 -1
  25. package/dist/auth/index.cjs +7 -9
  26. package/dist/auth/index.d.cts +3 -2
  27. package/dist/auth/index.d.cts.map +1 -1
  28. package/dist/auth/index.d.ts +3 -2
  29. package/dist/auth/index.d.ts.map +1 -1
  30. package/dist/auth/index.js +2 -8
  31. package/dist/auth/realms.cjs +80 -7
  32. package/dist/auth/realms.cjs.map +1 -1
  33. package/dist/auth/realms.d.cts +27 -4
  34. package/dist/auth/realms.d.cts.map +1 -1
  35. package/dist/auth/realms.d.ts +27 -4
  36. package/dist/auth/realms.d.ts.map +1 -1
  37. package/dist/auth/realms.js +80 -9
  38. package/dist/auth/realms.js.map +1 -1
  39. package/dist/auth/upload-url-pool.cjs +55 -51
  40. package/dist/auth/upload-url-pool.cjs.map +1 -1
  41. package/dist/auth/upload-url-pool.js +55 -51
  42. package/dist/auth/upload-url-pool.js.map +1 -1
  43. package/dist/bucket.cjs +785 -787
  44. package/dist/bucket.cjs.map +1 -1
  45. package/dist/bucket.d.cts +35 -47
  46. package/dist/bucket.d.cts.map +1 -1
  47. package/dist/bucket.d.ts +35 -47
  48. package/dist/bucket.d.ts.map +1 -1
  49. package/dist/bucket.js +780 -782
  50. package/dist/bucket.js.map +1 -1
  51. package/dist/client.cjs +246 -228
  52. package/dist/client.cjs.map +1 -1
  53. package/dist/client.d.cts +25 -17
  54. package/dist/client.d.cts.map +1 -1
  55. package/dist/client.d.ts +25 -17
  56. package/dist/client.d.ts.map +1 -1
  57. package/dist/client.js +243 -225
  58. package/dist/client.js.map +1 -1
  59. package/dist/copy/large.cjs +114 -71
  60. package/dist/copy/large.cjs.map +1 -1
  61. package/dist/copy/large.d.cts +6 -0
  62. package/dist/copy/large.d.cts.map +1 -1
  63. package/dist/copy/large.d.ts +6 -0
  64. package/dist/copy/large.d.ts.map +1 -1
  65. package/dist/copy/large.js +112 -69
  66. package/dist/copy/large.js.map +1 -1
  67. package/dist/download/checksum.cjs +89 -0
  68. package/dist/download/checksum.cjs.map +1 -0
  69. package/dist/download/checksum.d.cts +40 -0
  70. package/dist/download/checksum.d.cts.map +1 -0
  71. package/dist/download/checksum.d.ts +40 -0
  72. package/dist/download/checksum.d.ts.map +1 -0
  73. package/dist/download/checksum.js +87 -0
  74. package/dist/download/checksum.js.map +1 -0
  75. package/dist/download/parallel.cjs +214 -118
  76. package/dist/download/parallel.cjs.map +1 -1
  77. package/dist/download/parallel.d.cts +5 -1
  78. package/dist/download/parallel.d.cts.map +1 -1
  79. package/dist/download/parallel.d.ts +5 -1
  80. package/dist/download/parallel.d.ts.map +1 -1
  81. package/dist/download/parallel.js +212 -116
  82. package/dist/download/parallel.js.map +1 -1
  83. package/dist/download/single.cjs +188 -97
  84. package/dist/download/single.cjs.map +1 -1
  85. package/dist/download/single.d.cts +6 -1
  86. package/dist/download/single.d.cts.map +1 -1
  87. package/dist/download/single.d.ts +6 -1
  88. package/dist/download/single.d.ts.map +1 -1
  89. package/dist/download/single.js +186 -98
  90. package/dist/download/single.js.map +1 -1
  91. package/dist/errors/index.cjs +699 -243
  92. package/dist/errors/index.cjs.map +1 -1
  93. package/dist/errors/index.d.cts +285 -82
  94. package/dist/errors/index.d.cts.map +1 -1
  95. package/dist/errors/index.d.ts +285 -82
  96. package/dist/errors/index.d.ts.map +1 -1
  97. package/dist/errors/index.js +678 -261
  98. package/dist/errors/index.js.map +1 -1
  99. package/dist/http/retry.cjs +45 -28
  100. package/dist/http/retry.cjs.map +1 -1
  101. package/dist/http/retry.d.cts +15 -2
  102. package/dist/http/retry.d.cts.map +1 -1
  103. package/dist/http/retry.d.ts +15 -2
  104. package/dist/http/retry.d.ts.map +1 -1
  105. package/dist/http/retry.js +46 -31
  106. package/dist/http/retry.js.map +1 -1
  107. package/dist/http/transport.cjs +438 -140
  108. package/dist/http/transport.cjs.map +1 -1
  109. package/dist/http/transport.d.cts +21 -2
  110. package/dist/http/transport.d.cts.map +1 -1
  111. package/dist/http/transport.d.ts +21 -2
  112. package/dist/http/transport.d.ts.map +1 -1
  113. package/dist/http/transport.js +437 -140
  114. package/dist/http/transport.js.map +1 -1
  115. package/dist/http/url-guard.cjs +154 -89
  116. package/dist/http/url-guard.cjs.map +1 -1
  117. package/dist/http/url-guard.d.cts +25 -3
  118. package/dist/http/url-guard.d.cts.map +1 -1
  119. package/dist/http/url-guard.d.ts +25 -3
  120. package/dist/http/url-guard.d.ts.map +1 -1
  121. package/dist/http/url-guard.js +152 -90
  122. package/dist/http/url-guard.js.map +1 -1
  123. package/dist/http/user-agent.cjs +84 -44
  124. package/dist/http/user-agent.cjs.map +1 -1
  125. package/dist/http/user-agent.js +84 -46
  126. package/dist/http/user-agent.js.map +1 -1
  127. package/dist/index.cjs +101 -77
  128. package/dist/index.d.cts +27 -21
  129. package/dist/index.d.cts.map +1 -1
  130. package/dist/index.d.ts +27 -21
  131. package/dist/index.d.ts.map +1 -1
  132. package/dist/index.js +15 -71
  133. package/dist/internal/b2-naming.cjs +66 -0
  134. package/dist/internal/b2-naming.cjs.map +1 -0
  135. package/dist/internal/b2-naming.d.cts +43 -0
  136. package/dist/internal/b2-naming.d.cts.map +1 -0
  137. package/dist/internal/b2-naming.d.ts +43 -0
  138. package/dist/internal/b2-naming.d.ts.map +1 -0
  139. package/dist/internal/b2-naming.js +60 -0
  140. package/dist/internal/b2-naming.js.map +1 -0
  141. package/dist/internal/upload-retry-options.cjs +21 -0
  142. package/dist/internal/upload-retry-options.cjs.map +1 -0
  143. package/dist/internal/upload-retry-options.d.cts +12 -0
  144. package/dist/internal/upload-retry-options.d.cts.map +1 -0
  145. package/dist/internal/upload-retry-options.d.ts +12 -0
  146. package/dist/internal/upload-retry-options.d.ts.map +1 -0
  147. package/dist/internal/upload-retry-options.js +21 -0
  148. package/dist/internal/upload-retry-options.js.map +1 -0
  149. package/dist/internal/url-redaction.cjs +31 -0
  150. package/dist/internal/url-redaction.cjs.map +1 -0
  151. package/dist/internal/url-redaction.d.cts +17 -0
  152. package/dist/internal/url-redaction.d.cts.map +1 -0
  153. package/dist/internal/url-redaction.d.ts +17 -0
  154. package/dist/internal/url-redaction.d.ts.map +1 -0
  155. package/dist/internal/url-redaction.js +31 -0
  156. package/dist/internal/url-redaction.js.map +1 -0
  157. package/dist/notifications/index.cjs +4 -6
  158. package/dist/notifications/index.d.cts +1 -1
  159. package/dist/notifications/index.d.cts.map +1 -1
  160. package/dist/notifications/index.d.ts +1 -1
  161. package/dist/notifications/index.d.ts.map +1 -1
  162. package/dist/notifications/index.js +1 -6
  163. package/dist/notifications/webhook.cjs +195 -85
  164. package/dist/notifications/webhook.cjs.map +1 -1
  165. package/dist/notifications/webhook.d.cts.map +1 -1
  166. package/dist/notifications/webhook.d.ts.map +1 -1
  167. package/dist/notifications/webhook.js +195 -87
  168. package/dist/notifications/webhook.js.map +1 -1
  169. package/dist/object.cjs +253 -210
  170. package/dist/object.cjs.map +1 -1
  171. package/dist/object.d.cts +9 -55
  172. package/dist/object.d.cts.map +1 -1
  173. package/dist/object.d.ts +9 -55
  174. package/dist/object.d.ts.map +1 -1
  175. package/dist/object.js +249 -206
  176. package/dist/object.js.map +1 -1
  177. package/dist/raw/encoding.cjs +74 -35
  178. package/dist/raw/encoding.cjs.map +1 -1
  179. package/dist/raw/encoding.js +74 -38
  180. package/dist/raw/encoding.js.map +1 -1
  181. package/dist/raw/index.cjs +678 -587
  182. package/dist/raw/index.cjs.map +1 -1
  183. package/dist/raw/index.d.cts +121 -18
  184. package/dist/raw/index.d.cts.map +1 -1
  185. package/dist/raw/index.d.ts +121 -18
  186. package/dist/raw/index.d.ts.map +1 -1
  187. package/dist/raw/index.js +674 -589
  188. package/dist/raw/index.js.map +1 -1
  189. package/dist/s3/index.cjs +355 -18
  190. package/dist/s3/index.cjs.map +1 -1
  191. package/dist/s3/index.d.cts +233 -5
  192. package/dist/s3/index.d.cts.map +1 -1
  193. package/dist/s3/index.d.ts +233 -5
  194. package/dist/s3/index.d.ts.map +1 -1
  195. package/dist/s3/index.js +351 -22
  196. package/dist/s3/index.js.map +1 -1
  197. package/dist/s3/sigv4.cjs +149 -0
  198. package/dist/s3/sigv4.cjs.map +1 -0
  199. package/dist/s3/sigv4.d.cts +43 -0
  200. package/dist/s3/sigv4.d.cts.map +1 -0
  201. package/dist/s3/sigv4.d.ts +43 -0
  202. package/dist/s3/sigv4.d.ts.map +1 -0
  203. package/dist/s3/sigv4.js +148 -0
  204. package/dist/s3/sigv4.js.map +1 -0
  205. package/dist/s3/validation.cjs +69 -0
  206. package/dist/s3/validation.cjs.map +1 -0
  207. package/dist/s3/validation.d.cts +43 -0
  208. package/dist/s3/validation.d.cts.map +1 -0
  209. package/dist/s3/validation.d.ts +43 -0
  210. package/dist/s3/validation.d.ts.map +1 -0
  211. package/dist/s3/validation.js +66 -0
  212. package/dist/s3/validation.js.map +1 -0
  213. package/dist/simulator/capabilities.cjs +63 -48
  214. package/dist/simulator/capabilities.cjs.map +1 -1
  215. package/dist/simulator/capabilities.js +63 -49
  216. package/dist/simulator/capabilities.js.map +1 -1
  217. package/dist/simulator/index.cjs +2124 -1548
  218. package/dist/simulator/index.cjs.map +1 -1
  219. package/dist/simulator/index.d.cts +79 -11
  220. package/dist/simulator/index.d.cts.map +1 -1
  221. package/dist/simulator/index.d.ts +79 -11
  222. package/dist/simulator/index.d.ts.map +1 -1
  223. package/dist/simulator/index.js +2112 -1546
  224. package/dist/simulator/index.js.map +1 -1
  225. package/dist/simulator/validation.cjs +191 -153
  226. package/dist/simulator/validation.cjs.map +1 -1
  227. package/dist/simulator/validation.d.cts +3 -21
  228. package/dist/simulator/validation.d.cts.map +1 -1
  229. package/dist/simulator/validation.d.ts +3 -21
  230. package/dist/simulator/validation.d.ts.map +1 -1
  231. package/dist/simulator/validation.js +188 -162
  232. package/dist/simulator/validation.js.map +1 -1
  233. package/dist/streams/collect.cjs +74 -24
  234. package/dist/streams/collect.cjs.map +1 -1
  235. package/dist/streams/collect.d.cts +14 -1
  236. package/dist/streams/collect.d.cts.map +1 -1
  237. package/dist/streams/collect.d.ts +14 -1
  238. package/dist/streams/collect.d.ts.map +1 -1
  239. package/dist/streams/collect.js +74 -25
  240. package/dist/streams/collect.js.map +1 -1
  241. package/dist/streams/file-source.cjs +287 -0
  242. package/dist/streams/file-source.cjs.map +1 -0
  243. package/dist/streams/file-source.d.cts +96 -0
  244. package/dist/streams/file-source.d.cts.map +1 -0
  245. package/dist/streams/file-source.d.ts +96 -0
  246. package/dist/streams/file-source.d.ts.map +1 -0
  247. package/dist/streams/file-source.js +286 -0
  248. package/dist/streams/file-source.js.map +1 -0
  249. package/dist/streams/hash.cjs +207 -115
  250. package/dist/streams/hash.cjs.map +1 -1
  251. package/dist/streams/hash.d.cts +5 -4
  252. package/dist/streams/hash.d.cts.map +1 -1
  253. package/dist/streams/hash.d.ts +5 -4
  254. package/dist/streams/hash.d.ts.map +1 -1
  255. package/dist/streams/hash.js +208 -95
  256. package/dist/streams/hash.js.map +1 -1
  257. package/dist/streams/index.cjs +12 -12
  258. package/dist/streams/index.d.cts +3 -3
  259. package/dist/streams/index.d.cts.map +1 -1
  260. package/dist/streams/index.d.ts +3 -3
  261. package/dist/streams/index.d.ts.map +1 -1
  262. package/dist/streams/index.js +2 -10
  263. package/dist/streams/progress.cjs +60 -46
  264. package/dist/streams/progress.cjs.map +1 -1
  265. package/dist/streams/progress.js +60 -46
  266. package/dist/streams/progress.js.map +1 -1
  267. package/dist/streams/source.cjs +316 -146
  268. package/dist/streams/source.cjs.map +1 -1
  269. package/dist/streams/source.d.cts +56 -18
  270. package/dist/streams/source.d.cts.map +1 -1
  271. package/dist/streams/source.d.ts +56 -18
  272. package/dist/streams/source.d.ts.map +1 -1
  273. package/dist/streams/source.js +312 -149
  274. package/dist/streams/source.js.map +1 -1
  275. package/dist/sync/actions/index.cjs +236 -184
  276. package/dist/sync/actions/index.cjs.map +1 -1
  277. package/dist/sync/actions/index.d.cts +29 -21
  278. package/dist/sync/actions/index.d.cts.map +1 -1
  279. package/dist/sync/actions/index.d.ts +29 -21
  280. package/dist/sync/actions/index.d.ts.map +1 -1
  281. package/dist/sync/actions/index.js +236 -190
  282. package/dist/sync/actions/index.js.map +1 -1
  283. package/dist/sync/b2-sha1-reader.cjs +148 -0
  284. package/dist/sync/b2-sha1-reader.cjs.map +1 -0
  285. package/dist/sync/b2-sha1-reader.d.cts +58 -0
  286. package/dist/sync/b2-sha1-reader.d.cts.map +1 -0
  287. package/dist/sync/b2-sha1-reader.d.ts +58 -0
  288. package/dist/sync/b2-sha1-reader.d.ts.map +1 -0
  289. package/dist/sync/b2-sha1-reader.js +145 -0
  290. package/dist/sync/b2-sha1-reader.js.map +1 -0
  291. package/dist/sync/download-staging.cjs +265 -0
  292. package/dist/sync/download-staging.cjs.map +1 -0
  293. package/dist/sync/download-staging.d.cts +54 -0
  294. package/dist/sync/download-staging.d.cts.map +1 -0
  295. package/dist/sync/download-staging.d.ts +54 -0
  296. package/dist/sync/download-staging.d.ts.map +1 -0
  297. package/dist/sync/download-staging.js +259 -0
  298. package/dist/sync/download-staging.js.map +1 -0
  299. package/dist/sync/filesystem-errors.cjs +32 -0
  300. package/dist/sync/filesystem-errors.cjs.map +1 -0
  301. package/dist/sync/filesystem-errors.d.cts +8 -0
  302. package/dist/sync/filesystem-errors.d.cts.map +1 -0
  303. package/dist/sync/filesystem-errors.d.ts +8 -0
  304. package/dist/sync/filesystem-errors.d.ts.map +1 -0
  305. package/dist/sync/filesystem-errors.js +32 -0
  306. package/dist/sync/filesystem-errors.js.map +1 -0
  307. package/dist/sync/filters.cjs +217 -0
  308. package/dist/sync/filters.cjs.map +1 -0
  309. package/dist/sync/filters.d.cts +51 -0
  310. package/dist/sync/filters.d.cts.map +1 -0
  311. package/dist/sync/filters.d.ts +51 -0
  312. package/dist/sync/filters.d.ts.map +1 -0
  313. package/dist/sync/filters.js +213 -0
  314. package/dist/sync/filters.js.map +1 -0
  315. package/dist/sync/index.cjs +39 -22
  316. package/dist/sync/index.d.cts +14 -9
  317. package/dist/sync/index.d.cts.map +1 -1
  318. package/dist/sync/index.d.ts +14 -9
  319. package/dist/sync/index.d.ts.map +1 -1
  320. package/dist/sync/index.js +9 -20
  321. package/dist/sync/local-file-identity.cjs +61 -0
  322. package/dist/sync/local-file-identity.cjs.map +1 -0
  323. package/dist/sync/local-file-identity.d.cts +37 -0
  324. package/dist/sync/local-file-identity.d.cts.map +1 -0
  325. package/dist/sync/local-file-identity.d.ts +37 -0
  326. package/dist/sync/local-file-identity.d.ts.map +1 -0
  327. package/dist/sync/local-file-identity.js +60 -0
  328. package/dist/sync/local-file-identity.js.map +1 -0
  329. package/dist/sync/local-file-io.cjs +364 -0
  330. package/dist/sync/local-file-io.cjs.map +1 -0
  331. package/dist/sync/local-file-io.d.cts +75 -0
  332. package/dist/sync/local-file-io.d.cts.map +1 -0
  333. package/dist/sync/local-file-io.d.ts +75 -0
  334. package/dist/sync/local-file-io.d.ts.map +1 -0
  335. package/dist/sync/local-file-io.js +360 -0
  336. package/dist/sync/local-file-io.js.map +1 -0
  337. package/dist/sync/local-filesystem-root.cjs +27 -0
  338. package/dist/sync/local-filesystem-root.cjs.map +1 -0
  339. package/dist/sync/local-filesystem-root.d.cts +18 -0
  340. package/dist/sync/local-filesystem-root.d.cts.map +1 -0
  341. package/dist/sync/local-filesystem-root.d.ts +18 -0
  342. package/dist/sync/local-filesystem-root.d.ts.map +1 -0
  343. package/dist/sync/local-filesystem-root.js +26 -0
  344. package/dist/sync/local-filesystem-root.js.map +1 -0
  345. package/dist/sync/local-sha1.cjs +119 -0
  346. package/dist/sync/local-sha1.cjs.map +1 -0
  347. package/dist/sync/local-sha1.d.cts +39 -0
  348. package/dist/sync/local-sha1.d.cts.map +1 -0
  349. package/dist/sync/local-sha1.d.ts +39 -0
  350. package/dist/sync/local-sha1.d.ts.map +1 -0
  351. package/dist/sync/local-sha1.js +117 -0
  352. package/dist/sync/local-sha1.js.map +1 -0
  353. package/dist/sync/pairing.cjs +118 -29
  354. package/dist/sync/pairing.cjs.map +1 -1
  355. package/dist/sync/pairing.d.cts +7 -2
  356. package/dist/sync/pairing.d.cts.map +1 -1
  357. package/dist/sync/pairing.d.ts +7 -2
  358. package/dist/sync/pairing.d.ts.map +1 -1
  359. package/dist/sync/pairing.js +120 -31
  360. package/dist/sync/pairing.js.map +1 -1
  361. package/dist/sync/path-order.cjs +30 -0
  362. package/dist/sync/path-order.cjs.map +1 -0
  363. package/dist/sync/path-order.d.cts +28 -0
  364. package/dist/sync/path-order.d.cts.map +1 -0
  365. package/dist/sync/path-order.d.ts +28 -0
  366. package/dist/sync/path-order.d.ts.map +1 -0
  367. package/dist/sync/path-order.js +29 -0
  368. package/dist/sync/path-order.js.map +1 -0
  369. package/dist/sync/path-safety.cjs +111 -0
  370. package/dist/sync/path-safety.cjs.map +1 -0
  371. package/dist/sync/path-safety.d.cts +78 -0
  372. package/dist/sync/path-safety.d.cts.map +1 -0
  373. package/dist/sync/path-safety.d.ts +78 -0
  374. package/dist/sync/path-safety.d.ts.map +1 -0
  375. package/dist/sync/path-safety.js +105 -0
  376. package/dist/sync/path-safety.js.map +1 -0
  377. package/dist/sync/paths.d.cts +19 -0
  378. package/dist/sync/paths.d.cts.map +1 -0
  379. package/dist/sync/paths.d.ts +19 -0
  380. package/dist/sync/paths.d.ts.map +1 -0
  381. package/dist/sync/policies/compare.cjs +389 -11
  382. package/dist/sync/policies/compare.cjs.map +1 -1
  383. package/dist/sync/policies/compare.d.cts +100 -2
  384. package/dist/sync/policies/compare.d.cts.map +1 -1
  385. package/dist/sync/policies/compare.d.ts +100 -2
  386. package/dist/sync/policies/compare.d.ts.map +1 -1
  387. package/dist/sync/policies/compare.js +387 -13
  388. package/dist/sync/policies/compare.js.map +1 -1
  389. package/dist/sync/policies/index.cjs +76 -65
  390. package/dist/sync/policies/index.cjs.map +1 -1
  391. package/dist/sync/policies/index.d.cts +35 -6
  392. package/dist/sync/policies/index.d.cts.map +1 -1
  393. package/dist/sync/policies/index.d.ts +35 -6
  394. package/dist/sync/policies/index.d.ts.map +1 -1
  395. package/dist/sync/policies/index.js +76 -65
  396. package/dist/sync/policies/index.js.map +1 -1
  397. package/dist/sync/prefix.cjs +96 -0
  398. package/dist/sync/prefix.cjs.map +1 -0
  399. package/dist/sync/prefix.d.cts +55 -0
  400. package/dist/sync/prefix.d.cts.map +1 -0
  401. package/dist/sync/prefix.d.ts +55 -0
  402. package/dist/sync/prefix.d.ts.map +1 -0
  403. package/dist/sync/prefix.js +92 -0
  404. package/dist/sync/prefix.js.map +1 -0
  405. package/dist/sync/regexp-safety.cjs +192 -0
  406. package/dist/sync/regexp-safety.cjs.map +1 -0
  407. package/dist/sync/regexp-safety.d.cts +29 -0
  408. package/dist/sync/regexp-safety.d.cts.map +1 -0
  409. package/dist/sync/regexp-safety.d.ts +29 -0
  410. package/dist/sync/regexp-safety.d.ts.map +1 -0
  411. package/dist/sync/regexp-safety.js +190 -0
  412. package/dist/sync/regexp-safety.js.map +1 -0
  413. package/dist/sync/scan-events.cjs +33 -0
  414. package/dist/sync/scan-events.cjs.map +1 -0
  415. package/dist/sync/scan-events.d.cts +17 -0
  416. package/dist/sync/scan-events.d.cts.map +1 -0
  417. package/dist/sync/scan-events.d.ts +17 -0
  418. package/dist/sync/scan-events.d.ts.map +1 -0
  419. package/dist/sync/scan-events.js +32 -0
  420. package/dist/sync/scan-events.js.map +1 -0
  421. package/dist/sync/scan-limit.cjs +33 -0
  422. package/dist/sync/scan-limit.cjs.map +1 -0
  423. package/dist/sync/scan-limit.d.cts +21 -0
  424. package/dist/sync/scan-limit.d.cts.map +1 -0
  425. package/dist/sync/scan-limit.d.ts +21 -0
  426. package/dist/sync/scan-limit.d.ts.map +1 -0
  427. package/dist/sync/scan-limit.js +31 -0
  428. package/dist/sync/scan-limit.js.map +1 -0
  429. package/dist/sync/scanners/b2.cjs +239 -55
  430. package/dist/sync/scanners/b2.cjs.map +1 -1
  431. package/dist/sync/scanners/b2.d.cts +26 -7
  432. package/dist/sync/scanners/b2.d.cts.map +1 -1
  433. package/dist/sync/scanners/b2.d.ts +26 -7
  434. package/dist/sync/scanners/b2.d.ts.map +1 -1
  435. package/dist/sync/scanners/b2.js +239 -55
  436. package/dist/sync/scanners/b2.js.map +1 -1
  437. package/dist/sync/scanners/local.cjs +215 -56
  438. package/dist/sync/scanners/local.cjs.map +1 -1
  439. package/dist/sync/scanners/local.d.cts +22 -7
  440. package/dist/sync/scanners/local.d.cts.map +1 -1
  441. package/dist/sync/scanners/local.d.ts +22 -7
  442. package/dist/sync/scanners/local.d.ts.map +1 -1
  443. package/dist/sync/scanners/local.js +216 -57
  444. package/dist/sync/scanners/local.js.map +1 -1
  445. package/dist/sync/sha1-metadata.cjs +94 -0
  446. package/dist/sync/sha1-metadata.cjs.map +1 -0
  447. package/dist/sync/sha1-metadata.d.cts +82 -0
  448. package/dist/sync/sha1-metadata.d.cts.map +1 -0
  449. package/dist/sync/sha1-metadata.d.ts +82 -0
  450. package/dist/sync/sha1-metadata.d.ts.map +1 -0
  451. package/dist/sync/sha1-metadata.js +89 -0
  452. package/dist/sync/sha1-metadata.js.map +1 -0
  453. package/dist/sync/sha1-options.cjs +23 -0
  454. package/dist/sync/sha1-options.cjs.map +1 -0
  455. package/dist/sync/sha1-options.d.cts +14 -0
  456. package/dist/sync/sha1-options.d.cts.map +1 -0
  457. package/dist/sync/sha1-options.d.ts +14 -0
  458. package/dist/sync/sha1-options.d.ts.map +1 -0
  459. package/dist/sync/sha1-options.js +21 -0
  460. package/dist/sync/sha1-options.js.map +1 -0
  461. package/dist/sync/synchronizer.cjs +782 -197
  462. package/dist/sync/synchronizer.cjs.map +1 -1
  463. package/dist/sync/synchronizer.d.cts +47 -1
  464. package/dist/sync/synchronizer.d.cts.map +1 -1
  465. package/dist/sync/synchronizer.d.ts +47 -1
  466. package/dist/sync/synchronizer.d.ts.map +1 -1
  467. package/dist/sync/synchronizer.js +779 -173
  468. package/dist/sync/synchronizer.js.map +1 -1
  469. package/dist/sync/types.d.cts +208 -16
  470. package/dist/sync/types.d.cts.map +1 -1
  471. package/dist/sync/types.d.ts +208 -16
  472. package/dist/sync/types.d.ts.map +1 -1
  473. package/dist/types/auth.cjs +76 -56
  474. package/dist/types/auth.cjs.map +1 -1
  475. package/dist/types/auth.d.cts +67 -9
  476. package/dist/types/auth.d.cts.map +1 -1
  477. package/dist/types/auth.d.ts +67 -9
  478. package/dist/types/auth.d.ts.map +1 -1
  479. package/dist/types/auth.js +77 -57
  480. package/dist/types/auth.js.map +1 -1
  481. package/dist/types/bucket.cjs +74 -38
  482. package/dist/types/bucket.cjs.map +1 -1
  483. package/dist/types/bucket.js +75 -41
  484. package/dist/types/bucket.js.map +1 -1
  485. package/dist/types/encryption.cjs +364 -327
  486. package/dist/types/encryption.cjs.map +1 -1
  487. package/dist/types/encryption.d.cts +16 -0
  488. package/dist/types/encryption.d.cts.map +1 -1
  489. package/dist/types/encryption.d.ts +16 -0
  490. package/dist/types/encryption.d.ts.map +1 -1
  491. package/dist/types/encryption.js +364 -310
  492. package/dist/types/encryption.js.map +1 -1
  493. package/dist/types/errors.cjs +47 -0
  494. package/dist/types/errors.cjs.map +1 -0
  495. package/dist/types/errors.d.cts +13 -4
  496. package/dist/types/errors.d.cts.map +1 -1
  497. package/dist/types/errors.d.ts +13 -4
  498. package/dist/types/errors.d.ts.map +1 -1
  499. package/dist/types/errors.js +47 -0
  500. package/dist/types/errors.js.map +1 -0
  501. package/dist/types/file.cjs +36 -19
  502. package/dist/types/file.cjs.map +1 -1
  503. package/dist/types/file.d.cts +2 -2
  504. package/dist/types/file.d.cts.map +1 -1
  505. package/dist/types/file.d.ts +2 -2
  506. package/dist/types/file.d.ts.map +1 -1
  507. package/dist/types/file.js +37 -21
  508. package/dist/types/file.js.map +1 -1
  509. package/dist/types/ids.cjs +53 -9
  510. package/dist/types/ids.cjs.map +1 -1
  511. package/dist/types/ids.js +54 -15
  512. package/dist/types/ids.js.map +1 -1
  513. package/dist/types/index.d.cts +12 -11
  514. package/dist/types/index.d.cts.map +1 -1
  515. package/dist/types/index.d.ts +12 -11
  516. package/dist/types/index.d.ts.map +1 -1
  517. package/dist/types/key.d.cts +44 -8
  518. package/dist/types/key.d.cts.map +1 -1
  519. package/dist/types/key.d.ts +44 -8
  520. package/dist/types/key.d.ts.map +1 -1
  521. package/dist/types/lock.cjs +33 -13
  522. package/dist/types/lock.cjs.map +1 -1
  523. package/dist/types/lock.js +34 -15
  524. package/dist/types/lock.js.map +1 -1
  525. package/dist/types/notifications.cjs +44 -22
  526. package/dist/types/notifications.cjs.map +1 -1
  527. package/dist/types/notifications.js +45 -23
  528. package/dist/types/notifications.js.map +1 -1
  529. package/dist/types/upload.d.cts +39 -5
  530. package/dist/types/upload.d.cts.map +1 -1
  531. package/dist/types/upload.d.ts +39 -5
  532. package/dist/types/upload.d.ts.map +1 -1
  533. package/dist/upload/abort-scope.cjs +91 -0
  534. package/dist/upload/abort-scope.cjs.map +1 -0
  535. package/dist/upload/abort-scope.d.cts +48 -0
  536. package/dist/upload/abort-scope.d.cts.map +1 -0
  537. package/dist/upload/abort-scope.d.ts +48 -0
  538. package/dist/upload/abort-scope.d.ts.map +1 -0
  539. package/dist/upload/abort-scope.js +88 -0
  540. package/dist/upload/abort-scope.js.map +1 -0
  541. package/dist/upload/cancel.cjs +183 -8
  542. package/dist/upload/cancel.cjs.map +1 -1
  543. package/dist/upload/cancel.d.cts +110 -2
  544. package/dist/upload/cancel.d.cts.map +1 -1
  545. package/dist/upload/cancel.d.ts +110 -2
  546. package/dist/upload/cancel.d.ts.map +1 -1
  547. package/dist/upload/cancel.js +178 -9
  548. package/dist/upload/cancel.js.map +1 -1
  549. package/dist/upload/concurrency.cjs +79 -52
  550. package/dist/upload/concurrency.cjs.map +1 -1
  551. package/dist/upload/concurrency.js +79 -53
  552. package/dist/upload/concurrency.js.map +1 -1
  553. package/dist/upload/finish.cjs +59 -0
  554. package/dist/upload/finish.cjs.map +1 -0
  555. package/dist/upload/finish.d.cts +26 -0
  556. package/dist/upload/finish.d.cts.map +1 -0
  557. package/dist/upload/finish.d.ts +26 -0
  558. package/dist/upload/finish.d.ts.map +1 -0
  559. package/dist/upload/finish.js +59 -0
  560. package/dist/upload/finish.js.map +1 -0
  561. package/dist/upload/large.cjs +301 -218
  562. package/dist/upload/large.cjs.map +1 -1
  563. package/dist/upload/large.d.cts +76 -9
  564. package/dist/upload/large.d.cts.map +1 -1
  565. package/dist/upload/large.d.ts +76 -9
  566. package/dist/upload/large.d.ts.map +1 -1
  567. package/dist/upload/large.js +301 -218
  568. package/dist/upload/large.js.map +1 -1
  569. package/dist/upload/options.cjs +28 -0
  570. package/dist/upload/options.cjs.map +1 -0
  571. package/dist/upload/options.d.cts +104 -0
  572. package/dist/upload/options.d.cts.map +1 -0
  573. package/dist/upload/options.d.ts +104 -0
  574. package/dist/upload/options.d.ts.map +1 -0
  575. package/dist/upload/options.js +27 -0
  576. package/dist/upload/options.js.map +1 -0
  577. package/dist/upload/resume.cjs +333 -33
  578. package/dist/upload/resume.cjs.map +1 -1
  579. package/dist/upload/resume.d.cts +82 -12
  580. package/dist/upload/resume.d.cts.map +1 -1
  581. package/dist/upload/resume.d.ts +82 -12
  582. package/dist/upload/resume.d.ts.map +1 -1
  583. package/dist/upload/resume.js +330 -33
  584. package/dist/upload/resume.js.map +1 -1
  585. package/dist/upload/retry.cjs +186 -0
  586. package/dist/upload/retry.cjs.map +1 -0
  587. package/dist/upload/retry.d.cts +127 -0
  588. package/dist/upload/retry.d.cts.map +1 -0
  589. package/dist/upload/retry.d.ts +127 -0
  590. package/dist/upload/retry.d.ts.map +1 -0
  591. package/dist/upload/retry.js +182 -0
  592. package/dist/upload/retry.js.map +1 -0
  593. package/dist/upload/single.cjs +68 -44
  594. package/dist/upload/single.cjs.map +1 -1
  595. package/dist/upload/single.d.cts +2 -1
  596. package/dist/upload/single.d.cts.map +1 -1
  597. package/dist/upload/single.d.ts +2 -1
  598. package/dist/upload/single.d.ts.map +1 -1
  599. package/dist/upload/single.js +68 -44
  600. package/dist/upload/single.js.map +1 -1
  601. package/dist/upload/stream.cjs +317 -193
  602. package/dist/upload/stream.cjs.map +1 -1
  603. package/dist/upload/stream.d.cts +3 -1
  604. package/dist/upload/stream.d.cts.map +1 -1
  605. package/dist/upload/stream.d.ts +3 -1
  606. package/dist/upload/stream.d.ts.map +1 -1
  607. package/dist/upload/stream.js +316 -192
  608. package/dist/upload/stream.js.map +1 -1
  609. package/dist/util/best-effort.cjs +42 -8
  610. package/dist/util/best-effort.cjs.map +1 -1
  611. package/dist/util/best-effort.d.cts +2 -1
  612. package/dist/util/best-effort.d.cts.map +1 -1
  613. package/dist/util/best-effort.d.ts +2 -1
  614. package/dist/util/best-effort.d.ts.map +1 -1
  615. package/dist/util/best-effort.js +43 -9
  616. package/dist/util/best-effort.js.map +1 -1
  617. package/dist/util/bytes.cjs +23 -0
  618. package/dist/util/bytes.cjs.map +1 -0
  619. package/dist/util/bytes.d.cts +15 -0
  620. package/dist/util/bytes.d.cts.map +1 -0
  621. package/dist/util/bytes.d.ts +15 -0
  622. package/dist/util/bytes.d.ts.map +1 -0
  623. package/dist/util/bytes.js +23 -0
  624. package/dist/util/bytes.js.map +1 -0
  625. package/dist/util/crypto.cjs +68 -0
  626. package/dist/util/crypto.cjs.map +1 -0
  627. package/dist/util/crypto.d.cts +26 -0
  628. package/dist/util/crypto.d.cts.map +1 -0
  629. package/dist/util/crypto.d.ts +26 -0
  630. package/dist/util/crypto.d.ts.map +1 -0
  631. package/dist/util/crypto.js +66 -0
  632. package/dist/util/crypto.js.map +1 -0
  633. package/dist/util/defaults.cjs +25 -9
  634. package/dist/util/defaults.cjs.map +1 -1
  635. package/dist/util/defaults.js +26 -11
  636. package/dist/util/defaults.js.map +1 -1
  637. package/dist/util/error-reason.cjs +41 -0
  638. package/dist/util/error-reason.cjs.map +1 -0
  639. package/dist/util/error-reason.d.cts +9 -0
  640. package/dist/util/error-reason.d.cts.map +1 -0
  641. package/dist/util/error-reason.d.ts +9 -0
  642. package/dist/util/error-reason.d.ts.map +1 -0
  643. package/dist/util/error-reason.js +41 -0
  644. package/dist/util/error-reason.js.map +1 -0
  645. package/dist/util/http.cjs +23 -0
  646. package/dist/util/http.cjs.map +1 -0
  647. package/dist/util/http.d.cts +13 -0
  648. package/dist/util/http.d.cts.map +1 -0
  649. package/dist/util/http.d.ts +13 -0
  650. package/dist/util/http.d.ts.map +1 -0
  651. package/dist/util/http.js +23 -0
  652. package/dist/util/http.js.map +1 -0
  653. package/dist/util/normalize.cjs +66 -7
  654. package/dist/util/normalize.cjs.map +1 -1
  655. package/dist/util/normalize.js +67 -10
  656. package/dist/util/normalize.js.map +1 -1
  657. package/dist/util/paginator.cjs +63 -14
  658. package/dist/util/paginator.cjs.map +1 -1
  659. package/dist/util/paginator.js +64 -16
  660. package/dist/util/paginator.js.map +1 -1
  661. package/dist/util/plan-ranges.cjs +47 -22
  662. package/dist/util/plan-ranges.cjs.map +1 -1
  663. package/dist/util/plan-ranges.js +48 -24
  664. package/dist/util/plan-ranges.js.map +1 -1
  665. package/dist/util/sha1.cjs +27 -0
  666. package/dist/util/sha1.cjs.map +1 -0
  667. package/dist/util/sha1.d.cts +17 -0
  668. package/dist/util/sha1.d.cts.map +1 -0
  669. package/dist/util/sha1.d.ts +17 -0
  670. package/dist/util/sha1.d.ts.map +1 -0
  671. package/dist/util/sha1.js +26 -0
  672. package/dist/util/sha1.js.map +1 -0
  673. package/dist/util/text-codec.cjs +29 -5
  674. package/dist/util/text-codec.cjs.map +1 -1
  675. package/dist/util/text-codec.js +30 -7
  676. package/dist/util/text-codec.js.map +1 -1
  677. package/dist/util/to-error.cjs +18 -4
  678. package/dist/util/to-error.cjs.map +1 -1
  679. package/dist/util/to-error.js +19 -5
  680. package/dist/util/to-error.js.map +1 -1
  681. package/dist/version.cjs +17 -5
  682. package/dist/version.cjs.map +1 -1
  683. package/dist/version.d.cts +3 -3
  684. package/dist/version.d.ts +3 -3
  685. package/dist/version.js +19 -6
  686. package/dist/version.js.map +1 -1
  687. package/package.json +19 -16
  688. package/dist/auth/index.cjs.map +0 -1
  689. package/dist/auth/index.js.map +0 -1
  690. package/dist/index.cjs.map +0 -1
  691. package/dist/index.js.map +0 -1
  692. package/dist/notifications/index.cjs.map +0 -1
  693. package/dist/notifications/index.js.map +0 -1
  694. package/dist/package.json.cjs +0 -9
  695. package/dist/package.json.cjs.map +0 -1
  696. package/dist/package.json.js +0 -9
  697. package/dist/package.json.js.map +0 -1
  698. package/dist/streams/index.cjs.map +0 -1
  699. package/dist/streams/index.js.map +0 -1
  700. package/dist/sync/index.cjs.map +0 -1
  701. package/dist/sync/index.js.map +0 -1
@@ -0,0 +1,105 @@
1
+ //#region src/sync/path-safety.ts
2
+ var RESERVED_SYNC_TEMP_FILE_RE = /^\.b2sdk-[0-9a-f]{24}-[^/\\]+-[0-9a-f]{32}\.partial$/i;
3
+ var UUID_HEX_RE = /^[0-9a-f]{32}$/i;
4
+ /**
5
+ * Checks whether a basename is reserved for SDK-owned sync partial files.
6
+ * @param name - Basename to inspect.
7
+ *
8
+ * @returns Whether the basename matches the SDK reserved partial-file pattern.
9
+ *
10
+ * @internal
11
+ */
12
+ function isReservedSyncTempFileName(name) {
13
+ return RESERVED_SYNC_TEMP_FILE_RE.test(name);
14
+ }
15
+ /**
16
+ * Rejects sync paths whose basename is reserved for SDK-owned temporary files.
17
+ * @param relativePath - Sync-relative path using slash separators.
18
+ *
19
+ * @throws If any path segment uses the SDK's reserved temporary-file pattern.
20
+ *
21
+ * @internal
22
+ */
23
+ function assertSyncPathAllowed(relativePath) {
24
+ if (relativePath.split(/[\\/]+/).filter(Boolean).some((part) => isReservedSyncTempFileName(part))) throw new Error(`Sync path uses reserved SDK temporary-file name: ${relativePath}`);
25
+ }
26
+ /**
27
+ * Creates a download staging basename inside the SDK-reserved temp namespace.
28
+ * @param finalName - Final destination basename.
29
+ * @param uuid - UUID used to make the temp basename unique.
30
+ *
31
+ * @returns A basename that local and B2 scanners reject as SDK-owned temp data.
32
+ *
33
+ * @throws If the provided UUID cannot be normalized to 32 hex characters.
34
+ *
35
+ * @internal
36
+ */
37
+ function makeReservedSyncTempFileName(finalName, uuid) {
38
+ if (finalName.length === 0 || /[\\/]/.test(finalName)) throw new Error("invalid sync temporary-file basename");
39
+ const hex = uuid.replaceAll("-", "").toLowerCase();
40
+ if (!UUID_HEX_RE.test(hex)) throw new Error("invalid sync temporary-file nonce");
41
+ return `.b2sdk-${hex.slice(0, 24)}-${finalName}-${hex}.partial`;
42
+ }
43
+ /**
44
+ * Validates B2 relative names before they are materialized on a local filesystem.
45
+ *
46
+ * @param relPath - B2-style relative path.
47
+ *
48
+ * @returns Validated path segments.
49
+ *
50
+ * @throws When the path is empty, absolute, platform-ambiguous, or contains traversal.
51
+ *
52
+ * @internal
53
+ */
54
+ function safeRelativePathSegments(relPath) {
55
+ assertSyncPathAllowed(relPath);
56
+ if (relPath.length === 0 || relPath.includes("\0") || relPath.includes("\\") || relPath.startsWith("/") || /^[A-Za-z]:/.test(relPath)) throw new Error("unsafe local destination path");
57
+ const segments = relPath.split("/");
58
+ if (segments.some((segment) => segment.length === 0 || segment === "." || segment === ".." || segment.includes(":") || segment.endsWith(".") || segment.endsWith(" ") || WINDOWS_RESERVED_NAME.test(segment))) throw new Error("unsafe local destination path");
59
+ return segments;
60
+ }
61
+ var WINDOWS_RESERVED_NAME = /^(con|prn|aux|nul|conin\$|conout\$|com[0-9\u00b9\u00b2\u00b3]|lpt[0-9\u00b9\u00b2\u00b3])(?:\..*)?$/i;
62
+ /**
63
+ * Throws if {@link target} is outside {@link root} or names the root itself.
64
+ *
65
+ * @param root - Resolved filesystem root.
66
+ * @param target - Candidate path to validate.
67
+ * @param path - Node path module.
68
+ *
69
+ * @throws When the target is outside the root or equal to the root.
70
+ *
71
+ * @internal
72
+ */
73
+ function assertPathInsideRoot(root, target, path) {
74
+ const relative = path.relative(root, target);
75
+ if (relative.length === 0 || relative === ".." || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) throw new Error("unsafe local destination path");
76
+ }
77
+ /**
78
+ * Returns the platform's no-follow open flag when available.
79
+ *
80
+ * @param constants - Node filesystem constants.
81
+ *
82
+ * @returns The `O_NOFOLLOW` bit or `0`.
83
+ *
84
+ * @internal
85
+ */
86
+ function noFollowFlag(constants) {
87
+ return constants.O_NOFOLLOW ?? 0;
88
+ }
89
+ /**
90
+ * Checks whether an unknown thrown value has a specific Node error code.
91
+ *
92
+ * @param err - Unknown thrown value.
93
+ * @param code - Expected Node error code.
94
+ *
95
+ * @returns True when the value exposes the expected code.
96
+ *
97
+ * @internal
98
+ */
99
+ function hasErrorCode(err, code) {
100
+ return err.code === code;
101
+ }
102
+ //#endregion
103
+ export { assertPathInsideRoot, assertSyncPathAllowed, hasErrorCode, isReservedSyncTempFileName, makeReservedSyncTempFileName, noFollowFlag, safeRelativePathSegments };
104
+
105
+ //# sourceMappingURL=path-safety.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-safety.js","names":[],"sources":["../../src/sync/path-safety.ts"],"sourcesContent":["const RESERVED_SYNC_TEMP_FILE_RE = /^\\.b2sdk-[0-9a-f]{24}-[^/\\\\]+-[0-9a-f]{32}\\.partial$/i\nconst UUID_HEX_RE = /^[0-9a-f]{32}$/i\n\n/**\n * Checks whether a basename is reserved for SDK-owned sync partial files.\n * @param name - Basename to inspect.\n *\n * @returns Whether the basename matches the SDK reserved partial-file pattern.\n *\n * @internal\n */\nexport function isReservedSyncTempFileName(name: string): boolean {\n return RESERVED_SYNC_TEMP_FILE_RE.test(name)\n}\n\n/**\n * Rejects sync paths whose basename is reserved for SDK-owned temporary files.\n * @param relativePath - Sync-relative path using slash separators.\n *\n * @throws If any path segment uses the SDK's reserved temporary-file pattern.\n *\n * @internal\n */\nexport function assertSyncPathAllowed(relativePath: string): void {\n const parts = relativePath.split(/[\\\\/]+/).filter(Boolean)\n if (parts.some((part) => isReservedSyncTempFileName(part))) {\n throw new Error(`Sync path uses reserved SDK temporary-file name: ${relativePath}`)\n }\n}\n\n/**\n * Creates a download staging basename inside the SDK-reserved temp namespace.\n * @param finalName - Final destination basename.\n * @param uuid - UUID used to make the temp basename unique.\n *\n * @returns A basename that local and B2 scanners reject as SDK-owned temp data.\n *\n * @throws If the provided UUID cannot be normalized to 32 hex characters.\n *\n * @internal\n */\nexport function makeReservedSyncTempFileName(finalName: string, uuid: string): string {\n if (finalName.length === 0 || /[\\\\/]/.test(finalName)) {\n throw new Error('invalid sync temporary-file basename')\n }\n const hex = uuid.replaceAll('-', '').toLowerCase()\n if (!UUID_HEX_RE.test(hex)) {\n throw new Error('invalid sync temporary-file nonce')\n }\n return `.b2sdk-${hex.slice(0, 24)}-${finalName}-${hex}.partial`\n}\n\n/**\n * Validates B2 relative names before they are materialized on a local filesystem.\n *\n * @param relPath - B2-style relative path.\n *\n * @returns Validated path segments.\n *\n * @throws When the path is empty, absolute, platform-ambiguous, or contains traversal.\n *\n * @internal\n */\nexport function safeRelativePathSegments(relPath: string): string[] {\n assertSyncPathAllowed(relPath)\n if (\n relPath.length === 0 ||\n relPath.includes('\\0') ||\n relPath.includes('\\\\') ||\n relPath.startsWith('/') ||\n /^[A-Za-z]:/.test(relPath)\n ) {\n throw new Error('unsafe local destination path')\n }\n\n const segments = relPath.split('/')\n if (\n segments.some(\n (segment) =>\n segment.length === 0 ||\n segment === '.' ||\n segment === '..' ||\n segment.includes(':') ||\n segment.endsWith('.') ||\n segment.endsWith(' ') ||\n WINDOWS_RESERVED_NAME.test(segment),\n )\n ) {\n throw new Error('unsafe local destination path')\n }\n return segments\n}\n\nconst WINDOWS_RESERVED_NAME =\n /^(con|prn|aux|nul|conin\\$|conout\\$|com[0-9\\u00b9\\u00b2\\u00b3]|lpt[0-9\\u00b9\\u00b2\\u00b3])(?:\\..*)?$/i\n\n/**\n * Throws if {@link target} is outside {@link root} or names the root itself.\n *\n * @param root - Resolved filesystem root.\n * @param target - Candidate path to validate.\n * @param path - Node path module.\n *\n * @throws When the target is outside the root or equal to the root.\n *\n * @internal\n */\nexport function assertPathInsideRoot(\n root: string,\n target: string,\n path: typeof import('node:path'),\n): void {\n const relative = path.relative(root, target)\n if (\n relative.length === 0 ||\n relative === '..' ||\n relative.startsWith(`..${path.sep}`) ||\n path.isAbsolute(relative)\n ) {\n throw new Error('unsafe local destination path')\n }\n}\n\n/**\n * Returns the platform's no-follow open flag when available.\n *\n * @param constants - Node filesystem constants.\n *\n * @returns The `O_NOFOLLOW` bit or `0`.\n *\n * @internal\n */\nexport function noFollowFlag(constants: { readonly O_NOFOLLOW?: number }): number {\n return constants.O_NOFOLLOW ?? 0\n}\n\n/**\n * Checks whether an unknown thrown value has a specific Node error code.\n *\n * @param err - Unknown thrown value.\n * @param code - Expected Node error code.\n *\n * @returns True when the value exposes the expected code.\n *\n * @internal\n */\nexport function hasErrorCode(err: unknown, code: string): boolean {\n return (err as { readonly code?: unknown }).code === code\n}\n"],"mappings":";AAAA,IAAM,6BAA6B;AACnC,IAAM,cAAc;;;;;;;;;AAUpB,SAAgB,2BAA2B,MAAuB;CAChE,OAAO,2BAA2B,KAAK,IAAI;AAC7C;;;;;;;;;AAUA,SAAgB,sBAAsB,cAA4B;CAEhE,IADc,aAAa,MAAM,QAAQ,CAAC,CAAC,OAAO,OAC9C,CAAA,CAAM,MAAM,SAAS,2BAA2B,IAAI,CAAC,GACvD,MAAM,IAAI,MAAM,oDAAoD,cAAc;AAEtF;;;;;;;;;;;;AAaA,SAAgB,6BAA6B,WAAmB,MAAsB;CACpF,IAAI,UAAU,WAAW,KAAK,QAAQ,KAAK,SAAS,GAClD,MAAM,IAAI,MAAM,sCAAsC;CAExD,MAAM,MAAM,KAAK,WAAW,KAAK,EAAE,CAAC,CAAC,YAAY;CACjD,IAAI,CAAC,YAAY,KAAK,GAAG,GACvB,MAAM,IAAI,MAAM,mCAAmC;CAErD,OAAO,UAAU,IAAI,MAAM,GAAG,EAAE,EAAE,GAAG,UAAU,GAAG,IAAI;AACxD;;;;;;;;;;;;AAaA,SAAgB,yBAAyB,SAA2B;CAClE,sBAAsB,OAAO;CAC7B,IACE,QAAQ,WAAW,KACnB,QAAQ,SAAS,IAAI,KACrB,QAAQ,SAAS,IAAI,KACrB,QAAQ,WAAW,GAAG,KACtB,aAAa,KAAK,OAAO,GAEzB,MAAM,IAAI,MAAM,+BAA+B;CAGjD,MAAM,WAAW,QAAQ,MAAM,GAAG;CAClC,IACE,SAAS,MACN,YACC,QAAQ,WAAW,KACnB,YAAY,OACZ,YAAY,QACZ,QAAQ,SAAS,GAAG,KACpB,QAAQ,SAAS,GAAG,KACpB,QAAQ,SAAS,GAAG,KACpB,sBAAsB,KAAK,OAAO,CACtC,GAEA,MAAM,IAAI,MAAM,+BAA+B;CAEjD,OAAO;AACT;AAEA,IAAM,wBACJ;;;;;;;;;;;;AAaF,SAAgB,qBACd,MACA,QACA,MACM;CACN,MAAM,WAAW,KAAK,SAAS,MAAM,MAAM;CAC3C,IACE,SAAS,WAAW,KACpB,aAAa,QACb,SAAS,WAAW,KAAK,KAAK,KAAK,KACnC,KAAK,WAAW,QAAQ,GAExB,MAAM,IAAI,MAAM,+BAA+B;AAEnD;;;;;;;;;;AAWA,SAAgB,aAAa,WAAqD;CAChF,OAAO,UAAU,cAAc;AACjC;;;;;;;;;;;AAYA,SAAgB,aAAa,KAAc,MAAuB;CAChE,OAAQ,IAAoC,SAAS;AACvD"}
@@ -0,0 +1,19 @@
1
+ export { assertSyncPathAllowed } from './path-safety.js';
2
+ interface PathOperations {
3
+ isAbsolute(path: string): boolean;
4
+ resolve(...paths: string[]): string;
5
+ readonly sep: string;
6
+ }
7
+ /**
8
+ * Resolves a sync-relative path under a local root without allowing traversal
9
+ * or SDK-reserved temporary-file names.
10
+ * @param root - Absolute local sync root.
11
+ * @param relativePath - Sync-relative path to resolve.
12
+ * @param path - Node path operations for the local platform.
13
+ *
14
+ * @returns The absolute local filesystem path.
15
+ *
16
+ * @throws If the path is absolute, escapes the root, or uses a reserved basename.
17
+ */
18
+ export declare function resolveSafeLocalPath(root: string, relativePath: string, path: PathOperations): string;
19
+ //# sourceMappingURL=paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/sync/paths.js"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAA;AAExD,UAAU,cAAc;IACtB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAA;IACjC,OAAO,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAAA;IACnC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CACrB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,cAAc,GACnB,MAAM,CAYR"}
@@ -0,0 +1,19 @@
1
+ export { assertSyncPathAllowed } from './path-safety.js';
2
+ interface PathOperations {
3
+ isAbsolute(path: string): boolean;
4
+ resolve(...paths: string[]): string;
5
+ readonly sep: string;
6
+ }
7
+ /**
8
+ * Resolves a sync-relative path under a local root without allowing traversal
9
+ * or SDK-reserved temporary-file names.
10
+ * @param root - Absolute local sync root.
11
+ * @param relativePath - Sync-relative path to resolve.
12
+ * @param path - Node path operations for the local platform.
13
+ *
14
+ * @returns The absolute local filesystem path.
15
+ *
16
+ * @throws If the path is absolute, escapes the root, or uses a reserved basename.
17
+ */
18
+ export declare function resolveSafeLocalPath(root: string, relativePath: string, path: PathOperations): string;
19
+ //# sourceMappingURL=paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/sync/paths.js"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAA;AAExD,UAAU,cAAc;IACtB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAA;IACjC,OAAO,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAAA;IACnC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CACrB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,cAAc,GACnB,MAAM,CAYR"}
@@ -1,14 +1,392 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
1
+ const require_concurrency = require("../../upload/concurrency.cjs");
2
+ const require_sha1 = require("../../util/sha1.cjs");
3
+ const require_to_error = require("../../util/to-error.cjs");
4
+ const require_local_sha1 = require("../local-sha1.cjs");
5
+ const require_sha1_metadata = require("../sha1-metadata.cjs");
6
+ //#region src/sync/policies/compare.ts
7
+ /**
8
+ * Determines whether two files should be considered different based on the compare mode.
9
+ * For `sha1`, callers that use the low-level policy helpers should first prepare the pair so
10
+ * local hashes and comparable B2 hashes are populated.
11
+ *
12
+ * @param source - The source file metadata.
13
+ * @param dest - The destination file metadata.
14
+ * @param compareMode - The comparison strategy: 'modtime', 'size', 'sha1', or 'none'.
15
+ * @param threshold - Tolerance for the comparison (bytes for size, milliseconds for modtime).
16
+ *
17
+ * @returns `true` if the files are considered different.
18
+ *
19
+ * @throws When `compareMode` is not one of the supported compare modes.
20
+ */
3
21
  function filesAreDifferent(source, dest, compareMode, threshold = 0) {
4
- switch (compareMode) {
5
- case "none":
6
- return false;
7
- case "size":
8
- return Math.abs(source.size - dest.size) > threshold;
9
- case "modtime":
10
- return Math.abs(source.modTimeMillis - dest.modTimeMillis) > threshold;
11
- }
22
+ switch (compareMode) {
23
+ case "none": return false;
24
+ case "size": return Math.abs(source.size - dest.size) > threshold;
25
+ case "sha1": return sha1ValuesAreDifferent(source, dest);
26
+ case "modtime": return Math.abs(source.modTimeMillis - dest.modTimeMillis) > threshold;
27
+ default: throw new Error(`Unsupported compare mode: ${String(compareMode)}`);
28
+ }
12
29
  }
30
+ /**
31
+ * Throws when a runtime compare mode value is unsupported.
32
+ *
33
+ * @param compareMode - User-supplied compare mode.
34
+ *
35
+ * @throws When `compareMode` is not one of the supported values.
36
+ */
37
+ function assertSupportedCompareMode(compareMode) {
38
+ switch (compareMode) {
39
+ case "none":
40
+ case "size":
41
+ case "sha1":
42
+ case "modtime": return;
43
+ default: throw new Error(`Unsupported compare mode: ${String(compareMode)}`);
44
+ }
45
+ }
46
+ function sha1ValuesAreDifferent(source, dest) {
47
+ if (source.size !== dest.size) return true;
48
+ const sourceSha1 = comparableSha1(source);
49
+ const destSha1 = comparableSha1(dest);
50
+ if (sourceSha1.kind === "untrusted" || destSha1.kind === "untrusted") return true;
51
+ if (sourceSha1.kind === "unavailable" || destSha1.kind === "unavailable") return true;
52
+ return sourceSha1.value !== destSha1.value;
53
+ }
54
+ /**
55
+ * Prepares a pair for the selected compare mode.
56
+ *
57
+ * For `sha1`, this fills missing B2 hashes from comparable metadata and, when an explicit local
58
+ * reader is supplied, hashes the local side only when size cannot already prove a difference.
59
+ * Reader failures are converted into per-file sync events instead of aborting the whole run.
60
+ *
61
+ * @param pair - Source/destination pair from {@link zipFolders}.
62
+ * @param compareMode - The comparison strategy.
63
+ * @param options - Optional hashing dependencies and cancellation signal.
64
+ *
65
+ * @returns The prepared pair plus any preparation events.
66
+ */
67
+ async function preparePairForCompare(pair, compareMode, options = {}) {
68
+ assertSupportedCompareMode(compareMode);
69
+ if (compareMode !== "sha1") return readyComparePair(pair);
70
+ const [source, dest] = pair;
71
+ if (source === null || dest === null) return readyComparePair(pair);
72
+ if (source.size !== dest.size) return readyComparePair(pair);
73
+ const metadataPair = [withB2ContentSha1(source), withB2ContentSha1(dest)];
74
+ if (hasUnavailableB2Sha1(metadataPair)) return skipped(metadataPair, unavailableSha1Event(metadataPair));
75
+ if (options.readB2Sha1 === void 0 && hasUntrustedSha1(metadataPair) && !hasVerifiableUntrustedSha1(metadataPair)) return readyComparePair(metadataPair);
76
+ const [metadataSource, metadataDest] = metadataPair;
77
+ if (metadataSource === null || metadataDest === null) return readyComparePair(metadataPair);
78
+ const sourceResult = await prepareLocalPathSha1(metadataSource, options);
79
+ if (sourceResult.aborted) return aborted(metadataPair);
80
+ if (sourceResult.event) return skipped(metadataPair, sourceResult.event, sourceResult.error, sourceResult.bytesHashed);
81
+ const destResult = await prepareLocalPathSha1(metadataDest, options);
82
+ if (destResult.aborted) return aborted([sourceResult.path, destResult.path]);
83
+ if (destResult.event) return skipped([sourceResult.path, destResult.path], destResult.event, destResult.error, sourceResult.bytesHashed);
84
+ const preparedPair = [sourceResult.path, destResult.path];
85
+ const sourceState = comparableSha1(sourceResult.path);
86
+ const destState = comparableSha1(destResult.path);
87
+ const bytesHashed = sourceResult.bytesHashed + destResult.bytesHashed;
88
+ if (sourceState.kind === "unavailable" || destState.kind === "unavailable") return skipped(preparedPair, unavailableSha1Event(preparedPair), void 0, bytesHashed);
89
+ const shouldVerifyB2Bytes = untrustedSha1CouldSuppressTransfer(sourceState, destState);
90
+ const readB2Sha1 = options.readB2Sha1;
91
+ if (shouldVerifyB2Bytes && hasB2Path(preparedPair) && readB2Sha1 !== void 0) return verifyB2Sha1Bytes(preparedPair, {
92
+ ...options,
93
+ readB2Sha1
94
+ }, bytesHashed);
95
+ return readyComparePair(preparedPair, bytesHashed);
96
+ }
97
+ /**
98
+ * Prepares a list of pairs for the selected compare mode with bounded concurrency.
99
+ *
100
+ * @param pairs - Source/destination pairs from {@link zipFolders}.
101
+ * @param compareMode - The comparison strategy.
102
+ * @param options - Optional hashing dependencies, cancellation signal, and concurrency.
103
+ *
104
+ * @returns Prepared results in the same order as the input pairs.
105
+ */
106
+ async function preparePairsForCompare(pairs, compareMode, options = {}) {
107
+ assertSupportedCompareMode(compareMode);
108
+ if (compareMode !== "sha1") return pairs.map((pair) => ({
109
+ originalPair: pair,
110
+ prepared: readyComparePair(pair)
111
+ }));
112
+ return require_concurrency.mapConcurrent(pairs, normalizeConcurrency(options.concurrency), async (pair) => {
113
+ if (options.signal?.aborted) return {
114
+ originalPair: pair,
115
+ prepared: aborted(pair)
116
+ };
117
+ return {
118
+ originalPair: pair,
119
+ prepared: await preparePairForCompare(pair, compareMode, options)
120
+ };
121
+ });
122
+ }
123
+ async function prepareLocalPathSha1(path, options) {
124
+ if (!isLocalSyncPath(path)) return {
125
+ path,
126
+ bytesHashed: 0,
127
+ bytesVerified: 0,
128
+ aborted: false
129
+ };
130
+ if (options.signal?.aborted) return {
131
+ path,
132
+ bytesHashed: 0,
133
+ bytesVerified: 0,
134
+ aborted: true
135
+ };
136
+ try {
137
+ const state = require_sha1_metadata.syncSha1StateOf(path);
138
+ if (state.kind === "verified") return {
139
+ path: {
140
+ ...path,
141
+ contentSha1: state.value
142
+ },
143
+ bytesHashed: 0,
144
+ bytesVerified: 0,
145
+ aborted: false
146
+ };
147
+ if (state.kind === "unavailable") return {
148
+ path: {
149
+ ...path,
150
+ contentSha1: null
151
+ },
152
+ bytesHashed: 0,
153
+ bytesVerified: 0,
154
+ aborted: false
155
+ };
156
+ const readLocalSha1 = options.readLocalSha1;
157
+ if (readLocalSha1 === void 0) return {
158
+ path: {
159
+ ...path,
160
+ contentSha1: path.contentSha1 ?? null
161
+ },
162
+ bytesHashed: 0,
163
+ bytesVerified: 0,
164
+ aborted: false
165
+ };
166
+ const contentSha1 = await readLocalSha1(path, options.signal, { ...options.sha1ReadTimeoutMillis !== void 0 ? { timeoutMillis: options.sha1ReadTimeoutMillis } : {} });
167
+ return {
168
+ path: {
169
+ ...path,
170
+ contentSha1
171
+ },
172
+ bytesHashed: require_sha1.normalizeVerifiableSha1(contentSha1) === null ? 0 : path.size,
173
+ bytesVerified: 0,
174
+ aborted: false
175
+ };
176
+ } catch (err) {
177
+ if (options.signal?.aborted || require_local_sha1.isAbortError(err)) return {
178
+ path,
179
+ bytesHashed: 0,
180
+ bytesVerified: 0,
181
+ aborted: true
182
+ };
183
+ const error = require_to_error.toError(err);
184
+ return {
185
+ path,
186
+ bytesHashed: 0,
187
+ event: {
188
+ type: "error",
189
+ path: path.relativePath,
190
+ size: 0,
191
+ message: `failed to hash local file for sha1 comparison: ${require_local_sha1.formatHashError(error)}`
192
+ },
193
+ error,
194
+ bytesVerified: 0,
195
+ aborted: false
196
+ };
197
+ }
198
+ }
199
+ async function verifyB2Sha1Bytes(pair, options, bytesHashed) {
200
+ const [source, dest] = pair;
201
+ /* v8 ignore next -- callers only verify B2 bytes for paired compare results */
202
+ if (source === null || dest === null) return readyComparePair(pair, bytesHashed);
203
+ const sourceResult = await prepareUntrustedB2PathSha1(source, options);
204
+ const sourceBytesVerified = sourceResult.bytesVerified;
205
+ if (sourceResult.aborted) return aborted(pair);
206
+ if (sourceResult.event) return skipped([sourceResult.path, dest], sourceResult.event, sourceResult.error, bytesHashed, sourceBytesVerified);
207
+ const destResult = await prepareUntrustedB2PathSha1(dest, options);
208
+ const bytesVerified = sourceBytesVerified + destResult.bytesVerified;
209
+ /* v8 ignore next -- destination abort mirrors the covered source abort path */
210
+ if (destResult.aborted) return aborted([sourceResult.path, destResult.path]);
211
+ if (destResult.event) return skipped([sourceResult.path, destResult.path], destResult.event, destResult.error, bytesHashed, bytesVerified);
212
+ return readyComparePair([sourceResult.path, destResult.path], bytesHashed, bytesVerified);
213
+ }
214
+ async function prepareUntrustedB2PathSha1(path, options) {
215
+ if (!isB2SyncPath(path) || comparableSha1(path).kind !== "untrusted") return {
216
+ path,
217
+ bytesHashed: 0,
218
+ bytesVerified: 0,
219
+ aborted: false
220
+ };
221
+ return prepareB2PathSha1(path, options);
222
+ }
223
+ async function prepareB2PathSha1(path, options) {
224
+ /* v8 ignore next -- pre-aborted B2 reads are covered at pair level */
225
+ if (options.signal?.aborted) return {
226
+ path,
227
+ bytesHashed: 0,
228
+ bytesVerified: 0,
229
+ aborted: true
230
+ };
231
+ try {
232
+ const result = await options.readB2Sha1(path, options.signal);
233
+ const contentSha1 = typeof result === "object" && result !== null ? result.contentSha1 : result;
234
+ const bytesVerified = typeof result === "object" && result !== null ? Math.max(0, result.bytesRead) : 0;
235
+ const preparedPath = {
236
+ ...path,
237
+ contentSha1,
238
+ contentSha1State: require_sha1_metadata.syncSha1StateOf({ contentSha1 })
239
+ };
240
+ if (contentSha1 === null) return {
241
+ path: preparedPath,
242
+ bytesHashed: 0,
243
+ bytesVerified,
244
+ event: unavailableSha1PathEvent(path),
245
+ aborted: false
246
+ };
247
+ return {
248
+ path: preparedPath,
249
+ bytesHashed: 0,
250
+ bytesVerified,
251
+ aborted: false
252
+ };
253
+ } catch (err) {
254
+ if (options.signal?.aborted || require_local_sha1.isAbortError(err)) return {
255
+ path,
256
+ bytesHashed: 0,
257
+ bytesVerified: 0,
258
+ aborted: true
259
+ };
260
+ const error = require_to_error.toError(err);
261
+ return {
262
+ path,
263
+ bytesHashed: 0,
264
+ bytesVerified: 0,
265
+ event: {
266
+ type: "skip",
267
+ path: path.relativePath,
268
+ size: 0,
269
+ message: `sha1 comparison skipped because B2 verification failed: ${require_local_sha1.formatHashError(error)}`
270
+ },
271
+ aborted: false
272
+ };
273
+ }
274
+ }
275
+ function comparableSha1(path) {
276
+ const state = require_sha1_metadata.syncSha1StateOf(path);
277
+ if (state.kind === "verified") return {
278
+ kind: "verified",
279
+ value: state.value
280
+ };
281
+ if (state.kind === "untrusted") return {
282
+ kind: "untrusted",
283
+ value: state.value
284
+ };
285
+ return { kind: "unavailable" };
286
+ }
287
+ function untrustedSha1CouldSuppressTransfer(source, dest) {
288
+ if (source.kind === "untrusted" && dest.kind === "verified") return source.value === dest.value;
289
+ if (dest.kind === "untrusted" && source.kind === "verified") return dest.value === source.value;
290
+ if (source.kind === "untrusted" && dest.kind === "untrusted") return source.value !== null && source.value === dest.value;
291
+ return false;
292
+ }
293
+ function withB2ContentSha1(path) {
294
+ if (!isB2SyncPath(path) || path.contentSha1 !== void 0 || path.contentSha1State !== void 0) return path;
295
+ const contentSha1 = require_sha1_metadata.selectB2ComparableSha1(path.selectedVersion);
296
+ return {
297
+ ...path,
298
+ contentSha1,
299
+ contentSha1State: require_sha1_metadata.syncSha1StateOf({ contentSha1 })
300
+ };
301
+ }
302
+ function hasUnavailableB2Sha1(pair) {
303
+ const [source, dest] = pair;
304
+ return source !== null && isB2SyncPath(source) && comparableSha1(source).kind === "unavailable" || dest !== null && isB2SyncPath(dest) && comparableSha1(dest).kind === "unavailable";
305
+ }
306
+ function hasUntrustedSha1(pair) {
307
+ const [source, dest] = pair;
308
+ return source !== null && comparableSha1(source).kind === "untrusted" || dest !== null && comparableSha1(dest).kind === "untrusted";
309
+ }
310
+ function hasVerifiableUntrustedSha1(pair) {
311
+ const [source, dest] = pair;
312
+ return source !== null && verifiableUntrustedSha1(source) || dest !== null && verifiableUntrustedSha1(dest);
313
+ }
314
+ function verifiableUntrustedSha1(path) {
315
+ const state = comparableSha1(path);
316
+ return state.kind === "untrusted" && state.value !== null;
317
+ }
318
+ function hasB2Path(pair) {
319
+ const [source, dest] = pair;
320
+ return source !== null && isB2SyncPath(source) || dest !== null && isB2SyncPath(dest);
321
+ }
322
+ function isB2SyncPath(path) {
323
+ return "selectedVersion" in path;
324
+ }
325
+ function isLocalSyncPath(path) {
326
+ return "absolutePath" in path;
327
+ }
328
+ /**
329
+ * Creates a successful no-op compare preparation result for a pair.
330
+ *
331
+ * @param pair - Source/destination pair from {@link zipFolders}.
332
+ * @param bytesHashed - Local file bytes read while preparing the pair.
333
+ * @param bytesVerified - B2 bytes read while verifying untrusted SHA-1 metadata.
334
+ *
335
+ * @returns A ready preparation result that allows action generation.
336
+ */
337
+ function readyComparePair(pair, bytesHashed = 0, bytesVerified = 0) {
338
+ return {
339
+ pair,
340
+ events: [],
341
+ errors: [],
342
+ bytesHashed,
343
+ bytesVerified,
344
+ skipActionGeneration: false,
345
+ aborted: false
346
+ };
347
+ }
348
+ function skipped(pair, event, error, bytesHashed = 0, bytesVerified = 0) {
349
+ return {
350
+ pair,
351
+ events: [event],
352
+ errors: error !== void 0 ? [error] : [],
353
+ bytesHashed,
354
+ bytesVerified,
355
+ skipActionGeneration: true,
356
+ aborted: false
357
+ };
358
+ }
359
+ function aborted(pair) {
360
+ return {
361
+ pair,
362
+ events: [],
363
+ errors: [],
364
+ bytesHashed: 0,
365
+ bytesVerified: 0,
366
+ skipActionGeneration: true,
367
+ aborted: true
368
+ };
369
+ }
370
+ function unavailableSha1Event(pair) {
371
+ return unavailableSha1PathEvent({ relativePath: (pair[0] ?? pair[1])?.relativePath ?? "" });
372
+ }
373
+ function unavailableSha1PathEvent(path) {
374
+ return {
375
+ type: "skip",
376
+ path: path.relativePath,
377
+ size: 0,
378
+ message: "sha1 comparison skipped because a verifiable SHA-1 is unavailable"
379
+ };
380
+ }
381
+ function normalizeConcurrency(value) {
382
+ if (value === void 0 || !Number.isFinite(value) || value < 1) return 1;
383
+ return Math.max(1, Math.floor(value));
384
+ }
385
+ //#endregion
386
+ exports.assertSupportedCompareMode = assertSupportedCompareMode;
13
387
  exports.filesAreDifferent = filesAreDifferent;
14
- //# sourceMappingURL=compare.cjs.map
388
+ exports.preparePairForCompare = preparePairForCompare;
389
+ exports.preparePairsForCompare = preparePairsForCompare;
390
+ exports.readyComparePair = readyComparePair;
391
+
392
+ //# sourceMappingURL=compare.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"compare.cjs","sources":["../../../src/sync/policies/compare.ts"],"sourcesContent":["import type { CompareMode, SyncPath } from '../types.ts'\n\n/**\n * Determines whether two files should be considered different based on the compare mode.\n *\n * @param source - The source file metadata.\n * @param dest - The destination file metadata.\n * @param compareMode - The comparison strategy: 'modtime', 'size', or 'none'.\n * @param threshold - Tolerance for the comparison (bytes for size, milliseconds for modtime).\n *\n * @returns `true` if the files are considered different.\n */\nexport function filesAreDifferent(\n source: SyncPath,\n dest: SyncPath,\n compareMode: CompareMode,\n threshold = 0,\n): boolean {\n switch (compareMode) {\n case 'none':\n return false\n case 'size':\n return Math.abs(source.size - dest.size) > threshold\n case 'modtime':\n return Math.abs(source.modTimeMillis - dest.modTimeMillis) > threshold\n }\n}\n"],"names":[],"mappings":";;AAYO,SAAS,kBACd,QACA,MACA,aACA,YAAY,GACH;AACT,UAAQ,aAAA;AAAA,IACN,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO,KAAK,IAAI,OAAO,OAAO,KAAK,IAAI,IAAI;AAAA,IAC7C,KAAK;AACH,aAAO,KAAK,IAAI,OAAO,gBAAgB,KAAK,aAAa,IAAI;AAAA,EAAA;AAEnE;;"}
1
+ {"version":3,"file":"compare.cjs","names":[],"sources":["../../../src/sync/policies/compare.ts"],"sourcesContent":["import { mapConcurrent } from '../../upload/concurrency.ts'\nimport { normalizeVerifiableSha1 } from '../../util/sha1.ts'\nimport { toError } from '../../util/to-error.ts'\nimport { formatHashError, isAbortError, type LocalSha1Reader } from '../local-sha1.ts'\nimport type { SyncPair } from '../pairing.ts'\nimport { selectB2ComparableSha1, syncSha1StateOf } from '../sha1-metadata.ts'\nimport type {\n B2SyncPath,\n CompareMode,\n LocalSyncPath,\n SyncEvent,\n SyncPath,\n SyncSkipEvent,\n} from '../types.ts'\n\nexport { selectB2ComparableSha1 } from '../sha1-metadata.ts'\n\n/** Result from a B2 SHA-1 verification read. */\nexport interface B2Sha1ReadResult {\n /** SHA-1 digest of the selected B2 bytes, or null when unavailable. */\n readonly contentSha1: string | null\n /** Number of B2 bytes downloaded and hashed while verifying. */\n readonly bytesRead: number\n}\n\n/** Reads a B2 file and returns the SHA-1 digest of its actual bytes, or null when unavailable. */\nexport type B2Sha1Reader = (\n path: B2SyncPath,\n signal?: AbortSignal,\n) => Promise<string | null | B2Sha1ReadResult>\n\n/** Options for preparing a file pair before comparison. */\nexport interface PreparePairForCompareOptions {\n /** Signal used to abort local file hashing. */\n readonly signal?: AbortSignal\n /** Optional idle/no-progress timeout for local SHA-1 reads. */\n readonly sha1ReadTimeoutMillis?: number\n /** Optional local hashing override for tests or custom runtimes. */\n readonly readLocalSha1?: LocalSha1Reader\n /** Optional B2 hashing override used to verify metadata matches before skipping. */\n readonly readB2Sha1?: B2Sha1Reader\n}\n\n/** Options for preparing multiple file pairs before comparison. */\nexport interface PreparePairsForCompareOptions extends PreparePairForCompareOptions {\n /** Maximum number of file pairs to prepare concurrently. */\n readonly concurrency?: number\n}\n\n/** Result of preparing a file pair before policy comparison. */\nexport interface ComparePreparationResult {\n /** The pair with compare-mode metadata populated where possible. */\n readonly pair: SyncPair\n /** Events surfaced while preparing the pair, such as per-file hash errors or skips. */\n readonly events: readonly SyncEvent[]\n /** Errors surfaced while preparing the pair. These contribute to the final summary. */\n readonly errors: readonly Error[]\n /** Local file bytes read for hashing while preparing this pair. */\n readonly bytesHashed: number\n /** B2 bytes read for untrusted metadata verification while preparing this pair. */\n readonly bytesVerified: number\n /** Whether action generation should be skipped for this pair. */\n readonly skipActionGeneration: boolean\n /** Whether preparation stopped because the abort signal fired. */\n readonly aborted: boolean\n}\n\n/** A prepared pair result with the original pair retained for event context. */\nexport interface PreparedComparePair {\n /** Original pair from {@link zipFolders}. */\n readonly originalPair: SyncPair\n /** Preparation result for the original pair. */\n readonly prepared: ComparePreparationResult\n}\n\n/**\n * Determines whether two files should be considered different based on the compare mode.\n * For `sha1`, callers that use the low-level policy helpers should first prepare the pair so\n * local hashes and comparable B2 hashes are populated.\n *\n * @param source - The source file metadata.\n * @param dest - The destination file metadata.\n * @param compareMode - The comparison strategy: 'modtime', 'size', 'sha1', or 'none'.\n * @param threshold - Tolerance for the comparison (bytes for size, milliseconds for modtime).\n *\n * @returns `true` if the files are considered different.\n *\n * @throws When `compareMode` is not one of the supported compare modes.\n */\nexport function filesAreDifferent(\n source: SyncPath,\n dest: SyncPath,\n compareMode: CompareMode,\n threshold = 0,\n): boolean {\n switch (compareMode) {\n case 'none':\n return false\n case 'size':\n return Math.abs(source.size - dest.size) > threshold\n case 'sha1':\n return sha1ValuesAreDifferent(source, dest)\n case 'modtime':\n return Math.abs(source.modTimeMillis - dest.modTimeMillis) > threshold\n default:\n throw new Error(`Unsupported compare mode: ${String(compareMode)}`)\n }\n}\n\n/**\n * Throws when a runtime compare mode value is unsupported.\n *\n * @param compareMode - User-supplied compare mode.\n *\n * @throws When `compareMode` is not one of the supported values.\n */\nexport function assertSupportedCompareMode(\n compareMode: unknown,\n): asserts compareMode is CompareMode {\n switch (compareMode) {\n case 'none':\n case 'size':\n case 'sha1':\n case 'modtime':\n return\n default:\n throw new Error(`Unsupported compare mode: ${String(compareMode)}`)\n }\n}\n\nfunction sha1ValuesAreDifferent(source: SyncPath, dest: SyncPath): boolean {\n if (source.size !== dest.size) return true\n\n const sourceSha1 = comparableSha1(source)\n const destSha1 = comparableSha1(dest)\n if (sourceSha1.kind === 'untrusted' || destSha1.kind === 'untrusted') return true\n if (sourceSha1.kind === 'unavailable' || destSha1.kind === 'unavailable') return true\n return sourceSha1.value !== destSha1.value\n}\n\n/**\n * Prepares a pair for the selected compare mode.\n *\n * For `sha1`, this fills missing B2 hashes from comparable metadata and, when an explicit local\n * reader is supplied, hashes the local side only when size cannot already prove a difference.\n * Reader failures are converted into per-file sync events instead of aborting the whole run.\n *\n * @param pair - Source/destination pair from {@link zipFolders}.\n * @param compareMode - The comparison strategy.\n * @param options - Optional hashing dependencies and cancellation signal.\n *\n * @returns The prepared pair plus any preparation events.\n */\nexport async function preparePairForCompare(\n pair: SyncPair,\n compareMode: CompareMode,\n options: PreparePairForCompareOptions = {},\n): Promise<ComparePreparationResult> {\n assertSupportedCompareMode(compareMode)\n if (compareMode !== 'sha1') return readyComparePair(pair)\n\n const [source, dest] = pair\n if (source === null || dest === null) return readyComparePair(pair)\n if (source.size !== dest.size) return readyComparePair(pair)\n\n const metadataPair: SyncPair = [withB2ContentSha1(source), withB2ContentSha1(dest)]\n if (hasUnavailableB2Sha1(metadataPair)) {\n return skipped(metadataPair, unavailableSha1Event(metadataPair))\n }\n if (\n options.readB2Sha1 === undefined &&\n hasUntrustedSha1(metadataPair) &&\n !hasVerifiableUntrustedSha1(metadataPair)\n ) {\n return readyComparePair(metadataPair)\n }\n\n const [metadataSource, metadataDest] = metadataPair\n if (metadataSource === null || metadataDest === null) return readyComparePair(metadataPair)\n\n const sourceResult = await prepareLocalPathSha1(metadataSource, options)\n if (sourceResult.aborted) return aborted(metadataPair)\n if (sourceResult.event) {\n return skipped(metadataPair, sourceResult.event, sourceResult.error, sourceResult.bytesHashed)\n }\n\n const destResult = await prepareLocalPathSha1(metadataDest, options)\n if (destResult.aborted) return aborted([sourceResult.path, destResult.path])\n if (destResult.event) {\n return skipped(\n [sourceResult.path, destResult.path],\n destResult.event,\n destResult.error,\n sourceResult.bytesHashed,\n )\n }\n\n const preparedPair: SyncPair = [sourceResult.path, destResult.path]\n const sourceState = comparableSha1(sourceResult.path)\n const destState = comparableSha1(destResult.path)\n const bytesHashed = sourceResult.bytesHashed + destResult.bytesHashed\n\n if (sourceState.kind === 'unavailable' || destState.kind === 'unavailable') {\n return skipped(preparedPair, unavailableSha1Event(preparedPair), undefined, bytesHashed)\n }\n\n const shouldVerifyB2Bytes = untrustedSha1CouldSuppressTransfer(sourceState, destState)\n const readB2Sha1 = options.readB2Sha1\n if (shouldVerifyB2Bytes && hasB2Path(preparedPair) && readB2Sha1 !== undefined) {\n return verifyB2Sha1Bytes(preparedPair, { ...options, readB2Sha1 }, bytesHashed)\n }\n\n return readyComparePair(preparedPair, bytesHashed)\n}\n\n/**\n * Prepares a list of pairs for the selected compare mode with bounded concurrency.\n *\n * @param pairs - Source/destination pairs from {@link zipFolders}.\n * @param compareMode - The comparison strategy.\n * @param options - Optional hashing dependencies, cancellation signal, and concurrency.\n *\n * @returns Prepared results in the same order as the input pairs.\n */\nexport async function preparePairsForCompare(\n pairs: readonly SyncPair[],\n compareMode: CompareMode,\n options: PreparePairsForCompareOptions = {},\n): Promise<PreparedComparePair[]> {\n assertSupportedCompareMode(compareMode)\n if (compareMode !== 'sha1') {\n return pairs.map((pair) => ({ originalPair: pair, prepared: readyComparePair(pair) }))\n }\n\n const concurrency = normalizeConcurrency(options.concurrency)\n return mapConcurrent(pairs, concurrency, async (pair): Promise<PreparedComparePair> => {\n if (options.signal?.aborted) return { originalPair: pair, prepared: aborted(pair) }\n return {\n originalPair: pair,\n prepared: await preparePairForCompare(pair, compareMode, options),\n }\n })\n}\n\ntype Sha1State =\n | { readonly kind: 'verified'; readonly value: string }\n | { readonly kind: 'untrusted'; readonly value: string | null }\n | { readonly kind: 'unavailable' }\n\ninterface PreparedPath {\n readonly path: SyncPath\n readonly bytesHashed: number\n readonly bytesVerified: number\n readonly event?: SyncEvent\n readonly error?: Error\n readonly aborted: boolean\n}\n\nasync function prepareLocalPathSha1(\n path: SyncPath,\n options: PreparePairForCompareOptions,\n): Promise<PreparedPath> {\n if (!isLocalSyncPath(path)) {\n return { path, bytesHashed: 0, bytesVerified: 0, aborted: false }\n }\n\n if (options.signal?.aborted) return { path, bytesHashed: 0, bytesVerified: 0, aborted: true }\n\n try {\n const state = syncSha1StateOf(path)\n if (state.kind === 'verified') {\n return {\n path: { ...path, contentSha1: state.value },\n bytesHashed: 0,\n bytesVerified: 0,\n aborted: false,\n }\n }\n if (state.kind === 'unavailable') {\n return {\n path: { ...path, contentSha1: null },\n bytesHashed: 0,\n bytesVerified: 0,\n aborted: false,\n }\n }\n\n const readLocalSha1 = options.readLocalSha1\n if (readLocalSha1 === undefined) {\n return {\n path: { ...path, contentSha1: path.contentSha1 ?? null },\n bytesHashed: 0,\n bytesVerified: 0,\n aborted: false,\n }\n }\n const contentSha1 = await readLocalSha1(path, options.signal, {\n ...(options.sha1ReadTimeoutMillis !== undefined\n ? { timeoutMillis: options.sha1ReadTimeoutMillis }\n : {}),\n })\n return {\n path: {\n ...path,\n contentSha1,\n },\n bytesHashed: normalizeVerifiableSha1(contentSha1) === null ? 0 : path.size,\n bytesVerified: 0,\n aborted: false,\n }\n } catch (err) {\n if (options.signal?.aborted || isAbortError(err)) {\n return { path, bytesHashed: 0, bytesVerified: 0, aborted: true }\n }\n const error = toError(err)\n return {\n path,\n bytesHashed: 0,\n event: {\n type: 'error',\n path: path.relativePath,\n size: 0,\n message: `failed to hash local file for sha1 comparison: ${formatHashError(error)}`,\n },\n error,\n bytesVerified: 0,\n aborted: false,\n }\n }\n}\n\nasync function verifyB2Sha1Bytes(\n pair: SyncPair,\n options: PreparePairForCompareOptions & { readonly readB2Sha1: B2Sha1Reader },\n bytesHashed: number,\n): Promise<ComparePreparationResult> {\n const [source, dest] = pair\n /* v8 ignore next -- callers only verify B2 bytes for paired compare results */\n if (source === null || dest === null) return readyComparePair(pair, bytesHashed)\n\n const sourceResult = await prepareUntrustedB2PathSha1(source, options)\n const sourceBytesVerified = sourceResult.bytesVerified\n if (sourceResult.aborted) return aborted(pair)\n if (sourceResult.event) {\n return skipped(\n [sourceResult.path, dest],\n sourceResult.event,\n sourceResult.error,\n bytesHashed,\n sourceBytesVerified,\n )\n }\n\n const destResult = await prepareUntrustedB2PathSha1(dest, options)\n const bytesVerified = sourceBytesVerified + destResult.bytesVerified\n /* v8 ignore next -- destination abort mirrors the covered source abort path */\n if (destResult.aborted) return aborted([sourceResult.path, destResult.path])\n if (destResult.event) {\n return skipped(\n [sourceResult.path, destResult.path],\n destResult.event,\n destResult.error,\n bytesHashed,\n bytesVerified,\n )\n }\n\n return readyComparePair([sourceResult.path, destResult.path], bytesHashed, bytesVerified)\n}\n\nasync function prepareUntrustedB2PathSha1(\n path: SyncPath,\n options: PreparePairForCompareOptions & { readonly readB2Sha1: B2Sha1Reader },\n): Promise<PreparedPath> {\n if (!isB2SyncPath(path) || comparableSha1(path).kind !== 'untrusted') {\n return { path, bytesHashed: 0, bytesVerified: 0, aborted: false }\n }\n return prepareB2PathSha1(path, options)\n}\n\nasync function prepareB2PathSha1(\n path: B2SyncPath,\n options: PreparePairForCompareOptions & { readonly readB2Sha1: B2Sha1Reader },\n): Promise<PreparedPath> {\n /* v8 ignore next -- pre-aborted B2 reads are covered at pair level */\n if (options.signal?.aborted) return { path, bytesHashed: 0, bytesVerified: 0, aborted: true }\n\n try {\n const result = await options.readB2Sha1(path, options.signal)\n const contentSha1 = typeof result === 'object' && result !== null ? result.contentSha1 : result\n const bytesVerified =\n typeof result === 'object' && result !== null ? Math.max(0, result.bytesRead) : 0\n const preparedPath = {\n ...path,\n contentSha1,\n contentSha1State: syncSha1StateOf({ contentSha1 }),\n }\n if (contentSha1 === null) {\n return {\n path: preparedPath,\n bytesHashed: 0,\n bytesVerified,\n event: unavailableSha1PathEvent(path),\n aborted: false,\n }\n }\n return {\n path: preparedPath,\n bytesHashed: 0,\n bytesVerified,\n aborted: false,\n }\n } catch (err) {\n if (options.signal?.aborted || isAbortError(err)) {\n return { path, bytesHashed: 0, bytesVerified: 0, aborted: true }\n }\n const error = toError(err)\n return {\n path,\n bytesHashed: 0,\n bytesVerified: 0,\n event: {\n type: 'skip',\n path: path.relativePath,\n size: 0,\n message: `sha1 comparison skipped because B2 verification failed: ${formatHashError(error)}`,\n },\n aborted: false,\n }\n }\n}\n\nfunction comparableSha1(path: SyncPath): Sha1State {\n const state = syncSha1StateOf(path)\n if (state.kind === 'verified') return { kind: 'verified', value: state.value }\n if (state.kind === 'untrusted') return { kind: 'untrusted', value: state.value }\n return { kind: 'unavailable' }\n}\n\nfunction untrustedSha1CouldSuppressTransfer(source: Sha1State, dest: Sha1State): boolean {\n if (source.kind === 'untrusted' && dest.kind === 'verified') return source.value === dest.value\n if (dest.kind === 'untrusted' && source.kind === 'verified') return dest.value === source.value\n if (source.kind === 'untrusted' && dest.kind === 'untrusted') {\n return source.value !== null && source.value === dest.value\n }\n return false\n}\n\nfunction withB2ContentSha1(path: SyncPath): SyncPath {\n if (\n !isB2SyncPath(path) ||\n path.contentSha1 !== undefined ||\n path.contentSha1State !== undefined\n ) {\n return path\n }\n const contentSha1 = selectB2ComparableSha1(path.selectedVersion)\n return { ...path, contentSha1, contentSha1State: syncSha1StateOf({ contentSha1 }) }\n}\n\nfunction hasUnavailableB2Sha1(pair: SyncPair): boolean {\n const [source, dest] = pair\n return (\n (source !== null && isB2SyncPath(source) && comparableSha1(source).kind === 'unavailable') ||\n (dest !== null && isB2SyncPath(dest) && comparableSha1(dest).kind === 'unavailable')\n )\n}\n\nfunction hasUntrustedSha1(pair: SyncPair): boolean {\n const [source, dest] = pair\n return (\n (source !== null && comparableSha1(source).kind === 'untrusted') ||\n (dest !== null && comparableSha1(dest).kind === 'untrusted')\n )\n}\n\nfunction hasVerifiableUntrustedSha1(pair: SyncPair): boolean {\n const [source, dest] = pair\n return (\n (source !== null && verifiableUntrustedSha1(source)) ||\n (dest !== null && verifiableUntrustedSha1(dest))\n )\n}\n\nfunction verifiableUntrustedSha1(path: SyncPath): boolean {\n const state = comparableSha1(path)\n return state.kind === 'untrusted' && state.value !== null\n}\n\nfunction hasB2Path(pair: SyncPair): boolean {\n const [source, dest] = pair\n return (source !== null && isB2SyncPath(source)) || (dest !== null && isB2SyncPath(dest))\n}\n\nfunction isB2SyncPath(path: SyncPath): path is B2SyncPath {\n return 'selectedVersion' in path\n}\n\nfunction isLocalSyncPath(path: SyncPath): path is LocalSyncPath {\n return 'absolutePath' in path\n}\n\n/**\n * Creates a successful no-op compare preparation result for a pair.\n *\n * @param pair - Source/destination pair from {@link zipFolders}.\n * @param bytesHashed - Local file bytes read while preparing the pair.\n * @param bytesVerified - B2 bytes read while verifying untrusted SHA-1 metadata.\n *\n * @returns A ready preparation result that allows action generation.\n */\nexport function readyComparePair(\n pair: SyncPair,\n bytesHashed = 0,\n bytesVerified = 0,\n): ComparePreparationResult {\n return {\n pair,\n events: [],\n errors: [],\n bytesHashed,\n bytesVerified,\n skipActionGeneration: false,\n aborted: false,\n }\n}\n\nfunction skipped(\n pair: SyncPair,\n event: SyncEvent,\n error?: Error,\n bytesHashed = 0,\n bytesVerified = 0,\n): ComparePreparationResult {\n return {\n pair,\n events: [event],\n errors: error !== undefined ? [error] : [],\n bytesHashed,\n bytesVerified,\n skipActionGeneration: true,\n aborted: false,\n }\n}\n\nfunction aborted(pair: SyncPair): ComparePreparationResult {\n return {\n pair,\n events: [],\n errors: [],\n bytesHashed: 0,\n bytesVerified: 0,\n skipActionGeneration: true,\n aborted: true,\n }\n}\n\nfunction unavailableSha1Event(pair: SyncPair): SyncSkipEvent {\n /* v8 ignore next -- unavailable SHA-1 events always have at least one side */\n const path = (pair[0] ?? pair[1])?.relativePath ?? ''\n return unavailableSha1PathEvent({ relativePath: path })\n}\n\nfunction unavailableSha1PathEvent(path: Pick<SyncPath, 'relativePath'>): SyncSkipEvent {\n return {\n type: 'skip',\n path: path.relativePath,\n size: 0,\n message: 'sha1 comparison skipped because a verifiable SHA-1 is unavailable',\n }\n}\n\nfunction normalizeConcurrency(value: number | undefined): number {\n if (value === undefined || !Number.isFinite(value) || value < 1) return 1\n return Math.max(1, Math.floor(value))\n}\n"],"mappings":"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"}