@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.
Files changed (190) hide show
  1. package/README.md +83 -0
  2. package/dist/application/index.d.ts +3 -0
  3. package/dist/application/index.d.ts.map +1 -0
  4. package/dist/application/index.js +3 -0
  5. package/dist/application/index.js.map +1 -0
  6. package/dist/application/policies/index.d.ts +2 -0
  7. package/dist/application/policies/index.d.ts.map +1 -0
  8. package/dist/application/policies/index.js +2 -0
  9. package/dist/application/policies/index.js.map +1 -0
  10. package/dist/application/policies/object-key-policy.d.ts +13 -0
  11. package/dist/application/policies/object-key-policy.d.ts.map +1 -0
  12. package/dist/application/policies/object-key-policy.js +24 -0
  13. package/dist/application/policies/object-key-policy.js.map +1 -0
  14. package/dist/application/policies/object-key-policy.test.d.ts +2 -0
  15. package/dist/application/policies/object-key-policy.test.d.ts.map +1 -0
  16. package/dist/application/policies/object-key-policy.test.js +53 -0
  17. package/dist/application/policies/object-key-policy.test.js.map +1 -0
  18. package/dist/application/services/default-storage-service.d.ts +39 -0
  19. package/dist/application/services/default-storage-service.d.ts.map +1 -0
  20. package/dist/application/services/default-storage-service.js +290 -0
  21. package/dist/application/services/default-storage-service.js.map +1 -0
  22. package/dist/application/services/default-storage-service.test.d.ts +2 -0
  23. package/dist/application/services/default-storage-service.test.d.ts.map +1 -0
  24. package/dist/application/services/default-storage-service.test.js +902 -0
  25. package/dist/application/services/default-storage-service.test.js.map +1 -0
  26. package/dist/application/services/index.d.ts +2 -0
  27. package/dist/application/services/index.d.ts.map +1 -0
  28. package/dist/application/services/index.js +2 -0
  29. package/dist/application/services/index.js.map +1 -0
  30. package/dist/domain/enums/blob-status.d.ts +8 -0
  31. package/dist/domain/enums/blob-status.d.ts.map +1 -0
  32. package/dist/domain/enums/blob-status.js +7 -0
  33. package/dist/domain/enums/blob-status.js.map +1 -0
  34. package/dist/domain/enums/enums.test.d.ts +2 -0
  35. package/dist/domain/enums/enums.test.d.ts.map +1 -0
  36. package/dist/domain/enums/enums.test.js +59 -0
  37. package/dist/domain/enums/enums.test.js.map +1 -0
  38. package/dist/domain/enums/file-status.d.ts +6 -0
  39. package/dist/domain/enums/file-status.d.ts.map +1 -0
  40. package/dist/domain/enums/file-status.js +5 -0
  41. package/dist/domain/enums/file-status.js.map +1 -0
  42. package/dist/domain/enums/index.d.ts +5 -0
  43. package/dist/domain/enums/index.d.ts.map +1 -0
  44. package/dist/domain/enums/index.js +5 -0
  45. package/dist/domain/enums/index.js.map +1 -0
  46. package/dist/domain/enums/storage-provider.d.ts +7 -0
  47. package/dist/domain/enums/storage-provider.d.ts.map +1 -0
  48. package/dist/domain/enums/storage-provider.js +6 -0
  49. package/dist/domain/enums/storage-provider.js.map +1 -0
  50. package/dist/domain/enums/upload-status.d.ts +13 -0
  51. package/dist/domain/enums/upload-status.d.ts.map +1 -0
  52. package/dist/domain/enums/upload-status.js +11 -0
  53. package/dist/domain/enums/upload-status.js.map +1 -0
  54. package/dist/domain/index.d.ts +4 -0
  55. package/dist/domain/index.d.ts.map +1 -0
  56. package/dist/domain/index.js +4 -0
  57. package/dist/domain/index.js.map +1 -0
  58. package/dist/domain/models/blob-reference.d.ts +8 -0
  59. package/dist/domain/models/blob-reference.d.ts.map +1 -0
  60. package/dist/domain/models/blob-reference.js +2 -0
  61. package/dist/domain/models/blob-reference.js.map +1 -0
  62. package/dist/domain/models/blob.d.ts +20 -0
  63. package/dist/domain/models/blob.d.ts.map +1 -0
  64. package/dist/domain/models/blob.js +2 -0
  65. package/dist/domain/models/blob.js.map +1 -0
  66. package/dist/domain/models/file-version.d.ts +14 -0
  67. package/dist/domain/models/file-version.d.ts.map +1 -0
  68. package/dist/domain/models/file-version.js +2 -0
  69. package/dist/domain/models/file-version.js.map +1 -0
  70. package/dist/domain/models/file.d.ts +17 -0
  71. package/dist/domain/models/file.d.ts.map +1 -0
  72. package/dist/domain/models/file.js +2 -0
  73. package/dist/domain/models/file.js.map +1 -0
  74. package/dist/domain/models/index.d.ts +7 -0
  75. package/dist/domain/models/index.d.ts.map +1 -0
  76. package/dist/domain/models/index.js +2 -0
  77. package/dist/domain/models/index.js.map +1 -0
  78. package/dist/domain/models/upload-session.d.ts +26 -0
  79. package/dist/domain/models/upload-session.d.ts.map +1 -0
  80. package/dist/domain/models/upload-session.js +2 -0
  81. package/dist/domain/models/upload-session.js.map +1 -0
  82. package/dist/domain/models/uploaded-part.d.ts +13 -0
  83. package/dist/domain/models/uploaded-part.d.ts.map +1 -0
  84. package/dist/domain/models/uploaded-part.js +2 -0
  85. package/dist/domain/models/uploaded-part.js.map +1 -0
  86. package/dist/domain/value-objects/index.d.ts +3 -0
  87. package/dist/domain/value-objects/index.d.ts.map +1 -0
  88. package/dist/domain/value-objects/index.js +2 -0
  89. package/dist/domain/value-objects/index.js.map +1 -0
  90. package/dist/domain/value-objects/signed-access.d.ts +9 -0
  91. package/dist/domain/value-objects/signed-access.d.ts.map +1 -0
  92. package/dist/domain/value-objects/signed-access.js +2 -0
  93. package/dist/domain/value-objects/signed-access.js.map +1 -0
  94. package/dist/domain/value-objects/storage-locator.d.ts +7 -0
  95. package/dist/domain/value-objects/storage-locator.d.ts.map +1 -0
  96. package/dist/domain/value-objects/storage-locator.js +2 -0
  97. package/dist/domain/value-objects/storage-locator.js.map +1 -0
  98. package/dist/index.d.ts +6 -0
  99. package/dist/index.d.ts.map +1 -0
  100. package/dist/index.js +6 -0
  101. package/dist/index.js.map +1 -0
  102. package/dist/ports/index.d.ts +4 -0
  103. package/dist/ports/index.d.ts.map +1 -0
  104. package/dist/ports/index.js +4 -0
  105. package/dist/ports/index.js.map +1 -0
  106. package/dist/ports/metadata/i-blob-store.d.ts +38 -0
  107. package/dist/ports/metadata/i-blob-store.d.ts.map +1 -0
  108. package/dist/ports/metadata/i-blob-store.js +2 -0
  109. package/dist/ports/metadata/i-blob-store.js.map +1 -0
  110. package/dist/ports/metadata/i-file-store.d.ts +43 -0
  111. package/dist/ports/metadata/i-file-store.d.ts.map +1 -0
  112. package/dist/ports/metadata/i-file-store.js +2 -0
  113. package/dist/ports/metadata/i-file-store.js.map +1 -0
  114. package/dist/ports/metadata/i-metadata-store.d.ts +9 -0
  115. package/dist/ports/metadata/i-metadata-store.d.ts.map +1 -0
  116. package/dist/ports/metadata/i-metadata-store.js +2 -0
  117. package/dist/ports/metadata/i-metadata-store.js.map +1 -0
  118. package/dist/ports/metadata/i-upload-session-store.d.ts +48 -0
  119. package/dist/ports/metadata/i-upload-session-store.d.ts.map +1 -0
  120. package/dist/ports/metadata/i-upload-session-store.js +2 -0
  121. package/dist/ports/metadata/i-upload-session-store.js.map +1 -0
  122. package/dist/ports/metadata/index.d.ts +5 -0
  123. package/dist/ports/metadata/index.d.ts.map +1 -0
  124. package/dist/ports/metadata/index.js +2 -0
  125. package/dist/ports/metadata/index.js.map +1 -0
  126. package/dist/ports/services/i-storage-service.d.ts +75 -0
  127. package/dist/ports/services/i-storage-service.d.ts.map +1 -0
  128. package/dist/ports/services/i-storage-service.js +2 -0
  129. package/dist/ports/services/i-storage-service.js.map +1 -0
  130. package/dist/ports/services/index.d.ts +2 -0
  131. package/dist/ports/services/index.d.ts.map +1 -0
  132. package/dist/ports/services/index.js +2 -0
  133. package/dist/ports/services/index.js.map +1 -0
  134. package/dist/ports/storage/i-storage.d.ts +19 -0
  135. package/dist/ports/storage/i-storage.d.ts.map +1 -0
  136. package/dist/ports/storage/i-storage.js +2 -0
  137. package/dist/ports/storage/i-storage.js.map +1 -0
  138. package/dist/ports/storage/index.d.ts +3 -0
  139. package/dist/ports/storage/index.d.ts.map +1 -0
  140. package/dist/ports/storage/index.js +2 -0
  141. package/dist/ports/storage/index.js.map +1 -0
  142. package/dist/ports/storage/storage.types.d.ts +112 -0
  143. package/dist/ports/storage/storage.types.d.ts.map +1 -0
  144. package/dist/ports/storage/storage.types.js +2 -0
  145. package/dist/ports/storage/storage.types.js.map +1 -0
  146. package/dist/schemas/blob-reference.schema.d.ts +10 -0
  147. package/dist/schemas/blob-reference.schema.d.ts.map +1 -0
  148. package/dist/schemas/blob-reference.schema.js +9 -0
  149. package/dist/schemas/blob-reference.schema.js.map +1 -0
  150. package/dist/schemas/blob.schema.d.ts +28 -0
  151. package/dist/schemas/blob.schema.d.ts.map +1 -0
  152. package/dist/schemas/blob.schema.js +26 -0
  153. package/dist/schemas/blob.schema.js.map +1 -0
  154. package/dist/schemas/file-version.schema.d.ts +15 -0
  155. package/dist/schemas/file-version.schema.d.ts.map +1 -0
  156. package/dist/schemas/file-version.schema.js +15 -0
  157. package/dist/schemas/file-version.schema.js.map +1 -0
  158. package/dist/schemas/file.schema.d.ts +20 -0
  159. package/dist/schemas/file.schema.d.ts.map +1 -0
  160. package/dist/schemas/file.schema.js +18 -0
  161. package/dist/schemas/file.schema.js.map +1 -0
  162. package/dist/schemas/index.d.ts +7 -0
  163. package/dist/schemas/index.d.ts.map +1 -0
  164. package/dist/schemas/index.js +7 -0
  165. package/dist/schemas/index.js.map +1 -0
  166. package/dist/schemas/schemas.test.d.ts +2 -0
  167. package/dist/schemas/schemas.test.d.ts.map +1 -0
  168. package/dist/schemas/schemas.test.js +275 -0
  169. package/dist/schemas/schemas.test.js.map +1 -0
  170. package/dist/schemas/upload-session.schema.d.ts +37 -0
  171. package/dist/schemas/upload-session.schema.d.ts.map +1 -0
  172. package/dist/schemas/upload-session.schema.js +32 -0
  173. package/dist/schemas/upload-session.schema.js.map +1 -0
  174. package/dist/schemas/uploaded-part.schema.d.ts +14 -0
  175. package/dist/schemas/uploaded-part.schema.d.ts.map +1 -0
  176. package/dist/schemas/uploaded-part.schema.js +14 -0
  177. package/dist/schemas/uploaded-part.schema.js.map +1 -0
  178. package/dist/utils/ids.d.ts +2 -0
  179. package/dist/utils/ids.d.ts.map +1 -0
  180. package/dist/utils/ids.js +5 -0
  181. package/dist/utils/ids.js.map +1 -0
  182. package/dist/utils/ids.test.d.ts +2 -0
  183. package/dist/utils/ids.test.d.ts.map +1 -0
  184. package/dist/utils/ids.test.js +13 -0
  185. package/dist/utils/ids.test.js.map +1 -0
  186. package/dist/utils/index.d.ts +2 -0
  187. package/dist/utils/index.d.ts.map +1 -0
  188. package/dist/utils/index.js +2 -0
  189. package/dist/utils/index.js.map +1 -0
  190. 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,3 @@
1
+ export * from "./services/index.js";
2
+ export * from "./policies/index.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -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,3 @@
1
+ export * from "./services/index.js";
2
+ export * from "./policies/index.js";
3
+ //# sourceMappingURL=index.js.map
@@ -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,2 @@
1
+ export { type IObjectKeyPolicy, type ObjectKeyPolicyInput, DefaultObjectKeyPolicy, } from "./object-key-policy.js";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -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,2 @@
1
+ export { DefaultObjectKeyPolicy, } from "./object-key-policy.js";
2
+ //# sourceMappingURL=index.js.map
@@ -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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=object-key-policy.test.d.ts.map
@@ -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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=default-storage-service.test.d.ts.map
@@ -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":""}