@streetjs/storage 1.0.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/LICENSE +21 -0
- package/README.md +719 -0
- package/dist/access.d.ts +95 -0
- package/dist/access.d.ts.map +1 -0
- package/dist/access.js +114 -0
- package/dist/access.js.map +1 -0
- package/dist/cli/commands.d.ts +88 -0
- package/dist/cli/commands.d.ts.map +1 -0
- package/dist/cli/commands.js +369 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/cli/generators.d.ts +41 -0
- package/dist/cli/generators.d.ts.map +1 -0
- package/dist/cli/generators.js +119 -0
- package/dist/cli/generators.js.map +1 -0
- package/dist/directory.d.ts +88 -0
- package/dist/directory.d.ts.map +1 -0
- package/dist/directory.js +148 -0
- package/dist/directory.js.map +1 -0
- package/dist/driver.d.ts +83 -0
- package/dist/driver.d.ts.map +1 -0
- package/dist/driver.js +16 -0
- package/dist/driver.js.map +1 -0
- package/dist/drivers/azure.d.ts +239 -0
- package/dist/drivers/azure.d.ts.map +1 -0
- package/dist/drivers/azure.js +476 -0
- package/dist/drivers/azure.js.map +1 -0
- package/dist/drivers/backblaze.d.ts +105 -0
- package/dist/drivers/backblaze.d.ts.map +1 -0
- package/dist/drivers/backblaze.js +279 -0
- package/dist/drivers/backblaze.js.map +1 -0
- package/dist/drivers/gcs.d.ts +239 -0
- package/dist/drivers/gcs.d.ts.map +1 -0
- package/dist/drivers/gcs.js +454 -0
- package/dist/drivers/gcs.js.map +1 -0
- package/dist/drivers/local.d.ts +126 -0
- package/dist/drivers/local.d.ts.map +1 -0
- package/dist/drivers/local.js +321 -0
- package/dist/drivers/local.js.map +1 -0
- package/dist/drivers/memory.d.ts +104 -0
- package/dist/drivers/memory.d.ts.map +1 -0
- package/dist/drivers/memory.js +197 -0
- package/dist/drivers/memory.js.map +1 -0
- package/dist/drivers/minio.d.ts +90 -0
- package/dist/drivers/minio.d.ts.map +1 -0
- package/dist/drivers/minio.js +276 -0
- package/dist/drivers/minio.js.map +1 -0
- package/dist/drivers/r2.d.ts +100 -0
- package/dist/drivers/r2.d.ts.map +1 -0
- package/dist/drivers/r2.js +240 -0
- package/dist/drivers/r2.js.map +1 -0
- package/dist/drivers/s3-base.d.ts +270 -0
- package/dist/drivers/s3-base.d.ts.map +1 -0
- package/dist/drivers/s3-base.js +436 -0
- package/dist/drivers/s3-base.js.map +1 -0
- package/dist/drivers/s3.d.ts +111 -0
- package/dist/drivers/s3.d.ts.map +1 -0
- package/dist/drivers/s3.js +311 -0
- package/dist/drivers/s3.js.map +1 -0
- package/dist/drivers/supabase.d.ts +246 -0
- package/dist/drivers/supabase.d.ts.map +1 -0
- package/dist/drivers/supabase.js +502 -0
- package/dist/drivers/supabase.js.map +1 -0
- package/dist/errors.d.ts +115 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +131 -0
- package/dist/errors.js.map +1 -0
- package/dist/examples/storage-demo.d.ts +53 -0
- package/dist/examples/storage-demo.d.ts.map +1 -0
- package/dist/examples/storage-demo.js +242 -0
- package/dist/examples/storage-demo.js.map +1 -0
- package/dist/facade.d.ts +192 -0
- package/dist/facade.d.ts.map +1 -0
- package/dist/facade.js +898 -0
- package/dist/facade.js.map +1 -0
- package/dist/image.d.ts +94 -0
- package/dist/image.d.ts.map +1 -0
- package/dist/image.js +224 -0
- package/dist/image.js.map +1 -0
- package/dist/index.d.ts +47 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +53 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/events.d.ts +108 -0
- package/dist/integrations/events.d.ts.map +1 -0
- package/dist/integrations/events.js +111 -0
- package/dist/integrations/events.js.map +1 -0
- package/dist/integrations/queue.d.ts +89 -0
- package/dist/integrations/queue.d.ts.map +1 -0
- package/dist/integrations/queue.js +91 -0
- package/dist/integrations/queue.js.map +1 -0
- package/dist/integrations/realtime.d.ts +95 -0
- package/dist/integrations/realtime.d.ts.map +1 -0
- package/dist/integrations/realtime.js +90 -0
- package/dist/integrations/realtime.js.map +1 -0
- package/dist/lifecycle.d.ts +137 -0
- package/dist/lifecycle.d.ts.map +1 -0
- package/dist/lifecycle.js +240 -0
- package/dist/lifecycle.js.map +1 -0
- package/dist/metadata.d.ts +109 -0
- package/dist/metadata.d.ts.map +1 -0
- package/dist/metadata.js +139 -0
- package/dist/metadata.js.map +1 -0
- package/dist/multipart.d.ts +108 -0
- package/dist/multipart.d.ts.map +1 -0
- package/dist/multipart.js +200 -0
- package/dist/multipart.js.map +1 -0
- package/dist/observability.d.ts +82 -0
- package/dist/observability.d.ts.map +1 -0
- package/dist/observability.js +175 -0
- package/dist/observability.js.map +1 -0
- package/dist/plugin.d.ts +82 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +100 -0
- package/dist/plugin.js.map +1 -0
- package/dist/resumable.d.ts +118 -0
- package/dist/resumable.d.ts.map +1 -0
- package/dist/resumable.js +223 -0
- package/dist/resumable.js.map +1 -0
- package/dist/search.d.ts +57 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +172 -0
- package/dist/search.js.map +1 -0
- package/dist/signed-url.d.ts +110 -0
- package/dist/signed-url.d.ts.map +1 -0
- package/dist/signed-url.js +237 -0
- package/dist/signed-url.js.map +1 -0
- package/dist/testing/index.d.ts +219 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +393 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/tests/access.test.d.ts +2 -0
- package/dist/tests/access.test.d.ts.map +1 -0
- package/dist/tests/access.test.js +270 -0
- package/dist/tests/access.test.js.map +1 -0
- package/dist/tests/azure-driver.test.d.ts +2 -0
- package/dist/tests/azure-driver.test.d.ts.map +1 -0
- package/dist/tests/azure-driver.test.js +183 -0
- package/dist/tests/azure-driver.test.js.map +1 -0
- package/dist/tests/backblaze-driver.test.d.ts +2 -0
- package/dist/tests/backblaze-driver.test.d.ts.map +1 -0
- package/dist/tests/backblaze-driver.test.js +185 -0
- package/dist/tests/backblaze-driver.test.js.map +1 -0
- package/dist/tests/bridge-degradation.test.d.ts +2 -0
- package/dist/tests/bridge-degradation.test.d.ts.map +1 -0
- package/dist/tests/bridge-degradation.test.js +138 -0
- package/dist/tests/bridge-degradation.test.js.map +1 -0
- package/dist/tests/cli.test.d.ts +2 -0
- package/dist/tests/cli.test.d.ts.map +1 -0
- package/dist/tests/cli.test.js +127 -0
- package/dist/tests/cli.test.js.map +1 -0
- package/dist/tests/contract.d.ts +131 -0
- package/dist/tests/contract.d.ts.map +1 -0
- package/dist/tests/contract.js +222 -0
- package/dist/tests/contract.js.map +1 -0
- package/dist/tests/contract.test.d.ts +2 -0
- package/dist/tests/contract.test.d.ts.map +1 -0
- package/dist/tests/contract.test.js +110 -0
- package/dist/tests/contract.test.js.map +1 -0
- package/dist/tests/directory.test.d.ts +2 -0
- package/dist/tests/directory.test.d.ts.map +1 -0
- package/dist/tests/directory.test.js +125 -0
- package/dist/tests/directory.test.js.map +1 -0
- package/dist/tests/errors.test.d.ts +2 -0
- package/dist/tests/errors.test.d.ts.map +1 -0
- package/dist/tests/errors.test.js +93 -0
- package/dist/tests/errors.test.js.map +1 -0
- package/dist/tests/events-bridge.test.d.ts +2 -0
- package/dist/tests/events-bridge.test.d.ts.map +1 -0
- package/dist/tests/events-bridge.test.js +228 -0
- package/dist/tests/events-bridge.test.js.map +1 -0
- package/dist/tests/example-smoke.test.d.ts +2 -0
- package/dist/tests/example-smoke.test.d.ts.map +1 -0
- package/dist/tests/example-smoke.test.js +34 -0
- package/dist/tests/example-smoke.test.js.map +1 -0
- package/dist/tests/gcs-driver.test.d.ts +2 -0
- package/dist/tests/gcs-driver.test.d.ts.map +1 -0
- package/dist/tests/gcs-driver.test.js +197 -0
- package/dist/tests/gcs-driver.test.js.map +1 -0
- package/dist/tests/image.test.d.ts +2 -0
- package/dist/tests/image.test.d.ts.map +1 -0
- package/dist/tests/image.test.js +102 -0
- package/dist/tests/image.test.js.map +1 -0
- package/dist/tests/lifecycle.test.d.ts +2 -0
- package/dist/tests/lifecycle.test.d.ts.map +1 -0
- package/dist/tests/lifecycle.test.js +171 -0
- package/dist/tests/lifecycle.test.js.map +1 -0
- package/dist/tests/local-driver.test.d.ts +2 -0
- package/dist/tests/local-driver.test.d.ts.map +1 -0
- package/dist/tests/local-driver.test.js +153 -0
- package/dist/tests/local-driver.test.js.map +1 -0
- package/dist/tests/local-streaming.test.d.ts +2 -0
- package/dist/tests/local-streaming.test.d.ts.map +1 -0
- package/dist/tests/local-streaming.test.js +121 -0
- package/dist/tests/local-streaming.test.js.map +1 -0
- package/dist/tests/memory-driver.test.d.ts +2 -0
- package/dist/tests/memory-driver.test.d.ts.map +1 -0
- package/dist/tests/memory-driver.test.js +180 -0
- package/dist/tests/memory-driver.test.js.map +1 -0
- package/dist/tests/memory-streaming.test.d.ts +2 -0
- package/dist/tests/memory-streaming.test.d.ts.map +1 -0
- package/dist/tests/memory-streaming.test.js +92 -0
- package/dist/tests/memory-streaming.test.js.map +1 -0
- package/dist/tests/minio-driver.test.d.ts +2 -0
- package/dist/tests/minio-driver.test.d.ts.map +1 -0
- package/dist/tests/minio-driver.test.js +146 -0
- package/dist/tests/minio-driver.test.js.map +1 -0
- package/dist/tests/non-s3-integration.test.d.ts +2 -0
- package/dist/tests/non-s3-integration.test.d.ts.map +1 -0
- package/dist/tests/non-s3-integration.test.js +201 -0
- package/dist/tests/non-s3-integration.test.js.map +1 -0
- package/dist/tests/observability.registration.test.d.ts +2 -0
- package/dist/tests/observability.registration.test.d.ts.map +1 -0
- package/dist/tests/observability.registration.test.js +103 -0
- package/dist/tests/observability.registration.test.js.map +1 -0
- package/dist/tests/observability.test.d.ts +2 -0
- package/dist/tests/observability.test.d.ts.map +1 -0
- package/dist/tests/observability.test.js +240 -0
- package/dist/tests/observability.test.js.map +1 -0
- package/dist/tests/plugin.test.d.ts +2 -0
- package/dist/tests/plugin.test.d.ts.map +1 -0
- package/dist/tests/plugin.test.js +112 -0
- package/dist/tests/plugin.test.js.map +1 -0
- package/dist/tests/prop-concurrent.test.d.ts +2 -0
- package/dist/tests/prop-concurrent.test.d.ts.map +1 -0
- package/dist/tests/prop-concurrent.test.js +59 -0
- package/dist/tests/prop-concurrent.test.js.map +1 -0
- package/dist/tests/prop-copy.test.d.ts +2 -0
- package/dist/tests/prop-copy.test.d.ts.map +1 -0
- package/dist/tests/prop-copy.test.js +63 -0
- package/dist/tests/prop-copy.test.js.map +1 -0
- package/dist/tests/prop-delete.test.d.ts +2 -0
- package/dist/tests/prop-delete.test.d.ts.map +1 -0
- package/dist/tests/prop-delete.test.js +35 -0
- package/dist/tests/prop-delete.test.js.map +1 -0
- package/dist/tests/prop-directory.test.d.ts +2 -0
- package/dist/tests/prop-directory.test.d.ts.map +1 -0
- package/dist/tests/prop-directory.test.js +118 -0
- package/dist/tests/prop-directory.test.js.map +1 -0
- package/dist/tests/prop-driver-conformance.test.d.ts +2 -0
- package/dist/tests/prop-driver-conformance.test.d.ts.map +1 -0
- package/dist/tests/prop-driver-conformance.test.js +110 -0
- package/dist/tests/prop-driver-conformance.test.js.map +1 -0
- package/dist/tests/prop-driver-equivalence.test.d.ts +2 -0
- package/dist/tests/prop-driver-equivalence.test.d.ts.map +1 -0
- package/dist/tests/prop-driver-equivalence.test.js +163 -0
- package/dist/tests/prop-driver-equivalence.test.js.map +1 -0
- package/dist/tests/prop-lifecycle.test.d.ts +2 -0
- package/dist/tests/prop-lifecycle.test.d.ts.map +1 -0
- package/dist/tests/prop-lifecycle.test.js +83 -0
- package/dist/tests/prop-lifecycle.test.js.map +1 -0
- package/dist/tests/prop-list.test.d.ts +2 -0
- package/dist/tests/prop-list.test.d.ts.map +1 -0
- package/dist/tests/prop-list.test.js +53 -0
- package/dist/tests/prop-list.test.js.map +1 -0
- package/dist/tests/prop-metadata.test.d.ts +2 -0
- package/dist/tests/prop-metadata.test.d.ts.map +1 -0
- package/dist/tests/prop-metadata.test.js +87 -0
- package/dist/tests/prop-metadata.test.js.map +1 -0
- package/dist/tests/prop-move.test.d.ts +2 -0
- package/dist/tests/prop-move.test.d.ts.map +1 -0
- package/dist/tests/prop-move.test.js +67 -0
- package/dist/tests/prop-move.test.js.map +1 -0
- package/dist/tests/prop-multipart-abort.test.d.ts +2 -0
- package/dist/tests/prop-multipart-abort.test.d.ts.map +1 -0
- package/dist/tests/prop-multipart-abort.test.js +48 -0
- package/dist/tests/prop-multipart-abort.test.js.map +1 -0
- package/dist/tests/prop-multipart.test.d.ts +2 -0
- package/dist/tests/prop-multipart.test.d.ts.map +1 -0
- package/dist/tests/prop-multipart.test.js +65 -0
- package/dist/tests/prop-multipart.test.js.map +1 -0
- package/dist/tests/prop-resumable.test.d.ts +2 -0
- package/dist/tests/prop-resumable.test.d.ts.map +1 -0
- package/dist/tests/prop-resumable.test.js +78 -0
- package/dist/tests/prop-resumable.test.js.map +1 -0
- package/dist/tests/prop-search.test.d.ts +2 -0
- package/dist/tests/prop-search.test.d.ts.map +1 -0
- package/dist/tests/prop-search.test.js +120 -0
- package/dist/tests/prop-search.test.js.map +1 -0
- package/dist/tests/prop-signed-url.test.d.ts +2 -0
- package/dist/tests/prop-signed-url.test.d.ts.map +1 -0
- package/dist/tests/prop-signed-url.test.js +74 -0
- package/dist/tests/prop-signed-url.test.js.map +1 -0
- package/dist/tests/prop-streaming.test.d.ts +2 -0
- package/dist/tests/prop-streaming.test.d.ts.map +1 -0
- package/dist/tests/prop-streaming.test.js +34 -0
- package/dist/tests/prop-streaming.test.js.map +1 -0
- package/dist/tests/prop-upload-download.test.d.ts +2 -0
- package/dist/tests/prop-upload-download.test.d.ts.map +1 -0
- package/dist/tests/prop-upload-download.test.js +30 -0
- package/dist/tests/prop-upload-download.test.js.map +1 -0
- package/dist/tests/prop-validation.test.d.ts +2 -0
- package/dist/tests/prop-validation.test.d.ts.map +1 -0
- package/dist/tests/prop-validation.test.js +50 -0
- package/dist/tests/prop-validation.test.js.map +1 -0
- package/dist/tests/prop-versioning.test.d.ts +2 -0
- package/dist/tests/prop-versioning.test.d.ts.map +1 -0
- package/dist/tests/prop-versioning.test.js +74 -0
- package/dist/tests/prop-versioning.test.js.map +1 -0
- package/dist/tests/queue-bridge.test.d.ts +2 -0
- package/dist/tests/queue-bridge.test.d.ts.map +1 -0
- package/dist/tests/queue-bridge.test.js +111 -0
- package/dist/tests/queue-bridge.test.js.map +1 -0
- package/dist/tests/r2-driver.test.d.ts +2 -0
- package/dist/tests/r2-driver.test.d.ts.map +1 -0
- package/dist/tests/r2-driver.test.js +143 -0
- package/dist/tests/r2-driver.test.js.map +1 -0
- package/dist/tests/realtime-bridge.test.d.ts +2 -0
- package/dist/tests/realtime-bridge.test.d.ts.map +1 -0
- package/dist/tests/realtime-bridge.test.js +106 -0
- package/dist/tests/realtime-bridge.test.js.map +1 -0
- package/dist/tests/resumable.test.d.ts +2 -0
- package/dist/tests/resumable.test.d.ts.map +1 -0
- package/dist/tests/resumable.test.js +104 -0
- package/dist/tests/resumable.test.js.map +1 -0
- package/dist/tests/s3-base.test.d.ts +2 -0
- package/dist/tests/s3-base.test.d.ts.map +1 -0
- package/dist/tests/s3-base.test.js +289 -0
- package/dist/tests/s3-base.test.js.map +1 -0
- package/dist/tests/s3-integration.test.d.ts +2 -0
- package/dist/tests/s3-integration.test.d.ts.map +1 -0
- package/dist/tests/s3-integration.test.js +270 -0
- package/dist/tests/s3-integration.test.js.map +1 -0
- package/dist/tests/s3.test.d.ts +2 -0
- package/dist/tests/s3.test.d.ts.map +1 -0
- package/dist/tests/s3.test.js +203 -0
- package/dist/tests/s3.test.js.map +1 -0
- package/dist/tests/scaffold.test.d.ts +2 -0
- package/dist/tests/scaffold.test.d.ts.map +1 -0
- package/dist/tests/scaffold.test.js +13 -0
- package/dist/tests/scaffold.test.js.map +1 -0
- package/dist/tests/search.test.d.ts +2 -0
- package/dist/tests/search.test.d.ts.map +1 -0
- package/dist/tests/search.test.js +106 -0
- package/dist/tests/search.test.js.map +1 -0
- package/dist/tests/supabase-driver.test.d.ts +2 -0
- package/dist/tests/supabase-driver.test.d.ts.map +1 -0
- package/dist/tests/supabase-driver.test.js +196 -0
- package/dist/tests/supabase-driver.test.js.map +1 -0
- package/dist/tests/testing-utilities.test.d.ts +2 -0
- package/dist/tests/testing-utilities.test.d.ts.map +1 -0
- package/dist/tests/testing-utilities.test.js +138 -0
- package/dist/tests/testing-utilities.test.js.map +1 -0
- package/dist/tests/validation.test.d.ts +2 -0
- package/dist/tests/validation.test.d.ts.map +1 -0
- package/dist/tests/validation.test.js +135 -0
- package/dist/tests/validation.test.js.map +1 -0
- package/dist/tests/versioning.test.d.ts +2 -0
- package/dist/tests/versioning.test.d.ts.map +1 -0
- package/dist/tests/versioning.test.js +128 -0
- package/dist/tests/versioning.test.js.map +1 -0
- package/dist/types.d.ts +232 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +23 -0
- package/dist/types.js.map +1 -0
- package/dist/validation.d.ts +105 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +225 -0
- package/dist/validation.js.map +1 -0
- package/dist/versioning.d.ts +100 -0
- package/dist/versioning.d.ts.map +1 -0
- package/dist/versioning.js +179 -0
- package/dist/versioning.js.map +1 -0
- package/package.json +137 -0
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @streetjs/storage — the Backblaze B2 driver submodule (`@streetjs/storage/backblaze`).
|
|
3
|
+
*
|
|
4
|
+
* Backblaze B2 exposes a **fully S3-compatible API**, so this driver is a thin
|
|
5
|
+
* specialization of the shared S3-style base ({@link createS3StyleDriver} in
|
|
6
|
+
* `s3-base.ts`): it only differs in how the underlying client is
|
|
7
|
+
* built/configured (a B2 S3 endpoint and B2 application-key credentials), never
|
|
8
|
+
* in how the {@link StorageDriver} contract is satisfied. The driver name is
|
|
9
|
+
* fixed to `"backblaze"`.
|
|
10
|
+
*
|
|
11
|
+
* ## SDK isolation (Requirements 3.1, 3.3)
|
|
12
|
+
*
|
|
13
|
+
* This module imports **no provider SDK at the top level** — only this package's
|
|
14
|
+
* own type surface and the shared S3-style base. It supports two construction
|
|
15
|
+
* modes:
|
|
16
|
+
*
|
|
17
|
+
* 1. **Injected structural client** — the caller passes an {@link S3ClientLike}
|
|
18
|
+
* (the minimal, SDK-shaped structural interface the base depends on). The SDK
|
|
19
|
+
* is then entirely a concern of the caller; this package resolves nothing.
|
|
20
|
+
* ({@link createBackblazeB2Driver} with a client, synchronous.)
|
|
21
|
+
* 2. **Self-built client from connection config** — the driver constructs its own
|
|
22
|
+
* S3-compatible client for the B2 endpoint using a **lazy dynamic `import()`**
|
|
23
|
+
* performed inside the factory at construction time (never at module top
|
|
24
|
+
* level), so `@aws-sdk/client-s3` is resolved only when this submodule is
|
|
25
|
+
* actually used to build a client. If that optional peer SDK is absent (and no
|
|
26
|
+
* client was injected), a descriptive {@link StorageConfigError} is thrown.
|
|
27
|
+
* ({@link createBackblazeB2Driver} with a config, asynchronous.)
|
|
28
|
+
*
|
|
29
|
+
* Because this driver lives behind the `./backblaze` subpath export and the base
|
|
30
|
+
* package never imports it, `streetjs` stays the only runtime dependency and the
|
|
31
|
+
* B2/S3 SDK remains an optional peer dependency.
|
|
32
|
+
*
|
|
33
|
+
* _Requirements: 2.1, 2.3, 3.3_
|
|
34
|
+
*/
|
|
35
|
+
import { Buffer } from "node:buffer";
|
|
36
|
+
import { systemClock } from "streetjs";
|
|
37
|
+
import { StorageConfigError } from "../errors.js";
|
|
38
|
+
import { createS3StyleDriver, S3StyleDriver, } from "./s3-base.js";
|
|
39
|
+
/** The stable driver name surfaced as {@link StorageDriver.name}. */
|
|
40
|
+
export const BACKBLAZE_DRIVER_NAME = "backblaze";
|
|
41
|
+
/** Peer SDK specifier resolved lazily when the driver builds its own client. */
|
|
42
|
+
const BACKBLAZE_SDK_SPECIFIER = "@aws-sdk/client-s3";
|
|
43
|
+
export function createBackblazeB2Driver(clientOrConfig, options = {}) {
|
|
44
|
+
if (isS3ClientLike(clientOrConfig)) {
|
|
45
|
+
return buildDriver(clientOrConfig, options);
|
|
46
|
+
}
|
|
47
|
+
return buildFromConnectionConfig(clientOrConfig);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* A Backblaze B2 driver as a concrete class over an injected {@link S3ClientLike},
|
|
51
|
+
* for callers who prefer `new` construction. Equivalent to
|
|
52
|
+
* {@link createBackblazeB2Driver} with an injected client; the name defaults to
|
|
53
|
+
* `"backblaze"`.
|
|
54
|
+
*/
|
|
55
|
+
export class BackblazeB2Driver extends S3StyleDriver {
|
|
56
|
+
constructor(client, options = {}) {
|
|
57
|
+
super(client, {
|
|
58
|
+
name: options.name ?? BACKBLAZE_DRIVER_NAME,
|
|
59
|
+
clock: options.clock ?? systemClock,
|
|
60
|
+
capabilities: options.capabilities,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// ── Internal construction helpers ───────────────────────────────────────────
|
|
65
|
+
/** Delegate to the shared S3-style base, fixing the name to `"backblaze"`. */
|
|
66
|
+
function buildDriver(client, options) {
|
|
67
|
+
return createS3StyleDriver(client, {
|
|
68
|
+
name: options.name ?? BACKBLAZE_DRIVER_NAME,
|
|
69
|
+
clock: options.clock ?? systemClock,
|
|
70
|
+
capabilities: options.capabilities,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Build a B2 S3-compatible client via a lazy dynamic `import()` of the optional
|
|
75
|
+
* peer SDK, then wrap it in {@link S3ClientLike} and hand it to the base. Throws
|
|
76
|
+
* a descriptive {@link StorageConfigError} when the SDK cannot be resolved.
|
|
77
|
+
*/
|
|
78
|
+
async function buildFromConnectionConfig(config) {
|
|
79
|
+
const client = await buildBackblazeS3Client(config);
|
|
80
|
+
return buildDriver(client, config);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Structural guard distinguishing an injected {@link S3ClientLike} from a
|
|
84
|
+
* connection config: only a client exposes the mandatory `putObject` method.
|
|
85
|
+
*/
|
|
86
|
+
function isS3ClientLike(value) {
|
|
87
|
+
return typeof value.putObject === "function";
|
|
88
|
+
}
|
|
89
|
+
// ── The lazily-built S3-compatible client for Backblaze B2 ──────────────────────
|
|
90
|
+
/**
|
|
91
|
+
* Resolve `@aws-sdk/client-s3` lazily and adapt it into an {@link S3ClientLike}
|
|
92
|
+
* bound to the B2 bucket/endpoint. The specifier is held in a variable so the
|
|
93
|
+
* static build never requires the optional peer dependency to be installed; it
|
|
94
|
+
* is resolved only at call time.
|
|
95
|
+
*/
|
|
96
|
+
async function buildBackblazeS3Client(config) {
|
|
97
|
+
// Lazy dynamic import — never a top-level import. An indirection variable keeps
|
|
98
|
+
// the specifier non-literal so the module is not required at build time.
|
|
99
|
+
const specifier = BACKBLAZE_SDK_SPECIFIER;
|
|
100
|
+
let sdk;
|
|
101
|
+
try {
|
|
102
|
+
sdk = (await import(specifier));
|
|
103
|
+
}
|
|
104
|
+
catch (cause) {
|
|
105
|
+
throw new StorageConfigError(`The Backblaze B2 driver requires the optional peer dependency "${BACKBLAZE_SDK_SPECIFIER}". ` +
|
|
106
|
+
`Install it, or pass a pre-constructed S3ClientLike to createBackblazeB2Driver().`, { provider: BACKBLAZE_DRIVER_NAME, cause });
|
|
107
|
+
}
|
|
108
|
+
const bucket = config.bucket;
|
|
109
|
+
const raw = new sdk.S3Client({
|
|
110
|
+
endpoint: config.endpoint,
|
|
111
|
+
region: config.region ?? "auto",
|
|
112
|
+
credentials: {
|
|
113
|
+
accessKeyId: config.credentials.accessKeyId,
|
|
114
|
+
secretAccessKey: config.credentials.secretAccessKey,
|
|
115
|
+
},
|
|
116
|
+
forcePathStyle: config.forcePathStyle ?? false,
|
|
117
|
+
});
|
|
118
|
+
const send = (command) => raw.send(command);
|
|
119
|
+
return {
|
|
120
|
+
async putObject(input) {
|
|
121
|
+
const result = await send(new sdk.PutObjectCommand({
|
|
122
|
+
Bucket: bucket,
|
|
123
|
+
Key: input.key,
|
|
124
|
+
Body: input.body,
|
|
125
|
+
ContentType: input.contentType,
|
|
126
|
+
Metadata: input.metadata,
|
|
127
|
+
}));
|
|
128
|
+
return { etag: normalizeEtag(result.ETag) };
|
|
129
|
+
},
|
|
130
|
+
async getObject({ key }) {
|
|
131
|
+
let result;
|
|
132
|
+
try {
|
|
133
|
+
result = await send(new sdk.GetObjectCommand({ Bucket: bucket, Key: key }));
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
if (isNotFound(error)) {
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
throw error;
|
|
140
|
+
}
|
|
141
|
+
const body = await collectBody(result.Body);
|
|
142
|
+
return {
|
|
143
|
+
body,
|
|
144
|
+
contentType: result.ContentType,
|
|
145
|
+
etag: normalizeEtag(result.ETag),
|
|
146
|
+
size: result.ContentLength ?? body.byteLength,
|
|
147
|
+
lastModified: toEpochMs(result.LastModified),
|
|
148
|
+
metadata: result.Metadata,
|
|
149
|
+
};
|
|
150
|
+
},
|
|
151
|
+
async headObject({ key }) {
|
|
152
|
+
let result;
|
|
153
|
+
try {
|
|
154
|
+
result = await send(new sdk.HeadObjectCommand({ Bucket: bucket, Key: key }));
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
if (isNotFound(error)) {
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
throw error;
|
|
161
|
+
}
|
|
162
|
+
return {
|
|
163
|
+
contentType: result.ContentType,
|
|
164
|
+
etag: normalizeEtag(result.ETag),
|
|
165
|
+
size: result.ContentLength,
|
|
166
|
+
lastModified: toEpochMs(result.LastModified),
|
|
167
|
+
metadata: result.Metadata,
|
|
168
|
+
};
|
|
169
|
+
},
|
|
170
|
+
async deleteObject({ key }) {
|
|
171
|
+
await send(new sdk.DeleteObjectCommand({ Bucket: bucket, Key: key }));
|
|
172
|
+
},
|
|
173
|
+
async listObjects({ prefix, limit, cursor, delimiter }) {
|
|
174
|
+
const result = await send(new sdk.ListObjectsV2Command({
|
|
175
|
+
Bucket: bucket,
|
|
176
|
+
Prefix: prefix,
|
|
177
|
+
MaxKeys: limit,
|
|
178
|
+
ContinuationToken: cursor,
|
|
179
|
+
Delimiter: delimiter === true ? "/" : undefined,
|
|
180
|
+
}));
|
|
181
|
+
const contents = result.Contents ?? [];
|
|
182
|
+
return contents.map((entry) => ({
|
|
183
|
+
key: entry.Key ?? "",
|
|
184
|
+
size: entry.Size ?? 0,
|
|
185
|
+
updatedAt: toEpochMs(entry.LastModified) ?? 0,
|
|
186
|
+
}));
|
|
187
|
+
},
|
|
188
|
+
async createMultipartUpload({ key, contentType, metadata }) {
|
|
189
|
+
const result = await send(new sdk.CreateMultipartUploadCommand({
|
|
190
|
+
Bucket: bucket,
|
|
191
|
+
Key: key,
|
|
192
|
+
ContentType: contentType,
|
|
193
|
+
Metadata: metadata,
|
|
194
|
+
}));
|
|
195
|
+
if (typeof result.UploadId !== "string") {
|
|
196
|
+
throw new StorageConfigError("Backblaze B2 did not return an upload id for the multipart upload.", {
|
|
197
|
+
provider: BACKBLAZE_DRIVER_NAME,
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
return { uploadId: result.UploadId };
|
|
201
|
+
},
|
|
202
|
+
async uploadPart({ key, uploadId, partNumber, body }) {
|
|
203
|
+
const result = await send(new sdk.UploadPartCommand({
|
|
204
|
+
Bucket: bucket,
|
|
205
|
+
Key: key,
|
|
206
|
+
UploadId: uploadId,
|
|
207
|
+
PartNumber: partNumber,
|
|
208
|
+
Body: body,
|
|
209
|
+
}));
|
|
210
|
+
return { etag: normalizeEtag(result.ETag) };
|
|
211
|
+
},
|
|
212
|
+
async completeMultipartUpload({ key, uploadId, parts }) {
|
|
213
|
+
const result = await send(new sdk.CompleteMultipartUploadCommand({
|
|
214
|
+
Bucket: bucket,
|
|
215
|
+
Key: key,
|
|
216
|
+
UploadId: uploadId,
|
|
217
|
+
MultipartUpload: {
|
|
218
|
+
Parts: parts.map((part) => ({ PartNumber: part.partNumber, ETag: part.etag })),
|
|
219
|
+
},
|
|
220
|
+
}));
|
|
221
|
+
return { etag: normalizeEtag(result.ETag) };
|
|
222
|
+
},
|
|
223
|
+
async abortMultipartUpload({ key, uploadId }) {
|
|
224
|
+
await send(new sdk.AbortMultipartUploadCommand({ Bucket: bucket, Key: key, UploadId: uploadId }));
|
|
225
|
+
},
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
// ── Adapter utilities ───────────────────────────────────────────────────────
|
|
229
|
+
/** Strip the surrounding quotes S3 wraps around ETags; tolerate an absent value. */
|
|
230
|
+
function normalizeEtag(etag) {
|
|
231
|
+
if (typeof etag !== "string") {
|
|
232
|
+
return "";
|
|
233
|
+
}
|
|
234
|
+
return etag.replace(/^"|"$/g, "");
|
|
235
|
+
}
|
|
236
|
+
/** Coerce an S3 `LastModified` (Date or epoch ms) into epoch ms, if present. */
|
|
237
|
+
function toEpochMs(value) {
|
|
238
|
+
if (value === undefined) {
|
|
239
|
+
return undefined;
|
|
240
|
+
}
|
|
241
|
+
return value instanceof Date ? value.getTime() : value;
|
|
242
|
+
}
|
|
243
|
+
/** `true` when an AWS SDK error represents a missing key (404 / NoSuchKey / NotFound). */
|
|
244
|
+
function isNotFound(error) {
|
|
245
|
+
if (typeof error !== "object" || error === null) {
|
|
246
|
+
return false;
|
|
247
|
+
}
|
|
248
|
+
const err = error;
|
|
249
|
+
if (err.name === "NoSuchKey" || err.name === "NotFound") {
|
|
250
|
+
return true;
|
|
251
|
+
}
|
|
252
|
+
return err.$metadata?.httpStatusCode === 404;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Collect an AWS SDK response body (a streaming blob) into a `Uint8Array`,
|
|
256
|
+
* supporting the SDK's `transformToByteArray()` helper as well as Node streams
|
|
257
|
+
* and already-buffered values.
|
|
258
|
+
*/
|
|
259
|
+
async function collectBody(body) {
|
|
260
|
+
if (body === undefined || body === null) {
|
|
261
|
+
return new Uint8Array(0);
|
|
262
|
+
}
|
|
263
|
+
const maybe = body;
|
|
264
|
+
if (typeof maybe.transformToByteArray === "function") {
|
|
265
|
+
return maybe.transformToByteArray();
|
|
266
|
+
}
|
|
267
|
+
if (body instanceof Uint8Array) {
|
|
268
|
+
return body;
|
|
269
|
+
}
|
|
270
|
+
if (typeof maybe[Symbol.asyncIterator] === "function") {
|
|
271
|
+
const chunks = [];
|
|
272
|
+
for await (const chunk of body) {
|
|
273
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
274
|
+
}
|
|
275
|
+
return new Uint8Array(Buffer.concat(chunks));
|
|
276
|
+
}
|
|
277
|
+
return new Uint8Array(Buffer.from(body));
|
|
278
|
+
}
|
|
279
|
+
//# sourceMappingURL=backblaze.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backblaze.js","sourceRoot":"","sources":["../../src/drivers/backblaze.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,EAAE,WAAW,EAAc,MAAM,UAAU,CAAC;AAGnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EACL,mBAAmB,EACnB,aAAa,GAQd,MAAM,cAAc,CAAC;AAEtB,qEAAqE;AACrE,MAAM,CAAC,MAAM,qBAAqB,GAAG,WAAW,CAAC;AAEjD,gFAAgF;AAChF,MAAM,uBAAuB,GAAG,oBAAoB,CAAC;AAsErD,MAAM,UAAU,uBAAuB,CACrC,cAA0D,EAC1D,UAAoC,EAAE;IAEtC,IAAI,cAAc,CAAC,cAAc,CAAC,EAAE,CAAC;QACnC,OAAO,WAAW,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,yBAAyB,CAAC,cAAc,CAAC,CAAC;AACnD,CAAC;AAED;;;;;GAKG;AACH,MAAM,OAAO,iBAAkB,SAAQ,aAAa;IAClD,YAAY,MAAoB,EAAE,UAAoC,EAAE;QACtE,KAAK,CAAC,MAAM,EAAE;YACZ,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,qBAAqB;YAC3C,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,WAAW;YACnC,YAAY,EAAE,OAAO,CAAC,YAAY;SACnC,CAAC,CAAC;IACL,CAAC;CACF;AAED,+EAA+E;AAE/E,8EAA8E;AAC9E,SAAS,WAAW,CAAC,MAAoB,EAAE,OAAiC;IAC1E,OAAO,mBAAmB,CAAC,MAAM,EAAE;QACjC,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,qBAAqB;QAC3C,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,WAAW;QACnC,YAAY,EAAE,OAAO,CAAC,YAAY;KACnC,CAAC,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,yBAAyB,CACtC,MAAmC;IAEnC,MAAM,MAAM,GAAG,MAAM,sBAAsB,CAAC,MAAM,CAAC,CAAC;IACpD,OAAO,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACrC,CAAC;AAED;;;GAGG;AACH,SAAS,cAAc,CAAC,KAAiD;IACvE,OAAO,OAAQ,KAA+B,CAAC,SAAS,KAAK,UAAU,CAAC;AAC1E,CAAC;AAED,mFAAmF;AAEnF;;;;;GAKG;AACH,KAAK,UAAU,sBAAsB,CACnC,MAAmC;IAEnC,gFAAgF;IAChF,yEAAyE;IACzE,MAAM,SAAS,GAAG,uBAAuB,CAAC;IAC1C,IAAI,GAAmB,CAAC;IACxB,IAAI,CAAC;QACH,GAAG,GAAG,CAAC,MAAM,MAAM,CAAC,SAAS,CAAC,CAAmB,CAAC;IACpD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,kBAAkB,CAC1B,kEAAkE,uBAAuB,KAAK;YAC5F,kFAAkF,EACpF,EAAE,QAAQ,EAAE,qBAAqB,EAAE,KAAK,EAAE,CAC3C,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAC7B,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC;QAC3B,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,MAAM;QAC/B,WAAW,EAAE;YACX,WAAW,EAAE,MAAM,CAAC,WAAW,CAAC,WAAW;YAC3C,eAAe,EAAE,MAAM,CAAC,WAAW,CAAC,eAAe;SACpD;QACD,cAAc,EAAE,MAAM,CAAC,cAAc,IAAI,KAAK;KAC/C,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,CAAC,OAAgB,EAAsB,EAAE,CACpD,GAAG,CAAC,IAAI,CAAC,OAAgB,CAAuB,CAAC;IAEnD,OAAO;QACL,KAAK,CAAC,SAAS,CAAC,KAAuB;YACrC,MAAM,MAAM,GAAG,MAAM,IAAI,CACvB,IAAI,GAAG,CAAC,gBAAgB,CAAC;gBACvB,MAAM,EAAE,MAAM;gBACd,GAAG,EAAE,KAAK,CAAC,GAAG;gBACd,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,WAAW,EAAE,KAAK,CAAC,WAAW;gBAC9B,QAAQ,EAAE,KAAK,CAAC,QAAQ;aACzB,CAAC,CACH,CAAC;YACF,OAAO,EAAE,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9C,CAAC;QAED,KAAK,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE;YACrB,IAAI,MAAiB,CAAC;YACtB,IAAI,CAAC;gBACH,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,GAAG,CAAC,gBAAgB,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;YAC9E,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;oBACtB,OAAO,IAAI,CAAC;gBACd,CAAC;gBACD,MAAM,KAAK,CAAC;YACd,CAAC;YACD,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC5C,OAAO;gBACL,IAAI;gBACJ,WAAW,EAAE,MAAM,CAAC,WAAW;gBAC/B,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC;gBAChC,IAAI,EAAE,MAAM,CAAC,aAAa,IAAI,IAAI,CAAC,UAAU;gBAC7C,YAAY,EAAE,SAAS,CAAC,MAAM,CAAC,YAAY,CAAC;gBAC5C,QAAQ,EAAE,MAAM,CAAC,QAAQ;aAC1B,CAAC;QACJ,CAAC;QAED,KAAK,CAAC,UAAU,CAAC,EAAE,GAAG,EAAE;YACtB,IAAI,MAAiB,CAAC;YACtB,IAAI,CAAC;gBACH,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,GAAG,CAAC,iBAAiB,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;YAC/E,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;oBACtB,OAAO,IAAI,CAAC;gBACd,CAAC;gBACD,MAAM,KAAK,CAAC;YACd,CAAC;YACD,OAAO;gBACL,WAAW,EAAE,MAAM,CAAC,WAAW;gBAC/B,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC;gBAChC,IAAI,EAAE,MAAM,CAAC,aAAa;gBAC1B,YAAY,EAAE,SAAS,CAAC,MAAM,CAAC,YAAY,CAAC;gBAC5C,QAAQ,EAAE,MAAM,CAAC,QAAQ;aAC1B,CAAC;QACJ,CAAC;QAED,KAAK,CAAC,YAAY,CAAC,EAAE,GAAG,EAAE;YACxB,MAAM,IAAI,CAAC,IAAI,GAAG,CAAC,mBAAmB,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;QACxE,CAAC;QAED,KAAK,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE;YACpD,MAAM,MAAM,GAAG,MAAM,IAAI,CACvB,IAAI,GAAG,CAAC,oBAAoB,CAAC;gBAC3B,MAAM,EAAE,MAAM;gBACd,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,KAAK;gBACd,iBAAiB,EAAE,MAAM;gBACzB,SAAS,EAAE,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS;aAChD,CAAC,CACH,CAAC;YACF,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC;YACvC,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAmB,EAAc,EAAE,CAAC,CAAC;gBACxD,GAAG,EAAE,KAAK,CAAC,GAAG,IAAI,EAAE;gBACpB,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC;gBACrB,SAAS,EAAE,SAAS,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC;aAC9C,CAAC,CAAC,CAAC;QACN,CAAC;QAED,KAAK,CAAC,qBAAqB,CAAC,EAAE,GAAG,EAAE,WAAW,EAAE,QAAQ,EAAE;YACxD,MAAM,MAAM,GAAG,MAAM,IAAI,CACvB,IAAI,GAAG,CAAC,4BAA4B,CAAC;gBACnC,MAAM,EAAE,MAAM;gBACd,GAAG,EAAE,GAAG;gBACR,WAAW,EAAE,WAAW;gBACxB,QAAQ,EAAE,QAAQ;aACnB,CAAC,CACH,CAAC;YACF,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBACxC,MAAM,IAAI,kBAAkB,CAAC,oEAAoE,EAAE;oBACjG,QAAQ,EAAE,qBAAqB;iBAChC,CAAC,CAAC;YACL,CAAC;YACD,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC;QACvC,CAAC;QAED,KAAK,CAAC,UAAU,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE;YAClD,MAAM,MAAM,GAAG,MAAM,IAAI,CACvB,IAAI,GAAG,CAAC,iBAAiB,CAAC;gBACxB,MAAM,EAAE,MAAM;gBACd,GAAG,EAAE,GAAG;gBACR,QAAQ,EAAE,QAAQ;gBAClB,UAAU,EAAE,UAAU;gBACtB,IAAI,EAAE,IAAI;aACX,CAAC,CACH,CAAC;YACF,OAAO,EAAE,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9C,CAAC;QAED,KAAK,CAAC,uBAAuB,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE;YACpD,MAAM,MAAM,GAAG,MAAM,IAAI,CACvB,IAAI,GAAG,CAAC,8BAA8B,CAAC;gBACrC,MAAM,EAAE,MAAM;gBACd,GAAG,EAAE,GAAG;gBACR,QAAQ,EAAE,QAAQ;gBAClB,eAAe,EAAE;oBACf,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;iBAC/E;aACF,CAAC,CACH,CAAC;YACF,OAAO,EAAE,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9C,CAAC;QAED,KAAK,CAAC,oBAAoB,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE;YAC1C,MAAM,IAAI,CACR,IAAI,GAAG,CAAC,2BAA2B,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CACtF,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC;AAyCD,+EAA+E;AAE/E,oFAAoF;AACpF,SAAS,aAAa,CAAC,IAAwB;IAC7C,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;AACpC,CAAC;AAED,gFAAgF;AAChF,SAAS,SAAS,CAAC,KAAgC;IACjD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,KAAK,YAAY,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;AACzD,CAAC;AAED,0FAA0F;AAC1F,SAAS,UAAU,CAAC,KAAc;IAChC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QAChD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,GAAG,GAAG,KAAqE,CAAC;IAClF,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,IAAI,GAAG,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QACxD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,GAAG,CAAC,SAAS,EAAE,cAAc,KAAK,GAAG,CAAC;AAC/C,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,WAAW,CAAC,IAAa;IACtC,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QACxC,OAAO,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;IAC3B,CAAC;IACD,MAAM,KAAK,GAAG,IAGb,CAAC;IACF,IAAI,OAAO,KAAK,CAAC,oBAAoB,KAAK,UAAU,EAAE,CAAC;QACrD,OAAO,KAAK,CAAC,oBAAoB,EAAE,CAAC;IACtC,CAAC;IACD,IAAI,IAAI,YAAY,UAAU,EAAE,CAAC;QAC/B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,OAAO,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,UAAU,EAAE,CAAC;QACtD,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,IAA8B,EAAE,CAAC;YACzD,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAmB,CAAC,CAAC,CAAC;QACjF,CAAC;QACD,OAAO,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IAC/C,CAAC;IACD,OAAO,IAAI,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,IAAkB,CAAC,CAAC,CAAC;AACzD,CAAC"}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @streetjs/storage — GoogleCloudStorageDriver (submodule `@streetjs/storage/gcs`).
|
|
3
|
+
*
|
|
4
|
+
* Google Cloud Storage is **not** an S3-wire-compatible provider — its SDK
|
|
5
|
+
* exposes a bucket/file object model (`bucket.file(name).save/download/delete/
|
|
6
|
+
* exists/getMetadata`, `bucket.getFiles({ prefix })`) rather than the
|
|
7
|
+
* `putObject`/`getObject` verbs the S3-style base is built on. So, unlike
|
|
8
|
+
* `r2.ts`/`minio.ts`/`backblaze.ts`, this driver does **not** extend the shared
|
|
9
|
+
* S3 base ({@link ../drivers/s3-base}); it maps the {@link StorageDriver}
|
|
10
|
+
* contract directly onto a purpose-built structural {@link GcsClientLike} that
|
|
11
|
+
* mirrors just the GCS calls it needs.
|
|
12
|
+
*
|
|
13
|
+
* ## Two ways to obtain a driver
|
|
14
|
+
*
|
|
15
|
+
* - {@link createGoogleCloudStorageDriver} wraps an **already-constructed,
|
|
16
|
+
* injected** {@link GcsClientLike} and returns a driver synchronously. This is
|
|
17
|
+
* the SDK-free path: no provider SDK is touched, so it is fully testable with
|
|
18
|
+
* an in-memory fake and needs no `@google-cloud/storage` install.
|
|
19
|
+
* - {@link connectGoogleCloudStorageDriver} **builds its own client** from GCS
|
|
20
|
+
* connection config. It resolves `@google-cloud/storage` through a **lazy
|
|
21
|
+
* dynamic `import()` performed inside the function** (never at module top
|
|
22
|
+
* level), so the optional peer dependency is only required when this path is
|
|
23
|
+
* actually used. If the SDK is not installed and no client was injected, it
|
|
24
|
+
* throws {@link StorageConfigError} (Requirement 1.5).
|
|
25
|
+
*
|
|
26
|
+
* ## Capability delegation (Requirement 2.3)
|
|
27
|
+
*
|
|
28
|
+
* The driver implements only the **mandatory primitives** (`put`/`get`/`exists`/
|
|
29
|
+
* `delete`/`stat`/`list`/`putStream`/`getStream`), producing every
|
|
30
|
+
* {@link StorageObjectMetadata} through the shared metadata layer
|
|
31
|
+
* ({@link buildObjectMetadata}) so the field set is identical to Memory/Local/S3,
|
|
32
|
+
* and reporting a missing key consistently ({@link MaybeObject} `{ found: false }`
|
|
33
|
+
* for `get`, `null` for `stat`, {@link NotFoundError} for `getStream`). Advanced
|
|
34
|
+
* capabilities (`multipart`/`resumable`/`versioning`/`signedUrl`/`lifecycle`) are
|
|
35
|
+
* intentionally left `undefined` so the facade simulates them over the
|
|
36
|
+
* primitives, keeping behavior identical across providers.
|
|
37
|
+
*
|
|
38
|
+
* ## SDK isolation (Requirements 2.1, 3.3)
|
|
39
|
+
*
|
|
40
|
+
* This module imports **no provider SDK at the top level** — only Node built-ins,
|
|
41
|
+
* `streetjs` (for the injected {@link Clock}), and this package's own type
|
|
42
|
+
* surface. `@google-cloud/storage` is referenced solely via a dynamic `import()`
|
|
43
|
+
* with a non-literal specifier inside {@link connectGoogleCloudStorageDriver}, so
|
|
44
|
+
* `tsc` never requires the SDK to be present and `streetjs` stays the only
|
|
45
|
+
* runtime dependency. This driver is a submodule-only export
|
|
46
|
+
* (`./gcs` → `dist/drivers/gcs.js`); it is intentionally not re-exported from the
|
|
47
|
+
* package's main `index.ts`.
|
|
48
|
+
*
|
|
49
|
+
* _Requirements: 2.1, 2.3, 3.3_
|
|
50
|
+
*/
|
|
51
|
+
import { type Clock } from "streetjs";
|
|
52
|
+
import type { MaybeObject, NodeReadable, StorageDriver } from "../driver.js";
|
|
53
|
+
import type { ListOptions, StorageListItem, StorageObjectMetadata, WriteMetadata } from "../types.js";
|
|
54
|
+
/**
|
|
55
|
+
* Object attributes as surfaced by the GCS object model (`file.getMetadata()` /
|
|
56
|
+
* entries from `bucket.getFiles`). Every field is optional and loosely typed
|
|
57
|
+
* because GCS returns `size` as a numeric string and timestamps as RFC-3339
|
|
58
|
+
* strings; the driver normalizes them. Caller-supplied user metadata lives under
|
|
59
|
+
* the nested {@link metadata} map (GCS's "custom metadata").
|
|
60
|
+
*/
|
|
61
|
+
export interface GcsObjectAttributes {
|
|
62
|
+
/** Byte length. GCS returns this as a numeric string; a number is tolerated. */
|
|
63
|
+
readonly size?: number | string;
|
|
64
|
+
/** Declared content type. */
|
|
65
|
+
readonly contentType?: string;
|
|
66
|
+
/** Entity tag. */
|
|
67
|
+
readonly etag?: string;
|
|
68
|
+
/** Base64 MD5 hash of the content, when present. */
|
|
69
|
+
readonly md5Hash?: string;
|
|
70
|
+
/** Creation time as an RFC-3339 / ISO-8601 string. */
|
|
71
|
+
readonly timeCreated?: string;
|
|
72
|
+
/** Last-updated time as an RFC-3339 / ISO-8601 string. */
|
|
73
|
+
readonly updated?: string;
|
|
74
|
+
/** Caller-supplied custom metadata (string→string), GCS's "metadata" map. */
|
|
75
|
+
readonly metadata?: Record<string, string>;
|
|
76
|
+
}
|
|
77
|
+
/** Options accepted by {@link GcsClientLike.save}. */
|
|
78
|
+
export interface GcsSaveOptions {
|
|
79
|
+
/** Content type to persist alongside the object. */
|
|
80
|
+
readonly contentType?: string;
|
|
81
|
+
/** Custom metadata (string→string) to persist as GCS object metadata. */
|
|
82
|
+
readonly metadata?: Record<string, string>;
|
|
83
|
+
}
|
|
84
|
+
/** Options accepted by {@link GcsClientLike.getFiles}. */
|
|
85
|
+
export interface GcsListInput {
|
|
86
|
+
/** Only list objects whose name begins with this prefix. */
|
|
87
|
+
readonly prefix: string;
|
|
88
|
+
/** When set, collapse results on this delimiter (GCS directory semantics). */
|
|
89
|
+
readonly delimiter?: string;
|
|
90
|
+
/** Best-effort maximum number of results the caller wants. */
|
|
91
|
+
readonly maxResults?: number;
|
|
92
|
+
}
|
|
93
|
+
/** A single object entry returned by {@link GcsClientLike.getFiles}. */
|
|
94
|
+
export interface GcsFileEntry {
|
|
95
|
+
/** The object name (full key). */
|
|
96
|
+
readonly name: string;
|
|
97
|
+
/** The entry's attributes, when the listing includes them. */
|
|
98
|
+
readonly attributes?: GcsObjectAttributes;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* The **minimal, GCS-shaped structural interface** this driver depends on.
|
|
102
|
+
*
|
|
103
|
+
* It is bucket-scoped (the concrete adapter binds a bucket) and describes just
|
|
104
|
+
* the object operations the driver needs — never any concrete
|
|
105
|
+
* `@google-cloud/storage` type — so the SDK stays an optional peer concern of the
|
|
106
|
+
* consumer (Requirement 3.1). `download`/`getMetadata` return `null` for a
|
|
107
|
+
* missing object so not-found maps to the contract's consistent semantics rather
|
|
108
|
+
* than a thrown error.
|
|
109
|
+
*/
|
|
110
|
+
export interface GcsClientLike {
|
|
111
|
+
/** Store `bytes` under `name` with optional content type and custom metadata. */
|
|
112
|
+
save(name: string, bytes: Uint8Array, options?: GcsSaveOptions): Promise<void>;
|
|
113
|
+
/** Download the object's bytes, or `null` when it does not exist. */
|
|
114
|
+
download(name: string): Promise<Uint8Array | null>;
|
|
115
|
+
/** Delete the object at `name` (a no-op when it is already absent). */
|
|
116
|
+
delete(name: string): Promise<void>;
|
|
117
|
+
/** Report whether an object exists at `name`. */
|
|
118
|
+
exists(name: string): Promise<boolean>;
|
|
119
|
+
/** Fetch the object's attributes, or `null` when it does not exist. */
|
|
120
|
+
getMetadata(name: string): Promise<GcsObjectAttributes | null>;
|
|
121
|
+
/** List objects whose name begins with `input.prefix`. */
|
|
122
|
+
getFiles(input: GcsListInput): Promise<readonly GcsFileEntry[]>;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Options for the GCS driver. The provider name is fixed to `"gcs"` and is not
|
|
126
|
+
* caller-configurable, so provider identity stays stable.
|
|
127
|
+
*/
|
|
128
|
+
export interface GoogleCloudStorageDriverOptions {
|
|
129
|
+
/** Injected clock for deterministic timestamps in tests. Default `systemClock`. */
|
|
130
|
+
readonly clock?: Clock;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Maps the {@link StorageDriver} contract onto an injected {@link GcsClientLike}.
|
|
134
|
+
*
|
|
135
|
+
* Object identity fields (`etag`/`checksum`/`size`) and timestamps are computed
|
|
136
|
+
* locally at write time — the checksum/etag are the sha-256 hex digest of the
|
|
137
|
+
* stored bytes, the size is the byte length, and timestamps come from the
|
|
138
|
+
* injected {@link Clock} — then encoded into the object's custom metadata so they
|
|
139
|
+
* round-trip on read. Advanced capabilities are left `undefined` for facade
|
|
140
|
+
* simulation.
|
|
141
|
+
*/
|
|
142
|
+
export declare class GoogleCloudStorageDriver implements StorageDriver {
|
|
143
|
+
/** Stable driver name. */
|
|
144
|
+
readonly name = "gcs";
|
|
145
|
+
private readonly client;
|
|
146
|
+
private readonly clock;
|
|
147
|
+
constructor(client: GcsClientLike, options?: GoogleCloudStorageDriverOptions);
|
|
148
|
+
/**
|
|
149
|
+
* Store `bytes` under `key`, computing size and sha-256 checksum locally and
|
|
150
|
+
* taking timestamps from the injected clock. When overwriting, the original
|
|
151
|
+
* `createdAt` is preserved (a preceding attribute read). The typed metadata is
|
|
152
|
+
* encoded into the object's custom-metadata map so it round-trips on read
|
|
153
|
+
* (Requirements 4.1, 10.1, 10.2).
|
|
154
|
+
*/
|
|
155
|
+
put(key: string, bytes: Uint8Array, metadata: WriteMetadata): Promise<StorageObjectMetadata>;
|
|
156
|
+
/**
|
|
157
|
+
* Read the object at `key`, returning a discriminated {@link MaybeObject} so
|
|
158
|
+
* absence is reported rather than thrown (Requirements 4.2, 2.4). Metadata is
|
|
159
|
+
* rebuilt from the object's attributes and encoded custom metadata via the
|
|
160
|
+
* shared metadata layer.
|
|
161
|
+
*/
|
|
162
|
+
get(key: string): Promise<MaybeObject>;
|
|
163
|
+
/** Report whether an object is stored under `key` (Requirement 4.3). */
|
|
164
|
+
exists(key: string): Promise<boolean>;
|
|
165
|
+
/** Delete the object at `key`; deleting a missing key is a no-op (Requirement 4.4). */
|
|
166
|
+
delete(key: string): Promise<void>;
|
|
167
|
+
/**
|
|
168
|
+
* Return the metadata for `key` without its content, or `null` when absent
|
|
169
|
+
* (Requirement 4.10).
|
|
170
|
+
*/
|
|
171
|
+
stat(key: string): Promise<StorageObjectMetadata | null>;
|
|
172
|
+
/**
|
|
173
|
+
* List objects whose key begins with `prefix`, sorted by key for deterministic
|
|
174
|
+
* ordering (Requirement 4.9). Honors optional `cursor` (exclusive resume
|
|
175
|
+
* point), `limit`, and `delimiter` (collapse to immediate children on `/`).
|
|
176
|
+
*/
|
|
177
|
+
list(prefix: string, options?: ListOptions): Promise<StorageListItem[]>;
|
|
178
|
+
/**
|
|
179
|
+
* Consume a Node {@link Readable} and persist the assembled bytes under `key`
|
|
180
|
+
* with the same computed metadata as {@link put} (Requirement 5.1). Chunks are
|
|
181
|
+
* drained through a `pipeline` (correct backpressure and error propagation),
|
|
182
|
+
* then handed to {@link put}.
|
|
183
|
+
*/
|
|
184
|
+
putStream(key: string, stream: NodeReadable, metadata: WriteMetadata): Promise<StorageObjectMetadata>;
|
|
185
|
+
/**
|
|
186
|
+
* Return a Node {@link Readable} of the stored bytes at `key` (Requirement
|
|
187
|
+
* 5.2). Throws {@link NotFoundError} for a missing key (Requirement 5.5).
|
|
188
|
+
*/
|
|
189
|
+
getStream(key: string): Promise<NodeReadable>;
|
|
190
|
+
/**
|
|
191
|
+
* Rebuild the typed {@link StorageObjectMetadata} field set from the object's
|
|
192
|
+
* attributes and the encoded custom-metadata map, applying the shared layer's
|
|
193
|
+
* canonical defaults. Provider-supplied values are used as best-effort
|
|
194
|
+
* fallbacks when the encoded fields are absent (e.g. an object written outside
|
|
195
|
+
* this driver): `etag`/`md5Hash`/`timeCreated`/`updated` back-fill the
|
|
196
|
+
* identity/timestamp fields, keeping the shape consistent across providers.
|
|
197
|
+
*/
|
|
198
|
+
private decodeMeta;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Wrap an injected {@link GcsClientLike} as a GCS driver. Synchronous and
|
|
202
|
+
* SDK-free: the caller supplies the client, so no provider SDK is resolved here.
|
|
203
|
+
*
|
|
204
|
+
* @throws {StorageConfigError} when no client is injected — use
|
|
205
|
+
* {@link connectGoogleCloudStorageDriver} to build a client from connection
|
|
206
|
+
* options instead.
|
|
207
|
+
*/
|
|
208
|
+
export declare function createGoogleCloudStorageDriver(client: GcsClientLike, options?: GoogleCloudStorageDriverOptions): StorageDriver;
|
|
209
|
+
/**
|
|
210
|
+
* Connection configuration for {@link connectGoogleCloudStorageDriver}. These are
|
|
211
|
+
* forwarded to the `@google-cloud/storage` `Storage` constructor (except
|
|
212
|
+
* `bucket`, which scopes the resulting client).
|
|
213
|
+
*/
|
|
214
|
+
export interface GoogleCloudStorageConfig extends GoogleCloudStorageDriverOptions {
|
|
215
|
+
/** The GCS bucket the driver operates within (required). */
|
|
216
|
+
readonly bucket: string;
|
|
217
|
+
/** GCP project id. */
|
|
218
|
+
readonly projectId?: string;
|
|
219
|
+
/** Path to a service-account key file. */
|
|
220
|
+
readonly keyFilename?: string;
|
|
221
|
+
/** Inline service-account credentials. */
|
|
222
|
+
readonly credentials?: Record<string, unknown>;
|
|
223
|
+
/** Custom API endpoint (e.g. a fake/emulator host). */
|
|
224
|
+
readonly apiEndpoint?: string;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Build a GCS driver that owns its client, resolving `@google-cloud/storage`
|
|
228
|
+
* lazily.
|
|
229
|
+
*
|
|
230
|
+
* The SDK is loaded through a dynamic `import()` with a non-literal specifier so
|
|
231
|
+
* it is never a static/top-level dependency: `tsc` does not require it to be
|
|
232
|
+
* installed, and it is only resolved when this function runs. When the SDK
|
|
233
|
+
* cannot be resolved, a {@link StorageConfigError} is thrown (Requirement 1.5) —
|
|
234
|
+
* callers that cannot install the SDK should use
|
|
235
|
+
* {@link createGoogleCloudStorageDriver} with their own {@link GcsClientLike}
|
|
236
|
+
* instead.
|
|
237
|
+
*/
|
|
238
|
+
export declare function connectGoogleCloudStorageDriver(config: GoogleCloudStorageConfig): Promise<StorageDriver>;
|
|
239
|
+
//# sourceMappingURL=gcs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gcs.d.ts","sourceRoot":"","sources":["../../src/drivers/gcs.ts"],"names":[],"mappings":"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"}
|