@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
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @streetjs/storage — shared, strongly typed data models.
|
|
3
|
+
*
|
|
4
|
+
* This module is the foundational, provider-agnostic type surface of the
|
|
5
|
+
* package. Every other module (`driver.ts`, `facade.ts`, the drivers, the
|
|
6
|
+
* cross-cutting layers, the plugin/CLI/testing utilities, and the integration
|
|
7
|
+
* bridges) imports the models defined here, so this file intentionally has no
|
|
8
|
+
* dependency on any sibling module other than a type-only reference to the
|
|
9
|
+
* driver contract for {@link StorageConfig.driver}. Only core StreetJS
|
|
10
|
+
* primitives (`Clock`, `MetricsRegistry`, `HealthCheckRegistry`) are imported
|
|
11
|
+
* from `streetjs`.
|
|
12
|
+
*
|
|
13
|
+
* The structural bridge/auth/codec contracts ({@link AuthLike},
|
|
14
|
+
* {@link ImageCodec}, {@link EventsLike}, {@link QueueLike},
|
|
15
|
+
* {@link RealtimeLike}) live here because {@link StorageConfig} references them;
|
|
16
|
+
* the access/image/integration modules import these shapes from this module,
|
|
17
|
+
* keeping the dependency direction acyclic (leaf modules → types, never the
|
|
18
|
+
* reverse).
|
|
19
|
+
*
|
|
20
|
+
* _Requirements: 1.1, 4.1, 8.2, 10.1, 12.2, 13.1, 16.1, 23.2_
|
|
21
|
+
*/
|
|
22
|
+
import type { Clock, HealthCheckRegistry, MetricsRegistry } from "streetjs";
|
|
23
|
+
import type { StorageDriver } from "./driver.js";
|
|
24
|
+
/** Optional per-application map of custom metadata field types (default: unknown). */
|
|
25
|
+
export interface StorageMetadataMap {
|
|
26
|
+
[key: string]: unknown;
|
|
27
|
+
}
|
|
28
|
+
/** The typed metadata associated with every object (Requirement 10.1). */
|
|
29
|
+
export interface StorageObjectMetadata<C = Record<string, unknown>> {
|
|
30
|
+
readonly key: string;
|
|
31
|
+
readonly size: number;
|
|
32
|
+
readonly contentType: string;
|
|
33
|
+
readonly etag: string;
|
|
34
|
+
readonly checksum: string;
|
|
35
|
+
readonly owner?: string;
|
|
36
|
+
readonly tenant?: string;
|
|
37
|
+
readonly accessLevel: AccessLevel;
|
|
38
|
+
readonly createdAt: number;
|
|
39
|
+
readonly updatedAt: number;
|
|
40
|
+
readonly custom: C;
|
|
41
|
+
readonly versionId?: string;
|
|
42
|
+
}
|
|
43
|
+
/** Metadata supplied on write (Requirement 4.1). */
|
|
44
|
+
export interface WriteMetadata {
|
|
45
|
+
readonly contentType?: string;
|
|
46
|
+
readonly owner?: string;
|
|
47
|
+
readonly tenant?: string;
|
|
48
|
+
readonly accessLevel?: AccessLevel;
|
|
49
|
+
readonly custom?: Record<string, unknown>;
|
|
50
|
+
}
|
|
51
|
+
export interface GetResult {
|
|
52
|
+
readonly found: boolean;
|
|
53
|
+
readonly bytes?: Uint8Array;
|
|
54
|
+
readonly metadata?: StorageObjectMetadata;
|
|
55
|
+
}
|
|
56
|
+
export interface CopyResult {
|
|
57
|
+
readonly copied: boolean;
|
|
58
|
+
readonly metadata?: StorageObjectMetadata;
|
|
59
|
+
}
|
|
60
|
+
export interface MoveResult {
|
|
61
|
+
readonly moved: boolean;
|
|
62
|
+
readonly metadata?: StorageObjectMetadata;
|
|
63
|
+
}
|
|
64
|
+
export interface StorageListItem {
|
|
65
|
+
readonly key: string;
|
|
66
|
+
readonly size: number;
|
|
67
|
+
readonly updatedAt: number;
|
|
68
|
+
}
|
|
69
|
+
/** Options for listing keys under a prefix. */
|
|
70
|
+
export interface ListOptions {
|
|
71
|
+
/** Maximum number of items to return. */
|
|
72
|
+
readonly limit?: number;
|
|
73
|
+
/** Continuation token / key to resume listing after (exclusive). */
|
|
74
|
+
readonly cursor?: string;
|
|
75
|
+
/**
|
|
76
|
+
* When true, collapse results to immediate children by treating `/` as a
|
|
77
|
+
* directory delimiter rather than returning every key under the prefix.
|
|
78
|
+
*/
|
|
79
|
+
readonly delimiter?: boolean;
|
|
80
|
+
}
|
|
81
|
+
/** Access classifications (Requirement 11.1). */
|
|
82
|
+
export type AccessLevel = "public" | "private" | "signed" | "authenticated" | "role-based" | "tenant-aware";
|
|
83
|
+
/** Signed URL surface (Requirement 8). */
|
|
84
|
+
export type SignedOperation = "GET" | "PUT" | "DELETE";
|
|
85
|
+
export interface SignedUrlOptions {
|
|
86
|
+
readonly expiresInMs?: number;
|
|
87
|
+
readonly headers?: Record<string, string>;
|
|
88
|
+
readonly contentType?: string;
|
|
89
|
+
readonly maxSize?: number;
|
|
90
|
+
readonly metadata?: Record<string, string>;
|
|
91
|
+
}
|
|
92
|
+
export interface SignedUrlVerification {
|
|
93
|
+
readonly valid: boolean;
|
|
94
|
+
readonly reason?: "expired" | "operation-mismatch" | "signature-mismatch" | "malformed";
|
|
95
|
+
readonly key?: string;
|
|
96
|
+
readonly op?: SignedOperation;
|
|
97
|
+
}
|
|
98
|
+
/** Versioning (Requirement 12). */
|
|
99
|
+
export interface VersionInfo {
|
|
100
|
+
readonly versionId: string;
|
|
101
|
+
readonly size: number;
|
|
102
|
+
readonly createdAt: number;
|
|
103
|
+
readonly checksum: string;
|
|
104
|
+
}
|
|
105
|
+
/** Lifecycle rules (Requirement 13.1). */
|
|
106
|
+
export type LifecycleRule = {
|
|
107
|
+
readonly type: "delete-after-days";
|
|
108
|
+
readonly days: number;
|
|
109
|
+
readonly prefix?: string;
|
|
110
|
+
} | {
|
|
111
|
+
readonly type: "archive-after-months";
|
|
112
|
+
readonly months: number;
|
|
113
|
+
readonly prefix?: string;
|
|
114
|
+
} | {
|
|
115
|
+
readonly type: "expire-temp-uploads";
|
|
116
|
+
readonly afterMs: number;
|
|
117
|
+
} | {
|
|
118
|
+
readonly type: "move-to-cold";
|
|
119
|
+
readonly afterDays: number;
|
|
120
|
+
readonly coldPrefix: string;
|
|
121
|
+
readonly prefix?: string;
|
|
122
|
+
};
|
|
123
|
+
export interface LifecycleOutcome {
|
|
124
|
+
readonly key: string;
|
|
125
|
+
readonly action: "deleted" | "archived" | "expired" | "moved";
|
|
126
|
+
}
|
|
127
|
+
/** Validation (Requirement 9). */
|
|
128
|
+
export interface ValidationConfig {
|
|
129
|
+
readonly allowedMimeTypes?: readonly string[];
|
|
130
|
+
readonly allowedExtensions?: readonly string[];
|
|
131
|
+
readonly maxSize?: number;
|
|
132
|
+
readonly filenamePattern?: RegExp;
|
|
133
|
+
readonly requireChecksum?: boolean;
|
|
134
|
+
readonly custom?: (input: ValidationInput) => ValidationResult | Promise<ValidationResult>;
|
|
135
|
+
}
|
|
136
|
+
/** The subject a validator inspects before any content is persisted. */
|
|
137
|
+
export interface ValidationInput {
|
|
138
|
+
readonly key: string;
|
|
139
|
+
readonly size: number;
|
|
140
|
+
readonly contentType?: string;
|
|
141
|
+
readonly checksum?: string;
|
|
142
|
+
readonly metadata?: WriteMetadata;
|
|
143
|
+
}
|
|
144
|
+
export interface ValidationResult {
|
|
145
|
+
readonly ok: boolean;
|
|
146
|
+
readonly error?: string;
|
|
147
|
+
}
|
|
148
|
+
/** Search (Requirement 16.1). */
|
|
149
|
+
export interface SearchFilters {
|
|
150
|
+
readonly prefix?: string;
|
|
151
|
+
readonly contentType?: string;
|
|
152
|
+
readonly owner?: string;
|
|
153
|
+
readonly tenant?: string;
|
|
154
|
+
readonly minSize?: number;
|
|
155
|
+
readonly maxSize?: number;
|
|
156
|
+
readonly updatedAfter?: number;
|
|
157
|
+
readonly updatedBefore?: number;
|
|
158
|
+
readonly metadata?: Record<string, unknown>;
|
|
159
|
+
}
|
|
160
|
+
/** Structural auth bridge used for access-level decisions (optional). */
|
|
161
|
+
export interface AuthLike {
|
|
162
|
+
/** Resolve whether the given context is permitted to perform an operation. */
|
|
163
|
+
can(context: {
|
|
164
|
+
readonly key: string;
|
|
165
|
+
readonly operation: string;
|
|
166
|
+
readonly accessLevel: AccessLevel;
|
|
167
|
+
readonly owner?: string;
|
|
168
|
+
readonly tenant?: string;
|
|
169
|
+
}): boolean | Promise<boolean>;
|
|
170
|
+
}
|
|
171
|
+
/** Structural image codec used by the image processor (optional). */
|
|
172
|
+
export interface ImageCodec {
|
|
173
|
+
/** Transform/convert source image bytes, returning the processed bytes. */
|
|
174
|
+
transform(bytes: Uint8Array, operation: {
|
|
175
|
+
readonly resize?: {
|
|
176
|
+
readonly width?: number;
|
|
177
|
+
readonly height?: number;
|
|
178
|
+
};
|
|
179
|
+
readonly format?: string;
|
|
180
|
+
readonly quality?: number;
|
|
181
|
+
}): Uint8Array | Promise<Uint8Array>;
|
|
182
|
+
}
|
|
183
|
+
/** Structural events bridge: publishes typed storage events (optional). */
|
|
184
|
+
export interface EventsLike {
|
|
185
|
+
publish(event: string, payload: unknown): void | Promise<void>;
|
|
186
|
+
}
|
|
187
|
+
/** Structural queue bridge: dispatches background jobs (optional). */
|
|
188
|
+
export interface QueueLike {
|
|
189
|
+
dispatch(job: string, payload: unknown): void | Promise<void>;
|
|
190
|
+
}
|
|
191
|
+
/** Structural realtime bridge: broadcasts upload progress/state (optional). */
|
|
192
|
+
export interface RealtimeLike {
|
|
193
|
+
broadcast(channel: string, event: string, payload: unknown): void | Promise<void>;
|
|
194
|
+
}
|
|
195
|
+
/** Configuration (Requirement 1). */
|
|
196
|
+
export interface StorageConfig {
|
|
197
|
+
readonly provider: "memory" | "local" | (string & {});
|
|
198
|
+
readonly driver?: StorageDriver;
|
|
199
|
+
readonly root?: string;
|
|
200
|
+
readonly clock?: Clock;
|
|
201
|
+
readonly validation?: ValidationConfig;
|
|
202
|
+
readonly versioning?: boolean;
|
|
203
|
+
readonly signingSecret?: string;
|
|
204
|
+
readonly metrics?: MetricsRegistry;
|
|
205
|
+
readonly health?: HealthCheckRegistry;
|
|
206
|
+
readonly auth?: AuthLike;
|
|
207
|
+
readonly imageCodec?: ImageCodec;
|
|
208
|
+
readonly bridges?: {
|
|
209
|
+
readonly events?: EventsLike;
|
|
210
|
+
readonly queue?: QueueLike;
|
|
211
|
+
readonly realtime?: RealtimeLike;
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
export interface StorageStats {
|
|
215
|
+
readonly uploads: number;
|
|
216
|
+
readonly downloads: number;
|
|
217
|
+
readonly bytesUploaded: number;
|
|
218
|
+
readonly bytesDownloaded: number;
|
|
219
|
+
readonly activeUploads: number;
|
|
220
|
+
readonly failedUploads: number;
|
|
221
|
+
readonly storageUsage: number;
|
|
222
|
+
readonly multipartUploads: number;
|
|
223
|
+
readonly resumableSessions: number;
|
|
224
|
+
}
|
|
225
|
+
/** Best-effort connectivity/quota probe result surfaced by driver health checks. */
|
|
226
|
+
export interface DriverProbe {
|
|
227
|
+
readonly connectivity: boolean;
|
|
228
|
+
readonly writable: boolean;
|
|
229
|
+
readonly readable: boolean;
|
|
230
|
+
readonly quotaAvailable: boolean;
|
|
231
|
+
}
|
|
232
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @streetjs/storage — shared, strongly typed data models.
|
|
3
|
+
*
|
|
4
|
+
* This module is the foundational, provider-agnostic type surface of the
|
|
5
|
+
* package. Every other module (`driver.ts`, `facade.ts`, the drivers, the
|
|
6
|
+
* cross-cutting layers, the plugin/CLI/testing utilities, and the integration
|
|
7
|
+
* bridges) imports the models defined here, so this file intentionally has no
|
|
8
|
+
* dependency on any sibling module other than a type-only reference to the
|
|
9
|
+
* driver contract for {@link StorageConfig.driver}. Only core StreetJS
|
|
10
|
+
* primitives (`Clock`, `MetricsRegistry`, `HealthCheckRegistry`) are imported
|
|
11
|
+
* from `streetjs`.
|
|
12
|
+
*
|
|
13
|
+
* The structural bridge/auth/codec contracts ({@link AuthLike},
|
|
14
|
+
* {@link ImageCodec}, {@link EventsLike}, {@link QueueLike},
|
|
15
|
+
* {@link RealtimeLike}) live here because {@link StorageConfig} references them;
|
|
16
|
+
* the access/image/integration modules import these shapes from this module,
|
|
17
|
+
* keeping the dependency direction acyclic (leaf modules → types, never the
|
|
18
|
+
* reverse).
|
|
19
|
+
*
|
|
20
|
+
* _Requirements: 1.1, 4.1, 8.2, 10.1, 12.2, 13.1, 16.1, 23.2_
|
|
21
|
+
*/
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @streetjs/storage — the pre-persistence validation pipeline.
|
|
3
|
+
*
|
|
4
|
+
* The {@link ValidationPipeline} runs an ordered set of validators over a
|
|
5
|
+
* {@link ValidationInput} *before* any content is persisted, so an unacceptable
|
|
6
|
+
* upload is rejected without ever reaching the driver and therefore leaves no
|
|
7
|
+
* partial object stored (Requirements 9.3, 9.4). The facade constructs a
|
|
8
|
+
* pipeline from `config.validation` and invokes it as the first step of `put`
|
|
9
|
+
* and `putStream`; the driver's `put` is only called once the pipeline reports
|
|
10
|
+
* success.
|
|
11
|
+
*
|
|
12
|
+
* The built-in validators, applied strictly in this order, are:
|
|
13
|
+
*
|
|
14
|
+
* 1. **MIME type** — the write's `contentType` must be one of
|
|
15
|
+
* `allowedMimeTypes` (exact match, or a `type/*` wildcard entry).
|
|
16
|
+
* 2. **File extension** — the extension derived from the object key must be
|
|
17
|
+
* one of `allowedExtensions` (compared case-insensitively, leading dots
|
|
18
|
+
* ignored so `"png"` and `".png"` are equivalent).
|
|
19
|
+
* 3. **File size** — the byte length must not exceed `maxSize`.
|
|
20
|
+
* 4. **Filename** — the filename (final `/`-delimited segment of the key) must
|
|
21
|
+
* match `filenamePattern`.
|
|
22
|
+
* 5. **Checksum** — when `requireChecksum` is set, a non-empty `checksum` must
|
|
23
|
+
* be present on the input.
|
|
24
|
+
* 6. **Custom** — the configured `custom(input)` validator, if any, is invoked
|
|
25
|
+
* last and may reject with its own descriptive message.
|
|
26
|
+
*
|
|
27
|
+
* The pipeline short-circuits: it returns the **first** rejection it encounters
|
|
28
|
+
* and does not run subsequent validators. Each validator is a no-op (returns
|
|
29
|
+
* `{ ok: true }`) when its governing configuration field is absent, so a sparse
|
|
30
|
+
* {@link ValidationConfig} only enforces the constraints it actually declares.
|
|
31
|
+
*
|
|
32
|
+
* _Requirements: 9.1, 9.2, 9.3, 9.4_
|
|
33
|
+
*/
|
|
34
|
+
import type { ValidationConfig, ValidationInput, ValidationResult } from "./types.js";
|
|
35
|
+
/** A single validator: inspects the input against the config, returning a result. */
|
|
36
|
+
export type Validator = (input: ValidationInput, config: ValidationConfig) => ValidationResult | Promise<ValidationResult>;
|
|
37
|
+
/**
|
|
38
|
+
* Validator 1 — MIME type. When `allowedMimeTypes` is configured, the input's
|
|
39
|
+
* `contentType` must exactly equal one of the allowed entries, or match a
|
|
40
|
+
* `type/*` wildcard entry (e.g. `"image/*"` permits `"image/png"`). A missing
|
|
41
|
+
* `contentType` is rejected because it cannot be shown to be permitted.
|
|
42
|
+
*/
|
|
43
|
+
export declare const validateMimeType: Validator;
|
|
44
|
+
/**
|
|
45
|
+
* Validator 2 — file extension. When `allowedExtensions` is configured, the
|
|
46
|
+
* extension derived from the object key must be one of the allowed entries,
|
|
47
|
+
* compared case-insensitively with any leading dot ignored. A key with no
|
|
48
|
+
* extension is rejected.
|
|
49
|
+
*/
|
|
50
|
+
export declare const validateExtension: Validator;
|
|
51
|
+
/**
|
|
52
|
+
* Validator 3 — file size. When `maxSize` is configured, the input's byte
|
|
53
|
+
* length must not exceed it.
|
|
54
|
+
*/
|
|
55
|
+
export declare const validateSize: Validator;
|
|
56
|
+
/**
|
|
57
|
+
* Validator 4 — filename. When `filenamePattern` is configured, the filename
|
|
58
|
+
* (final `/`-delimited segment of the key) must match the pattern. The pattern
|
|
59
|
+
* is evaluated against a fresh, non-global {@link RegExp} so a shared, sticky
|
|
60
|
+
* (`/g`) source pattern cannot leak `lastIndex` state across calls.
|
|
61
|
+
*/
|
|
62
|
+
export declare const validateFilename: Validator;
|
|
63
|
+
/**
|
|
64
|
+
* Validator 5 — checksum. When `requireChecksum` is set, a non-empty `checksum`
|
|
65
|
+
* must be present on the input. For buffered writes the facade always supplies a
|
|
66
|
+
* computed checksum, so this only rejects when a checksum genuinely cannot be
|
|
67
|
+
* determined.
|
|
68
|
+
*/
|
|
69
|
+
export declare const validateChecksum: Validator;
|
|
70
|
+
/**
|
|
71
|
+
* Validator 6 — custom. When a `custom(input)` validator is configured it runs
|
|
72
|
+
* last and its (possibly asynchronous) result is returned verbatim, so a custom
|
|
73
|
+
* rejection carries its own descriptive message.
|
|
74
|
+
*/
|
|
75
|
+
export declare const validateCustom: Validator;
|
|
76
|
+
/**
|
|
77
|
+
* The built-in validators applied by every {@link ValidationPipeline}, in the
|
|
78
|
+
* fixed order MIME type → extension → size → filename → checksum → custom.
|
|
79
|
+
*/
|
|
80
|
+
export declare const BUILT_IN_VALIDATORS: readonly Validator[];
|
|
81
|
+
/**
|
|
82
|
+
* Runs an ordered chain of validators against a {@link ValidationInput},
|
|
83
|
+
* short-circuiting on the first rejection.
|
|
84
|
+
*
|
|
85
|
+
* Construct one from a {@link ValidationConfig}; the facade does this once per
|
|
86
|
+
* `Storage` instance when `config.validation` is present and calls
|
|
87
|
+
* {@link ValidationPipeline.validate} before delegating any bytes to the driver.
|
|
88
|
+
* Because a rejection is surfaced *before* `driver.put` is ever called, a
|
|
89
|
+
* rejected upload leaves no partial object stored (Requirement 9.4).
|
|
90
|
+
*/
|
|
91
|
+
export declare class ValidationPipeline {
|
|
92
|
+
/** The configuration each validator consults. */
|
|
93
|
+
private readonly config;
|
|
94
|
+
/** The ordered validators to run (defaults to {@link BUILT_IN_VALIDATORS}). */
|
|
95
|
+
private readonly validators;
|
|
96
|
+
constructor(config: ValidationConfig, validators?: readonly Validator[]);
|
|
97
|
+
/**
|
|
98
|
+
* Run every validator in order against `input`, returning the first rejection
|
|
99
|
+
* encountered or `{ ok: true }` when all validators accept. Validators are
|
|
100
|
+
* awaited sequentially so an async custom validator observes the same
|
|
101
|
+
* short-circuiting order as the synchronous built-ins.
|
|
102
|
+
*/
|
|
103
|
+
validate(input: ValidationInput): Promise<ValidationResult>;
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAEpB,qFAAqF;AACrF,MAAM,MAAM,SAAS,GAAG,CACtB,KAAK,EAAE,eAAe,EACtB,MAAM,EAAE,gBAAgB,KACrB,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;AAYlD;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,EAAE,SAa9B,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,EAAE,SAoB/B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,SAS1B,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,EAAE,SAW9B,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,EAAE,SAQ9B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAAE,SAM5B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,SAAS,EAOnD,CAAC;AAIF;;;;;;;;;GASG;AACH,qBAAa,kBAAkB;IAC7B,iDAAiD;IACjD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;IAE1C,+EAA+E;IAC/E,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAuB;gBAGhD,MAAM,EAAE,gBAAgB,EACxB,UAAU,GAAE,SAAS,SAAS,EAAwB;IAMxD;;;;;OAKG;IACG,QAAQ,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC;CASlE"}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @streetjs/storage — the pre-persistence validation pipeline.
|
|
3
|
+
*
|
|
4
|
+
* The {@link ValidationPipeline} runs an ordered set of validators over a
|
|
5
|
+
* {@link ValidationInput} *before* any content is persisted, so an unacceptable
|
|
6
|
+
* upload is rejected without ever reaching the driver and therefore leaves no
|
|
7
|
+
* partial object stored (Requirements 9.3, 9.4). The facade constructs a
|
|
8
|
+
* pipeline from `config.validation` and invokes it as the first step of `put`
|
|
9
|
+
* and `putStream`; the driver's `put` is only called once the pipeline reports
|
|
10
|
+
* success.
|
|
11
|
+
*
|
|
12
|
+
* The built-in validators, applied strictly in this order, are:
|
|
13
|
+
*
|
|
14
|
+
* 1. **MIME type** — the write's `contentType` must be one of
|
|
15
|
+
* `allowedMimeTypes` (exact match, or a `type/*` wildcard entry).
|
|
16
|
+
* 2. **File extension** — the extension derived from the object key must be
|
|
17
|
+
* one of `allowedExtensions` (compared case-insensitively, leading dots
|
|
18
|
+
* ignored so `"png"` and `".png"` are equivalent).
|
|
19
|
+
* 3. **File size** — the byte length must not exceed `maxSize`.
|
|
20
|
+
* 4. **Filename** — the filename (final `/`-delimited segment of the key) must
|
|
21
|
+
* match `filenamePattern`.
|
|
22
|
+
* 5. **Checksum** — when `requireChecksum` is set, a non-empty `checksum` must
|
|
23
|
+
* be present on the input.
|
|
24
|
+
* 6. **Custom** — the configured `custom(input)` validator, if any, is invoked
|
|
25
|
+
* last and may reject with its own descriptive message.
|
|
26
|
+
*
|
|
27
|
+
* The pipeline short-circuits: it returns the **first** rejection it encounters
|
|
28
|
+
* and does not run subsequent validators. Each validator is a no-op (returns
|
|
29
|
+
* `{ ok: true }`) when its governing configuration field is absent, so a sparse
|
|
30
|
+
* {@link ValidationConfig} only enforces the constraints it actually declares.
|
|
31
|
+
*
|
|
32
|
+
* _Requirements: 9.1, 9.2, 9.3, 9.4_
|
|
33
|
+
*/
|
|
34
|
+
/** The shared "accepted" result, reused to avoid reallocating on every pass. */
|
|
35
|
+
const OK = { ok: true };
|
|
36
|
+
/** Build a rejection result carrying a descriptive message. */
|
|
37
|
+
function reject(error) {
|
|
38
|
+
return { ok: false, error };
|
|
39
|
+
}
|
|
40
|
+
// ── Built-in validators ───────────────────────────────────────────────────────
|
|
41
|
+
/**
|
|
42
|
+
* Validator 1 — MIME type. When `allowedMimeTypes` is configured, the input's
|
|
43
|
+
* `contentType` must exactly equal one of the allowed entries, or match a
|
|
44
|
+
* `type/*` wildcard entry (e.g. `"image/*"` permits `"image/png"`). A missing
|
|
45
|
+
* `contentType` is rejected because it cannot be shown to be permitted.
|
|
46
|
+
*/
|
|
47
|
+
export const validateMimeType = (input, config) => {
|
|
48
|
+
const allowed = config.allowedMimeTypes;
|
|
49
|
+
if (allowed === undefined) {
|
|
50
|
+
return OK;
|
|
51
|
+
}
|
|
52
|
+
const contentType = input.contentType;
|
|
53
|
+
if (contentType !== undefined && allowed.some((entry) => mimeMatches(entry, contentType))) {
|
|
54
|
+
return OK;
|
|
55
|
+
}
|
|
56
|
+
return reject(`content type "${contentType ?? "(none)"}" is not permitted; ` +
|
|
57
|
+
`allowed MIME types: ${allowed.join(", ")}`);
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Validator 2 — file extension. When `allowedExtensions` is configured, the
|
|
61
|
+
* extension derived from the object key must be one of the allowed entries,
|
|
62
|
+
* compared case-insensitively with any leading dot ignored. A key with no
|
|
63
|
+
* extension is rejected.
|
|
64
|
+
*/
|
|
65
|
+
export const validateExtension = (input, config) => {
|
|
66
|
+
const allowed = config.allowedExtensions;
|
|
67
|
+
if (allowed === undefined) {
|
|
68
|
+
return OK;
|
|
69
|
+
}
|
|
70
|
+
const extension = extractExtension(input.key);
|
|
71
|
+
if (extension === undefined) {
|
|
72
|
+
return reject(`object key "${input.key}" has no file extension; ` +
|
|
73
|
+
`allowed extensions: ${allowed.join(", ")}`);
|
|
74
|
+
}
|
|
75
|
+
const normalized = normalizeExtension(extension);
|
|
76
|
+
if (allowed.some((entry) => normalizeExtension(entry) === normalized)) {
|
|
77
|
+
return OK;
|
|
78
|
+
}
|
|
79
|
+
return reject(`file extension ".${normalized}" is not permitted; ` +
|
|
80
|
+
`allowed extensions: ${allowed.join(", ")}`);
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* Validator 3 — file size. When `maxSize` is configured, the input's byte
|
|
84
|
+
* length must not exceed it.
|
|
85
|
+
*/
|
|
86
|
+
export const validateSize = (input, config) => {
|
|
87
|
+
const maxSize = config.maxSize;
|
|
88
|
+
if (maxSize === undefined) {
|
|
89
|
+
return OK;
|
|
90
|
+
}
|
|
91
|
+
if (input.size > maxSize) {
|
|
92
|
+
return reject(`size ${input.size} bytes exceeds the maximum of ${maxSize} bytes`);
|
|
93
|
+
}
|
|
94
|
+
return OK;
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* Validator 4 — filename. When `filenamePattern` is configured, the filename
|
|
98
|
+
* (final `/`-delimited segment of the key) must match the pattern. The pattern
|
|
99
|
+
* is evaluated against a fresh, non-global {@link RegExp} so a shared, sticky
|
|
100
|
+
* (`/g`) source pattern cannot leak `lastIndex` state across calls.
|
|
101
|
+
*/
|
|
102
|
+
export const validateFilename = (input, config) => {
|
|
103
|
+
const pattern = config.filenamePattern;
|
|
104
|
+
if (pattern === undefined) {
|
|
105
|
+
return OK;
|
|
106
|
+
}
|
|
107
|
+
const filename = extractFilename(input.key);
|
|
108
|
+
const safePattern = new RegExp(pattern.source, pattern.flags.replace(/[gy]/g, ""));
|
|
109
|
+
if (safePattern.test(filename)) {
|
|
110
|
+
return OK;
|
|
111
|
+
}
|
|
112
|
+
return reject(`filename "${filename}" does not match the required pattern ${pattern.toString()}`);
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
* Validator 5 — checksum. When `requireChecksum` is set, a non-empty `checksum`
|
|
116
|
+
* must be present on the input. For buffered writes the facade always supplies a
|
|
117
|
+
* computed checksum, so this only rejects when a checksum genuinely cannot be
|
|
118
|
+
* determined.
|
|
119
|
+
*/
|
|
120
|
+
export const validateChecksum = (input, config) => {
|
|
121
|
+
if (config.requireChecksum !== true) {
|
|
122
|
+
return OK;
|
|
123
|
+
}
|
|
124
|
+
if (input.checksum !== undefined && input.checksum !== "") {
|
|
125
|
+
return OK;
|
|
126
|
+
}
|
|
127
|
+
return reject("a checksum is required for this upload but none was provided");
|
|
128
|
+
};
|
|
129
|
+
/**
|
|
130
|
+
* Validator 6 — custom. When a `custom(input)` validator is configured it runs
|
|
131
|
+
* last and its (possibly asynchronous) result is returned verbatim, so a custom
|
|
132
|
+
* rejection carries its own descriptive message.
|
|
133
|
+
*/
|
|
134
|
+
export const validateCustom = async (input, config) => {
|
|
135
|
+
const custom = config.custom;
|
|
136
|
+
if (custom === undefined) {
|
|
137
|
+
return OK;
|
|
138
|
+
}
|
|
139
|
+
return custom(input);
|
|
140
|
+
};
|
|
141
|
+
/**
|
|
142
|
+
* The built-in validators applied by every {@link ValidationPipeline}, in the
|
|
143
|
+
* fixed order MIME type → extension → size → filename → checksum → custom.
|
|
144
|
+
*/
|
|
145
|
+
export const BUILT_IN_VALIDATORS = [
|
|
146
|
+
validateMimeType,
|
|
147
|
+
validateExtension,
|
|
148
|
+
validateSize,
|
|
149
|
+
validateFilename,
|
|
150
|
+
validateChecksum,
|
|
151
|
+
validateCustom,
|
|
152
|
+
];
|
|
153
|
+
// ── The pipeline ──────────────────────────────────────────────────────────────
|
|
154
|
+
/**
|
|
155
|
+
* Runs an ordered chain of validators against a {@link ValidationInput},
|
|
156
|
+
* short-circuiting on the first rejection.
|
|
157
|
+
*
|
|
158
|
+
* Construct one from a {@link ValidationConfig}; the facade does this once per
|
|
159
|
+
* `Storage` instance when `config.validation` is present and calls
|
|
160
|
+
* {@link ValidationPipeline.validate} before delegating any bytes to the driver.
|
|
161
|
+
* Because a rejection is surfaced *before* `driver.put` is ever called, a
|
|
162
|
+
* rejected upload leaves no partial object stored (Requirement 9.4).
|
|
163
|
+
*/
|
|
164
|
+
export class ValidationPipeline {
|
|
165
|
+
/** The configuration each validator consults. */
|
|
166
|
+
config;
|
|
167
|
+
/** The ordered validators to run (defaults to {@link BUILT_IN_VALIDATORS}). */
|
|
168
|
+
validators;
|
|
169
|
+
constructor(config, validators = BUILT_IN_VALIDATORS) {
|
|
170
|
+
this.config = config;
|
|
171
|
+
this.validators = validators;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Run every validator in order against `input`, returning the first rejection
|
|
175
|
+
* encountered or `{ ok: true }` when all validators accept. Validators are
|
|
176
|
+
* awaited sequentially so an async custom validator observes the same
|
|
177
|
+
* short-circuiting order as the synchronous built-ins.
|
|
178
|
+
*/
|
|
179
|
+
async validate(input) {
|
|
180
|
+
for (const validator of this.validators) {
|
|
181
|
+
const result = await validator(input, this.config);
|
|
182
|
+
if (!result.ok) {
|
|
183
|
+
return result;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return OK;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
// ── Helpers ────────────────────────────────────────────────────────────────────
|
|
190
|
+
/** Does a (possibly `type/*` wildcard) allow-list entry match a concrete MIME type? */
|
|
191
|
+
function mimeMatches(entry, contentType) {
|
|
192
|
+
const normalizedEntry = entry.trim().toLowerCase();
|
|
193
|
+
const normalizedType = contentType.trim().toLowerCase();
|
|
194
|
+
if (normalizedEntry === normalizedType) {
|
|
195
|
+
return true;
|
|
196
|
+
}
|
|
197
|
+
if (normalizedEntry.endsWith("/*")) {
|
|
198
|
+
const prefix = normalizedEntry.slice(0, normalizedEntry.length - 1); // keep trailing "/"
|
|
199
|
+
return normalizedType.startsWith(prefix);
|
|
200
|
+
}
|
|
201
|
+
return false;
|
|
202
|
+
}
|
|
203
|
+
/** The final `/`-delimited segment of a key (its filename). */
|
|
204
|
+
function extractFilename(key) {
|
|
205
|
+
const slashIndex = key.lastIndexOf("/");
|
|
206
|
+
return slashIndex === -1 ? key : key.slice(slashIndex + 1);
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* The extension of a key's filename (the text after the final `.`), or
|
|
210
|
+
* `undefined` when the filename has no extension. A leading-dot-only filename
|
|
211
|
+
* (e.g. `".gitignore"`) is treated as having no extension.
|
|
212
|
+
*/
|
|
213
|
+
function extractExtension(key) {
|
|
214
|
+
const filename = extractFilename(key);
|
|
215
|
+
const dotIndex = filename.lastIndexOf(".");
|
|
216
|
+
if (dotIndex <= 0 || dotIndex === filename.length - 1) {
|
|
217
|
+
return undefined;
|
|
218
|
+
}
|
|
219
|
+
return filename.slice(dotIndex + 1);
|
|
220
|
+
}
|
|
221
|
+
/** Normalize an extension for comparison: lowercase, leading dots stripped. */
|
|
222
|
+
function normalizeExtension(extension) {
|
|
223
|
+
return extension.replace(/^\.+/, "").toLowerCase();
|
|
224
|
+
}
|
|
225
|
+
//# sourceMappingURL=validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAcH,gFAAgF;AAChF,MAAM,EAAE,GAAqB,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;AAE1C,+DAA+D;AAC/D,SAAS,MAAM,CAAC,KAAa;IAC3B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AAC9B,CAAC;AAED,iFAAiF;AAEjF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAc,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;IAC3D,MAAM,OAAO,GAAG,MAAM,CAAC,gBAAgB,CAAC;IACxC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC;IACtC,IAAI,WAAW,KAAK,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC;QAC1F,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,MAAM,CACX,iBAAiB,WAAW,IAAI,QAAQ,sBAAsB;QAC5D,uBAAuB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC9C,CAAC;AACJ,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAc,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;IAC5D,MAAM,OAAO,GAAG,MAAM,CAAC,iBAAiB,CAAC;IACzC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,SAAS,GAAG,gBAAgB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC9C,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,OAAO,MAAM,CACX,eAAe,KAAK,CAAC,GAAG,2BAA2B;YACjD,uBAAuB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC9C,CAAC;IACJ,CAAC;IACD,MAAM,UAAU,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IACjD,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,kBAAkB,CAAC,KAAK,CAAC,KAAK,UAAU,CAAC,EAAE,CAAC;QACtE,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,MAAM,CACX,oBAAoB,UAAU,sBAAsB;QAClD,uBAAuB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC9C,CAAC;AACJ,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAc,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;IACvD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;IAC/B,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,GAAG,OAAO,EAAE,CAAC;QACzB,OAAO,MAAM,CAAC,QAAQ,KAAK,CAAC,IAAI,iCAAiC,OAAO,QAAQ,CAAC,CAAC;IACpF,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAc,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;IAC3D,MAAM,OAAO,GAAG,MAAM,CAAC,eAAe,CAAC;IACvC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,QAAQ,GAAG,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC5C,MAAM,WAAW,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;IACnF,IAAI,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC/B,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,MAAM,CAAC,aAAa,QAAQ,yCAAyC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;AACpG,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAc,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;IAC3D,IAAI,MAAM,CAAC,eAAe,KAAK,IAAI,EAAE,CAAC;QACpC,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS,IAAI,KAAK,CAAC,QAAQ,KAAK,EAAE,EAAE,CAAC;QAC1D,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,MAAM,CAAC,8DAA8D,CAAC,CAAC;AAChF,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAc,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;IAC/D,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAC7B,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAyB;IACvD,gBAAgB;IAChB,iBAAiB;IACjB,YAAY;IACZ,gBAAgB;IAChB,gBAAgB;IAChB,cAAc;CACf,CAAC;AAEF,iFAAiF;AAEjF;;;;;;;;;GASG;AACH,MAAM,OAAO,kBAAkB;IAC7B,iDAAiD;IAChC,MAAM,CAAmB;IAE1C,+EAA+E;IAC9D,UAAU,CAAuB;IAElD,YACE,MAAwB,EACxB,aAAmC,mBAAmB;QAEtD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,QAAQ,CAAC,KAAsB;QACnC,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACxC,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YACnD,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;gBACf,OAAO,MAAM,CAAC;YAChB,CAAC;QACH,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC;CACF;AAED,kFAAkF;AAElF,uFAAuF;AACvF,SAAS,WAAW,CAAC,KAAa,EAAE,WAAmB;IACrD,MAAM,eAAe,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACnD,MAAM,cAAc,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACxD,IAAI,eAAe,KAAK,cAAc,EAAE,CAAC;QACvC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC,EAAE,eAAe,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,oBAAoB;QACzF,OAAO,cAAc,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,+DAA+D;AAC/D,SAAS,eAAe,CAAC,GAAW;IAClC,MAAM,UAAU,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACxC,OAAO,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;AAC7D,CAAC;AAED;;;;GAIG;AACH,SAAS,gBAAgB,CAAC,GAAW;IACnC,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;IACtC,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAC3C,IAAI,QAAQ,IAAI,CAAC,IAAI,QAAQ,KAAK,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtD,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,QAAQ,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;AACtC,CAAC;AAED,+EAA+E;AAC/E,SAAS,kBAAkB,CAAC,SAAiB;IAC3C,OAAO,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;AACrD,CAAC"}
|