@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,119 @@
1
+ const require_hash = require("../streams/hash.cjs");
2
+ const require_to_error = require("../util/to-error.cjs");
3
+ const require_error_reason = require("../util/error-reason.cjs");
4
+ const require_local_file_identity = require("./local-file-identity.cjs");
5
+ const require_sha1_options = require("./sha1-options.cjs");
6
+ //#region src/sync/local-sha1.ts
7
+ /**
8
+ * Formats a hash error for public sync events without leaking filesystem paths.
9
+ *
10
+ * @param error - Error thrown while hashing.
11
+ *
12
+ * @returns A sanitized reason suitable for event messages.
13
+ */
14
+ function formatHashError(error) {
15
+ return require_error_reason.sanitizeErrorReason(error);
16
+ }
17
+ /**
18
+ * Returns whether an error represents an abort.
19
+ *
20
+ * @param err - Unknown thrown value.
21
+ *
22
+ * @returns True for AbortError values.
23
+ */
24
+ function isAbortError(err) {
25
+ return require_to_error.toError(err).name === "AbortError";
26
+ }
27
+ /**
28
+ * Reads a local file and computes its SHA-1 digest with non-regular-file rejection,
29
+ * scanned-size bounds, abort support, and an idle/no-progress timeout.
30
+ *
31
+ * @param path - Local sync path to hash.
32
+ * @param signal - Optional abort signal.
33
+ * @param options - Optional idle timeout override.
34
+ *
35
+ * @returns The lowercase SHA-1 digest of the file bytes.
36
+ */
37
+ async function readLocalSha1File(path, signal, options = {}) {
38
+ const { constants } = await import("node:fs");
39
+ const { lstat, open } = await import("node:fs/promises");
40
+ const timeoutMillis = require_sha1_options.normalizeSha1TimeoutMillis(options.timeoutMillis);
41
+ const flags = constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0) | (constants.O_NONBLOCK ?? 0);
42
+ const hash = new require_hash.IncrementalSha1();
43
+ let stream;
44
+ let file;
45
+ let timeout;
46
+ function armTimeout(onTimeout) {
47
+ if (timeout !== void 0) clearTimeout(timeout);
48
+ timeout = setTimeout(onTimeout, timeoutMillis);
49
+ }
50
+ try {
51
+ signal?.throwIfAborted();
52
+ require_local_file_identity.assertSameScannedRegularFile(await withTimeout(lstat(path.absolutePath), timeoutMillis, "sha1 file status"), path, "sha1 comparison");
53
+ file = await openWithTimeout(open(path.absolutePath, flags), timeoutMillis);
54
+ require_local_file_identity.assertSameScannedRegularFile(await withTimeout(lstat(path.absolutePath), timeoutMillis, "sha1 file status"), path, "sha1 comparison");
55
+ require_local_file_identity.assertSameScannedRegularFile(await withTimeout(file.stat(), timeoutMillis, "sha1 file status"), path, "sha1 comparison");
56
+ stream = file.createReadStream({
57
+ ...path.size > 0 ? {
58
+ start: 0,
59
+ end: path.size - 1
60
+ } : {},
61
+ ...signal !== void 0 ? { signal } : {}
62
+ });
63
+ let bytesRead = 0;
64
+ /* v8 ignore next 3 -- idle-timeout firing is timing-dependent in filesystem tests */
65
+ armTimeout(() => {
66
+ stream?.destroy(/* @__PURE__ */ new Error(`sha1 read stalled for ${timeoutMillis} ms`));
67
+ });
68
+ for await (const chunk of stream) {
69
+ bytesRead += chunk.byteLength;
70
+ await hash.update(chunk);
71
+ /* v8 ignore next 3 -- idle-timeout firing is timing-dependent in filesystem tests */
72
+ armTimeout(() => {
73
+ stream?.destroy(/* @__PURE__ */ new Error(`sha1 read stalled for ${timeoutMillis} ms`));
74
+ });
75
+ }
76
+ /* v8 ignore next -- defensive TOCTOU guard after the bounded stream completes */
77
+ if (bytesRead !== path.size) throw new Error("file changed during sha1 comparison");
78
+ return hash.digest();
79
+ } finally {
80
+ if (timeout !== void 0) clearTimeout(timeout);
81
+ stream?.destroy();
82
+ await file?.close().catch(() => {});
83
+ }
84
+ }
85
+ /* v8 ignore start -- defensive stale-filesystem stall handling is not portable to trigger */
86
+ async function withTimeout(promise, timeoutMillis, operation) {
87
+ let timeout;
88
+ try {
89
+ return await Promise.race([promise, new Promise((_, reject) => {
90
+ timeout = setTimeout(() => {
91
+ reject(/* @__PURE__ */ new Error(`${operation} stalled for ${timeoutMillis} ms`));
92
+ }, timeoutMillis);
93
+ })]);
94
+ } finally {
95
+ if (timeout !== void 0) clearTimeout(timeout);
96
+ }
97
+ }
98
+ async function openWithTimeout(promise, timeoutMillis) {
99
+ let timedOut = false;
100
+ const tracked = promise.then((file) => {
101
+ if (timedOut) file.close().catch(() => {});
102
+ return file;
103
+ }, (err) => {
104
+ throw err;
105
+ });
106
+ try {
107
+ return await withTimeout(tracked, timeoutMillis, "sha1 file open");
108
+ } catch (err) {
109
+ timedOut = true;
110
+ throw err;
111
+ }
112
+ }
113
+ /* v8 ignore stop */
114
+ //#endregion
115
+ exports.formatHashError = formatHashError;
116
+ exports.isAbortError = isAbortError;
117
+ exports.readLocalSha1File = readLocalSha1File;
118
+
119
+ //# sourceMappingURL=local-sha1.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-sha1.cjs","names":[],"sources":["../../src/sync/local-sha1.ts"],"sourcesContent":["import { IncrementalSha1 } from '../streams/hash.ts'\nimport { sanitizeErrorReason } from '../util/error-reason.ts'\nimport { toError } from '../util/to-error.ts'\nimport { assertSameScannedRegularFile } from './local-file-identity.ts'\nimport { normalizeSha1TimeoutMillis } from './sha1-options.ts'\nimport type { LocalSyncPath } from './types.ts'\n\n/** Options for reading a local file SHA-1 digest. */\nexport interface LocalSha1ReadOptions {\n /**\n * Maximum milliseconds to allow without filesystem progress while hashing.\n * Defaults to 30 seconds.\n */\n readonly timeoutMillis?: number\n}\n\n/** Reads a local file and returns its SHA-1 digest, or null when unavailable. */\nexport type LocalSha1Reader = (\n path: LocalSyncPath,\n signal?: AbortSignal,\n options?: LocalSha1ReadOptions,\n) => Promise<string | null>\n\n/**\n * Formats a hash error for public sync events without leaking filesystem paths.\n *\n * @param error - Error thrown while hashing.\n *\n * @returns A sanitized reason suitable for event messages.\n */\nexport function formatHashError(error: Error): string {\n return sanitizeErrorReason(error)\n}\n\n/**\n * Returns whether an error represents an abort.\n *\n * @param err - Unknown thrown value.\n *\n * @returns True for AbortError values.\n */\nexport function isAbortError(err: unknown): boolean {\n const error = toError(err)\n return error.name === 'AbortError'\n}\n\n/**\n * Reads a local file and computes its SHA-1 digest with non-regular-file rejection,\n * scanned-size bounds, abort support, and an idle/no-progress timeout.\n *\n * @param path - Local sync path to hash.\n * @param signal - Optional abort signal.\n * @param options - Optional idle timeout override.\n *\n * @returns The lowercase SHA-1 digest of the file bytes.\n */\nexport async function readLocalSha1File(\n path: LocalSyncPath,\n signal?: AbortSignal,\n options: LocalSha1ReadOptions = {},\n): Promise<string> {\n const { constants } = await import('node:fs')\n const { lstat, open } = await import('node:fs/promises')\n const timeoutMillis = normalizeSha1TimeoutMillis(options.timeoutMillis)\n const flags = constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0) | (constants.O_NONBLOCK ?? 0)\n const hash = new IncrementalSha1()\n let stream: (AsyncIterable<Uint8Array> & { destroy(error?: Error): void }) | undefined\n let file: Awaited<ReturnType<typeof open>> | undefined\n let timeout: ReturnType<typeof setTimeout> | undefined\n\n function armTimeout(onTimeout: () => void): void {\n if (timeout !== undefined) clearTimeout(timeout)\n timeout = setTimeout(onTimeout, timeoutMillis)\n }\n\n try {\n signal?.throwIfAborted()\n\n const preOpenStat = await withTimeout(\n lstat(path.absolutePath),\n timeoutMillis,\n 'sha1 file status',\n )\n assertSameScannedRegularFile(preOpenStat, path, 'sha1 comparison')\n\n file = await openWithTimeout(open(path.absolutePath, flags), timeoutMillis)\n\n const postOpenStat = await withTimeout(\n lstat(path.absolutePath),\n timeoutMillis,\n 'sha1 file status',\n )\n assertSameScannedRegularFile(postOpenStat, path, 'sha1 comparison')\n\n const stat = await withTimeout(file.stat(), timeoutMillis, 'sha1 file status')\n assertSameScannedRegularFile(stat, path, 'sha1 comparison')\n\n stream = file.createReadStream({\n ...(path.size > 0 ? { start: 0, end: path.size - 1 } : {}),\n ...(signal !== undefined ? { signal } : {}),\n })\n\n let bytesRead = 0\n /* v8 ignore next 3 -- idle-timeout firing is timing-dependent in filesystem tests */\n armTimeout(() => {\n stream?.destroy(new Error(`sha1 read stalled for ${timeoutMillis} ms`))\n })\n for await (const chunk of stream) {\n bytesRead += chunk.byteLength\n await hash.update(chunk)\n /* v8 ignore next 3 -- idle-timeout firing is timing-dependent in filesystem tests */\n armTimeout(() => {\n stream?.destroy(new Error(`sha1 read stalled for ${timeoutMillis} ms`))\n })\n }\n\n /* v8 ignore next -- defensive TOCTOU guard after the bounded stream completes */\n if (bytesRead !== path.size) throw new Error('file changed during sha1 comparison')\n return hash.digest()\n } finally {\n if (timeout !== undefined) clearTimeout(timeout)\n stream?.destroy()\n await file?.close().catch(() => {})\n }\n}\n\n/* v8 ignore start -- defensive stale-filesystem stall handling is not portable to trigger */\nasync function withTimeout<T>(\n promise: Promise<T>,\n timeoutMillis: number,\n operation: string,\n): Promise<T> {\n let timeout: ReturnType<typeof setTimeout> | undefined\n try {\n return await Promise.race([\n promise,\n new Promise<never>((_, reject) => {\n timeout = setTimeout(() => {\n reject(new Error(`${operation} stalled for ${timeoutMillis} ms`))\n }, timeoutMillis)\n }),\n ])\n } finally {\n if (timeout !== undefined) clearTimeout(timeout)\n }\n}\n\nasync function openWithTimeout<T extends { close(): Promise<void> }>(\n promise: Promise<T>,\n timeoutMillis: number,\n): Promise<T> {\n let timedOut = false\n const tracked = promise.then(\n (file) => {\n if (timedOut) void file.close().catch(() => {})\n return file\n },\n (err: unknown) => {\n throw err\n },\n )\n\n try {\n return await withTimeout(tracked, timeoutMillis, 'sha1 file open')\n } catch (err) {\n timedOut = true\n throw err\n }\n}\n/* v8 ignore stop */\n"],"mappings":";;;;;;;;;;;;;AA8BA,SAAgB,gBAAgB,OAAsB;CACpD,OAAO,qBAAA,oBAAoB,KAAK;AAClC;;;;;;;;AASA,SAAgB,aAAa,KAAuB;CAElD,OADc,iBAAA,QAAQ,GACf,CAAA,CAAM,SAAS;AACxB;;;;;;;;;;;AAYA,eAAsB,kBACpB,MACA,QACA,UAAgC,CAAC,GAChB;CACjB,MAAM,EAAE,cAAc,MAAM,OAAO;CACnC,MAAM,EAAE,OAAO,SAAS,MAAM,OAAO;CACrC,MAAM,gBAAgB,qBAAA,2BAA2B,QAAQ,aAAa;CACtE,MAAM,QAAQ,UAAU,YAAY,UAAU,cAAc,MAAM,UAAU,cAAc;CAC1F,MAAM,OAAO,IAAI,aAAA,gBAAgB;CACjC,IAAI;CACJ,IAAI;CACJ,IAAI;CAEJ,SAAS,WAAW,WAA6B;EAC/C,IAAI,YAAY,KAAA,GAAW,aAAa,OAAO;EAC/C,UAAU,WAAW,WAAW,aAAa;CAC/C;CAEA,IAAI;EACF,QAAQ,eAAe;EAOvB,4BAAA,6BAA6B,MALH,YACxB,MAAM,KAAK,YAAY,GACvB,eACA,kBACF,GAC0C,MAAM,iBAAiB;EAEjE,OAAO,MAAM,gBAAgB,KAAK,KAAK,cAAc,KAAK,GAAG,aAAa;EAO1E,4BAAA,6BAA6B,MALF,YACzB,MAAM,KAAK,YAAY,GACvB,eACA,kBACF,GAC2C,MAAM,iBAAiB;EAGlE,4BAAA,6BAA6B,MADV,YAAY,KAAK,KAAK,GAAG,eAAe,kBAAkB,GAC1C,MAAM,iBAAiB;EAE1D,SAAS,KAAK,iBAAiB;GAC7B,GAAI,KAAK,OAAO,IAAI;IAAE,OAAO;IAAG,KAAK,KAAK,OAAO;GAAE,IAAI,CAAC;GACxD,GAAI,WAAW,KAAA,IAAY,EAAE,OAAO,IAAI,CAAC;EAC3C,CAAC;EAED,IAAI,YAAY;;EAEhB,iBAAiB;GACf,QAAQ,wBAAQ,IAAI,MAAM,yBAAyB,cAAc,IAAI,CAAC;EACxE,CAAC;EACD,WAAW,MAAM,SAAS,QAAQ;GAChC,aAAa,MAAM;GACnB,MAAM,KAAK,OAAO,KAAK;;GAEvB,iBAAiB;IACf,QAAQ,wBAAQ,IAAI,MAAM,yBAAyB,cAAc,IAAI,CAAC;GACxE,CAAC;EACH;;EAGA,IAAI,cAAc,KAAK,MAAM,MAAM,IAAI,MAAM,qCAAqC;EAClF,OAAO,KAAK,OAAO;CACrB,UAAU;EACR,IAAI,YAAY,KAAA,GAAW,aAAa,OAAO;EAC/C,QAAQ,QAAQ;EAChB,MAAM,MAAM,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;CACpC;AACF;;AAGA,eAAe,YACb,SACA,eACA,WACY;CACZ,IAAI;CACJ,IAAI;EACF,OAAO,MAAM,QAAQ,KAAK,CACxB,SACA,IAAI,SAAgB,GAAG,WAAW;GAChC,UAAU,iBAAiB;IACzB,uBAAO,IAAI,MAAM,GAAG,UAAU,eAAe,cAAc,IAAI,CAAC;GAClE,GAAG,aAAa;EAClB,CAAC,CACH,CAAC;CACH,UAAU;EACR,IAAI,YAAY,KAAA,GAAW,aAAa,OAAO;CACjD;AACF;AAEA,eAAe,gBACb,SACA,eACY;CACZ,IAAI,WAAW;CACf,MAAM,UAAU,QAAQ,MACrB,SAAS;EACR,IAAI,UAAU,KAAU,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;EAC9C,OAAO;CACT,IACC,QAAiB;EAChB,MAAM;CACR,CACF;CAEA,IAAI;EACF,OAAO,MAAM,YAAY,SAAS,eAAe,gBAAgB;CACnE,SAAS,KAAK;EACZ,WAAW;EACX,MAAM;CACR;AACF"}
@@ -0,0 +1,39 @@
1
+ import { LocalSyncPath } from './types.js';
2
+ /** Options for reading a local file SHA-1 digest. */
3
+ export interface LocalSha1ReadOptions {
4
+ /**
5
+ * Maximum milliseconds to allow without filesystem progress while hashing.
6
+ * Defaults to 30 seconds.
7
+ */
8
+ readonly timeoutMillis?: number;
9
+ }
10
+ /** Reads a local file and returns its SHA-1 digest, or null when unavailable. */
11
+ export type LocalSha1Reader = (path: LocalSyncPath, signal?: AbortSignal, options?: LocalSha1ReadOptions) => Promise<string | null>;
12
+ /**
13
+ * Formats a hash error for public sync events without leaking filesystem paths.
14
+ *
15
+ * @param error - Error thrown while hashing.
16
+ *
17
+ * @returns A sanitized reason suitable for event messages.
18
+ */
19
+ export declare function formatHashError(error: Error): string;
20
+ /**
21
+ * Returns whether an error represents an abort.
22
+ *
23
+ * @param err - Unknown thrown value.
24
+ *
25
+ * @returns True for AbortError values.
26
+ */
27
+ export declare function isAbortError(err: unknown): boolean;
28
+ /**
29
+ * Reads a local file and computes its SHA-1 digest with non-regular-file rejection,
30
+ * scanned-size bounds, abort support, and an idle/no-progress timeout.
31
+ *
32
+ * @param path - Local sync path to hash.
33
+ * @param signal - Optional abort signal.
34
+ * @param options - Optional idle timeout override.
35
+ *
36
+ * @returns The lowercase SHA-1 digest of the file bytes.
37
+ */
38
+ export declare function readLocalSha1File(path: LocalSyncPath, signal?: AbortSignal, options?: LocalSha1ReadOptions): Promise<string>;
39
+ //# sourceMappingURL=local-sha1.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-sha1.d.ts","sourceRoot":"","sources":["../../src/sync/local-sha1.js"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE/C,qDAAqD;AACrD,MAAM,WAAW,oBAAoB;IACnC;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAChC;AAED,iFAAiF;AACjF,MAAM,MAAM,eAAe,GAAG,CAC5B,IAAI,EAAE,aAAa,EACnB,MAAM,CAAC,EAAE,WAAW,EACpB,OAAO,CAAC,EAAE,oBAAoB,KAC3B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;AAE3B;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAEpD;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAGlD;AAED;;;;;;;;;GASG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,aAAa,EACnB,MAAM,CAAC,EAAE,WAAW,EACpB,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,MAAM,CAAC,CAgEjB"}
@@ -0,0 +1,39 @@
1
+ import { LocalSyncPath } from './types.js';
2
+ /** Options for reading a local file SHA-1 digest. */
3
+ export interface LocalSha1ReadOptions {
4
+ /**
5
+ * Maximum milliseconds to allow without filesystem progress while hashing.
6
+ * Defaults to 30 seconds.
7
+ */
8
+ readonly timeoutMillis?: number;
9
+ }
10
+ /** Reads a local file and returns its SHA-1 digest, or null when unavailable. */
11
+ export type LocalSha1Reader = (path: LocalSyncPath, signal?: AbortSignal, options?: LocalSha1ReadOptions) => Promise<string | null>;
12
+ /**
13
+ * Formats a hash error for public sync events without leaking filesystem paths.
14
+ *
15
+ * @param error - Error thrown while hashing.
16
+ *
17
+ * @returns A sanitized reason suitable for event messages.
18
+ */
19
+ export declare function formatHashError(error: Error): string;
20
+ /**
21
+ * Returns whether an error represents an abort.
22
+ *
23
+ * @param err - Unknown thrown value.
24
+ *
25
+ * @returns True for AbortError values.
26
+ */
27
+ export declare function isAbortError(err: unknown): boolean;
28
+ /**
29
+ * Reads a local file and computes its SHA-1 digest with non-regular-file rejection,
30
+ * scanned-size bounds, abort support, and an idle/no-progress timeout.
31
+ *
32
+ * @param path - Local sync path to hash.
33
+ * @param signal - Optional abort signal.
34
+ * @param options - Optional idle timeout override.
35
+ *
36
+ * @returns The lowercase SHA-1 digest of the file bytes.
37
+ */
38
+ export declare function readLocalSha1File(path: LocalSyncPath, signal?: AbortSignal, options?: LocalSha1ReadOptions): Promise<string>;
39
+ //# sourceMappingURL=local-sha1.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-sha1.d.ts","sourceRoot":"","sources":["../../src/sync/local-sha1.js"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE/C,qDAAqD;AACrD,MAAM,WAAW,oBAAoB;IACnC;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAChC;AAED,iFAAiF;AACjF,MAAM,MAAM,eAAe,GAAG,CAC5B,IAAI,EAAE,aAAa,EACnB,MAAM,CAAC,EAAE,WAAW,EACpB,OAAO,CAAC,EAAE,oBAAoB,KAC3B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;AAE3B;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAEpD;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAGlD;AAED;;;;;;;;;GASG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,aAAa,EACnB,MAAM,CAAC,EAAE,WAAW,EACpB,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,MAAM,CAAC,CAgEjB"}
@@ -0,0 +1,117 @@
1
+ import { IncrementalSha1 } from "../streams/hash.js";
2
+ import { toError } from "../util/to-error.js";
3
+ import { sanitizeErrorReason } from "../util/error-reason.js";
4
+ import { assertSameScannedRegularFile } from "./local-file-identity.js";
5
+ import { normalizeSha1TimeoutMillis } from "./sha1-options.js";
6
+ //#region src/sync/local-sha1.ts
7
+ /**
8
+ * Formats a hash error for public sync events without leaking filesystem paths.
9
+ *
10
+ * @param error - Error thrown while hashing.
11
+ *
12
+ * @returns A sanitized reason suitable for event messages.
13
+ */
14
+ function formatHashError(error) {
15
+ return sanitizeErrorReason(error);
16
+ }
17
+ /**
18
+ * Returns whether an error represents an abort.
19
+ *
20
+ * @param err - Unknown thrown value.
21
+ *
22
+ * @returns True for AbortError values.
23
+ */
24
+ function isAbortError(err) {
25
+ return toError(err).name === "AbortError";
26
+ }
27
+ /**
28
+ * Reads a local file and computes its SHA-1 digest with non-regular-file rejection,
29
+ * scanned-size bounds, abort support, and an idle/no-progress timeout.
30
+ *
31
+ * @param path - Local sync path to hash.
32
+ * @param signal - Optional abort signal.
33
+ * @param options - Optional idle timeout override.
34
+ *
35
+ * @returns The lowercase SHA-1 digest of the file bytes.
36
+ */
37
+ async function readLocalSha1File(path, signal, options = {}) {
38
+ const { constants } = await import("node:fs");
39
+ const { lstat, open } = await import("node:fs/promises");
40
+ const timeoutMillis = normalizeSha1TimeoutMillis(options.timeoutMillis);
41
+ const flags = constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0) | (constants.O_NONBLOCK ?? 0);
42
+ const hash = new IncrementalSha1();
43
+ let stream;
44
+ let file;
45
+ let timeout;
46
+ function armTimeout(onTimeout) {
47
+ if (timeout !== void 0) clearTimeout(timeout);
48
+ timeout = setTimeout(onTimeout, timeoutMillis);
49
+ }
50
+ try {
51
+ signal?.throwIfAborted();
52
+ assertSameScannedRegularFile(await withTimeout(lstat(path.absolutePath), timeoutMillis, "sha1 file status"), path, "sha1 comparison");
53
+ file = await openWithTimeout(open(path.absolutePath, flags), timeoutMillis);
54
+ assertSameScannedRegularFile(await withTimeout(lstat(path.absolutePath), timeoutMillis, "sha1 file status"), path, "sha1 comparison");
55
+ assertSameScannedRegularFile(await withTimeout(file.stat(), timeoutMillis, "sha1 file status"), path, "sha1 comparison");
56
+ stream = file.createReadStream({
57
+ ...path.size > 0 ? {
58
+ start: 0,
59
+ end: path.size - 1
60
+ } : {},
61
+ ...signal !== void 0 ? { signal } : {}
62
+ });
63
+ let bytesRead = 0;
64
+ /* v8 ignore next 3 -- idle-timeout firing is timing-dependent in filesystem tests */
65
+ armTimeout(() => {
66
+ stream?.destroy(/* @__PURE__ */ new Error(`sha1 read stalled for ${timeoutMillis} ms`));
67
+ });
68
+ for await (const chunk of stream) {
69
+ bytesRead += chunk.byteLength;
70
+ await hash.update(chunk);
71
+ /* v8 ignore next 3 -- idle-timeout firing is timing-dependent in filesystem tests */
72
+ armTimeout(() => {
73
+ stream?.destroy(/* @__PURE__ */ new Error(`sha1 read stalled for ${timeoutMillis} ms`));
74
+ });
75
+ }
76
+ /* v8 ignore next -- defensive TOCTOU guard after the bounded stream completes */
77
+ if (bytesRead !== path.size) throw new Error("file changed during sha1 comparison");
78
+ return hash.digest();
79
+ } finally {
80
+ if (timeout !== void 0) clearTimeout(timeout);
81
+ stream?.destroy();
82
+ await file?.close().catch(() => {});
83
+ }
84
+ }
85
+ /* v8 ignore start -- defensive stale-filesystem stall handling is not portable to trigger */
86
+ async function withTimeout(promise, timeoutMillis, operation) {
87
+ let timeout;
88
+ try {
89
+ return await Promise.race([promise, new Promise((_, reject) => {
90
+ timeout = setTimeout(() => {
91
+ reject(/* @__PURE__ */ new Error(`${operation} stalled for ${timeoutMillis} ms`));
92
+ }, timeoutMillis);
93
+ })]);
94
+ } finally {
95
+ if (timeout !== void 0) clearTimeout(timeout);
96
+ }
97
+ }
98
+ async function openWithTimeout(promise, timeoutMillis) {
99
+ let timedOut = false;
100
+ const tracked = promise.then((file) => {
101
+ if (timedOut) file.close().catch(() => {});
102
+ return file;
103
+ }, (err) => {
104
+ throw err;
105
+ });
106
+ try {
107
+ return await withTimeout(tracked, timeoutMillis, "sha1 file open");
108
+ } catch (err) {
109
+ timedOut = true;
110
+ throw err;
111
+ }
112
+ }
113
+ /* v8 ignore stop */
114
+ //#endregion
115
+ export { formatHashError, isAbortError, readLocalSha1File };
116
+
117
+ //# sourceMappingURL=local-sha1.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-sha1.js","names":[],"sources":["../../src/sync/local-sha1.ts"],"sourcesContent":["import { IncrementalSha1 } from '../streams/hash.ts'\nimport { sanitizeErrorReason } from '../util/error-reason.ts'\nimport { toError } from '../util/to-error.ts'\nimport { assertSameScannedRegularFile } from './local-file-identity.ts'\nimport { normalizeSha1TimeoutMillis } from './sha1-options.ts'\nimport type { LocalSyncPath } from './types.ts'\n\n/** Options for reading a local file SHA-1 digest. */\nexport interface LocalSha1ReadOptions {\n /**\n * Maximum milliseconds to allow without filesystem progress while hashing.\n * Defaults to 30 seconds.\n */\n readonly timeoutMillis?: number\n}\n\n/** Reads a local file and returns its SHA-1 digest, or null when unavailable. */\nexport type LocalSha1Reader = (\n path: LocalSyncPath,\n signal?: AbortSignal,\n options?: LocalSha1ReadOptions,\n) => Promise<string | null>\n\n/**\n * Formats a hash error for public sync events without leaking filesystem paths.\n *\n * @param error - Error thrown while hashing.\n *\n * @returns A sanitized reason suitable for event messages.\n */\nexport function formatHashError(error: Error): string {\n return sanitizeErrorReason(error)\n}\n\n/**\n * Returns whether an error represents an abort.\n *\n * @param err - Unknown thrown value.\n *\n * @returns True for AbortError values.\n */\nexport function isAbortError(err: unknown): boolean {\n const error = toError(err)\n return error.name === 'AbortError'\n}\n\n/**\n * Reads a local file and computes its SHA-1 digest with non-regular-file rejection,\n * scanned-size bounds, abort support, and an idle/no-progress timeout.\n *\n * @param path - Local sync path to hash.\n * @param signal - Optional abort signal.\n * @param options - Optional idle timeout override.\n *\n * @returns The lowercase SHA-1 digest of the file bytes.\n */\nexport async function readLocalSha1File(\n path: LocalSyncPath,\n signal?: AbortSignal,\n options: LocalSha1ReadOptions = {},\n): Promise<string> {\n const { constants } = await import('node:fs')\n const { lstat, open } = await import('node:fs/promises')\n const timeoutMillis = normalizeSha1TimeoutMillis(options.timeoutMillis)\n const flags = constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0) | (constants.O_NONBLOCK ?? 0)\n const hash = new IncrementalSha1()\n let stream: (AsyncIterable<Uint8Array> & { destroy(error?: Error): void }) | undefined\n let file: Awaited<ReturnType<typeof open>> | undefined\n let timeout: ReturnType<typeof setTimeout> | undefined\n\n function armTimeout(onTimeout: () => void): void {\n if (timeout !== undefined) clearTimeout(timeout)\n timeout = setTimeout(onTimeout, timeoutMillis)\n }\n\n try {\n signal?.throwIfAborted()\n\n const preOpenStat = await withTimeout(\n lstat(path.absolutePath),\n timeoutMillis,\n 'sha1 file status',\n )\n assertSameScannedRegularFile(preOpenStat, path, 'sha1 comparison')\n\n file = await openWithTimeout(open(path.absolutePath, flags), timeoutMillis)\n\n const postOpenStat = await withTimeout(\n lstat(path.absolutePath),\n timeoutMillis,\n 'sha1 file status',\n )\n assertSameScannedRegularFile(postOpenStat, path, 'sha1 comparison')\n\n const stat = await withTimeout(file.stat(), timeoutMillis, 'sha1 file status')\n assertSameScannedRegularFile(stat, path, 'sha1 comparison')\n\n stream = file.createReadStream({\n ...(path.size > 0 ? { start: 0, end: path.size - 1 } : {}),\n ...(signal !== undefined ? { signal } : {}),\n })\n\n let bytesRead = 0\n /* v8 ignore next 3 -- idle-timeout firing is timing-dependent in filesystem tests */\n armTimeout(() => {\n stream?.destroy(new Error(`sha1 read stalled for ${timeoutMillis} ms`))\n })\n for await (const chunk of stream) {\n bytesRead += chunk.byteLength\n await hash.update(chunk)\n /* v8 ignore next 3 -- idle-timeout firing is timing-dependent in filesystem tests */\n armTimeout(() => {\n stream?.destroy(new Error(`sha1 read stalled for ${timeoutMillis} ms`))\n })\n }\n\n /* v8 ignore next -- defensive TOCTOU guard after the bounded stream completes */\n if (bytesRead !== path.size) throw new Error('file changed during sha1 comparison')\n return hash.digest()\n } finally {\n if (timeout !== undefined) clearTimeout(timeout)\n stream?.destroy()\n await file?.close().catch(() => {})\n }\n}\n\n/* v8 ignore start -- defensive stale-filesystem stall handling is not portable to trigger */\nasync function withTimeout<T>(\n promise: Promise<T>,\n timeoutMillis: number,\n operation: string,\n): Promise<T> {\n let timeout: ReturnType<typeof setTimeout> | undefined\n try {\n return await Promise.race([\n promise,\n new Promise<never>((_, reject) => {\n timeout = setTimeout(() => {\n reject(new Error(`${operation} stalled for ${timeoutMillis} ms`))\n }, timeoutMillis)\n }),\n ])\n } finally {\n if (timeout !== undefined) clearTimeout(timeout)\n }\n}\n\nasync function openWithTimeout<T extends { close(): Promise<void> }>(\n promise: Promise<T>,\n timeoutMillis: number,\n): Promise<T> {\n let timedOut = false\n const tracked = promise.then(\n (file) => {\n if (timedOut) void file.close().catch(() => {})\n return file\n },\n (err: unknown) => {\n throw err\n },\n )\n\n try {\n return await withTimeout(tracked, timeoutMillis, 'sha1 file open')\n } catch (err) {\n timedOut = true\n throw err\n }\n}\n/* v8 ignore stop */\n"],"mappings":";;;;;;;;;;;;;AA8BA,SAAgB,gBAAgB,OAAsB;CACpD,OAAO,oBAAoB,KAAK;AAClC;;;;;;;;AASA,SAAgB,aAAa,KAAuB;CAElD,OADc,QAAQ,GACf,CAAA,CAAM,SAAS;AACxB;;;;;;;;;;;AAYA,eAAsB,kBACpB,MACA,QACA,UAAgC,CAAC,GAChB;CACjB,MAAM,EAAE,cAAc,MAAM,OAAO;CACnC,MAAM,EAAE,OAAO,SAAS,MAAM,OAAO;CACrC,MAAM,gBAAgB,2BAA2B,QAAQ,aAAa;CACtE,MAAM,QAAQ,UAAU,YAAY,UAAU,cAAc,MAAM,UAAU,cAAc;CAC1F,MAAM,OAAO,IAAI,gBAAgB;CACjC,IAAI;CACJ,IAAI;CACJ,IAAI;CAEJ,SAAS,WAAW,WAA6B;EAC/C,IAAI,YAAY,KAAA,GAAW,aAAa,OAAO;EAC/C,UAAU,WAAW,WAAW,aAAa;CAC/C;CAEA,IAAI;EACF,QAAQ,eAAe;EAOvB,6BAA6B,MALH,YACxB,MAAM,KAAK,YAAY,GACvB,eACA,kBACF,GAC0C,MAAM,iBAAiB;EAEjE,OAAO,MAAM,gBAAgB,KAAK,KAAK,cAAc,KAAK,GAAG,aAAa;EAO1E,6BAA6B,MALF,YACzB,MAAM,KAAK,YAAY,GACvB,eACA,kBACF,GAC2C,MAAM,iBAAiB;EAGlE,6BAA6B,MADV,YAAY,KAAK,KAAK,GAAG,eAAe,kBAAkB,GAC1C,MAAM,iBAAiB;EAE1D,SAAS,KAAK,iBAAiB;GAC7B,GAAI,KAAK,OAAO,IAAI;IAAE,OAAO;IAAG,KAAK,KAAK,OAAO;GAAE,IAAI,CAAC;GACxD,GAAI,WAAW,KAAA,IAAY,EAAE,OAAO,IAAI,CAAC;EAC3C,CAAC;EAED,IAAI,YAAY;;EAEhB,iBAAiB;GACf,QAAQ,wBAAQ,IAAI,MAAM,yBAAyB,cAAc,IAAI,CAAC;EACxE,CAAC;EACD,WAAW,MAAM,SAAS,QAAQ;GAChC,aAAa,MAAM;GACnB,MAAM,KAAK,OAAO,KAAK;;GAEvB,iBAAiB;IACf,QAAQ,wBAAQ,IAAI,MAAM,yBAAyB,cAAc,IAAI,CAAC;GACxE,CAAC;EACH;;EAGA,IAAI,cAAc,KAAK,MAAM,MAAM,IAAI,MAAM,qCAAqC;EAClF,OAAO,KAAK,OAAO;CACrB,UAAU;EACR,IAAI,YAAY,KAAA,GAAW,aAAa,OAAO;EAC/C,QAAQ,QAAQ;EAChB,MAAM,MAAM,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;CACpC;AACF;;AAGA,eAAe,YACb,SACA,eACA,WACY;CACZ,IAAI;CACJ,IAAI;EACF,OAAO,MAAM,QAAQ,KAAK,CACxB,SACA,IAAI,SAAgB,GAAG,WAAW;GAChC,UAAU,iBAAiB;IACzB,uBAAO,IAAI,MAAM,GAAG,UAAU,eAAe,cAAc,IAAI,CAAC;GAClE,GAAG,aAAa;EAClB,CAAC,CACH,CAAC;CACH,UAAU;EACR,IAAI,YAAY,KAAA,GAAW,aAAa,OAAO;CACjD;AACF;AAEA,eAAe,gBACb,SACA,eACY;CACZ,IAAI,WAAW;CACf,MAAM,UAAU,QAAQ,MACrB,SAAS;EACR,IAAI,UAAU,KAAU,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;EAC9C,OAAO;CACT,IACC,QAAiB;EAChB,MAAM;CACR,CACF;CAEA,IAAI;EACF,OAAO,MAAM,YAAY,SAAS,eAAe,gBAAgB;CACnE,SAAS,KAAK;EACZ,WAAW;EACX,MAAM;CACR;AACF"}
@@ -1,31 +1,120 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- async function* zipFolders(source, dest) {
4
- const sourceIter = source.scan()[Symbol.asyncIterator]();
5
- const destIter = dest.scan()[Symbol.asyncIterator]();
6
- let sourceResult = await sourceIter.next();
7
- let destResult = await destIter.next();
8
- while (!sourceResult.done || !destResult.done) {
9
- const s = sourceResult.done ? null : sourceResult.value;
10
- const d = destResult.done ? null : destResult.value;
11
- if (s === null) {
12
- yield [null, d];
13
- destResult = await destIter.next();
14
- } else if (d === null) {
15
- yield [s, null];
16
- sourceResult = await sourceIter.next();
17
- } else if (s.relativePath < d.relativePath) {
18
- yield [s, null];
19
- sourceResult = await sourceIter.next();
20
- } else if (d.relativePath < s.relativePath) {
21
- yield [null, d];
22
- destResult = await destIter.next();
23
- } else {
24
- yield [s, d];
25
- sourceResult = await sourceIter.next();
26
- destResult = await destIter.next();
27
- }
28
- }
1
+ const require_regexp_safety = require("./regexp-safety.cjs");
2
+ const require_filters = require("./filters.cjs");
3
+ const require_path_order = require("./path-order.cjs");
4
+ const require_scan_limit = require("./scan-limit.cjs");
5
+ //#region src/sync/pairing.ts
6
+ /**
7
+ * Merge-joins two sorted folder scans by relative path, yielding paired tuples.
8
+ * Files present only in source yield `[source, null]`, only in dest yield `[null, dest]`,
9
+ * and files in both yield `[source, dest]`.
10
+ *
11
+ * @param source - The source folder to scan.
12
+ * @param dest - The destination folder to scan.
13
+ * @param options - Optional scan controls and filters shared by both folders.
14
+ * @param scanCallbacks - Optional internal source/destination skip callbacks.
15
+ */
16
+ async function* zipFolders(source, dest, options = {}, scanCallbacks = {}) {
17
+ require_regexp_safety.validateSyncFilters(options);
18
+ const sourceOptions = scanOptionsSnapshot(options, scanCallbacks.onSourceSkip);
19
+ const destOptions = scanOptionsSnapshot(options, scanCallbacks.onDestSkip);
20
+ const sourceIter = scanWithFilters(source, sourceOptions)[Symbol.asyncIterator]();
21
+ const destIter = scanWithFilters(dest, destOptions)[Symbol.asyncIterator]();
22
+ let sourceDone = false;
23
+ let destDone = false;
24
+ try {
25
+ let [sourceResult, destResult] = await Promise.all([sourceIter.next(), destIter.next()]);
26
+ sourceDone = sourceResult.done === true;
27
+ destDone = destResult.done === true;
28
+ while (!sourceResult.done || !destResult.done) {
29
+ const s = sourceResult.done ? null : sourceResult.value;
30
+ const d = destResult.done ? null : destResult.value;
31
+ if (s === null) {
32
+ yield [null, d];
33
+ destResult = await destIter.next();
34
+ destDone = destResult.done === true;
35
+ } else if (d === null) {
36
+ yield [s, null];
37
+ sourceResult = await sourceIter.next();
38
+ sourceDone = sourceResult.done === true;
39
+ } else {
40
+ const comparison = require_path_order.compareSyncRelativePaths(s.relativePath, d.relativePath);
41
+ if (comparison < 0) {
42
+ yield [s, null];
43
+ sourceResult = await sourceIter.next();
44
+ sourceDone = sourceResult.done === true;
45
+ } else if (comparison > 0) {
46
+ yield [null, d];
47
+ destResult = await destIter.next();
48
+ destDone = destResult.done === true;
49
+ } else {
50
+ yield [s, d];
51
+ sourceResult = await sourceIter.next();
52
+ destResult = await destIter.next();
53
+ sourceDone = sourceResult.done === true;
54
+ destDone = destResult.done === true;
55
+ }
56
+ }
57
+ }
58
+ } finally {
59
+ await closeScanIterator(sourceIter, sourceDone);
60
+ await closeScanIterator(destIter, destDone);
61
+ }
29
62
  }
63
+ async function closeScanIterator(iterator, alreadyDone) {
64
+ if (alreadyDone || iterator.return === void 0) return;
65
+ try {
66
+ await iterator.return();
67
+ } catch {}
68
+ }
69
+ function scanWithFilters(folder, options) {
70
+ const scanned = require_filters.filterSyncPaths(folder.scan(options.scanner), options.sdk);
71
+ if (folder.appliesScanSorting === true) return limitSyncPaths(scanned, options.sdk);
72
+ return sortSyncPaths(scanned, options.sdk);
73
+ }
74
+ async function* limitSyncPaths(paths, filters) {
75
+ const maxScanEntries = require_scan_limit.scanEntryLimit(filters);
76
+ let count = 0;
77
+ for await (const path of paths) {
78
+ count++;
79
+ require_scan_limit.assertScanEntryLimit(count, maxScanEntries);
80
+ yield path;
81
+ }
82
+ }
83
+ async function* sortSyncPaths(paths, filters) {
84
+ const maxScanEntries = require_scan_limit.scanEntryLimit(filters);
85
+ const collected = [];
86
+ for await (const path of paths) {
87
+ collected.push(path);
88
+ require_scan_limit.assertScanEntryLimit(collected.length, maxScanEntries);
89
+ }
90
+ collected.sort((a, b) => require_path_order.compareSyncRelativePaths(a.relativePath, b.relativePath));
91
+ yield* collected;
92
+ }
93
+ function scanOptionsSnapshot(options, onSkip) {
94
+ const onSkipSnapshot = options.onSkip === void 0 && onSkip === void 0 ? void 0 : (event) => {
95
+ options.onSkip?.(event);
96
+ onSkip?.(event);
97
+ };
98
+ return {
99
+ scanner: frozenScanOptions(options, frozenPatterns(options.include), frozenPatterns(options.exclude), onSkipSnapshot),
100
+ sdk: frozenScanOptions(options, frozenPatterns(options.include), frozenPatterns(options.exclude), onSkipSnapshot)
101
+ };
102
+ }
103
+ function frozenScanOptions(options, include, exclude, onSkip) {
104
+ return Object.freeze({
105
+ ...include !== void 0 ? { include } : {},
106
+ ...exclude !== void 0 ? { exclude } : {},
107
+ ...options.signal !== void 0 ? { signal: options.signal } : {},
108
+ ...options.onError !== void 0 ? { onError: options.onError } : {},
109
+ ...onSkip !== void 0 ? { onSkip } : {},
110
+ ...options.requireLocalSafePaths !== void 0 ? { requireLocalSafePaths: options.requireLocalSafePaths } : {},
111
+ ...options.maxScanEntries !== void 0 ? { maxScanEntries: options.maxScanEntries } : {}
112
+ });
113
+ }
114
+ function frozenPatterns(patterns) {
115
+ return patterns === void 0 ? void 0 : Object.freeze([...patterns]);
116
+ }
117
+ //#endregion
30
118
  exports.zipFolders = zipFolders;
31
- //# sourceMappingURL=pairing.cjs.map
119
+
120
+ //# sourceMappingURL=pairing.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"pairing.cjs","sources":["../../src/sync/pairing.ts"],"sourcesContent":["import type { SyncFolder, SyncPath } from './types.ts'\n\n/** A paired tuple of source and destination files. Either side may be null if the file is absent. */\nexport type SyncPair = readonly [SyncPath | null, SyncPath | null]\n\n/**\n * Merge-joins two sorted folder scans by relative path, yielding paired tuples.\n * Files present only in source yield `[source, null]`, only in dest yield `[null, dest]`,\n * and files in both yield `[source, dest]`.\n *\n * @param source - The source folder to scan.\n * @param dest - The destination folder to scan.\n */\nexport async function* zipFolders(source: SyncFolder, dest: SyncFolder): AsyncGenerator<SyncPair> {\n const sourceIter = source.scan()[Symbol.asyncIterator]()\n const destIter = dest.scan()[Symbol.asyncIterator]()\n\n let sourceResult = await sourceIter.next()\n let destResult = await destIter.next()\n\n while (!sourceResult.done || !destResult.done) {\n const s = sourceResult.done ? null : sourceResult.value\n const d = destResult.done ? null : destResult.value\n\n if (s === null) {\n yield [null, d]\n destResult = await destIter.next()\n } else if (d === null) {\n yield [s, null]\n sourceResult = await sourceIter.next()\n } else if (s.relativePath < d.relativePath) {\n yield [s, null]\n sourceResult = await sourceIter.next()\n } else if (d.relativePath < s.relativePath) {\n yield [null, d]\n destResult = await destIter.next()\n } else {\n yield [s, d]\n sourceResult = await sourceIter.next()\n destResult = await destIter.next()\n }\n }\n}\n"],"names":[],"mappings":";;AAaA,gBAAuB,WAAW,QAAoB,MAA4C;AAChG,QAAM,aAAa,OAAO,KAAA,EAAO,OAAO,aAAa,EAAA;AACrD,QAAM,WAAW,KAAK,KAAA,EAAO,OAAO,aAAa,EAAA;AAEjD,MAAI,eAAe,MAAM,WAAW,KAAA;AACpC,MAAI,aAAa,MAAM,SAAS,KAAA;AAEhC,SAAO,CAAC,aAAa,QAAQ,CAAC,WAAW,MAAM;AAC7C,UAAM,IAAI,aAAa,OAAO,OAAO,aAAa;AAClD,UAAM,IAAI,WAAW,OAAO,OAAO,WAAW;AAE9C,QAAI,MAAM,MAAM;AACd,YAAM,CAAC,MAAM,CAAC;AACd,mBAAa,MAAM,SAAS,KAAA;AAAA,IAC9B,WAAW,MAAM,MAAM;AACrB,YAAM,CAAC,GAAG,IAAI;AACd,qBAAe,MAAM,WAAW,KAAA;AAAA,IAClC,WAAW,EAAE,eAAe,EAAE,cAAc;AAC1C,YAAM,CAAC,GAAG,IAAI;AACd,qBAAe,MAAM,WAAW,KAAA;AAAA,IAClC,WAAW,EAAE,eAAe,EAAE,cAAc;AAC1C,YAAM,CAAC,MAAM,CAAC;AACd,mBAAa,MAAM,SAAS,KAAA;AAAA,IAC9B,OAAO;AACL,YAAM,CAAC,GAAG,CAAC;AACX,qBAAe,MAAM,WAAW,KAAA;AAChC,mBAAa,MAAM,SAAS,KAAA;AAAA,IAC9B;AAAA,EACF;AACF;;"}
1
+ {"version":3,"file":"pairing.cjs","names":[],"sources":["../../src/sync/pairing.ts"],"sourcesContent":["import { filterSyncPaths } from './filters.ts'\nimport { compareSyncRelativePaths } from './path-order.ts'\nimport { validateSyncFilters } from './regexp-safety.ts'\nimport { assertScanEntryLimit, scanEntryLimit } from './scan-limit.ts'\nimport type {\n SyncFilterPattern,\n SyncFolder,\n SyncPath,\n SyncScanOptions,\n SyncSkipEvent,\n} from './types.ts'\n\n/** A paired tuple of source and destination files. Either side may be null if the file is absent. */\nexport type SyncPair = readonly [SyncPath | null, SyncPath | null]\n\n/**\n * Merge-joins two sorted folder scans by relative path, yielding paired tuples.\n * Files present only in source yield `[source, null]`, only in dest yield `[null, dest]`,\n * and files in both yield `[source, dest]`.\n *\n * @param source - The source folder to scan.\n * @param dest - The destination folder to scan.\n * @param options - Optional scan controls and filters shared by both folders.\n * @param scanCallbacks - Optional internal source/destination skip callbacks.\n */\nexport async function* zipFolders(\n source: SyncFolder,\n dest: SyncFolder,\n options: SyncScanOptions = {},\n scanCallbacks: {\n readonly onSourceSkip?: (event: SyncSkipEvent) => void\n readonly onDestSkip?: (event: SyncSkipEvent) => void\n } = {},\n): AsyncGenerator<SyncPair> {\n validateSyncFilters(options)\n const sourceOptions = scanOptionsSnapshot(options, scanCallbacks.onSourceSkip)\n const destOptions = scanOptionsSnapshot(options, scanCallbacks.onDestSkip)\n const sourceIter = scanWithFilters(source, sourceOptions)[Symbol.asyncIterator]()\n const destIter = scanWithFilters(dest, destOptions)[Symbol.asyncIterator]()\n let sourceDone = false\n let destDone = false\n\n try {\n let [sourceResult, destResult] = await Promise.all([sourceIter.next(), destIter.next()])\n sourceDone = sourceResult.done === true\n destDone = destResult.done === true\n\n while (!sourceResult.done || !destResult.done) {\n const s = sourceResult.done ? null : sourceResult.value\n const d = destResult.done ? null : destResult.value\n\n if (s === null) {\n yield [null, d]\n destResult = await destIter.next()\n destDone = destResult.done === true\n } else if (d === null) {\n yield [s, null]\n sourceResult = await sourceIter.next()\n sourceDone = sourceResult.done === true\n } else {\n const comparison = compareSyncRelativePaths(s.relativePath, d.relativePath)\n if (comparison < 0) {\n yield [s, null]\n sourceResult = await sourceIter.next()\n sourceDone = sourceResult.done === true\n } else if (comparison > 0) {\n yield [null, d]\n destResult = await destIter.next()\n destDone = destResult.done === true\n } else {\n yield [s, d]\n sourceResult = await sourceIter.next()\n destResult = await destIter.next()\n sourceDone = sourceResult.done === true\n destDone = destResult.done === true\n }\n }\n }\n } finally {\n await closeScanIterator(sourceIter, sourceDone)\n await closeScanIterator(destIter, destDone)\n }\n}\n\nasync function closeScanIterator(\n iterator: AsyncIterator<SyncPath>,\n alreadyDone: boolean,\n): Promise<void> {\n if (alreadyDone || iterator.return === undefined) return\n try {\n await iterator.return()\n } catch {\n // Best-effort scanner cleanup should not mask the original stop reason.\n }\n}\n\nfunction scanWithFilters(\n folder: SyncFolder,\n options: { readonly scanner: SyncScanOptions; readonly sdk: SyncScanOptions },\n): AsyncIterable<SyncPath> {\n const scanned = filterSyncPaths(folder.scan(options.scanner), options.sdk)\n if (folder.appliesScanSorting === true) return limitSyncPaths(scanned, options.sdk)\n return sortSyncPaths(scanned, options.sdk)\n}\n\nasync function* limitSyncPaths(\n paths: AsyncIterable<SyncPath>,\n filters: SyncScanOptions | undefined,\n): AsyncGenerator<SyncPath> {\n const maxScanEntries = scanEntryLimit(filters)\n let count = 0\n for await (const path of paths) {\n count++\n assertScanEntryLimit(count, maxScanEntries)\n yield path\n }\n}\n\nasync function* sortSyncPaths(\n paths: AsyncIterable<SyncPath>,\n filters: SyncScanOptions | undefined,\n): AsyncGenerator<SyncPath> {\n const maxScanEntries = scanEntryLimit(filters)\n const collected: SyncPath[] = []\n for await (const path of paths) {\n collected.push(path)\n assertScanEntryLimit(collected.length, maxScanEntries)\n }\n collected.sort((a, b) => compareSyncRelativePaths(a.relativePath, b.relativePath))\n yield* collected\n}\n\nfunction scanOptionsSnapshot(\n options: SyncScanOptions,\n onSkip: ((event: SyncSkipEvent) => void) | undefined,\n): { readonly scanner: SyncScanOptions; readonly sdk: SyncScanOptions } {\n const onSkipSnapshot =\n options.onSkip === undefined && onSkip === undefined\n ? undefined\n : (event: SyncSkipEvent): void => {\n options.onSkip?.(event)\n onSkip?.(event)\n }\n\n return {\n scanner: frozenScanOptions(\n options,\n frozenPatterns(options.include),\n frozenPatterns(options.exclude),\n onSkipSnapshot,\n ),\n sdk: frozenScanOptions(\n options,\n frozenPatterns(options.include),\n frozenPatterns(options.exclude),\n onSkipSnapshot,\n ),\n }\n}\n\nfunction frozenScanOptions(\n options: SyncScanOptions,\n include: readonly SyncFilterPattern[] | undefined,\n exclude: readonly SyncFilterPattern[] | undefined,\n onSkip: ((event: SyncSkipEvent) => void) | undefined,\n): SyncScanOptions {\n return Object.freeze({\n ...(include !== undefined ? { include } : {}),\n ...(exclude !== undefined ? { exclude } : {}),\n ...(options.signal !== undefined ? { signal: options.signal } : {}),\n ...(options.onError !== undefined ? { onError: options.onError } : {}),\n ...(onSkip !== undefined ? { onSkip } : {}),\n ...(options.requireLocalSafePaths !== undefined\n ? { requireLocalSafePaths: options.requireLocalSafePaths }\n : {}),\n ...(options.maxScanEntries !== undefined ? { maxScanEntries: options.maxScanEntries } : {}),\n })\n}\n\nfunction frozenPatterns(\n patterns: readonly SyncFilterPattern[] | undefined,\n): readonly SyncFilterPattern[] | undefined {\n return patterns === undefined ? undefined : Object.freeze([...patterns])\n}\n"],"mappings":";;;;;;;;;;;;;;;AAyBA,gBAAuB,WACrB,QACA,MACA,UAA2B,CAAC,GAC5B,gBAGI,CAAC,GACqB;CAC1B,sBAAA,oBAAoB,OAAO;CAC3B,MAAM,gBAAgB,oBAAoB,SAAS,cAAc,YAAY;CAC7E,MAAM,cAAc,oBAAoB,SAAS,cAAc,UAAU;CACzE,MAAM,aAAa,gBAAgB,QAAQ,aAAa,CAAC,CAAC,OAAO,cAAc,CAAC;CAChF,MAAM,WAAW,gBAAgB,MAAM,WAAW,CAAC,CAAC,OAAO,cAAc,CAAC;CAC1E,IAAI,aAAa;CACjB,IAAI,WAAW;CAEf,IAAI;EACF,IAAI,CAAC,cAAc,cAAc,MAAM,QAAQ,IAAI,CAAC,WAAW,KAAK,GAAG,SAAS,KAAK,CAAC,CAAC;EACvF,aAAa,aAAa,SAAS;EACnC,WAAW,WAAW,SAAS;EAE/B,OAAO,CAAC,aAAa,QAAQ,CAAC,WAAW,MAAM;GAC7C,MAAM,IAAI,aAAa,OAAO,OAAO,aAAa;GAClD,MAAM,IAAI,WAAW,OAAO,OAAO,WAAW;GAE9C,IAAI,MAAM,MAAM;IACd,MAAM,CAAC,MAAM,CAAC;IACd,aAAa,MAAM,SAAS,KAAK;IACjC,WAAW,WAAW,SAAS;GACjC,OAAO,IAAI,MAAM,MAAM;IACrB,MAAM,CAAC,GAAG,IAAI;IACd,eAAe,MAAM,WAAW,KAAK;IACrC,aAAa,aAAa,SAAS;GACrC,OAAO;IACL,MAAM,aAAa,mBAAA,yBAAyB,EAAE,cAAc,EAAE,YAAY;IAC1E,IAAI,aAAa,GAAG;KAClB,MAAM,CAAC,GAAG,IAAI;KACd,eAAe,MAAM,WAAW,KAAK;KACrC,aAAa,aAAa,SAAS;IACrC,OAAO,IAAI,aAAa,GAAG;KACzB,MAAM,CAAC,MAAM,CAAC;KACd,aAAa,MAAM,SAAS,KAAK;KACjC,WAAW,WAAW,SAAS;IACjC,OAAO;KACL,MAAM,CAAC,GAAG,CAAC;KACX,eAAe,MAAM,WAAW,KAAK;KACrC,aAAa,MAAM,SAAS,KAAK;KACjC,aAAa,aAAa,SAAS;KACnC,WAAW,WAAW,SAAS;IACjC;GACF;EACF;CACF,UAAU;EACR,MAAM,kBAAkB,YAAY,UAAU;EAC9C,MAAM,kBAAkB,UAAU,QAAQ;CAC5C;AACF;AAEA,eAAe,kBACb,UACA,aACe;CACf,IAAI,eAAe,SAAS,WAAW,KAAA,GAAW;CAClD,IAAI;EACF,MAAM,SAAS,OAAO;CACxB,QAAQ,CAER;AACF;AAEA,SAAS,gBACP,QACA,SACyB;CACzB,MAAM,UAAU,gBAAA,gBAAgB,OAAO,KAAK,QAAQ,OAAO,GAAG,QAAQ,GAAG;CACzE,IAAI,OAAO,uBAAuB,MAAM,OAAO,eAAe,SAAS,QAAQ,GAAG;CAClF,OAAO,cAAc,SAAS,QAAQ,GAAG;AAC3C;AAEA,gBAAgB,eACd,OACA,SAC0B;CAC1B,MAAM,iBAAiB,mBAAA,eAAe,OAAO;CAC7C,IAAI,QAAQ;CACZ,WAAW,MAAM,QAAQ,OAAO;EAC9B;EACA,mBAAA,qBAAqB,OAAO,cAAc;EAC1C,MAAM;CACR;AACF;AAEA,gBAAgB,cACd,OACA,SAC0B;CAC1B,MAAM,iBAAiB,mBAAA,eAAe,OAAO;CAC7C,MAAM,YAAwB,CAAC;CAC/B,WAAW,MAAM,QAAQ,OAAO;EAC9B,UAAU,KAAK,IAAI;EACnB,mBAAA,qBAAqB,UAAU,QAAQ,cAAc;CACvD;CACA,UAAU,MAAM,GAAG,MAAM,mBAAA,yBAAyB,EAAE,cAAc,EAAE,YAAY,CAAC;CACjF,OAAO;AACT;AAEA,SAAS,oBACP,SACA,QACsE;CACtE,MAAM,iBACJ,QAAQ,WAAW,KAAA,KAAa,WAAW,KAAA,IACvC,KAAA,KACC,UAA+B;EAC9B,QAAQ,SAAS,KAAK;EACtB,SAAS,KAAK;CAChB;CAEN,OAAO;EACL,SAAS,kBACP,SACA,eAAe,QAAQ,OAAO,GAC9B,eAAe,QAAQ,OAAO,GAC9B,cACF;EACA,KAAK,kBACH,SACA,eAAe,QAAQ,OAAO,GAC9B,eAAe,QAAQ,OAAO,GAC9B,cACF;CACF;AACF;AAEA,SAAS,kBACP,SACA,SACA,SACA,QACiB;CACjB,OAAO,OAAO,OAAO;EACnB,GAAI,YAAY,KAAA,IAAY,EAAE,QAAQ,IAAI,CAAC;EAC3C,GAAI,YAAY,KAAA,IAAY,EAAE,QAAQ,IAAI,CAAC;EAC3C,GAAI,QAAQ,WAAW,KAAA,IAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;EACjE,GAAI,QAAQ,YAAY,KAAA,IAAY,EAAE,SAAS,QAAQ,QAAQ,IAAI,CAAC;EACpE,GAAI,WAAW,KAAA,IAAY,EAAE,OAAO,IAAI,CAAC;EACzC,GAAI,QAAQ,0BAA0B,KAAA,IAClC,EAAE,uBAAuB,QAAQ,sBAAsB,IACvD,CAAC;EACL,GAAI,QAAQ,mBAAmB,KAAA,IAAY,EAAE,gBAAgB,QAAQ,eAAe,IAAI,CAAC;CAC3F,CAAC;AACH;AAEA,SAAS,eACP,UAC0C;CAC1C,OAAO,aAAa,KAAA,IAAY,KAAA,IAAY,OAAO,OAAO,CAAC,GAAG,QAAQ,CAAC;AACzE"}
@@ -1,4 +1,4 @@
1
- import { SyncFolder, SyncPath } from './types.js';
1
+ import { SyncFolder, SyncPath, SyncScanOptions, SyncSkipEvent } from './types.js';
2
2
  /** A paired tuple of source and destination files. Either side may be null if the file is absent. */
3
3
  export type SyncPair = readonly [SyncPath | null, SyncPath | null];
4
4
  /**
@@ -8,6 +8,11 @@ export type SyncPair = readonly [SyncPath | null, SyncPath | null];
8
8
  *
9
9
  * @param source - The source folder to scan.
10
10
  * @param dest - The destination folder to scan.
11
+ * @param options - Optional scan controls and filters shared by both folders.
12
+ * @param scanCallbacks - Optional internal source/destination skip callbacks.
11
13
  */
12
- export declare function zipFolders(source: SyncFolder, dest: SyncFolder): AsyncGenerator<SyncPair>;
14
+ export declare function zipFolders(source: SyncFolder, dest: SyncFolder, options?: SyncScanOptions, scanCallbacks?: {
15
+ readonly onSourceSkip?: (event: SyncSkipEvent) => void;
16
+ readonly onDestSkip?: (event: SyncSkipEvent) => void;
17
+ }): AsyncGenerator<SyncPair>;
13
18
  //# sourceMappingURL=pairing.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pairing.d.ts","sourceRoot":"","sources":["../../src/sync/pairing.js"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAEtD,qGAAqG;AACrG,MAAM,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,GAAG,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC,CAAA;AAElE;;;;;;;GAOG;AACH,wBAAuB,UAAU,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,GAAG,cAAc,CAAC,QAAQ,CAAC,CA6BhG"}
1
+ {"version":3,"file":"pairing.d.ts","sourceRoot":"","sources":["../../src/sync/pairing.js"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAEV,UAAU,EACV,QAAQ,EACR,eAAe,EACf,aAAa,EACd,MAAM,YAAY,CAAA;AAEnB,qGAAqG;AACrG,MAAM,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,GAAG,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC,CAAA;AAElE;;;;;;;;;GASG;AACH,wBAAuB,UAAU,CAC/B,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,UAAU,EAChB,OAAO,GAAE,eAAoB,EAC7B,aAAa,GAAE;IACb,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAA;IACtD,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAA;CAChD,GACL,cAAc,CAAC,QAAQ,CAAC,CAiD1B"}
@@ -1,4 +1,4 @@
1
- import { SyncFolder, SyncPath } from './types.js';
1
+ import { SyncFolder, SyncPath, SyncScanOptions, SyncSkipEvent } from './types.js';
2
2
  /** A paired tuple of source and destination files. Either side may be null if the file is absent. */
3
3
  export type SyncPair = readonly [SyncPath | null, SyncPath | null];
4
4
  /**
@@ -8,6 +8,11 @@ export type SyncPair = readonly [SyncPath | null, SyncPath | null];
8
8
  *
9
9
  * @param source - The source folder to scan.
10
10
  * @param dest - The destination folder to scan.
11
+ * @param options - Optional scan controls and filters shared by both folders.
12
+ * @param scanCallbacks - Optional internal source/destination skip callbacks.
11
13
  */
12
- export declare function zipFolders(source: SyncFolder, dest: SyncFolder): AsyncGenerator<SyncPair>;
14
+ export declare function zipFolders(source: SyncFolder, dest: SyncFolder, options?: SyncScanOptions, scanCallbacks?: {
15
+ readonly onSourceSkip?: (event: SyncSkipEvent) => void;
16
+ readonly onDestSkip?: (event: SyncSkipEvent) => void;
17
+ }): AsyncGenerator<SyncPair>;
13
18
  //# sourceMappingURL=pairing.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pairing.d.ts","sourceRoot":"","sources":["../../src/sync/pairing.js"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAEtD,qGAAqG;AACrG,MAAM,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,GAAG,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC,CAAA;AAElE;;;;;;;GAOG;AACH,wBAAuB,UAAU,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,GAAG,cAAc,CAAC,QAAQ,CAAC,CA6BhG"}
1
+ {"version":3,"file":"pairing.d.ts","sourceRoot":"","sources":["../../src/sync/pairing.js"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAEV,UAAU,EACV,QAAQ,EACR,eAAe,EACf,aAAa,EACd,MAAM,YAAY,CAAA;AAEnB,qGAAqG;AACrG,MAAM,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,GAAG,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC,CAAA;AAElE;;;;;;;;;GASG;AACH,wBAAuB,UAAU,CAC/B,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,UAAU,EAChB,OAAO,GAAE,eAAoB,EAC7B,aAAa,GAAE;IACb,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAA;IACtD,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAA;CAChD,GACL,cAAc,CAAC,QAAQ,CAAC,CAiD1B"}