@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 @@
|
|
|
1
|
+
{"version":3,"file":"download-staging.d.ts","sourceRoot":"","sources":["../../src/sync/download-staging.js"],"names":[],"mappings":"AAEA,KAAK,UAAU,GAAG;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAAA;AACnD,KAAK,YAAY,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,CAAA;AAEzD,gBAAgB;AAChB,eAAO,MAAM,+BAA+B,4BAA4B,CAAA;AACxE,gBAAgB;AAChB,eAAO,MAAM,4BAA4B,kCAAkC,CAAA;AAS3E,gBAAgB;AAChB,eAAO,MAAM,qCAAqC,OAAO,CAAA;AAazD;;;;;;;;GAQG;AACH,wBAAgB,iCAAiC,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAKtF;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,8BAA8B,CAClD,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,cAAc,WAAW,CAAC,EAChC,UAAU,EAAE,MAAM,MAAM,EACxB,kBAAkB,EAAE,YAAY,EAChC,wBAAwB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,GACrE,OAAO,CAAC,MAAM,CAAC,CA6DjB;AAED;;;;;;;GAOG;AACH,wBAAsB,4BAA4B,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CA8BtF;AAkCD;;;;;;;;GAQG;AACH,wBAAsB,4BAA4B,CAChD,YAAY,EAAE,MAAM,EACpB,iBAAiB,EAAE,MAAM,EACzB,kBAAkB,EAAE,YAAY,EAChC,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAMf"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
type DeviceStat = {
|
|
2
|
+
readonly dev: number | bigint;
|
|
3
|
+
};
|
|
4
|
+
type DeviceStatFn = (path: string) => Promise<DeviceStat>;
|
|
5
|
+
/** @internal */
|
|
6
|
+
export declare const DOWNLOAD_STAGING_DIRECTORY_NAME = ".b2sdk-download-staging";
|
|
7
|
+
/** @internal */
|
|
8
|
+
export declare const DOWNLOAD_STAGING_MARKER_NAME = ".b2sdk-staging-marker.partial";
|
|
9
|
+
/** @internal */
|
|
10
|
+
export declare const DOWNLOAD_STAGING_ACTIVITY_ENTRY_LIMIT = 1024;
|
|
11
|
+
/**
|
|
12
|
+
* Checks whether a single path segment matches the SDK-managed staging directory name.
|
|
13
|
+
* @param segment - Candidate path segment.
|
|
14
|
+
*
|
|
15
|
+
* @returns True when the segment is the reserved staging directory name under
|
|
16
|
+
* local filesystem canonicalization.
|
|
17
|
+
*
|
|
18
|
+
* @internal
|
|
19
|
+
*/
|
|
20
|
+
export declare function isDownloadStagingDirectorySegment(segment: string | undefined): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Creates a private SDK-managed staging directory under a local sync root.
|
|
23
|
+
* @param rootRealPath - Resolved local sync root path.
|
|
24
|
+
* @param path - Node path module used for platform-specific path operations.
|
|
25
|
+
* @param randomUUID - UUID provider used to create unique staging entries.
|
|
26
|
+
* @param statForDeviceCheck - Stat function used to verify filesystem devices.
|
|
27
|
+
* @param beforeStagingMarkerWrite - Test hook called before marker creation.
|
|
28
|
+
*
|
|
29
|
+
* @returns The resolved staging directory path.
|
|
30
|
+
*
|
|
31
|
+
* @internal
|
|
32
|
+
*/
|
|
33
|
+
export declare function createDownloadStagingDirectory(rootRealPath: string, path: typeof import('node:path'), randomUUID: () => string, statForDeviceCheck: DeviceStatFn, beforeStagingMarkerWrite?: (directory: string) => Promise<void> | void): Promise<string>;
|
|
34
|
+
/**
|
|
35
|
+
* Returns true when a scan-root entry is an SDK-managed download staging root.
|
|
36
|
+
* @param directory - Candidate directory to inspect.
|
|
37
|
+
*
|
|
38
|
+
* @returns True when the directory contains SDK staging markers.
|
|
39
|
+
*
|
|
40
|
+
* @internal
|
|
41
|
+
*/
|
|
42
|
+
export declare function isManagedDownloadStagingRoot(directory: string): Promise<boolean>;
|
|
43
|
+
/**
|
|
44
|
+
* Verifies that a candidate path is on the same filesystem device as the root.
|
|
45
|
+
* @param rootRealPath - Resolved local sync root path.
|
|
46
|
+
* @param candidateRealPath - Resolved candidate path to compare.
|
|
47
|
+
* @param statForDeviceCheck - Stat function used to read device IDs.
|
|
48
|
+
* @param message - Error message used when devices differ.
|
|
49
|
+
*
|
|
50
|
+
* @internal
|
|
51
|
+
*/
|
|
52
|
+
export declare function assertDownloadPathSameDevice(rootRealPath: string, candidateRealPath: string, statForDeviceCheck: DeviceStatFn, message: string): Promise<void>;
|
|
53
|
+
export {};
|
|
54
|
+
//# sourceMappingURL=download-staging.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"download-staging.d.ts","sourceRoot":"","sources":["../../src/sync/download-staging.js"],"names":[],"mappings":"AAEA,KAAK,UAAU,GAAG;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAAA;AACnD,KAAK,YAAY,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,CAAA;AAEzD,gBAAgB;AAChB,eAAO,MAAM,+BAA+B,4BAA4B,CAAA;AACxE,gBAAgB;AAChB,eAAO,MAAM,4BAA4B,kCAAkC,CAAA;AAS3E,gBAAgB;AAChB,eAAO,MAAM,qCAAqC,OAAO,CAAA;AAazD;;;;;;;;GAQG;AACH,wBAAgB,iCAAiC,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAKtF;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,8BAA8B,CAClD,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,cAAc,WAAW,CAAC,EAChC,UAAU,EAAE,MAAM,MAAM,EACxB,kBAAkB,EAAE,YAAY,EAChC,wBAAwB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,GACrE,OAAO,CAAC,MAAM,CAAC,CA6DjB;AAED;;;;;;;GAOG;AACH,wBAAsB,4BAA4B,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CA8BtF;AAkCD;;;;;;;;GAQG;AACH,wBAAsB,4BAA4B,CAChD,YAAY,EAAE,MAAM,EACpB,iBAAiB,EAAE,MAAM,EACzB,kBAAkB,EAAE,YAAY,EAChC,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAMf"}
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import { assertPathInsideRoot, hasErrorCode, noFollowFlag } from "./path-safety.js";
|
|
2
|
+
//#region src/sync/download-staging.ts
|
|
3
|
+
/** @internal */
|
|
4
|
+
var DOWNLOAD_STAGING_DIRECTORY_NAME = ".b2sdk-download-staging";
|
|
5
|
+
/** @internal */
|
|
6
|
+
var DOWNLOAD_STAGING_MARKER_NAME = ".b2sdk-staging-marker.partial";
|
|
7
|
+
var CANONICAL_DOWNLOAD_STAGING_DIRECTORY_NAME = canonicalLocalFilesystemSegment(DOWNLOAD_STAGING_DIRECTORY_NAME);
|
|
8
|
+
var DOWNLOAD_STAGING_ENTRY_SUFFIX = ".download";
|
|
9
|
+
var STALE_DOWNLOAD_STAGING_AGE_MS = 1440 * 60 * 1e3;
|
|
10
|
+
var MAX_STAGING_CLEANUP_CONCURRENCY = 8;
|
|
11
|
+
var MAX_CLEANUP_WARNING_ENTRIES = 3;
|
|
12
|
+
/** @internal */
|
|
13
|
+
var DOWNLOAD_STAGING_ACTIVITY_ENTRY_LIMIT = 1024;
|
|
14
|
+
var reapedManagedDirectories = /* @__PURE__ */ new Map();
|
|
15
|
+
/**
|
|
16
|
+
* Checks whether a single path segment matches the SDK-managed staging directory name.
|
|
17
|
+
* @param segment - Candidate path segment.
|
|
18
|
+
*
|
|
19
|
+
* @returns True when the segment is the reserved staging directory name under
|
|
20
|
+
* local filesystem canonicalization.
|
|
21
|
+
*
|
|
22
|
+
* @internal
|
|
23
|
+
*/
|
|
24
|
+
function isDownloadStagingDirectorySegment(segment) {
|
|
25
|
+
return segment !== void 0 && canonicalLocalFilesystemSegment(segment) === CANONICAL_DOWNLOAD_STAGING_DIRECTORY_NAME;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Creates a private SDK-managed staging directory under a local sync root.
|
|
29
|
+
* @param rootRealPath - Resolved local sync root path.
|
|
30
|
+
* @param path - Node path module used for platform-specific path operations.
|
|
31
|
+
* @param randomUUID - UUID provider used to create unique staging entries.
|
|
32
|
+
* @param statForDeviceCheck - Stat function used to verify filesystem devices.
|
|
33
|
+
* @param beforeStagingMarkerWrite - Test hook called before marker creation.
|
|
34
|
+
*
|
|
35
|
+
* @returns The resolved staging directory path.
|
|
36
|
+
*
|
|
37
|
+
* @internal
|
|
38
|
+
*/
|
|
39
|
+
async function createDownloadStagingDirectory(rootRealPath, path, randomUUID, statForDeviceCheck, beforeStagingMarkerWrite) {
|
|
40
|
+
const { chmod, lstat, mkdir, readdir, realpath, rm } = await import("node:fs/promises");
|
|
41
|
+
const managedDirectory = path.join(rootRealPath, DOWNLOAD_STAGING_DIRECTORY_NAME);
|
|
42
|
+
try {
|
|
43
|
+
await mkdir(managedDirectory, { mode: PRIVATE_DOWNLOAD_DIRECTORY_MODE });
|
|
44
|
+
} catch (err) {
|
|
45
|
+
if (!hasErrorCode(err, "EEXIST")) throw err;
|
|
46
|
+
}
|
|
47
|
+
if (!(await lstat(managedDirectory)).isDirectory()) throw new Error(`unsafe local destination path: ${DOWNLOAD_STAGING_DIRECTORY_NAME} is not a directory`);
|
|
48
|
+
const realManagedDirectory = await realpath(managedDirectory);
|
|
49
|
+
assertPathInsideRoot(rootRealPath, realManagedDirectory, path);
|
|
50
|
+
await assertDownloadPathSameDevice(rootRealPath, realManagedDirectory, statForDeviceCheck, "unsafe local destination path: cannot stage download across filesystems");
|
|
51
|
+
if (!await isManagedDownloadStagingRoot(realManagedDirectory)) {
|
|
52
|
+
if ((await readdir(realManagedDirectory)).length > 0 && !await isManagedDownloadStagingRoot(realManagedDirectory)) throw new Error(`unsafe local destination path: ${DOWNLOAD_STAGING_DIRECTORY_NAME} is reserved for SDK download staging`);
|
|
53
|
+
}
|
|
54
|
+
await beforeStagingMarkerWrite?.(realManagedDirectory);
|
|
55
|
+
await writeStagingMarker(realManagedDirectory, path);
|
|
56
|
+
/* v8 ignore next -- best-effort chmod */
|
|
57
|
+
await chmod(realManagedDirectory, PRIVATE_DOWNLOAD_DIRECTORY_MODE).catch(() => {});
|
|
58
|
+
await reapStaleDownloadStagingDirectoriesOnce(realManagedDirectory, path, Date.now());
|
|
59
|
+
const stagingDirectory = path.join(realManagedDirectory, `${Date.now()}-${randomUUID()}${DOWNLOAD_STAGING_ENTRY_SUFFIX}`);
|
|
60
|
+
await mkdir(stagingDirectory, { mode: PRIVATE_DOWNLOAD_DIRECTORY_MODE });
|
|
61
|
+
/* v8 ignore next -- best-effort chmod */
|
|
62
|
+
await chmod(stagingDirectory, PRIVATE_DOWNLOAD_DIRECTORY_MODE).catch(() => {});
|
|
63
|
+
try {
|
|
64
|
+
const realStagingDirectory = await realpath(stagingDirectory);
|
|
65
|
+
assertPathInsideRoot(realManagedDirectory, realStagingDirectory, path);
|
|
66
|
+
await assertDownloadPathSameDevice(rootRealPath, realStagingDirectory, statForDeviceCheck, "unsafe local destination path: cannot stage download across filesystems");
|
|
67
|
+
await beforeStagingMarkerWrite?.(realStagingDirectory);
|
|
68
|
+
await writeStagingMarker(realStagingDirectory, path);
|
|
69
|
+
return realStagingDirectory;
|
|
70
|
+
} catch (err) {
|
|
71
|
+
/* v8 ignore next -- best-effort cleanup */
|
|
72
|
+
await rm(stagingDirectory, {
|
|
73
|
+
recursive: true,
|
|
74
|
+
force: true
|
|
75
|
+
}).catch(() => {});
|
|
76
|
+
throw err;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Returns true when a scan-root entry is an SDK-managed download staging root.
|
|
81
|
+
* @param directory - Candidate directory to inspect.
|
|
82
|
+
*
|
|
83
|
+
* @returns True when the directory contains SDK staging markers.
|
|
84
|
+
*
|
|
85
|
+
* @internal
|
|
86
|
+
*/
|
|
87
|
+
async function isManagedDownloadStagingRoot(directory) {
|
|
88
|
+
const { lstat, readdir } = await import("node:fs/promises");
|
|
89
|
+
const path = await import("node:path");
|
|
90
|
+
try {
|
|
91
|
+
if ((await lstat(path.join(directory, ".b2sdk-staging-marker.partial"))).isFile()) return true;
|
|
92
|
+
} catch (err) {
|
|
93
|
+
if (!hasErrorCode(err, "ENOENT")) return false;
|
|
94
|
+
}
|
|
95
|
+
let entries;
|
|
96
|
+
try {
|
|
97
|
+
entries = await readdir(directory, { withFileTypes: true });
|
|
98
|
+
} catch {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
for (const entry of entries) {
|
|
102
|
+
if (!entry.isDirectory() || !entry.name.endsWith(DOWNLOAD_STAGING_ENTRY_SUFFIX)) continue;
|
|
103
|
+
try {
|
|
104
|
+
if ((await lstat(path.join(directory, entry.name, ".b2sdk-staging-marker.partial"))).isFile()) return true;
|
|
105
|
+
} catch {}
|
|
106
|
+
}
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
var PRIVATE_DOWNLOAD_FILE_MODE = 384;
|
|
110
|
+
var PRIVATE_DOWNLOAD_DIRECTORY_MODE = 448;
|
|
111
|
+
async function writeStagingMarker(directory, path) {
|
|
112
|
+
const { constants } = await import("node:fs");
|
|
113
|
+
const { lstat, open } = await import("node:fs/promises");
|
|
114
|
+
const markerPath = path.join(directory, DOWNLOAD_STAGING_MARKER_NAME);
|
|
115
|
+
let handle;
|
|
116
|
+
try {
|
|
117
|
+
handle = await open(markerPath, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | noFollowFlag(constants), PRIVATE_DOWNLOAD_FILE_MODE);
|
|
118
|
+
/* v8 ignore next -- best-effort chmod */
|
|
119
|
+
await handle.chmod(PRIVATE_DOWNLOAD_FILE_MODE).catch(() => {});
|
|
120
|
+
} catch (err) {
|
|
121
|
+
if (hasErrorCode(err, "EEXIST") || hasErrorCode(err, "ELOOP")) {
|
|
122
|
+
if ((await lstat(markerPath).catch(() => void 0))?.isFile() === true) return;
|
|
123
|
+
throw new Error("unsafe local destination path: staging marker is not a regular file");
|
|
124
|
+
}
|
|
125
|
+
throw err;
|
|
126
|
+
} finally {
|
|
127
|
+
/* v8 ignore next -- best-effort close */
|
|
128
|
+
await handle?.close().catch(() => {});
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Verifies that a candidate path is on the same filesystem device as the root.
|
|
133
|
+
* @param rootRealPath - Resolved local sync root path.
|
|
134
|
+
* @param candidateRealPath - Resolved candidate path to compare.
|
|
135
|
+
* @param statForDeviceCheck - Stat function used to read device IDs.
|
|
136
|
+
* @param message - Error message used when devices differ.
|
|
137
|
+
*
|
|
138
|
+
* @internal
|
|
139
|
+
*/
|
|
140
|
+
async function assertDownloadPathSameDevice(rootRealPath, candidateRealPath, statForDeviceCheck, message) {
|
|
141
|
+
const [rootStats, candidateStats] = await Promise.all([statForDeviceCheck(rootRealPath), statForDeviceCheck(candidateRealPath)]);
|
|
142
|
+
if (rootStats.dev !== candidateStats.dev) throw new Error(message);
|
|
143
|
+
}
|
|
144
|
+
async function reapStaleDownloadStagingDirectoriesOnce(managedDirectory, path, nowMillis) {
|
|
145
|
+
const previous = reapedManagedDirectories.get(managedDirectory);
|
|
146
|
+
if (previous !== void 0) {
|
|
147
|
+
await previous;
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
const next = reapStaleDownloadStagingDirectories(managedDirectory, path, nowMillis).finally(() => {
|
|
151
|
+
if (reapedManagedDirectories.get(managedDirectory) === next) reapedManagedDirectories.delete(managedDirectory);
|
|
152
|
+
});
|
|
153
|
+
reapedManagedDirectories.set(managedDirectory, next);
|
|
154
|
+
await next;
|
|
155
|
+
}
|
|
156
|
+
async function reapStaleDownloadStagingDirectories(managedDirectory, path, nowMillis) {
|
|
157
|
+
const { readdir, realpath, rm } = await import("node:fs/promises");
|
|
158
|
+
let entries;
|
|
159
|
+
try {
|
|
160
|
+
entries = await readdir(managedDirectory, { withFileTypes: true });
|
|
161
|
+
} catch (err) {
|
|
162
|
+
if (hasErrorCode(err, "ENOENT")) return;
|
|
163
|
+
emitCleanupWarning("failed to inspect B2 SDK download staging entries");
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
const cleanupErrors = [];
|
|
167
|
+
await forEachWithConcurrency(entries, MAX_STAGING_CLEANUP_CONCURRENCY, async (entry) => {
|
|
168
|
+
if (!entry.isDirectory() || !entry.name.endsWith(DOWNLOAD_STAGING_ENTRY_SUFFIX)) return;
|
|
169
|
+
const candidate = path.join(managedDirectory, entry.name);
|
|
170
|
+
const activity = await readManagedStagingEntryActivity(candidate, path);
|
|
171
|
+
if (activity === void 0 || !stagingActivityIsStale(activity, nowMillis)) return;
|
|
172
|
+
const realCandidate = await realpath(candidate).catch(() => {
|
|
173
|
+
cleanupErrors.push({
|
|
174
|
+
entryName: entry.name,
|
|
175
|
+
operation: "inspect"
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
if (realCandidate === void 0) return;
|
|
179
|
+
try {
|
|
180
|
+
assertPathInsideRoot(managedDirectory, realCandidate, path);
|
|
181
|
+
const latestActivity = await readManagedStagingEntryActivity(candidate, path);
|
|
182
|
+
if (latestActivity === void 0 || latestActivity.signature !== activity.signature || !stagingActivityIsStale(latestActivity, nowMillis)) return;
|
|
183
|
+
await rm(realCandidate, {
|
|
184
|
+
recursive: true,
|
|
185
|
+
force: true
|
|
186
|
+
});
|
|
187
|
+
} catch {
|
|
188
|
+
cleanupErrors.push({
|
|
189
|
+
entryName: entry.name,
|
|
190
|
+
operation: "remove"
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
if (cleanupErrors.length > 0) {
|
|
195
|
+
const noun = cleanupErrors.length === 1 ? "entry" : "entries";
|
|
196
|
+
emitCleanupWarning(`failed to reap ${cleanupErrors.length} stale B2 SDK download staging ${noun}: ${cleanupErrors.slice(0, MAX_CLEANUP_WARNING_ENTRIES).map(formatCleanupWarning).join("; ")}`);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
async function readManagedStagingEntryActivity(candidate, path) {
|
|
200
|
+
const { lstat, readdir } = await import("node:fs/promises");
|
|
201
|
+
try {
|
|
202
|
+
const [directoryStats, markerStats] = await Promise.all([lstat(candidate), lstat(path.join(candidate, DOWNLOAD_STAGING_MARKER_NAME))]);
|
|
203
|
+
if (!directoryStats.isDirectory() || !markerStats.isFile()) return void 0;
|
|
204
|
+
const entries = await readdir(candidate, { withFileTypes: true });
|
|
205
|
+
if (entries.length > 1024) return void 0;
|
|
206
|
+
const statsParts = [`.:${stagingStatsSignature(directoryStats)}`, `${DOWNLOAD_STAGING_MARKER_NAME}:${stagingStatsSignature(markerStats)}`];
|
|
207
|
+
let newestActivityMs = Math.max(stagingStatsActivityMs(directoryStats), stagingStatsActivityMs(markerStats));
|
|
208
|
+
for (const entry of [...entries].sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0)) {
|
|
209
|
+
const stats = await lstat(path.join(candidate, entry.name));
|
|
210
|
+
statsParts.push(`${entry.name}:${stagingStatsSignature(stats)}`);
|
|
211
|
+
newestActivityMs = Math.max(newestActivityMs, stagingStatsActivityMs(stats));
|
|
212
|
+
}
|
|
213
|
+
return {
|
|
214
|
+
newestActivityMs,
|
|
215
|
+
signature: statsParts.join("|")
|
|
216
|
+
};
|
|
217
|
+
} catch {
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
function stagingStatsActivityMs(stats) {
|
|
222
|
+
return stats.mtimeMs;
|
|
223
|
+
}
|
|
224
|
+
function stagingStatsSignature(stats) {
|
|
225
|
+
return `${stats.dev}:${stats.ino}:${stats.size}:${stats.mtimeMs}:${stats.ctimeMs}`;
|
|
226
|
+
}
|
|
227
|
+
function stagingActivityIsStale(activity, nowMillis) {
|
|
228
|
+
return nowMillis - activity.newestActivityMs >= STALE_DOWNLOAD_STAGING_AGE_MS;
|
|
229
|
+
}
|
|
230
|
+
function formatCleanupWarning(error) {
|
|
231
|
+
return `${error.operation} ${safeWarningName(error.entryName)}`;
|
|
232
|
+
}
|
|
233
|
+
function safeWarningName(name) {
|
|
234
|
+
const chars = Array.from(name);
|
|
235
|
+
const bounded = chars.slice(0, 80).join("");
|
|
236
|
+
const suffix = chars.length > 80 ? "..." : "";
|
|
237
|
+
return JSON.stringify(`${bounded.replace(/[^A-Za-z0-9._-]/g, "?")}${suffix}`);
|
|
238
|
+
}
|
|
239
|
+
function canonicalLocalFilesystemSegment(segment) {
|
|
240
|
+
return segment.normalize("NFC").toLocaleLowerCase("en-US");
|
|
241
|
+
}
|
|
242
|
+
async function forEachWithConcurrency(items, concurrency, fn) {
|
|
243
|
+
let index = 0;
|
|
244
|
+
const workers = Array.from({ length: Math.min(concurrency, items.length) }, async () => {
|
|
245
|
+
while (index < items.length) {
|
|
246
|
+
const item = items[index];
|
|
247
|
+
index += 1;
|
|
248
|
+
if (item !== void 0) await fn(item);
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
await Promise.all(workers);
|
|
252
|
+
}
|
|
253
|
+
function emitCleanupWarning(message) {
|
|
254
|
+
globalThis.process?.emitWarning?.(message, { code: "B2SDK_DOWNLOAD_STAGING_CLEANUP_FAILED" });
|
|
255
|
+
}
|
|
256
|
+
//#endregion
|
|
257
|
+
export { DOWNLOAD_STAGING_ACTIVITY_ENTRY_LIMIT, DOWNLOAD_STAGING_DIRECTORY_NAME, DOWNLOAD_STAGING_MARKER_NAME, assertDownloadPathSameDevice, createDownloadStagingDirectory, isDownloadStagingDirectorySegment, isManagedDownloadStagingRoot };
|
|
258
|
+
|
|
259
|
+
//# sourceMappingURL=download-staging.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"download-staging.js","names":[],"sources":["../../src/sync/download-staging.ts"],"sourcesContent":["import { assertPathInsideRoot, hasErrorCode, noFollowFlag } from './path-safety.ts'\n\ntype DeviceStat = { readonly dev: number | bigint }\ntype DeviceStatFn = (path: string) => Promise<DeviceStat>\n\n/** @internal */\nexport const DOWNLOAD_STAGING_DIRECTORY_NAME = '.b2sdk-download-staging'\n/** @internal */\nexport const DOWNLOAD_STAGING_MARKER_NAME = '.b2sdk-staging-marker.partial'\n\nconst CANONICAL_DOWNLOAD_STAGING_DIRECTORY_NAME = canonicalLocalFilesystemSegment(\n DOWNLOAD_STAGING_DIRECTORY_NAME,\n)\nconst DOWNLOAD_STAGING_ENTRY_SUFFIX = '.download'\nconst STALE_DOWNLOAD_STAGING_AGE_MS = 24 * 60 * 60 * 1000\nconst MAX_STAGING_CLEANUP_CONCURRENCY = 8\nconst MAX_CLEANUP_WARNING_ENTRIES = 3\n/** @internal */\nexport const DOWNLOAD_STAGING_ACTIVITY_ENTRY_LIMIT = 1024\nconst reapedManagedDirectories = new Map<string, Promise<void>>()\n\ntype StagingActivitySnapshot = {\n readonly newestActivityMs: number\n readonly signature: string\n}\n\ntype CleanupWarning = {\n readonly entryName: string\n readonly operation: 'inspect' | 'remove'\n}\n\n/**\n * Checks whether a single path segment matches the SDK-managed staging directory name.\n * @param segment - Candidate path segment.\n *\n * @returns True when the segment is the reserved staging directory name under\n * local filesystem canonicalization.\n *\n * @internal\n */\nexport function isDownloadStagingDirectorySegment(segment: string | undefined): boolean {\n return (\n segment !== undefined &&\n canonicalLocalFilesystemSegment(segment) === CANONICAL_DOWNLOAD_STAGING_DIRECTORY_NAME\n )\n}\n\n/**\n * Creates a private SDK-managed staging directory under a local sync root.\n * @param rootRealPath - Resolved local sync root path.\n * @param path - Node path module used for platform-specific path operations.\n * @param randomUUID - UUID provider used to create unique staging entries.\n * @param statForDeviceCheck - Stat function used to verify filesystem devices.\n * @param beforeStagingMarkerWrite - Test hook called before marker creation.\n *\n * @returns The resolved staging directory path.\n *\n * @internal\n */\nexport async function createDownloadStagingDirectory(\n rootRealPath: string,\n path: typeof import('node:path'),\n randomUUID: () => string,\n statForDeviceCheck: DeviceStatFn,\n beforeStagingMarkerWrite?: (directory: string) => Promise<void> | void,\n): Promise<string> {\n const { chmod, lstat, mkdir, readdir, realpath, rm } = await import('node:fs/promises')\n const managedDirectory = path.join(rootRealPath, DOWNLOAD_STAGING_DIRECTORY_NAME)\n try {\n await mkdir(managedDirectory, { mode: PRIVATE_DOWNLOAD_DIRECTORY_MODE })\n } catch (err) {\n if (!hasErrorCode(err, 'EEXIST')) throw err\n }\n const managedStats = await lstat(managedDirectory)\n if (!managedStats.isDirectory()) {\n throw new Error(\n `unsafe local destination path: ${DOWNLOAD_STAGING_DIRECTORY_NAME} is not a directory`,\n )\n }\n const realManagedDirectory = await realpath(managedDirectory)\n assertPathInsideRoot(rootRealPath, realManagedDirectory, path)\n await assertDownloadPathSameDevice(\n rootRealPath,\n realManagedDirectory,\n statForDeviceCheck,\n 'unsafe local destination path: cannot stage download across filesystems',\n )\n\n if (!(await isManagedDownloadStagingRoot(realManagedDirectory))) {\n const entries = await readdir(realManagedDirectory)\n if (entries.length > 0 && !(await isManagedDownloadStagingRoot(realManagedDirectory))) {\n throw new Error(\n `unsafe local destination path: ${DOWNLOAD_STAGING_DIRECTORY_NAME} is reserved for SDK download staging`,\n )\n }\n }\n await beforeStagingMarkerWrite?.(realManagedDirectory)\n await writeStagingMarker(realManagedDirectory, path)\n /* v8 ignore next -- best-effort chmod */\n await chmod(realManagedDirectory, PRIVATE_DOWNLOAD_DIRECTORY_MODE).catch(() => {})\n await reapStaleDownloadStagingDirectoriesOnce(realManagedDirectory, path, Date.now())\n\n const stagingDirectory = path.join(\n realManagedDirectory,\n `${Date.now()}-${randomUUID()}${DOWNLOAD_STAGING_ENTRY_SUFFIX}`,\n )\n await mkdir(stagingDirectory, { mode: PRIVATE_DOWNLOAD_DIRECTORY_MODE })\n /* v8 ignore next -- best-effort chmod */\n await chmod(stagingDirectory, PRIVATE_DOWNLOAD_DIRECTORY_MODE).catch(() => {})\n try {\n const realStagingDirectory = await realpath(stagingDirectory)\n assertPathInsideRoot(realManagedDirectory, realStagingDirectory, path)\n await assertDownloadPathSameDevice(\n rootRealPath,\n realStagingDirectory,\n statForDeviceCheck,\n 'unsafe local destination path: cannot stage download across filesystems',\n )\n await beforeStagingMarkerWrite?.(realStagingDirectory)\n await writeStagingMarker(realStagingDirectory, path)\n return realStagingDirectory\n } catch (err) {\n /* v8 ignore next -- best-effort cleanup */\n await rm(stagingDirectory, { recursive: true, force: true }).catch(() => {})\n throw err\n }\n}\n\n/**\n * Returns true when a scan-root entry is an SDK-managed download staging root.\n * @param directory - Candidate directory to inspect.\n *\n * @returns True when the directory contains SDK staging markers.\n *\n * @internal\n */\nexport async function isManagedDownloadStagingRoot(directory: string): Promise<boolean> {\n const { lstat, readdir } = await import('node:fs/promises')\n const path = await import('node:path')\n\n try {\n const markerStats = await lstat(path.join(directory, DOWNLOAD_STAGING_MARKER_NAME))\n if (markerStats.isFile()) return true\n } catch (err) {\n if (!hasErrorCode(err, 'ENOENT')) return false\n }\n\n let entries: import('node:fs').Dirent[]\n try {\n entries = await readdir(directory, { withFileTypes: true })\n } catch {\n return false\n }\n\n for (const entry of entries) {\n if (!entry.isDirectory() || !entry.name.endsWith(DOWNLOAD_STAGING_ENTRY_SUFFIX)) continue\n try {\n const markerStats = await lstat(\n path.join(directory, entry.name, DOWNLOAD_STAGING_MARKER_NAME),\n )\n if (markerStats.isFile()) return true\n } catch {\n // Keep checking siblings; one corrupt entry should not hide user content.\n }\n }\n return false\n}\n\nconst PRIVATE_DOWNLOAD_FILE_MODE = 0o600\nconst PRIVATE_DOWNLOAD_DIRECTORY_MODE = 0o700\n\nasync function writeStagingMarker(\n directory: string,\n path: typeof import('node:path'),\n): Promise<void> {\n const { constants } = await import('node:fs')\n const { lstat, open } = await import('node:fs/promises')\n const markerPath = path.join(directory, DOWNLOAD_STAGING_MARKER_NAME)\n let handle: Awaited<ReturnType<typeof open>> | undefined\n try {\n handle = await open(\n markerPath,\n constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | noFollowFlag(constants),\n PRIVATE_DOWNLOAD_FILE_MODE,\n )\n /* v8 ignore next -- best-effort chmod */\n await handle.chmod(PRIVATE_DOWNLOAD_FILE_MODE).catch(() => {})\n } catch (err) {\n if (hasErrorCode(err, 'EEXIST') || hasErrorCode(err, 'ELOOP')) {\n const markerStats = await lstat(markerPath).catch(() => undefined)\n if (markerStats?.isFile() === true) return\n throw new Error('unsafe local destination path: staging marker is not a regular file')\n }\n throw err\n } finally {\n /* v8 ignore next -- best-effort close */\n await handle?.close().catch(() => {})\n }\n}\n\n/**\n * Verifies that a candidate path is on the same filesystem device as the root.\n * @param rootRealPath - Resolved local sync root path.\n * @param candidateRealPath - Resolved candidate path to compare.\n * @param statForDeviceCheck - Stat function used to read device IDs.\n * @param message - Error message used when devices differ.\n *\n * @internal\n */\nexport async function assertDownloadPathSameDevice(\n rootRealPath: string,\n candidateRealPath: string,\n statForDeviceCheck: DeviceStatFn,\n message: string,\n): Promise<void> {\n const [rootStats, candidateStats] = await Promise.all([\n statForDeviceCheck(rootRealPath),\n statForDeviceCheck(candidateRealPath),\n ])\n if (rootStats.dev !== candidateStats.dev) throw new Error(message)\n}\n\nasync function reapStaleDownloadStagingDirectoriesOnce(\n managedDirectory: string,\n path: typeof import('node:path'),\n nowMillis: number,\n): Promise<void> {\n const previous = reapedManagedDirectories.get(managedDirectory)\n if (previous !== undefined) {\n await previous\n return\n }\n\n const next = reapStaleDownloadStagingDirectories(managedDirectory, path, nowMillis).finally(\n () => {\n if (reapedManagedDirectories.get(managedDirectory) === next) {\n reapedManagedDirectories.delete(managedDirectory)\n }\n },\n )\n reapedManagedDirectories.set(managedDirectory, next)\n await next\n}\n\nasync function reapStaleDownloadStagingDirectories(\n managedDirectory: string,\n path: typeof import('node:path'),\n nowMillis: number,\n): Promise<void> {\n const { readdir, realpath, rm } = await import('node:fs/promises')\n let entries: import('node:fs').Dirent[]\n try {\n entries = await readdir(managedDirectory, { withFileTypes: true })\n } catch (err) {\n if (hasErrorCode(err, 'ENOENT')) return\n emitCleanupWarning('failed to inspect B2 SDK download staging entries')\n return\n }\n\n const cleanupErrors: CleanupWarning[] = []\n await forEachWithConcurrency(entries, MAX_STAGING_CLEANUP_CONCURRENCY, async (entry) => {\n if (!entry.isDirectory() || !entry.name.endsWith(DOWNLOAD_STAGING_ENTRY_SUFFIX)) return\n const candidate = path.join(managedDirectory, entry.name)\n const activity = await readManagedStagingEntryActivity(candidate, path)\n if (activity === undefined || !stagingActivityIsStale(activity, nowMillis)) return\n const realCandidate = await realpath(candidate).catch(() => {\n cleanupErrors.push({ entryName: entry.name, operation: 'inspect' })\n return undefined\n })\n if (realCandidate === undefined) return\n try {\n assertPathInsideRoot(managedDirectory, realCandidate, path)\n const latestActivity = await readManagedStagingEntryActivity(candidate, path)\n if (\n latestActivity === undefined ||\n latestActivity.signature !== activity.signature ||\n !stagingActivityIsStale(latestActivity, nowMillis)\n ) {\n return\n }\n await rm(realCandidate, { recursive: true, force: true })\n } catch {\n cleanupErrors.push({ entryName: entry.name, operation: 'remove' })\n }\n })\n\n if (cleanupErrors.length > 0) {\n const noun = cleanupErrors.length === 1 ? 'entry' : 'entries'\n emitCleanupWarning(\n `failed to reap ${cleanupErrors.length} stale B2 SDK download staging ${noun}: ${cleanupErrors\n .slice(0, MAX_CLEANUP_WARNING_ENTRIES)\n .map(formatCleanupWarning)\n .join('; ')}`,\n )\n }\n}\n\nasync function readManagedStagingEntryActivity(\n candidate: string,\n path: typeof import('node:path'),\n): Promise<StagingActivitySnapshot | undefined> {\n const { lstat, readdir } = await import('node:fs/promises')\n\n try {\n const [directoryStats, markerStats] = await Promise.all([\n lstat(candidate),\n lstat(path.join(candidate, DOWNLOAD_STAGING_MARKER_NAME)),\n ])\n if (!directoryStats.isDirectory() || !markerStats.isFile()) return undefined\n\n const entries = await readdir(candidate, { withFileTypes: true })\n if (entries.length > DOWNLOAD_STAGING_ACTIVITY_ENTRY_LIMIT) return undefined\n\n const statsParts = [\n `.:${stagingStatsSignature(directoryStats)}`,\n `${DOWNLOAD_STAGING_MARKER_NAME}:${stagingStatsSignature(markerStats)}`,\n ]\n let newestActivityMs = Math.max(\n stagingStatsActivityMs(directoryStats),\n stagingStatsActivityMs(markerStats),\n )\n\n for (const entry of [...entries].sort((a, b) =>\n a.name < b.name ? -1 : a.name > b.name ? 1 : 0,\n )) {\n const stats = await lstat(path.join(candidate, entry.name))\n statsParts.push(`${entry.name}:${stagingStatsSignature(stats)}`)\n newestActivityMs = Math.max(newestActivityMs, stagingStatsActivityMs(stats))\n }\n\n return { newestActivityMs, signature: statsParts.join('|') }\n } catch {\n return undefined\n }\n}\n\nfunction stagingStatsActivityMs(stats: { readonly mtimeMs: number }) {\n return stats.mtimeMs\n}\n\nfunction stagingStatsSignature(stats: {\n readonly ctimeMs: number\n readonly dev: number | bigint\n readonly ino: number | bigint\n readonly mtimeMs: number\n readonly size: number\n}): string {\n return `${stats.dev}:${stats.ino}:${stats.size}:${stats.mtimeMs}:${stats.ctimeMs}`\n}\n\nfunction stagingActivityIsStale(activity: StagingActivitySnapshot, nowMillis: number): boolean {\n return nowMillis - activity.newestActivityMs >= STALE_DOWNLOAD_STAGING_AGE_MS\n}\n\nfunction formatCleanupWarning(error: CleanupWarning): string {\n return `${error.operation} ${safeWarningName(error.entryName)}`\n}\n\nfunction safeWarningName(name: string): string {\n const chars = Array.from(name)\n const bounded = chars.slice(0, 80).join('')\n const suffix = chars.length > 80 ? '...' : ''\n return JSON.stringify(`${bounded.replace(/[^A-Za-z0-9._-]/g, '?')}${suffix}`)\n}\n\nfunction canonicalLocalFilesystemSegment(segment: string): string {\n return segment.normalize('NFC').toLocaleLowerCase('en-US')\n}\n\nasync function forEachWithConcurrency<T>(\n items: readonly T[],\n concurrency: number,\n fn: (item: T) => Promise<void>,\n): Promise<void> {\n let index = 0\n const workers = Array.from({ length: Math.min(concurrency, items.length) }, async () => {\n while (index < items.length) {\n const item = items[index]\n index += 1\n if (item !== undefined) await fn(item)\n }\n })\n await Promise.all(workers)\n}\n\nfunction emitCleanupWarning(message: string): void {\n const processLike = (\n globalThis as {\n process?: {\n emitWarning?: (warning: string, options?: { readonly code?: string }) => void\n }\n }\n ).process\n processLike?.emitWarning?.(message, { code: 'B2SDK_DOWNLOAD_STAGING_CLEANUP_FAILED' })\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
const require_to_error = require("../util/to-error.cjs");
|
|
2
|
+
//#region src/sync/filesystem-errors.ts
|
|
3
|
+
/**
|
|
4
|
+
* Formats local filesystem errors without including host filesystem paths.
|
|
5
|
+
* @param err - Unknown filesystem error.
|
|
6
|
+
*
|
|
7
|
+
* @returns A path-independent code or error name.
|
|
8
|
+
*/
|
|
9
|
+
function localFilesystemErrorReason(err) {
|
|
10
|
+
const error = require_to_error.toError(err);
|
|
11
|
+
const code = cleanFilesystemErrorPart(error.code);
|
|
12
|
+
if (code !== "") return code;
|
|
13
|
+
const name = cleanFilesystemErrorPart(error.name);
|
|
14
|
+
if (name !== "") return name;
|
|
15
|
+
return "Error";
|
|
16
|
+
}
|
|
17
|
+
function cleanFilesystemErrorPart(value) {
|
|
18
|
+
if (typeof value !== "string") return "";
|
|
19
|
+
let cleaned = "";
|
|
20
|
+
for (const char of value) {
|
|
21
|
+
const code = char.charCodeAt(0);
|
|
22
|
+
if (code < 32 || code === 127) continue;
|
|
23
|
+
cleaned += char;
|
|
24
|
+
if (cleaned.length >= 80) break;
|
|
25
|
+
}
|
|
26
|
+
const trimmed = cleaned.trim();
|
|
27
|
+
return /[\\/]/.test(trimmed) ? "" : trimmed;
|
|
28
|
+
}
|
|
29
|
+
//#endregion
|
|
30
|
+
exports.localFilesystemErrorReason = localFilesystemErrorReason;
|
|
31
|
+
|
|
32
|
+
//# sourceMappingURL=filesystem-errors.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filesystem-errors.cjs","names":[],"sources":["../../src/sync/filesystem-errors.ts"],"sourcesContent":["import { toError } from '../util/to-error.ts'\n\n/**\n * Formats local filesystem errors without including host filesystem paths.\n * @param err - Unknown filesystem error.\n *\n * @returns A path-independent code or error name.\n */\nexport function localFilesystemErrorReason(err: unknown): string {\n const error = toError(err)\n const code = cleanFilesystemErrorPart((error as { readonly code?: unknown }).code)\n if (code !== '') return code\n\n const name = cleanFilesystemErrorPart(error.name)\n if (name !== '') return name\n\n return 'Error'\n}\n\nfunction cleanFilesystemErrorPart(value: unknown): string {\n if (typeof value !== 'string') return ''\n let cleaned = ''\n for (const char of value) {\n const code = char.charCodeAt(0)\n if (code < 0x20 || code === 0x7f) continue\n cleaned += char\n if (cleaned.length >= 80) break\n }\n const trimmed = cleaned.trim()\n return /[\\\\/]/.test(trimmed) ? '' : trimmed\n}\n"],"mappings":";;;;;;;;AAQA,SAAgB,2BAA2B,KAAsB;CAC/D,MAAM,QAAQ,iBAAA,QAAQ,GAAG;CACzB,MAAM,OAAO,yBAA0B,MAAsC,IAAI;CACjF,IAAI,SAAS,IAAI,OAAO;CAExB,MAAM,OAAO,yBAAyB,MAAM,IAAI;CAChD,IAAI,SAAS,IAAI,OAAO;CAExB,OAAO;AACT;AAEA,SAAS,yBAAyB,OAAwB;CACxD,IAAI,OAAO,UAAU,UAAU,OAAO;CACtC,IAAI,UAAU;CACd,KAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,OAAO,KAAK,WAAW,CAAC;EAC9B,IAAI,OAAO,MAAQ,SAAS,KAAM;EAClC,WAAW;EACX,IAAI,QAAQ,UAAU,IAAI;CAC5B;CACA,MAAM,UAAU,QAAQ,KAAK;CAC7B,OAAO,QAAQ,KAAK,OAAO,IAAI,KAAK;AACtC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Formats local filesystem errors without including host filesystem paths.
|
|
3
|
+
* @param err - Unknown filesystem error.
|
|
4
|
+
*
|
|
5
|
+
* @returns A path-independent code or error name.
|
|
6
|
+
*/
|
|
7
|
+
export declare function localFilesystemErrorReason(err: unknown): string;
|
|
8
|
+
//# sourceMappingURL=filesystem-errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filesystem-errors.d.ts","sourceRoot":"","sources":["../../src/sync/filesystem-errors.js"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAS/D"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Formats local filesystem errors without including host filesystem paths.
|
|
3
|
+
* @param err - Unknown filesystem error.
|
|
4
|
+
*
|
|
5
|
+
* @returns A path-independent code or error name.
|
|
6
|
+
*/
|
|
7
|
+
export declare function localFilesystemErrorReason(err: unknown): string;
|
|
8
|
+
//# sourceMappingURL=filesystem-errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filesystem-errors.d.ts","sourceRoot":"","sources":["../../src/sync/filesystem-errors.js"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAS/D"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { toError } from "../util/to-error.js";
|
|
2
|
+
//#region src/sync/filesystem-errors.ts
|
|
3
|
+
/**
|
|
4
|
+
* Formats local filesystem errors without including host filesystem paths.
|
|
5
|
+
* @param err - Unknown filesystem error.
|
|
6
|
+
*
|
|
7
|
+
* @returns A path-independent code or error name.
|
|
8
|
+
*/
|
|
9
|
+
function localFilesystemErrorReason(err) {
|
|
10
|
+
const error = toError(err);
|
|
11
|
+
const code = cleanFilesystemErrorPart(error.code);
|
|
12
|
+
if (code !== "") return code;
|
|
13
|
+
const name = cleanFilesystemErrorPart(error.name);
|
|
14
|
+
if (name !== "") return name;
|
|
15
|
+
return "Error";
|
|
16
|
+
}
|
|
17
|
+
function cleanFilesystemErrorPart(value) {
|
|
18
|
+
if (typeof value !== "string") return "";
|
|
19
|
+
let cleaned = "";
|
|
20
|
+
for (const char of value) {
|
|
21
|
+
const code = char.charCodeAt(0);
|
|
22
|
+
if (code < 32 || code === 127) continue;
|
|
23
|
+
cleaned += char;
|
|
24
|
+
if (cleaned.length >= 80) break;
|
|
25
|
+
}
|
|
26
|
+
const trimmed = cleaned.trim();
|
|
27
|
+
return /[\\/]/.test(trimmed) ? "" : trimmed;
|
|
28
|
+
}
|
|
29
|
+
//#endregion
|
|
30
|
+
export { localFilesystemErrorReason };
|
|
31
|
+
|
|
32
|
+
//# sourceMappingURL=filesystem-errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filesystem-errors.js","names":[],"sources":["../../src/sync/filesystem-errors.ts"],"sourcesContent":["import { toError } from '../util/to-error.ts'\n\n/**\n * Formats local filesystem errors without including host filesystem paths.\n * @param err - Unknown filesystem error.\n *\n * @returns A path-independent code or error name.\n */\nexport function localFilesystemErrorReason(err: unknown): string {\n const error = toError(err)\n const code = cleanFilesystemErrorPart((error as { readonly code?: unknown }).code)\n if (code !== '') return code\n\n const name = cleanFilesystemErrorPart(error.name)\n if (name !== '') return name\n\n return 'Error'\n}\n\nfunction cleanFilesystemErrorPart(value: unknown): string {\n if (typeof value !== 'string') return ''\n let cleaned = ''\n for (const char of value) {\n const code = char.charCodeAt(0)\n if (code < 0x20 || code === 0x7f) continue\n cleaned += char\n if (cleaned.length >= 80) break\n }\n const trimmed = cleaned.trim()\n return /[\\\\/]/.test(trimmed) ? '' : trimmed\n}\n"],"mappings":";;;;;;;;AAQA,SAAgB,2BAA2B,KAAsB;CAC/D,MAAM,QAAQ,QAAQ,GAAG;CACzB,MAAM,OAAO,yBAA0B,MAAsC,IAAI;CACjF,IAAI,SAAS,IAAI,OAAO;CAExB,MAAM,OAAO,yBAAyB,MAAM,IAAI;CAChD,IAAI,SAAS,IAAI,OAAO;CAExB,OAAO;AACT;AAEA,SAAS,yBAAyB,OAAwB;CACxD,IAAI,OAAO,UAAU,UAAU,OAAO;CACtC,IAAI,UAAU;CACd,KAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,OAAO,KAAK,WAAW,CAAC;EAC9B,IAAI,OAAO,MAAQ,SAAS,KAAM;EAClC,WAAW;EACX,IAAI,QAAQ,UAAU,IAAI;CAC5B;CACA,MAAM,UAAU,QAAQ,KAAK;CAC7B,OAAO,QAAQ,KAAK,OAAO,IAAI,KAAK;AACtC"}
|