@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,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @streetjs/storage — the Directory API over a flat key space (task 17.1).
|
|
3
|
+
*
|
|
4
|
+
* Object stores have a flat key space with no real directories. This module
|
|
5
|
+
* implements a directory-style API entirely over that flat key space using
|
|
6
|
+
* `/`-delimited prefixes, so the same code runs unchanged on every
|
|
7
|
+
* {@link StorageDriver} — including prefix-only cloud providers (Requirement
|
|
8
|
+
* 15.5). The facade exposes the constructed instance as `storage.directory`.
|
|
9
|
+
*
|
|
10
|
+
* The four operations map onto driver primitives (`list`/`put`/`delete`) as
|
|
11
|
+
* follows:
|
|
12
|
+
*
|
|
13
|
+
* - `mkdir(path)` records an empty marker key `path/`, making the path
|
|
14
|
+
* available as a directory prefix (Requirement 15.1). A root/empty path needs
|
|
15
|
+
* no marker and is a no-op.
|
|
16
|
+
* - `listDirectory(path)` calls `driver.list(path/)` and collapses the results
|
|
17
|
+
* to the **immediate** children by splitting each key on the next `/` after
|
|
18
|
+
* the prefix: keys with no further `/` are file entries, keys with a further
|
|
19
|
+
* `/` contribute a single synthesized sub-directory entry (Requirement 15.2).
|
|
20
|
+
* - `removeDirectory(path)` deletes every key under the prefix; when the prefix
|
|
21
|
+
* contains no objects it is a success no-op that removes nothing
|
|
22
|
+
* (Requirements 15.3, 15.6).
|
|
23
|
+
* - `walk(path)` returns every object key strictly beneath the prefix
|
|
24
|
+
* (Requirement 15.4).
|
|
25
|
+
*
|
|
26
|
+
* The public {@link DirectoryApi} type is owned by `facade.ts` (and re-exported
|
|
27
|
+
* from `index.ts`); it is imported here type-only so there is no runtime import
|
|
28
|
+
* cycle between the two modules.
|
|
29
|
+
*
|
|
30
|
+
* _Requirements: 15.1, 15.2, 15.3, 15.4, 15.5, 15.6_
|
|
31
|
+
*/
|
|
32
|
+
/** The directory delimiter used to derive prefixes from paths. */
|
|
33
|
+
const DELIMITER = "/";
|
|
34
|
+
/**
|
|
35
|
+
* A {@link DirectoryApi} implementation over any {@link StorageDriver}'s flat
|
|
36
|
+
* key space. It holds only the driver and derives every directory operation
|
|
37
|
+
* from `/`-delimited prefixes, so it behaves identically across providers.
|
|
38
|
+
*/
|
|
39
|
+
export class StorageDirectoryApi {
|
|
40
|
+
driver;
|
|
41
|
+
constructor(driver) {
|
|
42
|
+
this.driver = driver;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Normalize a directory `path` to a prefix ending in the delimiter. The root
|
|
46
|
+
* (`""` or `"/"`) normalizes to the empty prefix (which matches every key),
|
|
47
|
+
* and any leading delimiter is dropped so `"/photos"` and `"photos"` refer to
|
|
48
|
+
* the same directory. A path that already ends with the delimiter is left
|
|
49
|
+
* unchanged.
|
|
50
|
+
*/
|
|
51
|
+
toPrefix(path) {
|
|
52
|
+
let p = path;
|
|
53
|
+
while (p.startsWith(DELIMITER)) {
|
|
54
|
+
p = p.slice(DELIMITER.length);
|
|
55
|
+
}
|
|
56
|
+
if (p === "") {
|
|
57
|
+
return "";
|
|
58
|
+
}
|
|
59
|
+
return p.endsWith(DELIMITER) ? p : p + DELIMITER;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* List the keys stored under `prefix`, defensively re-filtering by the prefix
|
|
63
|
+
* so drivers that interpret `list` loosely never leak keys from outside the
|
|
64
|
+
* directory into a directory operation.
|
|
65
|
+
*/
|
|
66
|
+
async keysUnder(prefix) {
|
|
67
|
+
const items = await this.driver.list(prefix);
|
|
68
|
+
if (prefix === "") {
|
|
69
|
+
return items;
|
|
70
|
+
}
|
|
71
|
+
return items.filter((item) => item.key.startsWith(prefix));
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Make `path` available as a directory prefix by recording an empty marker
|
|
75
|
+
* key `path/` (Requirement 15.1). The root/empty path requires no marker and
|
|
76
|
+
* is a no-op.
|
|
77
|
+
*/
|
|
78
|
+
async mkdir(path) {
|
|
79
|
+
const prefix = this.toPrefix(path);
|
|
80
|
+
if (prefix === "") {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
await this.driver.put(prefix, new Uint8Array(0), {});
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Return the immediate child entries under `path` (Requirement 15.2). Each
|
|
87
|
+
* key under the prefix is split on the next delimiter: a key with no further
|
|
88
|
+
* delimiter is returned as its file entry; keys sharing a further path
|
|
89
|
+
* segment collapse into a single synthesized sub-directory entry (key
|
|
90
|
+
* `path/child/`, `size` 0). The directory's own marker (a key equal to the
|
|
91
|
+
* prefix) is not reported as a child.
|
|
92
|
+
*/
|
|
93
|
+
async listDirectory(path) {
|
|
94
|
+
const prefix = this.toPrefix(path);
|
|
95
|
+
const items = await this.keysUnder(prefix);
|
|
96
|
+
const files = [];
|
|
97
|
+
const directories = new Map();
|
|
98
|
+
for (const item of items) {
|
|
99
|
+
const remainder = item.key.slice(prefix.length);
|
|
100
|
+
if (remainder === "") {
|
|
101
|
+
// The directory's own marker key — not one of its children.
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
const slash = remainder.indexOf(DELIMITER);
|
|
105
|
+
if (slash === -1) {
|
|
106
|
+
// Immediate file child.
|
|
107
|
+
files.push(item);
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
// Immediate sub-directory child: collapse everything sharing this segment
|
|
111
|
+
// into a single directory entry, tracking the most recent update time.
|
|
112
|
+
const dirKey = prefix + remainder.slice(0, slash) + DELIMITER;
|
|
113
|
+
const existing = directories.get(dirKey);
|
|
114
|
+
if (existing === undefined || item.updatedAt > existing.updatedAt) {
|
|
115
|
+
directories.set(dirKey, { key: dirKey, size: 0, updatedAt: item.updatedAt });
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return [...directories.values(), ...files];
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Remove every object stored under `path` (Requirement 15.3). When the prefix
|
|
122
|
+
* contains no objects — because the directory does not exist or is already
|
|
123
|
+
* empty — nothing is removed and a success result of `{ removed: false }` is
|
|
124
|
+
* returned without throwing (Requirement 15.6). When at least one object is
|
|
125
|
+
* removed the result is `{ removed: true }`.
|
|
126
|
+
*/
|
|
127
|
+
async removeDirectory(path) {
|
|
128
|
+
const prefix = this.toPrefix(path);
|
|
129
|
+
const items = await this.keysUnder(prefix);
|
|
130
|
+
if (items.length === 0) {
|
|
131
|
+
return { removed: false };
|
|
132
|
+
}
|
|
133
|
+
for (const item of items) {
|
|
134
|
+
await this.driver.delete(item.key);
|
|
135
|
+
}
|
|
136
|
+
return { removed: true };
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Return every object key strictly beneath `path` (Requirement 15.4),
|
|
140
|
+
* excluding the directory's own marker key (a key equal to the prefix).
|
|
141
|
+
*/
|
|
142
|
+
async walk(path) {
|
|
143
|
+
const prefix = this.toPrefix(path);
|
|
144
|
+
const items = await this.keysUnder(prefix);
|
|
145
|
+
return items.map((item) => item.key).filter((key) => key !== prefix);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=directory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"directory.js","sourceRoot":"","sources":["../src/directory.ts"],"names":[],"mappings":"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"}
|
package/dist/driver.d.ts
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @streetjs/storage — the single driver contract.
|
|
3
|
+
*
|
|
4
|
+
* `StorageDriver` is the one interface every provider implements. The storage
|
|
5
|
+
* facade never assumes a provider; it only calls the methods defined here.
|
|
6
|
+
* Mandatory methods are the primitive object operations (`put`/`get`/`exists`/
|
|
7
|
+
* `delete`/`stat`/`list`) plus streaming (`putStream`/`getStream`). Advanced
|
|
8
|
+
* capabilities (`multipart`/`resumable`/`versioning`/`signedUrl`/`lifecycle`)
|
|
9
|
+
* are **optional**; when a driver does not implement one natively, the facade's
|
|
10
|
+
* cross-cutting layer supplies a provider-agnostic simulation built on the
|
|
11
|
+
* mandatory primitives, keeping observable behavior identical across providers.
|
|
12
|
+
*
|
|
13
|
+
* Requirements: 2.1, 2.3, 2.4, 4.6, 5.5
|
|
14
|
+
*/
|
|
15
|
+
import type { Readable } from "node:stream";
|
|
16
|
+
import type { StorageObjectMetadata, WriteMetadata, StorageListItem, ListOptions, VersionInfo, SignedOperation, SignedUrlOptions, SignedUrlVerification, LifecycleRule, LifecycleOutcome, DriverProbe } from "./types.js";
|
|
17
|
+
/** Node's `Readable` stream, used for streaming uploads/downloads. */
|
|
18
|
+
export type NodeReadable = Readable;
|
|
19
|
+
/** Result of a lookup that may be absent, distinguishing "not found" from errors. */
|
|
20
|
+
export type MaybeObject = {
|
|
21
|
+
readonly found: true;
|
|
22
|
+
readonly bytes: Uint8Array;
|
|
23
|
+
readonly metadata: StorageObjectMetadata;
|
|
24
|
+
} | {
|
|
25
|
+
readonly found: false;
|
|
26
|
+
};
|
|
27
|
+
/** A single stored part for multipart assembly. */
|
|
28
|
+
export interface StoredPart {
|
|
29
|
+
readonly partNumber: number;
|
|
30
|
+
readonly etag: string;
|
|
31
|
+
readonly size: number;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The single contract every provider implements. Mandatory methods are the
|
|
35
|
+
* primitive object operations; capability methods are optional and, when
|
|
36
|
+
* absent, are simulated by the facade over the primitives.
|
|
37
|
+
*/
|
|
38
|
+
export interface StorageDriver {
|
|
39
|
+
/** Stable driver name (e.g. "memory", "local", "s3"). */
|
|
40
|
+
readonly name: string;
|
|
41
|
+
put(key: string, bytes: Uint8Array, metadata: WriteMetadata): Promise<StorageObjectMetadata>;
|
|
42
|
+
get(key: string): Promise<MaybeObject>;
|
|
43
|
+
exists(key: string): Promise<boolean>;
|
|
44
|
+
delete(key: string): Promise<void>;
|
|
45
|
+
stat(key: string): Promise<StorageObjectMetadata | null>;
|
|
46
|
+
list(prefix: string, options?: ListOptions): Promise<StorageListItem[]>;
|
|
47
|
+
putStream(key: string, stream: NodeReadable, metadata: WriteMetadata): Promise<StorageObjectMetadata>;
|
|
48
|
+
getStream(key: string): Promise<NodeReadable>;
|
|
49
|
+
multipart?: MultipartCapability;
|
|
50
|
+
resumable?: ResumableCapability;
|
|
51
|
+
versioning?: VersioningCapability;
|
|
52
|
+
signedUrl?: SignedUrlCapability;
|
|
53
|
+
lifecycle?: LifecycleCapability;
|
|
54
|
+
/** Best-effort connectivity/quota probe for health checks. */
|
|
55
|
+
probe?(): Promise<DriverProbe>;
|
|
56
|
+
}
|
|
57
|
+
export interface MultipartCapability {
|
|
58
|
+
create(key: string, metadata: WriteMetadata): Promise<string>;
|
|
59
|
+
uploadPart(uploadId: string, partNumber: number, bytes: Uint8Array): Promise<StoredPart>;
|
|
60
|
+
complete(uploadId: string, parts: readonly StoredPart[]): Promise<StorageObjectMetadata>;
|
|
61
|
+
abort(uploadId: string): Promise<void>;
|
|
62
|
+
}
|
|
63
|
+
export interface ResumableCapability {
|
|
64
|
+
start(key: string, metadata: WriteMetadata): Promise<string>;
|
|
65
|
+
append(sessionId: string, bytes: Uint8Array, offset: number): Promise<number>;
|
|
66
|
+
offset(sessionId: string): Promise<number>;
|
|
67
|
+
finish(sessionId: string): Promise<StorageObjectMetadata>;
|
|
68
|
+
cancel(sessionId: string): Promise<void>;
|
|
69
|
+
}
|
|
70
|
+
export interface VersioningCapability {
|
|
71
|
+
snapshot(key: string): Promise<string | null>;
|
|
72
|
+
list(key: string): Promise<VersionInfo[]>;
|
|
73
|
+
restore(key: string, versionId: string): Promise<StorageObjectMetadata>;
|
|
74
|
+
deleteVersion(key: string, versionId: string): Promise<void>;
|
|
75
|
+
}
|
|
76
|
+
export interface SignedUrlCapability {
|
|
77
|
+
sign(key: string, op: SignedOperation, options: SignedUrlOptions): Promise<string>;
|
|
78
|
+
verify(url: string, now: number): SignedUrlVerification;
|
|
79
|
+
}
|
|
80
|
+
export interface LifecycleCapability {
|
|
81
|
+
apply(rule: LifecycleRule, now: number): Promise<LifecycleOutcome[]>;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=driver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"driver.d.ts","sourceRoot":"","sources":["../src/driver.ts"],"names":[],"mappings":"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"}
|
package/dist/driver.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @streetjs/storage — the single driver contract.
|
|
3
|
+
*
|
|
4
|
+
* `StorageDriver` is the one interface every provider implements. The storage
|
|
5
|
+
* facade never assumes a provider; it only calls the methods defined here.
|
|
6
|
+
* Mandatory methods are the primitive object operations (`put`/`get`/`exists`/
|
|
7
|
+
* `delete`/`stat`/`list`) plus streaming (`putStream`/`getStream`). Advanced
|
|
8
|
+
* capabilities (`multipart`/`resumable`/`versioning`/`signedUrl`/`lifecycle`)
|
|
9
|
+
* are **optional**; when a driver does not implement one natively, the facade's
|
|
10
|
+
* cross-cutting layer supplies a provider-agnostic simulation built on the
|
|
11
|
+
* mandatory primitives, keeping observable behavior identical across providers.
|
|
12
|
+
*
|
|
13
|
+
* Requirements: 2.1, 2.3, 2.4, 4.6, 5.5
|
|
14
|
+
*/
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=driver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"driver.js","sourceRoot":"","sources":["../src/driver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG"}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @streetjs/storage — Azure Blob Storage driver submodule (`@streetjs/storage/azure`).
|
|
3
|
+
*
|
|
4
|
+
* Azure Blob Storage does **not** speak the S3 wire shape, so — unlike
|
|
5
|
+
* `s3.ts`/`r2.ts`/`minio.ts`/`backblaze.ts`, which specialize the shared
|
|
6
|
+
* {@link createS3StyleDriver} base — this driver maps the {@link StorageDriver}
|
|
7
|
+
* contract **directly** onto a structural Azure Blob client
|
|
8
|
+
* ({@link AzureBlobClientLike}). It computes object identity fields
|
|
9
|
+
* (`size`/`checksum`/`etag`) and timestamps locally and assembles every
|
|
10
|
+
* {@link StorageObjectMetadata} through the shared metadata layer
|
|
11
|
+
* ({@link buildObjectMetadata}) so the field set is identical to Memory/Local
|
|
12
|
+
* and every other provider (Requirement 2.1, 10.1).
|
|
13
|
+
*
|
|
14
|
+
* ## SDK isolation (Requirements 3.1, 3.3)
|
|
15
|
+
*
|
|
16
|
+
* This module imports **no provider SDK** at the top level — only Node built-ins,
|
|
17
|
+
* `streetjs` (for the injected {@link Clock}), and this package's own type
|
|
18
|
+
* surface. There are two ways to obtain a driver:
|
|
19
|
+
*
|
|
20
|
+
* 1. **Inject a structural client.** {@link createAzureBlobDriver} accepts an
|
|
21
|
+
* already-built {@link AzureBlobClientLike} (real SDK adapter or a test
|
|
22
|
+
* double) and maps the contract onto it. The `@azure/storage-blob` SDK stays
|
|
23
|
+
* an optional peer concern of the consumer and is never touched by this
|
|
24
|
+
* package.
|
|
25
|
+
*
|
|
26
|
+
* 2. **Let the driver build its own client.** {@link connectAzureBlobDriver}
|
|
27
|
+
* resolves the optional `@azure/storage-blob` peer SDK with a **lazy dynamic
|
|
28
|
+
* `import()`** performed *inside the function* (never at module top level),
|
|
29
|
+
* constructs a container-scoped client, adapts it to
|
|
30
|
+
* {@link AzureBlobClientLike}, and hands it to {@link createAzureBlobDriver}.
|
|
31
|
+
* If the SDK is absent, it throws {@link StorageConfigError} rather than a raw
|
|
32
|
+
* module-resolution error.
|
|
33
|
+
*
|
|
34
|
+
* Because the driver lives behind the `./azure` subpath export
|
|
35
|
+
* (`dist/drivers/azure.js`) and is *not* re-exported from the package index, a
|
|
36
|
+
* consumer only loads this code — and any SDK it lazily resolves — when they
|
|
37
|
+
* import `@streetjs/storage/azure`. `package.json` lists `@azure/storage-blob`
|
|
38
|
+
* as an optional peer dependency, never a runtime dependency, keeping `streetjs`
|
|
39
|
+
* the only runtime dependency.
|
|
40
|
+
*
|
|
41
|
+
* ## Capability delegation (Requirement 2.3)
|
|
42
|
+
*
|
|
43
|
+
* Only the **mandatory primitives** (`put`/`get`/`exists`/`delete`/`stat`/
|
|
44
|
+
* `list`/`putStream`/`getStream`) are implemented. The advanced capabilities
|
|
45
|
+
* (`multipart`/`resumable`/`versioning`/`signedUrl`/`lifecycle`) are left
|
|
46
|
+
* `undefined` so the facade's cross-cutting layer supplies a provider-agnostic
|
|
47
|
+
* simulation over the primitives, keeping observable behavior identical across
|
|
48
|
+
* providers.
|
|
49
|
+
*
|
|
50
|
+
* _Requirements: 2.1, 2.3, 3.3_
|
|
51
|
+
*/
|
|
52
|
+
import { type Clock } from "streetjs";
|
|
53
|
+
import type { MaybeObject, NodeReadable, StorageDriver } from "../driver.js";
|
|
54
|
+
import type { ListOptions, StorageListItem, StorageObjectMetadata, WriteMetadata } from "../types.js";
|
|
55
|
+
/** Input to {@link AzureBlobClientLike.upload}. */
|
|
56
|
+
export interface AzureUploadInput {
|
|
57
|
+
/** The blob name (object key) within the container. */
|
|
58
|
+
readonly blobName: string;
|
|
59
|
+
/** The bytes to store. */
|
|
60
|
+
readonly body: Uint8Array;
|
|
61
|
+
/** Blob content type, mapped to `blobHTTPHeaders.blobContentType`. */
|
|
62
|
+
readonly contentType?: string;
|
|
63
|
+
/** Blob metadata (string→string); used to round-trip the typed field set. */
|
|
64
|
+
readonly metadata?: Record<string, string>;
|
|
65
|
+
}
|
|
66
|
+
/** Result of {@link AzureBlobClientLike.upload}. */
|
|
67
|
+
export interface AzureUploadResult {
|
|
68
|
+
/** The blob's entity tag, when the service returns one. */
|
|
69
|
+
readonly etag?: string;
|
|
70
|
+
}
|
|
71
|
+
/** Blob attributes shared by download and property reads. */
|
|
72
|
+
export interface AzureBlobProperties {
|
|
73
|
+
/** Blob content type (`blobContentType`). */
|
|
74
|
+
readonly contentType?: string;
|
|
75
|
+
/** The blob's entity tag. */
|
|
76
|
+
readonly etag?: string;
|
|
77
|
+
/** Byte length of the blob content (`contentLength`). */
|
|
78
|
+
readonly contentLength?: number;
|
|
79
|
+
/** Last-modified time as epoch ms. */
|
|
80
|
+
readonly lastModified?: number;
|
|
81
|
+
/** Blob metadata (string→string). */
|
|
82
|
+
readonly metadata?: Record<string, string>;
|
|
83
|
+
}
|
|
84
|
+
/** Result of {@link AzureBlobClientLike.download} — attributes plus the body. */
|
|
85
|
+
export interface AzureBlobDownloadResult extends AzureBlobProperties {
|
|
86
|
+
/** The blob's content bytes. */
|
|
87
|
+
readonly body: Uint8Array;
|
|
88
|
+
}
|
|
89
|
+
/** A single entry returned by {@link AzureBlobClientLike.listBlobs}. */
|
|
90
|
+
export interface AzureBlobListItem {
|
|
91
|
+
/** The blob name (object key). */
|
|
92
|
+
readonly name: string;
|
|
93
|
+
/** Byte length of the blob content. */
|
|
94
|
+
readonly contentLength: number;
|
|
95
|
+
/** Last-modified time as epoch ms. */
|
|
96
|
+
readonly lastModified: number;
|
|
97
|
+
}
|
|
98
|
+
/** Options passed to {@link AzureBlobClientLike.listBlobs}. */
|
|
99
|
+
export interface AzureListInput {
|
|
100
|
+
/** Only blobs whose name begins with this prefix are returned. */
|
|
101
|
+
readonly prefix: string;
|
|
102
|
+
/** Maximum number of blobs to return. */
|
|
103
|
+
readonly limit?: number;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* The **minimal, container-scoped structural interface** the Azure Blob driver
|
|
107
|
+
* depends on.
|
|
108
|
+
*
|
|
109
|
+
* It describes just the blob operations the driver needs — never any concrete
|
|
110
|
+
* `@azure/storage-blob` type — so the actual SDK stays an optional peer concern
|
|
111
|
+
* of the consumer (Requirement 3.1). Every call is scoped to a single container
|
|
112
|
+
* (the adapter built by {@link connectAzureBlobDriver} closes over the container
|
|
113
|
+
* name), so the driver only ever passes blob names.
|
|
114
|
+
*/
|
|
115
|
+
export interface AzureBlobClientLike {
|
|
116
|
+
/** Upload `body` to `blobName` with optional content type and metadata. */
|
|
117
|
+
upload(input: AzureUploadInput): Promise<AzureUploadResult>;
|
|
118
|
+
/** Download the blob at `blobName`, or `null` when it does not exist. */
|
|
119
|
+
download(input: {
|
|
120
|
+
readonly blobName: string;
|
|
121
|
+
}): Promise<AzureBlobDownloadResult | null>;
|
|
122
|
+
/** Read blob attributes without the body, or `null` when absent. */
|
|
123
|
+
getProperties(input: {
|
|
124
|
+
readonly blobName: string;
|
|
125
|
+
}): Promise<AzureBlobProperties | null>;
|
|
126
|
+
/** Delete the blob at `blobName` (a no-op when it is already absent). */
|
|
127
|
+
deleteBlob(input: {
|
|
128
|
+
readonly blobName: string;
|
|
129
|
+
}): Promise<void>;
|
|
130
|
+
/** Report whether a blob exists at `blobName`. */
|
|
131
|
+
exists(input: {
|
|
132
|
+
readonly blobName: string;
|
|
133
|
+
}): Promise<boolean>;
|
|
134
|
+
/** List blobs whose name begins with `prefix`. */
|
|
135
|
+
listBlobs(input: AzureListInput): Promise<readonly AzureBlobListItem[]>;
|
|
136
|
+
}
|
|
137
|
+
/** Options for {@link createAzureBlobDriver} / {@link AzureBlobDriver}. */
|
|
138
|
+
export interface AzureBlobDriverOptions {
|
|
139
|
+
/** Injected clock for deterministic timestamps in tests. Default `systemClock`. */
|
|
140
|
+
readonly clock?: Clock;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Maps the {@link StorageDriver} contract directly onto an injected
|
|
144
|
+
* {@link AzureBlobClientLike}.
|
|
145
|
+
*
|
|
146
|
+
* Unlike the S3-compatible providers, Azure Blob does not share the S3 wire
|
|
147
|
+
* shape, so this driver does not build on {@link createS3StyleDriver}. It
|
|
148
|
+
* computes size/checksum/etag and timestamps locally, encodes the typed metadata
|
|
149
|
+
* into the blob metadata map so it round-trips on read, and reports a missing
|
|
150
|
+
* key consistently ({@link MaybeObject} `{ found: false }` for `get`, `null` for
|
|
151
|
+
* `stat`, {@link NotFoundError} for `getStream`).
|
|
152
|
+
*/
|
|
153
|
+
export declare class AzureBlobDriver implements StorageDriver {
|
|
154
|
+
/** Stable driver name. */
|
|
155
|
+
readonly name = "azure";
|
|
156
|
+
private readonly client;
|
|
157
|
+
private readonly clock;
|
|
158
|
+
constructor(client: AzureBlobClientLike, options?: AzureBlobDriverOptions);
|
|
159
|
+
/**
|
|
160
|
+
* Store `bytes` under `key`, computing size and sha-256 checksum locally and
|
|
161
|
+
* taking timestamps from the injected clock. When overwriting, the original
|
|
162
|
+
* `createdAt` is preserved (a preceding attribute read). The typed metadata is
|
|
163
|
+
* encoded into the blob metadata map so it round-trips on read
|
|
164
|
+
* (Requirements 4.1, 10.1, 10.2).
|
|
165
|
+
*/
|
|
166
|
+
put(key: string, bytes: Uint8Array, metadata: WriteMetadata): Promise<StorageObjectMetadata>;
|
|
167
|
+
/**
|
|
168
|
+
* Read the object at `key`, returning a discriminated {@link MaybeObject} so
|
|
169
|
+
* absence is reported rather than thrown (Requirements 4.2, 2.4). Metadata is
|
|
170
|
+
* rebuilt from the blob attributes and encoded metadata via the shared layer.
|
|
171
|
+
*/
|
|
172
|
+
get(key: string): Promise<MaybeObject>;
|
|
173
|
+
/** Report whether an object is stored under `key` (Requirement 4.3). */
|
|
174
|
+
exists(key: string): Promise<boolean>;
|
|
175
|
+
/** Delete the object at `key`; deleting a missing key is a no-op (Requirement 4.4). */
|
|
176
|
+
delete(key: string): Promise<void>;
|
|
177
|
+
/**
|
|
178
|
+
* Return the metadata for `key` without its content, or `null` when absent
|
|
179
|
+
* (Requirement 4.10).
|
|
180
|
+
*/
|
|
181
|
+
stat(key: string): Promise<StorageObjectMetadata | null>;
|
|
182
|
+
/** List objects whose key begins with `prefix` (Requirement 4.9). */
|
|
183
|
+
list(prefix: string, options?: ListOptions): Promise<StorageListItem[]>;
|
|
184
|
+
/**
|
|
185
|
+
* Consume a Node {@link Readable} and persist the assembled bytes under `key`
|
|
186
|
+
* with the same computed metadata as {@link put} (Requirement 5.1). Chunks are
|
|
187
|
+
* drained through a `pipeline` (correct backpressure and error propagation),
|
|
188
|
+
* then handed to {@link put}.
|
|
189
|
+
*/
|
|
190
|
+
putStream(key: string, stream: NodeReadable, metadata: WriteMetadata): Promise<StorageObjectMetadata>;
|
|
191
|
+
/**
|
|
192
|
+
* Return a Node {@link Readable} of the stored bytes at `key` (Requirement
|
|
193
|
+
* 5.2). Throws {@link NotFoundError} for a missing key (Requirement 5.5).
|
|
194
|
+
*/
|
|
195
|
+
getStream(key: string): Promise<NodeReadable>;
|
|
196
|
+
/**
|
|
197
|
+
* Rebuild the typed {@link StorageObjectMetadata} field set from blob
|
|
198
|
+
* attributes and the encoded metadata map, applying the shared layer's
|
|
199
|
+
* canonical defaults. Provider-supplied values back-fill identity/timestamp
|
|
200
|
+
* fields when the encoded ones are absent (e.g. a blob written outside this
|
|
201
|
+
* driver), keeping the shape consistent across providers.
|
|
202
|
+
*/
|
|
203
|
+
private decodeMeta;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Create an Azure-Blob-backed {@link StorageDriver} over an **injected**
|
|
207
|
+
* structural {@link AzureBlobClientLike}.
|
|
208
|
+
*
|
|
209
|
+
* This is the primary, SDK-free entry point: the caller supplies a client that
|
|
210
|
+
* already speaks the {@link AzureBlobClientLike} shape (built from
|
|
211
|
+
* `@azure/storage-blob`, or a test double), and this function maps the contract
|
|
212
|
+
* onto it. No provider SDK is imported.
|
|
213
|
+
*
|
|
214
|
+
* @throws {StorageConfigError} when no client is injected — use
|
|
215
|
+
* {@link connectAzureBlobDriver} to build a client from connection options.
|
|
216
|
+
*/
|
|
217
|
+
export declare function createAzureBlobDriver(client: AzureBlobClientLike, options?: AzureBlobDriverOptions): StorageDriver;
|
|
218
|
+
/** Connection options for building an Azure Blob client via {@link connectAzureBlobDriver}. */
|
|
219
|
+
export interface AzureBlobConnectionOptions {
|
|
220
|
+
/** The blob container the driver operates within (required). */
|
|
221
|
+
readonly container: string;
|
|
222
|
+
/** An Azure Storage connection string (e.g. from the portal). */
|
|
223
|
+
readonly connectionString: string;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Build an Azure-Blob-backed {@link StorageDriver}, constructing the underlying
|
|
227
|
+
* client from `connection` options using the optional `@azure/storage-blob` peer
|
|
228
|
+
* SDK.
|
|
229
|
+
*
|
|
230
|
+
* The SDK is resolved with a **lazy dynamic `import()`** performed inside this
|
|
231
|
+
* function, so the peer dependency is only touched when a caller actually asks
|
|
232
|
+
* the driver to build its own client. The resolved SDK client is adapted to the
|
|
233
|
+
* structural {@link AzureBlobClientLike} and handed to {@link createAzureBlobDriver}.
|
|
234
|
+
*
|
|
235
|
+
* @throws {StorageConfigError} when the `@azure/storage-blob` SDK is not
|
|
236
|
+
* installed, or when the client cannot be constructed from the supplied options.
|
|
237
|
+
*/
|
|
238
|
+
export declare function connectAzureBlobDriver(connection: AzureBlobConnectionOptions, options?: AzureBlobDriverOptions): Promise<StorageDriver>;
|
|
239
|
+
//# sourceMappingURL=azure.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"azure.d.ts","sourceRoot":"","sources":["../../src/drivers/azure.ts"],"names":[],"mappings":"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"}
|