@backblaze-labs/b2-sdk 0.1.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 +121 -0
- package/LICENSE +21 -0
- package/README.md +664 -0
- package/dist/auth/account-info.d.cts +51 -0
- package/dist/auth/account-info.d.cts.map +1 -0
- package/dist/auth/account-info.d.ts +51 -0
- package/dist/auth/account-info.d.ts.map +1 -0
- package/dist/auth/file.cjs +210 -0
- package/dist/auth/file.cjs.map +1 -0
- package/dist/auth/file.d.cts +157 -0
- package/dist/auth/file.d.cts.map +1 -0
- package/dist/auth/file.d.ts +157 -0
- package/dist/auth/file.d.ts.map +1 -0
- package/dist/auth/file.js +210 -0
- package/dist/auth/file.js.map +1 -0
- package/dist/auth/in-memory.cjs +184 -0
- package/dist/auth/in-memory.cjs.map +1 -0
- package/dist/auth/in-memory.d.cts +147 -0
- package/dist/auth/in-memory.d.cts.map +1 -0
- package/dist/auth/in-memory.d.ts +147 -0
- package/dist/auth/in-memory.d.ts.map +1 -0
- package/dist/auth/in-memory.js +184 -0
- package/dist/auth/in-memory.js.map +1 -0
- package/dist/auth/index.cjs +10 -0
- package/dist/auth/index.cjs.map +1 -0
- package/dist/auth/index.d.cts +6 -0
- package/dist/auth/index.d.cts.map +1 -0
- package/dist/auth/index.d.ts +6 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +10 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/realms.cjs +12 -0
- package/dist/auth/realms.cjs.map +1 -0
- package/dist/auth/realms.d.cts +12 -0
- package/dist/auth/realms.d.cts.map +1 -0
- package/dist/auth/realms.d.ts +12 -0
- package/dist/auth/realms.d.ts.map +1 -0
- package/dist/auth/realms.js +12 -0
- package/dist/auth/realms.js.map +1 -0
- package/dist/auth/upload-url-pool.cjs +52 -0
- package/dist/auth/upload-url-pool.cjs.map +1 -0
- package/dist/auth/upload-url-pool.d.cts +35 -0
- package/dist/auth/upload-url-pool.d.cts.map +1 -0
- package/dist/auth/upload-url-pool.d.ts +35 -0
- package/dist/auth/upload-url-pool.d.ts.map +1 -0
- package/dist/auth/upload-url-pool.js +52 -0
- package/dist/auth/upload-url-pool.js.map +1 -0
- package/dist/bucket.cjs +789 -0
- package/dist/bucket.cjs.map +1 -0
- package/dist/bucket.d.cts +659 -0
- package/dist/bucket.d.cts.map +1 -0
- package/dist/bucket.d.ts +659 -0
- package/dist/bucket.d.ts.map +1 -0
- package/dist/bucket.js +789 -0
- package/dist/bucket.js.map +1 -0
- package/dist/client.cjs +230 -0
- package/dist/client.cjs.map +1 -0
- package/dist/client.d.cts +222 -0
- package/dist/client.d.cts.map +1 -0
- package/dist/client.d.ts +222 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +230 -0
- package/dist/client.js.map +1 -0
- package/dist/copy/large.cjs +74 -0
- package/dist/copy/large.cjs.map +1 -0
- package/dist/copy/large.d.cts +53 -0
- package/dist/copy/large.d.cts.map +1 -0
- package/dist/copy/large.d.ts +53 -0
- package/dist/copy/large.d.ts.map +1 -0
- package/dist/copy/large.js +74 -0
- package/dist/copy/large.js.map +1 -0
- package/dist/download/parallel.cjs +122 -0
- package/dist/download/parallel.cjs.map +1 -0
- package/dist/download/parallel.d.cts +42 -0
- package/dist/download/parallel.d.cts.map +1 -0
- package/dist/download/parallel.d.ts +42 -0
- package/dist/download/parallel.d.ts.map +1 -0
- package/dist/download/parallel.js +122 -0
- package/dist/download/parallel.js.map +1 -0
- package/dist/download/single.cjs +117 -0
- package/dist/download/single.cjs.map +1 -0
- package/dist/download/single.d.cts +152 -0
- package/dist/download/single.d.cts.map +1 -0
- package/dist/download/single.d.ts +152 -0
- package/dist/download/single.d.ts.map +1 -0
- package/dist/download/single.js +117 -0
- package/dist/download/single.js.map +1 -0
- package/dist/errors/index.cjs +268 -0
- package/dist/errors/index.cjs.map +1 -0
- package/dist/errors/index.d.cts +264 -0
- package/dist/errors/index.d.cts.map +1 -0
- package/dist/errors/index.d.ts +264 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +268 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/http/retry.cjs +36 -0
- package/dist/http/retry.cjs.map +1 -0
- package/dist/http/retry.d.cts +34 -0
- package/dist/http/retry.d.cts.map +1 -0
- package/dist/http/retry.d.ts +34 -0
- package/dist/http/retry.d.ts.map +1 -0
- package/dist/http/retry.js +36 -0
- package/dist/http/retry.js.map +1 -0
- package/dist/http/transport.cjs +143 -0
- package/dist/http/transport.cjs.map +1 -0
- package/dist/http/transport.d.cts +122 -0
- package/dist/http/transport.d.cts.map +1 -0
- package/dist/http/transport.d.ts +122 -0
- package/dist/http/transport.d.ts.map +1 -0
- package/dist/http/transport.js +143 -0
- package/dist/http/transport.js.map +1 -0
- package/dist/http/url-guard.cjs +97 -0
- package/dist/http/url-guard.cjs.map +1 -0
- package/dist/http/url-guard.d.cts +88 -0
- package/dist/http/url-guard.d.cts.map +1 -0
- package/dist/http/url-guard.d.ts +88 -0
- package/dist/http/url-guard.d.ts.map +1 -0
- package/dist/http/url-guard.js +97 -0
- package/dist/http/url-guard.js.map +1 -0
- package/dist/http/user-agent.cjs +51 -0
- package/dist/http/user-agent.cjs.map +1 -0
- package/dist/http/user-agent.d.cts +28 -0
- package/dist/http/user-agent.d.cts.map +1 -0
- package/dist/http/user-agent.d.ts +28 -0
- package/dist/http/user-agent.d.ts.map +1 -0
- package/dist/http/user-agent.js +51 -0
- package/dist/http/user-agent.js.map +1 -0
- package/dist/index.cjs +78 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +39 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +78 -0
- package/dist/index.js.map +1 -0
- package/dist/notifications/index.cjs +7 -0
- package/dist/notifications/index.cjs.map +1 -0
- package/dist/notifications/index.d.cts +3 -0
- package/dist/notifications/index.d.cts.map +1 -0
- package/dist/notifications/index.d.ts +3 -0
- package/dist/notifications/index.d.ts.map +1 -0
- package/dist/notifications/index.js +7 -0
- package/dist/notifications/index.js.map +1 -0
- package/dist/notifications/webhook.cjs +106 -0
- package/dist/notifications/webhook.cjs.map +1 -0
- package/dist/notifications/webhook.d.cts +146 -0
- package/dist/notifications/webhook.d.cts.map +1 -0
- package/dist/notifications/webhook.d.ts +146 -0
- package/dist/notifications/webhook.d.ts.map +1 -0
- package/dist/notifications/webhook.js +106 -0
- package/dist/notifications/webhook.js.map +1 -0
- package/dist/object.cjs +212 -0
- package/dist/object.cjs.map +1 -0
- package/dist/object.d.cts +263 -0
- package/dist/object.d.cts.map +1 -0
- package/dist/object.d.ts +263 -0
- package/dist/object.d.ts.map +1 -0
- package/dist/object.js +212 -0
- package/dist/object.js.map +1 -0
- package/dist/package.json.cjs +9 -0
- package/dist/package.json.cjs.map +1 -0
- package/dist/package.json.js +9 -0
- package/dist/package.json.js.map +1 -0
- package/dist/raw/encoding.cjs +47 -0
- package/dist/raw/encoding.cjs.map +1 -0
- package/dist/raw/encoding.d.cts +46 -0
- package/dist/raw/encoding.d.cts.map +1 -0
- package/dist/raw/encoding.d.ts +46 -0
- package/dist/raw/encoding.d.ts.map +1 -0
- package/dist/raw/encoding.js +47 -0
- package/dist/raw/encoding.js.map +1 -0
- package/dist/raw/index.cjs +600 -0
- package/dist/raw/index.cjs.map +1 -0
- package/dist/raw/index.d.cts +381 -0
- package/dist/raw/index.d.cts.map +1 -0
- package/dist/raw/index.d.ts +381 -0
- package/dist/raw/index.d.ts.map +1 -0
- package/dist/raw/index.js +601 -0
- package/dist/raw/index.js.map +1 -0
- package/dist/s3/index.cjs +23 -0
- package/dist/s3/index.cjs.map +1 -0
- package/dist/s3/index.d.cts +74 -0
- package/dist/s3/index.d.cts.map +1 -0
- package/dist/s3/index.d.ts +74 -0
- package/dist/s3/index.d.ts.map +1 -0
- package/dist/s3/index.js +23 -0
- package/dist/s3/index.js.map +1 -0
- package/dist/simulator/capabilities.cjs +53 -0
- package/dist/simulator/capabilities.cjs.map +1 -0
- package/dist/simulator/capabilities.d.cts +15 -0
- package/dist/simulator/capabilities.d.cts.map +1 -0
- package/dist/simulator/capabilities.d.ts +15 -0
- package/dist/simulator/capabilities.d.ts.map +1 -0
- package/dist/simulator/capabilities.js +53 -0
- package/dist/simulator/capabilities.js.map +1 -0
- package/dist/simulator/index.cjs +1559 -0
- package/dist/simulator/index.cjs.map +1 -0
- package/dist/simulator/index.d.cts +495 -0
- package/dist/simulator/index.d.cts.map +1 -0
- package/dist/simulator/index.d.ts +495 -0
- package/dist/simulator/index.d.ts.map +1 -0
- package/dist/simulator/index.js +1560 -0
- package/dist/simulator/index.js.map +1 -0
- package/dist/simulator/validation.cjs +174 -0
- package/dist/simulator/validation.cjs.map +1 -0
- package/dist/simulator/validation.d.cts +104 -0
- package/dist/simulator/validation.d.cts.map +1 -0
- package/dist/simulator/validation.d.ts +104 -0
- package/dist/simulator/validation.d.ts.map +1 -0
- package/dist/simulator/validation.js +174 -0
- package/dist/simulator/validation.js.map +1 -0
- package/dist/streams/collect.cjs +26 -0
- package/dist/streams/collect.cjs.map +1 -0
- package/dist/streams/collect.d.cts +18 -0
- package/dist/streams/collect.d.cts.map +1 -0
- package/dist/streams/collect.d.ts +18 -0
- package/dist/streams/collect.d.ts.map +1 -0
- package/dist/streams/collect.js +26 -0
- package/dist/streams/collect.js.map +1 -0
- package/dist/streams/hash.cjs +123 -0
- package/dist/streams/hash.cjs.map +1 -0
- package/dist/streams/hash.d.cts +42 -0
- package/dist/streams/hash.d.cts.map +1 -0
- package/dist/streams/hash.d.ts +42 -0
- package/dist/streams/hash.d.ts.map +1 -0
- package/dist/streams/hash.js +101 -0
- package/dist/streams/hash.js.map +1 -0
- package/dist/streams/index.cjs +13 -0
- package/dist/streams/index.cjs.map +1 -0
- package/dist/streams/index.d.cts +7 -0
- package/dist/streams/index.d.cts.map +1 -0
- package/dist/streams/index.d.ts +7 -0
- package/dist/streams/index.d.ts.map +1 -0
- package/dist/streams/index.js +13 -0
- package/dist/streams/index.js.map +1 -0
- package/dist/streams/progress.cjs +47 -0
- package/dist/streams/progress.cjs.map +1 -0
- package/dist/streams/progress.d.cts +53 -0
- package/dist/streams/progress.d.cts.map +1 -0
- package/dist/streams/progress.d.ts +53 -0
- package/dist/streams/progress.d.ts.map +1 -0
- package/dist/streams/progress.js +47 -0
- package/dist/streams/progress.js.map +1 -0
- package/dist/streams/source.cjs +155 -0
- package/dist/streams/source.cjs.map +1 -0
- package/dist/streams/source.d.cts +140 -0
- package/dist/streams/source.d.cts.map +1 -0
- package/dist/streams/source.d.ts +140 -0
- package/dist/streams/source.d.ts.map +1 -0
- package/dist/streams/source.js +155 -0
- package/dist/streams/source.js.map +1 -0
- package/dist/sync/actions/index.cjs +191 -0
- package/dist/sync/actions/index.cjs.map +1 -0
- package/dist/sync/actions/index.d.cts +167 -0
- package/dist/sync/actions/index.d.cts.map +1 -0
- package/dist/sync/actions/index.d.ts +167 -0
- package/dist/sync/actions/index.d.ts.map +1 -0
- package/dist/sync/actions/index.js +191 -0
- package/dist/sync/actions/index.js.map +1 -0
- package/dist/sync/index.cjs +23 -0
- package/dist/sync/index.cjs.map +1 -0
- package/dist/sync/index.d.cts +21 -0
- package/dist/sync/index.d.cts.map +1 -0
- package/dist/sync/index.d.ts +21 -0
- package/dist/sync/index.d.ts.map +1 -0
- package/dist/sync/index.js +23 -0
- package/dist/sync/index.js.map +1 -0
- package/dist/sync/pairing.cjs +31 -0
- package/dist/sync/pairing.cjs.map +1 -0
- package/dist/sync/pairing.d.cts +13 -0
- package/dist/sync/pairing.d.cts.map +1 -0
- package/dist/sync/pairing.d.ts +13 -0
- package/dist/sync/pairing.d.ts.map +1 -0
- package/dist/sync/pairing.js +31 -0
- package/dist/sync/pairing.js.map +1 -0
- package/dist/sync/policies/compare.cjs +14 -0
- package/dist/sync/policies/compare.cjs.map +1 -0
- package/dist/sync/policies/compare.d.cts +13 -0
- package/dist/sync/policies/compare.d.cts.map +1 -0
- package/dist/sync/policies/compare.d.ts +13 -0
- package/dist/sync/policies/compare.d.ts.map +1 -0
- package/dist/sync/policies/compare.js +14 -0
- package/dist/sync/policies/compare.js.map +1 -0
- package/dist/sync/policies/index.cjs +74 -0
- package/dist/sync/policies/index.cjs.map +1 -0
- package/dist/sync/policies/index.d.cts +42 -0
- package/dist/sync/policies/index.d.cts.map +1 -0
- package/dist/sync/policies/index.d.ts +42 -0
- package/dist/sync/policies/index.d.ts.map +1 -0
- package/dist/sync/policies/index.js +74 -0
- package/dist/sync/policies/index.js.map +1 -0
- package/dist/sync/scanners/b2.cjs +57 -0
- package/dist/sync/scanners/b2.cjs.map +1 -0
- package/dist/sync/scanners/b2.d.cts +20 -0
- package/dist/sync/scanners/b2.d.cts.map +1 -0
- package/dist/sync/scanners/b2.d.ts +20 -0
- package/dist/sync/scanners/b2.d.ts.map +1 -0
- package/dist/sync/scanners/b2.js +57 -0
- package/dist/sync/scanners/b2.js.map +1 -0
- package/dist/sync/scanners/local.cjs +58 -0
- package/dist/sync/scanners/local.cjs.map +1 -0
- package/dist/sync/scanners/local.d.cts +24 -0
- package/dist/sync/scanners/local.d.cts.map +1 -0
- package/dist/sync/scanners/local.d.ts +24 -0
- package/dist/sync/scanners/local.d.ts.map +1 -0
- package/dist/sync/scanners/local.js +58 -0
- package/dist/sync/scanners/local.js.map +1 -0
- package/dist/sync/synchronizer.cjs +203 -0
- package/dist/sync/synchronizer.cjs.map +1 -0
- package/dist/sync/synchronizer.d.cts +52 -0
- package/dist/sync/synchronizer.d.cts.map +1 -0
- package/dist/sync/synchronizer.d.ts +52 -0
- package/dist/sync/synchronizer.d.ts.map +1 -0
- package/dist/sync/synchronizer.js +181 -0
- package/dist/sync/synchronizer.js.map +1 -0
- package/dist/sync/types.d.cts +121 -0
- package/dist/sync/types.d.cts.map +1 -0
- package/dist/sync/types.d.ts +121 -0
- package/dist/sync/types.d.ts.map +1 -0
- package/dist/types/auth.cjs +58 -0
- package/dist/types/auth.cjs.map +1 -0
- package/dist/types/auth.d.cts +150 -0
- package/dist/types/auth.d.cts.map +1 -0
- package/dist/types/auth.d.ts +150 -0
- package/dist/types/auth.d.ts.map +1 -0
- package/dist/types/auth.js +58 -0
- package/dist/types/auth.js.map +1 -0
- package/dist/types/bucket.cjs +44 -0
- package/dist/types/bucket.cjs.map +1 -0
- package/dist/types/bucket.d.cts +245 -0
- package/dist/types/bucket.d.cts.map +1 -0
- package/dist/types/bucket.d.ts +245 -0
- package/dist/types/bucket.d.ts.map +1 -0
- package/dist/types/bucket.js +44 -0
- package/dist/types/bucket.js.map +1 -0
- package/dist/types/download.d.cts +110 -0
- package/dist/types/download.d.cts.map +1 -0
- package/dist/types/download.d.ts +110 -0
- package/dist/types/download.d.ts.map +1 -0
- package/dist/types/encryption.cjs +343 -0
- package/dist/types/encryption.cjs.map +1 -0
- package/dist/types/encryption.d.cts +132 -0
- package/dist/types/encryption.d.cts.map +1 -0
- package/dist/types/encryption.d.ts +132 -0
- package/dist/types/encryption.d.ts.map +1 -0
- package/dist/types/encryption.js +321 -0
- package/dist/types/encryption.js.map +1 -0
- package/dist/types/errors.d.cts +16 -0
- package/dist/types/errors.d.cts.map +1 -0
- package/dist/types/errors.d.ts +16 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/file.cjs +23 -0
- package/dist/types/file.cjs.map +1 -0
- package/dist/types/file.d.cts +220 -0
- package/dist/types/file.d.cts.map +1 -0
- package/dist/types/file.d.ts +220 -0
- package/dist/types/file.d.ts.map +1 -0
- package/dist/types/file.js +23 -0
- package/dist/types/file.js.map +1 -0
- package/dist/types/ids.cjs +27 -0
- package/dist/types/ids.cjs.map +1 -0
- package/dist/types/ids.d.cts +84 -0
- package/dist/types/ids.d.cts.map +1 -0
- package/dist/types/ids.d.ts +84 -0
- package/dist/types/ids.d.ts.map +1 -0
- package/dist/types/ids.js +27 -0
- package/dist/types/ids.js.map +1 -0
- package/dist/types/index.d.cts +25 -0
- package/dist/types/index.d.cts.map +1 -0
- package/dist/types/index.d.ts +25 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/key.d.cts +84 -0
- package/dist/types/key.d.cts.map +1 -0
- package/dist/types/key.d.ts +84 -0
- package/dist/types/key.d.ts.map +1 -0
- package/dist/types/lock.cjs +17 -0
- package/dist/types/lock.cjs.map +1 -0
- package/dist/types/lock.d.cts +92 -0
- package/dist/types/lock.d.cts.map +1 -0
- package/dist/types/lock.d.ts +92 -0
- package/dist/types/lock.d.ts.map +1 -0
- package/dist/types/lock.js +17 -0
- package/dist/types/lock.js.map +1 -0
- package/dist/types/notifications.cjs +24 -0
- package/dist/types/notifications.cjs.map +1 -0
- package/dist/types/notifications.d.cts +97 -0
- package/dist/types/notifications.d.cts.map +1 -0
- package/dist/types/notifications.d.ts +97 -0
- package/dist/types/notifications.d.ts.map +1 -0
- package/dist/types/notifications.js +24 -0
- package/dist/types/notifications.js.map +1 -0
- package/dist/types/replication.d.cts +42 -0
- package/dist/types/replication.d.cts.map +1 -0
- package/dist/types/replication.d.ts +42 -0
- package/dist/types/replication.d.ts.map +1 -0
- package/dist/types/upload.d.cts +219 -0
- package/dist/types/upload.d.cts.map +1 -0
- package/dist/types/upload.d.ts +219 -0
- package/dist/types/upload.d.ts.map +1 -0
- package/dist/upload/cancel.cjs +10 -0
- package/dist/upload/cancel.cjs.map +1 -0
- package/dist/upload/cancel.d.cts +23 -0
- package/dist/upload/cancel.d.cts.map +1 -0
- package/dist/upload/cancel.d.ts +23 -0
- package/dist/upload/cancel.d.ts.map +1 -0
- package/dist/upload/cancel.js +10 -0
- package/dist/upload/cancel.js.map +1 -0
- package/dist/upload/concurrency.cjs +54 -0
- package/dist/upload/concurrency.cjs.map +1 -0
- package/dist/upload/concurrency.d.cts +46 -0
- package/dist/upload/concurrency.d.cts.map +1 -0
- package/dist/upload/concurrency.d.ts +46 -0
- package/dist/upload/concurrency.d.ts.map +1 -0
- package/dist/upload/concurrency.js +54 -0
- package/dist/upload/concurrency.js.map +1 -0
- package/dist/upload/large.cjs +222 -0
- package/dist/upload/large.cjs.map +1 -0
- package/dist/upload/large.d.cts +71 -0
- package/dist/upload/large.d.cts.map +1 -0
- package/dist/upload/large.d.ts +71 -0
- package/dist/upload/large.d.ts.map +1 -0
- package/dist/upload/large.js +222 -0
- package/dist/upload/large.js.map +1 -0
- package/dist/upload/resume.cjs +34 -0
- package/dist/upload/resume.cjs.map +1 -0
- package/dist/upload/resume.d.cts +33 -0
- package/dist/upload/resume.d.cts.map +1 -0
- package/dist/upload/resume.d.ts +33 -0
- package/dist/upload/resume.d.ts.map +1 -0
- package/dist/upload/resume.js +34 -0
- package/dist/upload/resume.js.map +1 -0
- package/dist/upload/single.cjs +47 -0
- package/dist/upload/single.cjs.map +1 -0
- package/dist/upload/single.d.cts +51 -0
- package/dist/upload/single.d.cts.map +1 -0
- package/dist/upload/single.d.ts +51 -0
- package/dist/upload/single.d.ts.map +1 -0
- package/dist/upload/single.js +47 -0
- package/dist/upload/single.js.map +1 -0
- package/dist/upload/stream.cjs +198 -0
- package/dist/upload/stream.cjs.map +1 -0
- package/dist/upload/stream.d.cts +61 -0
- package/dist/upload/stream.d.cts.map +1 -0
- package/dist/upload/stream.d.ts +61 -0
- package/dist/upload/stream.d.ts.map +1 -0
- package/dist/upload/stream.js +198 -0
- package/dist/upload/stream.js.map +1 -0
- package/dist/util/best-effort.cjs +10 -0
- package/dist/util/best-effort.cjs.map +1 -0
- package/dist/util/best-effort.d.cts +31 -0
- package/dist/util/best-effort.d.cts.map +1 -0
- package/dist/util/best-effort.d.ts +31 -0
- package/dist/util/best-effort.d.ts.map +1 -0
- package/dist/util/best-effort.js +10 -0
- package/dist/util/best-effort.js.map +1 -0
- package/dist/util/defaults.cjs +11 -0
- package/dist/util/defaults.cjs.map +1 -0
- package/dist/util/defaults.d.cts +54 -0
- package/dist/util/defaults.d.cts.map +1 -0
- package/dist/util/defaults.d.ts +54 -0
- package/dist/util/defaults.d.ts.map +1 -0
- package/dist/util/defaults.js +11 -0
- package/dist/util/defaults.js.map +1 -0
- package/dist/util/normalize.cjs +16 -0
- package/dist/util/normalize.cjs.map +1 -0
- package/dist/util/normalize.d.cts +62 -0
- package/dist/util/normalize.d.cts.map +1 -0
- package/dist/util/normalize.d.ts +62 -0
- package/dist/util/normalize.d.ts.map +1 -0
- package/dist/util/normalize.js +16 -0
- package/dist/util/normalize.js.map +1 -0
- package/dist/util/paginator.cjs +20 -0
- package/dist/util/paginator.cjs.map +1 -0
- package/dist/util/paginator.d.cts +120 -0
- package/dist/util/paginator.d.cts.map +1 -0
- package/dist/util/paginator.d.ts +120 -0
- package/dist/util/paginator.d.ts.map +1 -0
- package/dist/util/paginator.js +20 -0
- package/dist/util/paginator.js.map +1 -0
- package/dist/util/plan-ranges.cjs +28 -0
- package/dist/util/plan-ranges.cjs.map +1 -0
- package/dist/util/plan-ranges.d.cts +56 -0
- package/dist/util/plan-ranges.d.cts.map +1 -0
- package/dist/util/plan-ranges.d.ts +56 -0
- package/dist/util/plan-ranges.d.ts.map +1 -0
- package/dist/util/plan-ranges.js +28 -0
- package/dist/util/plan-ranges.js.map +1 -0
- package/dist/util/text-codec.cjs +7 -0
- package/dist/util/text-codec.cjs.map +1 -0
- package/dist/util/text-codec.d.cts +26 -0
- package/dist/util/text-codec.d.cts.map +1 -0
- package/dist/util/text-codec.d.ts +26 -0
- package/dist/util/text-codec.d.ts.map +1 -0
- package/dist/util/text-codec.js +7 -0
- package/dist/util/text-codec.js.map +1 -0
- package/dist/util/to-error.cjs +7 -0
- package/dist/util/to-error.cjs.map +1 -0
- package/dist/util/to-error.d.cts +15 -0
- package/dist/util/to-error.d.cts.map +1 -0
- package/dist/util/to-error.d.ts +15 -0
- package/dist/util/to-error.d.ts.map +1 -0
- package/dist/util/to-error.js +7 -0
- package/dist/util/to-error.js.map +1 -0
- package/dist/version.cjs +6 -0
- package/dist/version.cjs.map +1 -0
- package/dist/version.d.cts +14 -0
- package/dist/version.d.cts.map +1 -0
- package/dist/version.d.ts +14 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +6 -0
- package/dist/version.js.map +1 -0
- package/package.json +198 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Bucket } from '../../bucket.js';
|
|
2
|
+
import { B2SyncPath, SyncFolder } from '../types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Scans a B2 bucket (optionally filtered by prefix) and yields {@link B2SyncPath} entries
|
|
5
|
+
* sorted by file name. Hidden files are excluded. All versions are fetched and grouped.
|
|
6
|
+
*/
|
|
7
|
+
export declare class B2Folder implements SyncFolder {
|
|
8
|
+
readonly type: "b2";
|
|
9
|
+
private readonly bucket;
|
|
10
|
+
private readonly prefix;
|
|
11
|
+
/**
|
|
12
|
+
* Creates a new B2Folder for the given bucket and optional prefix.
|
|
13
|
+
* @param bucket - The B2 bucket to scan.
|
|
14
|
+
* @param prefix - Optional key prefix to restrict the scan scope.
|
|
15
|
+
*/
|
|
16
|
+
constructor(bucket: Bucket, prefix?: string);
|
|
17
|
+
/** Lists all file versions in the bucket, groups by name, and yields the latest visible version. */
|
|
18
|
+
scan(): AsyncGenerator<B2SyncPath>;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=b2.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"b2.d.ts","sourceRoot":"","sources":["../../../src/sync/scanners/b2.js"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAE7C,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAEzD;;;GAGG;AACH,qBAAa,QAAS,YAAW,UAAU;IACzC,QAAQ,CAAC,IAAI,EAAG,IAAI,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAE/B;;;;OAIG;gBACS,MAAM,EAAE,MAAM,EAAE,MAAM,SAAK;IAKvC,oGAAoG;IAC7F,IAAI,IAAI,cAAc,CAAC,UAAU,CAAC;CA+C1C"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { FileAction } from "../../types/file.js";
|
|
2
|
+
class B2Folder {
|
|
3
|
+
type = "b2";
|
|
4
|
+
bucket;
|
|
5
|
+
prefix;
|
|
6
|
+
/**
|
|
7
|
+
* Creates a new B2Folder for the given bucket and optional prefix.
|
|
8
|
+
* @param bucket - The B2 bucket to scan.
|
|
9
|
+
* @param prefix - Optional key prefix to restrict the scan scope.
|
|
10
|
+
*/
|
|
11
|
+
constructor(bucket, prefix = "") {
|
|
12
|
+
this.bucket = bucket;
|
|
13
|
+
this.prefix = prefix;
|
|
14
|
+
}
|
|
15
|
+
/** Lists all file versions in the bucket, groups by name, and yields the latest visible version. */
|
|
16
|
+
async *scan() {
|
|
17
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
18
|
+
let startFileName;
|
|
19
|
+
let startFileId;
|
|
20
|
+
while (true) {
|
|
21
|
+
const listing = await this.bucket.listFileVersions({
|
|
22
|
+
...this.prefix !== "" ? { prefix: this.prefix } : {},
|
|
23
|
+
...startFileName !== void 0 ? { startFileName } : {},
|
|
24
|
+
...startFileId !== void 0 ? { startFileId } : {}
|
|
25
|
+
});
|
|
26
|
+
for (const fv of listing.files) {
|
|
27
|
+
const existing = grouped.get(fv.fileName);
|
|
28
|
+
if (existing) {
|
|
29
|
+
existing.push(fv);
|
|
30
|
+
} else {
|
|
31
|
+
grouped.set(fv.fileName, [fv]);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (!listing.nextFileName) break;
|
|
35
|
+
startFileName = listing.nextFileName;
|
|
36
|
+
startFileId = listing.nextFileId;
|
|
37
|
+
}
|
|
38
|
+
const sorted = [...grouped.entries()].sort((a, b) => a[0].localeCompare(b[0]));
|
|
39
|
+
for (const [fileName, versions] of sorted) {
|
|
40
|
+
versions.sort((a, b) => b.uploadTimestamp - a.uploadTimestamp);
|
|
41
|
+
const selected = versions[0];
|
|
42
|
+
if (!selected || selected.action === FileAction.Hide) continue;
|
|
43
|
+
const relativePath = this.prefix !== "" ? fileName.slice(this.prefix.length) : fileName;
|
|
44
|
+
yield {
|
|
45
|
+
relativePath,
|
|
46
|
+
modTimeMillis: selected.uploadTimestamp,
|
|
47
|
+
size: selected.contentLength,
|
|
48
|
+
selectedVersion: selected,
|
|
49
|
+
allVersions: versions
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
export {
|
|
55
|
+
B2Folder
|
|
56
|
+
};
|
|
57
|
+
//# sourceMappingURL=b2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"b2.js","sources":["../../../src/sync/scanners/b2.ts"],"sourcesContent":["import type { Bucket } from '../../bucket.ts'\nimport { FileAction, type FileVersion } from '../../types/file.ts'\nimport type { B2SyncPath, SyncFolder } from '../types.ts'\n\n/**\n * Scans a B2 bucket (optionally filtered by prefix) and yields {@link B2SyncPath} entries\n * sorted by file name. Hidden files are excluded. All versions are fetched and grouped.\n */\nexport class B2Folder implements SyncFolder {\n readonly type = 'b2' as const\n private readonly bucket: Bucket\n private readonly prefix: string\n\n /**\n * Creates a new B2Folder for the given bucket and optional prefix.\n * @param bucket - The B2 bucket to scan.\n * @param prefix - Optional key prefix to restrict the scan scope.\n */\n constructor(bucket: Bucket, prefix = '') {\n this.bucket = bucket\n this.prefix = prefix\n }\n\n /** Lists all file versions in the bucket, groups by name, and yields the latest visible version. */\n async *scan(): AsyncGenerator<B2SyncPath> {\n const grouped = new Map<string, FileVersion[]>()\n\n let startFileName: string | undefined\n let startFileId: string | undefined\n\n while (true) {\n const listing = await this.bucket.listFileVersions({\n ...(this.prefix !== '' ? { prefix: this.prefix } : {}),\n ...(startFileName !== undefined ? { startFileName } : {}),\n ...(startFileId !== undefined\n ? { startFileId: startFileId as import('../../types/ids.ts').FileId }\n : {}),\n })\n\n for (const fv of listing.files) {\n const existing = grouped.get(fv.fileName)\n if (existing) {\n existing.push(fv)\n } else {\n grouped.set(fv.fileName, [fv])\n }\n }\n\n if (!listing.nextFileName) break\n startFileName = listing.nextFileName\n startFileId = listing.nextFileId as string | undefined\n }\n\n const sorted = [...grouped.entries()].sort((a, b) => a[0].localeCompare(b[0]))\n\n for (const [fileName, versions] of sorted) {\n versions.sort((a, b) => b.uploadTimestamp - a.uploadTimestamp)\n const selected = versions[0]\n if (!selected || selected.action === FileAction.Hide) continue\n\n const relativePath = this.prefix !== '' ? fileName.slice(this.prefix.length) : fileName\n\n yield {\n relativePath,\n modTimeMillis: selected.uploadTimestamp,\n size: selected.contentLength,\n selectedVersion: selected,\n allVersions: versions,\n }\n }\n }\n}\n"],"names":[],"mappings":";AAQO,MAAM,SAA+B;AAAA,EACjC,OAAO;AAAA,EACC;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOjB,YAAY,QAAgB,SAAS,IAAI;AACvC,SAAK,SAAS;AACd,SAAK,SAAS;AAAA,EAChB;AAAA;AAAA,EAGA,OAAO,OAAmC;AACxC,UAAM,8BAAc,IAAA;AAEpB,QAAI;AACJ,QAAI;AAEJ,WAAO,MAAM;AACX,YAAM,UAAU,MAAM,KAAK,OAAO,iBAAiB;AAAA,QACjD,GAAI,KAAK,WAAW,KAAK,EAAE,QAAQ,KAAK,OAAA,IAAW,CAAA;AAAA,QACnD,GAAI,kBAAkB,SAAY,EAAE,cAAA,IAAkB,CAAA;AAAA,QACtD,GAAI,gBAAgB,SAChB,EAAE,gBACF,CAAA;AAAA,MAAC,CACN;AAED,iBAAW,MAAM,QAAQ,OAAO;AAC9B,cAAM,WAAW,QAAQ,IAAI,GAAG,QAAQ;AACxC,YAAI,UAAU;AACZ,mBAAS,KAAK,EAAE;AAAA,QAClB,OAAO;AACL,kBAAQ,IAAI,GAAG,UAAU,CAAC,EAAE,CAAC;AAAA,QAC/B;AAAA,MACF;AAEA,UAAI,CAAC,QAAQ,aAAc;AAC3B,sBAAgB,QAAQ;AACxB,oBAAc,QAAQ;AAAA,IACxB;AAEA,UAAM,SAAS,CAAC,GAAG,QAAQ,QAAA,CAAS,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC;AAE7E,eAAW,CAAC,UAAU,QAAQ,KAAK,QAAQ;AACzC,eAAS,KAAK,CAAC,GAAG,MAAM,EAAE,kBAAkB,EAAE,eAAe;AAC7D,YAAM,WAAW,SAAS,CAAC;AAC3B,UAAI,CAAC,YAAY,SAAS,WAAW,WAAW,KAAM;AAEtD,YAAM,eAAe,KAAK,WAAW,KAAK,SAAS,MAAM,KAAK,OAAO,MAAM,IAAI;AAE/E,YAAM;AAAA,QACJ;AAAA,QACA,eAAe,SAAS;AAAA,QACxB,MAAM,SAAS;AAAA,QACf,iBAAiB;AAAA,QACjB,aAAa;AAAA,MAAA;AAAA,IAEjB;AAAA,EACF;AACF;"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const promises = require("node:fs/promises");
|
|
4
|
+
const node_path = require("node:path");
|
|
5
|
+
class LocalFolder {
|
|
6
|
+
type = "local";
|
|
7
|
+
/** Absolute path to the local root directory. */
|
|
8
|
+
root;
|
|
9
|
+
/**
|
|
10
|
+
* Creates a new LocalFolder for the given root directory.
|
|
11
|
+
* @param root - Absolute path to the local directory to scan.
|
|
12
|
+
*/
|
|
13
|
+
constructor(root) {
|
|
14
|
+
this.root = root;
|
|
15
|
+
}
|
|
16
|
+
/** Recursively walks the directory and yields files sorted by relative path. */
|
|
17
|
+
async *scan() {
|
|
18
|
+
const collected = [];
|
|
19
|
+
await this.walk(this.root, collected);
|
|
20
|
+
collected.sort((a, b) => a.relativePath.localeCompare(b.relativePath));
|
|
21
|
+
for (const entry of collected) {
|
|
22
|
+
yield entry;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Recursively collects files from {@link dir} into {@link out}.
|
|
27
|
+
* @param dir - Absolute path of the directory to scan.
|
|
28
|
+
* @param out - Accumulator array that receives discovered file entries.
|
|
29
|
+
*/
|
|
30
|
+
async walk(dir, out) {
|
|
31
|
+
let entries;
|
|
32
|
+
try {
|
|
33
|
+
entries = await promises.readdir(dir, { withFileTypes: true });
|
|
34
|
+
} catch {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
for (const entry of entries) {
|
|
38
|
+
const fullPath = node_path.join(dir, entry.name);
|
|
39
|
+
if (entry.isDirectory()) {
|
|
40
|
+
await this.walk(fullPath, out);
|
|
41
|
+
} else if (entry.isFile()) {
|
|
42
|
+
try {
|
|
43
|
+
const s = await promises.stat(fullPath);
|
|
44
|
+
const rel = node_path.relative(this.root, fullPath).split(node_path.sep).join("/");
|
|
45
|
+
out.push({
|
|
46
|
+
relativePath: rel,
|
|
47
|
+
absolutePath: fullPath,
|
|
48
|
+
modTimeMillis: Math.floor(s.mtimeMs),
|
|
49
|
+
size: s.size
|
|
50
|
+
});
|
|
51
|
+
} catch {
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
exports.LocalFolder = LocalFolder;
|
|
58
|
+
//# sourceMappingURL=local.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local.cjs","sources":["../../../src/sync/scanners/local.ts"],"sourcesContent":["import { readdir, stat } from 'node:fs/promises'\nimport { join, relative, sep } from 'node:path'\nimport type { LocalSyncPath, SyncFolder } from '../types.ts'\n\n/**\n * Scans a local directory tree and yields {@link LocalSyncPath} entries\n * sorted by relative path. Unreadable files and directories are silently skipped.\n */\nexport class LocalFolder implements SyncFolder {\n readonly type = 'local' as const\n /** 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 path to the local directory to scan.\n */\n constructor(root: string) {\n this.root = root\n }\n\n /** Recursively walks the directory and yields files sorted by relative path. */\n async *scan(): AsyncGenerator<LocalSyncPath> {\n const collected: LocalSyncPath[] = []\n await this.walk(this.root, collected)\n collected.sort((a, b) => a.relativePath.localeCompare(b.relativePath))\n for (const entry of collected) {\n yield entry\n }\n }\n\n /**\n * Recursively collects files from {@link dir} into {@link out}.\n * @param dir - Absolute path of the directory to scan.\n * @param out - Accumulator array that receives discovered file entries.\n */\n private async walk(dir: string, out: LocalSyncPath[]): Promise<void> {\n let entries: import('node:fs').Dirent[]\n try {\n entries = await readdir(dir, { withFileTypes: true })\n } catch {\n return\n }\n\n for (const entry of entries) {\n const fullPath = join(dir, entry.name)\n if (entry.isDirectory()) {\n await this.walk(fullPath, out)\n } else if (entry.isFile()) {\n try {\n const s = await stat(fullPath)\n const rel = relative(this.root, fullPath).split(sep).join('/')\n out.push({\n relativePath: rel,\n absolutePath: fullPath,\n modTimeMillis: Math.floor(s.mtimeMs),\n size: s.size,\n })\n } catch {\n // skip unreadable files\n }\n }\n }\n }\n}\n"],"names":["readdir","join","stat","relative","sep"],"mappings":";;;;AAQO,MAAM,YAAkC;AAAA,EACpC,OAAO;AAAA;AAAA,EAEP;AAAA;AAAA;AAAA;AAAA;AAAA,EAMT,YAAY,MAAc;AACxB,SAAK,OAAO;AAAA,EACd;AAAA;AAAA,EAGA,OAAO,OAAsC;AAC3C,UAAM,YAA6B,CAAA;AACnC,UAAM,KAAK,KAAK,KAAK,MAAM,SAAS;AACpC,cAAU,KAAK,CAAC,GAAG,MAAM,EAAE,aAAa,cAAc,EAAE,YAAY,CAAC;AACrE,eAAW,SAAS,WAAW;AAC7B,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAc,KAAK,KAAa,KAAqC;AACnE,QAAI;AACJ,QAAI;AACF,gBAAU,MAAMA,SAAAA,QAAQ,KAAK,EAAE,eAAe,MAAM;AAAA,IACtD,QAAQ;AACN;AAAA,IACF;AAEA,eAAW,SAAS,SAAS;AAC3B,YAAM,WAAWC,UAAAA,KAAK,KAAK,MAAM,IAAI;AACrC,UAAI,MAAM,eAAe;AACvB,cAAM,KAAK,KAAK,UAAU,GAAG;AAAA,MAC/B,WAAW,MAAM,UAAU;AACzB,YAAI;AACF,gBAAM,IAAI,MAAMC,SAAAA,KAAK,QAAQ;AAC7B,gBAAM,MAAMC,UAAAA,SAAS,KAAK,MAAM,QAAQ,EAAE,MAAMC,UAAAA,GAAG,EAAE,KAAK,GAAG;AAC7D,cAAI,KAAK;AAAA,YACP,cAAc;AAAA,YACd,cAAc;AAAA,YACd,eAAe,KAAK,MAAM,EAAE,OAAO;AAAA,YACnC,MAAM,EAAE;AAAA,UAAA,CACT;AAAA,QACH,QAAQ;AAAA,QAER;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { LocalSyncPath, SyncFolder } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Scans a local directory tree and yields {@link LocalSyncPath} entries
|
|
4
|
+
* sorted by relative path. Unreadable files and directories are silently skipped.
|
|
5
|
+
*/
|
|
6
|
+
export declare class LocalFolder implements SyncFolder {
|
|
7
|
+
readonly type: "local";
|
|
8
|
+
/** Absolute path to the local root directory. */
|
|
9
|
+
readonly root: string;
|
|
10
|
+
/**
|
|
11
|
+
* Creates a new LocalFolder for the given root directory.
|
|
12
|
+
* @param root - Absolute path to the local directory to scan.
|
|
13
|
+
*/
|
|
14
|
+
constructor(root: string);
|
|
15
|
+
/** Recursively walks the directory and yields files sorted by relative path. */
|
|
16
|
+
scan(): AsyncGenerator<LocalSyncPath>;
|
|
17
|
+
/**
|
|
18
|
+
* Recursively collects files from {@link dir} into {@link out}.
|
|
19
|
+
* @param dir - Absolute path of the directory to scan.
|
|
20
|
+
* @param out - Accumulator array that receives discovered file entries.
|
|
21
|
+
*/
|
|
22
|
+
private walk;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=local.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local.d.ts","sourceRoot":"","sources":["../../../src/sync/scanners/local.js"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAE5D;;;GAGG;AACH,qBAAa,WAAY,YAAW,UAAU;IAC5C,QAAQ,CAAC,IAAI,EAAG,OAAO,CAAS;IAChC,iDAAiD;IACjD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IAErB;;;OAGG;gBACS,IAAI,EAAE,MAAM;IAIxB,gFAAgF;IACzE,IAAI,IAAI,cAAc,CAAC,aAAa,CAAC;IAS5C;;;;OAIG;YACW,IAAI;CA4BnB"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { LocalSyncPath, SyncFolder } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Scans a local directory tree and yields {@link LocalSyncPath} entries
|
|
4
|
+
* sorted by relative path. Unreadable files and directories are silently skipped.
|
|
5
|
+
*/
|
|
6
|
+
export declare class LocalFolder implements SyncFolder {
|
|
7
|
+
readonly type: "local";
|
|
8
|
+
/** Absolute path to the local root directory. */
|
|
9
|
+
readonly root: string;
|
|
10
|
+
/**
|
|
11
|
+
* Creates a new LocalFolder for the given root directory.
|
|
12
|
+
* @param root - Absolute path to the local directory to scan.
|
|
13
|
+
*/
|
|
14
|
+
constructor(root: string);
|
|
15
|
+
/** Recursively walks the directory and yields files sorted by relative path. */
|
|
16
|
+
scan(): AsyncGenerator<LocalSyncPath>;
|
|
17
|
+
/**
|
|
18
|
+
* Recursively collects files from {@link dir} into {@link out}.
|
|
19
|
+
* @param dir - Absolute path of the directory to scan.
|
|
20
|
+
* @param out - Accumulator array that receives discovered file entries.
|
|
21
|
+
*/
|
|
22
|
+
private walk;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=local.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local.d.ts","sourceRoot":"","sources":["../../../src/sync/scanners/local.js"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAE5D;;;GAGG;AACH,qBAAa,WAAY,YAAW,UAAU;IAC5C,QAAQ,CAAC,IAAI,EAAG,OAAO,CAAS;IAChC,iDAAiD;IACjD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IAErB;;;OAGG;gBACS,IAAI,EAAE,MAAM;IAIxB,gFAAgF;IACzE,IAAI,IAAI,cAAc,CAAC,aAAa,CAAC;IAS5C;;;;OAIG;YACW,IAAI;CA4BnB"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { readdir, stat } from "node:fs/promises";
|
|
2
|
+
import { join, relative, sep } from "node:path";
|
|
3
|
+
class LocalFolder {
|
|
4
|
+
type = "local";
|
|
5
|
+
/** Absolute path to the local root directory. */
|
|
6
|
+
root;
|
|
7
|
+
/**
|
|
8
|
+
* Creates a new LocalFolder for the given root directory.
|
|
9
|
+
* @param root - Absolute path to the local directory to scan.
|
|
10
|
+
*/
|
|
11
|
+
constructor(root) {
|
|
12
|
+
this.root = root;
|
|
13
|
+
}
|
|
14
|
+
/** Recursively walks the directory and yields files sorted by relative path. */
|
|
15
|
+
async *scan() {
|
|
16
|
+
const collected = [];
|
|
17
|
+
await this.walk(this.root, collected);
|
|
18
|
+
collected.sort((a, b) => a.relativePath.localeCompare(b.relativePath));
|
|
19
|
+
for (const entry of collected) {
|
|
20
|
+
yield entry;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Recursively collects files from {@link dir} into {@link out}.
|
|
25
|
+
* @param dir - Absolute path of the directory to scan.
|
|
26
|
+
* @param out - Accumulator array that receives discovered file entries.
|
|
27
|
+
*/
|
|
28
|
+
async walk(dir, out) {
|
|
29
|
+
let entries;
|
|
30
|
+
try {
|
|
31
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
32
|
+
} catch {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
for (const entry of entries) {
|
|
36
|
+
const fullPath = join(dir, entry.name);
|
|
37
|
+
if (entry.isDirectory()) {
|
|
38
|
+
await this.walk(fullPath, out);
|
|
39
|
+
} else if (entry.isFile()) {
|
|
40
|
+
try {
|
|
41
|
+
const s = await stat(fullPath);
|
|
42
|
+
const rel = relative(this.root, fullPath).split(sep).join("/");
|
|
43
|
+
out.push({
|
|
44
|
+
relativePath: rel,
|
|
45
|
+
absolutePath: fullPath,
|
|
46
|
+
modTimeMillis: Math.floor(s.mtimeMs),
|
|
47
|
+
size: s.size
|
|
48
|
+
});
|
|
49
|
+
} catch {
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
export {
|
|
56
|
+
LocalFolder
|
|
57
|
+
};
|
|
58
|
+
//# sourceMappingURL=local.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local.js","sources":["../../../src/sync/scanners/local.ts"],"sourcesContent":["import { readdir, stat } from 'node:fs/promises'\nimport { join, relative, sep } from 'node:path'\nimport type { LocalSyncPath, SyncFolder } from '../types.ts'\n\n/**\n * Scans a local directory tree and yields {@link LocalSyncPath} entries\n * sorted by relative path. Unreadable files and directories are silently skipped.\n */\nexport class LocalFolder implements SyncFolder {\n readonly type = 'local' as const\n /** 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 path to the local directory to scan.\n */\n constructor(root: string) {\n this.root = root\n }\n\n /** Recursively walks the directory and yields files sorted by relative path. */\n async *scan(): AsyncGenerator<LocalSyncPath> {\n const collected: LocalSyncPath[] = []\n await this.walk(this.root, collected)\n collected.sort((a, b) => a.relativePath.localeCompare(b.relativePath))\n for (const entry of collected) {\n yield entry\n }\n }\n\n /**\n * Recursively collects files from {@link dir} into {@link out}.\n * @param dir - Absolute path of the directory to scan.\n * @param out - Accumulator array that receives discovered file entries.\n */\n private async walk(dir: string, out: LocalSyncPath[]): Promise<void> {\n let entries: import('node:fs').Dirent[]\n try {\n entries = await readdir(dir, { withFileTypes: true })\n } catch {\n return\n }\n\n for (const entry of entries) {\n const fullPath = join(dir, entry.name)\n if (entry.isDirectory()) {\n await this.walk(fullPath, out)\n } else if (entry.isFile()) {\n try {\n const s = await stat(fullPath)\n const rel = relative(this.root, fullPath).split(sep).join('/')\n out.push({\n relativePath: rel,\n absolutePath: fullPath,\n modTimeMillis: Math.floor(s.mtimeMs),\n size: s.size,\n })\n } catch {\n // skip unreadable files\n }\n }\n }\n }\n}\n"],"names":[],"mappings":";;AAQO,MAAM,YAAkC;AAAA,EACpC,OAAO;AAAA;AAAA,EAEP;AAAA;AAAA;AAAA;AAAA;AAAA,EAMT,YAAY,MAAc;AACxB,SAAK,OAAO;AAAA,EACd;AAAA;AAAA,EAGA,OAAO,OAAsC;AAC3C,UAAM,YAA6B,CAAA;AACnC,UAAM,KAAK,KAAK,KAAK,MAAM,SAAS;AACpC,cAAU,KAAK,CAAC,GAAG,MAAM,EAAE,aAAa,cAAc,EAAE,YAAY,CAAC;AACrE,eAAW,SAAS,WAAW;AAC7B,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAc,KAAK,KAAa,KAAqC;AACnE,QAAI;AACJ,QAAI;AACF,gBAAU,MAAM,QAAQ,KAAK,EAAE,eAAe,MAAM;AAAA,IACtD,QAAQ;AACN;AAAA,IACF;AAEA,eAAW,SAAS,SAAS;AAC3B,YAAM,WAAW,KAAK,KAAK,MAAM,IAAI;AACrC,UAAI,MAAM,eAAe;AACvB,cAAM,KAAK,KAAK,UAAU,GAAG;AAAA,MAC/B,WAAW,MAAM,UAAU;AACzB,YAAI;AACF,gBAAM,IAAI,MAAM,KAAK,QAAQ;AAC7B,gBAAM,MAAM,SAAS,KAAK,MAAM,QAAQ,EAAE,MAAM,GAAG,EAAE,KAAK,GAAG;AAC7D,cAAI,KAAK;AAAA,YACP,cAAc;AAAA,YACd,cAAc;AAAA,YACd,eAAe,KAAK,MAAM,EAAE,OAAO;AAAA,YACnC,MAAM,EAAE;AAAA,UAAA,CACT;AAAA,QACH,QAAQ;AAAA,QAER;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;"}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __copyProps = (to, from, except, desc) => {
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
10
|
+
for (let key of __getOwnPropNames(from))
|
|
11
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
12
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
13
|
+
}
|
|
14
|
+
return to;
|
|
15
|
+
};
|
|
16
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
17
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
18
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
19
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
20
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
21
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
22
|
+
mod
|
|
23
|
+
));
|
|
24
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
25
|
+
const source = require("../streams/source.cjs");
|
|
26
|
+
const ids = require("../types/ids.cjs");
|
|
27
|
+
const concurrency = require("../upload/concurrency.cjs");
|
|
28
|
+
const defaults = require("../util/defaults.cjs");
|
|
29
|
+
const toError = require("../util/to-error.cjs");
|
|
30
|
+
const index$1 = require("./actions/index.cjs");
|
|
31
|
+
const pairing = require("./pairing.cjs");
|
|
32
|
+
const index = require("./policies/index.cjs");
|
|
33
|
+
function resolveDirection(source2, dest) {
|
|
34
|
+
if (source2.type === "local" && dest.type === "b2") return "local-to-b2";
|
|
35
|
+
if (source2.type === "b2" && dest.type === "local") return "b2-to-local";
|
|
36
|
+
if (source2.type === "b2" && dest.type === "b2") return "b2-to-b2";
|
|
37
|
+
throw new Error(`Unsupported sync direction: ${source2.type} to ${dest.type}`);
|
|
38
|
+
}
|
|
39
|
+
async function* synchronize(config) {
|
|
40
|
+
const { source: source2, dest, options } = config;
|
|
41
|
+
const direction = resolveDirection(source2, dest);
|
|
42
|
+
const dryRun = options.dryRun ?? false;
|
|
43
|
+
const concurrency$1 = options.concurrency ?? defaults.DEFAULT_TRANSFER_CONCURRENCY;
|
|
44
|
+
const keepDays = options.keepDays ?? 0;
|
|
45
|
+
const compareThreshold = options.compareThreshold ?? 0;
|
|
46
|
+
const nowMillis = Date.now();
|
|
47
|
+
const factory = createActionFactory(config);
|
|
48
|
+
const actions = [];
|
|
49
|
+
for await (const pair of pairing.zipFolders(source2, dest)) {
|
|
50
|
+
if (options.signal?.aborted) return;
|
|
51
|
+
for (const action of index.generateActions(
|
|
52
|
+
pair,
|
|
53
|
+
direction,
|
|
54
|
+
options.compareMode,
|
|
55
|
+
options.keepMode,
|
|
56
|
+
keepDays,
|
|
57
|
+
nowMillis,
|
|
58
|
+
factory,
|
|
59
|
+
compareThreshold
|
|
60
|
+
)) {
|
|
61
|
+
actions.push(action);
|
|
62
|
+
}
|
|
63
|
+
yield { type: "compare", path: (pair[0] ?? pair[1])?.relativePath ?? "", size: 0 };
|
|
64
|
+
}
|
|
65
|
+
const sem = new concurrency.Semaphore(concurrency$1);
|
|
66
|
+
const results = [];
|
|
67
|
+
const errors = [];
|
|
68
|
+
const promises = actions.map(async (action) => {
|
|
69
|
+
await sem.acquire();
|
|
70
|
+
try {
|
|
71
|
+
if (options.signal?.aborted) return;
|
|
72
|
+
const event = await action.execute(dryRun);
|
|
73
|
+
results.push(event);
|
|
74
|
+
} catch (err) {
|
|
75
|
+
const errorValue = toError.toError(err);
|
|
76
|
+
errors.push(errorValue);
|
|
77
|
+
results.push({
|
|
78
|
+
type: "error",
|
|
79
|
+
path: action.relativePath,
|
|
80
|
+
size: 0,
|
|
81
|
+
message: errorValue.message
|
|
82
|
+
});
|
|
83
|
+
} finally {
|
|
84
|
+
sem.release();
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
await Promise.all(promises);
|
|
88
|
+
for (const event of results) {
|
|
89
|
+
yield event;
|
|
90
|
+
}
|
|
91
|
+
if (errors.length > 0) {
|
|
92
|
+
yield {
|
|
93
|
+
type: "error",
|
|
94
|
+
path: "",
|
|
95
|
+
size: 0,
|
|
96
|
+
message: `${errors.length} action(s) failed`
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
function assertBucket(bucket, context) {
|
|
101
|
+
if (!bucket) throw new Error(`Bucket required for ${context} actions`);
|
|
102
|
+
}
|
|
103
|
+
function createActionFactory(config) {
|
|
104
|
+
const upConfig = config;
|
|
105
|
+
const downConfig = config;
|
|
106
|
+
const destBucket = upConfig.bucket ?? downConfig.bucket;
|
|
107
|
+
const bucketIsLocked = destBucket?.info?.fileLockConfiguration?.value?.isFileLockEnabled ?? false;
|
|
108
|
+
const factory = {
|
|
109
|
+
upload(source$1) {
|
|
110
|
+
const bucket = upConfig.bucket;
|
|
111
|
+
const prefix = upConfig.prefix ?? "";
|
|
112
|
+
assertBucket(bucket, "upload");
|
|
113
|
+
return new index$1.UploadAction(
|
|
114
|
+
source$1.relativePath,
|
|
115
|
+
source$1.absolutePath,
|
|
116
|
+
source$1.size,
|
|
117
|
+
async (absPath, relPath) => {
|
|
118
|
+
const { readFile } = await import("node:fs/promises");
|
|
119
|
+
const data = await readFile(absPath);
|
|
120
|
+
await bucket.upload({
|
|
121
|
+
fileName: `${prefix}${relPath}`,
|
|
122
|
+
source: new source.BufferSource(new Uint8Array(data))
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
);
|
|
126
|
+
},
|
|
127
|
+
download(source2) {
|
|
128
|
+
const bucket = downConfig.bucket;
|
|
129
|
+
const root = downConfig.dest?.type === "local" ? downConfig.dest.root : "";
|
|
130
|
+
assertBucket(bucket, "download");
|
|
131
|
+
return new index$1.DownloadAction(source2.relativePath, source2.size, async (relPath) => {
|
|
132
|
+
const result = await bucket.download(source2.selectedVersion.fileName);
|
|
133
|
+
const reader = result.body.getReader();
|
|
134
|
+
let combined;
|
|
135
|
+
try {
|
|
136
|
+
const chunks = [];
|
|
137
|
+
while (true) {
|
|
138
|
+
const { done, value } = await reader.read();
|
|
139
|
+
if (done) break;
|
|
140
|
+
chunks.push(value);
|
|
141
|
+
}
|
|
142
|
+
let total = 0;
|
|
143
|
+
for (const c of chunks) total += c.byteLength;
|
|
144
|
+
combined = new Uint8Array(total);
|
|
145
|
+
let offset = 0;
|
|
146
|
+
for (const c of chunks) {
|
|
147
|
+
combined.set(c, offset);
|
|
148
|
+
offset += c.byteLength;
|
|
149
|
+
}
|
|
150
|
+
} finally {
|
|
151
|
+
reader.releaseLock();
|
|
152
|
+
}
|
|
153
|
+
const { mkdir, writeFile } = await import("node:fs/promises");
|
|
154
|
+
const { dirname, join } = await import("node:path");
|
|
155
|
+
const destPath = join(root, relPath);
|
|
156
|
+
await mkdir(dirname(destPath), { recursive: true });
|
|
157
|
+
await writeFile(destPath, combined);
|
|
158
|
+
});
|
|
159
|
+
},
|
|
160
|
+
copy(source2, destPath) {
|
|
161
|
+
const bucket = upConfig.bucket;
|
|
162
|
+
assertBucket(bucket, "copy");
|
|
163
|
+
return new index$1.CopyAction(source2.relativePath, source2.size, async () => {
|
|
164
|
+
await bucket.copyFile({
|
|
165
|
+
sourceFileId: source2.selectedVersion.fileId,
|
|
166
|
+
fileName: destPath
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
},
|
|
170
|
+
hide(path) {
|
|
171
|
+
const bucket = upConfig.bucket ?? downConfig.bucket;
|
|
172
|
+
assertBucket(bucket, "hide");
|
|
173
|
+
return new index$1.HideAction(path, async (relPath) => {
|
|
174
|
+
const prefix = upConfig.prefix ?? "";
|
|
175
|
+
await bucket.hideFile(`${prefix}${relPath}`);
|
|
176
|
+
});
|
|
177
|
+
},
|
|
178
|
+
deleteRemote(path) {
|
|
179
|
+
const bucket = upConfig.bucket ?? downConfig.bucket;
|
|
180
|
+
assertBucket(bucket, "delete");
|
|
181
|
+
const b2FileName = path.selectedVersion.fileName;
|
|
182
|
+
return new index$1.DeleteRemoteAction(
|
|
183
|
+
path.relativePath,
|
|
184
|
+
path.selectedVersion.fileId,
|
|
185
|
+
async (fileId) => {
|
|
186
|
+
await bucket.deleteFileVersion(b2FileName, ids.fileId(fileId));
|
|
187
|
+
}
|
|
188
|
+
);
|
|
189
|
+
},
|
|
190
|
+
deleteLocal(path) {
|
|
191
|
+
return new index$1.DeleteLocalAction(path.relativePath, path.absolutePath, async (absPath) => {
|
|
192
|
+
const { unlink } = await import("node:fs/promises");
|
|
193
|
+
await unlink(absPath);
|
|
194
|
+
});
|
|
195
|
+
},
|
|
196
|
+
removeOrphan(dest) {
|
|
197
|
+
return bucketIsLocked ? factory.hide(dest.relativePath) : factory.deleteRemote(dest);
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
return factory;
|
|
201
|
+
}
|
|
202
|
+
exports.synchronize = synchronize;
|
|
203
|
+
//# sourceMappingURL=synchronizer.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"synchronizer.cjs","sources":["../../src/sync/synchronizer.ts"],"sourcesContent":["import type { Bucket } from '../bucket.ts'\nimport { BufferSource } from '../streams/source.ts'\nimport { fileId as fileIdOf } from '../types/ids.ts'\nimport { Semaphore } from '../upload/concurrency.ts'\nimport { DEFAULT_TRANSFER_CONCURRENCY } from '../util/defaults.ts'\nimport { toError } from '../util/to-error.ts'\nimport type { SyncAction } from './actions/index.ts'\nimport {\n CopyAction,\n DeleteLocalAction,\n DeleteRemoteAction,\n DownloadAction,\n HideAction,\n UploadAction,\n} from './actions/index.ts'\nimport { zipFolders } from './pairing.ts'\nimport type { ActionFactory } from './policies/index.ts'\nimport { generateActions } from './policies/index.ts'\nimport type {\n B2SyncPath,\n LocalSyncPath,\n SyncDirection,\n SyncEvent,\n SyncFolder,\n SyncOptions,\n} from './types.ts'\n\n/** Base configuration for a sync operation. */\nexport interface SynchronizerConfig {\n /** The folder to read files from. */\n readonly source: SyncFolder\n /** The folder to write files to. */\n readonly dest: SyncFolder\n /** Options controlling comparison, deletion policy, and concurrency. */\n readonly options: SyncOptions\n}\n\n/** A sync folder constrained to the local filesystem. */\nexport interface LocalSyncFolder extends SyncFolder {\n /** Discriminant identifying a local folder. */\n readonly type: 'local'\n /** Absolute filesystem path to the local root directory. */\n readonly root: string\n}\n\n/** A sync folder constrained to a B2 bucket prefix. */\nexport interface B2SyncFolder extends SyncFolder {\n /** Discriminant identifying a B2 folder. */\n readonly type: 'b2'\n}\n\n/** Configuration for a local-to-B2 sync (upload direction). */\nexport interface SynchronizerUpConfig extends SynchronizerConfig {\n /** Local source folder. */\n readonly source: LocalSyncFolder\n /** B2 destination folder. */\n readonly dest: B2SyncFolder\n /** The target B2 bucket. */\n readonly bucket: Bucket\n /** Key prefix for uploaded files in the bucket. */\n readonly prefix: string\n}\n\n/** Configuration for a B2-to-local sync (download direction). */\nexport interface SynchronizerDownConfig extends SynchronizerConfig {\n /** B2 source folder. */\n readonly source: B2SyncFolder\n /** Local destination folder. */\n readonly dest: LocalSyncFolder\n /** The source B2 bucket. */\n readonly bucket: Bucket\n}\n\n/**\n * Infers the sync direction from the source and destination folder types.\n * @param source - The folder to read files from.\n * @param dest - The folder to write files to.\n *\n * @returns The resolved sync direction based on folder types.\n *\n * @throws When the source and destination folder types form an unsupported combination.\n */\nfunction resolveDirection(source: SyncFolder, dest: SyncFolder): SyncDirection {\n if (source.type === 'local' && dest.type === 'b2') return 'local-to-b2'\n if (source.type === 'b2' && dest.type === 'local') return 'b2-to-local'\n if (source.type === 'b2' && dest.type === 'b2') return 'b2-to-b2'\n throw new Error(`Unsupported sync direction: ${source.type} to ${dest.type}`)\n}\n\n/**\n * Runs a full sync operation: scans both folders, pairs files, generates actions,\n * and executes them with bounded concurrency. Yields {@link SyncEvent} entries for\n * each comparison and action result.\n *\n * @param config - The synchronizer configuration (source, dest, options, and optional bucket).\n */\nexport async function* synchronize(config: SynchronizerConfig): AsyncGenerator<SyncEvent> {\n const { source, dest, options } = config\n const direction = resolveDirection(source, dest)\n const dryRun = options.dryRun ?? false\n const concurrency = options.concurrency ?? DEFAULT_TRANSFER_CONCURRENCY\n const keepDays = options.keepDays ?? 0\n const compareThreshold = options.compareThreshold ?? 0\n const nowMillis = Date.now()\n\n const factory = createActionFactory(config)\n\n const actions: SyncAction[] = []\n\n for await (const pair of zipFolders(source, dest)) {\n if (options.signal?.aborted) return\n\n for (const action of generateActions(\n pair,\n direction,\n options.compareMode,\n options.keepMode,\n keepDays,\n nowMillis,\n factory,\n compareThreshold,\n )) {\n actions.push(action)\n }\n\n yield { type: 'compare', path: (pair[0] ?? pair[1])?.relativePath ?? '', size: 0 }\n }\n\n const sem = new Semaphore(concurrency)\n const results: SyncEvent[] = []\n const errors: Error[] = []\n\n const promises = actions.map(async (action) => {\n await sem.acquire()\n try {\n if (options.signal?.aborted) return\n const event = await action.execute(dryRun)\n results.push(event)\n } catch (err) {\n const errorValue = toError(err)\n errors.push(errorValue)\n results.push({\n type: 'error',\n path: action.relativePath,\n size: 0,\n message: errorValue.message,\n })\n } finally {\n sem.release()\n }\n })\n\n await Promise.all(promises)\n\n for (const event of results) {\n yield event\n }\n\n if (errors.length > 0) {\n yield {\n type: 'error',\n path: '',\n size: 0,\n message: `${errors.length} action(s) failed`,\n }\n }\n}\n\n/**\n * Narrowing assertion that a `Bucket` is present for an action that requires\n * it. Throws with a consistent, context-tagged message when the configured\n * direction did not supply one (e.g. `b2-to-local` direction asking for an\n * upload action).\n *\n * Uses TypeScript's `asserts` signature so call-site flow narrows\n * `bucket` from `Bucket | undefined` to `Bucket` after the check, without\n * requiring a separate `if (!bucket) throw ...` line per action factory.\n *\n * @param bucket - The (possibly missing) bucket reference.\n * @param context - Short verb describing the action being constructed\n * (e.g. `'upload'`, `'download'`). Surfaced in the error message.\n *\n * @throws `Error` when `bucket` is `undefined` or `null`.\n */\nfunction assertBucket(bucket: Bucket | undefined, context: string): asserts bucket is Bucket {\n if (!bucket) throw new Error(`Bucket required for ${context} actions`)\n}\n\n/**\n * Creates a configured sync engine wired to the bucket and paths in the given config.\n *\n * For sync operations that may need to remove destination-only files (the\n * `keepMode: 'delete'` policy), the factory reads the destination\n * bucket's cached `fileLockConfiguration` once so `removeOrphan` can\n * dispatch to either `hide` (locked buckets) or `deleteFileVersion`\n * (vanilla buckets) without a per-file branch. The cache is whatever\n * `client.listBuckets()` or `client.createBucket()` returned — callers\n * who flipped lock state mid-sync (rare) should refresh before\n * synchronize().\n *\n * @param config - The synchronizer configuration containing source, destination, and options.\n *\n * @returns An action factory bound to the provided configuration.\n */\nfunction createActionFactory(config: SynchronizerConfig): ActionFactory {\n const upConfig = config as Partial<SynchronizerUpConfig>\n const downConfig = config as Partial<SynchronizerDownConfig>\n\n const destBucket = upConfig.bucket ?? downConfig.bucket\n // Defensive optional chain on `info`: synchronizer tests use Bucket\n // mocks that don't populate this field. Real `Bucket` instances always\n // do (constructor parameter).\n const bucketIsLocked = destBucket?.info?.fileLockConfiguration?.value?.isFileLockEnabled ?? false\n\n const factory: ActionFactory = {\n upload(source: LocalSyncPath): SyncAction {\n const bucket = upConfig.bucket\n const prefix = upConfig.prefix ?? ''\n assertBucket(bucket, 'upload')\n\n return new UploadAction(\n source.relativePath,\n source.absolutePath,\n source.size,\n async (absPath, relPath) => {\n const { readFile } = await import('node:fs/promises')\n const data = await readFile(absPath)\n await bucket.upload({\n fileName: `${prefix}${relPath}`,\n source: new BufferSource(new Uint8Array(data)),\n })\n },\n )\n },\n\n download(source: B2SyncPath): SyncAction {\n const bucket = downConfig.bucket\n const root =\n downConfig.dest?.type === 'local' ? (downConfig.dest as { root: string }).root : ''\n assertBucket(bucket, 'download')\n\n return new DownloadAction(source.relativePath, source.size, async (relPath) => {\n const result = await bucket.download(source.selectedVersion.fileName)\n const reader = result.body.getReader()\n let combined: Uint8Array\n try {\n const chunks: Uint8Array[] = []\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n chunks.push(value)\n }\n let total = 0\n for (const c of chunks) total += c.byteLength\n combined = new Uint8Array(total)\n let offset = 0\n for (const c of chunks) {\n combined.set(c, offset)\n offset += c.byteLength\n }\n } finally {\n // Release the body stream's reader lock so a downstream\n // writeFile failure doesn't strand the response stream half-\n // open with the upstream HTTP connection still pumping.\n reader.releaseLock()\n }\n\n const { mkdir, writeFile } = await import('node:fs/promises')\n const { dirname, join } = await import('node:path')\n const destPath = join(root, relPath)\n await mkdir(dirname(destPath), { recursive: true })\n await writeFile(destPath, combined)\n })\n },\n\n copy(source: B2SyncPath, destPath: string): SyncAction {\n const bucket = upConfig.bucket\n assertBucket(bucket, 'copy')\n\n return new CopyAction(source.relativePath, source.size, async () => {\n await bucket.copyFile({\n sourceFileId: source.selectedVersion.fileId,\n fileName: destPath,\n })\n })\n },\n\n hide(path: string): SyncAction {\n const bucket = upConfig.bucket ?? downConfig.bucket\n assertBucket(bucket, 'hide')\n\n return new HideAction(path, async (relPath) => {\n const prefix = upConfig.prefix ?? ''\n await bucket.hideFile(`${prefix}${relPath}`)\n })\n },\n\n deleteRemote(path: B2SyncPath): SyncAction {\n const bucket = upConfig.bucket ?? downConfig.bucket\n assertBucket(bucket, 'delete')\n\n // Bug fix: `DeleteRemoteAction` invokes the closure with\n // `relativePath` (the scanner-stripped name relative to the sync\n // prefix), but B2 stores files under the FULL name including the\n // prefix. Use the FileVersion's authoritative `fileName` — the\n // actual B2 key — rather than reconstructing it via prefix\n // concat. Without this, syncs with a non-empty destination\n // prefix (e.g. `'site/'`) failed orphan deletion with\n // `file_not_present`.\n const b2FileName = path.selectedVersion.fileName\n return new DeleteRemoteAction(\n path.relativePath,\n path.selectedVersion.fileId as string,\n async (fileId) => {\n await bucket.deleteFileVersion(b2FileName, fileIdOf(fileId))\n },\n )\n },\n\n deleteLocal(path: LocalSyncPath): SyncAction {\n return new DeleteLocalAction(path.relativePath, path.absolutePath, async (absPath) => {\n const { unlink } = await import('node:fs/promises')\n await unlink(absPath)\n })\n },\n\n removeOrphan(dest: B2SyncPath): SyncAction {\n // Locked buckets: `b2_delete_file_version` is blocked or stacks\n // hide markers under retention; a hide is the safe choice.\n // Vanilla buckets: plain delete is the right move — hide markers\n // would just litter the version history.\n return bucketIsLocked ? factory.hide(dest.relativePath) : factory.deleteRemote(dest)\n },\n }\n\n return factory\n}\n"],"names":["source","concurrency","DEFAULT_TRANSFER_CONCURRENCY","zipFolders","generateActions","Semaphore","toError","UploadAction","BufferSource","DownloadAction","CopyAction","HideAction","DeleteRemoteAction","fileIdOf","DeleteLocalAction"],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Bucket } from '../bucket.js';
|
|
2
|
+
import { SyncEvent, SyncFolder, SyncOptions } from './types.js';
|
|
3
|
+
/** Base configuration for a sync operation. */
|
|
4
|
+
export interface SynchronizerConfig {
|
|
5
|
+
/** The folder to read files from. */
|
|
6
|
+
readonly source: SyncFolder;
|
|
7
|
+
/** The folder to write files to. */
|
|
8
|
+
readonly dest: SyncFolder;
|
|
9
|
+
/** Options controlling comparison, deletion policy, and concurrency. */
|
|
10
|
+
readonly options: SyncOptions;
|
|
11
|
+
}
|
|
12
|
+
/** A sync folder constrained to the local filesystem. */
|
|
13
|
+
export interface LocalSyncFolder extends SyncFolder {
|
|
14
|
+
/** Discriminant identifying a local folder. */
|
|
15
|
+
readonly type: 'local';
|
|
16
|
+
/** Absolute filesystem path to the local root directory. */
|
|
17
|
+
readonly root: string;
|
|
18
|
+
}
|
|
19
|
+
/** A sync folder constrained to a B2 bucket prefix. */
|
|
20
|
+
export interface B2SyncFolder extends SyncFolder {
|
|
21
|
+
/** Discriminant identifying a B2 folder. */
|
|
22
|
+
readonly type: 'b2';
|
|
23
|
+
}
|
|
24
|
+
/** Configuration for a local-to-B2 sync (upload direction). */
|
|
25
|
+
export interface SynchronizerUpConfig extends SynchronizerConfig {
|
|
26
|
+
/** Local source folder. */
|
|
27
|
+
readonly source: LocalSyncFolder;
|
|
28
|
+
/** B2 destination folder. */
|
|
29
|
+
readonly dest: B2SyncFolder;
|
|
30
|
+
/** The target B2 bucket. */
|
|
31
|
+
readonly bucket: Bucket;
|
|
32
|
+
/** Key prefix for uploaded files in the bucket. */
|
|
33
|
+
readonly prefix: string;
|
|
34
|
+
}
|
|
35
|
+
/** Configuration for a B2-to-local sync (download direction). */
|
|
36
|
+
export interface SynchronizerDownConfig extends SynchronizerConfig {
|
|
37
|
+
/** B2 source folder. */
|
|
38
|
+
readonly source: B2SyncFolder;
|
|
39
|
+
/** Local destination folder. */
|
|
40
|
+
readonly dest: LocalSyncFolder;
|
|
41
|
+
/** The source B2 bucket. */
|
|
42
|
+
readonly bucket: Bucket;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Runs a full sync operation: scans both folders, pairs files, generates actions,
|
|
46
|
+
* and executes them with bounded concurrency. Yields {@link SyncEvent} entries for
|
|
47
|
+
* each comparison and action result.
|
|
48
|
+
*
|
|
49
|
+
* @param config - The synchronizer configuration (source, dest, options, and optional bucket).
|
|
50
|
+
*/
|
|
51
|
+
export declare function synchronize(config: SynchronizerConfig): AsyncGenerator<SyncEvent>;
|
|
52
|
+
//# sourceMappingURL=synchronizer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"synchronizer.d.ts","sourceRoot":"","sources":["../../src/sync/synchronizer.js"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAkB1C,OAAO,KAAK,EAIV,SAAS,EACT,UAAU,EACV,WAAW,EACZ,MAAM,YAAY,CAAA;AAEnB,+CAA+C;AAC/C,MAAM,WAAW,kBAAkB;IACjC,qCAAqC;IACrC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAA;IAC3B,oCAAoC;IACpC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;IACzB,wEAAwE;IACxE,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAA;CAC9B;AAED,yDAAyD;AACzD,MAAM,WAAW,eAAgB,SAAQ,UAAU;IACjD,+CAA+C;IAC/C,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;IACtB,4DAA4D;IAC5D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED,uDAAuD;AACvD,MAAM,WAAW,YAAa,SAAQ,UAAU;IAC9C,4CAA4C;IAC5C,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAA;CACpB;AAED,+DAA+D;AAC/D,MAAM,WAAW,oBAAqB,SAAQ,kBAAkB;IAC9D,2BAA2B;IAC3B,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAA;IAChC,6BAA6B;IAC7B,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAA;IAC3B,4BAA4B;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,mDAAmD;IACnD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB;AAED,iEAAiE;AACjE,MAAM,WAAW,sBAAuB,SAAQ,kBAAkB;IAChE,wBAAwB;IACxB,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAA;IAC7B,gCAAgC;IAChC,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAA;IAC9B,4BAA4B;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB;AAkBD;;;;;;GAMG;AACH,wBAAuB,WAAW,CAAC,MAAM,EAAE,kBAAkB,GAAG,cAAc,CAAC,SAAS,CAAC,CAsExF"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Bucket } from '../bucket.js';
|
|
2
|
+
import { SyncEvent, SyncFolder, SyncOptions } from './types.js';
|
|
3
|
+
/** Base configuration for a sync operation. */
|
|
4
|
+
export interface SynchronizerConfig {
|
|
5
|
+
/** The folder to read files from. */
|
|
6
|
+
readonly source: SyncFolder;
|
|
7
|
+
/** The folder to write files to. */
|
|
8
|
+
readonly dest: SyncFolder;
|
|
9
|
+
/** Options controlling comparison, deletion policy, and concurrency. */
|
|
10
|
+
readonly options: SyncOptions;
|
|
11
|
+
}
|
|
12
|
+
/** A sync folder constrained to the local filesystem. */
|
|
13
|
+
export interface LocalSyncFolder extends SyncFolder {
|
|
14
|
+
/** Discriminant identifying a local folder. */
|
|
15
|
+
readonly type: 'local';
|
|
16
|
+
/** Absolute filesystem path to the local root directory. */
|
|
17
|
+
readonly root: string;
|
|
18
|
+
}
|
|
19
|
+
/** A sync folder constrained to a B2 bucket prefix. */
|
|
20
|
+
export interface B2SyncFolder extends SyncFolder {
|
|
21
|
+
/** Discriminant identifying a B2 folder. */
|
|
22
|
+
readonly type: 'b2';
|
|
23
|
+
}
|
|
24
|
+
/** Configuration for a local-to-B2 sync (upload direction). */
|
|
25
|
+
export interface SynchronizerUpConfig extends SynchronizerConfig {
|
|
26
|
+
/** Local source folder. */
|
|
27
|
+
readonly source: LocalSyncFolder;
|
|
28
|
+
/** B2 destination folder. */
|
|
29
|
+
readonly dest: B2SyncFolder;
|
|
30
|
+
/** The target B2 bucket. */
|
|
31
|
+
readonly bucket: Bucket;
|
|
32
|
+
/** Key prefix for uploaded files in the bucket. */
|
|
33
|
+
readonly prefix: string;
|
|
34
|
+
}
|
|
35
|
+
/** Configuration for a B2-to-local sync (download direction). */
|
|
36
|
+
export interface SynchronizerDownConfig extends SynchronizerConfig {
|
|
37
|
+
/** B2 source folder. */
|
|
38
|
+
readonly source: B2SyncFolder;
|
|
39
|
+
/** Local destination folder. */
|
|
40
|
+
readonly dest: LocalSyncFolder;
|
|
41
|
+
/** The source B2 bucket. */
|
|
42
|
+
readonly bucket: Bucket;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Runs a full sync operation: scans both folders, pairs files, generates actions,
|
|
46
|
+
* and executes them with bounded concurrency. Yields {@link SyncEvent} entries for
|
|
47
|
+
* each comparison and action result.
|
|
48
|
+
*
|
|
49
|
+
* @param config - The synchronizer configuration (source, dest, options, and optional bucket).
|
|
50
|
+
*/
|
|
51
|
+
export declare function synchronize(config: SynchronizerConfig): AsyncGenerator<SyncEvent>;
|
|
52
|
+
//# sourceMappingURL=synchronizer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"synchronizer.d.ts","sourceRoot":"","sources":["../../src/sync/synchronizer.js"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAkB1C,OAAO,KAAK,EAIV,SAAS,EACT,UAAU,EACV,WAAW,EACZ,MAAM,YAAY,CAAA;AAEnB,+CAA+C;AAC/C,MAAM,WAAW,kBAAkB;IACjC,qCAAqC;IACrC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAA;IAC3B,oCAAoC;IACpC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;IACzB,wEAAwE;IACxE,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAA;CAC9B;AAED,yDAAyD;AACzD,MAAM,WAAW,eAAgB,SAAQ,UAAU;IACjD,+CAA+C;IAC/C,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;IACtB,4DAA4D;IAC5D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED,uDAAuD;AACvD,MAAM,WAAW,YAAa,SAAQ,UAAU;IAC9C,4CAA4C;IAC5C,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAA;CACpB;AAED,+DAA+D;AAC/D,MAAM,WAAW,oBAAqB,SAAQ,kBAAkB;IAC9D,2BAA2B;IAC3B,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAA;IAChC,6BAA6B;IAC7B,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAA;IAC3B,4BAA4B;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,mDAAmD;IACnD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB;AAED,iEAAiE;AACjE,MAAM,WAAW,sBAAuB,SAAQ,kBAAkB;IAChE,wBAAwB;IACxB,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAA;IAC7B,gCAAgC;IAChC,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAA;IAC9B,4BAA4B;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB;AAkBD;;;;;;GAMG;AACH,wBAAuB,WAAW,CAAC,MAAM,EAAE,kBAAkB,GAAG,cAAc,CAAC,SAAS,CAAC,CAsExF"}
|