@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,436 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @streetjs/storage — the shared S3-style driver base and {@link S3ClientLike}.
|
|
3
|
+
*
|
|
4
|
+
* S3-compatible providers (Amazon S3, Cloudflare R2, MinIO, and the Backblaze B2
|
|
5
|
+
* S3 API) share one wire shape: a small set of object operations
|
|
6
|
+
* (`putObject`/`getObject`/`deleteObject`/`listObjects`) plus optional
|
|
7
|
+
* multipart and presign calls. This module captures that shape as the structural
|
|
8
|
+
* {@link S3ClientLike} interface and maps the {@link StorageDriver} contract onto
|
|
9
|
+
* it, so `s3.ts`, `r2.ts`, `minio.ts`, and `backblaze.ts` (tasks 28.2–28.5) only
|
|
10
|
+
* differ in how they build/configure the client, never in how the contract is
|
|
11
|
+
* satisfied.
|
|
12
|
+
*
|
|
13
|
+
* ## SDK isolation (Requirements 3.1, 3.3)
|
|
14
|
+
*
|
|
15
|
+
* This module imports **no provider SDK** at the top level — only Node built-ins,
|
|
16
|
+
* `streetjs` (for the injected {@link Clock}), and this package's own type
|
|
17
|
+
* surface. The base accepts an **injected** {@link S3ClientLike}; it never
|
|
18
|
+
* resolves an SDK itself. The concrete submodules that *can* construct their own
|
|
19
|
+
* client do so with a **lazy dynamic `import()`** performed inside that submodule
|
|
20
|
+
* at construction time, so the optional peer SDK is resolved only when that
|
|
21
|
+
* submodule is actually imported. `streetjs` therefore stays the only runtime
|
|
22
|
+
* dependency.
|
|
23
|
+
*
|
|
24
|
+
* ## Capability delegation (Requirement 2.3)
|
|
25
|
+
*
|
|
26
|
+
* The base implements the **mandatory primitives** (`put`/`get`/`exists`/
|
|
27
|
+
* `delete`/`stat`/`list`/`putStream`/`getStream`) by mapping onto
|
|
28
|
+
* {@link S3ClientLike}, producing every {@link StorageObjectMetadata} through the
|
|
29
|
+
* shared metadata layer ({@link buildObjectMetadata}) so the field set is
|
|
30
|
+
* identical to Memory/Local, and reporting a missing key consistently
|
|
31
|
+
* ({@link MaybeObject} `{ found: false }` for `get`, `null` for `stat`,
|
|
32
|
+
* {@link NotFoundError} for `getStream`).
|
|
33
|
+
*
|
|
34
|
+
* Advanced capabilities are **delegated to the client when available, otherwise
|
|
35
|
+
* left `undefined` so the facade simulates them over the primitives**
|
|
36
|
+
* (Requirement 2, keeping behavior identical across providers):
|
|
37
|
+
*
|
|
38
|
+
* - **Multipart** is wired only when the client exposes the full SDK-shaped
|
|
39
|
+
* multipart method set; the base adapts those calls into a
|
|
40
|
+
* {@link MultipartCapability}, tracking the `uploadId → key` mapping the S3 API
|
|
41
|
+
* requires.
|
|
42
|
+
* - **Versioning / lifecycle / signed URLs** are delegated only when a native
|
|
43
|
+
* capability object is supplied through `options.capabilities`; otherwise they
|
|
44
|
+
* are left `undefined`. (A provider's presigned URLs are verified by the
|
|
45
|
+
* provider, not locally, so the base does not synthesize a
|
|
46
|
+
* {@link SignedUrlCapability} from a bare `presignUrl` — the facade's HMAC
|
|
47
|
+
* simulation is used instead unless a full native capability is injected.)
|
|
48
|
+
*
|
|
49
|
+
* _Requirements: 2.3, 3.1, 3.3_
|
|
50
|
+
*/
|
|
51
|
+
import { createHash } from "node:crypto";
|
|
52
|
+
import { Readable, Writable } from "node:stream";
|
|
53
|
+
import { pipeline } from "node:stream/promises";
|
|
54
|
+
import { systemClock } from "streetjs";
|
|
55
|
+
import { NotFoundError } from "../errors.js";
|
|
56
|
+
import { buildObjectMetadata } from "../metadata.js";
|
|
57
|
+
// ── User-metadata encoding keys ───────────────────────────────────────────────
|
|
58
|
+
/**
|
|
59
|
+
* Reserved user-metadata keys used to round-trip the typed metadata field set
|
|
60
|
+
* through the provider's string→string user-metadata map. Prefixed so they never
|
|
61
|
+
* collide with a caller's own custom fields.
|
|
62
|
+
*/
|
|
63
|
+
const MK = {
|
|
64
|
+
checksum: "x-street-checksum",
|
|
65
|
+
createdAt: "x-street-created-at",
|
|
66
|
+
updatedAt: "x-street-updated-at",
|
|
67
|
+
owner: "x-street-owner",
|
|
68
|
+
tenant: "x-street-tenant",
|
|
69
|
+
accessLevel: "x-street-access-level",
|
|
70
|
+
custom: "x-street-custom",
|
|
71
|
+
};
|
|
72
|
+
// ── The S3-style base driver ──────────────────────────────────────────────────
|
|
73
|
+
/**
|
|
74
|
+
* Maps the {@link StorageDriver} contract onto an injected {@link S3ClientLike}.
|
|
75
|
+
*
|
|
76
|
+
* This class is provider-agnostic: every S3-compatible driver (S3, R2, MinIO,
|
|
77
|
+
* Backblaze) is this base with a differently-constructed client. It imports no
|
|
78
|
+
* provider SDK; the client is supplied by the caller (typically a submodule that
|
|
79
|
+
* lazily `import()`s its SDK).
|
|
80
|
+
*/
|
|
81
|
+
export class S3StyleDriver {
|
|
82
|
+
name;
|
|
83
|
+
client;
|
|
84
|
+
clock;
|
|
85
|
+
/** Tracks the `key` for each in-flight multipart `uploadId` (S3 needs both). */
|
|
86
|
+
multipartKeys = new Map();
|
|
87
|
+
// Optional capabilities — populated only when delegation is available.
|
|
88
|
+
multipart;
|
|
89
|
+
versioning;
|
|
90
|
+
signedUrl;
|
|
91
|
+
lifecycle;
|
|
92
|
+
constructor(client, options = {}) {
|
|
93
|
+
this.client = client;
|
|
94
|
+
this.name = options.name ?? "s3";
|
|
95
|
+
this.clock = options.clock ?? systemClock;
|
|
96
|
+
// Wire native multipart only when the client exposes the full method set;
|
|
97
|
+
// otherwise the facade simulates multipart over put/get.
|
|
98
|
+
if (typeof client.createMultipartUpload === "function" &&
|
|
99
|
+
typeof client.uploadPart === "function" &&
|
|
100
|
+
typeof client.completeMultipartUpload === "function" &&
|
|
101
|
+
typeof client.abortMultipartUpload === "function") {
|
|
102
|
+
this.multipart = this.buildMultipartCapability();
|
|
103
|
+
}
|
|
104
|
+
// Delegate versioning/lifecycle/signed URLs only when a native capability
|
|
105
|
+
// object is injected; otherwise leave undefined for facade simulation.
|
|
106
|
+
this.versioning = options.capabilities?.versioning;
|
|
107
|
+
this.lifecycle = options.capabilities?.lifecycle;
|
|
108
|
+
this.signedUrl = options.capabilities?.signedUrl;
|
|
109
|
+
}
|
|
110
|
+
// ── Mandatory primitives ──────────────────────────────────────────────────
|
|
111
|
+
/**
|
|
112
|
+
* Store `bytes` under `key`, computing size and sha-256 checksum locally and
|
|
113
|
+
* taking timestamps from the injected clock. When overwriting, the original
|
|
114
|
+
* `createdAt` is preserved (a preceding attribute read). The typed metadata is
|
|
115
|
+
* encoded into the provider's user-metadata map so it round-trips on read
|
|
116
|
+
* (Requirements 4.1, 10.1, 10.2).
|
|
117
|
+
*/
|
|
118
|
+
async put(key, bytes, metadata) {
|
|
119
|
+
const stored = bytes.slice();
|
|
120
|
+
const checksum = sha256Hex(stored);
|
|
121
|
+
const now = this.clock();
|
|
122
|
+
const existing = await this.readMeta(key);
|
|
123
|
+
const objectMetadata = buildObjectMetadata({
|
|
124
|
+
key,
|
|
125
|
+
size: stored.byteLength,
|
|
126
|
+
checksum,
|
|
127
|
+
createdAt: existing?.createdAt ?? now,
|
|
128
|
+
updatedAt: now,
|
|
129
|
+
write: metadata,
|
|
130
|
+
});
|
|
131
|
+
await this.client.putObject({
|
|
132
|
+
key,
|
|
133
|
+
body: stored,
|
|
134
|
+
contentType: objectMetadata.contentType,
|
|
135
|
+
metadata: encodeUserMetadata(objectMetadata),
|
|
136
|
+
});
|
|
137
|
+
return objectMetadata;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Read the object at `key`, returning a discriminated {@link MaybeObject} so
|
|
141
|
+
* absence is reported rather than thrown (Requirements 4.2, 2.4). Metadata is
|
|
142
|
+
* rebuilt from the provider attributes and encoded user metadata via the
|
|
143
|
+
* shared metadata layer.
|
|
144
|
+
*/
|
|
145
|
+
async get(key) {
|
|
146
|
+
const out = await this.client.getObject({ key });
|
|
147
|
+
if (out === null) {
|
|
148
|
+
return { found: false };
|
|
149
|
+
}
|
|
150
|
+
const bytes = out.body.slice();
|
|
151
|
+
const metadata = this.decodeMeta(key, {
|
|
152
|
+
contentType: out.contentType,
|
|
153
|
+
etag: out.etag,
|
|
154
|
+
size: bytes.byteLength,
|
|
155
|
+
lastModified: out.lastModified,
|
|
156
|
+
metadata: out.metadata,
|
|
157
|
+
});
|
|
158
|
+
return { found: true, bytes, metadata };
|
|
159
|
+
}
|
|
160
|
+
/** Report whether an object is stored under `key` (Requirement 4.3). */
|
|
161
|
+
async exists(key) {
|
|
162
|
+
if (typeof this.client.headObject === "function") {
|
|
163
|
+
const head = await this.client.headObject({ key });
|
|
164
|
+
return head !== null;
|
|
165
|
+
}
|
|
166
|
+
const out = await this.client.getObject({ key });
|
|
167
|
+
return out !== null;
|
|
168
|
+
}
|
|
169
|
+
/** Delete the object at `key`; deleting a missing key is a no-op (Requirement 4.4). */
|
|
170
|
+
async delete(key) {
|
|
171
|
+
await this.client.deleteObject({ key });
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Return the metadata for `key` without its content, or `null` when absent
|
|
175
|
+
* (Requirement 4.10). Uses `headObject` when available, else falls back to a
|
|
176
|
+
* body fetch.
|
|
177
|
+
*/
|
|
178
|
+
async stat(key) {
|
|
179
|
+
if (typeof this.client.headObject === "function") {
|
|
180
|
+
const head = await this.client.headObject({ key });
|
|
181
|
+
if (head === null) {
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
return this.decodeMeta(key, head);
|
|
185
|
+
}
|
|
186
|
+
const out = await this.client.getObject({ key });
|
|
187
|
+
if (out === null) {
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
return this.decodeMeta(key, {
|
|
191
|
+
contentType: out.contentType,
|
|
192
|
+
etag: out.etag,
|
|
193
|
+
size: out.size ?? out.body.byteLength,
|
|
194
|
+
lastModified: out.lastModified,
|
|
195
|
+
metadata: out.metadata,
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
/** List objects whose key begins with `prefix` (Requirement 4.9). */
|
|
199
|
+
async list(prefix, options) {
|
|
200
|
+
const items = await this.client.listObjects({
|
|
201
|
+
prefix,
|
|
202
|
+
limit: options?.limit,
|
|
203
|
+
cursor: options?.cursor,
|
|
204
|
+
delimiter: options?.delimiter,
|
|
205
|
+
});
|
|
206
|
+
return items.map((item) => ({
|
|
207
|
+
key: item.key,
|
|
208
|
+
size: item.size,
|
|
209
|
+
updatedAt: item.updatedAt,
|
|
210
|
+
}));
|
|
211
|
+
}
|
|
212
|
+
// ── Streaming ───────────────────────────────────────────────────────────────
|
|
213
|
+
/**
|
|
214
|
+
* Consume a Node {@link Readable} and persist the assembled bytes under `key`
|
|
215
|
+
* with the same computed metadata as {@link put} (Requirement 5.1). Chunks are
|
|
216
|
+
* drained through a `pipeline` (correct backpressure and error propagation),
|
|
217
|
+
* then handed to {@link put}.
|
|
218
|
+
*/
|
|
219
|
+
async putStream(key, stream, metadata) {
|
|
220
|
+
const chunks = [];
|
|
221
|
+
const collector = new Writable({
|
|
222
|
+
write(chunk, _encoding, callback) {
|
|
223
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
224
|
+
callback();
|
|
225
|
+
},
|
|
226
|
+
});
|
|
227
|
+
await pipeline(stream, collector);
|
|
228
|
+
return this.put(key, new Uint8Array(Buffer.concat(chunks)), metadata);
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Return a Node {@link Readable} of the stored bytes at `key` (Requirement
|
|
232
|
+
* 5.2). Throws {@link NotFoundError} for a missing key (Requirement 5.5).
|
|
233
|
+
*/
|
|
234
|
+
async getStream(key) {
|
|
235
|
+
const out = await this.client.getObject({ key });
|
|
236
|
+
if (out === null) {
|
|
237
|
+
throw new NotFoundError(key);
|
|
238
|
+
}
|
|
239
|
+
return Readable.from([Buffer.from(out.body)]);
|
|
240
|
+
}
|
|
241
|
+
// ── Internal helpers ──────────────────────────────────────────────────────
|
|
242
|
+
/**
|
|
243
|
+
* Best-effort read of an object's existing metadata (used to preserve
|
|
244
|
+
* `createdAt` on overwrite). Returns `null` when the object does not exist.
|
|
245
|
+
*/
|
|
246
|
+
async readMeta(key) {
|
|
247
|
+
return this.stat(key);
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Rebuild the typed {@link StorageObjectMetadata} field set from provider
|
|
251
|
+
* attributes and the encoded user-metadata map, applying the shared layer's
|
|
252
|
+
* canonical defaults. Provider-supplied values are used as best-effort
|
|
253
|
+
* fallbacks when the encoded fields are absent (e.g. an object written outside
|
|
254
|
+
* this base): `etag`/`size`/`lastModified` back-fill the identity/timestamp
|
|
255
|
+
* fields, keeping the shape consistent across providers.
|
|
256
|
+
*/
|
|
257
|
+
decodeMeta(key, out) {
|
|
258
|
+
const um = out.metadata ?? {};
|
|
259
|
+
const now = this.clock();
|
|
260
|
+
const checksum = um[MK.checksum] ?? out.etag ?? "";
|
|
261
|
+
const createdAt = parseEpoch(um[MK.createdAt]) ?? out.lastModified ?? now;
|
|
262
|
+
const updatedAt = parseEpoch(um[MK.updatedAt]) ?? out.lastModified ?? createdAt;
|
|
263
|
+
const write = {
|
|
264
|
+
contentType: out.contentType,
|
|
265
|
+
owner: um[MK.owner],
|
|
266
|
+
tenant: um[MK.tenant],
|
|
267
|
+
accessLevel: decodeAccessLevel(um[MK.accessLevel]),
|
|
268
|
+
custom: parseCustom(um[MK.custom]),
|
|
269
|
+
};
|
|
270
|
+
return buildObjectMetadata({
|
|
271
|
+
key,
|
|
272
|
+
size: out.size ?? 0,
|
|
273
|
+
checksum,
|
|
274
|
+
etag: out.etag ?? checksum,
|
|
275
|
+
createdAt,
|
|
276
|
+
updatedAt,
|
|
277
|
+
write,
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Adapt the client's SDK-shaped multipart calls into a
|
|
282
|
+
* {@link MultipartCapability}. The S3 API requires the object key on every
|
|
283
|
+
* part/complete/abort call, so the `uploadId → key` mapping is tracked here.
|
|
284
|
+
*/
|
|
285
|
+
buildMultipartCapability() {
|
|
286
|
+
const client = this.client;
|
|
287
|
+
const clock = this.clock;
|
|
288
|
+
const keys = this.multipartKeys;
|
|
289
|
+
const readMeta = (key) => this.stat(key);
|
|
290
|
+
const requireKey = (uploadId) => {
|
|
291
|
+
const key = keys.get(uploadId);
|
|
292
|
+
if (key === undefined) {
|
|
293
|
+
throw new NotFoundError(uploadId, `Unknown multipart upload "${uploadId}"`);
|
|
294
|
+
}
|
|
295
|
+
return key;
|
|
296
|
+
};
|
|
297
|
+
return {
|
|
298
|
+
async create(key, metadata) {
|
|
299
|
+
const now = clock();
|
|
300
|
+
const { uploadId } = await client.createMultipartUpload({
|
|
301
|
+
key,
|
|
302
|
+
contentType: metadata.contentType,
|
|
303
|
+
metadata: encodeWriteMetadata(metadata, now),
|
|
304
|
+
});
|
|
305
|
+
keys.set(uploadId, key);
|
|
306
|
+
return uploadId;
|
|
307
|
+
},
|
|
308
|
+
async uploadPart(uploadId, partNumber, bytes) {
|
|
309
|
+
const key = requireKey(uploadId);
|
|
310
|
+
const { etag } = await client.uploadPart({ key, uploadId, partNumber, body: bytes });
|
|
311
|
+
return { partNumber, etag, size: bytes.byteLength };
|
|
312
|
+
},
|
|
313
|
+
async complete(uploadId, parts) {
|
|
314
|
+
const key = requireKey(uploadId);
|
|
315
|
+
await client.completeMultipartUpload({
|
|
316
|
+
key,
|
|
317
|
+
uploadId,
|
|
318
|
+
parts: parts.map((part) => ({ partNumber: part.partNumber, etag: part.etag })),
|
|
319
|
+
});
|
|
320
|
+
keys.delete(uploadId);
|
|
321
|
+
const metadata = await readMeta(key);
|
|
322
|
+
if (metadata !== null) {
|
|
323
|
+
return metadata;
|
|
324
|
+
}
|
|
325
|
+
// The object should exist after completion; fall back to a minimal,
|
|
326
|
+
// shaped record if the provider cannot immediately describe it.
|
|
327
|
+
const now = clock();
|
|
328
|
+
const size = parts.reduce((total, part) => total + part.size, 0);
|
|
329
|
+
return buildObjectMetadata({
|
|
330
|
+
key,
|
|
331
|
+
size,
|
|
332
|
+
checksum: "",
|
|
333
|
+
createdAt: now,
|
|
334
|
+
updatedAt: now,
|
|
335
|
+
write: {},
|
|
336
|
+
});
|
|
337
|
+
},
|
|
338
|
+
async abort(uploadId) {
|
|
339
|
+
const key = requireKey(uploadId);
|
|
340
|
+
await client.abortMultipartUpload({ key, uploadId });
|
|
341
|
+
keys.delete(uploadId);
|
|
342
|
+
},
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Construct an S3-style {@link StorageDriver} over an injected
|
|
348
|
+
* {@link S3ClientLike}. This is the entry point consumed by the concrete
|
|
349
|
+
* provider submodules (`s3.ts`/`r2.ts`/`minio.ts`/`backblaze.ts`), each of which
|
|
350
|
+
* supplies a differently-constructed client.
|
|
351
|
+
*/
|
|
352
|
+
export function createS3StyleDriver(client, options) {
|
|
353
|
+
return new S3StyleDriver(client, options);
|
|
354
|
+
}
|
|
355
|
+
// ── Module-private encoding helpers ────────────────────────────────────────────
|
|
356
|
+
/** Compute the lowercase sha-256 hex digest of `bytes`. */
|
|
357
|
+
function sha256Hex(bytes) {
|
|
358
|
+
return createHash("sha256").update(bytes).digest("hex");
|
|
359
|
+
}
|
|
360
|
+
/** Encode a built object's typed metadata into the provider user-metadata map. */
|
|
361
|
+
function encodeUserMetadata(metadata) {
|
|
362
|
+
const map = {
|
|
363
|
+
[MK.checksum]: metadata.checksum,
|
|
364
|
+
[MK.createdAt]: String(metadata.createdAt),
|
|
365
|
+
[MK.updatedAt]: String(metadata.updatedAt),
|
|
366
|
+
[MK.accessLevel]: metadata.accessLevel,
|
|
367
|
+
[MK.custom]: JSON.stringify(metadata.custom ?? {}),
|
|
368
|
+
};
|
|
369
|
+
if (metadata.owner !== undefined) {
|
|
370
|
+
map[MK.owner] = metadata.owner;
|
|
371
|
+
}
|
|
372
|
+
if (metadata.tenant !== undefined) {
|
|
373
|
+
map[MK.tenant] = metadata.tenant;
|
|
374
|
+
}
|
|
375
|
+
return map;
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* Encode write-time metadata (plus timestamps) into a user-metadata map for a
|
|
379
|
+
* multipart create, so the assembled object round-trips its typed fields.
|
|
380
|
+
*/
|
|
381
|
+
function encodeWriteMetadata(metadata, now) {
|
|
382
|
+
const map = {
|
|
383
|
+
[MK.createdAt]: String(now),
|
|
384
|
+
[MK.updatedAt]: String(now),
|
|
385
|
+
[MK.accessLevel]: metadata.accessLevel ?? "private",
|
|
386
|
+
[MK.custom]: JSON.stringify(metadata.custom ?? {}),
|
|
387
|
+
};
|
|
388
|
+
if (metadata.owner !== undefined) {
|
|
389
|
+
map[MK.owner] = metadata.owner;
|
|
390
|
+
}
|
|
391
|
+
if (metadata.tenant !== undefined) {
|
|
392
|
+
map[MK.tenant] = metadata.tenant;
|
|
393
|
+
}
|
|
394
|
+
return map;
|
|
395
|
+
}
|
|
396
|
+
/** Parse an epoch-ms string, returning `undefined` when absent or non-numeric. */
|
|
397
|
+
function parseEpoch(value) {
|
|
398
|
+
if (value === undefined) {
|
|
399
|
+
return undefined;
|
|
400
|
+
}
|
|
401
|
+
const parsed = Number(value);
|
|
402
|
+
return Number.isFinite(parsed) ? parsed : undefined;
|
|
403
|
+
}
|
|
404
|
+
/** Parse the encoded custom-field JSON, tolerating malformed values. */
|
|
405
|
+
function parseCustom(value) {
|
|
406
|
+
if (value === undefined) {
|
|
407
|
+
return {};
|
|
408
|
+
}
|
|
409
|
+
try {
|
|
410
|
+
const parsed = JSON.parse(value);
|
|
411
|
+
if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
412
|
+
return parsed;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
catch {
|
|
416
|
+
// Fall through to the empty default on malformed JSON.
|
|
417
|
+
}
|
|
418
|
+
return {};
|
|
419
|
+
}
|
|
420
|
+
/** The recognized access levels, used to validate the decoded value. */
|
|
421
|
+
const ACCESS_LEVELS = [
|
|
422
|
+
"public",
|
|
423
|
+
"private",
|
|
424
|
+
"signed",
|
|
425
|
+
"authenticated",
|
|
426
|
+
"role-based",
|
|
427
|
+
"tenant-aware",
|
|
428
|
+
];
|
|
429
|
+
/** Decode an access-level string, returning `undefined` for an unknown value. */
|
|
430
|
+
function decodeAccessLevel(value) {
|
|
431
|
+
if (value !== undefined && ACCESS_LEVELS.includes(value)) {
|
|
432
|
+
return value;
|
|
433
|
+
}
|
|
434
|
+
return undefined;
|
|
435
|
+
}
|
|
436
|
+
//# sourceMappingURL=s3-base.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"s3-base.js","sourceRoot":"","sources":["../../src/drivers/s3-base.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @streetjs/storage — {@link S3StorageDriver} (Amazon S3), submodule `./s3`.
|
|
3
|
+
*
|
|
4
|
+
* This module is the concrete Amazon S3 provider driver, exposed only through
|
|
5
|
+
* the optional subpath export `@streetjs/storage/s3` (Requirement 3.3). It is
|
|
6
|
+
* **not** re-exported from the package entry point `src/index.ts`, so importing
|
|
7
|
+
* the base package never pulls in this file or any AWS SDK.
|
|
8
|
+
*
|
|
9
|
+
* ## What this module adds over the base
|
|
10
|
+
*
|
|
11
|
+
* The entire {@link StorageDriver} contract mapping already lives in the shared
|
|
12
|
+
* {@link createS3StyleDriver} / {@link S3StyleDriver} base (task 28.1) built over
|
|
13
|
+
* the structural {@link S3ClientLike}. Amazon S3, Cloudflare R2, MinIO and the
|
|
14
|
+
* Backblaze B2 S3 API differ only in **how the client is built/configured**, not
|
|
15
|
+
* in how the contract is satisfied — so this module contributes only:
|
|
16
|
+
*
|
|
17
|
+
* 1. {@link createS3StorageDriver} — wrap an **injected** {@link S3ClientLike}
|
|
18
|
+
* (the preferred, SDK-free path) as a `name: "s3"` driver by delegating to the
|
|
19
|
+
* base. No AWS SDK is loaded on this path.
|
|
20
|
+
* 2. {@link createS3StorageDriverFromConfig} — construct an {@link S3ClientLike}
|
|
21
|
+
* from `bucket`/`region`/`endpoint`/`credentials` using a **lazy dynamic
|
|
22
|
+
* `import()`** of the AWS SDK performed *inside* the function. The SDK is
|
|
23
|
+
* therefore resolved only when this construction path actually runs, never at
|
|
24
|
+
* module load, keeping the AWS SDK an optional peer concern of the consumer
|
|
25
|
+
* (Requirement 3.1). If the SDK cannot be loaded and no client was injected, a
|
|
26
|
+
* descriptive {@link StorageConfigError} is thrown.
|
|
27
|
+
*
|
|
28
|
+
* ## SDK isolation (Requirements 2.1, 3.3)
|
|
29
|
+
*
|
|
30
|
+
* There is **no top-level `import` of any AWS SDK** in this file — only `streetjs`
|
|
31
|
+
* (for {@link Clock}), this package's own type surface, and the shared base. The
|
|
32
|
+
* `@aws-sdk/client-s3` / `@aws-sdk/s3-request-presigner` packages are declared as
|
|
33
|
+
* **optional peer dependencies** in `package.json`; they are pulled in only by
|
|
34
|
+
* the lazy `import()` inside {@link createS3StorageDriverFromConfig}. The dynamic
|
|
35
|
+
* specifier is held in a variable so the build never statically requires the SDK
|
|
36
|
+
* to be installed.
|
|
37
|
+
*
|
|
38
|
+
* _Requirements: 2.1, 2.3, 3.3_
|
|
39
|
+
*/
|
|
40
|
+
import { type Clock } from "streetjs";
|
|
41
|
+
import type { StorageDriver } from "../driver.js";
|
|
42
|
+
import { type S3ClientLike, type S3NativeCapabilities } from "./s3-base.js";
|
|
43
|
+
/**
|
|
44
|
+
* Options accepted by {@link createS3StorageDriver} and, alongside the
|
|
45
|
+
* connection fields, by {@link createS3StorageDriverFromConfig}.
|
|
46
|
+
*
|
|
47
|
+
* The driver `name` is always `"s3"` and is intentionally not configurable here
|
|
48
|
+
* (use the shared base directly if a different name is required).
|
|
49
|
+
*/
|
|
50
|
+
export interface S3StorageDriverOptions {
|
|
51
|
+
/** Injected clock for deterministic timestamps in tests. Default `systemClock`. */
|
|
52
|
+
readonly clock?: Clock;
|
|
53
|
+
/**
|
|
54
|
+
* Native capability objects to delegate to (versioning / lifecycle / signed
|
|
55
|
+
* URLs). Any capability omitted here is left `undefined` so the facade
|
|
56
|
+
* simulates it over the primitives, keeping behavior identical across
|
|
57
|
+
* providers (Requirement 2.3).
|
|
58
|
+
*/
|
|
59
|
+
readonly capabilities?: S3NativeCapabilities;
|
|
60
|
+
}
|
|
61
|
+
/** AWS credentials used when constructing a client from configuration. */
|
|
62
|
+
export interface S3Credentials {
|
|
63
|
+
readonly accessKeyId: string;
|
|
64
|
+
readonly secretAccessKey: string;
|
|
65
|
+
readonly sessionToken?: string;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Connection configuration for {@link createS3StorageDriverFromConfig}. A
|
|
69
|
+
* pre-constructed {@link S3ClientLike} may be supplied via `client` to bypass SDK
|
|
70
|
+
* construction entirely (the preferred, SDK-free path).
|
|
71
|
+
*/
|
|
72
|
+
export interface S3StorageDriverConfig extends S3StorageDriverOptions {
|
|
73
|
+
/** The S3 bucket every operation targets. Required when constructing a client. */
|
|
74
|
+
readonly bucket: string;
|
|
75
|
+
/** AWS region (e.g. `"us-east-1"`). */
|
|
76
|
+
readonly region?: string;
|
|
77
|
+
/** Custom endpoint (for S3-compatible gateways). */
|
|
78
|
+
readonly endpoint?: string;
|
|
79
|
+
/** Static credentials; when omitted the SDK's default credential chain is used. */
|
|
80
|
+
readonly credentials?: S3Credentials;
|
|
81
|
+
/** Force path-style addressing (needed by some S3-compatible endpoints). */
|
|
82
|
+
readonly forcePathStyle?: boolean;
|
|
83
|
+
/**
|
|
84
|
+
* A pre-constructed structural client. When provided, no AWS SDK is loaded and
|
|
85
|
+
* this client is wrapped directly.
|
|
86
|
+
*/
|
|
87
|
+
readonly client?: S3ClientLike;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Wrap an **injected** {@link S3ClientLike} as an Amazon S3 {@link StorageDriver}
|
|
91
|
+
* (`name: "s3"`). This is the preferred path: no AWS SDK is required because the
|
|
92
|
+
* caller supplies the structural client, and the whole {@link StorageDriver}
|
|
93
|
+
* contract is satisfied by the shared base (Requirement 2.3).
|
|
94
|
+
*
|
|
95
|
+
* @throws {StorageConfigError} when `client` is missing or does not implement the
|
|
96
|
+
* mandatory {@link S3ClientLike} object operations. To build a client from
|
|
97
|
+
* credentials instead, use {@link createS3StorageDriverFromConfig}.
|
|
98
|
+
*/
|
|
99
|
+
export declare function createS3StorageDriver(client: S3ClientLike, options?: S3StorageDriverOptions): StorageDriver;
|
|
100
|
+
/**
|
|
101
|
+
* Construct an Amazon S3 {@link StorageDriver} from connection configuration.
|
|
102
|
+
*
|
|
103
|
+
* When `config.client` is supplied it is wrapped directly (no SDK is loaded).
|
|
104
|
+
* Otherwise this **lazily `import()`s** `@aws-sdk/client-s3` and builds a client
|
|
105
|
+
* over the SDK — the SDK is resolved only here, at construction time, never at
|
|
106
|
+
* module load. If the SDK cannot be loaded, a descriptive {@link StorageConfigError}
|
|
107
|
+
* is thrown so a missing optional peer dependency surfaces clearly rather than as
|
|
108
|
+
* an opaque module-resolution failure (Requirements 2.1, 3.3).
|
|
109
|
+
*/
|
|
110
|
+
export declare function createS3StorageDriverFromConfig(config: S3StorageDriverConfig): Promise<StorageDriver>;
|
|
111
|
+
//# sourceMappingURL=s3.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"s3.d.ts","sourceRoot":"","sources":["../../src/drivers/s3.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,UAAU,CAAC;AAEtC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,EAEL,KAAK,YAAY,EAEjB,KAAK,oBAAoB,EAC1B,MAAM,cAAc,CAAC;AAOtB;;;;;;GAMG;AACH,MAAM,WAAW,sBAAsB;IACrC,mFAAmF;IACnF,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;IACvB;;;;;OAKG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,oBAAoB,CAAC;CAC9C;AAED,0EAA0E;AAC1E,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAChC;AAED;;;;GAIG;AACH,MAAM,WAAW,qBAAsB,SAAQ,sBAAsB;IACnE,kFAAkF;IAClF,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,uCAAuC;IACvC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,oDAAoD;IACpD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,mFAAmF;IACnF,QAAQ,CAAC,WAAW,CAAC,EAAE,aAAa,CAAC;IACrC,4EAA4E;IAC5E,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAClC;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC;CAChC;AAID;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,YAAY,EACpB,OAAO,GAAE,sBAA2B,GACnC,aAAa,CAef;AAED;;;;;;;;;GASG;AACH,wBAAsB,+BAA+B,CACnD,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,aAAa,CAAC,CAUxB"}
|