@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.
- package/CHANGELOG.md +110 -5
- package/README.md +144 -33
- package/dist/_virtual/_b2-sdk-version-json.cjs +4 -0
- package/dist/_virtual/_b2-sdk-version-json.js +4 -0
- package/dist/auth/account-info.d.cts +32 -0
- package/dist/auth/account-info.d.cts.map +1 -1
- package/dist/auth/account-info.d.ts +32 -0
- package/dist/auth/account-info.d.ts.map +1 -1
- package/dist/auth/file.cjs +408 -207
- package/dist/auth/file.cjs.map +1 -1
- package/dist/auth/file.d.cts +77 -3
- package/dist/auth/file.d.cts.map +1 -1
- package/dist/auth/file.d.ts +77 -3
- package/dist/auth/file.d.ts.map +1 -1
- package/dist/auth/file.js +407 -207
- package/dist/auth/file.js.map +1 -1
- package/dist/auth/in-memory.cjs +212 -183
- package/dist/auth/in-memory.cjs.map +1 -1
- package/dist/auth/in-memory.d.cts +8 -0
- package/dist/auth/in-memory.d.cts.map +1 -1
- package/dist/auth/in-memory.d.ts +8 -0
- package/dist/auth/in-memory.d.ts.map +1 -1
- package/dist/auth/in-memory.js +211 -182
- package/dist/auth/in-memory.js.map +1 -1
- package/dist/auth/index.cjs +7 -9
- package/dist/auth/index.d.cts +3 -2
- package/dist/auth/index.d.cts.map +1 -1
- package/dist/auth/index.d.ts +3 -2
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +2 -8
- package/dist/auth/realms.cjs +80 -7
- package/dist/auth/realms.cjs.map +1 -1
- package/dist/auth/realms.d.cts +27 -4
- package/dist/auth/realms.d.cts.map +1 -1
- package/dist/auth/realms.d.ts +27 -4
- package/dist/auth/realms.d.ts.map +1 -1
- package/dist/auth/realms.js +80 -9
- package/dist/auth/realms.js.map +1 -1
- package/dist/auth/upload-url-pool.cjs +55 -51
- package/dist/auth/upload-url-pool.cjs.map +1 -1
- package/dist/auth/upload-url-pool.js +55 -51
- package/dist/auth/upload-url-pool.js.map +1 -1
- package/dist/bucket.cjs +785 -787
- package/dist/bucket.cjs.map +1 -1
- package/dist/bucket.d.cts +35 -47
- package/dist/bucket.d.cts.map +1 -1
- package/dist/bucket.d.ts +35 -47
- package/dist/bucket.d.ts.map +1 -1
- package/dist/bucket.js +780 -782
- package/dist/bucket.js.map +1 -1
- package/dist/client.cjs +246 -228
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +25 -17
- package/dist/client.d.cts.map +1 -1
- package/dist/client.d.ts +25 -17
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +243 -225
- package/dist/client.js.map +1 -1
- package/dist/copy/large.cjs +114 -71
- package/dist/copy/large.cjs.map +1 -1
- package/dist/copy/large.d.cts +6 -0
- package/dist/copy/large.d.cts.map +1 -1
- package/dist/copy/large.d.ts +6 -0
- package/dist/copy/large.d.ts.map +1 -1
- package/dist/copy/large.js +112 -69
- package/dist/copy/large.js.map +1 -1
- package/dist/download/checksum.cjs +89 -0
- package/dist/download/checksum.cjs.map +1 -0
- package/dist/download/checksum.d.cts +40 -0
- package/dist/download/checksum.d.cts.map +1 -0
- package/dist/download/checksum.d.ts +40 -0
- package/dist/download/checksum.d.ts.map +1 -0
- package/dist/download/checksum.js +87 -0
- package/dist/download/checksum.js.map +1 -0
- package/dist/download/parallel.cjs +214 -118
- package/dist/download/parallel.cjs.map +1 -1
- package/dist/download/parallel.d.cts +5 -1
- package/dist/download/parallel.d.cts.map +1 -1
- package/dist/download/parallel.d.ts +5 -1
- package/dist/download/parallel.d.ts.map +1 -1
- package/dist/download/parallel.js +212 -116
- package/dist/download/parallel.js.map +1 -1
- package/dist/download/single.cjs +188 -97
- package/dist/download/single.cjs.map +1 -1
- package/dist/download/single.d.cts +6 -1
- package/dist/download/single.d.cts.map +1 -1
- package/dist/download/single.d.ts +6 -1
- package/dist/download/single.d.ts.map +1 -1
- package/dist/download/single.js +186 -98
- package/dist/download/single.js.map +1 -1
- package/dist/errors/index.cjs +699 -243
- package/dist/errors/index.cjs.map +1 -1
- package/dist/errors/index.d.cts +285 -82
- package/dist/errors/index.d.cts.map +1 -1
- package/dist/errors/index.d.ts +285 -82
- package/dist/errors/index.d.ts.map +1 -1
- package/dist/errors/index.js +678 -261
- package/dist/errors/index.js.map +1 -1
- package/dist/http/retry.cjs +45 -28
- package/dist/http/retry.cjs.map +1 -1
- package/dist/http/retry.d.cts +15 -2
- package/dist/http/retry.d.cts.map +1 -1
- package/dist/http/retry.d.ts +15 -2
- package/dist/http/retry.d.ts.map +1 -1
- package/dist/http/retry.js +46 -31
- package/dist/http/retry.js.map +1 -1
- package/dist/http/transport.cjs +438 -140
- package/dist/http/transport.cjs.map +1 -1
- package/dist/http/transport.d.cts +21 -2
- package/dist/http/transport.d.cts.map +1 -1
- package/dist/http/transport.d.ts +21 -2
- package/dist/http/transport.d.ts.map +1 -1
- package/dist/http/transport.js +437 -140
- package/dist/http/transport.js.map +1 -1
- package/dist/http/url-guard.cjs +154 -89
- package/dist/http/url-guard.cjs.map +1 -1
- package/dist/http/url-guard.d.cts +25 -3
- package/dist/http/url-guard.d.cts.map +1 -1
- package/dist/http/url-guard.d.ts +25 -3
- package/dist/http/url-guard.d.ts.map +1 -1
- package/dist/http/url-guard.js +152 -90
- package/dist/http/url-guard.js.map +1 -1
- package/dist/http/user-agent.cjs +84 -44
- package/dist/http/user-agent.cjs.map +1 -1
- package/dist/http/user-agent.js +84 -46
- package/dist/http/user-agent.js.map +1 -1
- package/dist/index.cjs +101 -77
- package/dist/index.d.cts +27 -21
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +27 -21
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -71
- package/dist/internal/b2-naming.cjs +66 -0
- package/dist/internal/b2-naming.cjs.map +1 -0
- package/dist/internal/b2-naming.d.cts +43 -0
- package/dist/internal/b2-naming.d.cts.map +1 -0
- package/dist/internal/b2-naming.d.ts +43 -0
- package/dist/internal/b2-naming.d.ts.map +1 -0
- package/dist/internal/b2-naming.js +60 -0
- package/dist/internal/b2-naming.js.map +1 -0
- package/dist/internal/upload-retry-options.cjs +21 -0
- package/dist/internal/upload-retry-options.cjs.map +1 -0
- package/dist/internal/upload-retry-options.d.cts +12 -0
- package/dist/internal/upload-retry-options.d.cts.map +1 -0
- package/dist/internal/upload-retry-options.d.ts +12 -0
- package/dist/internal/upload-retry-options.d.ts.map +1 -0
- package/dist/internal/upload-retry-options.js +21 -0
- package/dist/internal/upload-retry-options.js.map +1 -0
- package/dist/internal/url-redaction.cjs +31 -0
- package/dist/internal/url-redaction.cjs.map +1 -0
- package/dist/internal/url-redaction.d.cts +17 -0
- package/dist/internal/url-redaction.d.cts.map +1 -0
- package/dist/internal/url-redaction.d.ts +17 -0
- package/dist/internal/url-redaction.d.ts.map +1 -0
- package/dist/internal/url-redaction.js +31 -0
- package/dist/internal/url-redaction.js.map +1 -0
- package/dist/notifications/index.cjs +4 -6
- package/dist/notifications/index.d.cts +1 -1
- package/dist/notifications/index.d.cts.map +1 -1
- package/dist/notifications/index.d.ts +1 -1
- package/dist/notifications/index.d.ts.map +1 -1
- package/dist/notifications/index.js +1 -6
- package/dist/notifications/webhook.cjs +195 -85
- package/dist/notifications/webhook.cjs.map +1 -1
- package/dist/notifications/webhook.d.cts.map +1 -1
- package/dist/notifications/webhook.d.ts.map +1 -1
- package/dist/notifications/webhook.js +195 -87
- package/dist/notifications/webhook.js.map +1 -1
- package/dist/object.cjs +253 -210
- package/dist/object.cjs.map +1 -1
- package/dist/object.d.cts +9 -55
- package/dist/object.d.cts.map +1 -1
- package/dist/object.d.ts +9 -55
- package/dist/object.d.ts.map +1 -1
- package/dist/object.js +249 -206
- package/dist/object.js.map +1 -1
- package/dist/raw/encoding.cjs +74 -35
- package/dist/raw/encoding.cjs.map +1 -1
- package/dist/raw/encoding.js +74 -38
- package/dist/raw/encoding.js.map +1 -1
- package/dist/raw/index.cjs +678 -587
- package/dist/raw/index.cjs.map +1 -1
- package/dist/raw/index.d.cts +121 -18
- package/dist/raw/index.d.cts.map +1 -1
- package/dist/raw/index.d.ts +121 -18
- package/dist/raw/index.d.ts.map +1 -1
- package/dist/raw/index.js +674 -589
- package/dist/raw/index.js.map +1 -1
- package/dist/s3/index.cjs +355 -18
- package/dist/s3/index.cjs.map +1 -1
- package/dist/s3/index.d.cts +233 -5
- package/dist/s3/index.d.cts.map +1 -1
- package/dist/s3/index.d.ts +233 -5
- package/dist/s3/index.d.ts.map +1 -1
- package/dist/s3/index.js +351 -22
- package/dist/s3/index.js.map +1 -1
- package/dist/s3/sigv4.cjs +149 -0
- package/dist/s3/sigv4.cjs.map +1 -0
- package/dist/s3/sigv4.d.cts +43 -0
- package/dist/s3/sigv4.d.cts.map +1 -0
- package/dist/s3/sigv4.d.ts +43 -0
- package/dist/s3/sigv4.d.ts.map +1 -0
- package/dist/s3/sigv4.js +148 -0
- package/dist/s3/sigv4.js.map +1 -0
- package/dist/s3/validation.cjs +69 -0
- package/dist/s3/validation.cjs.map +1 -0
- package/dist/s3/validation.d.cts +43 -0
- package/dist/s3/validation.d.cts.map +1 -0
- package/dist/s3/validation.d.ts +43 -0
- package/dist/s3/validation.d.ts.map +1 -0
- package/dist/s3/validation.js +66 -0
- package/dist/s3/validation.js.map +1 -0
- package/dist/simulator/capabilities.cjs +63 -48
- package/dist/simulator/capabilities.cjs.map +1 -1
- package/dist/simulator/capabilities.js +63 -49
- package/dist/simulator/capabilities.js.map +1 -1
- package/dist/simulator/index.cjs +2124 -1548
- package/dist/simulator/index.cjs.map +1 -1
- package/dist/simulator/index.d.cts +79 -11
- package/dist/simulator/index.d.cts.map +1 -1
- package/dist/simulator/index.d.ts +79 -11
- package/dist/simulator/index.d.ts.map +1 -1
- package/dist/simulator/index.js +2112 -1546
- package/dist/simulator/index.js.map +1 -1
- package/dist/simulator/validation.cjs +191 -153
- package/dist/simulator/validation.cjs.map +1 -1
- package/dist/simulator/validation.d.cts +3 -21
- package/dist/simulator/validation.d.cts.map +1 -1
- package/dist/simulator/validation.d.ts +3 -21
- package/dist/simulator/validation.d.ts.map +1 -1
- package/dist/simulator/validation.js +188 -162
- package/dist/simulator/validation.js.map +1 -1
- package/dist/streams/collect.cjs +74 -24
- package/dist/streams/collect.cjs.map +1 -1
- package/dist/streams/collect.d.cts +14 -1
- package/dist/streams/collect.d.cts.map +1 -1
- package/dist/streams/collect.d.ts +14 -1
- package/dist/streams/collect.d.ts.map +1 -1
- package/dist/streams/collect.js +74 -25
- package/dist/streams/collect.js.map +1 -1
- package/dist/streams/file-source.cjs +287 -0
- package/dist/streams/file-source.cjs.map +1 -0
- package/dist/streams/file-source.d.cts +96 -0
- package/dist/streams/file-source.d.cts.map +1 -0
- package/dist/streams/file-source.d.ts +96 -0
- package/dist/streams/file-source.d.ts.map +1 -0
- package/dist/streams/file-source.js +286 -0
- package/dist/streams/file-source.js.map +1 -0
- package/dist/streams/hash.cjs +207 -115
- package/dist/streams/hash.cjs.map +1 -1
- package/dist/streams/hash.d.cts +5 -4
- package/dist/streams/hash.d.cts.map +1 -1
- package/dist/streams/hash.d.ts +5 -4
- package/dist/streams/hash.d.ts.map +1 -1
- package/dist/streams/hash.js +208 -95
- package/dist/streams/hash.js.map +1 -1
- package/dist/streams/index.cjs +12 -12
- package/dist/streams/index.d.cts +3 -3
- package/dist/streams/index.d.cts.map +1 -1
- package/dist/streams/index.d.ts +3 -3
- package/dist/streams/index.d.ts.map +1 -1
- package/dist/streams/index.js +2 -10
- package/dist/streams/progress.cjs +60 -46
- package/dist/streams/progress.cjs.map +1 -1
- package/dist/streams/progress.js +60 -46
- package/dist/streams/progress.js.map +1 -1
- package/dist/streams/source.cjs +316 -146
- package/dist/streams/source.cjs.map +1 -1
- package/dist/streams/source.d.cts +56 -18
- package/dist/streams/source.d.cts.map +1 -1
- package/dist/streams/source.d.ts +56 -18
- package/dist/streams/source.d.ts.map +1 -1
- package/dist/streams/source.js +312 -149
- package/dist/streams/source.js.map +1 -1
- package/dist/sync/actions/index.cjs +236 -184
- package/dist/sync/actions/index.cjs.map +1 -1
- package/dist/sync/actions/index.d.cts +29 -21
- package/dist/sync/actions/index.d.cts.map +1 -1
- package/dist/sync/actions/index.d.ts +29 -21
- package/dist/sync/actions/index.d.ts.map +1 -1
- package/dist/sync/actions/index.js +236 -190
- package/dist/sync/actions/index.js.map +1 -1
- package/dist/sync/b2-sha1-reader.cjs +148 -0
- package/dist/sync/b2-sha1-reader.cjs.map +1 -0
- package/dist/sync/b2-sha1-reader.d.cts +58 -0
- package/dist/sync/b2-sha1-reader.d.cts.map +1 -0
- package/dist/sync/b2-sha1-reader.d.ts +58 -0
- package/dist/sync/b2-sha1-reader.d.ts.map +1 -0
- package/dist/sync/b2-sha1-reader.js +145 -0
- package/dist/sync/b2-sha1-reader.js.map +1 -0
- package/dist/sync/download-staging.cjs +265 -0
- package/dist/sync/download-staging.cjs.map +1 -0
- package/dist/sync/download-staging.d.cts +54 -0
- package/dist/sync/download-staging.d.cts.map +1 -0
- package/dist/sync/download-staging.d.ts +54 -0
- package/dist/sync/download-staging.d.ts.map +1 -0
- package/dist/sync/download-staging.js +259 -0
- package/dist/sync/download-staging.js.map +1 -0
- package/dist/sync/filesystem-errors.cjs +32 -0
- package/dist/sync/filesystem-errors.cjs.map +1 -0
- package/dist/sync/filesystem-errors.d.cts +8 -0
- package/dist/sync/filesystem-errors.d.cts.map +1 -0
- package/dist/sync/filesystem-errors.d.ts +8 -0
- package/dist/sync/filesystem-errors.d.ts.map +1 -0
- package/dist/sync/filesystem-errors.js +32 -0
- package/dist/sync/filesystem-errors.js.map +1 -0
- package/dist/sync/filters.cjs +217 -0
- package/dist/sync/filters.cjs.map +1 -0
- package/dist/sync/filters.d.cts +51 -0
- package/dist/sync/filters.d.cts.map +1 -0
- package/dist/sync/filters.d.ts +51 -0
- package/dist/sync/filters.d.ts.map +1 -0
- package/dist/sync/filters.js +213 -0
- package/dist/sync/filters.js.map +1 -0
- package/dist/sync/index.cjs +39 -22
- package/dist/sync/index.d.cts +14 -9
- package/dist/sync/index.d.cts.map +1 -1
- package/dist/sync/index.d.ts +14 -9
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/index.js +9 -20
- package/dist/sync/local-file-identity.cjs +61 -0
- package/dist/sync/local-file-identity.cjs.map +1 -0
- package/dist/sync/local-file-identity.d.cts +37 -0
- package/dist/sync/local-file-identity.d.cts.map +1 -0
- package/dist/sync/local-file-identity.d.ts +37 -0
- package/dist/sync/local-file-identity.d.ts.map +1 -0
- package/dist/sync/local-file-identity.js +60 -0
- package/dist/sync/local-file-identity.js.map +1 -0
- package/dist/sync/local-file-io.cjs +364 -0
- package/dist/sync/local-file-io.cjs.map +1 -0
- package/dist/sync/local-file-io.d.cts +75 -0
- package/dist/sync/local-file-io.d.cts.map +1 -0
- package/dist/sync/local-file-io.d.ts +75 -0
- package/dist/sync/local-file-io.d.ts.map +1 -0
- package/dist/sync/local-file-io.js +360 -0
- package/dist/sync/local-file-io.js.map +1 -0
- package/dist/sync/local-filesystem-root.cjs +27 -0
- package/dist/sync/local-filesystem-root.cjs.map +1 -0
- package/dist/sync/local-filesystem-root.d.cts +18 -0
- package/dist/sync/local-filesystem-root.d.cts.map +1 -0
- package/dist/sync/local-filesystem-root.d.ts +18 -0
- package/dist/sync/local-filesystem-root.d.ts.map +1 -0
- package/dist/sync/local-filesystem-root.js +26 -0
- package/dist/sync/local-filesystem-root.js.map +1 -0
- package/dist/sync/local-sha1.cjs +119 -0
- package/dist/sync/local-sha1.cjs.map +1 -0
- package/dist/sync/local-sha1.d.cts +39 -0
- package/dist/sync/local-sha1.d.cts.map +1 -0
- package/dist/sync/local-sha1.d.ts +39 -0
- package/dist/sync/local-sha1.d.ts.map +1 -0
- package/dist/sync/local-sha1.js +117 -0
- package/dist/sync/local-sha1.js.map +1 -0
- package/dist/sync/pairing.cjs +118 -29
- package/dist/sync/pairing.cjs.map +1 -1
- package/dist/sync/pairing.d.cts +7 -2
- package/dist/sync/pairing.d.cts.map +1 -1
- package/dist/sync/pairing.d.ts +7 -2
- package/dist/sync/pairing.d.ts.map +1 -1
- package/dist/sync/pairing.js +120 -31
- package/dist/sync/pairing.js.map +1 -1
- package/dist/sync/path-order.cjs +30 -0
- package/dist/sync/path-order.cjs.map +1 -0
- package/dist/sync/path-order.d.cts +28 -0
- package/dist/sync/path-order.d.cts.map +1 -0
- package/dist/sync/path-order.d.ts +28 -0
- package/dist/sync/path-order.d.ts.map +1 -0
- package/dist/sync/path-order.js +29 -0
- package/dist/sync/path-order.js.map +1 -0
- package/dist/sync/path-safety.cjs +111 -0
- package/dist/sync/path-safety.cjs.map +1 -0
- package/dist/sync/path-safety.d.cts +78 -0
- package/dist/sync/path-safety.d.cts.map +1 -0
- package/dist/sync/path-safety.d.ts +78 -0
- package/dist/sync/path-safety.d.ts.map +1 -0
- package/dist/sync/path-safety.js +105 -0
- package/dist/sync/path-safety.js.map +1 -0
- package/dist/sync/paths.d.cts +19 -0
- package/dist/sync/paths.d.cts.map +1 -0
- package/dist/sync/paths.d.ts +19 -0
- package/dist/sync/paths.d.ts.map +1 -0
- package/dist/sync/policies/compare.cjs +389 -11
- package/dist/sync/policies/compare.cjs.map +1 -1
- package/dist/sync/policies/compare.d.cts +100 -2
- package/dist/sync/policies/compare.d.cts.map +1 -1
- package/dist/sync/policies/compare.d.ts +100 -2
- package/dist/sync/policies/compare.d.ts.map +1 -1
- package/dist/sync/policies/compare.js +387 -13
- package/dist/sync/policies/compare.js.map +1 -1
- package/dist/sync/policies/index.cjs +76 -65
- package/dist/sync/policies/index.cjs.map +1 -1
- package/dist/sync/policies/index.d.cts +35 -6
- package/dist/sync/policies/index.d.cts.map +1 -1
- package/dist/sync/policies/index.d.ts +35 -6
- package/dist/sync/policies/index.d.ts.map +1 -1
- package/dist/sync/policies/index.js +76 -65
- package/dist/sync/policies/index.js.map +1 -1
- package/dist/sync/prefix.cjs +96 -0
- package/dist/sync/prefix.cjs.map +1 -0
- package/dist/sync/prefix.d.cts +55 -0
- package/dist/sync/prefix.d.cts.map +1 -0
- package/dist/sync/prefix.d.ts +55 -0
- package/dist/sync/prefix.d.ts.map +1 -0
- package/dist/sync/prefix.js +92 -0
- package/dist/sync/prefix.js.map +1 -0
- package/dist/sync/regexp-safety.cjs +192 -0
- package/dist/sync/regexp-safety.cjs.map +1 -0
- package/dist/sync/regexp-safety.d.cts +29 -0
- package/dist/sync/regexp-safety.d.cts.map +1 -0
- package/dist/sync/regexp-safety.d.ts +29 -0
- package/dist/sync/regexp-safety.d.ts.map +1 -0
- package/dist/sync/regexp-safety.js +190 -0
- package/dist/sync/regexp-safety.js.map +1 -0
- package/dist/sync/scan-events.cjs +33 -0
- package/dist/sync/scan-events.cjs.map +1 -0
- package/dist/sync/scan-events.d.cts +17 -0
- package/dist/sync/scan-events.d.cts.map +1 -0
- package/dist/sync/scan-events.d.ts +17 -0
- package/dist/sync/scan-events.d.ts.map +1 -0
- package/dist/sync/scan-events.js +32 -0
- package/dist/sync/scan-events.js.map +1 -0
- package/dist/sync/scan-limit.cjs +33 -0
- package/dist/sync/scan-limit.cjs.map +1 -0
- package/dist/sync/scan-limit.d.cts +21 -0
- package/dist/sync/scan-limit.d.cts.map +1 -0
- package/dist/sync/scan-limit.d.ts +21 -0
- package/dist/sync/scan-limit.d.ts.map +1 -0
- package/dist/sync/scan-limit.js +31 -0
- package/dist/sync/scan-limit.js.map +1 -0
- package/dist/sync/scanners/b2.cjs +239 -55
- package/dist/sync/scanners/b2.cjs.map +1 -1
- package/dist/sync/scanners/b2.d.cts +26 -7
- package/dist/sync/scanners/b2.d.cts.map +1 -1
- package/dist/sync/scanners/b2.d.ts +26 -7
- package/dist/sync/scanners/b2.d.ts.map +1 -1
- package/dist/sync/scanners/b2.js +239 -55
- package/dist/sync/scanners/b2.js.map +1 -1
- package/dist/sync/scanners/local.cjs +215 -56
- package/dist/sync/scanners/local.cjs.map +1 -1
- package/dist/sync/scanners/local.d.cts +22 -7
- package/dist/sync/scanners/local.d.cts.map +1 -1
- package/dist/sync/scanners/local.d.ts +22 -7
- package/dist/sync/scanners/local.d.ts.map +1 -1
- package/dist/sync/scanners/local.js +216 -57
- package/dist/sync/scanners/local.js.map +1 -1
- package/dist/sync/sha1-metadata.cjs +94 -0
- package/dist/sync/sha1-metadata.cjs.map +1 -0
- package/dist/sync/sha1-metadata.d.cts +82 -0
- package/dist/sync/sha1-metadata.d.cts.map +1 -0
- package/dist/sync/sha1-metadata.d.ts +82 -0
- package/dist/sync/sha1-metadata.d.ts.map +1 -0
- package/dist/sync/sha1-metadata.js +89 -0
- package/dist/sync/sha1-metadata.js.map +1 -0
- package/dist/sync/sha1-options.cjs +23 -0
- package/dist/sync/sha1-options.cjs.map +1 -0
- package/dist/sync/sha1-options.d.cts +14 -0
- package/dist/sync/sha1-options.d.cts.map +1 -0
- package/dist/sync/sha1-options.d.ts +14 -0
- package/dist/sync/sha1-options.d.ts.map +1 -0
- package/dist/sync/sha1-options.js +21 -0
- package/dist/sync/sha1-options.js.map +1 -0
- package/dist/sync/synchronizer.cjs +782 -197
- package/dist/sync/synchronizer.cjs.map +1 -1
- package/dist/sync/synchronizer.d.cts +47 -1
- package/dist/sync/synchronizer.d.cts.map +1 -1
- package/dist/sync/synchronizer.d.ts +47 -1
- package/dist/sync/synchronizer.d.ts.map +1 -1
- package/dist/sync/synchronizer.js +779 -173
- package/dist/sync/synchronizer.js.map +1 -1
- package/dist/sync/types.d.cts +208 -16
- package/dist/sync/types.d.cts.map +1 -1
- package/dist/sync/types.d.ts +208 -16
- package/dist/sync/types.d.ts.map +1 -1
- package/dist/types/auth.cjs +76 -56
- package/dist/types/auth.cjs.map +1 -1
- package/dist/types/auth.d.cts +67 -9
- package/dist/types/auth.d.cts.map +1 -1
- package/dist/types/auth.d.ts +67 -9
- package/dist/types/auth.d.ts.map +1 -1
- package/dist/types/auth.js +77 -57
- package/dist/types/auth.js.map +1 -1
- package/dist/types/bucket.cjs +74 -38
- package/dist/types/bucket.cjs.map +1 -1
- package/dist/types/bucket.js +75 -41
- package/dist/types/bucket.js.map +1 -1
- package/dist/types/encryption.cjs +364 -327
- package/dist/types/encryption.cjs.map +1 -1
- package/dist/types/encryption.d.cts +16 -0
- package/dist/types/encryption.d.cts.map +1 -1
- package/dist/types/encryption.d.ts +16 -0
- package/dist/types/encryption.d.ts.map +1 -1
- package/dist/types/encryption.js +364 -310
- package/dist/types/encryption.js.map +1 -1
- package/dist/types/errors.cjs +47 -0
- package/dist/types/errors.cjs.map +1 -0
- package/dist/types/errors.d.cts +13 -4
- package/dist/types/errors.d.cts.map +1 -1
- package/dist/types/errors.d.ts +13 -4
- package/dist/types/errors.d.ts.map +1 -1
- package/dist/types/errors.js +47 -0
- package/dist/types/errors.js.map +1 -0
- package/dist/types/file.cjs +36 -19
- package/dist/types/file.cjs.map +1 -1
- package/dist/types/file.d.cts +2 -2
- package/dist/types/file.d.cts.map +1 -1
- package/dist/types/file.d.ts +2 -2
- package/dist/types/file.d.ts.map +1 -1
- package/dist/types/file.js +37 -21
- package/dist/types/file.js.map +1 -1
- package/dist/types/ids.cjs +53 -9
- package/dist/types/ids.cjs.map +1 -1
- package/dist/types/ids.js +54 -15
- package/dist/types/ids.js.map +1 -1
- package/dist/types/index.d.cts +12 -11
- package/dist/types/index.d.cts.map +1 -1
- package/dist/types/index.d.ts +12 -11
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/key.d.cts +44 -8
- package/dist/types/key.d.cts.map +1 -1
- package/dist/types/key.d.ts +44 -8
- package/dist/types/key.d.ts.map +1 -1
- package/dist/types/lock.cjs +33 -13
- package/dist/types/lock.cjs.map +1 -1
- package/dist/types/lock.js +34 -15
- package/dist/types/lock.js.map +1 -1
- package/dist/types/notifications.cjs +44 -22
- package/dist/types/notifications.cjs.map +1 -1
- package/dist/types/notifications.js +45 -23
- package/dist/types/notifications.js.map +1 -1
- package/dist/types/upload.d.cts +39 -5
- package/dist/types/upload.d.cts.map +1 -1
- package/dist/types/upload.d.ts +39 -5
- package/dist/types/upload.d.ts.map +1 -1
- package/dist/upload/abort-scope.cjs +91 -0
- package/dist/upload/abort-scope.cjs.map +1 -0
- package/dist/upload/abort-scope.d.cts +48 -0
- package/dist/upload/abort-scope.d.cts.map +1 -0
- package/dist/upload/abort-scope.d.ts +48 -0
- package/dist/upload/abort-scope.d.ts.map +1 -0
- package/dist/upload/abort-scope.js +88 -0
- package/dist/upload/abort-scope.js.map +1 -0
- package/dist/upload/cancel.cjs +183 -8
- package/dist/upload/cancel.cjs.map +1 -1
- package/dist/upload/cancel.d.cts +110 -2
- package/dist/upload/cancel.d.cts.map +1 -1
- package/dist/upload/cancel.d.ts +110 -2
- package/dist/upload/cancel.d.ts.map +1 -1
- package/dist/upload/cancel.js +178 -9
- package/dist/upload/cancel.js.map +1 -1
- package/dist/upload/concurrency.cjs +79 -52
- package/dist/upload/concurrency.cjs.map +1 -1
- package/dist/upload/concurrency.js +79 -53
- package/dist/upload/concurrency.js.map +1 -1
- package/dist/upload/finish.cjs +59 -0
- package/dist/upload/finish.cjs.map +1 -0
- package/dist/upload/finish.d.cts +26 -0
- package/dist/upload/finish.d.cts.map +1 -0
- package/dist/upload/finish.d.ts +26 -0
- package/dist/upload/finish.d.ts.map +1 -0
- package/dist/upload/finish.js +59 -0
- package/dist/upload/finish.js.map +1 -0
- package/dist/upload/large.cjs +301 -218
- package/dist/upload/large.cjs.map +1 -1
- package/dist/upload/large.d.cts +76 -9
- package/dist/upload/large.d.cts.map +1 -1
- package/dist/upload/large.d.ts +76 -9
- package/dist/upload/large.d.ts.map +1 -1
- package/dist/upload/large.js +301 -218
- package/dist/upload/large.js.map +1 -1
- package/dist/upload/options.cjs +28 -0
- package/dist/upload/options.cjs.map +1 -0
- package/dist/upload/options.d.cts +104 -0
- package/dist/upload/options.d.cts.map +1 -0
- package/dist/upload/options.d.ts +104 -0
- package/dist/upload/options.d.ts.map +1 -0
- package/dist/upload/options.js +27 -0
- package/dist/upload/options.js.map +1 -0
- package/dist/upload/resume.cjs +333 -33
- package/dist/upload/resume.cjs.map +1 -1
- package/dist/upload/resume.d.cts +82 -12
- package/dist/upload/resume.d.cts.map +1 -1
- package/dist/upload/resume.d.ts +82 -12
- package/dist/upload/resume.d.ts.map +1 -1
- package/dist/upload/resume.js +330 -33
- package/dist/upload/resume.js.map +1 -1
- package/dist/upload/retry.cjs +186 -0
- package/dist/upload/retry.cjs.map +1 -0
- package/dist/upload/retry.d.cts +127 -0
- package/dist/upload/retry.d.cts.map +1 -0
- package/dist/upload/retry.d.ts +127 -0
- package/dist/upload/retry.d.ts.map +1 -0
- package/dist/upload/retry.js +182 -0
- package/dist/upload/retry.js.map +1 -0
- package/dist/upload/single.cjs +68 -44
- package/dist/upload/single.cjs.map +1 -1
- package/dist/upload/single.d.cts +2 -1
- package/dist/upload/single.d.cts.map +1 -1
- package/dist/upload/single.d.ts +2 -1
- package/dist/upload/single.d.ts.map +1 -1
- package/dist/upload/single.js +68 -44
- package/dist/upload/single.js.map +1 -1
- package/dist/upload/stream.cjs +317 -193
- package/dist/upload/stream.cjs.map +1 -1
- package/dist/upload/stream.d.cts +3 -1
- package/dist/upload/stream.d.cts.map +1 -1
- package/dist/upload/stream.d.ts +3 -1
- package/dist/upload/stream.d.ts.map +1 -1
- package/dist/upload/stream.js +316 -192
- package/dist/upload/stream.js.map +1 -1
- package/dist/util/best-effort.cjs +42 -8
- package/dist/util/best-effort.cjs.map +1 -1
- package/dist/util/best-effort.d.cts +2 -1
- package/dist/util/best-effort.d.cts.map +1 -1
- package/dist/util/best-effort.d.ts +2 -1
- package/dist/util/best-effort.d.ts.map +1 -1
- package/dist/util/best-effort.js +43 -9
- package/dist/util/best-effort.js.map +1 -1
- package/dist/util/bytes.cjs +23 -0
- package/dist/util/bytes.cjs.map +1 -0
- package/dist/util/bytes.d.cts +15 -0
- package/dist/util/bytes.d.cts.map +1 -0
- package/dist/util/bytes.d.ts +15 -0
- package/dist/util/bytes.d.ts.map +1 -0
- package/dist/util/bytes.js +23 -0
- package/dist/util/bytes.js.map +1 -0
- package/dist/util/crypto.cjs +68 -0
- package/dist/util/crypto.cjs.map +1 -0
- package/dist/util/crypto.d.cts +26 -0
- package/dist/util/crypto.d.cts.map +1 -0
- package/dist/util/crypto.d.ts +26 -0
- package/dist/util/crypto.d.ts.map +1 -0
- package/dist/util/crypto.js +66 -0
- package/dist/util/crypto.js.map +1 -0
- package/dist/util/defaults.cjs +25 -9
- package/dist/util/defaults.cjs.map +1 -1
- package/dist/util/defaults.js +26 -11
- package/dist/util/defaults.js.map +1 -1
- package/dist/util/error-reason.cjs +41 -0
- package/dist/util/error-reason.cjs.map +1 -0
- package/dist/util/error-reason.d.cts +9 -0
- package/dist/util/error-reason.d.cts.map +1 -0
- package/dist/util/error-reason.d.ts +9 -0
- package/dist/util/error-reason.d.ts.map +1 -0
- package/dist/util/error-reason.js +41 -0
- package/dist/util/error-reason.js.map +1 -0
- package/dist/util/http.cjs +23 -0
- package/dist/util/http.cjs.map +1 -0
- package/dist/util/http.d.cts +13 -0
- package/dist/util/http.d.cts.map +1 -0
- package/dist/util/http.d.ts +13 -0
- package/dist/util/http.d.ts.map +1 -0
- package/dist/util/http.js +23 -0
- package/dist/util/http.js.map +1 -0
- package/dist/util/normalize.cjs +66 -7
- package/dist/util/normalize.cjs.map +1 -1
- package/dist/util/normalize.js +67 -10
- package/dist/util/normalize.js.map +1 -1
- package/dist/util/paginator.cjs +63 -14
- package/dist/util/paginator.cjs.map +1 -1
- package/dist/util/paginator.js +64 -16
- package/dist/util/paginator.js.map +1 -1
- package/dist/util/plan-ranges.cjs +47 -22
- package/dist/util/plan-ranges.cjs.map +1 -1
- package/dist/util/plan-ranges.js +48 -24
- package/dist/util/plan-ranges.js.map +1 -1
- package/dist/util/sha1.cjs +27 -0
- package/dist/util/sha1.cjs.map +1 -0
- package/dist/util/sha1.d.cts +17 -0
- package/dist/util/sha1.d.cts.map +1 -0
- package/dist/util/sha1.d.ts +17 -0
- package/dist/util/sha1.d.ts.map +1 -0
- package/dist/util/sha1.js +26 -0
- package/dist/util/sha1.js.map +1 -0
- package/dist/util/text-codec.cjs +29 -5
- package/dist/util/text-codec.cjs.map +1 -1
- package/dist/util/text-codec.js +30 -7
- package/dist/util/text-codec.js.map +1 -1
- package/dist/util/to-error.cjs +18 -4
- package/dist/util/to-error.cjs.map +1 -1
- package/dist/util/to-error.js +19 -5
- package/dist/util/to-error.js.map +1 -1
- package/dist/version.cjs +17 -5
- package/dist/version.cjs.map +1 -1
- package/dist/version.d.cts +3 -3
- package/dist/version.d.ts +3 -3
- package/dist/version.js +19 -6
- package/dist/version.js.map +1 -1
- package/package.json +19 -16
- package/dist/auth/index.cjs.map +0 -1
- package/dist/auth/index.js.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/notifications/index.cjs.map +0 -1
- package/dist/notifications/index.js.map +0 -1
- package/dist/package.json.cjs +0 -9
- package/dist/package.json.cjs.map +0 -1
- package/dist/package.json.js +0 -9
- package/dist/package.json.js.map +0 -1
- package/dist/streams/index.cjs.map +0 -1
- package/dist/streams/index.js.map +0 -1
- package/dist/sync/index.cjs.map +0 -1
- 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"}
|
package/dist/sync/pairing.cjs
CHANGED
|
@@ -1,31 +1,120 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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
|
-
|
|
119
|
+
|
|
120
|
+
//# sourceMappingURL=pairing.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pairing.cjs","sources":["../../src/sync/pairing.ts"],"sourcesContent":["import
|
|
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"}
|
package/dist/sync/pairing.d.cts
CHANGED
|
@@ -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
|
|
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":"
|
|
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"}
|
package/dist/sync/pairing.d.ts
CHANGED
|
@@ -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
|
|
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":"
|
|
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"}
|