@backblaze-labs/b2-sdk 0.2.0 → 0.4.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 +86 -1
- package/README.md +38 -7
- package/dist/_virtual/_b2-sdk-version-json.cjs +1 -1
- package/dist/_virtual/_b2-sdk-version-json.js +1 -1
- package/dist/auth/file.cjs.map +1 -1
- package/dist/auth/reauth-coalescer.cjs +65 -0
- package/dist/auth/reauth-coalescer.cjs.map +1 -0
- package/dist/auth/reauth-coalescer.d.cts +34 -0
- package/dist/auth/reauth-coalescer.d.cts.map +1 -0
- package/dist/auth/reauth-coalescer.d.ts +34 -0
- package/dist/auth/reauth-coalescer.d.ts.map +1 -0
- package/dist/auth/reauth-coalescer.js +65 -0
- package/dist/auth/reauth-coalescer.js.map +1 -0
- package/dist/backup/client.cjs +206 -0
- package/dist/backup/client.cjs.map +1 -0
- package/dist/backup/client.d.cts +238 -0
- package/dist/backup/client.d.cts.map +1 -0
- package/dist/backup/client.d.ts +238 -0
- package/dist/backup/client.d.ts.map +1 -0
- package/dist/backup/client.js +206 -0
- package/dist/backup/client.js.map +1 -0
- package/dist/backup/index.cjs +15 -0
- package/dist/backup/index.d.cts +22 -0
- package/dist/backup/index.d.cts.map +1 -0
- package/dist/backup/index.d.ts +22 -0
- package/dist/backup/index.d.ts.map +1 -0
- package/dist/backup/index.js +7 -0
- package/dist/backup/raw.cjs +168 -0
- package/dist/backup/raw.cjs.map +1 -0
- package/dist/backup/raw.d.cts +122 -0
- package/dist/backup/raw.d.cts.map +1 -0
- package/dist/backup/raw.d.ts +122 -0
- package/dist/backup/raw.d.ts.map +1 -0
- package/dist/backup/raw.js +168 -0
- package/dist/backup/raw.js.map +1 -0
- package/dist/bucket-validation.cjs +111 -0
- package/dist/bucket-validation.cjs.map +1 -0
- package/dist/bucket-validation.d.cts +27 -0
- package/dist/bucket-validation.d.cts.map +1 -0
- package/dist/bucket-validation.d.ts +27 -0
- package/dist/bucket-validation.d.ts.map +1 -0
- package/dist/bucket-validation.js +109 -0
- package/dist/bucket-validation.js.map +1 -0
- package/dist/bucket.cjs +125 -74
- package/dist/bucket.cjs.map +1 -1
- package/dist/bucket.d.cts +156 -61
- package/dist/bucket.d.cts.map +1 -1
- package/dist/bucket.d.ts +156 -61
- package/dist/bucket.d.ts.map +1 -1
- package/dist/bucket.js +125 -74
- package/dist/bucket.js.map +1 -1
- package/dist/client.cjs +29 -8
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +30 -9
- package/dist/client.d.cts.map +1 -1
- package/dist/client.d.ts +30 -9
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +29 -8
- package/dist/client.js.map +1 -1
- package/dist/copy/large.cjs +5 -3
- package/dist/copy/large.cjs.map +1 -1
- package/dist/copy/large.d.cts.map +1 -1
- package/dist/copy/large.d.ts.map +1 -1
- package/dist/copy/large.js +5 -3
- package/dist/copy/large.js.map +1 -1
- package/dist/download/checksum.cjs +6 -2
- package/dist/download/checksum.cjs.map +1 -1
- package/dist/download/checksum.js +6 -2
- package/dist/download/checksum.js.map +1 -1
- package/dist/download/parallel.cjs +52 -15
- package/dist/download/parallel.cjs.map +1 -1
- package/dist/download/parallel.d.cts +8 -1
- package/dist/download/parallel.d.cts.map +1 -1
- package/dist/download/parallel.d.ts +8 -1
- package/dist/download/parallel.d.ts.map +1 -1
- package/dist/download/parallel.js +52 -15
- package/dist/download/parallel.js.map +1 -1
- package/dist/download/single.cjs +179 -19
- package/dist/download/single.cjs.map +1 -1
- package/dist/download/single.d.cts +10 -4
- package/dist/download/single.d.cts.map +1 -1
- package/dist/download/single.d.ts +10 -4
- package/dist/download/single.d.ts.map +1 -1
- package/dist/download/single.js +179 -19
- package/dist/download/single.js.map +1 -1
- package/dist/errors/index.cjs +196 -3
- package/dist/errors/index.cjs.map +1 -1
- package/dist/errors/index.d.cts +134 -0
- package/dist/errors/index.d.cts.map +1 -1
- package/dist/errors/index.d.ts +134 -0
- package/dist/errors/index.d.ts.map +1 -1
- package/dist/errors/index.js +183 -4
- package/dist/errors/index.js.map +1 -1
- package/dist/http/non-idempotent-mutations.cjs +38 -0
- package/dist/http/non-idempotent-mutations.cjs.map +1 -0
- package/dist/http/non-idempotent-mutations.d.cts +25 -0
- package/dist/http/non-idempotent-mutations.d.cts.map +1 -0
- package/dist/http/non-idempotent-mutations.d.ts +25 -0
- package/dist/http/non-idempotent-mutations.d.ts.map +1 -0
- package/dist/http/non-idempotent-mutations.js +35 -0
- package/dist/http/non-idempotent-mutations.js.map +1 -0
- package/dist/http/retry.cjs +1 -1
- package/dist/http/retry.cjs.map +1 -1
- package/dist/http/retry.js +1 -1
- package/dist/http/retry.js.map +1 -1
- package/dist/http/transport.cjs +62 -23
- package/dist/http/transport.cjs.map +1 -1
- package/dist/http/transport.d.cts +30 -3
- package/dist/http/transport.d.cts.map +1 -1
- package/dist/http/transport.d.ts +30 -3
- package/dist/http/transport.d.ts.map +1 -1
- package/dist/http/transport.js +60 -22
- package/dist/http/transport.js.map +1 -1
- package/dist/http/user-agent.cjs +12 -1
- package/dist/http/user-agent.cjs.map +1 -1
- package/dist/http/user-agent.d.cts +8 -0
- package/dist/http/user-agent.d.cts.map +1 -1
- package/dist/http/user-agent.d.ts +8 -0
- package/dist/http/user-agent.d.ts.map +1 -1
- package/dist/http/user-agent.js +13 -3
- package/dist/http/user-agent.js.map +1 -1
- package/dist/index.cjs +50 -2
- package/dist/index.d.cts +15 -12
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +15 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -10
- package/dist/notifications/index.cjs +3 -0
- package/dist/notifications/index.d.cts +2 -0
- package/dist/notifications/index.d.cts.map +1 -1
- package/dist/notifications/index.d.ts +2 -0
- package/dist/notifications/index.d.ts.map +1 -1
- package/dist/notifications/index.js +2 -1
- package/dist/object.cjs +13 -2
- package/dist/object.cjs.map +1 -1
- package/dist/object.d.cts +11 -3
- package/dist/object.d.cts.map +1 -1
- package/dist/object.d.ts +11 -3
- package/dist/object.d.ts.map +1 -1
- package/dist/object.js +13 -2
- package/dist/object.js.map +1 -1
- package/dist/partner/account-info.d.cts +43 -0
- package/dist/partner/account-info.d.cts.map +1 -0
- package/dist/partner/account-info.d.ts +43 -0
- package/dist/partner/account-info.d.ts.map +1 -0
- package/dist/partner/auth-clone.cjs +64 -0
- package/dist/partner/auth-clone.cjs.map +1 -0
- package/dist/partner/auth-clone.d.cts +27 -0
- package/dist/partner/auth-clone.d.cts.map +1 -0
- package/dist/partner/auth-clone.d.ts +27 -0
- package/dist/partner/auth-clone.d.ts.map +1 -0
- package/dist/partner/auth-clone.js +63 -0
- package/dist/partner/auth-clone.js.map +1 -0
- package/dist/partner/auth-core.cjs +156 -0
- package/dist/partner/auth-core.cjs.map +1 -0
- package/dist/partner/auth-core.d.cts +111 -0
- package/dist/partner/auth-core.d.cts.map +1 -0
- package/dist/partner/auth-core.d.ts +111 -0
- package/dist/partner/auth-core.d.ts.map +1 -0
- package/dist/partner/auth-core.js +156 -0
- package/dist/partner/auth-core.js.map +1 -0
- package/dist/partner/auth-shape.cjs +36 -0
- package/dist/partner/auth-shape.cjs.map +1 -0
- package/dist/partner/auth-shape.d.cts +12 -0
- package/dist/partner/auth-shape.d.cts.map +1 -0
- package/dist/partner/auth-shape.d.ts +12 -0
- package/dist/partner/auth-shape.d.ts.map +1 -0
- package/dist/partner/auth-shape.js +36 -0
- package/dist/partner/auth-shape.js.map +1 -0
- package/dist/partner/client.cjs +270 -0
- package/dist/partner/client.cjs.map +1 -0
- package/dist/partner/client.d.cts +357 -0
- package/dist/partner/client.d.cts.map +1 -0
- package/dist/partner/client.d.ts +357 -0
- package/dist/partner/client.d.ts.map +1 -0
- package/dist/partner/client.js +270 -0
- package/dist/partner/client.js.map +1 -0
- package/dist/partner/endpoint-url.cjs +109 -0
- package/dist/partner/endpoint-url.cjs.map +1 -0
- package/dist/partner/endpoint-url.d.cts +74 -0
- package/dist/partner/endpoint-url.d.cts.map +1 -0
- package/dist/partner/endpoint-url.d.ts +74 -0
- package/dist/partner/endpoint-url.d.ts.map +1 -0
- package/dist/partner/endpoint-url.js +106 -0
- package/dist/partner/endpoint-url.js.map +1 -0
- package/dist/partner/in-memory.cjs +135 -0
- package/dist/partner/in-memory.cjs.map +1 -0
- package/dist/partner/in-memory.d.cts +99 -0
- package/dist/partner/in-memory.d.cts.map +1 -0
- package/dist/partner/in-memory.d.ts +99 -0
- package/dist/partner/in-memory.d.ts.map +1 -0
- package/dist/partner/in-memory.js +135 -0
- package/dist/partner/in-memory.js.map +1 -0
- package/dist/partner/index.cjs +27 -0
- package/dist/partner/index.d.cts +32 -0
- package/dist/partner/index.d.cts.map +1 -0
- package/dist/partner/index.d.ts +32 -0
- package/dist/partner/index.d.ts.map +1 -0
- package/dist/partner/index.js +9 -0
- package/dist/partner/raw.cjs +400 -0
- package/dist/partner/raw.cjs.map +1 -0
- package/dist/partner/raw.d.cts +220 -0
- package/dist/partner/raw.d.cts.map +1 -0
- package/dist/partner/raw.d.ts +220 -0
- package/dist/partner/raw.d.ts.map +1 -0
- package/dist/partner/raw.js +398 -0
- package/dist/partner/raw.js.map +1 -0
- package/dist/partner/redaction-placeholders.cjs +10 -0
- package/dist/partner/redaction-placeholders.cjs.map +1 -0
- package/dist/partner/redaction-placeholders.d.cts +5 -0
- package/dist/partner/redaction-placeholders.d.cts.map +1 -0
- package/dist/partner/redaction-placeholders.d.ts +5 -0
- package/dist/partner/redaction-placeholders.d.ts.map +1 -0
- package/dist/partner/redaction-placeholders.js +9 -0
- package/dist/partner/redaction-placeholders.js.map +1 -0
- package/dist/partner/redaction.cjs +292 -0
- package/dist/partner/redaction.cjs.map +1 -0
- package/dist/partner/redaction.d.cts +158 -0
- package/dist/partner/redaction.d.cts.map +1 -0
- package/dist/partner/redaction.d.ts +158 -0
- package/dist/partner/redaction.d.ts.map +1 -0
- package/dist/partner/redaction.js +281 -0
- package/dist/partner/redaction.js.map +1 -0
- package/dist/raw/encoding.cjs +29 -10
- package/dist/raw/encoding.cjs.map +1 -1
- package/dist/raw/encoding.d.cts +3 -2
- package/dist/raw/encoding.d.cts.map +1 -1
- package/dist/raw/encoding.d.ts +3 -2
- package/dist/raw/encoding.d.ts.map +1 -1
- package/dist/raw/encoding.js +29 -10
- package/dist/raw/encoding.js.map +1 -1
- package/dist/raw/index.cjs +131 -44
- package/dist/raw/index.cjs.map +1 -1
- package/dist/raw/index.d.cts +21 -15
- package/dist/raw/index.d.cts.map +1 -1
- package/dist/raw/index.d.ts +21 -15
- package/dist/raw/index.d.ts.map +1 -1
- package/dist/raw/index.js +114 -45
- package/dist/raw/index.js.map +1 -1
- package/dist/raw/url.cjs +111 -0
- package/dist/raw/url.cjs.map +1 -0
- package/dist/raw/url.d.cts +41 -0
- package/dist/raw/url.d.cts.map +1 -0
- package/dist/raw/url.d.ts +41 -0
- package/dist/raw/url.d.ts.map +1 -0
- package/dist/raw/url.js +110 -0
- package/dist/raw/url.js.map +1 -0
- package/dist/s3/sigv4.cjs +15 -10
- package/dist/s3/sigv4.cjs.map +1 -1
- package/dist/s3/sigv4.js +15 -10
- package/dist/s3/sigv4.js.map +1 -1
- package/dist/simulator/index.cjs +1579 -257
- package/dist/simulator/index.cjs.map +1 -1
- package/dist/simulator/index.d.cts +124 -11
- package/dist/simulator/index.d.cts.map +1 -1
- package/dist/simulator/index.d.ts +124 -11
- package/dist/simulator/index.d.ts.map +1 -1
- package/dist/simulator/index.js +1568 -262
- package/dist/simulator/index.js.map +1 -1
- package/dist/simulator/partner-capabilities.cjs +77 -0
- package/dist/simulator/partner-capabilities.cjs.map +1 -0
- package/dist/simulator/partner-capabilities.d.cts +53 -0
- package/dist/simulator/partner-capabilities.d.cts.map +1 -0
- package/dist/simulator/partner-capabilities.d.ts +53 -0
- package/dist/simulator/partner-capabilities.d.ts.map +1 -0
- package/dist/simulator/partner-capabilities.js +73 -0
- package/dist/simulator/partner-capabilities.js.map +1 -0
- package/dist/simulator/partner.cjs +713 -0
- package/dist/simulator/partner.cjs.map +1 -0
- package/dist/simulator/partner.d.cts +186 -0
- package/dist/simulator/partner.d.cts.map +1 -0
- package/dist/simulator/partner.d.ts +186 -0
- package/dist/simulator/partner.d.ts.map +1 -0
- package/dist/simulator/partner.js +713 -0
- package/dist/simulator/partner.js.map +1 -0
- package/dist/simulator/validation.cjs +732 -25
- package/dist/simulator/validation.cjs.map +1 -1
- package/dist/simulator/validation.d.cts +145 -6
- package/dist/simulator/validation.d.cts.map +1 -1
- package/dist/simulator/validation.d.ts +145 -6
- package/dist/simulator/validation.d.ts.map +1 -1
- package/dist/simulator/validation.js +705 -26
- package/dist/simulator/validation.js.map +1 -1
- package/dist/streams/file-source.cjs +2 -2
- package/dist/streams/file-source.cjs.map +1 -1
- package/dist/streams/file-source.js +2 -2
- package/dist/streams/file-source.js.map +1 -1
- package/dist/streams/hash.cjs +246 -13
- package/dist/streams/hash.cjs.map +1 -1
- package/dist/streams/hash.d.cts +37 -12
- package/dist/streams/hash.d.cts.map +1 -1
- package/dist/streams/hash.d.ts +37 -12
- package/dist/streams/hash.d.ts.map +1 -1
- package/dist/streams/hash.js +246 -15
- package/dist/streams/hash.js.map +1 -1
- package/dist/streams/index.cjs +3 -1
- package/dist/streams/index.d.cts +1 -1
- package/dist/streams/index.d.cts.map +1 -1
- package/dist/streams/index.d.ts +1 -1
- package/dist/streams/index.d.ts.map +1 -1
- package/dist/streams/index.js +3 -3
- package/dist/streams/progress.cjs +63 -4
- package/dist/streams/progress.cjs.map +1 -1
- package/dist/streams/progress.d.cts +28 -2
- package/dist/streams/progress.d.cts.map +1 -1
- package/dist/streams/progress.d.ts +28 -2
- package/dist/streams/progress.d.ts.map +1 -1
- package/dist/streams/progress.js +63 -4
- package/dist/streams/progress.js.map +1 -1
- package/dist/streams/source.cjs +2 -1
- package/dist/streams/source.cjs.map +1 -1
- package/dist/streams/source.js +2 -1
- package/dist/streams/source.js.map +1 -1
- package/dist/sync/b2-sha1-reader.cjs +6 -2
- package/dist/sync/b2-sha1-reader.cjs.map +1 -1
- package/dist/sync/b2-sha1-reader.d.cts.map +1 -1
- package/dist/sync/b2-sha1-reader.d.ts.map +1 -1
- package/dist/sync/b2-sha1-reader.js +6 -2
- package/dist/sync/b2-sha1-reader.js.map +1 -1
- package/dist/sync/download-staging.cjs +156 -43
- package/dist/sync/download-staging.cjs.map +1 -1
- package/dist/sync/download-staging.d.cts +26 -2
- package/dist/sync/download-staging.d.cts.map +1 -1
- package/dist/sync/download-staging.d.ts +26 -2
- package/dist/sync/download-staging.d.ts.map +1 -1
- package/dist/sync/download-staging.js +155 -44
- package/dist/sync/download-staging.js.map +1 -1
- package/dist/sync/filters.cjs.map +1 -1
- package/dist/sync/filters.js.map +1 -1
- package/dist/sync/index.d.cts +1 -1
- package/dist/sync/index.d.cts.map +1 -1
- package/dist/sync/index.d.ts +1 -1
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/local-file-io.cjs +15 -6
- package/dist/sync/local-file-io.cjs.map +1 -1
- package/dist/sync/local-file-io.d.cts +3 -0
- package/dist/sync/local-file-io.d.cts.map +1 -1
- package/dist/sync/local-file-io.d.ts +3 -0
- package/dist/sync/local-file-io.d.ts.map +1 -1
- package/dist/sync/local-file-io.js +15 -6
- package/dist/sync/local-file-io.js.map +1 -1
- package/dist/sync/local-sha1.cjs +6 -15
- package/dist/sync/local-sha1.cjs.map +1 -1
- package/dist/sync/local-sha1.d.cts +0 -8
- package/dist/sync/local-sha1.d.cts.map +1 -1
- package/dist/sync/local-sha1.d.ts +0 -8
- package/dist/sync/local-sha1.d.ts.map +1 -1
- package/dist/sync/local-sha1.js +7 -15
- package/dist/sync/local-sha1.js.map +1 -1
- package/dist/sync/pairing.cjs +1 -0
- package/dist/sync/pairing.cjs.map +1 -1
- package/dist/sync/pairing.js +1 -0
- package/dist/sync/pairing.js.map +1 -1
- package/dist/sync/policies/compare.cjs +5 -3
- package/dist/sync/policies/compare.cjs.map +1 -1
- package/dist/sync/policies/compare.d.cts.map +1 -1
- package/dist/sync/policies/compare.d.ts.map +1 -1
- package/dist/sync/policies/compare.js +6 -4
- package/dist/sync/policies/compare.js.map +1 -1
- package/dist/sync/policies/index.cjs +4 -10
- package/dist/sync/policies/index.cjs.map +1 -1
- package/dist/sync/policies/index.js +4 -10
- package/dist/sync/policies/index.js.map +1 -1
- package/dist/sync/scanners/b2.cjs +4 -2
- package/dist/sync/scanners/b2.cjs.map +1 -1
- package/dist/sync/scanners/b2.d.cts.map +1 -1
- package/dist/sync/scanners/b2.d.ts.map +1 -1
- package/dist/sync/scanners/b2.js +4 -2
- package/dist/sync/scanners/b2.js.map +1 -1
- package/dist/sync/scanners/local.cjs +150 -33
- package/dist/sync/scanners/local.cjs.map +1 -1
- package/dist/sync/scanners/local.d.cts +6 -0
- package/dist/sync/scanners/local.d.cts.map +1 -1
- package/dist/sync/scanners/local.d.ts +6 -0
- package/dist/sync/scanners/local.d.ts.map +1 -1
- package/dist/sync/scanners/local.js +150 -33
- package/dist/sync/scanners/local.js.map +1 -1
- package/dist/sync/synchronizer.cjs +79 -31
- package/dist/sync/synchronizer.cjs.map +1 -1
- package/dist/sync/synchronizer.d.cts +1 -0
- package/dist/sync/synchronizer.d.cts.map +1 -1
- package/dist/sync/synchronizer.d.ts +1 -0
- package/dist/sync/synchronizer.d.ts.map +1 -1
- package/dist/sync/synchronizer.js +79 -31
- package/dist/sync/synchronizer.js.map +1 -1
- package/dist/sync/types.d.cts +19 -3
- package/dist/sync/types.d.cts.map +1 -1
- package/dist/sync/types.d.ts +19 -3
- package/dist/sync/types.d.ts.map +1 -1
- package/dist/types/auth.cjs +4 -0
- package/dist/types/auth.cjs.map +1 -1
- package/dist/types/auth.d.cts +4 -0
- package/dist/types/auth.d.cts.map +1 -1
- package/dist/types/auth.d.ts +4 -0
- package/dist/types/auth.d.ts.map +1 -1
- package/dist/types/auth.js +4 -0
- package/dist/types/auth.js.map +1 -1
- package/dist/types/backup.d.cts +85 -0
- package/dist/types/backup.d.cts.map +1 -0
- package/dist/types/backup.d.ts +85 -0
- package/dist/types/backup.d.ts.map +1 -0
- package/dist/types/bucket.cjs +81 -11
- package/dist/types/bucket.cjs.map +1 -1
- package/dist/types/bucket.d.cts +194 -41
- package/dist/types/bucket.d.cts.map +1 -1
- package/dist/types/bucket.d.ts +194 -41
- package/dist/types/bucket.d.ts.map +1 -1
- package/dist/types/bucket.js +67 -12
- package/dist/types/bucket.js.map +1 -1
- package/dist/types/download.cjs +62 -0
- package/dist/types/download.cjs.map +1 -0
- package/dist/types/download.d.cts +100 -16
- package/dist/types/download.d.cts.map +1 -1
- package/dist/types/download.d.ts +100 -16
- package/dist/types/download.d.ts.map +1 -1
- package/dist/types/download.js +61 -0
- package/dist/types/download.js.map +1 -0
- package/dist/types/encryption.cjs +76 -229
- package/dist/types/encryption.cjs.map +1 -1
- package/dist/types/encryption.d.cts +48 -6
- package/dist/types/encryption.d.cts.map +1 -1
- package/dist/types/encryption.d.ts +48 -6
- package/dist/types/encryption.d.ts.map +1 -1
- package/dist/types/encryption.js +74 -229
- package/dist/types/encryption.js.map +1 -1
- package/dist/types/errors.cjs +9 -0
- package/dist/types/errors.cjs.map +1 -1
- package/dist/types/errors.d.cts +1 -1
- package/dist/types/errors.d.cts.map +1 -1
- package/dist/types/errors.d.ts +1 -1
- package/dist/types/errors.d.ts.map +1 -1
- package/dist/types/errors.js +9 -0
- package/dist/types/errors.js.map +1 -1
- package/dist/types/file.cjs +3 -0
- package/dist/types/file.cjs.map +1 -1
- package/dist/types/file.d.cts +140 -18
- package/dist/types/file.d.cts.map +1 -1
- package/dist/types/file.d.ts +140 -18
- package/dist/types/file.d.ts.map +1 -1
- package/dist/types/file.js +3 -1
- package/dist/types/file.js.map +1 -1
- package/dist/types/ids.cjs +30 -0
- package/dist/types/ids.cjs.map +1 -1
- package/dist/types/ids.d.cts +32 -0
- package/dist/types/ids.d.cts.map +1 -1
- package/dist/types/ids.d.ts +32 -0
- package/dist/types/ids.d.ts.map +1 -1
- package/dist/types/ids.js +28 -1
- package/dist/types/ids.js.map +1 -1
- package/dist/types/index.d.cts +16 -12
- package/dist/types/index.d.cts.map +1 -1
- package/dist/types/index.d.ts +16 -12
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/key.d.cts +4 -3
- package/dist/types/key.d.cts.map +1 -1
- package/dist/types/key.d.ts +4 -3
- package/dist/types/key.d.ts.map +1 -1
- package/dist/types/lock.cjs.map +1 -1
- package/dist/types/lock.d.cts +14 -0
- package/dist/types/lock.d.cts.map +1 -1
- package/dist/types/lock.d.ts +14 -0
- package/dist/types/lock.d.ts.map +1 -1
- package/dist/types/lock.js.map +1 -1
- package/dist/types/notifications.cjs +31 -1
- package/dist/types/notifications.cjs.map +1 -1
- package/dist/types/notifications.d.cts +31 -4
- package/dist/types/notifications.d.cts.map +1 -1
- package/dist/types/notifications.d.ts +31 -4
- package/dist/types/notifications.d.ts.map +1 -1
- package/dist/types/notifications.js +30 -2
- package/dist/types/notifications.js.map +1 -1
- package/dist/types/partner.cjs +32 -0
- package/dist/types/partner.cjs.map +1 -0
- package/dist/types/partner.d.cts +386 -0
- package/dist/types/partner.d.cts.map +1 -0
- package/dist/types/partner.d.ts +386 -0
- package/dist/types/partner.d.ts.map +1 -0
- package/dist/types/partner.js +29 -0
- package/dist/types/partner.js.map +1 -0
- package/dist/types/upload.d.cts +35 -18
- package/dist/types/upload.d.cts.map +1 -1
- package/dist/types/upload.d.ts +35 -18
- package/dist/types/upload.d.ts.map +1 -1
- package/dist/upload/abort-scope.cjs +0 -45
- package/dist/upload/abort-scope.cjs.map +1 -1
- package/dist/upload/abort-scope.d.cts +0 -22
- package/dist/upload/abort-scope.d.cts.map +1 -1
- package/dist/upload/abort-scope.d.ts +0 -22
- package/dist/upload/abort-scope.d.ts.map +1 -1
- package/dist/upload/abort-scope.js +1 -44
- package/dist/upload/abort-scope.js.map +1 -1
- package/dist/upload/finish.cjs +3 -8
- package/dist/upload/finish.cjs.map +1 -1
- package/dist/upload/finish.d.cts.map +1 -1
- package/dist/upload/finish.d.ts.map +1 -1
- package/dist/upload/finish.js +1 -6
- package/dist/upload/finish.js.map +1 -1
- package/dist/upload/large.cjs +15 -8
- package/dist/upload/large.cjs.map +1 -1
- package/dist/upload/large.d.cts +31 -8
- package/dist/upload/large.d.cts.map +1 -1
- package/dist/upload/large.d.ts +31 -8
- package/dist/upload/large.d.ts.map +1 -1
- package/dist/upload/large.js +15 -8
- package/dist/upload/large.js.map +1 -1
- package/dist/upload/options.cjs.map +1 -1
- package/dist/upload/options.d.cts +24 -0
- package/dist/upload/options.d.cts.map +1 -1
- package/dist/upload/options.d.ts +24 -0
- package/dist/upload/options.d.ts.map +1 -1
- package/dist/upload/options.js.map +1 -1
- package/dist/upload/resume.cjs +6 -4
- package/dist/upload/resume.cjs.map +1 -1
- package/dist/upload/resume.d.cts +9 -5
- package/dist/upload/resume.d.cts.map +1 -1
- package/dist/upload/resume.d.ts +9 -5
- package/dist/upload/resume.d.ts.map +1 -1
- package/dist/upload/resume.js +6 -4
- package/dist/upload/resume.js.map +1 -1
- package/dist/upload/retry.cjs +25 -13
- package/dist/upload/retry.cjs.map +1 -1
- package/dist/upload/retry.d.cts.map +1 -1
- package/dist/upload/retry.d.ts.map +1 -1
- package/dist/upload/retry.js +25 -13
- package/dist/upload/retry.js.map +1 -1
- package/dist/upload/single.cjs +35 -30
- package/dist/upload/single.cjs.map +1 -1
- package/dist/upload/single.d.cts +12 -0
- package/dist/upload/single.d.cts.map +1 -1
- package/dist/upload/single.d.ts +12 -0
- package/dist/upload/single.d.ts.map +1 -1
- package/dist/upload/single.js +35 -30
- package/dist/upload/single.js.map +1 -1
- package/dist/upload/stream.cjs +18 -5
- package/dist/upload/stream.cjs.map +1 -1
- package/dist/upload/stream.d.cts +12 -0
- package/dist/upload/stream.d.cts.map +1 -1
- package/dist/upload/stream.d.ts +12 -0
- package/dist/upload/stream.d.ts.map +1 -1
- package/dist/upload/stream.js +15 -2
- package/dist/upload/stream.js.map +1 -1
- package/dist/util/abort.cjs +114 -0
- package/dist/util/abort.cjs.map +1 -0
- package/dist/util/abort.d.cts +65 -0
- package/dist/util/abort.d.cts.map +1 -0
- package/dist/util/abort.d.ts +65 -0
- package/dist/util/abort.d.ts.map +1 -0
- package/dist/util/abort.js +109 -0
- package/dist/util/abort.js.map +1 -0
- package/dist/util/defaults.cjs +3 -0
- package/dist/util/defaults.cjs.map +1 -1
- package/dist/util/defaults.d.cts +2 -0
- package/dist/util/defaults.d.cts.map +1 -1
- package/dist/util/defaults.d.ts +2 -0
- package/dist/util/defaults.d.ts.map +1 -1
- package/dist/util/defaults.js +3 -1
- package/dist/util/defaults.js.map +1 -1
- package/dist/util/md5.cjs +211 -0
- package/dist/util/md5.cjs.map +1 -0
- package/dist/util/md5.d.cts +43 -0
- package/dist/util/md5.d.cts.map +1 -0
- package/dist/util/md5.d.ts +43 -0
- package/dist/util/md5.d.ts.map +1 -0
- package/dist/util/md5.js +209 -0
- package/dist/util/md5.js.map +1 -0
- package/dist/util/normalize.cjs +5 -5
- package/dist/util/normalize.cjs.map +1 -1
- package/dist/util/normalize.d.cts +7 -7
- package/dist/util/normalize.d.cts.map +1 -1
- package/dist/util/normalize.d.ts +7 -7
- package/dist/util/normalize.d.ts.map +1 -1
- package/dist/util/normalize.js +5 -5
- package/dist/util/normalize.js.map +1 -1
- package/dist/util/paginator.cjs +7 -1
- package/dist/util/paginator.cjs.map +1 -1
- package/dist/util/paginator.d.cts +3 -1
- package/dist/util/paginator.d.cts.map +1 -1
- package/dist/util/paginator.d.ts +3 -1
- package/dist/util/paginator.d.ts.map +1 -1
- package/dist/util/paginator.js +7 -1
- package/dist/util/paginator.js.map +1 -1
- package/dist/version.cjs +56 -4
- package/dist/version.cjs.map +1 -1
- package/dist/version.d.cts +53 -4
- package/dist/version.d.cts.map +1 -1
- package/dist/version.d.ts +53 -4
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +52 -5
- package/dist/version.js.map +1 -1
- package/package.json +47 -18
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local.js","names":[],"sources":["../../../src/sync/scanners/local.ts"],"sourcesContent":["import {\n isDownloadStagingDirectorySegment,\n isManagedDownloadStagingRoot,\n} from '../download-staging.ts'\nimport { localFilesystemErrorReason } from '../filesystem-errors.ts'\nimport {\n directoryMayContainSyncPaths,\n pathPassesSyncFilters,\n pathSkippedByRegExpInputLimit,\n} from '../filters.ts'\nimport { localFileIdentityFromStats } from '../local-file-identity.ts'\nimport { registerLocalFilesystemRoot } from '../local-filesystem-root.ts'\nimport { compareSyncRelativePaths } from '../path-order.ts'\nimport { isReservedSyncTempFileName } from '../path-safety.ts'\nimport { validateSyncFilters } from '../regexp-safety.ts'\nimport { emitScannerSkip, regexpInputTooLongSkip } from '../scan-events.ts'\nimport { assertScanEntryLimit, scanEntryLimit } from '../scan-limit.ts'\nimport type { LocalSyncPath, SyncErrorEvent, SyncFolder, SyncScanOptions } from '../types.ts'\n\ntype LocalDirent = {\n readonly name: string\n isDirectory(): boolean\n isFile(): boolean\n}\n\ntype LocalStats = {\n readonly dev: number\n readonly ino: number\n readonly mtimeMs: number\n readonly ctimeMs: number\n readonly size: number\n isFile(): boolean\n}\n\ntype LocalNodeDeps = {\n readdir(path: string, options: { readonly withFileTypes: true }): Promise<LocalDirent[]>\n lstat(path: string): Promise<LocalStats>\n join(...paths: string[]): string\n relative(from: string, to: string): string\n resolve(...paths: string[]): string\n sep: string\n}\n\n/**\n * Scans a local directory tree and yields {@link LocalSyncPath} entries sorted by relative path.\n * A root directory read failure aborts the scan with an error diagnostic. Per-entry file or\n * directory failures are reported through `onError` and the scan continues over readable siblings.\n * SDK-managed partial download file names are skipped so unfinished internal\n * temp files are not synchronized.\n * The current implementation collects matching entries before sorting, so memory usage is\n * proportional to the number of matched files.\n */\nexport class LocalFolder implements SyncFolder {\n readonly type = 'local' as const\n readonly appliesScanFilters = true as const\n readonly appliesScanSorting = true as const\n /** Resolved absolute path to the local root directory. */\n readonly root: string\n\n /**\n * Creates a new LocalFolder for the given root directory.\n * @param root - Absolute or relative path to the local directory to scan.\n */\n constructor(root: string) {\n this.root = resolvePathAtConstruction(root)\n registerLocalFilesystemRoot(this)\n }\n\n /**\n * Recursively walks the directory and yields files in sync path order.\n * @param options - Optional scan controls.\n */\n async *scan(options: SyncScanOptions = {}): AsyncGenerator<LocalSyncPath> {\n validateSyncFilters(options)\n const nodeDeps = await loadLocalNodeDeps()\n const root = nodeDeps.resolve(this.root)\n const collected: LocalSyncPath[] = []\n await this.walk(root, root, collected, options, scanEntryLimit(options), nodeDeps)\n collected.sort((a, b) => compareSyncRelativePaths(a.relativePath, b.relativePath))\n for (const entry of collected) {\n throwIfScanAborted(options)\n yield entry\n }\n }\n\n /**\n * Recursively collects files from {@link dir} into {@link out}.\n * @param root - Resolved scan root used for relative path calculation.\n * @param dir - Absolute path of the directory to scan.\n * @param out - Accumulator array that receives discovered file entries.\n * @param options - Optional scan controls.\n * @param maxScanEntries - Maximum number of entries to retain before failing.\n * @param nodeDeps - Lazy-loaded Node filesystem and path helpers.\n */\n private async walk(\n root: string,\n dir: string,\n out: LocalSyncPath[],\n options: SyncScanOptions,\n maxScanEntries: number,\n nodeDeps: LocalNodeDeps,\n ): Promise<void> {\n throwIfScanAborted(options)\n let entries: LocalDirent[]\n try {\n entries = await nodeDeps.readdir(dir, { withFileTypes: true })\n } catch (err) {\n const error = this.emitScanError(\n options,\n relativePathFromRoot(root, dir, nodeDeps),\n 'directory',\n err,\n )\n if (dir === root) throw error\n return\n }\n\n for (const entry of entries) {\n throwIfScanAborted(options)\n const fullPath = nodeDeps.join(dir, entry.name)\n const rel = relativePathFromRoot(root, fullPath, nodeDeps)\n if (\n isDownloadStagingDirectorySegment(rel) &&\n entry.isDirectory() &&\n isDownloadStagingDirectorySegment(entry.name) &&\n (await isManagedDownloadStagingRoot(fullPath))\n ) {\n continue\n }\n if (rel.includes('\\\\')) {\n emitScannerSkip(options, {\n type: 'skip',\n path: rel,\n size: 0,\n reason: 'unsafe-name',\n message: `Skipped local path ${JSON.stringify(rel)}: backslashes are not safe sync path characters`,\n })\n continue\n }\n if (isReservedSyncTempFileName(entry.name)) {\n emitScannerSkip(options, {\n type: 'skip',\n path: rel,\n size: 0,\n reason: 'stale-download-partial',\n message: `Skipped local path ${JSON.stringify(rel)}: reserved SDK partial download file`,\n })\n continue\n }\n // Symlinks, FIFOs, sockets, and device nodes are not syncable files.\n // Ignore them without poisoning delete-mode orphan handling for unrelated paths.\n if (entry.isDirectory()) {\n if (directoryMayContainSyncPaths(rel, options)) {\n await this.walk(root, fullPath, out, options, maxScanEntries, nodeDeps)\n }\n } else if (entry.isFile()) {\n if (!pathPassesSyncFilters(rel, options)) {\n if (pathSkippedByRegExpInputLimit(rel, options)) {\n emitScannerSkip(options, regexpInputTooLongSkip(rel))\n }\n continue\n }\n let s: LocalStats\n try {\n s = await nodeDeps.lstat(fullPath)\n /* v8 ignore start -- lstat race after a Dirent file result is not deterministic */\n if (!s.isFile()) {\n this.emitScanError(options, rel, 'file', new Error('not a regular file'))\n continue\n }\n /* v8 ignore stop */\n } catch (err) {\n /* v8 ignore next -- stat TOCTOU failures are not deterministic to trigger */\n this.emitScanError(options, relativePathFromRoot(root, fullPath, nodeDeps), 'file', err)\n continue\n }\n assertScanEntryLimit(out.length + 1, maxScanEntries)\n out.push({\n relativePath: rel,\n absolutePath: fullPath,\n modTimeMillis: Math.floor(s.mtimeMs),\n size: s.size,\n fileIdentity: localFileIdentityFromStats(s),\n })\n }\n }\n }\n\n private emitScanError(\n options: SyncScanOptions,\n path: string,\n kind: 'directory' | 'file',\n err: unknown,\n ): Error {\n const event: SyncErrorEvent = {\n type: 'error',\n path,\n size: 0,\n message: `failed to scan local ${kind}: ${localFilesystemErrorReason(err)}`,\n }\n options.onError?.(event)\n return new Error(event.message)\n }\n}\n\nasync function loadLocalNodeDeps(): Promise<LocalNodeDeps> {\n const [fsPromises, path] = await Promise.all([import('node:fs/promises'), import('node:path')])\n return {\n readdir: fsPromises.readdir as LocalNodeDeps['readdir'],\n lstat: fsPromises.lstat as LocalNodeDeps['lstat'],\n join: path.join,\n relative: path.relative,\n resolve: path.resolve,\n sep: path.sep,\n }\n}\n\nfunction resolvePathAtConstruction(root: string): string {\n const processLike = (\n globalThis as {\n process?: { cwd?: () => string; platform?: string }\n }\n ).process\n if (typeof processLike?.cwd !== 'function') return root\n\n const cwd = processLike.cwd()\n if (processLike.platform === 'win32') return resolveWindowsPath(cwd, root)\n return resolvePosixPath(cwd, root)\n}\n\nfunction resolvePosixPath(cwd: string, root: string): string {\n const joined = root.startsWith('/') ? root : `${cwd}/${root}`\n const resolved = normalizePathSegments(joined.split('/'), '/')\n return resolved === '' ? '/' : `/${resolved}`\n}\n\nfunction resolveWindowsPath(cwd: string, root: string): string {\n const normalizedRoot = root.replaceAll('/', '\\\\')\n const normalizedCwd = cwd.replaceAll('/', '\\\\')\n const drive = /^[A-Za-z]:/.exec(normalizedCwd)?.[0] ?? ''\n const cwdUnc = splitUncPath(normalizedCwd)\n if (/^\\\\\\\\/.test(normalizedRoot)) return normalizeUncPath(normalizedRoot)\n if (/^[A-Za-z]:\\\\/.test(normalizedRoot)) {\n const prefix = normalizedRoot.slice(0, 2)\n const rest = normalizedRoot.slice(3).split('\\\\')\n return joinWindowsRoot(prefix, normalizePathSegments(rest, '\\\\'))\n }\n if (/^[A-Za-z]:/.test(normalizedRoot)) {\n throw new Error('LocalFolder root must not be a drive-relative Windows path')\n }\n if (normalizedRoot.startsWith('\\\\')) {\n const rest = normalizePathSegments(normalizedRoot.slice(1).split('\\\\'), '\\\\')\n return joinWindowsRoot(cwdUnc?.prefix ?? drive, rest)\n }\n if (cwdUnc !== undefined) {\n const resolved = normalizePathSegments([...cwdUnc.rest, ...normalizedRoot.split('\\\\')], '\\\\')\n return joinWindowsRoot(cwdUnc.prefix, resolved)\n }\n const base = /^[A-Za-z]:\\\\/.test(normalizedCwd) ? normalizedCwd : `${drive}\\\\`\n const prefix = /^[A-Za-z]:/.exec(base)?.[0] ?? drive\n const baseRest = base.slice(prefix.length).replace(/^\\\\/, '').split('\\\\')\n const resolved = normalizePathSegments([...baseRest, ...normalizedRoot.split('\\\\')], '\\\\')\n return joinWindowsRoot(prefix, resolved)\n}\n\nfunction normalizeUncPath(path: string): string {\n const unc = splitUncPath(path)\n if (unc === undefined) return path\n return joinWindowsRoot(unc.prefix, normalizePathSegments(unc.rest, '\\\\'))\n}\n\nfunction splitUncPath(\n path: string,\n): { readonly prefix: string; readonly rest: string[] } | undefined {\n if (!path.startsWith('\\\\\\\\')) return undefined\n const parts = path.split('\\\\').filter((part) => part !== '')\n const [server, share, ...rest] = parts\n if (server === undefined || share === undefined) return undefined\n return { prefix: `\\\\\\\\${server}\\\\${share}`, rest }\n}\n\nfunction joinWindowsRoot(prefix: string, rest: string): string {\n return rest === '' ? `${prefix}\\\\` : `${prefix}\\\\${rest}`\n}\n\nfunction normalizePathSegments(segments: readonly string[], separator: '/' | '\\\\'): string {\n const out: string[] = []\n for (const segment of segments) {\n if (segment === '' || segment === '.') continue\n if (segment === '..') {\n out.pop()\n continue\n }\n out.push(segment)\n }\n return out.join(separator)\n}\n\nfunction relativePathFromRoot(root: string, path: string, nodeDeps: LocalNodeDeps): string {\n return nodeDeps.relative(root, path).split(nodeDeps.sep).join('/')\n}\n\nfunction throwIfScanAborted(options: SyncScanOptions): void {\n if (options.signal?.aborted === true) {\n throw options.signal.reason ?? new DOMException('Aborted', 'AbortError')\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"local.js","names":[],"sources":["../../../src/sync/scanners/local.ts"],"sourcesContent":["import {\n isDownloadStagingDirectorySegment,\n isManagedDownloadStagingRoot,\n} from '../download-staging.ts'\nimport { localFilesystemErrorReason } from '../filesystem-errors.ts'\nimport {\n directoryMayContainSyncPaths,\n pathPassesSyncFilters,\n pathSkippedByRegExpInputLimit,\n} from '../filters.ts'\nimport { localFileIdentityFromStats } from '../local-file-identity.ts'\nimport { registerLocalFilesystemRoot } from '../local-filesystem-root.ts'\nimport { compareSyncRelativePaths } from '../path-order.ts'\nimport { isReservedSyncTempFileName } from '../path-safety.ts'\nimport { validateSyncFilters } from '../regexp-safety.ts'\nimport { emitScannerSkip, regexpInputTooLongSkip } from '../scan-events.ts'\nimport { assertScanEntryLimit, scanEntryLimit } from '../scan-limit.ts'\nimport type { LocalSyncPath, SyncErrorEvent, SyncFolder, SyncScanOptions } from '../types.ts'\n\ntype LocalDirent = {\n readonly name: string\n isDirectory(): boolean\n isFile(): boolean\n isSymbolicLink(): boolean\n}\n\ntype LocalStats = {\n readonly dev: number\n readonly ino: number\n readonly mtimeMs: number\n readonly ctimeMs: number\n readonly size: number\n isDirectory(): boolean\n isFile(): boolean\n}\n\ntype LocalNodeDeps = {\n readdir(path: string, options: { readonly withFileTypes: true }): Promise<LocalDirent[]>\n lstat(path: string): Promise<LocalStats>\n stat(path: string): Promise<LocalStats>\n join(...paths: string[]): string\n relative(from: string, to: string): string\n realpath(path: string): Promise<string>\n resolve(...paths: string[]): string\n isAbsolute(path: string): boolean\n sep: string\n}\n\n/**\n * Scans a local directory tree and yields {@link LocalSyncPath} entries sorted by relative path.\n * A root directory read failure aborts the scan with an error diagnostic. Per-entry file or\n * directory failures are reported through `onError` and the scan continues over readable siblings.\n * SDK-managed partial download file names are skipped so unfinished internal\n * temp files are not synchronized.\n * The current implementation collects matching entries before sorting, so memory usage is\n * proportional to the number of matched files.\n */\nexport class LocalFolder implements SyncFolder {\n readonly type = 'local' as const\n readonly appliesScanFilters = true as const\n readonly appliesScanSorting = true as const\n /** Resolved absolute path to the local root directory. */\n readonly root: string\n\n /**\n * Creates a new LocalFolder for the given root directory.\n * @param root - Absolute or relative path to the local directory to scan.\n */\n constructor(root: string) {\n this.root = resolvePathAtConstruction(root)\n registerLocalFilesystemRoot(this)\n }\n\n /**\n * Recursively walks the directory and yields files in sync path order.\n * @param options - Optional scan controls.\n */\n async *scan(options: SyncScanOptions = {}): AsyncGenerator<LocalSyncPath> {\n validateSyncFilters(options)\n const nodeDeps = await loadLocalNodeDeps()\n const root = nodeDeps.resolve(this.root)\n const followSymlinks =\n options.localSymlinks === 'follow' && options.requireLocalSafePaths !== true\n let scanRoot = root\n const collected: LocalSyncPath[] = []\n const activeDirectoryIds = new Set<string>()\n const followedDirectoryIds = new Set<string>()\n if (followSymlinks) {\n try {\n scanRoot = await nodeDeps.realpath(root)\n const rootStats = await nodeDeps.stat(scanRoot)\n if (rootStats.isDirectory()) activeDirectoryIds.add(localNodeIdentity(rootStats))\n } catch {\n // Root read errors are reported by walk(), preserving the existing diagnostic shape.\n }\n }\n await this.walk(\n scanRoot,\n scanRoot,\n '',\n collected,\n options,\n scanEntryLimit(options),\n nodeDeps,\n activeDirectoryIds,\n followedDirectoryIds,\n )\n collected.sort((a, b) => compareSyncRelativePaths(a.relativePath, b.relativePath))\n for (const entry of collected) {\n throwIfScanAborted(options)\n yield entry\n }\n }\n\n /**\n * Recursively collects files from {@link dir} into {@link out}.\n * @param root - Resolved scan root used for relative path calculation.\n * @param dir - Absolute path of the directory to scan.\n * @param dirRel - Sync-relative path represented by {@link dir}.\n * @param out - Accumulator array that receives discovered file entries.\n * @param options - Optional scan controls.\n * @param maxScanEntries - Maximum number of entries to retain before failing.\n * @param nodeDeps - Lazy-loaded Node filesystem and path helpers.\n * @param activeDirectoryIds - Directory identities in the current recursion stack.\n * @param followedDirectoryIds - Followed symlink directory identities already traversed.\n */\n private async walk(\n root: string,\n dir: string,\n dirRel: string,\n out: LocalSyncPath[],\n options: SyncScanOptions,\n maxScanEntries: number,\n nodeDeps: LocalNodeDeps,\n activeDirectoryIds: Set<string>,\n followedDirectoryIds: Set<string>,\n ): Promise<void> {\n throwIfScanAborted(options)\n let entries: LocalDirent[]\n try {\n entries = await nodeDeps.readdir(dir, { withFileTypes: true })\n } catch (err) {\n const error = this.emitScanError(options, dirRel, 'directory', err)\n if (dir === root) throw error\n return\n }\n\n for (const entry of entries) {\n throwIfScanAborted(options)\n const fullPath = nodeDeps.join(dir, entry.name)\n const rel = joinSyncRelativePath(dirRel, entry.name)\n if (\n isDownloadStagingDirectorySegment(rel) &&\n entry.isDirectory() &&\n isDownloadStagingDirectorySegment(entry.name) &&\n (await isManagedDownloadStagingRoot(fullPath))\n ) {\n continue\n }\n if (rel.includes('\\\\')) {\n emitScannerSkip(options, {\n type: 'skip',\n path: rel,\n size: 0,\n reason: 'unsafe-name',\n message: `Skipped local path ${JSON.stringify(rel)}: backslashes are not safe sync path characters`,\n })\n continue\n }\n if (isReservedSyncTempFileName(entry.name)) {\n emitScannerSkip(options, {\n type: 'skip',\n path: rel,\n size: 0,\n reason: 'stale-download-partial',\n message: `Skipped local path ${JSON.stringify(rel)}: reserved SDK partial download file`,\n })\n continue\n }\n // Symlinks, FIFOs, sockets, and device nodes are not syncable files.\n // Ignore them without poisoning delete-mode orphan handling for unrelated paths.\n if (entry.isDirectory()) {\n if (directoryMayContainSyncPaths(rel, options)) {\n await this.walkDirectory(\n root,\n fullPath,\n rel,\n out,\n options,\n maxScanEntries,\n nodeDeps,\n activeDirectoryIds,\n followedDirectoryIds,\n )\n }\n } else if (entry.isFile()) {\n await this.collectFile(fullPath, rel, out, options, maxScanEntries, nodeDeps)\n } else if (entry.isSymbolicLink()) {\n await this.handleSymlink(\n root,\n fullPath,\n rel,\n out,\n options,\n maxScanEntries,\n nodeDeps,\n activeDirectoryIds,\n followedDirectoryIds,\n )\n }\n }\n }\n\n private async walkDirectory(\n root: string,\n dir: string,\n rel: string,\n out: LocalSyncPath[],\n options: SyncScanOptions,\n maxScanEntries: number,\n nodeDeps: LocalNodeDeps,\n activeDirectoryIds: Set<string>,\n followedDirectoryIds: Set<string>,\n knownStats?: LocalStats,\n ): Promise<void> {\n let stats = knownStats\n if (stats === undefined) {\n try {\n stats = await nodeDeps.stat(dir)\n } catch (err) {\n /* v8 ignore start -- stat TOCTOU failures after a Dirent directory result are not deterministic */\n this.emitScanError(options, rel, 'directory', err)\n return\n /* v8 ignore stop */\n }\n }\n /* v8 ignore start -- stat TOCTOU races after a Dirent directory result are not deterministic */\n if (!stats.isDirectory()) {\n this.emitScanError(options, rel, 'directory', new Error('not a directory'))\n return\n }\n /* v8 ignore stop */\n\n const identity = localNodeIdentity(stats)\n if (activeDirectoryIds.has(identity)) {\n emitScannerSkip(options, {\n type: 'skip',\n path: rel,\n size: 0,\n reason: 'local-symlink-loop',\n message: `Skipped local path ${JSON.stringify(rel)}: symlink would revisit an ancestor directory`,\n })\n return\n }\n\n activeDirectoryIds.add(identity)\n try {\n await this.walk(\n root,\n dir,\n rel,\n out,\n options,\n maxScanEntries,\n nodeDeps,\n activeDirectoryIds,\n followedDirectoryIds,\n )\n } finally {\n activeDirectoryIds.delete(identity)\n }\n }\n\n private async collectFile(\n fullPath: string,\n rel: string,\n out: LocalSyncPath[],\n options: SyncScanOptions,\n maxScanEntries: number,\n nodeDeps: LocalNodeDeps,\n knownStats?: LocalStats,\n ): Promise<void> {\n if (!pathPassesSyncFilters(rel, options)) {\n if (pathSkippedByRegExpInputLimit(rel, options)) {\n emitScannerSkip(options, regexpInputTooLongSkip(rel))\n }\n return\n }\n\n let s = knownStats\n if (s === undefined) {\n try {\n s = await nodeDeps.lstat(fullPath)\n /* v8 ignore start -- lstat race after a Dirent file result is not deterministic */\n if (!s.isFile()) {\n this.emitScanError(options, rel, 'file', new Error('not a regular file'))\n return\n }\n /* v8 ignore stop */\n } catch (err) {\n /* v8 ignore start -- stat TOCTOU failures are not deterministic to trigger */\n this.emitScanError(options, rel, 'file', err)\n return\n /* v8 ignore stop */\n }\n }\n\n assertScanEntryLimit(out.length + 1, maxScanEntries)\n out.push({\n relativePath: rel,\n absolutePath: fullPath,\n modTimeMillis: Math.floor(s.mtimeMs),\n size: s.size,\n fileIdentity: localFileIdentityFromStats(s),\n })\n }\n\n private async handleSymlink(\n root: string,\n fullPath: string,\n rel: string,\n out: LocalSyncPath[],\n options: SyncScanOptions,\n maxScanEntries: number,\n nodeDeps: LocalNodeDeps,\n activeDirectoryIds: Set<string>,\n followedDirectoryIds: Set<string>,\n ): Promise<void> {\n if ((options.localSymlinks ?? 'skip') === 'skip' || options.requireLocalSafePaths === true) {\n emitScannerSkip(options, {\n type: 'skip',\n path: rel,\n size: 0,\n reason: 'local-symlink',\n message: `Skipped local path ${JSON.stringify(rel)}: local symlinks are disabled`,\n })\n return\n }\n\n let targetPath: string\n let targetStats: LocalStats\n try {\n targetPath = await nodeDeps.realpath(fullPath)\n targetStats = await nodeDeps.stat(targetPath)\n } catch (err) {\n this.emitScanError(options, rel, 'symlink', err)\n return\n }\n\n if (!isPathInsideRoot(root, targetPath, nodeDeps)) {\n emitScannerSkip(options, {\n type: 'skip',\n path: rel,\n size: 0,\n reason: 'local-symlink',\n message: `Skipped local path ${JSON.stringify(rel)}: symlink target is outside the sync root`,\n })\n return\n }\n\n if (targetStats.isDirectory()) {\n if (directoryMayContainSyncPaths(rel, options)) {\n const identity = localNodeIdentity(targetStats)\n if (followedDirectoryIds.has(identity)) {\n emitScannerSkip(options, {\n type: 'skip',\n path: rel,\n size: 0,\n reason: 'local-symlink-loop',\n message: `Skipped local path ${JSON.stringify(rel)}: symlink target was already visited`,\n })\n return\n }\n followedDirectoryIds.add(identity)\n await this.walkDirectory(\n root,\n targetPath,\n rel,\n out,\n options,\n maxScanEntries,\n nodeDeps,\n activeDirectoryIds,\n followedDirectoryIds,\n targetStats,\n )\n }\n return\n }\n\n if (targetStats.isFile()) {\n await this.collectFile(targetPath, rel, out, options, maxScanEntries, nodeDeps, targetStats)\n return\n }\n\n emitScannerSkip(options, {\n type: 'skip',\n path: rel,\n size: 0,\n reason: 'local-symlink',\n message: `Skipped local path ${JSON.stringify(rel)}: symlink target is not a regular file or directory`,\n })\n }\n\n private emitScanError(\n options: SyncScanOptions,\n path: string,\n kind: 'directory' | 'file' | 'symlink',\n err: unknown,\n ): Error {\n const event: SyncErrorEvent = {\n type: 'error',\n path,\n size: 0,\n message: `failed to scan local ${kind}: ${localFilesystemErrorReason(err)}`,\n }\n options.onError?.(event)\n return new Error(event.message)\n }\n}\n\nasync function loadLocalNodeDeps(): Promise<LocalNodeDeps> {\n const [fsPromises, path] = await Promise.all([import('node:fs/promises'), import('node:path')])\n return {\n readdir: fsPromises.readdir as LocalNodeDeps['readdir'],\n lstat: fsPromises.lstat as LocalNodeDeps['lstat'],\n stat: fsPromises.stat as LocalNodeDeps['stat'],\n join: path.join,\n relative: path.relative,\n realpath: fsPromises.realpath,\n resolve: path.resolve,\n isAbsolute: path.isAbsolute,\n sep: path.sep,\n }\n}\n\nfunction resolvePathAtConstruction(root: string): string {\n const processLike = (\n globalThis as {\n process?: { cwd?: () => string; platform?: string }\n }\n ).process\n if (typeof processLike?.cwd !== 'function') return root\n\n const cwd = processLike.cwd()\n if (processLike.platform === 'win32') return resolveWindowsPath(cwd, root)\n return resolvePosixPath(cwd, root)\n}\n\nfunction resolvePosixPath(cwd: string, root: string): string {\n const joined = root.startsWith('/') ? root : `${cwd}/${root}`\n const resolved = normalizePathSegments(joined.split('/'), '/')\n return resolved === '' ? '/' : `/${resolved}`\n}\n\nfunction resolveWindowsPath(cwd: string, root: string): string {\n const normalizedRoot = root.replaceAll('/', '\\\\')\n const normalizedCwd = cwd.replaceAll('/', '\\\\')\n const drive = /^[A-Za-z]:/.exec(normalizedCwd)?.[0] ?? ''\n const cwdUnc = splitUncPath(normalizedCwd)\n if (/^\\\\\\\\/.test(normalizedRoot)) return normalizeUncPath(normalizedRoot)\n if (/^[A-Za-z]:\\\\/.test(normalizedRoot)) {\n const prefix = normalizedRoot.slice(0, 2)\n const rest = normalizedRoot.slice(3).split('\\\\')\n return joinWindowsRoot(prefix, normalizePathSegments(rest, '\\\\'))\n }\n if (/^[A-Za-z]:/.test(normalizedRoot)) {\n throw new Error('LocalFolder root must not be a drive-relative Windows path')\n }\n if (normalizedRoot.startsWith('\\\\')) {\n const rest = normalizePathSegments(normalizedRoot.slice(1).split('\\\\'), '\\\\')\n return joinWindowsRoot(cwdUnc?.prefix ?? drive, rest)\n }\n if (cwdUnc !== undefined) {\n const resolved = normalizePathSegments([...cwdUnc.rest, ...normalizedRoot.split('\\\\')], '\\\\')\n return joinWindowsRoot(cwdUnc.prefix, resolved)\n }\n const base = /^[A-Za-z]:\\\\/.test(normalizedCwd) ? normalizedCwd : `${drive}\\\\`\n const prefix = /^[A-Za-z]:/.exec(base)?.[0] ?? drive\n const baseRest = base.slice(prefix.length).replace(/^\\\\/, '').split('\\\\')\n const resolved = normalizePathSegments([...baseRest, ...normalizedRoot.split('\\\\')], '\\\\')\n return joinWindowsRoot(prefix, resolved)\n}\n\nfunction normalizeUncPath(path: string): string {\n const unc = splitUncPath(path)\n if (unc === undefined) return path\n return joinWindowsRoot(unc.prefix, normalizePathSegments(unc.rest, '\\\\'))\n}\n\nfunction splitUncPath(\n path: string,\n): { readonly prefix: string; readonly rest: string[] } | undefined {\n if (!path.startsWith('\\\\\\\\')) return undefined\n const parts = path.split('\\\\').filter((part) => part !== '')\n const [server, share, ...rest] = parts\n if (server === undefined || share === undefined) return undefined\n return { prefix: `\\\\\\\\${server}\\\\${share}`, rest }\n}\n\nfunction joinWindowsRoot(prefix: string, rest: string): string {\n return rest === '' ? `${prefix}\\\\` : `${prefix}\\\\${rest}`\n}\n\nfunction normalizePathSegments(segments: readonly string[], separator: '/' | '\\\\'): string {\n const out: string[] = []\n for (const segment of segments) {\n if (segment === '' || segment === '.') continue\n if (segment === '..') {\n out.pop()\n continue\n }\n out.push(segment)\n }\n return out.join(separator)\n}\n\nfunction joinSyncRelativePath(parent: string, child: string): string {\n return parent === '' ? child : `${parent}/${child}`\n}\n\nfunction isPathInsideRoot(root: string, path: string, nodeDeps: LocalNodeDeps): boolean {\n const rel = nodeDeps.relative(root, path)\n return (\n rel === '' ||\n (!rel.startsWith(`..${nodeDeps.sep}`) && rel !== '..' && !nodeDeps.isAbsolute(rel))\n )\n}\n\nfunction localNodeIdentity(stats: LocalStats): string {\n return `${stats.dev}:${stats.ino}`\n}\n\nfunction throwIfScanAborted(options: SyncScanOptions): void {\n if (options.signal?.aborted === true) {\n throw options.signal.reason ?? new DOMException('Aborted', 'AbortError')\n }\n}\n"],"mappings":"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"}
|
|
@@ -7,9 +7,10 @@ const require_sha1_options = require("./sha1-options.cjs");
|
|
|
7
7
|
const require_local_sha1 = require("./local-sha1.cjs");
|
|
8
8
|
const require_compare = require("./policies/compare.cjs");
|
|
9
9
|
const require_index$1 = require("./policies/index.cjs");
|
|
10
|
+
const require_filesystem_errors = require("./filesystem-errors.cjs");
|
|
10
11
|
const require_path_safety = require("./path-safety.cjs");
|
|
12
|
+
const require_download_staging = require("./download-staging.cjs");
|
|
11
13
|
const require_prefix = require("./prefix.cjs");
|
|
12
|
-
const require_filesystem_errors = require("./filesystem-errors.cjs");
|
|
13
14
|
const require_local_filesystem_root = require("./local-filesystem-root.cjs");
|
|
14
15
|
const require_b2_sha1_reader = require("./b2-sha1-reader.cjs");
|
|
15
16
|
const require_local_file_io = require("./local-file-io.cjs");
|
|
@@ -64,6 +65,7 @@ async function* synchronize(config) {
|
|
|
64
65
|
...options.exclude !== void 0 ? { exclude: options.exclude } : {},
|
|
65
66
|
...options.signal !== void 0 ? { signal: options.signal } : {},
|
|
66
67
|
...options.maxScanEntries !== void 0 ? { maxScanEntries: options.maxScanEntries } : {},
|
|
68
|
+
...options.localSymlinks !== void 0 ? { localSymlinks: options.localSymlinks } : {},
|
|
67
69
|
...direction === "b2-to-local" ? { requireLocalSafePaths: true } : {},
|
|
68
70
|
onError: (event) => {
|
|
69
71
|
scanHadError = true;
|
|
@@ -71,7 +73,10 @@ async function* synchronize(config) {
|
|
|
71
73
|
queueEvent(event);
|
|
72
74
|
}
|
|
73
75
|
};
|
|
74
|
-
const
|
|
76
|
+
const downloadStagingRoots = await downloadStagingRootCleanupTargets(direction, localRootContexts);
|
|
77
|
+
const factory = createActionFactory(config, localRootContexts, { onDownloadStagingRoot(target) {
|
|
78
|
+
downloadStagingRoots.set(target.managedDirectory, target);
|
|
79
|
+
} });
|
|
75
80
|
const readB2Sha1 = dryRun ? void 0 : createB2Sha1Reader(config);
|
|
76
81
|
const actionAbortController = new AbortController();
|
|
77
82
|
const removeAbortForwarder = forwardAbortSignal(options.signal, actionAbortController);
|
|
@@ -127,6 +132,7 @@ async function* synchronize(config) {
|
|
|
127
132
|
if (!completed) abortActionController(actionAbortController, new DOMException("Sync iterator closed", "AbortError"));
|
|
128
133
|
removeAbortForwarder();
|
|
129
134
|
await drainActions();
|
|
135
|
+
await removeDownloadStagingRootMarkersAndDirectoriesAfterSync(downloadStagingRoots);
|
|
130
136
|
}
|
|
131
137
|
async function collectPairs() {
|
|
132
138
|
const pairs = [];
|
|
@@ -145,6 +151,7 @@ async function* synchronize(config) {
|
|
|
145
151
|
return pairs;
|
|
146
152
|
}
|
|
147
153
|
async function* emitSha1Batch(batch) {
|
|
154
|
+
/* v8 ignore next -- SHA-1 batches are sliced only while index is within pairs.length */
|
|
148
155
|
if (batch.length === 0) return false;
|
|
149
156
|
await drainActions();
|
|
150
157
|
yield* emitQueuedEvents();
|
|
@@ -174,6 +181,7 @@ async function* synchronize(config) {
|
|
|
174
181
|
return false;
|
|
175
182
|
}
|
|
176
183
|
async function processPreparedBatch(batch) {
|
|
184
|
+
/* v8 ignore next -- callers guard empty SHA-1 batches before preparing pairs */
|
|
177
185
|
if (batch.length === 0) return {
|
|
178
186
|
items: [],
|
|
179
187
|
aborted: false
|
|
@@ -201,6 +209,7 @@ async function* synchronize(config) {
|
|
|
201
209
|
function planPreparedPair(pair, prepared) {
|
|
202
210
|
const event = {
|
|
203
211
|
type: "compare",
|
|
212
|
+
/* v8 ignore next -- zipFolders never emits a pair with both sides absent */
|
|
204
213
|
path: (pair[0] ?? pair[1])?.relativePath ?? "",
|
|
205
214
|
size: 0,
|
|
206
215
|
bytesHashed: prepared.bytesHashed,
|
|
@@ -224,9 +233,9 @@ async function* synchronize(config) {
|
|
|
224
233
|
event,
|
|
225
234
|
actions: [new require_index.SkipAction(prepared.pair[1].relativePath, "not removed because scan errors occurred")]
|
|
226
235
|
};
|
|
227
|
-
if (
|
|
236
|
+
if (scanEvents.sourceInventoryIncompleteMessage !== void 0 && prepared.pair[0] === null && prepared.pair[1] !== null) return {
|
|
228
237
|
event,
|
|
229
|
-
actions: [new require_index.SkipAction(prepared.pair[1].relativePath, scanEvents.sourceInventoryIncompleteMessage
|
|
238
|
+
actions: [new require_index.SkipAction(prepared.pair[1].relativePath, scanEvents.sourceInventoryIncompleteMessage)]
|
|
230
239
|
};
|
|
231
240
|
return {
|
|
232
241
|
event,
|
|
@@ -288,6 +297,24 @@ async function* synchronize(config) {
|
|
|
288
297
|
while (runningActions.size > 0) await Promise.race(runningActions);
|
|
289
298
|
}
|
|
290
299
|
}
|
|
300
|
+
async function downloadStagingRootCleanupTargets(direction, localRootContexts) {
|
|
301
|
+
const targets = /* @__PURE__ */ new Map();
|
|
302
|
+
if (direction !== "b2-to-local" || localRootContexts.dest === void 0) return targets;
|
|
303
|
+
const target = {
|
|
304
|
+
managedDirectory: (await import("node:path")).join(localRootContexts.dest.realPath, require_download_staging.DOWNLOAD_STAGING_DIRECTORY_NAME),
|
|
305
|
+
rootRealPath: localRootContexts.dest.realPath
|
|
306
|
+
};
|
|
307
|
+
targets.set(target.managedDirectory, target);
|
|
308
|
+
return targets;
|
|
309
|
+
}
|
|
310
|
+
async function removeDownloadStagingRootMarkersAndDirectoriesAfterSync(targets) {
|
|
311
|
+
if (targets.size === 0) return;
|
|
312
|
+
const path = await import("node:path");
|
|
313
|
+
for (const target of targets.values()) {
|
|
314
|
+
await synchronizerTestHooks.beforeDownloadStagingRootCleanup?.(target.managedDirectory);
|
|
315
|
+
await require_download_staging.removeDownloadStagingRootMarkerAndDirectory(target.rootRealPath, target.managedDirectory, path);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
291
318
|
/**
|
|
292
319
|
* Normalizes user-provided sync concurrency before it controls compare batches and transfers.
|
|
293
320
|
*
|
|
@@ -328,10 +355,11 @@ function createB2Sha1Reader(config) {
|
|
|
328
355
|
if (maxBytes < expectedBytes) throw new Error(`sha1 B2 verification skipped because contentLength ${expectedBytes} exceeds ${maxBytes} byte verification budget`);
|
|
329
356
|
const serverSideEncryption = toSseCDownloadKey(config.options.encryptionProvider?.getSettingForDownload(path.selectedVersion));
|
|
330
357
|
const fileName = validateB2SyncPathInAnyPrefix(readablePrefixes, path, "read");
|
|
331
|
-
const
|
|
358
|
+
const result = await bucket.file(fileName).downloadById(path.selectedVersion.fileId, {
|
|
332
359
|
...serverSideEncryption !== void 0 ? { serverSideEncryption } : {},
|
|
333
360
|
signal: deadlineSignal
|
|
334
|
-
})
|
|
361
|
+
});
|
|
362
|
+
const verified = await require_b2_sha1_reader.hashReadableStreamSha1(result.body, deadlineSignal, {
|
|
335
363
|
idleTimeoutMillis,
|
|
336
364
|
maxBytes,
|
|
337
365
|
expectedBytes
|
|
@@ -462,10 +490,11 @@ function toSseCDownloadKey(setting) {
|
|
|
462
490
|
*
|
|
463
491
|
* @param config - Synchronizer configuration containing source, destination, and options.
|
|
464
492
|
* @param localRootContexts - Resolved filesystem roots captured before action creation.
|
|
493
|
+
* @param lifecycleHooks - Hooks used to report action-scoped cleanup state.
|
|
465
494
|
*
|
|
466
495
|
* @returns An action factory bound to the provided configuration.
|
|
467
496
|
*/
|
|
468
|
-
function createActionFactory(config, localRootContexts) {
|
|
497
|
+
function createActionFactory(config, localRootContexts, lifecycleHooks = {}) {
|
|
469
498
|
const upConfig = config;
|
|
470
499
|
const downConfig = config;
|
|
471
500
|
const uploadPrefix = require_prefix.asRawB2KeyPrefix(upConfig.prefix ?? b2FolderRawPrefix(config.dest) ?? "");
|
|
@@ -480,16 +509,16 @@ function createActionFactory(config, localRootContexts) {
|
|
|
480
509
|
const root = rootContext?.root ?? upConfig.source.root ?? "";
|
|
481
510
|
const fileName = dest !== void 0 ? validateB2SyncPathInPrefix(uploadPrefix, dest) : `${uploadPrefix}${relPath}`;
|
|
482
511
|
if (rootContext !== void 0) await assertLocalRootContextCurrent(rootContext, relPath, { allowSymlinkRoot: true });
|
|
483
|
-
const targetPath = rootContext === void 0 ? await resolveContainedLocalPath(root, source.relativePath, absPath) : await resolveContainedLocalPath(rootContext.realPath, source.relativePath);
|
|
484
|
-
throwIfAborted(signal);
|
|
512
|
+
const targetPath = rootContext === void 0 ? await resolveContainedLocalPath(root, source.relativePath, absPath) : config.options.localSymlinks === "follow" ? await resolveContainedLocalPath(rootContext.realPath, source.relativePath, absPath) : await resolveContainedLocalPath(rootContext.realPath, source.relativePath);
|
|
513
|
+
throwIfAborted(actionSignal(signal));
|
|
485
514
|
const fileSource = await createValidatedUploadFileSource(source, targetPath);
|
|
486
|
-
throwIfAborted(signal);
|
|
515
|
+
throwIfAborted(actionSignal(signal));
|
|
487
516
|
const serverSideEncryption = config.options.encryptionProvider?.getSettingForUpload(fileName, fileSource.size);
|
|
488
517
|
await bucket.upload({
|
|
489
518
|
fileName,
|
|
490
519
|
source: fileSource,
|
|
491
520
|
...serverSideEncryption !== void 0 ? { serverSideEncryption } : {},
|
|
492
|
-
|
|
521
|
+
signal: actionSignal(signal)
|
|
493
522
|
});
|
|
494
523
|
});
|
|
495
524
|
},
|
|
@@ -508,14 +537,22 @@ function createActionFactory(config, localRootContexts) {
|
|
|
508
537
|
const serverSideEncryption = toSseCDownloadKey(config.options.encryptionProvider?.getSettingForDownload(source.selectedVersion));
|
|
509
538
|
const result = await bucket.file(b2FileName).downloadById(source.selectedVersion.fileId, {
|
|
510
539
|
...serverSideEncryption !== void 0 ? { serverSideEncryption } : {},
|
|
511
|
-
|
|
540
|
+
signal: actionSignal(signal)
|
|
512
541
|
});
|
|
513
542
|
try {
|
|
514
543
|
await require_local_file_io.writeLocalStreamInsideRoot(root, relPath, result.body, {
|
|
515
544
|
expectedBytes,
|
|
516
545
|
...scannedDest !== void 0 ? { expectedDestination: scannedDest } : {},
|
|
517
546
|
idleTimeoutMillis,
|
|
518
|
-
...
|
|
547
|
+
...lifecycleHooks.onDownloadStagingRoot !== void 0 ? { onDownloadStagingRoot: (managedDirectory) => {
|
|
548
|
+
const rootRealPath = localRootContexts.dest?.realPath;
|
|
549
|
+
if (rootRealPath === void 0) return;
|
|
550
|
+
lifecycleHooks.onDownloadStagingRoot?.({
|
|
551
|
+
managedDirectory,
|
|
552
|
+
rootRealPath
|
|
553
|
+
});
|
|
554
|
+
} } : {},
|
|
555
|
+
signal: actionSignal(signal)
|
|
519
556
|
});
|
|
520
557
|
} catch (err) {
|
|
521
558
|
await cancelReadableStreamBody(result.body, err);
|
|
@@ -533,7 +570,7 @@ function createActionFactory(config, localRootContexts) {
|
|
|
533
570
|
const bucket = upConfig.bucket ?? downConfig.bucket;
|
|
534
571
|
assertBucket(bucket, "hide");
|
|
535
572
|
return new require_index.HideAction(path, async (_relPath, signal) => {
|
|
536
|
-
await bucket.hideFile(`${uploadPrefix}${path}`, signal
|
|
573
|
+
await bucket.hideFile(`${uploadPrefix}${path}`, { signal: actionSignal(signal) });
|
|
537
574
|
});
|
|
538
575
|
},
|
|
539
576
|
hideB2Path(path) {
|
|
@@ -541,7 +578,7 @@ function createActionFactory(config, localRootContexts) {
|
|
|
541
578
|
assertBucket(bucket, "hide");
|
|
542
579
|
const b2FileName = validateB2SyncPathInPrefix(uploadPrefix, path);
|
|
543
580
|
return new require_index.HideAction(path.relativePath, async (_relPath, signal) => {
|
|
544
|
-
await bucket.hideFile(b2FileName, signal
|
|
581
|
+
await bucket.hideFile(b2FileName, { signal: actionSignal(signal) });
|
|
545
582
|
});
|
|
546
583
|
},
|
|
547
584
|
deleteRemote(path) {
|
|
@@ -549,16 +586,16 @@ function createActionFactory(config, localRootContexts) {
|
|
|
549
586
|
assertBucket(bucket, "delete");
|
|
550
587
|
const b2FileName = validateB2SyncPathInPrefix(uploadPrefix, path);
|
|
551
588
|
return new require_index.DeleteRemoteAction(path.relativePath, path.selectedVersion.fileId, async (fileId$1, _fileName, signal) => {
|
|
552
|
-
await bucket.deleteFileVersion(b2FileName, require_ids.fileId(fileId$1), signal
|
|
589
|
+
await bucket.deleteFileVersion(b2FileName, require_ids.fileId(fileId$1), { signal: actionSignal(signal) });
|
|
553
590
|
});
|
|
554
591
|
},
|
|
555
592
|
deleteLocal(path) {
|
|
556
593
|
const rootContext = localRootContexts.dest;
|
|
557
594
|
const root = rootContext?.root ?? localSyncRoot(downConfig.dest);
|
|
558
595
|
return new require_index.DeleteLocalAction(path.relativePath, path.absolutePath, async (absPath, signal) => {
|
|
559
|
-
signal
|
|
596
|
+
actionSignal(signal).throwIfAborted();
|
|
560
597
|
if (absPath !== path.absolutePath) throw new Error(`Refusing to delete outside sync root: ${path.relativePath}`);
|
|
561
|
-
signal
|
|
598
|
+
actionSignal(signal).throwIfAborted();
|
|
562
599
|
try {
|
|
563
600
|
if (rootContext !== void 0) await assertLocalRootContextCurrent(rootContext, path.relativePath, { allowSymlinkRoot: false });
|
|
564
601
|
await require_local_file_io.deleteLocalFileInsideRoot(root, path);
|
|
@@ -584,7 +621,7 @@ function createActionFactory(config, localRootContexts) {
|
|
|
584
621
|
fileName: targetPath,
|
|
585
622
|
...destinationServerSideEncryption !== void 0 ? { destinationServerSideEncryption } : {},
|
|
586
623
|
...sourceServerSideEncryption !== void 0 ? { sourceServerSideEncryption } : {},
|
|
587
|
-
|
|
624
|
+
signal: actionSignal(signal)
|
|
588
625
|
});
|
|
589
626
|
});
|
|
590
627
|
}
|
|
@@ -650,10 +687,15 @@ function validateB2SyncPathInPrefix(prefix, path, operation = "mutate") {
|
|
|
650
687
|
function isB2SyncPath(path) {
|
|
651
688
|
return "selectedVersion" in path;
|
|
652
689
|
}
|
|
690
|
+
var defaultActionSignal = new AbortController().signal;
|
|
691
|
+
function actionSignal(signal) {
|
|
692
|
+
return signal ?? defaultActionSignal;
|
|
693
|
+
}
|
|
653
694
|
function throwIfAborted(signal) {
|
|
654
|
-
if (signal
|
|
695
|
+
if (signal.aborted) throw signal.reason ?? new DOMException("Aborted", "AbortError");
|
|
655
696
|
}
|
|
656
697
|
async function cancelReadableStreamBody(body, reason) {
|
|
698
|
+
/* v8 ignore next -- writeLocalStreamInsideRoot releases the body reader before throwing */
|
|
657
699
|
if (body.locked) return;
|
|
658
700
|
try {
|
|
659
701
|
await body.cancel(reason);
|
|
@@ -703,10 +745,7 @@ function bufferScanEvent(buffer, event, direction, scanSide) {
|
|
|
703
745
|
else buffer.dropped++;
|
|
704
746
|
}
|
|
705
747
|
function* drainScanEvents(buffer) {
|
|
706
|
-
while (buffer.events.length > 0)
|
|
707
|
-
const event = buffer.events.shift();
|
|
708
|
-
if (event) yield event;
|
|
709
|
-
}
|
|
748
|
+
while (buffer.events.length > 0) yield buffer.events.shift();
|
|
710
749
|
if (buffer.dropped > 0) {
|
|
711
750
|
yield {
|
|
712
751
|
type: "skip",
|
|
@@ -721,9 +760,6 @@ function* drainScanEvents(buffer) {
|
|
|
721
760
|
function scanHadFilesystemError(scanEvents) {
|
|
722
761
|
return scanEvents.fatalFilesystemErrorMessage !== void 0;
|
|
723
762
|
}
|
|
724
|
-
function sourceInventoryIncomplete(scanEvents) {
|
|
725
|
-
return scanEvents.sourceInventoryIncompleteMessage !== void 0;
|
|
726
|
-
}
|
|
727
763
|
function scanFilesystemError(scanEvents) {
|
|
728
764
|
return scanEvents.fatalFilesystemErrorMessage === void 0 ? void 0 : new Error(scanEvents.fatalFilesystemErrorMessage);
|
|
729
765
|
}
|
|
@@ -742,14 +778,26 @@ function isLocalDeleteSafetyError(err) {
|
|
|
742
778
|
}
|
|
743
779
|
async function resolveContainedLocalPath(root, relativePath, absolutePath) {
|
|
744
780
|
if (root === "") throw new Error("Local sync root required for filesystem mutation");
|
|
781
|
+
const { realpath } = await import("node:fs/promises");
|
|
745
782
|
const { isAbsolute, relative, resolve, sep } = await import("node:path");
|
|
746
783
|
const safeRoot = resolve(root);
|
|
747
784
|
const target = absolutePath === void 0 ? resolve(safeRoot, relativePath) : resolve(absolutePath);
|
|
748
|
-
|
|
785
|
+
let containmentRoot = safeRoot;
|
|
786
|
+
let pathFromRoot = relative(containmentRoot, target);
|
|
787
|
+
let escapesRoot = pathFromRoot === ".." || pathFromRoot.startsWith(`..${sep}`) || isAbsolute(pathFromRoot);
|
|
788
|
+
if (escapesRoot && absolutePath !== void 0) {
|
|
789
|
+
const realRoot = await realpath(safeRoot).catch(() => safeRoot);
|
|
790
|
+
const realPathFromRoot = relative(realRoot, target);
|
|
791
|
+
if (!(realPathFromRoot === ".." || realPathFromRoot.startsWith(`..${sep}`) || isAbsolute(realPathFromRoot))) {
|
|
792
|
+
containmentRoot = realRoot;
|
|
793
|
+
pathFromRoot = realPathFromRoot;
|
|
794
|
+
escapesRoot = false;
|
|
795
|
+
}
|
|
796
|
+
}
|
|
749
797
|
/* v8 ignore next -- defense-in-depth after prior no-follow and symlink checks. */
|
|
750
|
-
if (
|
|
751
|
-
await assertLocalRootHasNoSymlink(
|
|
752
|
-
await assertPathHasNoSymlinkComponents(
|
|
798
|
+
if (escapesRoot) throw new Error(`Refusing to access path outside sync root: ${relativePath}`);
|
|
799
|
+
await assertLocalRootHasNoSymlink(containmentRoot, relativePath);
|
|
800
|
+
await assertPathHasNoSymlinkComponents(containmentRoot, pathFromRoot, relativePath);
|
|
753
801
|
return target;
|
|
754
802
|
}
|
|
755
803
|
async function assertLocalRootHasNoSymlink(safeRoot, relativePath) {
|