@vankyle/storage-core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +83 -0
- package/dist/application/index.d.ts +3 -0
- package/dist/application/index.d.ts.map +1 -0
- package/dist/application/index.js +3 -0
- package/dist/application/index.js.map +1 -0
- package/dist/application/policies/index.d.ts +2 -0
- package/dist/application/policies/index.d.ts.map +1 -0
- package/dist/application/policies/index.js +2 -0
- package/dist/application/policies/index.js.map +1 -0
- package/dist/application/policies/object-key-policy.d.ts +13 -0
- package/dist/application/policies/object-key-policy.d.ts.map +1 -0
- package/dist/application/policies/object-key-policy.js +24 -0
- package/dist/application/policies/object-key-policy.js.map +1 -0
- package/dist/application/policies/object-key-policy.test.d.ts +2 -0
- package/dist/application/policies/object-key-policy.test.d.ts.map +1 -0
- package/dist/application/policies/object-key-policy.test.js +53 -0
- package/dist/application/policies/object-key-policy.test.js.map +1 -0
- package/dist/application/services/default-storage-service.d.ts +39 -0
- package/dist/application/services/default-storage-service.d.ts.map +1 -0
- package/dist/application/services/default-storage-service.js +290 -0
- package/dist/application/services/default-storage-service.js.map +1 -0
- package/dist/application/services/default-storage-service.test.d.ts +2 -0
- package/dist/application/services/default-storage-service.test.d.ts.map +1 -0
- package/dist/application/services/default-storage-service.test.js +902 -0
- package/dist/application/services/default-storage-service.test.js.map +1 -0
- package/dist/application/services/index.d.ts +2 -0
- package/dist/application/services/index.d.ts.map +1 -0
- package/dist/application/services/index.js +2 -0
- package/dist/application/services/index.js.map +1 -0
- package/dist/domain/enums/blob-status.d.ts +8 -0
- package/dist/domain/enums/blob-status.d.ts.map +1 -0
- package/dist/domain/enums/blob-status.js +7 -0
- package/dist/domain/enums/blob-status.js.map +1 -0
- package/dist/domain/enums/enums.test.d.ts +2 -0
- package/dist/domain/enums/enums.test.d.ts.map +1 -0
- package/dist/domain/enums/enums.test.js +59 -0
- package/dist/domain/enums/enums.test.js.map +1 -0
- package/dist/domain/enums/file-status.d.ts +6 -0
- package/dist/domain/enums/file-status.d.ts.map +1 -0
- package/dist/domain/enums/file-status.js +5 -0
- package/dist/domain/enums/file-status.js.map +1 -0
- package/dist/domain/enums/index.d.ts +5 -0
- package/dist/domain/enums/index.d.ts.map +1 -0
- package/dist/domain/enums/index.js +5 -0
- package/dist/domain/enums/index.js.map +1 -0
- package/dist/domain/enums/storage-provider.d.ts +7 -0
- package/dist/domain/enums/storage-provider.d.ts.map +1 -0
- package/dist/domain/enums/storage-provider.js +6 -0
- package/dist/domain/enums/storage-provider.js.map +1 -0
- package/dist/domain/enums/upload-status.d.ts +13 -0
- package/dist/domain/enums/upload-status.d.ts.map +1 -0
- package/dist/domain/enums/upload-status.js +11 -0
- package/dist/domain/enums/upload-status.js.map +1 -0
- package/dist/domain/index.d.ts +4 -0
- package/dist/domain/index.d.ts.map +1 -0
- package/dist/domain/index.js +4 -0
- package/dist/domain/index.js.map +1 -0
- package/dist/domain/models/blob-reference.d.ts +8 -0
- package/dist/domain/models/blob-reference.d.ts.map +1 -0
- package/dist/domain/models/blob-reference.js +2 -0
- package/dist/domain/models/blob-reference.js.map +1 -0
- package/dist/domain/models/blob.d.ts +20 -0
- package/dist/domain/models/blob.d.ts.map +1 -0
- package/dist/domain/models/blob.js +2 -0
- package/dist/domain/models/blob.js.map +1 -0
- package/dist/domain/models/file-version.d.ts +14 -0
- package/dist/domain/models/file-version.d.ts.map +1 -0
- package/dist/domain/models/file-version.js +2 -0
- package/dist/domain/models/file-version.js.map +1 -0
- package/dist/domain/models/file.d.ts +17 -0
- package/dist/domain/models/file.d.ts.map +1 -0
- package/dist/domain/models/file.js +2 -0
- package/dist/domain/models/file.js.map +1 -0
- package/dist/domain/models/index.d.ts +7 -0
- package/dist/domain/models/index.d.ts.map +1 -0
- package/dist/domain/models/index.js +2 -0
- package/dist/domain/models/index.js.map +1 -0
- package/dist/domain/models/upload-session.d.ts +26 -0
- package/dist/domain/models/upload-session.d.ts.map +1 -0
- package/dist/domain/models/upload-session.js +2 -0
- package/dist/domain/models/upload-session.js.map +1 -0
- package/dist/domain/models/uploaded-part.d.ts +13 -0
- package/dist/domain/models/uploaded-part.d.ts.map +1 -0
- package/dist/domain/models/uploaded-part.js +2 -0
- package/dist/domain/models/uploaded-part.js.map +1 -0
- package/dist/domain/value-objects/index.d.ts +3 -0
- package/dist/domain/value-objects/index.d.ts.map +1 -0
- package/dist/domain/value-objects/index.js +2 -0
- package/dist/domain/value-objects/index.js.map +1 -0
- package/dist/domain/value-objects/signed-access.d.ts +9 -0
- package/dist/domain/value-objects/signed-access.d.ts.map +1 -0
- package/dist/domain/value-objects/signed-access.js +2 -0
- package/dist/domain/value-objects/signed-access.js.map +1 -0
- package/dist/domain/value-objects/storage-locator.d.ts +7 -0
- package/dist/domain/value-objects/storage-locator.d.ts.map +1 -0
- package/dist/domain/value-objects/storage-locator.js +2 -0
- package/dist/domain/value-objects/storage-locator.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/ports/index.d.ts +4 -0
- package/dist/ports/index.d.ts.map +1 -0
- package/dist/ports/index.js +4 -0
- package/dist/ports/index.js.map +1 -0
- package/dist/ports/metadata/i-blob-store.d.ts +38 -0
- package/dist/ports/metadata/i-blob-store.d.ts.map +1 -0
- package/dist/ports/metadata/i-blob-store.js +2 -0
- package/dist/ports/metadata/i-blob-store.js.map +1 -0
- package/dist/ports/metadata/i-file-store.d.ts +43 -0
- package/dist/ports/metadata/i-file-store.d.ts.map +1 -0
- package/dist/ports/metadata/i-file-store.js +2 -0
- package/dist/ports/metadata/i-file-store.js.map +1 -0
- package/dist/ports/metadata/i-metadata-store.d.ts +9 -0
- package/dist/ports/metadata/i-metadata-store.d.ts.map +1 -0
- package/dist/ports/metadata/i-metadata-store.js +2 -0
- package/dist/ports/metadata/i-metadata-store.js.map +1 -0
- package/dist/ports/metadata/i-upload-session-store.d.ts +48 -0
- package/dist/ports/metadata/i-upload-session-store.d.ts.map +1 -0
- package/dist/ports/metadata/i-upload-session-store.js +2 -0
- package/dist/ports/metadata/i-upload-session-store.js.map +1 -0
- package/dist/ports/metadata/index.d.ts +5 -0
- package/dist/ports/metadata/index.d.ts.map +1 -0
- package/dist/ports/metadata/index.js +2 -0
- package/dist/ports/metadata/index.js.map +1 -0
- package/dist/ports/services/i-storage-service.d.ts +75 -0
- package/dist/ports/services/i-storage-service.d.ts.map +1 -0
- package/dist/ports/services/i-storage-service.js +2 -0
- package/dist/ports/services/i-storage-service.js.map +1 -0
- package/dist/ports/services/index.d.ts +2 -0
- package/dist/ports/services/index.d.ts.map +1 -0
- package/dist/ports/services/index.js +2 -0
- package/dist/ports/services/index.js.map +1 -0
- package/dist/ports/storage/i-storage.d.ts +19 -0
- package/dist/ports/storage/i-storage.d.ts.map +1 -0
- package/dist/ports/storage/i-storage.js +2 -0
- package/dist/ports/storage/i-storage.js.map +1 -0
- package/dist/ports/storage/index.d.ts +3 -0
- package/dist/ports/storage/index.d.ts.map +1 -0
- package/dist/ports/storage/index.js +2 -0
- package/dist/ports/storage/index.js.map +1 -0
- package/dist/ports/storage/storage.types.d.ts +112 -0
- package/dist/ports/storage/storage.types.d.ts.map +1 -0
- package/dist/ports/storage/storage.types.js +2 -0
- package/dist/ports/storage/storage.types.js.map +1 -0
- package/dist/schemas/blob-reference.schema.d.ts +10 -0
- package/dist/schemas/blob-reference.schema.d.ts.map +1 -0
- package/dist/schemas/blob-reference.schema.js +9 -0
- package/dist/schemas/blob-reference.schema.js.map +1 -0
- package/dist/schemas/blob.schema.d.ts +28 -0
- package/dist/schemas/blob.schema.d.ts.map +1 -0
- package/dist/schemas/blob.schema.js +26 -0
- package/dist/schemas/blob.schema.js.map +1 -0
- package/dist/schemas/file-version.schema.d.ts +15 -0
- package/dist/schemas/file-version.schema.d.ts.map +1 -0
- package/dist/schemas/file-version.schema.js +15 -0
- package/dist/schemas/file-version.schema.js.map +1 -0
- package/dist/schemas/file.schema.d.ts +20 -0
- package/dist/schemas/file.schema.d.ts.map +1 -0
- package/dist/schemas/file.schema.js +18 -0
- package/dist/schemas/file.schema.js.map +1 -0
- package/dist/schemas/index.d.ts +7 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +7 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/schemas.test.d.ts +2 -0
- package/dist/schemas/schemas.test.d.ts.map +1 -0
- package/dist/schemas/schemas.test.js +275 -0
- package/dist/schemas/schemas.test.js.map +1 -0
- package/dist/schemas/upload-session.schema.d.ts +37 -0
- package/dist/schemas/upload-session.schema.d.ts.map +1 -0
- package/dist/schemas/upload-session.schema.js +32 -0
- package/dist/schemas/upload-session.schema.js.map +1 -0
- package/dist/schemas/uploaded-part.schema.d.ts +14 -0
- package/dist/schemas/uploaded-part.schema.d.ts.map +1 -0
- package/dist/schemas/uploaded-part.schema.js +14 -0
- package/dist/schemas/uploaded-part.schema.js.map +1 -0
- package/dist/utils/ids.d.ts +2 -0
- package/dist/utils/ids.d.ts.map +1 -0
- package/dist/utils/ids.js +5 -0
- package/dist/utils/ids.js.map +1 -0
- package/dist/utils/ids.test.d.ts +2 -0
- package/dist/utils/ids.test.d.ts.map +1 -0
- package/dist/utils/ids.test.js +13 -0
- package/dist/utils/ids.test.js.map +1 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +2 -0
- package/dist/utils/index.js.map +1 -0
- package/package.json +40 -0
package/README.md
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# @vankyle-hub/storage-core
|
|
2
|
+
|
|
3
|
+
Domain models, port interfaces, and the default application service for `vankyle-storage`.
|
|
4
|
+
|
|
5
|
+
This package has no dependency on any cloud SDK. It defines *what the system models* and *how it should behave*, leaving all infrastructure concerns to provider packages.
|
|
6
|
+
|
|
7
|
+
## What's in here
|
|
8
|
+
|
|
9
|
+
| Path | Content |
|
|
10
|
+
|---|---|
|
|
11
|
+
| `domain/models/` | `File`, `Blob`, `FileVersion`, `BlobReference`, `UploadSession`, `UploadedPart` |
|
|
12
|
+
| `domain/enums/` | `StorageProvider`, `UploadMode`, `UploadSessionStatus`, `BlobStatus`, `FileStatus` |
|
|
13
|
+
| `domain/value-objects/` | `SignedAccess`, `StorageLocator` |
|
|
14
|
+
| `schemas/` | Zod schemas for all six entities |
|
|
15
|
+
| `ports/storage/` | `IStorage`, `StorageCapabilities`, and all storage I/O types |
|
|
16
|
+
| `ports/metadata/` | `IMetadataStore`, `IUploadSessionStore`, `IBlobStore`, `IFileStore` |
|
|
17
|
+
| `ports/services/` | `IStorageService` |
|
|
18
|
+
| `application/services/` | `DefaultStorageService` |
|
|
19
|
+
| `application/policies/` | `IObjectKeyPolicy`, `DefaultObjectKeyPolicy` |
|
|
20
|
+
| `utils/` | `generateId()` |
|
|
21
|
+
|
|
22
|
+
## Dependencies
|
|
23
|
+
|
|
24
|
+
- `@vankyle-hub/storage-shared` — errors, `Result` type, utilities
|
|
25
|
+
- `zod` — schema validation
|
|
26
|
+
|
|
27
|
+
## Key interfaces
|
|
28
|
+
|
|
29
|
+
### `IStorage`
|
|
30
|
+
|
|
31
|
+
The abstraction for object storage operations. Required methods cover object CRUD and the full multipart upload lifecycle. Optional methods (`createReadUrl?`, `createPutUrl?`, `createUploadPartUrl?`) are gated by `capabilities`.
|
|
32
|
+
|
|
33
|
+
### `IMetadataStore`
|
|
34
|
+
|
|
35
|
+
Aggregates `IUploadSessionStore`, `IBlobStore`, and `IFileStore` under a single object.
|
|
36
|
+
|
|
37
|
+
### `IStorageService`
|
|
38
|
+
|
|
39
|
+
The public API for application code. Orchestrates uploads, manages blob and file records, and generates access URLs.
|
|
40
|
+
|
|
41
|
+
## `DefaultStorageService`
|
|
42
|
+
|
|
43
|
+
The reference implementation of `IStorageService`. Inject it with any `IStorage` + `IMetadataStore` combination.
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
import { DefaultStorageService, UploadMode } from "@vankyle-hub/storage-core";
|
|
47
|
+
|
|
48
|
+
const service = new DefaultStorageService({
|
|
49
|
+
storage, // IStorage
|
|
50
|
+
metadata, // IMetadataStore
|
|
51
|
+
bucket: "my-bucket",
|
|
52
|
+
objectKeyPrefix: "uploads/",
|
|
53
|
+
defaultUploadExpiresInSeconds: 3600,
|
|
54
|
+
defaultReadUrlExpiresInSeconds: 900,
|
|
55
|
+
});
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
See the [Getting Started guide](../../docs/getting-started.md) for full usage examples.
|
|
59
|
+
|
|
60
|
+
## Object key policy
|
|
61
|
+
|
|
62
|
+
By default, `DefaultObjectKeyPolicy` generates keys as:
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
[prefix/][ownerId/]<uuid>[.ext]
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Override by implementing `IObjectKeyPolicy`:
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
import type { IObjectKeyPolicy, ObjectKeyPolicyInput } from "@vankyle-hub/storage-core";
|
|
72
|
+
|
|
73
|
+
class MyKeyPolicy implements IObjectKeyPolicy {
|
|
74
|
+
generate(input: ObjectKeyPolicyInput): string {
|
|
75
|
+
return `${input.ownerId ?? "anon"}/${Date.now()}-${input.fileName ?? "upload"}`;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const service = new DefaultStorageService({
|
|
80
|
+
...,
|
|
81
|
+
objectKeyPolicy: new MyKeyPolicy(),
|
|
82
|
+
});
|
|
83
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/application/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/application/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/application/policies/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,sBAAsB,GACvB,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/application/policies/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,sBAAsB,GACvB,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface ObjectKeyPolicyInput {
|
|
2
|
+
readonly fileName?: string | undefined;
|
|
3
|
+
readonly mimeType?: string | undefined;
|
|
4
|
+
readonly ownerId?: string | undefined;
|
|
5
|
+
readonly prefix?: string | undefined;
|
|
6
|
+
}
|
|
7
|
+
export interface IObjectKeyPolicy {
|
|
8
|
+
generate(input: ObjectKeyPolicyInput): string;
|
|
9
|
+
}
|
|
10
|
+
export declare class DefaultObjectKeyPolicy implements IObjectKeyPolicy {
|
|
11
|
+
generate(input: ObjectKeyPolicyInput): string;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=object-key-policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"object-key-policy.d.ts","sourceRoot":"","sources":["../../../src/application/policies/object-key-policy.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACtC;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,KAAK,EAAE,oBAAoB,GAAG,MAAM,CAAC;CAC/C;AAED,qBAAa,sBAAuB,YAAW,gBAAgB;IAC7D,QAAQ,CAAC,KAAK,EAAE,oBAAoB,GAAG,MAAM;CAiB9C"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { generateId } from "../../utils/ids.js";
|
|
2
|
+
export class DefaultObjectKeyPolicy {
|
|
3
|
+
generate(input) {
|
|
4
|
+
const id = generateId();
|
|
5
|
+
const parts = [];
|
|
6
|
+
if (input.prefix) {
|
|
7
|
+
parts.push(input.prefix.replace(/\/+$/, ""));
|
|
8
|
+
}
|
|
9
|
+
if (input.ownerId) {
|
|
10
|
+
parts.push(input.ownerId);
|
|
11
|
+
}
|
|
12
|
+
const ext = input.fileName ? extractExtension(input.fileName) : "";
|
|
13
|
+
parts.push(ext ? `${id}${ext}` : id);
|
|
14
|
+
return parts.join("/");
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function extractExtension(fileName) {
|
|
18
|
+
const dot = fileName.lastIndexOf(".");
|
|
19
|
+
if (dot <= 0) {
|
|
20
|
+
return "";
|
|
21
|
+
}
|
|
22
|
+
return fileName.slice(dot).toLowerCase();
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=object-key-policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"object-key-policy.js","sourceRoot":"","sources":["../../../src/application/policies/object-key-policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAahD,MAAM,OAAO,sBAAsB;IACjC,QAAQ,CAAC,KAA2B;QAClC,MAAM,EAAE,GAAG,UAAU,EAAE,CAAC;QACxB,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YACjB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC;QAC/C,CAAC;QAED,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YAClB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC5B,CAAC;QAED,MAAM,GAAG,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,gBAAgB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACnE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAErC,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC;CACF;AAED,SAAS,gBAAgB,CAAC,QAAgB;IACxC,MAAM,GAAG,GAAG,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACtC,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC;QACb,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;AAC3C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"object-key-policy.test.d.ts","sourceRoot":"","sources":["../../../src/application/policies/object-key-policy.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { DefaultObjectKeyPolicy } from "@vankyle-hub/storage-core";
|
|
3
|
+
describe("DefaultObjectKeyPolicy", () => {
|
|
4
|
+
const policy = new DefaultObjectKeyPolicy();
|
|
5
|
+
it("should generate a key with just an id when no inputs provided", () => {
|
|
6
|
+
const key = policy.generate({});
|
|
7
|
+
// Should be a UUID (36 chars)
|
|
8
|
+
expect(key).toMatch(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/);
|
|
9
|
+
});
|
|
10
|
+
it("should include prefix when provided", () => {
|
|
11
|
+
const key = policy.generate({ prefix: "uploads" });
|
|
12
|
+
expect(key).toMatch(/^uploads\//);
|
|
13
|
+
});
|
|
14
|
+
it("should strip trailing slashes from prefix", () => {
|
|
15
|
+
const key = policy.generate({ prefix: "uploads///" });
|
|
16
|
+
expect(key).toMatch(/^uploads\//);
|
|
17
|
+
expect(key).not.toContain("///");
|
|
18
|
+
});
|
|
19
|
+
it("should include ownerId when provided", () => {
|
|
20
|
+
const key = policy.generate({ ownerId: "user-123" });
|
|
21
|
+
expect(key).toContain("user-123/");
|
|
22
|
+
});
|
|
23
|
+
it("should include file extension from fileName", () => {
|
|
24
|
+
const key = policy.generate({ fileName: "document.pdf" });
|
|
25
|
+
expect(key).toMatch(/\.pdf$/);
|
|
26
|
+
});
|
|
27
|
+
it("should lowercase the extension", () => {
|
|
28
|
+
const key = policy.generate({ fileName: "image.PNG" });
|
|
29
|
+
expect(key).toMatch(/\.png$/);
|
|
30
|
+
});
|
|
31
|
+
it("should handle files without extension", () => {
|
|
32
|
+
const key = policy.generate({ fileName: "Makefile" });
|
|
33
|
+
// No dot extension, should just be the UUID
|
|
34
|
+
expect(key).not.toContain(".");
|
|
35
|
+
});
|
|
36
|
+
it("should combine prefix, ownerId, and extension", () => {
|
|
37
|
+
const key = policy.generate({
|
|
38
|
+
prefix: "files",
|
|
39
|
+
ownerId: "user-1",
|
|
40
|
+
fileName: "photo.jpg",
|
|
41
|
+
});
|
|
42
|
+
const segments = key.split("/");
|
|
43
|
+
expect(segments[0]).toBe("files");
|
|
44
|
+
expect(segments[1]).toBe("user-1");
|
|
45
|
+
expect(segments[2]).toMatch(/\.jpg$/);
|
|
46
|
+
});
|
|
47
|
+
it("should generate unique keys on each call", () => {
|
|
48
|
+
const key1 = policy.generate({ fileName: "test.txt" });
|
|
49
|
+
const key2 = policy.generate({ fileName: "test.txt" });
|
|
50
|
+
expect(key1).not.toBe(key2);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
//# sourceMappingURL=object-key-policy.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"object-key-policy.test.js","sourceRoot":"","sources":["../../../src/application/policies/object-key-policy.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { IStorage } from "../../ports/storage/i-storage.js";
|
|
2
|
+
import type { IMetadataStore } from "../../ports/metadata/i-metadata-store.js";
|
|
3
|
+
import type { IStorageService, CreateUploadSessionRequest, CreateUploadSessionResponse, GetUploadPartUrlRequest, UploadPartRequest, RegisterPartRequest, CompleteUploadSessionRequest, CompleteUploadSessionResponse, GetReadUrlRequest, DeleteFileRequest } from "../../ports/services/i-storage-service.js";
|
|
4
|
+
import type { UploadedPart } from "../../domain/models/uploaded-part.js";
|
|
5
|
+
import type { Blob as StorageBlob } from "../../domain/models/blob.js";
|
|
6
|
+
import type { File } from "../../domain/models/file.js";
|
|
7
|
+
import type { SignedAccess } from "../../domain/value-objects/signed-access.js";
|
|
8
|
+
import type { IObjectKeyPolicy } from "../policies/object-key-policy.js";
|
|
9
|
+
export interface DefaultStorageServiceOptions {
|
|
10
|
+
readonly storage: IStorage;
|
|
11
|
+
readonly metadata: IMetadataStore;
|
|
12
|
+
readonly bucket: string;
|
|
13
|
+
readonly objectKeyPolicy?: IObjectKeyPolicy | undefined;
|
|
14
|
+
readonly objectKeyPrefix?: string | undefined;
|
|
15
|
+
readonly defaultUploadExpiresInSeconds?: number | undefined;
|
|
16
|
+
readonly defaultReadUrlExpiresInSeconds?: number | undefined;
|
|
17
|
+
}
|
|
18
|
+
export declare class DefaultStorageService implements IStorageService {
|
|
19
|
+
private readonly storage;
|
|
20
|
+
private readonly metadata;
|
|
21
|
+
private readonly bucket;
|
|
22
|
+
private readonly objectKeyPolicy;
|
|
23
|
+
private readonly objectKeyPrefix;
|
|
24
|
+
private readonly defaultUploadExpiresInSeconds;
|
|
25
|
+
private readonly defaultReadUrlExpiresInSeconds;
|
|
26
|
+
constructor(options: DefaultStorageServiceOptions);
|
|
27
|
+
createUploadSession(request: CreateUploadSessionRequest): Promise<CreateUploadSessionResponse>;
|
|
28
|
+
getUploadPartUrl(request: GetUploadPartUrlRequest): Promise<SignedAccess>;
|
|
29
|
+
uploadPart(request: UploadPartRequest): Promise<UploadedPart>;
|
|
30
|
+
registerPart(request: RegisterPartRequest): Promise<UploadedPart>;
|
|
31
|
+
completeUploadSession(request: CompleteUploadSessionRequest): Promise<CompleteUploadSessionResponse>;
|
|
32
|
+
abortUploadSession(sessionId: string): Promise<void>;
|
|
33
|
+
getReadUrl(request: GetReadUrlRequest): Promise<SignedAccess>;
|
|
34
|
+
getFile(fileId: string): Promise<File | undefined>;
|
|
35
|
+
getBlob(blobId: string): Promise<StorageBlob | undefined>;
|
|
36
|
+
deleteFile(request: DeleteFileRequest): Promise<void>;
|
|
37
|
+
private requireSession;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=default-storage-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"default-storage-service.d.ts","sourceRoot":"","sources":["../../../src/application/services/default-storage-service.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kCAAkC,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAC/E,OAAO,KAAK,EACV,eAAe,EACf,0BAA0B,EAC1B,2BAA2B,EAC3B,uBAAuB,EACvB,iBAAiB,EACjB,mBAAmB,EACnB,4BAA4B,EAC5B,6BAA6B,EAC7B,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,2CAA2C,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AACzE,OAAO,KAAK,EAAE,IAAI,IAAI,WAAW,EAAE,MAAM,6BAA6B,CAAC;AACvE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,6BAA6B,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6CAA6C,CAAC;AAKhF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAGzE,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,eAAe,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;IACxD,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9C,QAAQ,CAAC,6BAA6B,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5D,QAAQ,CAAC,8BAA8B,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC9D;AAED,qBAAa,qBAAsB,YAAW,eAAe;IAC3D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAW;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiB;IAC1C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAmB;IACnD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAqB;IACrD,OAAO,CAAC,QAAQ,CAAC,6BAA6B,CAAS;IACvD,OAAO,CAAC,QAAQ,CAAC,8BAA8B,CAAS;gBAE5C,OAAO,EAAE,4BAA4B;IAU3C,mBAAmB,CACvB,OAAO,EAAE,0BAA0B,GAClC,OAAO,CAAC,2BAA2B,CAAC;IAyDjC,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,YAAY,CAAC;IAoBzE,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,YAAY,CAAC;IAiC7D,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,YAAY,CAAC;IAmBjE,qBAAqB,CACzB,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,6BAA6B,CAAC;IAsFnC,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBpD,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,YAAY,CAAC;IAkC7D,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC;IAIlD,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IAIzD,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;YAkC7C,cAAc;CAO7B"}
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
import { CapabilityNotSupportedError, MetadataNotFoundError, } from "@vankyle-hub/storage-shared";
|
|
2
|
+
import { UploadMode, UploadSessionStatus } from "../../domain/enums/upload-status.js";
|
|
3
|
+
import { BlobStatus } from "../../domain/enums/blob-status.js";
|
|
4
|
+
import { FileStatus } from "../../domain/enums/file-status.js";
|
|
5
|
+
import { generateId } from "../../utils/ids.js";
|
|
6
|
+
import { DefaultObjectKeyPolicy } from "../policies/object-key-policy.js";
|
|
7
|
+
export class DefaultStorageService {
|
|
8
|
+
storage;
|
|
9
|
+
metadata;
|
|
10
|
+
bucket;
|
|
11
|
+
objectKeyPolicy;
|
|
12
|
+
objectKeyPrefix;
|
|
13
|
+
defaultUploadExpiresInSeconds;
|
|
14
|
+
defaultReadUrlExpiresInSeconds;
|
|
15
|
+
constructor(options) {
|
|
16
|
+
this.storage = options.storage;
|
|
17
|
+
this.metadata = options.metadata;
|
|
18
|
+
this.bucket = options.bucket;
|
|
19
|
+
this.objectKeyPolicy = options.objectKeyPolicy ?? new DefaultObjectKeyPolicy();
|
|
20
|
+
this.objectKeyPrefix = options.objectKeyPrefix;
|
|
21
|
+
this.defaultUploadExpiresInSeconds = options.defaultUploadExpiresInSeconds ?? 3600;
|
|
22
|
+
this.defaultReadUrlExpiresInSeconds = options.defaultReadUrlExpiresInSeconds ?? 3600;
|
|
23
|
+
}
|
|
24
|
+
async createUploadSession(request) {
|
|
25
|
+
const mode = request.mode ?? UploadMode.Multipart;
|
|
26
|
+
const objectKey = this.objectKeyPolicy.generate({
|
|
27
|
+
fileName: request.fileName,
|
|
28
|
+
mimeType: request.mimeType,
|
|
29
|
+
ownerId: request.ownerId,
|
|
30
|
+
prefix: this.objectKeyPrefix,
|
|
31
|
+
});
|
|
32
|
+
let providerUploadId;
|
|
33
|
+
let uploadUrl;
|
|
34
|
+
if (mode === UploadMode.Multipart) {
|
|
35
|
+
const result = await this.storage.initUploadSession({
|
|
36
|
+
bucket: this.bucket,
|
|
37
|
+
objectKey,
|
|
38
|
+
contentType: request.mimeType,
|
|
39
|
+
});
|
|
40
|
+
providerUploadId = result.providerUploadId;
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
// Single mode: generate a presigned PUT URL if supported
|
|
44
|
+
if (this.storage.createPutUrl) {
|
|
45
|
+
uploadUrl = await this.storage.createPutUrl({
|
|
46
|
+
bucket: this.bucket,
|
|
47
|
+
objectKey,
|
|
48
|
+
contentType: request.mimeType,
|
|
49
|
+
expiresInSeconds: request.expiresInSeconds ?? this.defaultUploadExpiresInSeconds,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const expiresAt = new Date(Date.now() +
|
|
54
|
+
(request.expiresInSeconds ?? this.defaultUploadExpiresInSeconds) * 1000);
|
|
55
|
+
const session = await this.metadata.uploads.createSession({
|
|
56
|
+
id: generateId(),
|
|
57
|
+
provider: this.storage.provider,
|
|
58
|
+
bucket: this.bucket,
|
|
59
|
+
objectKey,
|
|
60
|
+
mode,
|
|
61
|
+
fileName: request.fileName,
|
|
62
|
+
mimeType: request.mimeType,
|
|
63
|
+
expectedSize: request.expectedSize,
|
|
64
|
+
expectedSha256: request.expectedSha256,
|
|
65
|
+
providerUploadId,
|
|
66
|
+
createdBy: request.createdBy,
|
|
67
|
+
ownerId: request.ownerId,
|
|
68
|
+
metadata: request.metadata,
|
|
69
|
+
expiresAt,
|
|
70
|
+
});
|
|
71
|
+
return { session, uploadUrl };
|
|
72
|
+
}
|
|
73
|
+
async getUploadPartUrl(request) {
|
|
74
|
+
const session = await this.requireSession(request.sessionId);
|
|
75
|
+
if (!this.storage.createUploadPartUrl) {
|
|
76
|
+
throw new CapabilityNotSupportedError("signedPartUrl");
|
|
77
|
+
}
|
|
78
|
+
if (!session.providerUploadId) {
|
|
79
|
+
throw new MetadataNotFoundError("UploadSession", session.id);
|
|
80
|
+
}
|
|
81
|
+
return this.storage.createUploadPartUrl({
|
|
82
|
+
bucket: session.bucket,
|
|
83
|
+
objectKey: session.objectKey,
|
|
84
|
+
providerUploadId: session.providerUploadId,
|
|
85
|
+
partNumber: request.partNumber,
|
|
86
|
+
expiresInSeconds: this.defaultUploadExpiresInSeconds,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
async uploadPart(request) {
|
|
90
|
+
const session = await this.requireSession(request.sessionId);
|
|
91
|
+
if (!session.providerUploadId) {
|
|
92
|
+
throw new MetadataNotFoundError("UploadSession", session.id);
|
|
93
|
+
}
|
|
94
|
+
const result = await this.storage.uploadPart({
|
|
95
|
+
bucket: session.bucket,
|
|
96
|
+
objectKey: session.objectKey,
|
|
97
|
+
providerUploadId: session.providerUploadId,
|
|
98
|
+
partNumber: request.partNumber,
|
|
99
|
+
body: request.body,
|
|
100
|
+
contentLength: request.contentLength,
|
|
101
|
+
});
|
|
102
|
+
// Update session status to in-progress if still pending
|
|
103
|
+
if (session.status === UploadSessionStatus.Pending) {
|
|
104
|
+
await this.metadata.uploads.updateSession(session.id, {
|
|
105
|
+
status: UploadSessionStatus.InProgress,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
return this.metadata.uploads.addPart({
|
|
109
|
+
id: generateId(),
|
|
110
|
+
sessionId: session.id,
|
|
111
|
+
partNumber: result.partNumber,
|
|
112
|
+
size: result.size ?? 0,
|
|
113
|
+
etag: result.etag,
|
|
114
|
+
checksumSha256: result.checksumSha256,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
async registerPart(request) {
|
|
118
|
+
const session = await this.requireSession(request.sessionId);
|
|
119
|
+
if (session.status === UploadSessionStatus.Pending) {
|
|
120
|
+
await this.metadata.uploads.updateSession(session.id, {
|
|
121
|
+
status: UploadSessionStatus.InProgress,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
return this.metadata.uploads.addPart({
|
|
125
|
+
id: generateId(),
|
|
126
|
+
sessionId: session.id,
|
|
127
|
+
partNumber: request.partNumber,
|
|
128
|
+
size: request.size,
|
|
129
|
+
etag: request.etag,
|
|
130
|
+
checksumSha256: request.checksumSha256,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
async completeUploadSession(request) {
|
|
134
|
+
const session = await this.requireSession(request.sessionId);
|
|
135
|
+
let etag;
|
|
136
|
+
if (session.mode === UploadMode.Multipart && session.providerUploadId) {
|
|
137
|
+
const parts = await this.metadata.uploads.listParts(session.id);
|
|
138
|
+
const result = await this.storage.completeUploadSession({
|
|
139
|
+
bucket: session.bucket,
|
|
140
|
+
objectKey: session.objectKey,
|
|
141
|
+
providerUploadId: session.providerUploadId,
|
|
142
|
+
parts: parts.map((p) => ({ partNumber: p.partNumber, etag: p.etag })),
|
|
143
|
+
});
|
|
144
|
+
etag = result.etag;
|
|
145
|
+
}
|
|
146
|
+
// Head the object to get final metadata
|
|
147
|
+
const head = await this.storage.headObject({
|
|
148
|
+
bucket: session.bucket,
|
|
149
|
+
objectKey: session.objectKey,
|
|
150
|
+
});
|
|
151
|
+
// Mark session completed
|
|
152
|
+
const now = new Date();
|
|
153
|
+
await this.metadata.uploads.updateSession(session.id, {
|
|
154
|
+
status: UploadSessionStatus.Completed,
|
|
155
|
+
completedAt: now,
|
|
156
|
+
});
|
|
157
|
+
// Create blob record
|
|
158
|
+
const blob = await this.metadata.blobs.createBlob({
|
|
159
|
+
id: generateId(),
|
|
160
|
+
provider: session.provider,
|
|
161
|
+
bucket: session.bucket,
|
|
162
|
+
objectKey: session.objectKey,
|
|
163
|
+
size: head.contentLength ?? 0,
|
|
164
|
+
mimeType: head.contentType ?? session.mimeType,
|
|
165
|
+
etag: etag ?? head.etag,
|
|
166
|
+
});
|
|
167
|
+
let file;
|
|
168
|
+
let fileVersion;
|
|
169
|
+
if (request.createFile) {
|
|
170
|
+
const fileId = generateId();
|
|
171
|
+
const versionId = generateId();
|
|
172
|
+
fileVersion = await this.metadata.files.createVersion({
|
|
173
|
+
id: versionId,
|
|
174
|
+
fileId,
|
|
175
|
+
blobId: blob.id,
|
|
176
|
+
version: 1,
|
|
177
|
+
size: blob.size,
|
|
178
|
+
mimeType: blob.mimeType,
|
|
179
|
+
sha256: blob.sha256,
|
|
180
|
+
createdBy: session.createdBy,
|
|
181
|
+
metadata: request.createFile.metadata,
|
|
182
|
+
});
|
|
183
|
+
file = await this.metadata.files.createFile({
|
|
184
|
+
id: fileId,
|
|
185
|
+
ownerId: request.createFile.ownerId ?? session.ownerId,
|
|
186
|
+
displayName: request.createFile.displayName,
|
|
187
|
+
mimeType: blob.mimeType,
|
|
188
|
+
size: blob.size,
|
|
189
|
+
parentId: request.createFile.parentId,
|
|
190
|
+
metadata: request.createFile.metadata,
|
|
191
|
+
});
|
|
192
|
+
// Set current version
|
|
193
|
+
file = await this.metadata.files.updateFile(file.id, {
|
|
194
|
+
currentVersionId: versionId,
|
|
195
|
+
});
|
|
196
|
+
// Create blob reference
|
|
197
|
+
await this.metadata.blobs.createReference({
|
|
198
|
+
id: generateId(),
|
|
199
|
+
blobId: blob.id,
|
|
200
|
+
refType: "file-version",
|
|
201
|
+
refId: versionId,
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
return { blob, file, fileVersion };
|
|
205
|
+
}
|
|
206
|
+
async abortUploadSession(sessionId) {
|
|
207
|
+
const session = await this.requireSession(sessionId);
|
|
208
|
+
if (session.providerUploadId) {
|
|
209
|
+
await this.storage.abortUploadSession({
|
|
210
|
+
bucket: session.bucket,
|
|
211
|
+
objectKey: session.objectKey,
|
|
212
|
+
providerUploadId: session.providerUploadId,
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
await this.metadata.uploads.updateSession(session.id, {
|
|
216
|
+
status: UploadSessionStatus.Aborted,
|
|
217
|
+
abortedAt: new Date(),
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
async getReadUrl(request) {
|
|
221
|
+
if (!this.storage.createReadUrl) {
|
|
222
|
+
throw new CapabilityNotSupportedError("signedReadUrl");
|
|
223
|
+
}
|
|
224
|
+
const file = await this.metadata.files.getFile(request.fileId);
|
|
225
|
+
if (!file) {
|
|
226
|
+
throw new MetadataNotFoundError("File", request.fileId);
|
|
227
|
+
}
|
|
228
|
+
const versionId = request.versionId ?? file.currentVersionId;
|
|
229
|
+
if (!versionId) {
|
|
230
|
+
throw new MetadataNotFoundError("FileVersion", request.fileId);
|
|
231
|
+
}
|
|
232
|
+
const version = await this.metadata.files.getVersion(versionId);
|
|
233
|
+
if (!version) {
|
|
234
|
+
throw new MetadataNotFoundError("FileVersion", versionId);
|
|
235
|
+
}
|
|
236
|
+
const blob = await this.metadata.blobs.getBlob(version.blobId);
|
|
237
|
+
if (!blob) {
|
|
238
|
+
throw new MetadataNotFoundError("Blob", version.blobId);
|
|
239
|
+
}
|
|
240
|
+
return this.storage.createReadUrl({
|
|
241
|
+
bucket: blob.bucket,
|
|
242
|
+
objectKey: blob.objectKey,
|
|
243
|
+
expiresInSeconds: request.expiresInSeconds ?? this.defaultReadUrlExpiresInSeconds,
|
|
244
|
+
responseContentType: file.mimeType ?? blob.mimeType,
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
async getFile(fileId) {
|
|
248
|
+
return this.metadata.files.getFile(fileId);
|
|
249
|
+
}
|
|
250
|
+
async getBlob(blobId) {
|
|
251
|
+
return this.metadata.blobs.getBlob(blobId);
|
|
252
|
+
}
|
|
253
|
+
async deleteFile(request) {
|
|
254
|
+
const file = await this.metadata.files.getFile(request.fileId);
|
|
255
|
+
if (!file) {
|
|
256
|
+
throw new MetadataNotFoundError("File", request.fileId);
|
|
257
|
+
}
|
|
258
|
+
const now = new Date();
|
|
259
|
+
// Soft-delete the file
|
|
260
|
+
await this.metadata.files.updateFile(file.id, {
|
|
261
|
+
status: FileStatus.Deleted,
|
|
262
|
+
deletedAt: now,
|
|
263
|
+
});
|
|
264
|
+
// Remove blob references for all versions and check for orphans
|
|
265
|
+
const versions = await this.metadata.files.listVersions(file.id);
|
|
266
|
+
for (const version of versions) {
|
|
267
|
+
const refs = await this.metadata.blobs.listReferences(version.blobId);
|
|
268
|
+
for (const ref of refs) {
|
|
269
|
+
if (ref.refType === "file-version" && ref.refId === version.id) {
|
|
270
|
+
await this.metadata.blobs.deleteReference(ref.id);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
// If no more references, mark blob as orphaned
|
|
274
|
+
const remainingRefs = await this.metadata.blobs.listReferences(version.blobId);
|
|
275
|
+
if (remainingRefs.length === 0) {
|
|
276
|
+
await this.metadata.blobs.updateBlob(version.blobId, {
|
|
277
|
+
status: BlobStatus.Orphaned,
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
async requireSession(sessionId) {
|
|
283
|
+
const session = await this.metadata.uploads.getSession(sessionId);
|
|
284
|
+
if (!session) {
|
|
285
|
+
throw new MetadataNotFoundError("UploadSession", sessionId);
|
|
286
|
+
}
|
|
287
|
+
return session;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
//# sourceMappingURL=default-storage-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"default-storage-service.js","sourceRoot":"","sources":["../../../src/application/services/default-storage-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"default-storage-service.test.d.ts","sourceRoot":"","sources":["../../../src/application/services/default-storage-service.test.ts"],"names":[],"mappings":""}
|